Skip to content

Commit 216575e

Browse files
author
Snehasish Kumar
committed
Revert "Revert "[ProfileData] Read and symbolize raw memprof profiles.""
This reverts commit dbf47d2. Reapply https://reviews.llvm.org/D116784 now that https://reviews.llvm.org/D118413 has landed with a couple of fixes: * fix raw profile reader unaligned access identified by ubsan * fix windows build by using MOCK_CONST_METHOD3 instead of MOCK_METHOD.
1 parent f16cc5d commit 216575e

File tree

14 files changed

+720
-29
lines changed

14 files changed

+720
-29
lines changed

llvm/include/llvm/DebugInfo/DIContext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ struct DILineInfoSpecifier {
151151
DILineInfoSpecifier(FileLineInfoKind FLIKind = FileLineInfoKind::RawValue,
152152
FunctionNameKind FNKind = FunctionNameKind::None)
153153
: FLIKind(FLIKind), FNKind(FNKind) {}
154+
155+
inline bool operator==(const DILineInfoSpecifier &RHS) const {
156+
return FLIKind == RHS.FLIKind && FNKind == RHS.FNKind;
157+
}
154158
};
155159

156160
/// This is just a helper to programmatically construct DIDumpType.
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#ifndef LLVM_PROFILEDATA_MEMPROF_H_
2+
#define LLVM_PROFILEDATA_MEMPROF_H_
3+
4+
#include <cstdint>
5+
#include <string>
6+
#include <vector>
7+
8+
#include "llvm/ProfileData/MemProfData.inc"
9+
#include "llvm/Support/raw_ostream.h"
10+
11+
namespace llvm {
12+
namespace memprof {
13+
14+
struct MemProfRecord {
15+
struct Frame {
16+
std::string Function;
17+
uint32_t LineOffset;
18+
uint32_t Column;
19+
bool IsInlineFrame;
20+
21+
Frame(std::string Str, uint32_t Off, uint32_t Col, bool Inline)
22+
: Function(std::move(Str)), LineOffset(Off), Column(Col),
23+
IsInlineFrame(Inline) {}
24+
};
25+
26+
std::vector<Frame> CallStack;
27+
// TODO: Replace this with the entry format described in the RFC so
28+
// that the InstrProfRecord reader and writer do not have to be concerned
29+
// about backwards compat.
30+
MemInfoBlock Info;
31+
32+
void clear() {
33+
CallStack.clear();
34+
Info = MemInfoBlock();
35+
}
36+
37+
// Prints out the contents of the memprof record in YAML.
38+
void print(llvm::raw_ostream &OS) const {
39+
OS << " Callstack:\n";
40+
// TODO: Print out the frame on one line with to make it easier for deep
41+
// callstacks once we have a test to check valid YAML is generated.
42+
for (const auto &Frame : CallStack) {
43+
OS << " -\n"
44+
<< " Function: " << Frame.Function << "\n"
45+
<< " LineOffset: " << Frame.LineOffset << "\n"
46+
<< " Column: " << Frame.Column << "\n"
47+
<< " Inline: " << Frame.IsInlineFrame << "\n";
48+
}
49+
50+
OS << " MemInfoBlock:\n";
51+
52+
// TODO: Replace this once the format is updated to be version agnostic.
53+
OS << " "
54+
<< "AllocCount: " << Info.alloc_count << "\n";
55+
OS << " "
56+
<< "TotalAccessCount: " << Info.total_access_count << "\n";
57+
OS << " "
58+
<< "MinAccessCount: " << Info.min_access_count << "\n";
59+
OS << " "
60+
<< "MaxAccessCount: " << Info.max_access_count << "\n";
61+
OS << " "
62+
<< "TotalSize: " << Info.total_size << "\n";
63+
OS << " "
64+
<< "MinSize: " << Info.min_size << "\n";
65+
OS << " "
66+
<< "MaxSize: " << Info.max_size << "\n";
67+
OS << " "
68+
<< "AllocTimestamp: " << Info.alloc_timestamp << "\n";
69+
OS << " "
70+
<< "DeallocTimestamp: " << Info.dealloc_timestamp << "\n";
71+
OS << " "
72+
<< "TotalLifetime: " << Info.total_lifetime << "\n";
73+
OS << " "
74+
<< "MinLifetime: " << Info.min_lifetime << "\n";
75+
OS << " "
76+
<< "MaxLifetime: " << Info.max_lifetime << "\n";
77+
OS << " "
78+
<< "AllocCpuId: " << Info.alloc_cpu_id << "\n";
79+
OS << " "
80+
<< "DeallocCpuId: " << Info.dealloc_cpu_id << "\n";
81+
OS << " "
82+
<< "NumMigratedCpu: " << Info.num_migrated_cpu << "\n";
83+
OS << " "
84+
<< "NumLifetimeOverlaps: " << Info.num_lifetime_overlaps << "\n";
85+
OS << " "
86+
<< "NumSameAllocCpu: " << Info.num_same_alloc_cpu << "\n";
87+
OS << " "
88+
<< "NumSameDeallocCpu: " << Info.num_same_dealloc_cpu << "\n";
89+
}
90+
};
91+
92+
} // namespace memprof
93+
} // namespace llvm
94+
95+
#endif // LLVM_PROFILEDATA_MEMPROF_H_

