Skip to content

Commit c74389b

Browse files
author
Snehasish Kumar
committed
[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
1 parent c46aab0 commit c74389b

File tree

2 files changed

+20
-4
lines changed

2 files changed

+20
-4
lines changed

llvm/include/llvm/ProfileData/MemProf.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ struct MemProfRecord {
161161
bool operator!=(const Frame &Other) const { return !operator==(Other); }
162162

163163
// Write the contents of the frame to the ostream \p OS.
164-
void write(raw_ostream & OS) const {
164+
void serialize(raw_ostream & OS) const {
165165
using namespace support;
166166

167167
endian::Writer LE(OS, little);
@@ -176,6 +176,22 @@ struct MemProfRecord {
176176
LE.write<uint32_t>(Column);
177177
LE.write<bool>(IsInlineFrame);
178178
}
179+
180+
// Read a frame from char data which has been serialized as little endian.
181+
static Frame deserialize(const unsigned char *Ptr) {
182+
using namespace support;
183+
return Frame(
184+
/*Function=*/endian::readNext<uint64_t, little, unaligned>(Ptr),
185+
/*LineOffset=*/endian::readNext<uint32_t, little, unaligned>(Ptr),
186+
/*Column=*/endian::readNext<uint32_t, little, unaligned>(Ptr),
187+
/*IsInlineFrame=*/endian::readNext<bool, little, unaligned>(Ptr));
188+
}
189+
190+
// Returns the size of the frame information.
191+
static constexpr size_t serializedSize() {
192+
return sizeof(Frame::Function) + sizeof(Frame::LineOffset) +
193+
sizeof(Frame::Column) + sizeof(Frame::IsInlineFrame);
194+
}
179195
});
180196

181197
// The dynamic calling context for the allocation.

llvm/lib/ProfileData/MemProf.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ void serializeRecords(const ArrayRef<MemProfRecord> Records,
1515
for (const MemProfRecord &MR : Records) {
1616
LE.write<uint64_t>(MR.CallStack.size());
1717
for (const MemProfRecord::Frame &F : MR.CallStack) {
18-
F.write(OS);
18+
F.serialize(OS);
1919
}
2020
MR.Info.serialize(Schema, OS);
2121
}
@@ -33,8 +33,8 @@ SmallVector<MemProfRecord, 4> deserializeRecords(const MemProfSchema &Schema,
3333
const uint64_t NumFrames =
3434
endian::readNext<uint64_t, little, unaligned>(Ptr);
3535
for (uint64_t J = 0; J < NumFrames; J++) {
36-
const auto F = *reinterpret_cast<const MemProfRecord::Frame *>(Ptr);
37-
Ptr += sizeof(MemProfRecord::Frame);
36+
const auto F = MemProfRecord::Frame::deserialize(Ptr);
37+
Ptr += MemProfRecord::Frame::serializedSize();
3838
MR.CallStack.push_back(F);
3939
}
4040
MR.Info.deserialize(Schema, Ptr);

0 commit comments

Comments
 (0)