diff --git a/llvm/include/llvm/ProfileData/MemProf.h b/llvm/include/llvm/ProfileData/MemProf.h index f356e3a54a3645..7ba2a4b7a507fb 100644 --- a/llvm/include/llvm/ProfileData/MemProf.h +++ b/llvm/include/llvm/ProfileData/MemProf.h @@ -578,14 +578,21 @@ class FrameWriterTrait { static hash_value_type ComputeHash(key_type_ref K) { return K; } - static std::pair + FrameWriterTrait() = delete; + FrameWriterTrait(IndexedVersion Version) : Version(Version) {} + + std::pair EmitKeyDataLength(raw_ostream &Out, key_type_ref K, data_type_ref V) { using namespace support; endian::Writer LE(Out, llvm::endianness::little); offset_type N = sizeof(K); - LE.write(N); - offset_type M = V.serializedSize(); - LE.write(M); + offset_type M = Frame::serializedSize(); + // Starting with Version2, we do not explicitly emit the key/data lengths + // because they are constants. + if (Version < Version2) { + LE.write(N); + LE.write(M); + } return std::make_pair(N, M); } @@ -599,6 +606,10 @@ class FrameWriterTrait { offset_type /*Unused*/) { V.serialize(Out); } + +private: + // Holds the MemProf version. + IndexedVersion Version; }; // Trait for reading frame mappings from the on-disk hash table. @@ -610,6 +621,9 @@ class FrameLookupTrait { using hash_value_type = FrameId; using offset_type = uint64_t; + FrameLookupTrait() = delete; + FrameLookupTrait(IndexedVersion Version) : Version(Version) {} + static bool EqualKey(internal_key_type A, internal_key_type B) { return A == B; } @@ -618,14 +632,18 @@ class FrameLookupTrait { hash_value_type ComputeHash(internal_key_type K) { return K; } - static std::pair + std::pair ReadKeyDataLength(const unsigned char *&D) { using namespace support; offset_type KeyLen = - endian::readNext(D); + Version < Version2 + ? endian::readNext(D) + : sizeof(FrameId); offset_type DataLen = - endian::readNext(D); + Version < Version2 + ? endian::readNext(D) + : Frame::serializedSize(); return std::make_pair(KeyLen, DataLen); } @@ -638,6 +656,10 @@ class FrameLookupTrait { offset_type /*Unused*/) { return Frame::deserialize(D); } + +private: + // Holds the MemProf version. + IndexedVersion Version; }; // Trait for writing call stacks to the on-disk hash table. diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp index cefb6af12d0021..df0c43a0386958 100644 --- a/llvm/lib/ProfileData/InstrProfReader.cpp +++ b/llvm/lib/ProfileData/InstrProfReader.cpp @@ -1272,7 +1272,7 @@ Error IndexedMemProfReader::deserialize(const unsigned char *Start, MemProfFrameTable.reset(MemProfFrameHashTable::Create( /*Buckets=*/Start + FrameTableOffset, /*Payload=*/Start + FramePayloadOffset, - /*Base=*/Start)); + /*Base=*/Start, memprof::FrameLookupTrait(Version))); if (Version >= memprof::Version2) MemProfCallStackTable.reset(MemProfCallStackHashTable::Create( diff --git a/llvm/lib/ProfileData/InstrProfWriter.cpp b/llvm/lib/ProfileData/InstrProfWriter.cpp index 4a6fc9d64b6900..1a7edf18801218 100644 --- a/llvm/lib/ProfileData/InstrProfWriter.cpp +++ b/llvm/lib/ProfileData/InstrProfWriter.cpp @@ -470,17 +470,19 @@ static uint64_t writeMemProfRecords( // Serialize MemProfFrameData. Return FrameTableOffset. static uint64_t writeMemProfFrames( ProfOStream &OS, - llvm::MapVector &MemProfFrameData) { + llvm::MapVector &MemProfFrameData, + memprof::IndexedVersion Version) { + memprof::FrameWriterTrait FrameWriter(Version); OnDiskChainedHashTableGenerator FrameTableGenerator; for (auto &[FrameId, Frame] : MemProfFrameData) { // Insert the key (frame id) and value (frame contents). - FrameTableGenerator.insert(FrameId, Frame); + FrameTableGenerator.insert(FrameId, Frame, FrameWriter); } // Release the memory of this MapVector as it is no longer needed. MemProfFrameData.clear(); - return FrameTableGenerator.Emit(OS.OS); + return FrameTableGenerator.Emit(OS.OS, FrameWriter); } static uint64_t writeMemProfCallStacks( @@ -514,7 +516,8 @@ static Error writeMemProfV0( writeMemProfRecords(OS, MemProfRecordData, &Schema, memprof::Version0); uint64_t FramePayloadOffset = OS.tell(); - uint64_t FrameTableOffset = writeMemProfFrames(OS, MemProfFrameData); + uint64_t FrameTableOffset = + writeMemProfFrames(OS, MemProfFrameData, memprof::Version0); uint64_t Header[] = {RecordTableOffset, FramePayloadOffset, FrameTableOffset}; OS.patch({{HeaderUpdatePos, Header, std::size(Header)}}); @@ -540,7 +543,8 @@ static Error writeMemProfV1( writeMemProfRecords(OS, MemProfRecordData, &Schema, memprof::Version1); uint64_t FramePayloadOffset = OS.tell(); - uint64_t FrameTableOffset = writeMemProfFrames(OS, MemProfFrameData); + uint64_t FrameTableOffset = + writeMemProfFrames(OS, MemProfFrameData, memprof::Version1); uint64_t Header[] = {RecordTableOffset, FramePayloadOffset, FrameTableOffset}; OS.patch({{HeaderUpdatePos, Header, std::size(Header)}}); @@ -570,7 +574,8 @@ static Error writeMemProfV2( writeMemProfRecords(OS, MemProfRecordData, &Schema, memprof::Version2); uint64_t FramePayloadOffset = OS.tell(); - uint64_t FrameTableOffset = writeMemProfFrames(OS, MemProfFrameData); + uint64_t FrameTableOffset = + writeMemProfFrames(OS, MemProfFrameData, memprof::Version2); uint64_t CallStackPayloadOffset = OS.tell(); uint64_t CallStackTableOffset =