]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/include/llvm/XRay/FDRRecords.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / include / llvm / XRay / FDRRecords.h
1 //===- FDRRecords.h - XRay Flight Data Recorder Mode Records --------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Define types and operations on these types that represent the different kinds
10 // of records we encounter in XRay flight data recorder mode traces.
11 //
12 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_XRAY_FDRRECORDS_H_
14 #define LLVM_LIB_XRAY_FDRRECORDS_H_
15
16 #include <cstdint>
17 #include <string>
18
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/Support/Casting.h"
21 #include "llvm/Support/DataExtractor.h"
22 #include "llvm/Support/Error.h"
23 #include "llvm/XRay/XRayRecord.h"
24
25 namespace llvm {
26 namespace xray {
27
28 class RecordVisitor;
29 class RecordInitializer;
30
31 class Record {
32 public:
33   enum class RecordKind {
34     RK_Metadata,
35     RK_Metadata_BufferExtents,
36     RK_Metadata_WallClockTime,
37     RK_Metadata_NewCPUId,
38     RK_Metadata_TSCWrap,
39     RK_Metadata_CustomEvent,
40     RK_Metadata_CustomEventV5,
41     RK_Metadata_CallArg,
42     RK_Metadata_PIDEntry,
43     RK_Metadata_NewBuffer,
44     RK_Metadata_EndOfBuffer,
45     RK_Metadata_TypedEvent,
46     RK_Metadata_LastMetadata,
47     RK_Function,
48   };
49
50   static StringRef kindToString(RecordKind K);
51
52 private:
53   const RecordKind T;
54
55 public:
56   Record(const Record &) = delete;
57   Record(Record &&) = delete;
58   Record &operator=(const Record &) = delete;
59   Record &operator=(Record &&) = delete;
60   explicit Record(RecordKind T) : T(T) {}
61
62   RecordKind getRecordType() const { return T; }
63
64   // Each Record should be able to apply an abstract visitor, and choose the
65   // appropriate function in the visitor to invoke, given its own type.
66   virtual Error apply(RecordVisitor &V) = 0;
67
68   virtual ~Record() = default;
69 };
70
71 class MetadataRecord : public Record {
72 public:
73   enum class MetadataType : unsigned {
74     Unknown,
75     BufferExtents,
76     WallClockTime,
77     NewCPUId,
78     TSCWrap,
79     CustomEvent,
80     CallArg,
81     PIDEntry,
82     NewBuffer,
83     EndOfBuffer,
84     TypedEvent,
85   };
86
87 protected:
88   static constexpr int kMetadataBodySize = 15;
89   friend class RecordInitializer;
90
91 private:
92   const MetadataType MT;
93
94 public:
95   explicit MetadataRecord(RecordKind T, MetadataType M) : Record(T), MT(M) {}
96
97   static bool classof(const Record *R) {
98     return R->getRecordType() >= RecordKind::RK_Metadata &&
99            R->getRecordType() <= RecordKind::RK_Metadata_LastMetadata;
100   }
101
102   MetadataType metadataType() const { return MT; }
103
104   virtual ~MetadataRecord() = default;
105 };
106
107 // What follows are specific Metadata record types which encapsulate the
108 // information associated with specific metadata record types in an FDR mode
109 // log.
110 class BufferExtents : public MetadataRecord {
111   uint64_t Size = 0;
112   friend class RecordInitializer;
113
114 public:
115   BufferExtents()
116       : MetadataRecord(RecordKind::RK_Metadata_BufferExtents,
117                        MetadataType::BufferExtents) {}
118
119   explicit BufferExtents(uint64_t S)
120       : MetadataRecord(RecordKind::RK_Metadata_BufferExtents,
121                        MetadataType::BufferExtents),
122         Size(S) {}
123
124   uint64_t size() const { return Size; }
125
126   Error apply(RecordVisitor &V) override;
127
128   static bool classof(const Record *R) {
129     return R->getRecordType() == RecordKind::RK_Metadata_BufferExtents;
130   }
131 };
132
133 class WallclockRecord : public MetadataRecord {
134   uint64_t Seconds = 0;
135   uint32_t Nanos = 0;
136   friend class RecordInitializer;
137
138 public:
139   WallclockRecord()
140       : MetadataRecord(RecordKind::RK_Metadata_WallClockTime,
141                        MetadataType::WallClockTime) {}
142
143   explicit WallclockRecord(uint64_t S, uint32_t N)
144       : MetadataRecord(RecordKind::RK_Metadata_WallClockTime,
145                        MetadataType::WallClockTime),
146         Seconds(S), Nanos(N) {}
147
148   uint64_t seconds() const { return Seconds; }
149   uint32_t nanos() const { return Nanos; }
150
151   Error apply(RecordVisitor &V) override;
152
153   static bool classof(const Record *R) {
154     return R->getRecordType() == RecordKind::RK_Metadata_WallClockTime;
155   }
156 };
157
158 class NewCPUIDRecord : public MetadataRecord {
159   uint16_t CPUId = 0;
160   uint64_t TSC = 0;
161   friend class RecordInitializer;
162
163 public:
164   NewCPUIDRecord()
165       : MetadataRecord(RecordKind::RK_Metadata_NewCPUId,
166                        MetadataType::NewCPUId) {}
167
168   NewCPUIDRecord(uint16_t C, uint64_t T)
169       : MetadataRecord(RecordKind::RK_Metadata_NewCPUId,
170                        MetadataType::NewCPUId),
171         CPUId(C), TSC(T) {}
172
173   uint16_t cpuid() const { return CPUId; }
174
175   uint64_t tsc() const { return TSC; }
176
177   Error apply(RecordVisitor &V) override;
178
179   static bool classof(const Record *R) {
180     return R->getRecordType() == RecordKind::RK_Metadata_NewCPUId;
181   }
182 };
183
184 class TSCWrapRecord : public MetadataRecord {
185   uint64_t BaseTSC = 0;
186   friend class RecordInitializer;
187
188 public:
189   TSCWrapRecord()
190       : MetadataRecord(RecordKind::RK_Metadata_TSCWrap, MetadataType::TSCWrap) {
191   }
192
193   explicit TSCWrapRecord(uint64_t B)
194       : MetadataRecord(RecordKind::RK_Metadata_TSCWrap, MetadataType::TSCWrap),
195         BaseTSC(B) {}
196
197   uint64_t tsc() const { return BaseTSC; }
198
199   Error apply(RecordVisitor &V) override;
200
201   static bool classof(const Record *R) {
202     return R->getRecordType() == RecordKind::RK_Metadata_TSCWrap;
203   }
204 };
205
206 class CustomEventRecord : public MetadataRecord {
207   int32_t Size = 0;
208   uint64_t TSC = 0;
209   uint16_t CPU = 0;
210   std::string Data{};
211   friend class RecordInitializer;
212
213 public:
214   CustomEventRecord()
215       : MetadataRecord(RecordKind::RK_Metadata_CustomEvent,
216                        MetadataType::CustomEvent) {}
217
218   explicit CustomEventRecord(uint64_t S, uint64_t T, uint16_t C, std::string D)
219       : MetadataRecord(RecordKind::RK_Metadata_CustomEvent,
220                        MetadataType::CustomEvent),
221         Size(S), TSC(T), CPU(C), Data(std::move(D)) {}
222
223   int32_t size() const { return Size; }
224   uint64_t tsc() const { return TSC; }
225   uint16_t cpu() const { return CPU; }
226   StringRef data() const { return Data; }
227
228   Error apply(RecordVisitor &V) override;
229
230   static bool classof(const Record *R) {
231     return R->getRecordType() == RecordKind::RK_Metadata_CustomEvent;
232   }
233 };
234
235 class CustomEventRecordV5 : public MetadataRecord {
236   int32_t Size = 0;
237   int32_t Delta = 0;
238   std::string Data{};
239   friend class RecordInitializer;
240
241 public:
242   CustomEventRecordV5()
243       : MetadataRecord(RecordKind::RK_Metadata_CustomEventV5,
244                        MetadataType::CustomEvent) {}
245
246   explicit CustomEventRecordV5(int32_t S, int32_t D, std::string P)
247       : MetadataRecord(RecordKind::RK_Metadata_CustomEventV5,
248                        MetadataType::CustomEvent),
249         Size(S), Delta(D), Data(std::move(P)) {}
250
251   int32_t size() const { return Size; }
252   int32_t delta() const { return Delta; }
253   StringRef data() const { return Data; }
254
255   Error apply(RecordVisitor &V) override;
256
257   static bool classof(const Record *R) {
258     return R->getRecordType() == RecordKind::RK_Metadata_CustomEventV5;
259   }
260 };
261
262 class TypedEventRecord : public MetadataRecord {
263   int32_t Size = 0;
264   int32_t Delta = 0;
265   uint16_t EventType = 0;
266   std::string Data{};
267   friend class RecordInitializer;
268
269 public:
270   TypedEventRecord()
271       : MetadataRecord(RecordKind::RK_Metadata_TypedEvent,
272                        MetadataType::TypedEvent) {}
273
274   explicit TypedEventRecord(int32_t S, int32_t D, uint16_t E, std::string P)
275       : MetadataRecord(RecordKind::RK_Metadata_TypedEvent,
276                        MetadataType::TypedEvent),
277         Size(S), Delta(D), Data(std::move(P)) {}
278
279   int32_t size() const { return Size; }
280   int32_t delta() const { return Delta; }
281   uint16_t eventType() const { return EventType; }
282   StringRef data() const { return Data; }
283
284   Error apply(RecordVisitor &V) override;
285
286   static bool classof(const Record *R) {
287     return R->getRecordType() == RecordKind::RK_Metadata_TypedEvent;
288   }
289 };
290
291 class CallArgRecord : public MetadataRecord {
292   uint64_t Arg = 0;
293   friend class RecordInitializer;
294
295 public:
296   CallArgRecord()
297       : MetadataRecord(RecordKind::RK_Metadata_CallArg, MetadataType::CallArg) {
298   }
299
300   explicit CallArgRecord(uint64_t A)
301       : MetadataRecord(RecordKind::RK_Metadata_CallArg, MetadataType::CallArg),
302         Arg(A) {}
303
304   uint64_t arg() const { return Arg; }
305
306   Error apply(RecordVisitor &V) override;
307
308   static bool classof(const Record *R) {
309     return R->getRecordType() == RecordKind::RK_Metadata_CallArg;
310   }
311 };
312
313 class PIDRecord : public MetadataRecord {
314   int32_t PID = 0;
315   friend class RecordInitializer;
316
317 public:
318   PIDRecord()
319       : MetadataRecord(RecordKind::RK_Metadata_PIDEntry,
320                        MetadataType::PIDEntry) {}
321
322   explicit PIDRecord(int32_t P)
323       : MetadataRecord(RecordKind::RK_Metadata_PIDEntry,
324                        MetadataType::PIDEntry),
325         PID(P) {}
326
327   int32_t pid() const { return PID; }
328
329   Error apply(RecordVisitor &V) override;
330
331   static bool classof(const Record *R) {
332     return R->getRecordType() == RecordKind::RK_Metadata_PIDEntry;
333   }
334 };
335
336 class NewBufferRecord : public MetadataRecord {
337   int32_t TID = 0;
338   friend class RecordInitializer;
339
340 public:
341   NewBufferRecord()
342       : MetadataRecord(RecordKind::RK_Metadata_NewBuffer,
343                        MetadataType::NewBuffer) {}
344
345   explicit NewBufferRecord(int32_t T)
346       : MetadataRecord(RecordKind::RK_Metadata_NewBuffer,
347                        MetadataType::NewBuffer),
348         TID(T) {}
349
350   int32_t tid() const { return TID; }
351
352   Error apply(RecordVisitor &V) override;
353
354   static bool classof(const Record *R) {
355     return R->getRecordType() == RecordKind::RK_Metadata_NewBuffer;
356   }
357 };
358
359 class EndBufferRecord : public MetadataRecord {
360 public:
361   EndBufferRecord()
362       : MetadataRecord(RecordKind::RK_Metadata_EndOfBuffer,
363                        MetadataType::EndOfBuffer) {}
364
365   Error apply(RecordVisitor &V) override;
366
367   static bool classof(const Record *R) {
368     return R->getRecordType() == RecordKind::RK_Metadata_EndOfBuffer;
369   }
370 };
371
372 class FunctionRecord : public Record {
373   RecordTypes Kind;
374   int32_t FuncId = 0;
375   uint32_t Delta = 0;
376   friend class RecordInitializer;
377
378   static constexpr unsigned kFunctionRecordSize = 8;
379
380 public:
381   FunctionRecord() : Record(RecordKind::RK_Function) {}
382
383   explicit FunctionRecord(RecordTypes K, int32_t F, uint32_t D)
384       : Record(RecordKind::RK_Function), Kind(K), FuncId(F), Delta(D) {}
385
386   // A function record is a concrete record type which has a number of common
387   // properties.
388   RecordTypes recordType() const { return Kind; }
389   int32_t functionId() const { return FuncId; }
390   uint32_t delta() const { return Delta; }
391
392   Error apply(RecordVisitor &V) override;
393
394   static bool classof(const Record *R) {
395     return R->getRecordType() == RecordKind::RK_Function;
396   }
397 };
398
399 class RecordVisitor {
400 public:
401   virtual ~RecordVisitor() = default;
402
403   // Support all specific kinds of records:
404   virtual Error visit(BufferExtents &) = 0;
405   virtual Error visit(WallclockRecord &) = 0;
406   virtual Error visit(NewCPUIDRecord &) = 0;
407   virtual Error visit(TSCWrapRecord &) = 0;
408   virtual Error visit(CustomEventRecord &) = 0;
409   virtual Error visit(CallArgRecord &) = 0;
410   virtual Error visit(PIDRecord &) = 0;
411   virtual Error visit(NewBufferRecord &) = 0;
412   virtual Error visit(EndBufferRecord &) = 0;
413   virtual Error visit(FunctionRecord &) = 0;
414   virtual Error visit(CustomEventRecordV5 &) = 0;
415   virtual Error visit(TypedEventRecord &) = 0;
416 };
417
418 class RecordInitializer : public RecordVisitor {
419   DataExtractor &E;
420   uint64_t &OffsetPtr;
421   uint16_t Version;
422
423 public:
424   static constexpr uint16_t DefaultVersion = 5u;
425
426   explicit RecordInitializer(DataExtractor &DE, uint64_t &OP, uint16_t V)
427       : RecordVisitor(), E(DE), OffsetPtr(OP), Version(V) {}
428
429   explicit RecordInitializer(DataExtractor &DE, uint64_t &OP)
430       : RecordInitializer(DE, OP, DefaultVersion) {}
431
432   Error visit(BufferExtents &) override;
433   Error visit(WallclockRecord &) override;
434   Error visit(NewCPUIDRecord &) override;
435   Error visit(TSCWrapRecord &) override;
436   Error visit(CustomEventRecord &) override;
437   Error visit(CallArgRecord &) override;
438   Error visit(PIDRecord &) override;
439   Error visit(NewBufferRecord &) override;
440   Error visit(EndBufferRecord &) override;
441   Error visit(FunctionRecord &) override;
442   Error visit(CustomEventRecordV5 &) override;
443   Error visit(TypedEventRecord &) override;
444 };
445
446 } // namespace xray
447 } // namespace llvm
448
449 #endif // LLVM_LIB_XRAY_FDRRECORDS_H_