1 //===- FDRRecords.h - XRay Flight Data Recorder Mode Records --------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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.
13 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_LIB_XRAY_FDRRECORDS_H_
15 #define LLVM_LIB_XRAY_FDRRECORDS_H_
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Support/Casting.h"
22 #include "llvm/Support/DataExtractor.h"
23 #include "llvm/Support/Error.h"
24 #include "llvm/XRay/XRayRecord.h"
30 class RecordInitializer;
34 enum class RecordKind {
36 RK_Metadata_BufferExtents,
37 RK_Metadata_WallClockTime,
40 RK_Metadata_CustomEvent,
41 RK_Metadata_CustomEventV5,
44 RK_Metadata_NewBuffer,
45 RK_Metadata_EndOfBuffer,
46 RK_Metadata_TypedEvent,
47 RK_Metadata_LastMetadata,
51 static StringRef kindToString(RecordKind K);
57 Record(const Record &) = delete;
58 Record(Record &&) = delete;
59 Record &operator=(const Record &) = delete;
60 Record &operator=(Record &&) = delete;
61 explicit Record(RecordKind T) : T(T) {}
63 RecordKind getRecordType() const { return T; }
65 // Each Record should be able to apply an abstract visitor, and choose the
66 // appropriate function in the visitor to invoke, given its own type.
67 virtual Error apply(RecordVisitor &V) = 0;
69 virtual ~Record() = default;
72 class MetadataRecord : public Record {
74 enum class MetadataType : unsigned {
89 static constexpr int kMetadataBodySize = 15;
90 friend class RecordInitializer;
93 const MetadataType MT;
96 explicit MetadataRecord(RecordKind T, MetadataType M) : Record(T), MT(M) {}
98 static bool classof(const Record *R) {
99 return R->getRecordType() >= RecordKind::RK_Metadata &&
100 R->getRecordType() <= RecordKind::RK_Metadata_LastMetadata;
103 MetadataType metadataType() const { return MT; }
105 virtual ~MetadataRecord() = default;
108 // What follows are specific Metadata record types which encapsulate the
109 // information associated with specific metadata record types in an FDR mode
111 class BufferExtents : public MetadataRecord {
113 friend class RecordInitializer;
117 : MetadataRecord(RecordKind::RK_Metadata_BufferExtents,
118 MetadataType::BufferExtents) {}
120 explicit BufferExtents(uint64_t S)
121 : MetadataRecord(RecordKind::RK_Metadata_BufferExtents,
122 MetadataType::BufferExtents),
125 uint64_t size() const { return Size; }
127 Error apply(RecordVisitor &V) override;
129 static bool classof(const Record *R) {
130 return R->getRecordType() == RecordKind::RK_Metadata_BufferExtents;
134 class WallclockRecord : public MetadataRecord {
135 uint64_t Seconds = 0;
137 friend class RecordInitializer;
141 : MetadataRecord(RecordKind::RK_Metadata_WallClockTime,
142 MetadataType::WallClockTime) {}
144 explicit WallclockRecord(uint64_t S, uint32_t N)
145 : MetadataRecord(RecordKind::RK_Metadata_WallClockTime,
146 MetadataType::WallClockTime),
147 Seconds(S), Nanos(N) {}
149 uint64_t seconds() const { return Seconds; }
150 uint32_t nanos() const { return Nanos; }
152 Error apply(RecordVisitor &V) override;
154 static bool classof(const Record *R) {
155 return R->getRecordType() == RecordKind::RK_Metadata_WallClockTime;
159 class NewCPUIDRecord : public MetadataRecord {
162 friend class RecordInitializer;
166 : MetadataRecord(RecordKind::RK_Metadata_NewCPUId,
167 MetadataType::NewCPUId) {}
169 NewCPUIDRecord(uint16_t C, uint64_t T)
170 : MetadataRecord(RecordKind::RK_Metadata_NewCPUId,
171 MetadataType::NewCPUId),
174 uint16_t cpuid() const { return CPUId; }
176 uint64_t tsc() const { return TSC; }
178 Error apply(RecordVisitor &V) override;
180 static bool classof(const Record *R) {
181 return R->getRecordType() == RecordKind::RK_Metadata_NewCPUId;
185 class TSCWrapRecord : public MetadataRecord {
186 uint64_t BaseTSC = 0;
187 friend class RecordInitializer;
191 : MetadataRecord(RecordKind::RK_Metadata_TSCWrap, MetadataType::TSCWrap) {
194 explicit TSCWrapRecord(uint64_t B)
195 : MetadataRecord(RecordKind::RK_Metadata_TSCWrap, MetadataType::TSCWrap),
198 uint64_t tsc() const { return BaseTSC; }
200 Error apply(RecordVisitor &V) override;
202 static bool classof(const Record *R) {
203 return R->getRecordType() == RecordKind::RK_Metadata_TSCWrap;
207 class CustomEventRecord : public MetadataRecord {
212 friend class RecordInitializer;
216 : MetadataRecord(RecordKind::RK_Metadata_CustomEvent,
217 MetadataType::CustomEvent) {}
219 explicit CustomEventRecord(uint64_t S, uint64_t T, uint16_t C, std::string D)
220 : MetadataRecord(RecordKind::RK_Metadata_CustomEvent,
221 MetadataType::CustomEvent),
222 Size(S), TSC(T), CPU(C), Data(std::move(D)) {}
224 int32_t size() const { return Size; }
225 uint64_t tsc() const { return TSC; }
226 uint16_t cpu() const { return CPU; }
227 StringRef data() const { return Data; }
229 Error apply(RecordVisitor &V) override;
231 static bool classof(const Record *R) {
232 return R->getRecordType() == RecordKind::RK_Metadata_CustomEvent;
236 class CustomEventRecordV5 : public MetadataRecord {
240 friend class RecordInitializer;
243 CustomEventRecordV5()
244 : MetadataRecord(RecordKind::RK_Metadata_CustomEventV5,
245 MetadataType::CustomEvent) {}
247 explicit CustomEventRecordV5(int32_t S, int32_t D, std::string P)
248 : MetadataRecord(RecordKind::RK_Metadata_CustomEventV5,
249 MetadataType::CustomEvent),
250 Size(S), Delta(D), Data(std::move(P)) {}
252 int32_t size() const { return Size; }
253 int32_t delta() const { return Delta; }
254 StringRef data() const { return Data; }
256 Error apply(RecordVisitor &V) override;
258 static bool classof(const Record *R) {
259 return R->getRecordType() == RecordKind::RK_Metadata_CustomEventV5;
263 class TypedEventRecord : public MetadataRecord {
266 uint16_t EventType = 0;
268 friend class RecordInitializer;
272 : MetadataRecord(RecordKind::RK_Metadata_TypedEvent,
273 MetadataType::TypedEvent) {}
275 explicit TypedEventRecord(int32_t S, int32_t D, uint16_t E, std::string P)
276 : MetadataRecord(RecordKind::RK_Metadata_TypedEvent,
277 MetadataType::TypedEvent),
278 Size(S), Delta(D), Data(std::move(P)) {}
280 int32_t size() const { return Size; }
281 int32_t delta() const { return Delta; }
282 uint16_t eventType() const { return EventType; }
283 StringRef data() const { return Data; }
285 Error apply(RecordVisitor &V) override;
287 static bool classof(const Record *R) {
288 return R->getRecordType() == RecordKind::RK_Metadata_TypedEvent;
292 class CallArgRecord : public MetadataRecord {
294 friend class RecordInitializer;
298 : MetadataRecord(RecordKind::RK_Metadata_CallArg, MetadataType::CallArg) {
301 explicit CallArgRecord(uint64_t A)
302 : MetadataRecord(RecordKind::RK_Metadata_CallArg, MetadataType::CallArg),
305 uint64_t arg() const { return Arg; }
307 Error apply(RecordVisitor &V) override;
309 static bool classof(const Record *R) {
310 return R->getRecordType() == RecordKind::RK_Metadata_CallArg;
314 class PIDRecord : public MetadataRecord {
316 friend class RecordInitializer;
320 : MetadataRecord(RecordKind::RK_Metadata_PIDEntry,
321 MetadataType::PIDEntry) {}
323 explicit PIDRecord(int32_t P)
324 : MetadataRecord(RecordKind::RK_Metadata_PIDEntry,
325 MetadataType::PIDEntry),
328 int32_t pid() const { return PID; }
330 Error apply(RecordVisitor &V) override;
332 static bool classof(const Record *R) {
333 return R->getRecordType() == RecordKind::RK_Metadata_PIDEntry;
337 class NewBufferRecord : public MetadataRecord {
339 friend class RecordInitializer;
343 : MetadataRecord(RecordKind::RK_Metadata_NewBuffer,
344 MetadataType::NewBuffer) {}
346 explicit NewBufferRecord(int32_t T)
347 : MetadataRecord(RecordKind::RK_Metadata_NewBuffer,
348 MetadataType::NewBuffer),
351 int32_t tid() const { return TID; }
353 Error apply(RecordVisitor &V) override;
355 static bool classof(const Record *R) {
356 return R->getRecordType() == RecordKind::RK_Metadata_NewBuffer;
360 class EndBufferRecord : public MetadataRecord {
363 : MetadataRecord(RecordKind::RK_Metadata_EndOfBuffer,
364 MetadataType::EndOfBuffer) {}
366 Error apply(RecordVisitor &V) override;
368 static bool classof(const Record *R) {
369 return R->getRecordType() == RecordKind::RK_Metadata_EndOfBuffer;
373 class FunctionRecord : public Record {
377 friend class RecordInitializer;
379 static constexpr unsigned kFunctionRecordSize = 8;
382 FunctionRecord() : Record(RecordKind::RK_Function) {}
384 explicit FunctionRecord(RecordTypes K, int32_t F, uint32_t D)
385 : Record(RecordKind::RK_Function), Kind(K), FuncId(F), Delta(D) {}
387 // A function record is a concrete record type which has a number of common
389 RecordTypes recordType() const { return Kind; }
390 int32_t functionId() const { return FuncId; }
391 uint32_t delta() const { return Delta; }
393 Error apply(RecordVisitor &V) override;
395 static bool classof(const Record *R) {
396 return R->getRecordType() == RecordKind::RK_Function;
400 class RecordVisitor {
402 virtual ~RecordVisitor() = default;
404 // Support all specific kinds of records:
405 virtual Error visit(BufferExtents &) = 0;
406 virtual Error visit(WallclockRecord &) = 0;
407 virtual Error visit(NewCPUIDRecord &) = 0;
408 virtual Error visit(TSCWrapRecord &) = 0;
409 virtual Error visit(CustomEventRecord &) = 0;
410 virtual Error visit(CallArgRecord &) = 0;
411 virtual Error visit(PIDRecord &) = 0;
412 virtual Error visit(NewBufferRecord &) = 0;
413 virtual Error visit(EndBufferRecord &) = 0;
414 virtual Error visit(FunctionRecord &) = 0;
415 virtual Error visit(CustomEventRecordV5 &) = 0;
416 virtual Error visit(TypedEventRecord &) = 0;
419 class RecordInitializer : public RecordVisitor {
425 static constexpr uint16_t DefaultVersion = 5u;
427 explicit RecordInitializer(DataExtractor &DE, uint32_t &OP, uint16_t V)
428 : RecordVisitor(), E(DE), OffsetPtr(OP), Version(V) {}
430 explicit RecordInitializer(DataExtractor &DE, uint32_t &OP)
431 : RecordInitializer(DE, OP, DefaultVersion) {}
433 Error visit(BufferExtents &) override;
434 Error visit(WallclockRecord &) override;
435 Error visit(NewCPUIDRecord &) override;
436 Error visit(TSCWrapRecord &) override;
437 Error visit(CustomEventRecord &) override;
438 Error visit(CallArgRecord &) override;
439 Error visit(PIDRecord &) override;
440 Error visit(NewBufferRecord &) override;
441 Error visit(EndBufferRecord &) override;
442 Error visit(FunctionRecord &) override;
443 Error visit(CustomEventRecordV5 &) override;
444 Error visit(TypedEventRecord &) override;
450 #endif // LLVM_LIB_XRAY_FDRRECORDS_H_