RawMemProfReader.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. #ifndef LLVM_PROFILEDATA_RAWMEMPROFREADER_H_
  7. #define LLVM_PROFILEDATA_RAWMEMPROFREADER_H_
  8. //===- MemProfReader.h - Instrumented memory profiling reader ---*- C++ -*-===//
  9. //
  10. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  11. // See https://llvm.org/LICENSE.txt for license information.
  12. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  13. //
  14. //===----------------------------------------------------------------------===//
  15. //
  16. // This file contains support for reading MemProf profiling data.
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #include "llvm/ADT/DenseMap.h"
  20. #include "llvm/ADT/MapVector.h"
  21. #include "llvm/ADT/StringRef.h"
  22. #include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
  23. #include "llvm/DebugInfo/Symbolize/Symbolize.h"
  24. #include "llvm/IR/GlobalValue.h"
  25. #include "llvm/Object/Binary.h"
  26. #include "llvm/Object/ObjectFile.h"
  27. #include "llvm/ProfileData/InstrProfReader.h"
  28. #include "llvm/ProfileData/MemProf.h"
  29. #include "llvm/ProfileData/MemProfData.inc"
  30. #include "llvm/Support/Error.h"
  31. #include "llvm/Support/MemoryBuffer.h"
  32. #include <cstddef>
  33. namespace llvm {
  34. namespace memprof {
  35. // Map from id (recorded from sanitizer stack depot) to virtual addresses for
  36. // each program counter address in the callstack.
  37. using CallStackMap = llvm::DenseMap<uint64_t, llvm::SmallVector<uint64_t>>;
  38. class RawMemProfReader {
  39. public:
  40. RawMemProfReader(const RawMemProfReader &) = delete;
  41. RawMemProfReader &operator=(const RawMemProfReader &) = delete;
  42. // Prints the contents of the profile in YAML format.
  43. void printYAML(raw_ostream &OS);
  44. // Return true if the \p DataBuffer starts with magic bytes indicating it is
  45. // a raw binary memprof profile.
  46. static bool hasFormat(const MemoryBuffer &DataBuffer);
  47. // Return true if the file at \p Path starts with magic bytes indicating it is
  48. // a raw binary memprof profile.
  49. static bool hasFormat(const StringRef Path);
  50. // Create a RawMemProfReader after sanity checking the contents of the file at
  51. // \p Path. The binary from which the profile has been collected is specified
  52. // via a path in \p ProfiledBinary.
  53. static Expected<std::unique_ptr<RawMemProfReader>>
  54. create(const Twine &Path, const StringRef ProfiledBinary,
  55. bool KeepName = false);
  56. using GuidMemProfRecordPair = std::pair<GlobalValue::GUID, MemProfRecord>;
  57. using Iterator = InstrProfIterator<GuidMemProfRecordPair, RawMemProfReader>;
  58. Iterator end() { return Iterator(); }
  59. Iterator begin() {
  60. Iter = FunctionProfileData.begin();
  61. return Iterator(this);
  62. }
  63. Error readNextRecord(GuidMemProfRecordPair &GuidRecord);
  64. // The RawMemProfReader only holds memory profile information.
  65. InstrProfKind getProfileKind() const { return InstrProfKind::MemProf; }
  66. // Constructor for unittests only.
  67. RawMemProfReader(std::unique_ptr<llvm::symbolize::SymbolizableModule> Sym,
  68. llvm::SmallVectorImpl<SegmentEntry> &Seg,
  69. llvm::MapVector<uint64_t, MemInfoBlock> &Prof,
  70. CallStackMap &SM, bool KeepName = false)
  71. : Symbolizer(std::move(Sym)), SegmentInfo(Seg.begin(), Seg.end()),
  72. CallstackProfileData(Prof), StackMap(SM), KeepSymbolName(KeepName) {
  73. // We don't call initialize here since there is no raw profile to read. The
  74. // test should pass in the raw profile as structured data.
  75. // If there is an error here then the mock symbolizer has not been
  76. // initialized properly.
  77. if (Error E = symbolizeAndFilterStackFrames())
  78. report_fatal_error(std::move(E));
  79. if (Error E = mapRawProfileToRecords())
  80. report_fatal_error(std::move(E));
  81. }
  82. // Return a const reference to the internal Id to Frame mappings.
  83. const llvm::DenseMap<FrameId, Frame> &getFrameMapping() const {
  84. return IdToFrame;
  85. }
  86. // Return a const reference to the internal function profile data.
  87. const llvm::MapVector<GlobalValue::GUID, IndexedMemProfRecord> &
  88. getProfileData() const {
  89. return FunctionProfileData;
  90. }
  91. private:
  92. RawMemProfReader(object::OwningBinary<object::Binary> &&Bin, bool KeepName)
  93. : Binary(std::move(Bin)), KeepSymbolName(KeepName) {}
  94. // Initializes the RawMemProfReader with the contents in `DataBuffer`.
  95. Error initialize(std::unique_ptr<MemoryBuffer> DataBuffer);
  96. // Read and parse the contents of the `DataBuffer` as a binary format profile.
  97. Error readRawProfile(std::unique_ptr<MemoryBuffer> DataBuffer);
  98. // Symbolize and cache all the virtual addresses we encounter in the
  99. // callstacks from the raw profile. Also prune callstack frames which we can't
  100. // symbolize or those that belong to the runtime. For profile entries where
  101. // the entire callstack is pruned, we drop the entry from the profile.
  102. Error symbolizeAndFilterStackFrames();
  103. // Construct memprof records for each function and store it in the
  104. // `FunctionProfileData` map. A function may have allocation profile data or
  105. // callsite data or both.
  106. Error mapRawProfileToRecords();
  107. // A helper method to extract the frame from the IdToFrame map.
  108. const Frame &idToFrame(const FrameId Id) const {
  109. auto It = IdToFrame.find(Id);
  110. assert(It != IdToFrame.end() && "Id not found in map.");
  111. return It->getSecond();
  112. }
  113. object::SectionedAddress getModuleOffset(uint64_t VirtualAddress);
  114. object::OwningBinary<object::Binary> Binary;
  115. std::unique_ptr<llvm::symbolize::SymbolizableModule> Symbolizer;
  116. // The contents of the raw profile.
  117. llvm::SmallVector<SegmentEntry, 16> SegmentInfo;
  118. // A map from callstack id (same as key in CallStackMap below) to the heap
  119. // information recorded for that allocation context.
  120. llvm::MapVector<uint64_t, MemInfoBlock> CallstackProfileData;
  121. CallStackMap StackMap;
  122. // Cached symbolization from PC to Frame.
  123. llvm::DenseMap<uint64_t, llvm::SmallVector<FrameId>> SymbolizedFrame;
  124. llvm::DenseMap<FrameId, Frame> IdToFrame;
  125. llvm::MapVector<GlobalValue::GUID, IndexedMemProfRecord> FunctionProfileData;
  126. llvm::MapVector<GlobalValue::GUID, IndexedMemProfRecord>::iterator Iter;
  127. // Whether to keep the symbol name for each frame after hashing.
  128. bool KeepSymbolName = false;
  129. // A mapping of the hash to symbol name, only used if KeepSymbolName is true.
  130. llvm::DenseMap<uint64_t, std::string> GuidToSymbolName;
  131. };
  132. } // namespace memprof
  133. } // namespace llvm
  134. #endif // LLVM_PROFILEDATA_RAWMEMPROFREADER_H_
  135. #ifdef __GNUC__
  136. #pragma GCC diagnostic pop
  137. #endif