Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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_XRAY_FDRRECORDS_H
  14. #define LLVM_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.       : 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_XRAY_FDRRECORDS_H
  450.