1 //===--- PerfSharedStructs.h --- RPC Structs for perf support ---*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Structs and serialization to share perf-related information 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_PERFSHAREDSTRUCTS_H 14 #define LLVM_EXECUTIONENGINE_ORC_SHARED_PERFSHAREDSTRUCTS_H 15 16 #include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h" 17 18 namespace llvm { 19 20 namespace orc { 21 22 // The following are POD struct definitions from the perf jit specification 23 24 enum class PerfJITRecordType { 25 JIT_CODE_LOAD = 0, 26 JIT_CODE_MOVE = 1, // not emitted, code isn't moved 27 JIT_CODE_DEBUG_INFO = 2, 28 JIT_CODE_CLOSE = 3, // not emitted, unnecessary 29 JIT_CODE_UNWINDING_INFO = 4, // not emitted 30 31 JIT_CODE_MAX 32 }; 33 34 struct PerfJITRecordPrefix { 35 PerfJITRecordType Id; // record type identifier, uint32_t 36 uint32_t TotalSize; 37 }; 38 struct PerfJITCodeLoadRecord { 39 PerfJITRecordPrefix Prefix; 40 41 uint32_t Pid; 42 uint32_t Tid; 43 uint64_t Vma; 44 uint64_t CodeAddr; 45 uint64_t CodeSize; 46 uint64_t CodeIndex; 47 std::string Name; 48 }; 49 50 struct PerfJITDebugEntry { 51 uint64_t Addr; 52 uint32_t Lineno; // source line number starting at 1 53 uint32_t Discrim; // column discriminator, 0 is default 54 std::string Name; 55 }; 56 57 struct PerfJITDebugInfoRecord { 58 PerfJITRecordPrefix Prefix; 59 60 uint64_t CodeAddr; 61 std::vector<PerfJITDebugEntry> Entries; 62 }; 63 64 struct PerfJITCodeUnwindingInfoRecord { 65 PerfJITRecordPrefix Prefix; 66 67 uint64_t UnwindDataSize; 68 uint64_t EHFrameHdrSize; 69 uint64_t MappedSize; 70 // Union, one will always be 0/"", the other has data 71 uint64_t EHFrameHdrAddr; 72 std::string EHFrameHdr; 73 74 uint64_t EHFrameAddr; 75 // size is UnwindDataSize - EHFrameHdrSize 76 }; 77 78 // Batch vehicle for minimizing RPC calls for perf jit records 79 struct PerfJITRecordBatch { 80 std::vector<PerfJITDebugInfoRecord> DebugInfoRecords; 81 std::vector<PerfJITCodeLoadRecord> CodeLoadRecords; 82 // only valid if record size > 0 83 PerfJITCodeUnwindingInfoRecord UnwindingRecord; 84 }; 85 86 // SPS traits for Records 87 88 namespace shared { 89 90 using SPSPerfJITRecordPrefix = SPSTuple<uint32_t, uint32_t>; 91 92 template <> 93 class SPSSerializationTraits<SPSPerfJITRecordPrefix, PerfJITRecordPrefix> { 94 public: 95 static size_t size(const PerfJITRecordPrefix &Val) { 96 return SPSPerfJITRecordPrefix::AsArgList::size( 97 static_cast<uint32_t>(Val.Id), Val.TotalSize); 98 } 99 static bool deserialize(SPSInputBuffer &IB, PerfJITRecordPrefix &Val) { 100 uint32_t Id; 101 if (!SPSPerfJITRecordPrefix::AsArgList::deserialize(IB, Id, Val.TotalSize)) 102 return false; 103 Val.Id = static_cast<PerfJITRecordType>(Id); 104 return true; 105 } 106 static bool serialize(SPSOutputBuffer &OB, const PerfJITRecordPrefix &Val) { 107 return SPSPerfJITRecordPrefix::AsArgList::serialize( 108 OB, static_cast<uint32_t>(Val.Id), Val.TotalSize); 109 } 110 }; 111 112 using SPSPerfJITCodeLoadRecord = 113 SPSTuple<SPSPerfJITRecordPrefix, uint32_t, uint32_t, uint64_t, uint64_t, 114 uint64_t, uint64_t, SPSString>; 115 116 template <> 117 class SPSSerializationTraits<SPSPerfJITCodeLoadRecord, PerfJITCodeLoadRecord> { 118 public: 119 static size_t size(const PerfJITCodeLoadRecord &Val) { 120 return SPSPerfJITCodeLoadRecord::AsArgList::size( 121 Val.Prefix, Val.Pid, Val.Tid, Val.Vma, Val.CodeAddr, Val.CodeSize, 122 Val.CodeIndex, Val.Name); 123 } 124 125 static bool deserialize(SPSInputBuffer &IB, PerfJITCodeLoadRecord &Val) { 126 return SPSPerfJITCodeLoadRecord::AsArgList::deserialize( 127 IB, Val.Prefix, Val.Pid, Val.Tid, Val.Vma, Val.CodeAddr, Val.CodeSize, 128 Val.CodeIndex, Val.Name); 129 } 130 131 static bool serialize(SPSOutputBuffer &OB, const PerfJITCodeLoadRecord &Val) { 132 return SPSPerfJITCodeLoadRecord::AsArgList::serialize( 133 OB, Val.Prefix, Val.Pid, Val.Tid, Val.Vma, Val.CodeAddr, Val.CodeSize, 134 Val.CodeIndex, Val.Name); 135 } 136 }; 137 138 using SPSPerfJITDebugEntry = SPSTuple<uint64_t, uint32_t, uint32_t, SPSString>; 139 140 template <> 141 class SPSSerializationTraits<SPSPerfJITDebugEntry, PerfJITDebugEntry> { 142 public: 143 static size_t size(const PerfJITDebugEntry &Val) { 144 return SPSPerfJITDebugEntry::AsArgList::size(Val.Addr, Val.Lineno, 145 Val.Discrim, Val.Name); 146 } 147 148 static bool deserialize(SPSInputBuffer &IB, PerfJITDebugEntry &Val) { 149 return SPSPerfJITDebugEntry::AsArgList::deserialize( 150 IB, Val.Addr, Val.Lineno, Val.Discrim, Val.Name); 151 } 152 153 static bool serialize(SPSOutputBuffer &OB, const PerfJITDebugEntry &Val) { 154 return SPSPerfJITDebugEntry::AsArgList::serialize(OB, Val.Addr, Val.Lineno, 155 Val.Discrim, Val.Name); 156 } 157 }; 158 159 using SPSPerfJITDebugInfoRecord = SPSTuple<SPSPerfJITRecordPrefix, uint64_t, 160 SPSSequence<SPSPerfJITDebugEntry>>; 161 162 template <> 163 class SPSSerializationTraits<SPSPerfJITDebugInfoRecord, 164 PerfJITDebugInfoRecord> { 165 public: 166 static size_t size(const PerfJITDebugInfoRecord &Val) { 167 return SPSPerfJITDebugInfoRecord::AsArgList::size(Val.Prefix, Val.CodeAddr, 168 Val.Entries); 169 } 170 static bool deserialize(SPSInputBuffer &IB, PerfJITDebugInfoRecord &Val) { 171 return SPSPerfJITDebugInfoRecord::AsArgList::deserialize( 172 IB, Val.Prefix, Val.CodeAddr, Val.Entries); 173 } 174 static bool serialize(SPSOutputBuffer &OB, 175 const PerfJITDebugInfoRecord &Val) { 176 return SPSPerfJITDebugInfoRecord::AsArgList::serialize( 177 OB, Val.Prefix, Val.CodeAddr, Val.Entries); 178 } 179 }; 180 181 using SPSPerfJITCodeUnwindingInfoRecord = 182 SPSTuple<SPSPerfJITRecordPrefix, uint64_t, uint64_t, uint64_t, uint64_t, 183 SPSString, uint64_t>; 184 template <> 185 class SPSSerializationTraits<SPSPerfJITCodeUnwindingInfoRecord, 186 PerfJITCodeUnwindingInfoRecord> { 187 public: 188 static size_t size(const PerfJITCodeUnwindingInfoRecord &Val) { 189 return SPSPerfJITCodeUnwindingInfoRecord::AsArgList::size( 190 Val.Prefix, Val.UnwindDataSize, Val.EHFrameHdrSize, Val.MappedSize, 191 Val.EHFrameHdrAddr, Val.EHFrameHdr, Val.EHFrameAddr); 192 } 193 static bool deserialize(SPSInputBuffer &IB, 194 PerfJITCodeUnwindingInfoRecord &Val) { 195 return SPSPerfJITCodeUnwindingInfoRecord::AsArgList::deserialize( 196 IB, Val.Prefix, Val.UnwindDataSize, Val.EHFrameHdrSize, Val.MappedSize, 197 Val.EHFrameHdrAddr, Val.EHFrameHdr, Val.EHFrameAddr); 198 } 199 static bool serialize(SPSOutputBuffer &OB, 200 const PerfJITCodeUnwindingInfoRecord &Val) { 201 return SPSPerfJITCodeUnwindingInfoRecord::AsArgList::serialize( 202 OB, Val.Prefix, Val.UnwindDataSize, Val.EHFrameHdrSize, Val.MappedSize, 203 Val.EHFrameHdrAddr, Val.EHFrameHdr, Val.EHFrameAddr); 204 } 205 }; 206 207 using SPSPerfJITRecordBatch = SPSTuple<SPSSequence<SPSPerfJITCodeLoadRecord>, 208 SPSSequence<SPSPerfJITDebugInfoRecord>, 209 SPSPerfJITCodeUnwindingInfoRecord>; 210 template <> 211 class SPSSerializationTraits<SPSPerfJITRecordBatch, PerfJITRecordBatch> { 212 public: 213 static size_t size(const PerfJITRecordBatch &Val) { 214 return SPSPerfJITRecordBatch::AsArgList::size( 215 Val.CodeLoadRecords, Val.DebugInfoRecords, Val.UnwindingRecord); 216 } 217 static bool deserialize(SPSInputBuffer &IB, PerfJITRecordBatch &Val) { 218 return SPSPerfJITRecordBatch::AsArgList::deserialize( 219 IB, Val.CodeLoadRecords, Val.DebugInfoRecords, Val.UnwindingRecord); 220 } 221 static bool serialize(SPSOutputBuffer &OB, const PerfJITRecordBatch &Val) { 222 return SPSPerfJITRecordBatch::AsArgList::serialize( 223 OB, Val.CodeLoadRecords, Val.DebugInfoRecords, Val.UnwindingRecord); 224 } 225 }; 226 227 } // namespace shared 228 229 } // namespace orc 230 231 } // namespace llvm 232 233 #endif