#include "llvm/ProfileData/MemProf.h" #include "llvm/Support/Endian.h" #include "llvm/Support/EndianStream.h" namespace llvm { namespace memprof { void serializeRecords(const ArrayRef Records, const MemProfSchema &Schema, raw_ostream &OS) { using namespace support; endian::Writer LE(OS, little); LE.write(Records.size()); for (const MemProfRecord &MR : Records) { LE.write(MR.CallStack.size()); for (const MemProfRecord::Frame &F : MR.CallStack) { F.serialize(OS); } MR.Info.serialize(Schema, OS); } } SmallVector deserializeRecords(const MemProfSchema &Schema, const unsigned char *Ptr) { using namespace support; SmallVector Records; const uint64_t NumRecords = endian::readNext(Ptr); for (uint64_t I = 0; I < NumRecords; I++) { MemProfRecord MR; const uint64_t NumFrames = endian::readNext(Ptr); for (uint64_t J = 0; J < NumFrames; J++) { const auto F = MemProfRecord::Frame::deserialize(Ptr); Ptr += MemProfRecord::Frame::serializedSize(); MR.CallStack.push_back(F); } MR.Info.deserialize(Schema, Ptr); Ptr += PortableMemInfoBlock::serializedSize(); Records.push_back(MR); } return Records; } Expected readMemProfSchema(const unsigned char *&Buffer) { using namespace support; const unsigned char *Ptr = Buffer; const uint64_t NumSchemaIds = endian::readNext(Ptr); if (NumSchemaIds > static_cast(Meta::Size)) { return make_error(instrprof_error::malformed, "memprof schema invalid"); } MemProfSchema Result; for (size_t I = 0; I < NumSchemaIds; I++) { const uint64_t Tag = endian::readNext(Ptr); if (Tag >= static_cast(Meta::Size)) { return make_error(instrprof_error::malformed, "memprof schema invalid"); } Result.push_back(static_cast(Tag)); } // Advace the buffer to one past the schema if we succeeded. Buffer = Ptr; return Result; } } // namespace memprof } // namespace llvm