123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- #ifndef LLVM_PROFILEDATA_RAWMEMPROFREADER_H_
- #define LLVM_PROFILEDATA_RAWMEMPROFREADER_H_
- //===- MemProfReader.h - Instrumented memory profiling reader ---*- C++ -*-===//
- //
- // 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
- //
- //===----------------------------------------------------------------------===//
- //
- // This file contains support for reading MemProf profiling data.
- //
- //===----------------------------------------------------------------------===//
- #include "llvm/ADT/DenseMap.h"
- #include "llvm/ADT/MapVector.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
- #include "llvm/DebugInfo/Symbolize/Symbolize.h"
- #include "llvm/IR/GlobalValue.h"
- #include "llvm/Object/Binary.h"
- #include "llvm/Object/ObjectFile.h"
- #include "llvm/ProfileData/InstrProfReader.h"
- #include "llvm/ProfileData/MemProf.h"
- #include "llvm/ProfileData/MemProfData.inc"
- #include "llvm/Support/Error.h"
- #include "llvm/Support/MemoryBuffer.h"
- #include <cstddef>
- namespace llvm {
- namespace memprof {
- // Map from id (recorded from sanitizer stack depot) to virtual addresses for
- // each program counter address in the callstack.
- using CallStackMap = llvm::DenseMap<uint64_t, llvm::SmallVector<uint64_t>>;
- class RawMemProfReader {
- public:
- RawMemProfReader(const RawMemProfReader &) = delete;
- RawMemProfReader &operator=(const RawMemProfReader &) = delete;
- // Prints the contents of the profile in YAML format.
- void printYAML(raw_ostream &OS);
- // Return true if the \p DataBuffer starts with magic bytes indicating it is
- // a raw binary memprof profile.
- static bool hasFormat(const MemoryBuffer &DataBuffer);
- // Return true if the file at \p Path starts with magic bytes indicating it is
- // a raw binary memprof profile.
- static bool hasFormat(const StringRef Path);
- // Create a RawMemProfReader after sanity checking the contents of the file at
- // \p Path. The binary from which the profile has been collected is specified
- // via a path in \p ProfiledBinary.
- static Expected<std::unique_ptr<RawMemProfReader>>
- create(const Twine &Path, const StringRef ProfiledBinary,
- bool KeepName = false);
- using GuidMemProfRecordPair = std::pair<GlobalValue::GUID, MemProfRecord>;
- using Iterator = InstrProfIterator<GuidMemProfRecordPair, RawMemProfReader>;
- Iterator end() { return Iterator(); }
- Iterator begin() {
- Iter = FunctionProfileData.begin();
- return Iterator(this);
- }
- Error readNextRecord(GuidMemProfRecordPair &GuidRecord);
- // The RawMemProfReader only holds memory profile information.
- InstrProfKind getProfileKind() const { return InstrProfKind::MemProf; }
- // Constructor for unittests only.
- RawMemProfReader(std::unique_ptr<llvm::symbolize::SymbolizableModule> Sym,
- llvm::SmallVectorImpl<SegmentEntry> &Seg,
- llvm::MapVector<uint64_t, MemInfoBlock> &Prof,
- CallStackMap &SM, bool KeepName = false)
- : Symbolizer(std::move(Sym)), SegmentInfo(Seg.begin(), Seg.end()),
- CallstackProfileData(Prof), StackMap(SM), KeepSymbolName(KeepName) {
- // We don't call initialize here since there is no raw profile to read. The
- // test should pass in the raw profile as structured data.
- // If there is an error here then the mock symbolizer has not been
- // initialized properly.
- if (Error E = symbolizeAndFilterStackFrames())
- report_fatal_error(std::move(E));
- if (Error E = mapRawProfileToRecords())
- report_fatal_error(std::move(E));
- }
- // Return a const reference to the internal Id to Frame mappings.
- const llvm::DenseMap<FrameId, Frame> &getFrameMapping() const {
- return IdToFrame;
- }
- // Return a const reference to the internal function profile data.
- const llvm::MapVector<GlobalValue::GUID, IndexedMemProfRecord> &
- getProfileData() const {
- return FunctionProfileData;
- }
- private:
- RawMemProfReader(object::OwningBinary<object::Binary> &&Bin, bool KeepName)
- : Binary(std::move(Bin)), KeepSymbolName(KeepName) {}
- // Initializes the RawMemProfReader with the contents in `DataBuffer`.
- Error initialize(std::unique_ptr<MemoryBuffer> DataBuffer);
- // Read and parse the contents of the `DataBuffer` as a binary format profile.
- Error readRawProfile(std::unique_ptr<MemoryBuffer> DataBuffer);
- // Symbolize and cache all the virtual addresses we encounter in the
- // callstacks from the raw profile. Also prune callstack frames which we can't
- // symbolize or those that belong to the runtime. For profile entries where
- // the entire callstack is pruned, we drop the entry from the profile.
- Error symbolizeAndFilterStackFrames();
- // Construct memprof records for each function and store it in the
- // `FunctionProfileData` map. A function may have allocation profile data or
- // callsite data or both.
- Error mapRawProfileToRecords();
- // A helper method to extract the frame from the IdToFrame map.
- const Frame &idToFrame(const FrameId Id) const {
- auto It = IdToFrame.find(Id);
- assert(It != IdToFrame.end() && "Id not found in map.");
- return It->getSecond();
- }
- object::SectionedAddress getModuleOffset(uint64_t VirtualAddress);
- object::OwningBinary<object::Binary> Binary;
- std::unique_ptr<llvm::symbolize::SymbolizableModule> Symbolizer;
- // The contents of the raw profile.
- llvm::SmallVector<SegmentEntry, 16> SegmentInfo;
- // A map from callstack id (same as key in CallStackMap below) to the heap
- // information recorded for that allocation context.
- llvm::MapVector<uint64_t, MemInfoBlock> CallstackProfileData;
- CallStackMap StackMap;
- // Cached symbolization from PC to Frame.
- llvm::DenseMap<uint64_t, llvm::SmallVector<FrameId>> SymbolizedFrame;
- llvm::DenseMap<FrameId, Frame> IdToFrame;
- llvm::MapVector<GlobalValue::GUID, IndexedMemProfRecord> FunctionProfileData;
- llvm::MapVector<GlobalValue::GUID, IndexedMemProfRecord>::iterator Iter;
- // Whether to keep the symbol name for each frame after hashing.
- bool KeepSymbolName = false;
- // A mapping of the hash to symbol name, only used if KeepSymbolName is true.
- llvm::DenseMap<uint64_t, std::string> GuidToSymbolName;
- };
- } // namespace memprof
- } // namespace llvm
- #endif // LLVM_PROFILEDATA_RAWMEMPROFREADER_H_
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|