FDRRecords.h revision 343210
1//===- FDRRecords.h - XRay Flight Data Recorder Mode Records --------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Define types and operations on these types that represent the different kinds 11// of records we encounter in XRay flight data recorder mode traces. 12// 13//===----------------------------------------------------------------------===// 14#ifndef LLVM_LIB_XRAY_FDRRECORDS_H_ 15#define LLVM_LIB_XRAY_FDRRECORDS_H_ 16 17#include <cstdint> 18#include <string> 19 20#include "llvm/ADT/StringRef.h" 21#include "llvm/Support/Casting.h" 22#include "llvm/Support/DataExtractor.h" 23#include "llvm/Support/Error.h" 24#include "llvm/XRay/XRayRecord.h" 25 26namespace llvm { 27namespace xray { 28 29class RecordVisitor; 30class RecordInitializer; 31 32class Record { 33public: 34 enum class RecordKind { 35 RK_Metadata, 36 RK_Metadata_BufferExtents, 37 RK_Metadata_WallClockTime, 38 RK_Metadata_NewCPUId, 39 RK_Metadata_TSCWrap, 40 RK_Metadata_CustomEvent, 41 RK_Metadata_CustomEventV5, 42 RK_Metadata_CallArg, 43 RK_Metadata_PIDEntry, 44 RK_Metadata_NewBuffer, 45 RK_Metadata_EndOfBuffer, 46 RK_Metadata_TypedEvent, 47 RK_Metadata_LastMetadata, 48 RK_Function, 49 }; 50 51 static StringRef kindToString(RecordKind K); 52 53private: 54 const RecordKind T; 55 56public: 57 Record(const Record &) = delete; 58 Record(Record &&) = delete; 59 Record &operator=(const Record &) = delete; 60 Record &operator=(Record &&) = delete; 61 explicit Record(RecordKind T) : T(T) {} 62 63 RecordKind getRecordType() const { return T; } 64 65 // Each Record should be able to apply an abstract visitor, and choose the 66 // appropriate function in the visitor to invoke, given its own type. 67 virtual Error apply(RecordVisitor &V) = 0; 68 69 virtual ~Record() = default; 70}; 71 72class MetadataRecord : public Record { 73public: 74 enum class MetadataType : unsigned { 75 Unknown, 76 BufferExtents, 77 WallClockTime, 78 NewCPUId, 79 TSCWrap, 80 CustomEvent, 81 CallArg, 82 PIDEntry, 83 NewBuffer, 84 EndOfBuffer, 85 TypedEvent, 86 }; 87 88protected: 89 static constexpr int kMetadataBodySize = 15; 90 friend class RecordInitializer; 91 92private: 93 const MetadataType MT; 94 95public: 96 explicit MetadataRecord(RecordKind T, MetadataType M) : Record(T), MT(M) {} 97 98 static bool classof(const Record *R) { 99 return R->getRecordType() >= RecordKind::RK_Metadata && 100 R->getRecordType() <= RecordKind::RK_Metadata_LastMetadata; 101 } 102 103 MetadataType metadataType() const { return MT; } 104 105 virtual ~MetadataRecord() = default; 106}; 107 108// What follows are specific Metadata record types which encapsulate the 109// information associated with specific metadata record types in an FDR mode 110// log. 111class BufferExtents : public MetadataRecord { 112 uint64_t Size = 0; 113 friend class RecordInitializer; 114 115public: 116 BufferExtents() 117 : MetadataRecord(RecordKind::RK_Metadata_BufferExtents, 118 MetadataType::BufferExtents) {} 119 120 explicit BufferExtents(uint64_t S) 121 : MetadataRecord(RecordKind::RK_Metadata_BufferExtents, 122 MetadataType::BufferExtents), 123 Size(S) {} 124 125 uint64_t size() const { return Size; } 126 127 Error apply(RecordVisitor &V) override; 128 129 static bool classof(const Record *R) { 130 return R->getRecordType() == RecordKind::RK_Metadata_BufferExtents; 131 } 132}; 133 134class WallclockRecord : public MetadataRecord { 135 uint64_t Seconds = 0; 136 uint32_t Nanos = 0; 137 friend class RecordInitializer; 138 139public: 140 WallclockRecord() 141 : MetadataRecord(RecordKind::RK_Metadata_WallClockTime, 142 MetadataType::WallClockTime) {} 143 144 explicit WallclockRecord(uint64_t S, uint32_t N) 145 : MetadataRecord(RecordKind::RK_Metadata_WallClockTime, 146 MetadataType::WallClockTime), 147 Seconds(S), Nanos(N) {} 148 149 uint64_t seconds() const { return Seconds; } 150 uint32_t nanos() const { return Nanos; } 151 152 Error apply(RecordVisitor &V) override; 153 154 static bool classof(const Record *R) { 155 return R->getRecordType() == RecordKind::RK_Metadata_WallClockTime; 156 } 157}; 158 159class NewCPUIDRecord : public MetadataRecord { 160 uint16_t CPUId = 0; 161 uint64_t TSC = 0; 162 friend class RecordInitializer; 163 164public: 165 NewCPUIDRecord() 166 : MetadataRecord(RecordKind::RK_Metadata_NewCPUId, 167 MetadataType::NewCPUId) {} 168 169 NewCPUIDRecord(uint16_t C, uint64_t T) 170 : MetadataRecord(RecordKind::RK_Metadata_NewCPUId, 171 MetadataType::NewCPUId), 172 CPUId(C), TSC(T) {} 173 174 uint16_t cpuid() const { return CPUId; } 175 176 uint64_t tsc() const { return TSC; } 177 178 Error apply(RecordVisitor &V) override; 179 180 static bool classof(const Record *R) { 181 return R->getRecordType() == RecordKind::RK_Metadata_NewCPUId; 182 } 183}; 184 185class TSCWrapRecord : public MetadataRecord { 186 uint64_t BaseTSC = 0; 187 friend class RecordInitializer; 188 189public: 190 TSCWrapRecord() 191 : MetadataRecord(RecordKind::RK_Metadata_TSCWrap, MetadataType::TSCWrap) { 192 } 193 194 explicit TSCWrapRecord(uint64_t B) 195 : MetadataRecord(RecordKind::RK_Metadata_TSCWrap, MetadataType::TSCWrap), 196 BaseTSC(B) {} 197 198 uint64_t tsc() const { return BaseTSC; } 199 200 Error apply(RecordVisitor &V) override; 201 202 static bool classof(const Record *R) { 203 return R->getRecordType() == RecordKind::RK_Metadata_TSCWrap; 204 } 205}; 206 207class CustomEventRecord : public MetadataRecord { 208 int32_t Size = 0; 209 uint64_t TSC = 0; 210 uint16_t CPU = 0; 211 std::string Data{}; 212 friend class RecordInitializer; 213 214public: 215 CustomEventRecord() 216 : MetadataRecord(RecordKind::RK_Metadata_CustomEvent, 217 MetadataType::CustomEvent) {} 218 219 explicit CustomEventRecord(uint64_t S, uint64_t T, uint16_t C, std::string D) 220 : MetadataRecord(RecordKind::RK_Metadata_CustomEvent, 221 MetadataType::CustomEvent), 222 Size(S), TSC(T), CPU(C), Data(std::move(D)) {} 223 224 int32_t size() const { return Size; } 225 uint64_t tsc() const { return TSC; } 226 uint16_t cpu() const { return CPU; } 227 StringRef data() const { return Data; } 228 229 Error apply(RecordVisitor &V) override; 230 231 static bool classof(const Record *R) { 232 return R->getRecordType() == RecordKind::RK_Metadata_CustomEvent; 233 } 234}; 235 236class CustomEventRecordV5 : public MetadataRecord { 237 int32_t Size = 0; 238 int32_t Delta = 0; 239 std::string Data{}; 240 friend class RecordInitializer; 241 242public: 243 CustomEventRecordV5() 244 : MetadataRecord(RecordKind::RK_Metadata_CustomEventV5, 245 MetadataType::CustomEvent) {} 246 247 explicit CustomEventRecordV5(int32_t S, int32_t D, std::string P) 248 : MetadataRecord(RecordKind::RK_Metadata_CustomEventV5, 249 MetadataType::CustomEvent), 250 Size(S), Delta(D), Data(std::move(P)) {} 251 252 int32_t size() const { return Size; } 253 int32_t delta() const { return Delta; } 254 StringRef data() const { return Data; } 255 256 Error apply(RecordVisitor &V) override; 257 258 static bool classof(const Record *R) { 259 return R->getRecordType() == RecordKind::RK_Metadata_CustomEventV5; 260 } 261}; 262 263class TypedEventRecord : public MetadataRecord { 264 int32_t Size = 0; 265 int32_t Delta = 0; 266 uint16_t EventType = 0; 267 std::string Data{}; 268 friend class RecordInitializer; 269 270public: 271 TypedEventRecord() 272 : MetadataRecord(RecordKind::RK_Metadata_TypedEvent, 273 MetadataType::TypedEvent) {} 274 275 explicit TypedEventRecord(int32_t S, int32_t D, uint16_t E, std::string P) 276 : MetadataRecord(RecordKind::RK_Metadata_TypedEvent, 277 MetadataType::TypedEvent), 278 Size(S), Delta(D), Data(std::move(P)) {} 279 280 int32_t size() const { return Size; } 281 int32_t delta() const { return Delta; } 282 uint16_t eventType() const { return EventType; } 283 StringRef data() const { return Data; } 284 285 Error apply(RecordVisitor &V) override; 286 287 static bool classof(const Record *R) { 288 return R->getRecordType() == RecordKind::RK_Metadata_TypedEvent; 289 } 290}; 291 292class CallArgRecord : public MetadataRecord { 293 uint64_t Arg; 294 friend class RecordInitializer; 295 296public: 297 CallArgRecord() 298 : MetadataRecord(RecordKind::RK_Metadata_CallArg, MetadataType::CallArg) { 299 } 300 301 explicit CallArgRecord(uint64_t A) 302 : MetadataRecord(RecordKind::RK_Metadata_CallArg, MetadataType::CallArg), 303 Arg(A) {} 304 305 uint64_t arg() const { return Arg; } 306 307 Error apply(RecordVisitor &V) override; 308 309 static bool classof(const Record *R) { 310 return R->getRecordType() == RecordKind::RK_Metadata_CallArg; 311 } 312}; 313 314class PIDRecord : public MetadataRecord { 315 int32_t PID = 0; 316 friend class RecordInitializer; 317 318public: 319 PIDRecord() 320 : MetadataRecord(RecordKind::RK_Metadata_PIDEntry, 321 MetadataType::PIDEntry) {} 322 323 explicit PIDRecord(int32_t P) 324 : MetadataRecord(RecordKind::RK_Metadata_PIDEntry, 325 MetadataType::PIDEntry), 326 PID(P) {} 327 328 int32_t pid() const { return PID; } 329 330 Error apply(RecordVisitor &V) override; 331 332 static bool classof(const Record *R) { 333 return R->getRecordType() == RecordKind::RK_Metadata_PIDEntry; 334 } 335}; 336 337class NewBufferRecord : public MetadataRecord { 338 int32_t TID = 0; 339 friend class RecordInitializer; 340 341public: 342 NewBufferRecord() 343 : MetadataRecord(RecordKind::RK_Metadata_NewBuffer, 344 MetadataType::NewBuffer) {} 345 346 explicit NewBufferRecord(int32_t T) 347 : MetadataRecord(RecordKind::RK_Metadata_NewBuffer, 348 MetadataType::NewBuffer), 349 TID(T) {} 350 351 int32_t tid() const { return TID; } 352 353 Error apply(RecordVisitor &V) override; 354 355 static bool classof(const Record *R) { 356 return R->getRecordType() == RecordKind::RK_Metadata_NewBuffer; 357 } 358}; 359 360class EndBufferRecord : public MetadataRecord { 361public: 362 EndBufferRecord() 363 : MetadataRecord(RecordKind::RK_Metadata_EndOfBuffer, 364 MetadataType::EndOfBuffer) {} 365 366 Error apply(RecordVisitor &V) override; 367 368 static bool classof(const Record *R) { 369 return R->getRecordType() == RecordKind::RK_Metadata_EndOfBuffer; 370 } 371}; 372 373class FunctionRecord : public Record { 374 RecordTypes Kind; 375 int32_t FuncId; 376 uint32_t Delta; 377 friend class RecordInitializer; 378 379 static constexpr unsigned kFunctionRecordSize = 8; 380 381public: 382 FunctionRecord() : Record(RecordKind::RK_Function) {} 383 384 explicit FunctionRecord(RecordTypes K, int32_t F, uint32_t D) 385 : Record(RecordKind::RK_Function), Kind(K), FuncId(F), Delta(D) {} 386 387 // A function record is a concrete record type which has a number of common 388 // properties. 389 RecordTypes recordType() const { return Kind; } 390 int32_t functionId() const { return FuncId; } 391 uint32_t delta() const { return Delta; } 392 393 Error apply(RecordVisitor &V) override; 394 395 static bool classof(const Record *R) { 396 return R->getRecordType() == RecordKind::RK_Function; 397 } 398}; 399 400class RecordVisitor { 401public: 402 virtual ~RecordVisitor() = default; 403 404 // Support all specific kinds of records: 405 virtual Error visit(BufferExtents &) = 0; 406 virtual Error visit(WallclockRecord &) = 0; 407 virtual Error visit(NewCPUIDRecord &) = 0; 408 virtual Error visit(TSCWrapRecord &) = 0; 409 virtual Error visit(CustomEventRecord &) = 0; 410 virtual Error visit(CallArgRecord &) = 0; 411 virtual Error visit(PIDRecord &) = 0; 412 virtual Error visit(NewBufferRecord &) = 0; 413 virtual Error visit(EndBufferRecord &) = 0; 414 virtual Error visit(FunctionRecord &) = 0; 415 virtual Error visit(CustomEventRecordV5 &) = 0; 416 virtual Error visit(TypedEventRecord &) = 0; 417}; 418 419class RecordInitializer : public RecordVisitor { 420 DataExtractor &E; 421 uint32_t &OffsetPtr; 422 uint16_t Version; 423 424public: 425 static constexpr uint16_t DefaultVersion = 5u; 426 427 explicit RecordInitializer(DataExtractor &DE, uint32_t &OP, uint16_t V) 428 : RecordVisitor(), E(DE), OffsetPtr(OP), Version(V) {} 429 430 explicit RecordInitializer(DataExtractor &DE, uint32_t &OP) 431 : RecordInitializer(DE, OP, DefaultVersion) {} 432 433 Error visit(BufferExtents &) override; 434 Error visit(WallclockRecord &) override; 435 Error visit(NewCPUIDRecord &) override; 436 Error visit(TSCWrapRecord &) override; 437 Error visit(CustomEventRecord &) override; 438 Error visit(CallArgRecord &) override; 439 Error visit(PIDRecord &) override; 440 Error visit(NewBufferRecord &) override; 441 Error visit(EndBufferRecord &) override; 442 Error visit(FunctionRecord &) override; 443 Error visit(CustomEventRecordV5 &) override; 444 Error visit(TypedEventRecord &) override; 445}; 446 447} // namespace xray 448} // namespace llvm 449 450#endif // LLVM_LIB_XRAY_FDRRECORDS_H_ 451