|
1 | 1 | #include "llvm/ProfileData/MemProf.h"
|
2 | 2 | #include "llvm/ADT/DenseMap.h"
|
3 | 3 | #include "llvm/ADT/MapVector.h"
|
| 4 | +#include "llvm/ADT/STLForwardCompat.h" |
4 | 5 | #include "llvm/DebugInfo/DIContext.h"
|
5 | 6 | #include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
|
6 | 7 | #include "llvm/IR/Value.h"
|
@@ -326,6 +327,65 @@ TEST(MemProf, RecordSerializationRoundTripVerion2) {
|
326 | 327 | EXPECT_EQ(Record, GotRecord);
|
327 | 328 | }
|
328 | 329 |
|
| 330 | +TEST(MemProf, RecordSerializationRoundTripVersion2HotColdSchema) { |
| 331 | + const auto Schema = llvm::memprof::getHotColdSchema(); |
| 332 | + |
| 333 | + MemInfoBlock Info; |
| 334 | + Info.AllocCount = 11; |
| 335 | + Info.TotalSize = 22; |
| 336 | + Info.TotalLifetime = 33; |
| 337 | + Info.TotalLifetimeAccessDensity = 44; |
| 338 | + |
| 339 | + llvm::SmallVector<llvm::memprof::CallStackId> CallStackIds = {0x123, 0x456}; |
| 340 | + |
| 341 | + llvm::SmallVector<llvm::memprof::CallStackId> CallSiteIds = {0x333, 0x444}; |
| 342 | + |
| 343 | + IndexedMemProfRecord Record; |
| 344 | + for (const auto &CSId : CallStackIds) { |
| 345 | + // Use the same info block for both allocation sites. |
| 346 | + Record.AllocSites.emplace_back(llvm::SmallVector<FrameId>(), CSId, Info, |
| 347 | + Schema); |
| 348 | + } |
| 349 | + Record.CallSiteIds.assign(CallSiteIds); |
| 350 | + |
| 351 | + std::bitset<llvm::to_underlying(Meta::Size)> SchemaBitSet; |
| 352 | + for (auto Id : Schema) |
| 353 | + SchemaBitSet.set(llvm::to_underlying(Id)); |
| 354 | + |
| 355 | + // Verify that SchemaBitSet has the fields we expect and nothing else, which |
| 356 | + // we check with count(). |
| 357 | + EXPECT_EQ(SchemaBitSet.count(), 4U); |
| 358 | + EXPECT_TRUE(SchemaBitSet[llvm::to_underlying(Meta::AllocCount)]); |
| 359 | + EXPECT_TRUE(SchemaBitSet[llvm::to_underlying(Meta::TotalSize)]); |
| 360 | + EXPECT_TRUE(SchemaBitSet[llvm::to_underlying(Meta::TotalLifetime)]); |
| 361 | + EXPECT_TRUE( |
| 362 | + SchemaBitSet[llvm::to_underlying(Meta::TotalLifetimeAccessDensity)]); |
| 363 | + |
| 364 | + // Verify that Schema has propagated all the way to the Info field in each |
| 365 | + // IndexedAllocationInfo. |
| 366 | + ASSERT_THAT(Record.AllocSites, ::SizeIs(2)); |
| 367 | + EXPECT_EQ(Record.AllocSites[0].Info.getSchema(), SchemaBitSet); |
| 368 | + EXPECT_EQ(Record.AllocSites[1].Info.getSchema(), SchemaBitSet); |
| 369 | + |
| 370 | + std::string Buffer; |
| 371 | + llvm::raw_string_ostream OS(Buffer); |
| 372 | + Record.serialize(Schema, OS, llvm::memprof::Version2); |
| 373 | + OS.flush(); |
| 374 | + |
| 375 | + const IndexedMemProfRecord GotRecord = IndexedMemProfRecord::deserialize( |
| 376 | + Schema, reinterpret_cast<const unsigned char *>(Buffer.data()), |
| 377 | + llvm::memprof::Version2); |
| 378 | + |
| 379 | + // Verify that Schema comes back correctly after deserialization. Technically, |
| 380 | + // the comparison between Record and GotRecord below includes the comparison |
| 381 | + // of their Schemas, but we'll verify the Schemas on our own. |
| 382 | + ASSERT_THAT(GotRecord.AllocSites, ::SizeIs(2)); |
| 383 | + EXPECT_EQ(GotRecord.AllocSites[0].Info.getSchema(), SchemaBitSet); |
| 384 | + EXPECT_EQ(GotRecord.AllocSites[1].Info.getSchema(), SchemaBitSet); |
| 385 | + |
| 386 | + EXPECT_EQ(Record, GotRecord); |
| 387 | +} |
| 388 | + |
329 | 389 | TEST(MemProf, SymbolizationFilter) {
|
330 | 390 | std::unique_ptr<MockSymbolizer> Symbolizer(new MockSymbolizer());
|
331 | 391 |
|
|
0 commit comments