//===--- PerfSharedStructs.h --- RPC Structs for perf support ---*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Structs and serialization to share perf-related information // //===----------------------------------------------------------------------===// #ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_PERFSHAREDSTRUCTS_H #define LLVM_EXECUTIONENGINE_ORC_SHARED_PERFSHAREDSTRUCTS_H #include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h" namespace llvm { namespace orc { // The following are POD struct definitions from the perf jit specification enum class PerfJITRecordType { JIT_CODE_LOAD = 0, JIT_CODE_MOVE = 1, // not emitted, code isn't moved JIT_CODE_DEBUG_INFO = 2, JIT_CODE_CLOSE = 3, // not emitted, unnecessary JIT_CODE_UNWINDING_INFO = 4, // not emitted JIT_CODE_MAX }; struct PerfJITRecordPrefix { PerfJITRecordType Id; // record type identifier, uint32_t uint32_t TotalSize; }; struct PerfJITCodeLoadRecord { PerfJITRecordPrefix Prefix; uint32_t Pid; uint32_t Tid; uint64_t Vma; uint64_t CodeAddr; uint64_t CodeSize; uint64_t CodeIndex; std::string Name; }; struct PerfJITDebugEntry { uint64_t Addr; uint32_t Lineno; // source line number starting at 1 uint32_t Discrim; // column discriminator, 0 is default std::string Name; }; struct PerfJITDebugInfoRecord { PerfJITRecordPrefix Prefix; uint64_t CodeAddr; std::vector Entries; }; struct PerfJITCodeUnwindingInfoRecord { PerfJITRecordPrefix Prefix; uint64_t UnwindDataSize; uint64_t EHFrameHdrSize; uint64_t MappedSize; // Union, one will always be 0/"", the other has data uint64_t EHFrameHdrAddr; std::string EHFrameHdr; uint64_t EHFrameAddr; // size is UnwindDataSize - EHFrameHdrSize }; // Batch vehicle for minimizing RPC calls for perf jit records struct PerfJITRecordBatch { std::vector DebugInfoRecords; std::vector CodeLoadRecords; // only valid if record size > 0 PerfJITCodeUnwindingInfoRecord UnwindingRecord; }; // SPS traits for Records namespace shared { using SPSPerfJITRecordPrefix = SPSTuple; template <> class SPSSerializationTraits { public: static size_t size(const PerfJITRecordPrefix &Val) { return SPSPerfJITRecordPrefix::AsArgList::size( static_cast(Val.Id), Val.TotalSize); } static bool deserialize(SPSInputBuffer &IB, PerfJITRecordPrefix &Val) { uint32_t Id; if (!SPSPerfJITRecordPrefix::AsArgList::deserialize(IB, Id, Val.TotalSize)) return false; Val.Id = static_cast(Id); return true; } static bool serialize(SPSOutputBuffer &OB, const PerfJITRecordPrefix &Val) { return SPSPerfJITRecordPrefix::AsArgList::serialize( OB, static_cast(Val.Id), Val.TotalSize); } }; using SPSPerfJITCodeLoadRecord = SPSTuple; template <> class SPSSerializationTraits { public: static size_t size(const PerfJITCodeLoadRecord &Val) { return SPSPerfJITCodeLoadRecord::AsArgList::size( Val.Prefix, Val.Pid, Val.Tid, Val.Vma, Val.CodeAddr, Val.CodeSize, Val.CodeIndex, Val.Name); } static bool deserialize(SPSInputBuffer &IB, PerfJITCodeLoadRecord &Val) { return SPSPerfJITCodeLoadRecord::AsArgList::deserialize( IB, Val.Prefix, Val.Pid, Val.Tid, Val.Vma, Val.CodeAddr, Val.CodeSize, Val.CodeIndex, Val.Name); } static bool serialize(SPSOutputBuffer &OB, const PerfJITCodeLoadRecord &Val) { return SPSPerfJITCodeLoadRecord::AsArgList::serialize( OB, Val.Prefix, Val.Pid, Val.Tid, Val.Vma, Val.CodeAddr, Val.CodeSize, Val.CodeIndex, Val.Name); } }; using SPSPerfJITDebugEntry = SPSTuple; template <> class SPSSerializationTraits { public: static size_t size(const PerfJITDebugEntry &Val) { return SPSPerfJITDebugEntry::AsArgList::size(Val.Addr, Val.Lineno, Val.Discrim, Val.Name); } static bool deserialize(SPSInputBuffer &IB, PerfJITDebugEntry &Val) { return SPSPerfJITDebugEntry::AsArgList::deserialize( IB, Val.Addr, Val.Lineno, Val.Discrim, Val.Name); } static bool serialize(SPSOutputBuffer &OB, const PerfJITDebugEntry &Val) { return SPSPerfJITDebugEntry::AsArgList::serialize(OB, Val.Addr, Val.Lineno, Val.Discrim, Val.Name); } }; using SPSPerfJITDebugInfoRecord = SPSTuple>; template <> class SPSSerializationTraits { public: static size_t size(const PerfJITDebugInfoRecord &Val) { return SPSPerfJITDebugInfoRecord::AsArgList::size(Val.Prefix, Val.CodeAddr, Val.Entries); } static bool deserialize(SPSInputBuffer &IB, PerfJITDebugInfoRecord &Val) { return SPSPerfJITDebugInfoRecord::AsArgList::deserialize( IB, Val.Prefix, Val.CodeAddr, Val.Entries); } static bool serialize(SPSOutputBuffer &OB, const PerfJITDebugInfoRecord &Val) { return SPSPerfJITDebugInfoRecord::AsArgList::serialize( OB, Val.Prefix, Val.CodeAddr, Val.Entries); } }; using SPSPerfJITCodeUnwindingInfoRecord = SPSTuple; template <> class SPSSerializationTraits { public: static size_t size(const PerfJITCodeUnwindingInfoRecord &Val) { return SPSPerfJITCodeUnwindingInfoRecord::AsArgList::size( Val.Prefix, Val.UnwindDataSize, Val.EHFrameHdrSize, Val.MappedSize, Val.EHFrameHdrAddr, Val.EHFrameHdr, Val.EHFrameAddr); } static bool deserialize(SPSInputBuffer &IB, PerfJITCodeUnwindingInfoRecord &Val) { return SPSPerfJITCodeUnwindingInfoRecord::AsArgList::deserialize( IB, Val.Prefix, Val.UnwindDataSize, Val.EHFrameHdrSize, Val.MappedSize, Val.EHFrameHdrAddr, Val.EHFrameHdr, Val.EHFrameAddr); } static bool serialize(SPSOutputBuffer &OB, const PerfJITCodeUnwindingInfoRecord &Val) { return SPSPerfJITCodeUnwindingInfoRecord::AsArgList::serialize( OB, Val.Prefix, Val.UnwindDataSize, Val.EHFrameHdrSize, Val.MappedSize, Val.EHFrameHdrAddr, Val.EHFrameHdr, Val.EHFrameAddr); } }; using SPSPerfJITRecordBatch = SPSTuple, SPSSequence, SPSPerfJITCodeUnwindingInfoRecord>; template <> class SPSSerializationTraits { public: static size_t size(const PerfJITRecordBatch &Val) { return SPSPerfJITRecordBatch::AsArgList::size( Val.CodeLoadRecords, Val.DebugInfoRecords, Val.UnwindingRecord); } static bool deserialize(SPSInputBuffer &IB, PerfJITRecordBatch &Val) { return SPSPerfJITRecordBatch::AsArgList::deserialize( IB, Val.CodeLoadRecords, Val.DebugInfoRecords, Val.UnwindingRecord); } static bool serialize(SPSOutputBuffer &OB, const PerfJITRecordBatch &Val) { return SPSPerfJITRecordBatch::AsArgList::serialize( OB, Val.CodeLoadRecords, Val.DebugInfoRecords, Val.UnwindingRecord); } }; } // namespace shared } // namespace orc } // namespace llvm #endif