llvm/include/llvm/ProfileData/RawMemProfReader.h

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,95 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15+
#include "llvm/ADT/DenseMap.h"
16+
#include "llvm/ADT/MapVector.h"
17+
#include "llvm/ADT/StringRef.h"
18+
#include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
19+
#include "llvm/DebugInfo/Symbolize/Symbolize.h"
20+
#include "llvm/Object/Binary.h"
21+
#include "llvm/Object/ObjectFile.h"
22+
#include "llvm/ProfileData/InstrProfReader.h"
23+
#include "llvm/ProfileData/MemProf.h"
24+
#include "llvm/ProfileData/MemProfData.inc"
1525
#include "llvm/Support/Error.h"
1626
#include "llvm/Support/MemoryBuffer.h"
1727

28+
#include <cstddef>
29+
1830
namespace llvm {
1931
namespace memprof {
2032

33+
// Map from id (recorded from sanitizer stack depot) to virtual addresses for
34+
// each program counter address in the callstack.
35+
using CallStackMap = llvm::DenseMap<uint64_t, llvm::SmallVector<uint64_t, 32>>;
36+
2137
class RawMemProfReader {
2238
public:
2339
RawMemProfReader(std::unique_ptr<MemoryBuffer> DataBuffer)
2440
: DataBuffer(std::move(DataBuffer)) {}
41+
RawMemProfReader(const RawMemProfReader &) = delete;
42+
RawMemProfReader &operator=(const RawMemProfReader &) = delete;
43+
2544
// Prints the contents of the profile in YAML format.
2645
void printYAML(raw_ostream &OS);
2746

2847
// Return true if the \p DataBuffer starts with magic bytes indicating it is
2948
// a raw binary memprof profile.
3049
static bool hasFormat(const MemoryBuffer &DataBuffer);
50+
// Return true if the file at \p Path starts with magic bytes indicating it is
51+
// a raw binary memprof profile.
52+
static bool hasFormat(const StringRef Path);
3153

3254
// Create a RawMemProfReader after sanity checking the contents of the file at
33-
// \p Path.
34-
static Expected<std::unique_ptr<RawMemProfReader>> create(const Twine &Path);
55+
// \p Path. The binary from which the profile has been collected is specified
56+
// via a path in \p ProfiledBinary.
57+
static Expected<std::unique_ptr<RawMemProfReader>>
58+
create(const Twine &Path, const StringRef ProfiledBinary);
59+
60+
Error readNextRecord(MemProfRecord &Record);
61+
62+
using Iterator = InstrProfIterator<MemProfRecord, RawMemProfReader>;
63+
Iterator end() { return Iterator(); }
64+
Iterator begin() {
65+
Iter = ProfileData.begin();
66+
return Iterator(this);
67+
}
68+
69+
// Constructor for unittests only.
70+
RawMemProfReader(std::unique_ptr<llvm::symbolize::SymbolizableModule> Sym,
71+
llvm::SmallVectorImpl<SegmentEntry> &Seg,
72+
llvm::MapVector<uint64_t, MemInfoBlock> &Prof,
73+
CallStackMap &SM)
74+
: Symbolizer(std::move(Sym)), SegmentInfo(Seg.begin(), Seg.end()),
75+
ProfileData(Prof), StackMap(SM) {}
3576

3677
private:
78+
RawMemProfReader(std::unique_ptr<MemoryBuffer> DataBuffer,
79+
object::OwningBinary<object::Binary> &&Bin)
80+
: DataBuffer(std::move(DataBuffer)), Binary(std::move(Bin)) {}
81+
Error initialize();
82+
Error readRawProfile();
83+
84+
object::SectionedAddress getModuleOffset(uint64_t VirtualAddress);
85+
Error fillRecord(const uint64_t Id, const MemInfoBlock &MIB,
86+
MemProfRecord &Record);
3787
// Prints aggregate counts for each raw profile parsed from the DataBuffer in
3888
// YAML format.
3989
void printSummaries(raw_ostream &OS) const;
4090

4191
std::unique_ptr<MemoryBuffer> DataBuffer;
92+
object::OwningBinary<object::Binary> Binary;
93+
std::unique_ptr<llvm::symbolize::SymbolizableModule> Symbolizer;
94+
95+
// The contents of the raw profile.
96+
llvm::SmallVector<SegmentEntry, 16> SegmentInfo;
97+
// A map from callstack id (same as key in CallStackMap below) to the heap
98+
// information recorded for that allocation context.
99+
llvm::MapVector<uint64_t, MemInfoBlock> ProfileData;
100+
CallStackMap StackMap;
101+
102+
// Iterator to read from the ProfileData MapVector.
103+
llvm::MapVector<uint64_t, MemInfoBlock>::iterator Iter = ProfileData.end();
42104
};
43105

44106
} // namespace memprof

llvm/lib/ProfileData/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ add_llvm_component_library(LLVMProfileData
1818

1919
LINK_COMPONENTS
2020
Core
21+
Object
2122
Support
2223
Demangle
23-
Object
24+
Symbolize
2425
DebugInfoDWARF
2526
)
2627

0 commit comments

Comments
 (0)