@@ -214,23 +214,13 @@ static Error writeMemProfV2(ProfOStream &OS,
214214 return Error::success ();
215215}
216216
217- // Write out MemProf Version3 as follows:
218- // uint64_t Version
219- // uint64_t CallStackPayloadOffset = Offset for the call stack payload
220- // uint64_t RecordPayloadOffset = Offset for the record payload
221- // uint64_t RecordTableOffset = RecordTableGenerator.Emit
222- // uint64_t Num schema entries
223- // uint64_t Schema entry 0
224- // uint64_t Schema entry 1
225- // ....
226- // uint64_t Schema entry N - 1
227- // Frames serialized one after another
228- // Call stacks encoded as a radix tree
229- // OnDiskChainedHashTable MemProfRecordData
230- static Error writeMemProfV3 (ProfOStream &OS,
231- memprof::IndexedMemProfData &MemProfData,
232- bool MemProfFullSchema) {
233- OS.write (memprof::Version3);
217+ static Error writeMemProfRadixTreeBased (
218+ ProfOStream &OS, memprof::IndexedMemProfData &MemProfData,
219+ memprof::IndexedVersion Version, bool MemProfFullSchema) {
220+ assert ((Version == memprof::Version3 || Version == memprof::Version4) &&
221+ " Unsupported version for radix tree format" );
222+
223+ OS.write (Version); // Write the specific version (V3 or V4)
234224 uint64_t HeaderUpdatePos = OS.tell ();
235225 OS.write (0ULL ); // Reserve space for the memprof call stack payload offset.
236226 OS.write (0ULL ); // Reserve space for the memprof record payload offset.
@@ -258,13 +248,12 @@ static Error writeMemProfV3(ProfOStream &OS,
258248 NumElements);
259249
260250 uint64_t RecordPayloadOffset = OS.tell ();
261- uint64_t RecordTableOffset =
262- writeMemProfRecords ( OS, MemProfData.Records , &Schema, memprof::Version3,
263- &MemProfCallStackIndexes);
251+ uint64_t RecordTableOffset = writeMemProfRecords (
252+ OS, MemProfData.Records , &Schema, Version, // Pass Version
253+ &MemProfCallStackIndexes);
264254
265- // IndexedMemProfReader::deserializeV3 computes the number of elements in the
266- // call stack array from the difference between CallStackPayloadOffset and
267- // RecordPayloadOffset. Verify that the computation works.
255+ // Verify that the computation for the number of elements in the call stack
256+ // array works.
268257 assert (CallStackPayloadOffset +
269258 NumElements * sizeof (memprof::LinearFrameId) ==
270259 RecordPayloadOffset);
@@ -279,15 +268,34 @@ static Error writeMemProfV3(ProfOStream &OS,
279268 return Error::success ();
280269}
281270
271+ // Write out MemProf Version3
272+ static Error writeMemProfV3 (ProfOStream &OS,
273+ memprof::IndexedMemProfData &MemProfData,
274+ bool MemProfFullSchema) {
275+ return writeMemProfRadixTreeBased (OS, MemProfData, memprof::Version3,
276+ MemProfFullSchema);
277+ }
278+
279+ // Write out MemProf Version4
280+ static Error writeMemProfV4 (ProfOStream &OS,
281+ memprof::IndexedMemProfData &MemProfData,
282+ bool MemProfFullSchema) {
283+ return writeMemProfRadixTreeBased (OS, MemProfData, memprof::Version4,
284+ MemProfFullSchema);
285+ }
286+
282287// Write out the MemProf data in a requested version.
283- Error writeMemProf (ProfOStream &OS, memprof::IndexedMemProfData &MemProfData,
284- memprof::IndexedVersion MemProfVersionRequested,
285- bool MemProfFullSchema) {
288+ Error writeMemProf (ProfOStream &OS,
289+ memprof::IndexedMemProfData &MemProfData,
290+ memprof::IndexedVersion MemProfVersionRequested,
291+ bool MemProfFullSchema) {
286292 switch (MemProfVersionRequested) {
287293 case memprof::Version2:
288294 return writeMemProfV2 (OS, MemProfData, MemProfFullSchema);
289295 case memprof::Version3:
290296 return writeMemProfV3 (OS, MemProfData, MemProfFullSchema);
297+ case memprof::Version4:
298+ return writeMemProfV4 (OS, MemProfData, MemProfFullSchema);
291299 }
292300
293301 return make_error<InstrProfError>(
@@ -350,8 +358,8 @@ Error IndexedMemProfReader::deserializeV2(const unsigned char *Start,
350358 return Error::success ();
351359}
352360
353- Error IndexedMemProfReader::deserializeV3 ( const unsigned char *Start,
354- const unsigned char *Ptr) {
361+ Error IndexedMemProfReader::deserializeRadixTreeBased (
362+ const unsigned char *Start, const unsigned char *Ptr) {
355363 // The offset in the stream right before invoking
356364 // CallStackTableGenerator.Emit.
357365 const uint64_t CallStackPayloadOffset =
@@ -382,7 +390,7 @@ Error IndexedMemProfReader::deserializeV3(const unsigned char *Start,
382390 MemProfRecordTable.reset (MemProfRecordHashTable::Create (
383391 /* Buckets=*/ Start + RecordTableOffset,
384392 /* Payload=*/ Start + RecordPayloadOffset,
385- /* Base=*/ Start, memprof::RecordLookupTrait (memprof::Version3 , Schema)));
393+ /* Base=*/ Start, memprof::RecordLookupTrait (Version , Schema)));
386394
387395 return Error::success ();
388396}
@@ -395,8 +403,10 @@ Error IndexedMemProfReader::deserialize(const unsigned char *Start,
395403 const uint64_t FirstWord =
396404 support::endian::readNext<uint64_t , llvm::endianness::little>(Ptr);
397405
398- if (FirstWord == memprof::Version2 || FirstWord == memprof::Version3) {
399- // Everything is good. We can proceed to deserialize the rest.
406+ // Check if the version is supported
407+ if (FirstWord >= memprof::MinimumSupportedVersion &&
408+ FirstWord <= memprof::MaximumSupportedVersion) {
409+ // Everything is good. We can proceed to deserialize the rest.
400410 Version = static_cast <memprof::IndexedVersion>(FirstWord);
401411 } else {
402412 return make_error<InstrProfError>(
@@ -413,12 +423,13 @@ Error IndexedMemProfReader::deserialize(const unsigned char *Start,
413423 return E;
414424 break ;
415425 case memprof::Version3:
416- if (Error E = deserializeV3 (Start, Ptr))
426+ case memprof::Version4:
427+ // V3 and V4 share the same high-level structure (radix tree, linear IDs).
428+ if (Error E = deserializeRadixTreeBased (Start, Ptr))
417429 return E;
418430 break ;
419431 }
420432
421433 return Error::success ();
422434}
423-
424435} // namespace llvm
0 commit comments