mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
c92524272b
Identified with llvm-header-guard.
450 lines
12 KiB
C++
450 lines
12 KiB
C++
//===- FDRRecords.h - XRay Flight Data Recorder Mode Records --------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Define types and operations on these types that represent the different kinds
|
|
// of records we encounter in XRay flight data recorder mode traces.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#ifndef LLVM_XRAY_FDRRECORDS_H
|
|
#define LLVM_XRAY_FDRRECORDS_H
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/Support/Casting.h"
|
|
#include "llvm/Support/DataExtractor.h"
|
|
#include "llvm/Support/Error.h"
|
|
#include "llvm/XRay/XRayRecord.h"
|
|
|
|
namespace llvm {
|
|
namespace xray {
|
|
|
|
class RecordVisitor;
|
|
class RecordInitializer;
|
|
|
|
class Record {
|
|
public:
|
|
enum class RecordKind {
|
|
RK_Metadata,
|
|
RK_Metadata_BufferExtents,
|
|
RK_Metadata_WallClockTime,
|
|
RK_Metadata_NewCPUId,
|
|
RK_Metadata_TSCWrap,
|
|
RK_Metadata_CustomEvent,
|
|
RK_Metadata_CustomEventV5,
|
|
RK_Metadata_CallArg,
|
|
RK_Metadata_PIDEntry,
|
|
RK_Metadata_NewBuffer,
|
|
RK_Metadata_EndOfBuffer,
|
|
RK_Metadata_TypedEvent,
|
|
RK_Metadata_LastMetadata,
|
|
RK_Function,
|
|
};
|
|
|
|
static StringRef kindToString(RecordKind K);
|
|
|
|
private:
|
|
const RecordKind T;
|
|
|
|
public:
|
|
Record(const Record &) = delete;
|
|
Record(Record &&) = delete;
|
|
Record &operator=(const Record &) = delete;
|
|
Record &operator=(Record &&) = delete;
|
|
explicit Record(RecordKind T) : T(T) {}
|
|
|
|
RecordKind getRecordType() const { return T; }
|
|
|
|
// Each Record should be able to apply an abstract visitor, and choose the
|
|
// appropriate function in the visitor to invoke, given its own type.
|
|
virtual Error apply(RecordVisitor &V) = 0;
|
|
|
|
virtual ~Record() = default;
|
|
};
|
|
|
|
class MetadataRecord : public Record {
|
|
public:
|
|
enum class MetadataType : unsigned {
|
|
Unknown,
|
|
BufferExtents,
|
|
WallClockTime,
|
|
NewCPUId,
|
|
TSCWrap,
|
|
CustomEvent,
|
|
CallArg,
|
|
PIDEntry,
|
|
NewBuffer,
|
|
EndOfBuffer,
|
|
TypedEvent,
|
|
};
|
|
|
|
protected:
|
|
static constexpr int kMetadataBodySize = 15;
|
|
friend class RecordInitializer;
|
|
|
|
private:
|
|
const MetadataType MT;
|
|
|
|
public:
|
|
explicit MetadataRecord(RecordKind T, MetadataType M) : Record(T), MT(M) {}
|
|
|
|
static bool classof(const Record *R) {
|
|
return R->getRecordType() >= RecordKind::RK_Metadata &&
|
|
R->getRecordType() <= RecordKind::RK_Metadata_LastMetadata;
|
|
}
|
|
|
|
MetadataType metadataType() const { return MT; }
|
|
|
|
virtual ~MetadataRecord() = default;
|
|
};
|
|
|
|
// What follows are specific Metadata record types which encapsulate the
|
|
// information associated with specific metadata record types in an FDR mode
|
|
// log.
|
|
class BufferExtents : public MetadataRecord {
|
|
uint64_t Size = 0;
|
|
friend class RecordInitializer;
|
|
|
|
public:
|
|
BufferExtents()
|
|
: MetadataRecord(RecordKind::RK_Metadata_BufferExtents,
|
|
MetadataType::BufferExtents) {}
|
|
|
|
explicit BufferExtents(uint64_t S)
|
|
: MetadataRecord(RecordKind::RK_Metadata_BufferExtents,
|
|
MetadataType::BufferExtents),
|
|
Size(S) {}
|
|
|
|
uint64_t size() const { return Size; }
|
|
|
|
Error apply(RecordVisitor &V) override;
|
|
|
|
static bool classof(const Record *R) {
|
|
return R->getRecordType() == RecordKind::RK_Metadata_BufferExtents;
|
|
}
|
|
};
|
|
|
|
class WallclockRecord : public MetadataRecord {
|
|
uint64_t Seconds = 0;
|
|
uint32_t Nanos = 0;
|
|
friend class RecordInitializer;
|
|
|
|
public:
|
|
WallclockRecord()
|
|
: MetadataRecord(RecordKind::RK_Metadata_WallClockTime,
|
|
MetadataType::WallClockTime) {}
|
|
|
|
explicit WallclockRecord(uint64_t S, uint32_t N)
|
|
: MetadataRecord(RecordKind::RK_Metadata_WallClockTime,
|
|
MetadataType::WallClockTime),
|
|
Seconds(S), Nanos(N) {}
|
|
|
|
uint64_t seconds() const { return Seconds; }
|
|
uint32_t nanos() const { return Nanos; }
|
|
|
|
Error apply(RecordVisitor &V) override;
|
|
|
|
static bool classof(const Record *R) {
|
|
return R->getRecordType() == RecordKind::RK_Metadata_WallClockTime;
|
|
}
|
|
};
|
|
|
|
class NewCPUIDRecord : public MetadataRecord {
|
|
uint16_t CPUId = 0;
|
|
uint64_t TSC = 0;
|
|
friend class RecordInitializer;
|
|
|
|
public:
|
|
NewCPUIDRecord()
|
|
: MetadataRecord(RecordKind::RK_Metadata_NewCPUId,
|
|
MetadataType::NewCPUId) {}
|
|
|
|
NewCPUIDRecord(uint16_t C, uint64_t T)
|
|
: MetadataRecord(RecordKind::RK_Metadata_NewCPUId,
|
|
MetadataType::NewCPUId),
|
|
CPUId(C), TSC(T) {}
|
|
|
|
uint16_t cpuid() const { return CPUId; }
|
|
|
|
uint64_t tsc() const { return TSC; }
|
|
|
|
Error apply(RecordVisitor &V) override;
|
|
|
|
static bool classof(const Record *R) {
|
|
return R->getRecordType() == RecordKind::RK_Metadata_NewCPUId;
|
|
}
|
|
};
|
|
|
|
class TSCWrapRecord : public MetadataRecord {
|
|
uint64_t BaseTSC = 0;
|
|
friend class RecordInitializer;
|
|
|
|
public:
|
|
TSCWrapRecord()
|
|
: MetadataRecord(RecordKind::RK_Metadata_TSCWrap, MetadataType::TSCWrap) {
|
|
}
|
|
|
|
explicit TSCWrapRecord(uint64_t B)
|
|
: MetadataRecord(RecordKind::RK_Metadata_TSCWrap, MetadataType::TSCWrap),
|
|
BaseTSC(B) {}
|
|
|
|
uint64_t tsc() const { return BaseTSC; }
|
|
|
|
Error apply(RecordVisitor &V) override;
|
|
|
|
static bool classof(const Record *R) {
|
|
return R->getRecordType() == RecordKind::RK_Metadata_TSCWrap;
|
|
}
|
|
};
|
|
|
|
class CustomEventRecord : public MetadataRecord {
|
|
int32_t Size = 0;
|
|
uint64_t TSC = 0;
|
|
uint16_t CPU = 0;
|
|
std::string Data{};
|
|
friend class RecordInitializer;
|
|
|
|
public:
|
|
CustomEventRecord()
|
|
: MetadataRecord(RecordKind::RK_Metadata_CustomEvent,
|
|
MetadataType::CustomEvent) {}
|
|
|
|
explicit CustomEventRecord(uint64_t S, uint64_t T, uint16_t C, std::string D)
|
|
: MetadataRecord(RecordKind::RK_Metadata_CustomEvent,
|
|
MetadataType::CustomEvent),
|
|
Size(S), TSC(T), CPU(C), Data(std::move(D)) {}
|
|
|
|
int32_t size() const { return Size; }
|
|
uint64_t tsc() const { return TSC; }
|
|
uint16_t cpu() const { return CPU; }
|
|
StringRef data() const { return Data; }
|
|
|
|
Error apply(RecordVisitor &V) override;
|
|
|
|
static bool classof(const Record *R) {
|
|
return R->getRecordType() == RecordKind::RK_Metadata_CustomEvent;
|
|
}
|
|
};
|
|
|
|
class CustomEventRecordV5 : public MetadataRecord {
|
|
int32_t Size = 0;
|
|
int32_t Delta = 0;
|
|
std::string Data{};
|
|
friend class RecordInitializer;
|
|
|
|
public:
|
|
CustomEventRecordV5()
|
|
: MetadataRecord(RecordKind::RK_Metadata_CustomEventV5,
|
|
MetadataType::CustomEvent) {}
|
|
|
|
explicit CustomEventRecordV5(int32_t S, int32_t D, std::string P)
|
|
: MetadataRecord(RecordKind::RK_Metadata_CustomEventV5,
|
|
MetadataType::CustomEvent),
|
|
Size(S), Delta(D), Data(std::move(P)) {}
|
|
|
|
int32_t size() const { return Size; }
|
|
int32_t delta() const { return Delta; }
|
|
StringRef data() const { return Data; }
|
|
|
|
Error apply(RecordVisitor &V) override;
|
|
|
|
static bool classof(const Record *R) {
|
|
return R->getRecordType() == RecordKind::RK_Metadata_CustomEventV5;
|
|
}
|
|
};
|
|
|
|
class TypedEventRecord : public MetadataRecord {
|
|
int32_t Size = 0;
|
|
int32_t Delta = 0;
|
|
uint16_t EventType = 0;
|
|
std::string Data{};
|
|
friend class RecordInitializer;
|
|
|
|
public:
|
|
TypedEventRecord()
|
|
: MetadataRecord(RecordKind::RK_Metadata_TypedEvent,
|
|
MetadataType::TypedEvent) {}
|
|
|
|
explicit TypedEventRecord(int32_t S, int32_t D, uint16_t E, std::string P)
|
|
: MetadataRecord(RecordKind::RK_Metadata_TypedEvent,
|
|
MetadataType::TypedEvent),
|
|
Size(S), Delta(D), Data(std::move(P)) {}
|
|
|
|
int32_t size() const { return Size; }
|
|
int32_t delta() const { return Delta; }
|
|
uint16_t eventType() const { return EventType; }
|
|
StringRef data() const { return Data; }
|
|
|
|
Error apply(RecordVisitor &V) override;
|
|
|
|
static bool classof(const Record *R) {
|
|
return R->getRecordType() == RecordKind::RK_Metadata_TypedEvent;
|
|
}
|
|
};
|
|
|
|
class CallArgRecord : public MetadataRecord {
|
|
uint64_t Arg = 0;
|
|
friend class RecordInitializer;
|
|
|
|
public:
|
|
CallArgRecord()
|
|
: MetadataRecord(RecordKind::RK_Metadata_CallArg, MetadataType::CallArg) {
|
|
}
|
|
|
|
explicit CallArgRecord(uint64_t A)
|
|
: MetadataRecord(RecordKind::RK_Metadata_CallArg, MetadataType::CallArg),
|
|
Arg(A) {}
|
|
|
|
uint64_t arg() const { return Arg; }
|
|
|
|
Error apply(RecordVisitor &V) override;
|
|
|
|
static bool classof(const Record *R) {
|
|
return R->getRecordType() == RecordKind::RK_Metadata_CallArg;
|
|
}
|
|
};
|
|
|
|
class PIDRecord : public MetadataRecord {
|
|
int32_t PID = 0;
|
|
friend class RecordInitializer;
|
|
|
|
public:
|
|
PIDRecord()
|
|
: MetadataRecord(RecordKind::RK_Metadata_PIDEntry,
|
|
MetadataType::PIDEntry) {}
|
|
|
|
explicit PIDRecord(int32_t P)
|
|
: MetadataRecord(RecordKind::RK_Metadata_PIDEntry,
|
|
MetadataType::PIDEntry),
|
|
PID(P) {}
|
|
|
|
int32_t pid() const { return PID; }
|
|
|
|
Error apply(RecordVisitor &V) override;
|
|
|
|
static bool classof(const Record *R) {
|
|
return R->getRecordType() == RecordKind::RK_Metadata_PIDEntry;
|
|
}
|
|
};
|
|
|
|
class NewBufferRecord : public MetadataRecord {
|
|
int32_t TID = 0;
|
|
friend class RecordInitializer;
|
|
|
|
public:
|
|
NewBufferRecord()
|
|
: MetadataRecord(RecordKind::RK_Metadata_NewBuffer,
|
|
MetadataType::NewBuffer) {}
|
|
|
|
explicit NewBufferRecord(int32_t T)
|
|
: MetadataRecord(RecordKind::RK_Metadata_NewBuffer,
|
|
MetadataType::NewBuffer),
|
|
TID(T) {}
|
|
|
|
int32_t tid() const { return TID; }
|
|
|
|
Error apply(RecordVisitor &V) override;
|
|
|
|
static bool classof(const Record *R) {
|
|
return R->getRecordType() == RecordKind::RK_Metadata_NewBuffer;
|
|
}
|
|
};
|
|
|
|
class EndBufferRecord : public MetadataRecord {
|
|
public:
|
|
EndBufferRecord()
|
|
: MetadataRecord(RecordKind::RK_Metadata_EndOfBuffer,
|
|
MetadataType::EndOfBuffer) {}
|
|
|
|
Error apply(RecordVisitor &V) override;
|
|
|
|
static bool classof(const Record *R) {
|
|
return R->getRecordType() == RecordKind::RK_Metadata_EndOfBuffer;
|
|
}
|
|
};
|
|
|
|
class FunctionRecord : public Record {
|
|
RecordTypes Kind;
|
|
int32_t FuncId = 0;
|
|
uint32_t Delta = 0;
|
|
friend class RecordInitializer;
|
|
|
|
static constexpr unsigned kFunctionRecordSize = 8;
|
|
|
|
public:
|
|
FunctionRecord() : Record(RecordKind::RK_Function) {}
|
|
|
|
explicit FunctionRecord(RecordTypes K, int32_t F, uint32_t D)
|
|
: Record(RecordKind::RK_Function), Kind(K), FuncId(F), Delta(D) {}
|
|
|
|
// A function record is a concrete record type which has a number of common
|
|
// properties.
|
|
RecordTypes recordType() const { return Kind; }
|
|
int32_t functionId() const { return FuncId; }
|
|
uint32_t delta() const { return Delta; }
|
|
|
|
Error apply(RecordVisitor &V) override;
|
|
|
|
static bool classof(const Record *R) {
|
|
return R->getRecordType() == RecordKind::RK_Function;
|
|
}
|
|
};
|
|
|
|
class RecordVisitor {
|
|
public:
|
|
virtual ~RecordVisitor() = default;
|
|
|
|
// Support all specific kinds of records:
|
|
virtual Error visit(BufferExtents &) = 0;
|
|
virtual Error visit(WallclockRecord &) = 0;
|
|
virtual Error visit(NewCPUIDRecord &) = 0;
|
|
virtual Error visit(TSCWrapRecord &) = 0;
|
|
virtual Error visit(CustomEventRecord &) = 0;
|
|
virtual Error visit(CallArgRecord &) = 0;
|
|
virtual Error visit(PIDRecord &) = 0;
|
|
virtual Error visit(NewBufferRecord &) = 0;
|
|
virtual Error visit(EndBufferRecord &) = 0;
|
|
virtual Error visit(FunctionRecord &) = 0;
|
|
virtual Error visit(CustomEventRecordV5 &) = 0;
|
|
virtual Error visit(TypedEventRecord &) = 0;
|
|
};
|
|
|
|
class RecordInitializer : public RecordVisitor {
|
|
DataExtractor &E;
|
|
uint64_t &OffsetPtr;
|
|
uint16_t Version;
|
|
|
|
public:
|
|
static constexpr uint16_t DefaultVersion = 5u;
|
|
|
|
explicit RecordInitializer(DataExtractor &DE, uint64_t &OP, uint16_t V)
|
|
: RecordVisitor(), E(DE), OffsetPtr(OP), Version(V) {}
|
|
|
|
explicit RecordInitializer(DataExtractor &DE, uint64_t &OP)
|
|
: RecordInitializer(DE, OP, DefaultVersion) {}
|
|
|
|
Error visit(BufferExtents &) override;
|
|
Error visit(WallclockRecord &) override;
|
|
Error visit(NewCPUIDRecord &) override;
|
|
Error visit(TSCWrapRecord &) override;
|
|
Error visit(CustomEventRecord &) override;
|
|
Error visit(CallArgRecord &) override;
|
|
Error visit(PIDRecord &) override;
|
|
Error visit(NewBufferRecord &) override;
|
|
Error visit(EndBufferRecord &) override;
|
|
Error visit(FunctionRecord &) override;
|
|
Error visit(CustomEventRecordV5 &) override;
|
|
Error visit(TypedEventRecord &) override;
|
|
};
|
|
|
|
} // namespace xray
|
|
} // namespace llvm
|
|
|
|
#endif // LLVM_XRAY_FDRRECORDS_H
|