Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:46

0001 //===- FDRRecords.h - XRay Flight Data Recorder Mode Records --------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // Define types and operations on these types that represent the different kinds
0010 // of records we encounter in XRay flight data recorder mode traces.
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   // Each Record should be able to apply an abstract visitor, and choose the
0065   // appropriate function in the visitor to invoke, given its own type.
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 // What follows are specific Metadata record types which encapsulate the
0108 // information associated with specific metadata record types in an FDR mode
0109 // log.
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   // A function record is a concrete record type which has a number of common
0387   // properties.
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   // Support all specific kinds of records:
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 } // namespace xray
0447 } // namespace llvm
0448 
0449 #endif // LLVM_XRAY_FDRRECORDS_H