File indexing completed on 2026-05-10 08:44:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_PROFILEDATA_MEMPROFREADER_H_
0014 #define LLVM_PROFILEDATA_MEMPROFREADER_H_
0015
0016 #include "llvm/ADT/DenseMap.h"
0017 #include "llvm/ADT/MapVector.h"
0018 #include "llvm/ADT/StringRef.h"
0019 #include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
0020 #include "llvm/DebugInfo/Symbolize/Symbolize.h"
0021 #include "llvm/IR/GlobalValue.h"
0022 #include "llvm/Object/Binary.h"
0023 #include "llvm/Object/ObjectFile.h"
0024 #include "llvm/ProfileData/InstrProfReader.h"
0025 #include "llvm/ProfileData/MemProf.h"
0026 #include "llvm/ProfileData/MemProfData.inc"
0027 #include "llvm/Support/Error.h"
0028 #include "llvm/Support/MemoryBuffer.h"
0029
0030 #include <functional>
0031
0032 namespace llvm {
0033 namespace memprof {
0034
0035
0036 class MemProfReader {
0037 public:
0038
0039 InstrProfKind getProfileKind() const { return InstrProfKind::MemProf; }
0040
0041 using GuidMemProfRecordPair = std::pair<GlobalValue::GUID, MemProfRecord>;
0042 using Iterator = InstrProfIterator<GuidMemProfRecordPair, MemProfReader>;
0043 Iterator end() { return Iterator(); }
0044 Iterator begin() {
0045 Iter = MemProfData.Records.begin();
0046 return Iterator(this);
0047 }
0048
0049
0050
0051 IndexedMemProfData takeMemProfData() { return std::move(MemProfData); }
0052
0053 virtual Error
0054 readNextRecord(GuidMemProfRecordPair &GuidRecord,
0055 std::function<const Frame(const FrameId)> Callback = nullptr) {
0056 if (MemProfData.Records.empty())
0057 return make_error<InstrProfError>(instrprof_error::empty_raw_profile);
0058
0059 if (Iter == MemProfData.Records.end())
0060 return make_error<InstrProfError>(instrprof_error::eof);
0061
0062 if (Callback == nullptr)
0063 Callback =
0064 std::bind(&MemProfReader::idToFrame, this, std::placeholders::_1);
0065
0066 CallStackIdConverter<decltype(MemProfData.CallStacks)> CSIdConv(
0067 MemProfData.CallStacks, Callback);
0068
0069 const IndexedMemProfRecord &IndexedRecord = Iter->second;
0070 GuidRecord = {
0071 Iter->first,
0072 IndexedRecord.toMemProfRecord(CSIdConv),
0073 };
0074 if (CSIdConv.LastUnmappedId)
0075 return make_error<InstrProfError>(instrprof_error::hash_mismatch);
0076 Iter++;
0077 return Error::success();
0078 }
0079
0080
0081
0082 MemProfReader() = default;
0083 virtual ~MemProfReader() = default;
0084
0085
0086 MemProfReader(IndexedMemProfData &&MemProfData)
0087 : MemProfData(std::move(MemProfData)) {}
0088
0089 protected:
0090
0091 const Frame &idToFrame(const FrameId Id) const {
0092 auto It = MemProfData.Frames.find(Id);
0093 assert(It != MemProfData.Frames.end() && "Id not found in map.");
0094 return It->second;
0095 }
0096
0097 IndexedMemProfData MemProfData;
0098
0099 llvm::MapVector<GlobalValue::GUID, IndexedMemProfRecord>::iterator Iter;
0100 };
0101
0102
0103
0104 using CallStackMap = llvm::DenseMap<uint64_t, llvm::SmallVector<uint64_t>>;
0105
0106
0107
0108 class RawMemProfReader final : public MemProfReader {
0109 public:
0110 RawMemProfReader(const RawMemProfReader &) = delete;
0111 RawMemProfReader &operator=(const RawMemProfReader &) = delete;
0112 virtual ~RawMemProfReader() override;
0113
0114
0115 void printYAML(raw_ostream &OS);
0116
0117
0118
0119 static bool hasFormat(const MemoryBuffer &DataBuffer);
0120
0121
0122 static bool hasFormat(const StringRef Path);
0123
0124
0125
0126
0127 static Expected<std::unique_ptr<RawMemProfReader>>
0128 create(const Twine &Path, StringRef ProfiledBinary, bool KeepName = false);
0129 static Expected<std::unique_ptr<RawMemProfReader>>
0130 create(std::unique_ptr<MemoryBuffer> Buffer, StringRef ProfiledBinary,
0131 bool KeepName = false);
0132
0133
0134 static std::vector<std::string> peekBuildIds(MemoryBuffer *DataBuffer);
0135
0136 Error
0137 readNextRecord(GuidMemProfRecordPair &GuidRecord,
0138 std::function<const Frame(const FrameId)> Callback) override;
0139
0140
0141 RawMemProfReader(std::unique_ptr<llvm::symbolize::SymbolizableModule> Sym,
0142 llvm::SmallVectorImpl<SegmentEntry> &Seg,
0143 llvm::MapVector<uint64_t, MemInfoBlock> &Prof,
0144 CallStackMap &SM, bool KeepName = false)
0145 : SegmentInfo(Seg.begin(), Seg.end()), CallstackProfileData(Prof),
0146 StackMap(SM), KeepSymbolName(KeepName) {
0147
0148
0149
0150
0151
0152 if (Error E = symbolizeAndFilterStackFrames(std::move(Sym)))
0153 report_fatal_error(std::move(E));
0154 if (Error E = mapRawProfileToRecords())
0155 report_fatal_error(std::move(E));
0156 }
0157
0158 private:
0159 RawMemProfReader(object::OwningBinary<object::Binary> &&Bin, bool KeepName)
0160 : Binary(std::move(Bin)), KeepSymbolName(KeepName) {}
0161
0162 Error initialize(std::unique_ptr<MemoryBuffer> DataBuffer);
0163
0164 Error readRawProfile(std::unique_ptr<MemoryBuffer> DataBuffer);
0165
0166 Error setupForSymbolization();
0167
0168
0169
0170
0171 Error symbolizeAndFilterStackFrames(
0172 std::unique_ptr<llvm::symbolize::SymbolizableModule> Symbolizer);
0173
0174
0175
0176 Error mapRawProfileToRecords();
0177
0178 object::SectionedAddress getModuleOffset(uint64_t VirtualAddress);
0179
0180 llvm::SmallVector<std::pair<uint64_t, MemInfoBlock>>
0181 readMemInfoBlocks(const char *Ptr);
0182
0183
0184 object::OwningBinary<object::Binary> Binary;
0185
0186
0187 uint64_t MemprofRawVersion = MEMPROF_RAW_VERSION;
0188
0189 uint64_t PreferredTextSegmentAddress = 0;
0190
0191 uint64_t ProfiledTextSegmentStart = 0;
0192
0193 uint64_t ProfiledTextSegmentEnd = 0;
0194
0195
0196
0197 llvm::SmallVector<SegmentEntry, 2> SegmentInfo;
0198
0199
0200
0201 llvm::MapVector<uint64_t, MemInfoBlock> CallstackProfileData;
0202 CallStackMap StackMap;
0203
0204
0205 llvm::DenseMap<uint64_t, llvm::SmallVector<FrameId>> SymbolizedFrame;
0206
0207
0208 bool KeepSymbolName = false;
0209
0210 llvm::DenseMap<uint64_t, std::string> GuidToSymbolName;
0211 };
0212
0213 class YAMLMemProfReader final : public MemProfReader {
0214 public:
0215 YAMLMemProfReader() = default;
0216
0217
0218
0219 static bool hasFormat(const MemoryBuffer &DataBuffer);
0220
0221
0222 static bool hasFormat(const StringRef Path);
0223
0224
0225
0226 static Expected<std::unique_ptr<YAMLMemProfReader>> create(const Twine &Path);
0227 static Expected<std::unique_ptr<YAMLMemProfReader>>
0228 create(std::unique_ptr<MemoryBuffer> Buffer);
0229
0230 void parse(StringRef YAMLData);
0231 };
0232 }
0233 }
0234
0235 #endif