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