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 | Arg: static_cast<uint32_t>(Val.Id), Args: Val.TotalSize); |
98 | } |
99 | static bool deserialize(SPSInputBuffer &IB, PerfJITRecordPrefix &Val) { |
100 | uint32_t Id; |
101 | if (!SPSPerfJITRecordPrefix::AsArgList::deserialize(IB, Arg&: Id, Args&: 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, Arg: static_cast<uint32_t>(Val.Id), Args: 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 | Arg: Val.Prefix, Args: Val.Pid, Args: Val.Tid, Args: Val.Vma, Args: Val.CodeAddr, Args: Val.CodeSize, |
122 | Args: Val.CodeIndex, Args: Val.Name); |
123 | } |
124 | |
125 | static bool deserialize(SPSInputBuffer &IB, PerfJITCodeLoadRecord &Val) { |
126 | return SPSPerfJITCodeLoadRecord::AsArgList::deserialize( |
127 | IB, Arg&: Val.Prefix, Args&: Val.Pid, Args&: Val.Tid, Args&: Val.Vma, Args&: Val.CodeAddr, Args&: Val.CodeSize, |
128 | Args&: Val.CodeIndex, Args&: Val.Name); |
129 | } |
130 | |
131 | static bool serialize(SPSOutputBuffer &OB, const PerfJITCodeLoadRecord &Val) { |
132 | return SPSPerfJITCodeLoadRecord::AsArgList::serialize( |
133 | OB, Arg: Val.Prefix, Args: Val.Pid, Args: Val.Tid, Args: Val.Vma, Args: Val.CodeAddr, Args: Val.CodeSize, |
134 | Args: Val.CodeIndex, Args: 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(Arg: Val.Addr, Args: Val.Lineno, |
145 | Args: Val.Discrim, Args: Val.Name); |
146 | } |
147 | |
148 | static bool deserialize(SPSInputBuffer &IB, PerfJITDebugEntry &Val) { |
149 | return SPSPerfJITDebugEntry::AsArgList::deserialize( |
150 | IB, Arg&: Val.Addr, Args&: Val.Lineno, Args&: Val.Discrim, Args&: Val.Name); |
151 | } |
152 | |
153 | static bool serialize(SPSOutputBuffer &OB, const PerfJITDebugEntry &Val) { |
154 | return SPSPerfJITDebugEntry::AsArgList::serialize(OB, Arg: Val.Addr, Args: Val.Lineno, |
155 | Args: Val.Discrim, Args: 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(Arg: Val.Prefix, Args: Val.CodeAddr, |
168 | Args: Val.Entries); |
169 | } |
170 | static bool deserialize(SPSInputBuffer &IB, PerfJITDebugInfoRecord &Val) { |
171 | return SPSPerfJITDebugInfoRecord::AsArgList::deserialize( |
172 | IB, Arg&: Val.Prefix, Args&: Val.CodeAddr, Args&: Val.Entries); |
173 | } |
174 | static bool serialize(SPSOutputBuffer &OB, |
175 | const PerfJITDebugInfoRecord &Val) { |
176 | return SPSPerfJITDebugInfoRecord::AsArgList::serialize( |
177 | OB, Arg: Val.Prefix, Args: Val.CodeAddr, Args: 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 | Arg: Val.Prefix, Args: Val.UnwindDataSize, Args: Val.EHFrameHdrSize, Args: Val.MappedSize, |
191 | Args: Val.EHFrameHdrAddr, Args: Val.EHFrameHdr, Args: Val.EHFrameAddr); |
192 | } |
193 | static bool deserialize(SPSInputBuffer &IB, |
194 | PerfJITCodeUnwindingInfoRecord &Val) { |
195 | return SPSPerfJITCodeUnwindingInfoRecord::AsArgList::deserialize( |
196 | IB, Arg&: Val.Prefix, Args&: Val.UnwindDataSize, Args&: Val.EHFrameHdrSize, Args&: Val.MappedSize, |
197 | Args&: Val.EHFrameHdrAddr, Args&: Val.EHFrameHdr, Args&: Val.EHFrameAddr); |
198 | } |
199 | static bool serialize(SPSOutputBuffer &OB, |
200 | const PerfJITCodeUnwindingInfoRecord &Val) { |
201 | return SPSPerfJITCodeUnwindingInfoRecord::AsArgList::serialize( |
202 | OB, Arg: Val.Prefix, Args: Val.UnwindDataSize, Args: Val.EHFrameHdrSize, Args: Val.MappedSize, |
203 | Args: Val.EHFrameHdrAddr, Args: Val.EHFrameHdr, Args: 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 | Arg: Val.CodeLoadRecords, Args: Val.DebugInfoRecords, Args: Val.UnwindingRecord); |
216 | } |
217 | static bool deserialize(SPSInputBuffer &IB, PerfJITRecordBatch &Val) { |
218 | return SPSPerfJITRecordBatch::AsArgList::deserialize( |
219 | IB, Arg&: Val.CodeLoadRecords, Args&: Val.DebugInfoRecords, Args&: Val.UnwindingRecord); |
220 | } |
221 | static bool serialize(SPSOutputBuffer &OB, const PerfJITRecordBatch &Val) { |
222 | return SPSPerfJITRecordBatch::AsArgList::serialize( |
223 | OB, Arg: Val.CodeLoadRecords, Args: Val.DebugInfoRecords, Args: Val.UnwindingRecord); |
224 | } |
225 | }; |
226 | |
227 | } // namespace shared |
228 | |
229 | } // namespace orc |
230 | |
231 | } // namespace llvm |
232 | |
233 | #endif |