[XRay] Fix FunctionRecord serialization

This change makes the writer implementation more consistent with the way
fields are written down to avoid assumptions on bitfield order and
padding. We also fix an inconsistency between the type returned by the
`delta()` accessor to match the data member it's returning.

This is a follow-up to D51289 and D51210.

llvm-svn: 341230
This commit is contained in:
Dean Michael Berris 2018-08-31 17:49:59 +00:00
parent 5abf7d90ac
commit c1dceee50b
2 changed files with 10 additions and 31 deletions

View File

@ -244,7 +244,7 @@ public:
// properties.
RecordTypes recordType() const { return Kind; }
int32_t functionId() const { return FuncId; }
uint64_t delta() const { return Delta; }
uint32_t delta() const { return Delta; }
Error apply(RecordVisitor &V) override;
};

View File

@ -18,27 +18,6 @@ namespace xray {
namespace {
struct alignas(32) FileHeader {
uint16_t Version;
uint16_t Type;
uint32_t BitField;
uint64_t CycleFrequency;
char FreeForm[16];
};
struct MetadataBlob {
uint8_t Type : 1;
uint8_t RecordKind : 7;
char Data[15];
};
struct FunctionDeltaBlob {
uint8_t Type : 1;
uint8_t RecordKind : 3;
int FuncId : 28;
uint32_t TSCDelta;
};
template <size_t Index> struct IndexedWriter {
template <
class Tuple,
@ -139,16 +118,16 @@ Error FDRTraceWriter::visit(EndBufferRecord &R) {
}
Error FDRTraceWriter::visit(FunctionRecord &R) {
FunctionDeltaBlob B;
B.Type = 0;
B.RecordKind = static_cast<uint8_t>(R.recordType());
B.FuncId = R.functionId();
B.TSCDelta = R.delta();
ArrayRef<char> Bytes(reinterpret_cast<const char *>(&B),
sizeof(FunctionDeltaBlob));
OS.write(Bytes);
// Write out the data in "field" order, to be endian-aware.
uint32_t TypeRecordFuncId = uint32_t{R.functionId() & ~uint32_t{0x0Fu << 28}};
TypeRecordFuncId <<= 3;
TypeRecordFuncId |= static_cast<uint32_t>(R.recordType());
TypeRecordFuncId <<= 1;
TypeRecordFuncId &= ~uint32_t{0x01};
OS.write(TypeRecordFuncId);
OS.write(R.delta());
return Error::success();
}
} // namespace xray
} // namespace xray
} // namespace llvm