1 //===- FDRRecords.h - XRay Flight Data Recorder Mode Records --------------===//
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
7 //===----------------------------------------------------------------------===//
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.
12 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_XRAY_FDRRECORDS_H_
14 #define LLVM_LIB_XRAY_FDRRECORDS_H_
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"
29 class RecordInitializer
;
33 enum class RecordKind
{
35 RK_Metadata_BufferExtents
,
36 RK_Metadata_WallClockTime
,
39 RK_Metadata_CustomEvent
,
40 RK_Metadata_CustomEventV5
,
43 RK_Metadata_NewBuffer
,
44 RK_Metadata_EndOfBuffer
,
45 RK_Metadata_TypedEvent
,
46 RK_Metadata_LastMetadata
,
50 static StringRef
kindToString(RecordKind K
);
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
) {}
62 RecordKind
getRecordType() const { return T
; }
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;
68 virtual ~Record() = default;
71 class MetadataRecord
: public Record
{
73 enum class MetadataType
: unsigned {
88 static constexpr int kMetadataBodySize
= 15;
89 friend class RecordInitializer
;
92 const MetadataType MT
;
95 explicit MetadataRecord(RecordKind T
, MetadataType M
) : Record(T
), MT(M
) {}
97 static bool classof(const Record
*R
) {
98 return R
->getRecordType() >= RecordKind::RK_Metadata
&&
99 R
->getRecordType() <= RecordKind::RK_Metadata_LastMetadata
;
102 MetadataType
metadataType() const { return MT
; }
104 virtual ~MetadataRecord() = default;
107 // What follows are specific Metadata record types which encapsulate the
108 // information associated with specific metadata record types in an FDR mode
110 class BufferExtents
: public MetadataRecord
{
112 friend class RecordInitializer
;
116 : MetadataRecord(RecordKind::RK_Metadata_BufferExtents
,
117 MetadataType::BufferExtents
) {}
119 explicit BufferExtents(uint64_t S
)
120 : MetadataRecord(RecordKind::RK_Metadata_BufferExtents
,
121 MetadataType::BufferExtents
),
124 uint64_t size() const { return Size
; }
126 Error
apply(RecordVisitor
&V
) override
;
128 static bool classof(const Record
*R
) {
129 return R
->getRecordType() == RecordKind::RK_Metadata_BufferExtents
;
133 class WallclockRecord
: public MetadataRecord
{
134 uint64_t Seconds
= 0;
136 friend class RecordInitializer
;
140 : MetadataRecord(RecordKind::RK_Metadata_WallClockTime
,
141 MetadataType::WallClockTime
) {}
143 explicit WallclockRecord(uint64_t S
, uint32_t N
)
144 : MetadataRecord(RecordKind::RK_Metadata_WallClockTime
,
145 MetadataType::WallClockTime
),
146 Seconds(S
), Nanos(N
) {}
148 uint64_t seconds() const { return Seconds
; }
149 uint32_t nanos() const { return Nanos
; }
151 Error
apply(RecordVisitor
&V
) override
;
153 static bool classof(const Record
*R
) {
154 return R
->getRecordType() == RecordKind::RK_Metadata_WallClockTime
;
158 class NewCPUIDRecord
: public MetadataRecord
{
161 friend class RecordInitializer
;
165 : MetadataRecord(RecordKind::RK_Metadata_NewCPUId
,
166 MetadataType::NewCPUId
) {}
168 NewCPUIDRecord(uint16_t C
, uint64_t T
)
169 : MetadataRecord(RecordKind::RK_Metadata_NewCPUId
,
170 MetadataType::NewCPUId
),
173 uint16_t cpuid() const { return CPUId
; }
175 uint64_t tsc() const { return TSC
; }
177 Error
apply(RecordVisitor
&V
) override
;
179 static bool classof(const Record
*R
) {
180 return R
->getRecordType() == RecordKind::RK_Metadata_NewCPUId
;
184 class TSCWrapRecord
: public MetadataRecord
{
185 uint64_t BaseTSC
= 0;
186 friend class RecordInitializer
;
190 : MetadataRecord(RecordKind::RK_Metadata_TSCWrap
, MetadataType::TSCWrap
) {
193 explicit TSCWrapRecord(uint64_t B
)
194 : MetadataRecord(RecordKind::RK_Metadata_TSCWrap
, MetadataType::TSCWrap
),
197 uint64_t tsc() const { return BaseTSC
; }
199 Error
apply(RecordVisitor
&V
) override
;
201 static bool classof(const Record
*R
) {
202 return R
->getRecordType() == RecordKind::RK_Metadata_TSCWrap
;
206 class CustomEventRecord
: public MetadataRecord
{
211 friend class RecordInitializer
;
215 : MetadataRecord(RecordKind::RK_Metadata_CustomEvent
,
216 MetadataType::CustomEvent
) {}
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
)) {}
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
; }
228 Error
apply(RecordVisitor
&V
) override
;
230 static bool classof(const Record
*R
) {
231 return R
->getRecordType() == RecordKind::RK_Metadata_CustomEvent
;
235 class CustomEventRecordV5
: public MetadataRecord
{
239 friend class RecordInitializer
;
242 CustomEventRecordV5()
243 : MetadataRecord(RecordKind::RK_Metadata_CustomEventV5
,
244 MetadataType::CustomEvent
) {}
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
)) {}
251 int32_t size() const { return Size
; }
252 int32_t delta() const { return Delta
; }
253 StringRef
data() const { return Data
; }
255 Error
apply(RecordVisitor
&V
) override
;
257 static bool classof(const Record
*R
) {
258 return R
->getRecordType() == RecordKind::RK_Metadata_CustomEventV5
;
262 class TypedEventRecord
: public MetadataRecord
{
265 uint16_t EventType
= 0;
267 friend class RecordInitializer
;
271 : MetadataRecord(RecordKind::RK_Metadata_TypedEvent
,
272 MetadataType::TypedEvent
) {}
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
)) {}
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
; }
284 Error
apply(RecordVisitor
&V
) override
;
286 static bool classof(const Record
*R
) {
287 return R
->getRecordType() == RecordKind::RK_Metadata_TypedEvent
;
291 class CallArgRecord
: public MetadataRecord
{
293 friend class RecordInitializer
;
297 : MetadataRecord(RecordKind::RK_Metadata_CallArg
, MetadataType::CallArg
) {
300 explicit CallArgRecord(uint64_t A
)
301 : MetadataRecord(RecordKind::RK_Metadata_CallArg
, MetadataType::CallArg
),
304 uint64_t arg() const { return Arg
; }
306 Error
apply(RecordVisitor
&V
) override
;
308 static bool classof(const Record
*R
) {
309 return R
->getRecordType() == RecordKind::RK_Metadata_CallArg
;
313 class PIDRecord
: public MetadataRecord
{
315 friend class RecordInitializer
;
319 : MetadataRecord(RecordKind::RK_Metadata_PIDEntry
,
320 MetadataType::PIDEntry
) {}
322 explicit PIDRecord(int32_t P
)
323 : MetadataRecord(RecordKind::RK_Metadata_PIDEntry
,
324 MetadataType::PIDEntry
),
327 int32_t pid() const { return PID
; }
329 Error
apply(RecordVisitor
&V
) override
;
331 static bool classof(const Record
*R
) {
332 return R
->getRecordType() == RecordKind::RK_Metadata_PIDEntry
;
336 class NewBufferRecord
: public MetadataRecord
{
338 friend class RecordInitializer
;
342 : MetadataRecord(RecordKind::RK_Metadata_NewBuffer
,
343 MetadataType::NewBuffer
) {}
345 explicit NewBufferRecord(int32_t T
)
346 : MetadataRecord(RecordKind::RK_Metadata_NewBuffer
,
347 MetadataType::NewBuffer
),
350 int32_t tid() const { return TID
; }
352 Error
apply(RecordVisitor
&V
) override
;
354 static bool classof(const Record
*R
) {
355 return R
->getRecordType() == RecordKind::RK_Metadata_NewBuffer
;
359 class EndBufferRecord
: public MetadataRecord
{
362 : MetadataRecord(RecordKind::RK_Metadata_EndOfBuffer
,
363 MetadataType::EndOfBuffer
) {}
365 Error
apply(RecordVisitor
&V
) override
;
367 static bool classof(const Record
*R
) {
368 return R
->getRecordType() == RecordKind::RK_Metadata_EndOfBuffer
;
372 class FunctionRecord
: public Record
{
376 friend class RecordInitializer
;
378 static constexpr unsigned kFunctionRecordSize
= 8;
381 FunctionRecord() : Record(RecordKind::RK_Function
) {}
383 explicit FunctionRecord(RecordTypes K
, int32_t F
, uint32_t D
)
384 : Record(RecordKind::RK_Function
), Kind(K
), FuncId(F
), Delta(D
) {}
386 // A function record is a concrete record type which has a number of common
388 RecordTypes
recordType() const { return Kind
; }
389 int32_t functionId() const { return FuncId
; }
390 uint32_t delta() const { return Delta
; }
392 Error
apply(RecordVisitor
&V
) override
;
394 static bool classof(const Record
*R
) {
395 return R
->getRecordType() == RecordKind::RK_Function
;
399 class RecordVisitor
{
401 virtual ~RecordVisitor() = default;
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;
418 class RecordInitializer
: public RecordVisitor
{
424 static constexpr uint16_t DefaultVersion
= 5u;
426 explicit RecordInitializer(DataExtractor
&DE
, uint64_t &OP
, uint16_t V
)
427 : RecordVisitor(), E(DE
), OffsetPtr(OP
), Version(V
) {}
429 explicit RecordInitializer(DataExtractor
&DE
, uint64_t &OP
)
430 : RecordInitializer(DE
, OP
, DefaultVersion
) {}
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
;
449 #endif // LLVM_LIB_XRAY_FDRRECORDS_H_