diff options
author | Kazu Hirata <kazu@google.com> | 2024-05-15 17:53:28 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-15 17:53:28 -0700 |
commit | 26fabdded34f8cea490060a70188a07ad6b76b8b (patch) | |
tree | 950e488b0083b66a2fbaf9eca0bee143f3815a77 /llvm/unittests/ProfileData/MemProfTest.cpp | |
parent | c6e787f771d1f9d6a846b2d9b8db6adcd87e8dba (diff) | |
download | llvm-26fabdded34f8cea490060a70188a07ad6b76b8b.zip llvm-26fabdded34f8cea490060a70188a07ad6b76b8b.tar.gz llvm-26fabdded34f8cea490060a70188a07ad6b76b8b.tar.bz2 |
[memprof] Pass FrameIdConverter and CallStackIdConverter by reference (#92327)
CallStackIdConverter sets LastUnmappedId when a mapping failure
occurs. Now, since toMemProfRecord takes an instance of
CallStackIdConverter by value, namely std::function, the caller of
toMemProfRecord never receives the mapping failure that occurs inside
toMemProfRecord. The same problem applies to FrameIdConverter.
The patch fixes the problem by passing FrameIdConverter and
CallStackIdConverter by reference, namely llvm::function_ref.
While I am it, this patch deletes the copy constructor and copy
assignment operator to avoid accidental copies.
Diffstat (limited to 'llvm/unittests/ProfileData/MemProfTest.cpp')
-rw-r--r-- | llvm/unittests/ProfileData/MemProfTest.cpp | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/llvm/unittests/ProfileData/MemProfTest.cpp b/llvm/unittests/ProfileData/MemProfTest.cpp index 8b97866..a913718 100644 --- a/llvm/unittests/ProfileData/MemProfTest.cpp +++ b/llvm/unittests/ProfileData/MemProfTest.cpp @@ -596,4 +596,70 @@ TEST(MemProf, IndexedMemProfRecordToMemProfRecord) { EXPECT_EQ(Record.CallSites[1][0].hash(), F2.hash()); EXPECT_EQ(Record.CallSites[1][1].hash(), F4.hash()); } + +using FrameIdMapTy = + llvm::DenseMap<::llvm::memprof::FrameId, ::llvm::memprof::Frame>; +using CallStackIdMapTy = + llvm::DenseMap<::llvm::memprof::CallStackId, + ::llvm::SmallVector<::llvm::memprof::FrameId>>; + +// Populate those fields returned by getHotColdSchema. +MemInfoBlock makePartialMIB() { + MemInfoBlock MIB; + MIB.AllocCount = 1; + MIB.TotalSize = 5; + MIB.TotalLifetime = 10; + MIB.TotalLifetimeAccessDensity = 23; + return MIB; +} + +TEST(MemProf, MissingCallStackId) { + // Use a non-existent CallStackId to trigger a mapping error in + // toMemProfRecord. + llvm::memprof::IndexedAllocationInfo AI({}, 0xdeadbeefU, makePartialMIB(), + llvm::memprof::getHotColdSchema()); + + IndexedMemProfRecord IndexedMR; + IndexedMR.AllocSites.push_back(AI); + + // Create empty maps. + const FrameIdMapTy IdToFrameMap; + const CallStackIdMapTy CSIdToCallStackMap; + llvm::memprof::FrameIdConverter<decltype(IdToFrameMap)> FrameIdConv( + IdToFrameMap); + llvm::memprof::CallStackIdConverter<decltype(CSIdToCallStackMap)> CSIdConv( + CSIdToCallStackMap, FrameIdConv); + + // We are only interested in errors, not the return value. + (void)IndexedMR.toMemProfRecord(CSIdConv); + + ASSERT_TRUE(CSIdConv.LastUnmappedId.has_value()); + EXPECT_EQ(*CSIdConv.LastUnmappedId, 0xdeadbeefU); + EXPECT_EQ(FrameIdConv.LastUnmappedId, std::nullopt); +} + +TEST(MemProf, MissingFrameId) { + llvm::memprof::IndexedAllocationInfo AI({}, 0x222, makePartialMIB(), + llvm::memprof::getHotColdSchema()); + + IndexedMemProfRecord IndexedMR; + IndexedMR.AllocSites.push_back(AI); + + // An empty map to trigger a mapping error. + const FrameIdMapTy IdToFrameMap; + CallStackIdMapTy CSIdToCallStackMap; + CSIdToCallStackMap.insert({0x222, {2, 3}}); + + llvm::memprof::FrameIdConverter<decltype(IdToFrameMap)> FrameIdConv( + IdToFrameMap); + llvm::memprof::CallStackIdConverter<decltype(CSIdToCallStackMap)> CSIdConv( + CSIdToCallStackMap, FrameIdConv); + + // We are only interested in errors, not the return value. + (void)IndexedMR.toMemProfRecord(CSIdConv); + + EXPECT_EQ(CSIdConv.LastUnmappedId, std::nullopt); + ASSERT_TRUE(FrameIdConv.LastUnmappedId.has_value()); + EXPECT_EQ(*FrameIdConv.LastUnmappedId, 3U); +} } // namespace |