File indexing completed on 2026-05-10 08:44:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_XRAY_FDRRECORDS_H
0014 #define LLVM_XRAY_FDRRECORDS_H
0015
0016 #include <cstdint>
0017 #include <string>
0018
0019 #include "llvm/ADT/StringRef.h"
0020 #include "llvm/Support/Casting.h"
0021 #include "llvm/Support/DataExtractor.h"
0022 #include "llvm/Support/Error.h"
0023 #include "llvm/XRay/XRayRecord.h"
0024
0025 namespace llvm {
0026 namespace xray {
0027
0028 class RecordVisitor;
0029 class RecordInitializer;
0030
0031 class Record {
0032 public:
0033 enum class RecordKind {
0034 RK_Metadata,
0035 RK_Metadata_BufferExtents,
0036 RK_Metadata_WallClockTime,
0037 RK_Metadata_NewCPUId,
0038 RK_Metadata_TSCWrap,
0039 RK_Metadata_CustomEvent,
0040 RK_Metadata_CustomEventV5,
0041 RK_Metadata_CallArg,
0042 RK_Metadata_PIDEntry,
0043 RK_Metadata_NewBuffer,
0044 RK_Metadata_EndOfBuffer,
0045 RK_Metadata_TypedEvent,
0046 RK_Metadata_LastMetadata,
0047 RK_Function,
0048 };
0049
0050 static StringRef kindToString(RecordKind K);
0051
0052 private:
0053 const RecordKind T;
0054
0055 public:
0056 Record(const Record &) = delete;
0057 Record(Record &&) = delete;
0058 Record &operator=(const Record &) = delete;
0059 Record &operator=(Record &&) = delete;
0060 explicit Record(RecordKind T) : T(T) {}
0061
0062 RecordKind getRecordType() const { return T; }
0063
0064
0065
0066 virtual Error apply(RecordVisitor &V) = 0;
0067
0068 virtual ~Record() = default;
0069 };
0070
0071 class MetadataRecord : public Record {
0072 public:
0073 enum class MetadataType : unsigned {
0074 Unknown,
0075 BufferExtents,
0076 WallClockTime,
0077 NewCPUId,
0078 TSCWrap,
0079 CustomEvent,
0080 CallArg,
0081 PIDEntry,
0082 NewBuffer,
0083 EndOfBuffer,
0084 TypedEvent,
0085 };
0086
0087 protected:
0088 static constexpr int kMetadataBodySize = 15;
0089 friend class RecordInitializer;
0090
0091 private:
0092 const MetadataType MT;
0093
0094 public:
0095 explicit MetadataRecord(RecordKind T, MetadataType M) : Record(T), MT(M) {}
0096
0097 static bool classof(const Record *R) {
0098 return R->getRecordType() >= RecordKind::RK_Metadata &&
0099 R->getRecordType() <= RecordKind::RK_Metadata_LastMetadata;
0100 }
0101
0102 MetadataType metadataType() const { return MT; }
0103
0104 virtual ~MetadataRecord() = default;
0105 };
0106
0107
0108
0109
0110 class BufferExtents : public MetadataRecord {
0111 uint64_t Size = 0;
0112 friend class RecordInitializer;
0113
0114 public:
0115 BufferExtents()
0116 : MetadataRecord(RecordKind::RK_Metadata_BufferExtents,
0117 MetadataType::BufferExtents) {}
0118
0119 explicit BufferExtents(uint64_t S)
0120 : MetadataRecord(RecordKind::RK_Metadata_BufferExtents,
0121 MetadataType::BufferExtents),
0122 Size(S) {}
0123
0124 uint64_t size() const { return Size; }
0125
0126 Error apply(RecordVisitor &V) override;
0127
0128 static bool classof(const Record *R) {
0129 return R->getRecordType() == RecordKind::RK_Metadata_BufferExtents;
0130 }
0131 };
0132
0133 class WallclockRecord : public MetadataRecord {
0134 uint64_t Seconds = 0;
0135 uint32_t Nanos = 0;
0136 friend class RecordInitializer;
0137
0138 public:
0139 WallclockRecord()
0140 : MetadataRecord(RecordKind::RK_Metadata_WallClockTime,
0141 MetadataType::WallClockTime) {}
0142
0143 explicit WallclockRecord(uint64_t S, uint32_t N)
0144 : MetadataRecord(RecordKind::RK_Metadata_WallClockTime,
0145 MetadataType::WallClockTime),
0146 Seconds(S), Nanos(N) {}
0147
0148 uint64_t seconds() const { return Seconds; }
0149 uint32_t nanos() const { return Nanos; }
0150
0151 Error apply(RecordVisitor &V) override;
0152
0153 static bool classof(const Record *R) {
0154 return R->getRecordType() == RecordKind::RK_Metadata_WallClockTime;
0155 }
0156 };
0157
0158 class NewCPUIDRecord : public MetadataRecord {
0159 uint16_t CPUId = 0;
0160 uint64_t TSC = 0;
0161 friend class RecordInitializer;
0162
0163 public:
0164 NewCPUIDRecord()
0165 : MetadataRecord(RecordKind::RK_Metadata_NewCPUId,
0166 MetadataType::NewCPUId) {}
0167
0168 NewCPUIDRecord(uint16_t C, uint64_t T)
0169 : MetadataRecord(RecordKind::RK_Metadata_NewCPUId,
0170 MetadataType::NewCPUId),
0171 CPUId(C), TSC(T) {}
0172
0173 uint16_t cpuid() const { return CPUId; }
0174
0175 uint64_t tsc() const { return TSC; }
0176
0177 Error apply(RecordVisitor &V) override;
0178
0179 static bool classof(const Record *R) {
0180 return R->getRecordType() == RecordKind::RK_Metadata_NewCPUId;
0181 }
0182 };
0183
0184 class TSCWrapRecord : public MetadataRecord {
0185 uint64_t BaseTSC = 0;
0186 friend class RecordInitializer;
0187
0188 public:
0189 TSCWrapRecord()
0190 : MetadataRecord(RecordKind::RK_Metadata_TSCWrap, MetadataType::TSCWrap) {
0191 }
0192
0193 explicit TSCWrapRecord(uint64_t B)
0194 : MetadataRecord(RecordKind::RK_Metadata_TSCWrap, MetadataType::TSCWrap),
0195 BaseTSC(B) {}
0196
0197 uint64_t tsc() const { return BaseTSC; }
0198
0199 Error apply(RecordVisitor &V) override;
0200
0201 static bool classof(const Record *R) {
0202 return R->getRecordType() == RecordKind::RK_Metadata_TSCWrap;
0203 }
0204 };
0205
0206 class CustomEventRecord : public MetadataRecord {
0207 int32_t Size = 0;
0208 uint64_t TSC = 0;
0209 uint16_t CPU = 0;
0210 std::string Data{};
0211 friend class RecordInitializer;
0212
0213 public:
0214 CustomEventRecord()
0215 : MetadataRecord(RecordKind::RK_Metadata_CustomEvent,
0216 MetadataType::CustomEvent) {}
0217
0218 explicit CustomEventRecord(uint64_t S, uint64_t T, uint16_t C, std::string D)
0219 : MetadataRecord(RecordKind::RK_Metadata_CustomEvent,
0220 MetadataType::CustomEvent),
0221 Size(S), TSC(T), CPU(C), Data(std::move(D)) {}
0222
0223 int32_t size() const { return Size; }
0224 uint64_t tsc() const { return TSC; }
0225 uint16_t cpu() const { return CPU; }
0226 StringRef data() const { return Data; }
0227
0228 Error apply(RecordVisitor &V) override;
0229
0230 static bool classof(const Record *R) {
0231 return R->getRecordType() == RecordKind::RK_Metadata_CustomEvent;
0232 }
0233 };
0234
0235 class CustomEventRecordV5 : public MetadataRecord {
0236 int32_t Size = 0;
0237 int32_t Delta = 0;
0238 std::string Data{};
0239 friend class RecordInitializer;
0240
0241 public:
0242 CustomEventRecordV5()
0243 : MetadataRecord(RecordKind::RK_Metadata_CustomEventV5,
0244 MetadataType::CustomEvent) {}
0245
0246 explicit CustomEventRecordV5(int32_t S, int32_t D, std::string P)
0247 : MetadataRecord(RecordKind::RK_Metadata_CustomEventV5,
0248 MetadataType::CustomEvent),
0249 Size(S), Delta(D), Data(std::move(P)) {}
0250
0251 int32_t size() const { return Size; }
0252 int32_t delta() const { return Delta; }
0253 StringRef data() const { return Data; }
0254
0255 Error apply(RecordVisitor &V) override;
0256
0257 static bool classof(const Record *R) {
0258 return R->getRecordType() == RecordKind::RK_Metadata_CustomEventV5;
0259 }
0260 };
0261
0262 class TypedEventRecord : public MetadataRecord {
0263 int32_t Size = 0;
0264 int32_t Delta = 0;
0265 uint16_t EventType = 0;
0266 std::string Data{};
0267 friend class RecordInitializer;
0268
0269 public:
0270 TypedEventRecord()
0271 : MetadataRecord(RecordKind::RK_Metadata_TypedEvent,
0272 MetadataType::TypedEvent) {}
0273
0274 explicit TypedEventRecord(int32_t S, int32_t D, uint16_t E, std::string P)
0275 : MetadataRecord(RecordKind::RK_Metadata_TypedEvent,
0276 MetadataType::TypedEvent),
0277 Size(S), Delta(D), Data(std::move(P)) {}
0278
0279 int32_t size() const { return Size; }
0280 int32_t delta() const { return Delta; }
0281 uint16_t eventType() const { return EventType; }
0282 StringRef data() const { return Data; }
0283
0284 Error apply(RecordVisitor &V) override;
0285
0286 static bool classof(const Record *R) {
0287 return R->getRecordType() == RecordKind::RK_Metadata_TypedEvent;
0288 }
0289 };
0290
0291 class CallArgRecord : public MetadataRecord {
0292 uint64_t Arg = 0;
0293 friend class RecordInitializer;
0294
0295 public:
0296 CallArgRecord()
0297 : MetadataRecord(RecordKind::RK_Metadata_CallArg, MetadataType::CallArg) {
0298 }
0299
0300 explicit CallArgRecord(uint64_t A)
0301 : MetadataRecord(RecordKind::RK_Metadata_CallArg, MetadataType::CallArg),
0302 Arg(A) {}
0303
0304 uint64_t arg() const { return Arg; }
0305
0306 Error apply(RecordVisitor &V) override;
0307
0308 static bool classof(const Record *R) {
0309 return R->getRecordType() == RecordKind::RK_Metadata_CallArg;
0310 }
0311 };
0312
0313 class PIDRecord : public MetadataRecord {
0314 int32_t PID = 0;
0315 friend class RecordInitializer;
0316
0317 public:
0318 PIDRecord()
0319 : MetadataRecord(RecordKind::RK_Metadata_PIDEntry,
0320 MetadataType::PIDEntry) {}
0321
0322 explicit PIDRecord(int32_t P)
0323 : MetadataRecord(RecordKind::RK_Metadata_PIDEntry,
0324 MetadataType::PIDEntry),
0325 PID(P) {}
0326
0327 int32_t pid() const { return PID; }
0328
0329 Error apply(RecordVisitor &V) override;
0330
0331 static bool classof(const Record *R) {
0332 return R->getRecordType() == RecordKind::RK_Metadata_PIDEntry;
0333 }
0334 };
0335
0336 class NewBufferRecord : public MetadataRecord {
0337 int32_t TID = 0;
0338 friend class RecordInitializer;
0339
0340 public:
0341 NewBufferRecord()
0342 : MetadataRecord(RecordKind::RK_Metadata_NewBuffer,
0343 MetadataType::NewBuffer) {}
0344
0345 explicit NewBufferRecord(int32_t T)
0346 : MetadataRecord(RecordKind::RK_Metadata_NewBuffer,
0347 MetadataType::NewBuffer),
0348 TID(T) {}
0349
0350 int32_t tid() const { return TID; }
0351
0352 Error apply(RecordVisitor &V) override;
0353
0354 static bool classof(const Record *R) {
0355 return R->getRecordType() == RecordKind::RK_Metadata_NewBuffer;
0356 }
0357 };
0358
0359 class EndBufferRecord : public MetadataRecord {
0360 public:
0361 EndBufferRecord()
0362 : MetadataRecord(RecordKind::RK_Metadata_EndOfBuffer,
0363 MetadataType::EndOfBuffer) {}
0364
0365 Error apply(RecordVisitor &V) override;
0366
0367 static bool classof(const Record *R) {
0368 return R->getRecordType() == RecordKind::RK_Metadata_EndOfBuffer;
0369 }
0370 };
0371
0372 class FunctionRecord : public Record {
0373 RecordTypes Kind;
0374 int32_t FuncId = 0;
0375 uint32_t Delta = 0;
0376 friend class RecordInitializer;
0377
0378 static constexpr unsigned kFunctionRecordSize = 8;
0379
0380 public:
0381 FunctionRecord() : Record(RecordKind::RK_Function) {}
0382
0383 explicit FunctionRecord(RecordTypes K, int32_t F, uint32_t D)
0384 : Record(RecordKind::RK_Function), Kind(K), FuncId(F), Delta(D) {}
0385
0386
0387
0388 RecordTypes recordType() const { return Kind; }
0389 int32_t functionId() const { return FuncId; }
0390 uint32_t delta() const { return Delta; }
0391
0392 Error apply(RecordVisitor &V) override;
0393
0394 static bool classof(const Record *R) {
0395 return R->getRecordType() == RecordKind::RK_Function;
0396 }
0397 };
0398
0399 class RecordVisitor {
0400 public:
0401 virtual ~RecordVisitor() = default;
0402
0403
0404 virtual Error visit(BufferExtents &) = 0;
0405 virtual Error visit(WallclockRecord &) = 0;
0406 virtual Error visit(NewCPUIDRecord &) = 0;
0407 virtual Error visit(TSCWrapRecord &) = 0;
0408 virtual Error visit(CustomEventRecord &) = 0;
0409 virtual Error visit(CallArgRecord &) = 0;
0410 virtual Error visit(PIDRecord &) = 0;
0411 virtual Error visit(NewBufferRecord &) = 0;
0412 virtual Error visit(EndBufferRecord &) = 0;
0413 virtual Error visit(FunctionRecord &) = 0;
0414 virtual Error visit(CustomEventRecordV5 &) = 0;
0415 virtual Error visit(TypedEventRecord &) = 0;
0416 };
0417
0418 class RecordInitializer : public RecordVisitor {
0419 DataExtractor &E;
0420 uint64_t &OffsetPtr;
0421 uint16_t Version;
0422
0423 public:
0424 static constexpr uint16_t DefaultVersion = 5u;
0425
0426 explicit RecordInitializer(DataExtractor &DE, uint64_t &OP, uint16_t V)
0427 : E(DE), OffsetPtr(OP), Version(V) {}
0428
0429 explicit RecordInitializer(DataExtractor &DE, uint64_t &OP)
0430 : RecordInitializer(DE, OP, DefaultVersion) {}
0431
0432 Error visit(BufferExtents &) override;
0433 Error visit(WallclockRecord &) override;
0434 Error visit(NewCPUIDRecord &) override;
0435 Error visit(TSCWrapRecord &) override;
0436 Error visit(CustomEventRecord &) override;
0437 Error visit(CallArgRecord &) override;
0438 Error visit(PIDRecord &) override;
0439 Error visit(NewBufferRecord &) override;
0440 Error visit(EndBufferRecord &) override;
0441 Error visit(FunctionRecord &) override;
0442 Error visit(CustomEventRecordV5 &) override;
0443 Error visit(TypedEventRecord &) override;
0444 };
0445
0446 }
0447 }
0448
0449 #endif