[llvm] c74389b - [memprof] Fix frame deserialization on big endian systems.

Snehasish Kumar via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 17 15:31:37 PST 2022


Author: Snehasish Kumar
Date: 2022-02-17T15:31:22-08:00
New Revision: c74389b4b58d8db3f8262ce15b9d514d62fe265c

URL: https://github.com/llvm/llvm-project/commit/c74389b4b58d8db3f8262ce15b9d514d62fe265c
DIFF: https://github.com/llvm/llvm-project/commit/c74389b4b58d8db3f8262ce15b9d514d62fe265c.diff

LOG: [memprof] Fix frame deserialization on big endian systems.

We write the memprof internal call frame data in little endian format.
However when reading the frame information we were casting it directly
to a MemProfRecord::Frame pointer. In this change we add a separate
deserialization method which uses an endian reader to read the bytes as
little endian.

This fixes https://lab.llvm.org/buildbot/#/builders/100/builds/12940

Differential Revision: https://reviews.llvm.org/D120093

Added: 
    

Modified: 
    llvm/include/llvm/ProfileData/MemProf.h
    llvm/lib/ProfileData/MemProf.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ProfileData/MemProf.h b/llvm/include/llvm/ProfileData/MemProf.h
index dcc9b69386e8a..07bf629ce146a 100644
--- a/llvm/include/llvm/ProfileData/MemProf.h
+++ b/llvm/include/llvm/ProfileData/MemProf.h
@@ -161,7 +161,7 @@ struct MemProfRecord {
     bool operator!=(const Frame &Other) const { return !operator==(Other); }
 
     // Write the contents of the frame to the ostream \p OS.
-    void write(raw_ostream & OS) const {
+    void serialize(raw_ostream & OS) const {
       using namespace support;
 
       endian::Writer LE(OS, little);
@@ -176,6 +176,22 @@ struct MemProfRecord {
       LE.write<uint32_t>(Column);
       LE.write<bool>(IsInlineFrame);
     }
+
+    // Read a frame from char data which has been serialized as little endian.
+    static Frame deserialize(const unsigned char *Ptr) {
+      using namespace support;
+      return Frame(
+          /*Function=*/endian::readNext<uint64_t, little, unaligned>(Ptr),
+          /*LineOffset=*/endian::readNext<uint32_t, little, unaligned>(Ptr),
+          /*Column=*/endian::readNext<uint32_t, little, unaligned>(Ptr),
+          /*IsInlineFrame=*/endian::readNext<bool, little, unaligned>(Ptr));
+    }
+
+    // Returns the size of the frame information.
+    static constexpr size_t serializedSize() {
+      return sizeof(Frame::Function) + sizeof(Frame::LineOffset) +
+             sizeof(Frame::Column) + sizeof(Frame::IsInlineFrame);
+    }
   });
 
   // The dynamic calling context for the allocation.

diff  --git a/llvm/lib/ProfileData/MemProf.cpp b/llvm/lib/ProfileData/MemProf.cpp
index 6a9b69ff6cff0..48950d41d0234 100644
--- a/llvm/lib/ProfileData/MemProf.cpp
+++ b/llvm/lib/ProfileData/MemProf.cpp
@@ -15,7 +15,7 @@ void serializeRecords(const ArrayRef<MemProfRecord> Records,
   for (const MemProfRecord &MR : Records) {
     LE.write<uint64_t>(MR.CallStack.size());
     for (const MemProfRecord::Frame &F : MR.CallStack) {
-      F.write(OS);
+      F.serialize(OS);
     }
     MR.Info.serialize(Schema, OS);
   }
@@ -33,8 +33,8 @@ SmallVector<MemProfRecord, 4> deserializeRecords(const MemProfSchema &Schema,
     const uint64_t NumFrames =
         endian::readNext<uint64_t, little, unaligned>(Ptr);
     for (uint64_t J = 0; J < NumFrames; J++) {
-      const auto F = *reinterpret_cast<const MemProfRecord::Frame *>(Ptr);
-      Ptr += sizeof(MemProfRecord::Frame);
+      const auto F = MemProfRecord::Frame::deserialize(Ptr);
+      Ptr += MemProfRecord::Frame::serializedSize();
       MR.CallStack.push_back(F);
     }
     MR.Info.deserialize(Schema, Ptr);


        


More information about the llvm-commits mailing list