1//
2// Copyright (c) Microsoft. All rights reserved.
3// Licensed under the MIT license. See LICENSE file in the project root for full license information.
4//
5//----------------------------------------------------------
6// CompileResult.h - CompileResult contains the stuff generated by a compilation
7//----------------------------------------------------------
8#ifndef _CompileResult
9#define _CompileResult
10
11#include "runtimedetails.h"
12#include "lightweightmap.h"
13
14class CompileResult
15{
16public:
17#pragma pack(push, 1)
18 struct Agnostic_RecordRelocation
19 {
20 DWORDLONG location;
21 DWORDLONG target;
22 DWORD fRelocType;
23 DWORD slotNum;
24 DWORD addlDelta;
25 };
26 struct Capture_AllocMemDetails
27 {
28 ULONG hotCodeSize;
29 ULONG coldCodeSize;
30 ULONG roDataSize;
31 ULONG xcptnsCount;
32 CorJitAllocMemFlag flag;
33 void* hotCodeBlock;
34 void* coldCodeBlock;
35 void* roDataBlock;
36 };
37 struct allocGCInfoDetails
38 {
39 size_t size;
40 void* retval;
41 };
42 struct Agnostic_AddressMap
43 {
44 DWORDLONG Address;
45 DWORD size;
46 };
47 struct Agnostic_AllocGCInfo
48 {
49 DWORDLONG size;
50 DWORD retval_offset;
51 };
52 struct Agnostic_AllocMemDetails
53 {
54 DWORD hotCodeSize;
55 DWORD coldCodeSize;
56 DWORD roDataSize;
57 DWORD xcptnsCount;
58 DWORD flag;
59 DWORD hotCodeBlock_offset;
60 DWORD coldCodeBlock_offset;
61 DWORD roDataBlock_offset;
62 DWORDLONG hotCodeBlock;
63 DWORDLONG coldCodeBlock;
64 DWORDLONG roDataBlock;
65 };
66 struct Agnostic_AllocUnwindInfo
67 {
68 DWORDLONG pHotCode;
69 DWORDLONG pColdCode;
70 DWORD startOffset;
71 DWORD endOffset;
72 DWORD unwindSize;
73 DWORD pUnwindBlock_index;
74 DWORD funcKind;
75 };
76 struct Agnostic_CompileMethodResults
77 {
78 DWORDLONG nativeEntry;
79 DWORD nativeSizeOfCode;
80 DWORD CorJitResult;
81 };
82 struct Agnostic_ReportInliningDecision
83 {
84 DWORDLONG inlinerHnd;
85 DWORDLONG inlineeHnd;
86 DWORD inlineResult;
87 DWORD reason_offset;
88 };
89 struct Agnostic_ReportTailCallDecision
90 {
91 DWORDLONG callerHnd;
92 DWORDLONG calleeHnd;
93 DWORD fIsTailPrefix;
94 DWORD tailCallResult;
95 DWORD reason_index;
96 };
97 struct Agnostic_ReserveUnwindInfo
98 {
99 DWORD isFunclet;
100 DWORD isColdCode;
101 DWORD unwindSize;
102 };
103 struct Agnostic_SetBoundaries
104 {
105 DWORDLONG ftn;
106 DWORD cMap;
107 DWORD pMap_offset;
108 };
109 struct Agnostic_SetVars
110 {
111 DWORDLONG ftn;
112 DWORD cVars;
113 DWORD vars_offset;
114 };
115 struct Agnostic_CORINFO_EH_CLAUSE2
116 {
117 DWORD Flags;
118 DWORD TryOffset;
119 DWORD TryLength;
120 DWORD HandlerOffset;
121 DWORD HandlerLength;
122 DWORD ClassToken; // one view of symetric union
123 };
124 struct Agnostic_AllocBBProfileBuffer
125 {
126 DWORD count;
127 DWORD profileBuffer_index;
128 DWORD result;
129 };
130 struct Agnostic_CORINFO_SIG_INFO2
131 {
132 DWORD callConv;
133 DWORDLONG retTypeClass;
134 DWORDLONG retTypeSigClass;
135 DWORD retType;
136 DWORD flags;
137 DWORD numArgs;
138 DWORD sigInst_classInstCount;
139 DWORD sigInst_classInst_Index;
140 DWORD sigInst_methInstCount;
141 DWORD sigInst_methInst_Index;
142 DWORDLONG args;
143 DWORD pSig_Index;
144 DWORD cbSig;
145 DWORDLONG scope;
146 DWORD token;
147 };
148 struct Agnostic_RecordCallSite
149 {
150 Agnostic_CORINFO_SIG_INFO2 callSig;
151 DWORDLONG methodHandle;
152 };
153#pragma pack(pop)
154
155 CompileResult();
156 ~CompileResult();
157
158 bool IsEmpty();
159
160 void AddCall(const char* name);
161 unsigned int CallLog_GetCount();
162 bool CallLog_Contains(const char* str);
163 void dmpCallLog(DWORD key, DWORD value);
164
165 void dumpToConsole();
166
167 HANDLE getCodeHeap();
168
169 void recAssert(const char* buff);
170 void dmpAssertLog(DWORD key, DWORD value);
171 const char* repAssert();
172
173 void recAllocMem(ULONG hotCodeSize,
174 ULONG coldCodeSize,
175 ULONG roDataSize,
176 ULONG xcptnsCount,
177 CorJitAllocMemFlag flag,
178 void** hotCodeBlock,
179 void** coldCodeBlock,
180 void** roDataBlock);
181 void recAllocMemCapture();
182 void dmpAllocMem(DWORD key, const Agnostic_AllocMemDetails& value);
183 void repAllocMem(ULONG* hotCodeSize,
184 ULONG* coldCodeSize,
185 ULONG* roDataSize,
186 ULONG* xcptnsCount,
187 CorJitAllocMemFlag* flag,
188 unsigned char** hotCodeBlock,
189 unsigned char** coldCodeBlock,
190 unsigned char** roDataBlock,
191 void** orig_hotCodeBlock,
192 void** orig_coldCodeBlock,
193 void** orig_roDataBlock);
194
195 void recSetBoundaries(CORINFO_METHOD_HANDLE ftn, ULONG32 cMap, ICorDebugInfo::OffsetMapping* pMap);
196 void dmpSetBoundaries(DWORD key, const Agnostic_SetBoundaries& value);
197 bool repSetBoundaries(CORINFO_METHOD_HANDLE* ftn, ULONG32* cMap, ICorDebugInfo::OffsetMapping** pMap);
198
199 void recSetVars(CORINFO_METHOD_HANDLE ftn, ULONG32 cVars, ICorDebugInfo::NativeVarInfo* vars);
200 void dmpSetVars(DWORD key, const Agnostic_SetVars& value);
201 bool repSetVars(CORINFO_METHOD_HANDLE* ftn, ULONG32* cVars, ICorDebugInfo::NativeVarInfo** vars);
202
203 void recAllocGCInfo(size_t size, void* retval);
204 void recAllocGCInfoCapture();
205 void dmpAllocGCInfo(DWORD key, const Agnostic_AllocGCInfo& value);
206 void repAllocGCInfo(size_t* size, void** retval);
207
208 void recCompileMethod(BYTE** nativeEntry, ULONG* nativeSizeOfCode, CorJitResult result);
209 void dmpCompileMethod(DWORD key, const Agnostic_CompileMethodResults& value);
210 void repCompileMethod(BYTE** nativeEntry, ULONG* nativeSizeOfCode, CorJitResult* result);
211
212 void recMessageLog(const char* fmt, ...);
213 void dmpMessageLog(DWORD key, DWORD value);
214
215 void recClassMustBeLoadedBeforeCodeIsRun(CORINFO_CLASS_HANDLE cls);
216 void dmpClassMustBeLoadedBeforeCodeIsRun(DWORD key, DWORDLONG value);
217
218 void recReportInliningDecision(CORINFO_METHOD_HANDLE inlinerHnd,
219 CORINFO_METHOD_HANDLE inlineeHnd,
220 CorInfoInline inlineResult,
221 const char* reason);
222 void dmpReportInliningDecision(DWORD key, const Agnostic_ReportInliningDecision& value);
223 CorInfoInline repReportInliningDecision(CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd);
224
225 void recSetEHcount(unsigned cEH);
226 void dmpSetEHcount(DWORD key, DWORD value);
227 ULONG repSetEHcount();
228
229 void recSetEHinfo(unsigned EHnumber, const CORINFO_EH_CLAUSE* clause);
230 void dmpSetEHinfo(DWORD key, const Agnostic_CORINFO_EH_CLAUSE2& value);
231 void repSetEHinfo(unsigned EHnumber,
232 ULONG* flags,
233 ULONG* tryOffset,
234 ULONG* tryLength,
235 ULONG* handlerOffset,
236 ULONG* handlerLength,
237 ULONG* classToken);
238
239 void recSetMethodAttribs(CORINFO_METHOD_HANDLE ftn, CorInfoMethodRuntimeFlags attribs);
240 void dmpSetMethodAttribs(DWORDLONG key, DWORD value);
241 CorInfoMethodRuntimeFlags repSetMethodAttribs(CORINFO_METHOD_HANDLE ftn);
242
243 void recMethodMustBeLoadedBeforeCodeIsRun(CORINFO_METHOD_HANDLE method);
244 void dmpMethodMustBeLoadedBeforeCodeIsRun(DWORD key, DWORDLONG value);
245
246 void recReportTailCallDecision(CORINFO_METHOD_HANDLE callerHnd,
247 CORINFO_METHOD_HANDLE calleeHnd,
248 bool fIsTailPrefix,
249 CorInfoTailCall tailCallResult,
250 const char* reason);
251 void dmpReportTailCallDecision(DWORD key, const Agnostic_ReportTailCallDecision& value);
252
253 void recReportFatalError(CorJitResult result);
254 void dmpReportFatalError(DWORD key, DWORD value);
255
256 void recRecordRelocation(void* location, void* target, WORD fRelocType, WORD slotNum, INT32 addlDelta);
257 void dmpRecordRelocation(DWORD key, const Agnostic_RecordRelocation& value);
258 void repRecordRelocation(void* location, void* target, WORD fRelocType, WORD slotNum, INT32 addlDelta);
259 void applyRelocs(unsigned char* block1, ULONG blocksize1, void* originalAddr);
260
261 void recProcessName(const char* name);
262 void dmpProcessName(DWORD key, DWORD value);
263 const char* repProcessName();
264
265 void recAddressMap(void* original_address, void* replay_address, unsigned int size);
266 void dmpAddressMap(DWORDLONG key, const Agnostic_AddressMap& value);
267 void* repAddressMap(void* replay_address);
268 void* searchAddressMap(void* replay_address);
269
270 void recReserveUnwindInfo(BOOL isFunclet, BOOL isColdCode, ULONG unwindSize);
271 void dmpReserveUnwindInfo(DWORD key, const Agnostic_ReserveUnwindInfo& value);
272
273 void recAllocUnwindInfo(BYTE* pHotCode,
274 BYTE* pColdCode,
275 ULONG startOffset,
276 ULONG endOffset,
277 ULONG unwindSize,
278 BYTE* pUnwindBlock,
279 CorJitFuncKind funcKind);
280 void dmpAllocUnwindInfo(DWORD key, const Agnostic_AllocUnwindInfo& value);
281
282 void recAllocBBProfileBuffer(ULONG count, ICorJitInfo::ProfileBuffer** profileBuffer, HRESULT result);
283 void dmpAllocBBProfileBuffer(DWORD key, const Agnostic_AllocBBProfileBuffer& value);
284 HRESULT repAllocBBProfileBuffer(ULONG count, ICorJitInfo::ProfileBuffer** profileBuffer);
285
286 void recRecordCallSite(ULONG instrOffset, CORINFO_SIG_INFO* callSig, CORINFO_METHOD_HANDLE methodHandle);
287 void dmpRecordCallSite(DWORD key, const Agnostic_RecordCallSite& value);
288 void repRecordCallSite(ULONG instrOffset, CORINFO_SIG_INFO* callSig, CORINFO_METHOD_HANDLE methodHandle);
289 bool fndRecordCallSiteSigInfo(ULONG instrOffset, CORINFO_SIG_INFO* pCallSig);
290 bool fndRecordCallSiteMethodHandle(ULONG instrOffset, CORINFO_METHOD_HANDLE* pMethodHandle);
291
292 DOUBLE secondsToCompile;
293 ULONGLONG clockCyclesToCompile;
294
295#define LWM(map, key, value) LightWeightMap<key, value>* map;
296#define DENSELWM(map, value) DenseLightWeightMap<value>* map;
297#include "crlwmlist.h"
298
299 // not persisted to disk.
300public:
301 LightWeightMap<DWORDLONG, DWORD>* CallTargetTypes;
302
303private:
304 HANDLE codeHeap;
305 Capture_AllocMemDetails allocMemDets;
306 allocGCInfoDetails allocGCInfoDets;
307};
308#endif
309