FDRRecords.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- FDRRecords.h - XRay Flight Data Recorder Mode Records --------------===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // Define types and operations on these types that represent the different kinds
  15. // of records we encounter in XRay flight data recorder mode traces.
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_LIB_XRAY_FDRRECORDS_H_
  19. #define LLVM_LIB_XRAY_FDRRECORDS_H_
  20. #include <cstdint>
  21. #include <string>
  22. #include "llvm/ADT/StringRef.h"
  23. #include "llvm/Support/Casting.h"
  24. #include "llvm/Support/DataExtractor.h"
  25. #include "llvm/Support/Error.h"
  26. #include "llvm/XRay/XRayRecord.h"
  27. namespace llvm {
  28. namespace xray {
  29. class RecordVisitor;
  30. class RecordInitializer;
  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. static StringRef kindToString(RecordKind K);
  50. private:
  51. const RecordKind T;
  52. public:
  53. Record(const Record &) = delete;
  54. Record(Record &&) = delete;
  55. Record &operator=(const Record &) = delete;
  56. Record &operator=(Record &&) = delete;
  57. explicit Record(RecordKind T) : T(T) {}
  58. RecordKind getRecordType() const { return T; }
  59. // Each Record should be able to apply an abstract visitor, and choose the
  60. // appropriate function in the visitor to invoke, given its own type.
  61. virtual Error apply(RecordVisitor &V) = 0;
  62. virtual ~Record() = default;
  63. };
  64. class MetadataRecord : public Record {
  65. public:
  66. enum class MetadataType : unsigned {
  67. Unknown,
  68. BufferExtents,
  69. WallClockTime,
  70. NewCPUId,
  71. TSCWrap,
  72. CustomEvent,
  73. CallArg,
  74. PIDEntry,
  75. NewBuffer,
  76. EndOfBuffer,
  77. TypedEvent,
  78. };
  79. protected:
  80. static constexpr int kMetadataBodySize = 15;
  81. friend class RecordInitializer;
  82. private:
  83. const MetadataType MT;
  84. public:
  85. explicit MetadataRecord(RecordKind T, MetadataType M) : Record(T), MT(M) {}
  86. static bool classof(const Record *R) {
  87. return R->getRecordType() >= RecordKind::RK_Metadata &&
  88. R->getRecordType() <= RecordKind::RK_Metadata_LastMetadata;
  89. }
  90. MetadataType metadataType() const { return MT; }
  91. virtual ~MetadataRecord() = default;
  92. };
  93. // What follows are specific Metadata record types which encapsulate the
  94. // information associated with specific metadata record types in an FDR mode
  95. // log.
  96. class BufferExtents : public MetadataRecord {
  97. uint64_t Size = 0;
  98. friend class RecordInitializer;
  99. public:
  100. BufferExtents()
  101. : MetadataRecord(RecordKind::RK_Metadata_BufferExtents,
  102. MetadataType::BufferExtents) {}
  103. explicit BufferExtents(uint64_t S)
  104. : MetadataRecord(RecordKind::RK_Metadata_BufferExtents,
  105. MetadataType::BufferExtents),
  106. Size(S) {}
  107. uint64_t size() const { return Size; }
  108. Error apply(RecordVisitor &V) override;
  109. static bool classof(const Record *R) {
  110. return R->getRecordType() == RecordKind::RK_Metadata_BufferExtents;
  111. }
  112. };
  113. class WallclockRecord : public MetadataRecord {
  114. uint64_t Seconds = 0;
  115. uint32_t Nanos = 0;
  116. friend class RecordInitializer;
  117. public:
  118. WallclockRecord()
  119. : MetadataRecord(RecordKind::RK_Metadata_WallClockTime,
  120. MetadataType::WallClockTime) {}
  121. explicit WallclockRecord(uint64_t S, uint32_t N)
  122. : MetadataRecord(RecordKind::RK_Metadata_WallClockTime,
  123. MetadataType::WallClockTime),
  124. Seconds(S), Nanos(N) {}
  125. uint64_t seconds() const { return Seconds; }
  126. uint32_t nanos() const { return Nanos; }
  127. Error apply(RecordVisitor &V) override;
  128. static bool classof(const Record *R) {
  129. return R->getRecordType() == RecordKind::RK_Metadata_WallClockTime;
  130. }
  131. };
  132. class NewCPUIDRecord : public MetadataRecord {
  133. uint16_t CPUId = 0;
  134. uint64_t TSC = 0;
  135. friend class RecordInitializer;
  136. public:
  137. NewCPUIDRecord()
  138. : MetadataRecord(RecordKind::RK_Metadata_NewCPUId,
  139. MetadataType::NewCPUId) {}
  140. NewCPUIDRecord(uint16_t C, uint64_t T)
  141. : MetadataRecord(RecordKind::RK_Metadata_NewCPUId,
  142. MetadataType::NewCPUId),
  143. CPUId(C), TSC(T) {}
  144. uint16_t cpuid() const { return CPUId; }
  145. uint64_t tsc() const { return TSC; }
  146. Error apply(RecordVisitor &V) override;
  147. static bool classof(const Record *R) {
  148. return R->getRecordType() == RecordKind::RK_Metadata_NewCPUId;
  149. }
  150. };
  151. class TSCWrapRecord : public MetadataRecord {
  152. uint64_t BaseTSC = 0;
  153. friend class RecordInitializer;
  154. public:
  155. TSCWrapRecord()
  156. : MetadataRecord(RecordKind::RK_Metadata_TSCWrap, MetadataType::TSCWrap) {
  157. }
  158. explicit TSCWrapRecord(uint64_t B)
  159. : MetadataRecord(RecordKind::RK_Metadata_TSCWrap, MetadataType::TSCWrap),
  160. BaseTSC(B) {}
  161. uint64_t tsc() const { return BaseTSC; }
  162. Error apply(RecordVisitor &V) override;
  163. static bool classof(const Record *R) {
  164. return R->getRecordType() == RecordKind::RK_Metadata_TSCWrap;
  165. }
  166. };
  167. class CustomEventRecord : public MetadataRecord {
  168. int32_t Size = 0;
  169. uint64_t TSC = 0;
  170. uint16_t CPU = 0;
  171. std::string Data{};
  172. friend class RecordInitializer;
  173. public:
  174. CustomEventRecord()
  175. : MetadataRecord(RecordKind::RK_Metadata_CustomEvent,
  176. MetadataType::CustomEvent) {}
  177. explicit CustomEventRecord(uint64_t S, uint64_t T, uint16_t C, std::string D)
  178. : MetadataRecord(RecordKind::RK_Metadata_CustomEvent,
  179. MetadataType::CustomEvent),
  180. Size(S), TSC(T), CPU(C), Data(std::move(D)) {}
  181. int32_t size() const { return Size; }
  182. uint64_t tsc() const { return TSC; }
  183. uint16_t cpu() const { return CPU; }
  184. StringRef data() const { return Data; }
  185. Error apply(RecordVisitor &V) override;
  186. static bool classof(const Record *R) {
  187. return R->getRecordType() == RecordKind::RK_Metadata_CustomEvent;
  188. }
  189. };
  190. class CustomEventRecordV5 : public MetadataRecord {
  191. int32_t Size = 0;
  192. int32_t Delta = 0;
  193. std::string Data{};
  194. friend class RecordInitializer;
  195. public:
  196. CustomEventRecordV5()
  197. : MetadataRecord(RecordKind::RK_Metadata_CustomEventV5,
  198. MetadataType::CustomEvent) {}
  199. explicit CustomEventRecordV5(int32_t S, int32_t D, std::string P)
  200. : MetadataRecord(RecordKind::RK_Metadata_CustomEventV5,
  201. MetadataType::CustomEvent),
  202. Size(S), Delta(D), Data(std::move(P)) {}
  203. int32_t size() const { return Size; }
  204. int32_t delta() const { return Delta; }
  205. StringRef data() const { return Data; }
  206. Error apply(RecordVisitor &V) override;
  207. static bool classof(const Record *R) {
  208. return R->getRecordType() == RecordKind::RK_Metadata_CustomEventV5;
  209. }
  210. };
  211. class TypedEventRecord : public MetadataRecord {
  212. int32_t Size = 0;
  213. int32_t Delta = 0;
  214. uint16_t EventType = 0;
  215. std::string Data{};
  216. friend class RecordInitializer;
  217. public:
  218. TypedEventRecord()
  219. : MetadataRecord(RecordKind::RK_Metadata_TypedEvent,
  220. MetadataType::TypedEvent) {}
  221. explicit TypedEventRecord(int32_t S, int32_t D, uint16_t E, std::string P)
  222. : MetadataRecord(RecordKind::RK_Metadata_TypedEvent,
  223. MetadataType::TypedEvent),
  224. Size(S), Delta(D), Data(std::move(P)) {}
  225. int32_t size() const { return Size; }
  226. int32_t delta() const { return Delta; }
  227. uint16_t eventType() const { return EventType; }
  228. StringRef data() const { return Data; }
  229. Error apply(RecordVisitor &V) override;
  230. static bool classof(const Record *R) {
  231. return R->getRecordType() == RecordKind::RK_Metadata_TypedEvent;
  232. }
  233. };
  234. class CallArgRecord : public MetadataRecord {
  235. uint64_t Arg = 0;
  236. friend class RecordInitializer;
  237. public:
  238. CallArgRecord()
  239. : MetadataRecord(RecordKind::RK_Metadata_CallArg, MetadataType::CallArg) {
  240. }
  241. explicit CallArgRecord(uint64_t A)
  242. : MetadataRecord(RecordKind::RK_Metadata_CallArg, MetadataType::CallArg),
  243. Arg(A) {}
  244. uint64_t arg() const { return Arg; }
  245. Error apply(RecordVisitor &V) override;
  246. static bool classof(const Record *R) {
  247. return R->getRecordType() == RecordKind::RK_Metadata_CallArg;
  248. }
  249. };
  250. class PIDRecord : public MetadataRecord {
  251. int32_t PID = 0;
  252. friend class RecordInitializer;
  253. public:
  254. PIDRecord()
  255. : MetadataRecord(RecordKind::RK_Metadata_PIDEntry,
  256. MetadataType::PIDEntry) {}
  257. explicit PIDRecord(int32_t P)
  258. : MetadataRecord(RecordKind::RK_Metadata_PIDEntry,
  259. MetadataType::PIDEntry),
  260. PID(P) {}
  261. int32_t pid() const { return PID; }
  262. Error apply(RecordVisitor &V) override;
  263. static bool classof(const Record *R) {
  264. return R->getRecordType() == RecordKind::RK_Metadata_PIDEntry;
  265. }
  266. };
  267. class NewBufferRecord : public MetadataRecord {
  268. int32_t TID = 0;
  269. friend class RecordInitializer;
  270. public:
  271. NewBufferRecord()
  272. : MetadataRecord(RecordKind::RK_Metadata_NewBuffer,
  273. MetadataType::NewBuffer) {}
  274. explicit NewBufferRecord(int32_t T)
  275. : MetadataRecord(RecordKind::RK_Metadata_NewBuffer,
  276. MetadataType::NewBuffer),
  277. TID(T) {}
  278. int32_t tid() const { return TID; }
  279. Error apply(RecordVisitor &V) override;
  280. static bool classof(const Record *R) {
  281. return R->getRecordType() == RecordKind::RK_Metadata_NewBuffer;
  282. }
  283. };
  284. class EndBufferRecord : public MetadataRecord {
  285. public:
  286. EndBufferRecord()
  287. : MetadataRecord(RecordKind::RK_Metadata_EndOfBuffer,
  288. MetadataType::EndOfBuffer) {}
  289. Error apply(RecordVisitor &V) override;
  290. static bool classof(const Record *R) {
  291. return R->getRecordType() == RecordKind::RK_Metadata_EndOfBuffer;
  292. }
  293. };
  294. class FunctionRecord : public Record {
  295. RecordTypes Kind;
  296. int32_t FuncId = 0;
  297. uint32_t Delta = 0;
  298. friend class RecordInitializer;
  299. static constexpr unsigned kFunctionRecordSize = 8;
  300. public:
  301. FunctionRecord() : Record(RecordKind::RK_Function) {}
  302. explicit FunctionRecord(RecordTypes K, int32_t F, uint32_t D)
  303. : Record(RecordKind::RK_Function), Kind(K), FuncId(F), Delta(D) {}
  304. // A function record is a concrete record type which has a number of common
  305. // properties.
  306. RecordTypes recordType() const { return Kind; }
  307. int32_t functionId() const { return FuncId; }
  308. uint32_t delta() const { return Delta; }
  309. Error apply(RecordVisitor &V) override;
  310. static bool classof(const Record *R) {
  311. return R->getRecordType() == RecordKind::RK_Function;
  312. }
  313. };
  314. class RecordVisitor {
  315. public:
  316. virtual ~RecordVisitor() = default;
  317. // Support all specific kinds of records:
  318. virtual Error visit(BufferExtents &) = 0;
  319. virtual Error visit(WallclockRecord &) = 0;
  320. virtual Error visit(NewCPUIDRecord &) = 0;
  321. virtual Error visit(TSCWrapRecord &) = 0;
  322. virtual Error visit(CustomEventRecord &) = 0;
  323. virtual Error visit(CallArgRecord &) = 0;
  324. virtual Error visit(PIDRecord &) = 0;
  325. virtual Error visit(NewBufferRecord &) = 0;
  326. virtual Error visit(EndBufferRecord &) = 0;
  327. virtual Error visit(FunctionRecord &) = 0;
  328. virtual Error visit(CustomEventRecordV5 &) = 0;
  329. virtual Error visit(TypedEventRecord &) = 0;
  330. };
  331. class RecordInitializer : public RecordVisitor {
  332. DataExtractor &E;
  333. uint64_t &OffsetPtr;
  334. uint16_t Version;
  335. public:
  336. static constexpr uint16_t DefaultVersion = 5u;
  337. explicit RecordInitializer(DataExtractor &DE, uint64_t &OP, uint16_t V)
  338. : RecordVisitor(), E(DE), OffsetPtr(OP), Version(V) {}
  339. explicit RecordInitializer(DataExtractor &DE, uint64_t &OP)
  340. : RecordInitializer(DE, OP, DefaultVersion) {}
  341. Error visit(BufferExtents &) override;
  342. Error visit(WallclockRecord &) override;
  343. Error visit(NewCPUIDRecord &) override;
  344. Error visit(TSCWrapRecord &) override;
  345. Error visit(CustomEventRecord &) override;
  346. Error visit(CallArgRecord &) override;
  347. Error visit(PIDRecord &) override;
  348. Error visit(NewBufferRecord &) override;
  349. Error visit(EndBufferRecord &) override;
  350. Error visit(FunctionRecord &) override;
  351. Error visit(CustomEventRecordV5 &) override;
  352. Error visit(TypedEventRecord &) override;
  353. };
  354. } // namespace xray
  355. } // namespace llvm
  356. #endif // LLVM_LIB_XRAY_FDRRECORDS_H_
  357. #ifdef __GNUC__
  358. #pragma GCC diagnostic pop
  359. #endif