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 | //---------------------------------------------------------- |
7 | // MethodContext.cpp - Primary structure to store all the EE-JIT details required to replay creation of a method |
8 | // CompileResult contains the stuff generated by a compilation |
9 | //---------------------------------------------------------- |
10 | |
11 | #include "standardpch.h" |
12 | #include "md5.h" |
13 | #include "methodcontext.h" |
14 | #include "compileresult.h" |
15 | #include "lightweightmap.h" |
16 | #include "callutils.h" |
17 | #include "spmirecordhelper.h" |
18 | #include "spmidumphelper.h" |
19 | |
20 | #define sparseMC // Support filling in details where guesses are okay and will still generate good code. (i.e. helper |
21 | // function addresses) |
22 | |
23 | #if 0 |
24 | // Enable these to get verbose logging during record or playback. |
25 | #define DEBUG_REC(x) \ |
26 | printf("rec"); \ |
27 | x; \ |
28 | printf("\n"); |
29 | |
30 | #define DEBUG_REP(x) \ |
31 | printf("rep"); \ |
32 | x; \ |
33 | printf("\n"); |
34 | #else |
35 | #define DEBUG_REC(x) |
36 | #define DEBUG_REP(x) |
37 | #endif |
38 | |
39 | MethodContext::MethodContext() |
40 | { |
41 | methodSize = 0; |
42 | |
43 | #define LWM(map, key, value) map = nullptr; |
44 | #include "lwmlist.h" |
45 | |
46 | cr = new CompileResult(); |
47 | index = -1; |
48 | } |
49 | |
50 | MethodContext::~MethodContext() |
51 | { |
52 | Destroy(); |
53 | } |
54 | |
55 | void MethodContext::Destroy() |
56 | { |
57 | #define LWM(map, key, value) \ |
58 | if (map != nullptr) \ |
59 | delete map; |
60 | #include "lwmlist.h" |
61 | |
62 | delete cr; |
63 | } |
64 | |
65 | #define sparseAddLen(target) \ |
66 | if (target != nullptr) \ |
67 | { \ |
68 | if (target->GetCount() != 0) \ |
69 | totalLen += target->CalculateArraySize() + 6; /* packet canary from lightweightmap + packet marker */ \ |
70 | } |
71 | |
72 | #define sparseWriteFile(target) \ |
73 | if (target != nullptr) \ |
74 | { \ |
75 | if (target->GetCount() != 0) \ |
76 | { \ |
77 | buff2[buffIndex++] = (unsigned char)Packet_##target; \ |
78 | unsigned int loc = target->DumpToArray(&buff2[buffIndex + 4]); \ |
79 | memcpy(&buff2[buffIndex], &loc, sizeof(unsigned int)); \ |
80 | buffIndex += 4 + loc; \ |
81 | buff2[buffIndex++] = 0x42; \ |
82 | } \ |
83 | } |
84 | |
85 | #define sparseWriteFileCR(target) \ |
86 | if (cr != nullptr) \ |
87 | { \ |
88 | if (cr->target != nullptr) \ |
89 | { \ |
90 | if (cr->target->GetCount() != 0) \ |
91 | { \ |
92 | buff2[buffIndex++] = (unsigned char)PacketCR_##target; \ |
93 | unsigned int loc = cr->target->DumpToArray(&buff2[buffIndex + 4]); \ |
94 | memcpy(&buff2[buffIndex], &loc, sizeof(unsigned int)); \ |
95 | buffIndex += 4 + loc; \ |
96 | buff2[buffIndex++] = 0x42; \ |
97 | } \ |
98 | } \ |
99 | } |
100 | |
101 | #define sparseReadFile(target, key, value) \ |
102 | case Packet_##target: \ |
103 | { \ |
104 | target = new LightWeightMap<key, value>(); \ |
105 | target->ReadFromArray(&buff2[buffIndex], localsize); \ |
106 | break; \ |
107 | } |
108 | |
109 | #define sparseReadFileCR(target, key, value) \ |
110 | case PacketCR_##target: \ |
111 | { \ |
112 | cr->target = new LightWeightMap<key, value>(); \ |
113 | cr->target->ReadFromArray(&buff2[buffIndex], localsize); \ |
114 | break; \ |
115 | } |
116 | |
117 | #define sparseReadFileDense(target, value) \ |
118 | case Packet_##target: \ |
119 | { \ |
120 | target = new DenseLightWeightMap<value>(); \ |
121 | target->ReadFromArray(&buff2[buffIndex], localsize); \ |
122 | break; \ |
123 | } |
124 | |
125 | #define sparseReadFileCRDense(target, value) \ |
126 | case PacketCR_##target: \ |
127 | { \ |
128 | cr->target = new DenseLightWeightMap<value>(); \ |
129 | cr->target->ReadFromArray(&buff2[buffIndex], localsize); \ |
130 | break; \ |
131 | } |
132 | |
133 | unsigned int MethodContext::calculateFileSize() |
134 | { |
135 | // Calculate file size |
136 | unsigned int totalLen = 0; |
137 | |
138 | #define LWM(map, key, value) sparseAddLen(map) |
139 | #include "lwmlist.h" |
140 | |
141 | // Compile Result members |
142 | if (cr != nullptr) |
143 | { |
144 | #define LWM(map, key, value) sparseAddLen(cr->map); |
145 | #include "crlwmlist.h" |
146 | } |
147 | |
148 | return totalLen; |
149 | } |
150 | |
151 | unsigned int MethodContext::calculateRawFileSize() |
152 | { |
153 | return 2 /* leading magic cookie 'm', 'c' */ + 4 /* 4-byte data length */ + calculateFileSize() + |
154 | 2 /* end canary '4', '2' */; |
155 | } |
156 | |
157 | unsigned int MethodContext::saveToFile(HANDLE hFile) |
158 | { |
159 | unsigned int totalLen = calculateFileSize(); |
160 | unsigned int totalFileSize = |
161 | 2 /* leading magic cookie 'm', 'c' */ + 4 /* 4-byte data length */ + totalLen + 2 /* end canary '4', '2' */; |
162 | |
163 | DWORD bytesWritten = 0; |
164 | unsigned int buffIndex = 0; |
165 | unsigned char* buff2 = new unsigned char[totalFileSize]; |
166 | buff2[buffIndex++] = 'm'; |
167 | buff2[buffIndex++] = 'c'; |
168 | memcpy(&buff2[buffIndex], &totalLen, sizeof(unsigned int)); |
169 | buffIndex += 4; |
170 | |
171 | #define LWM(map, key, value) sparseWriteFile(map) |
172 | #include "lwmlist.h" |
173 | |
174 | // Compile Result members |
175 | #define LWM(map, key, value) sparseWriteFileCR(map); |
176 | #include "crlwmlist.h" |
177 | |
178 | // Write the end canary |
179 | buff2[buffIndex++] = '4'; |
180 | buff2[buffIndex++] = '2'; |
181 | |
182 | Assert(buffIndex == totalFileSize); |
183 | |
184 | WriteFile(hFile, buff2, totalFileSize, &bytesWritten, NULL); |
185 | delete[] buff2; |
186 | return bytesWritten; |
187 | } |
188 | |
189 | // This code can't exist in a function with C++ objects needing destruction. Returns true on success |
190 | // (and sets *ppmc with new MethodContext), false on failure. |
191 | // |
192 | // static |
193 | bool MethodContext::Initialize(int loadedCount, unsigned char* buff, DWORD size, /* OUT */ MethodContext** ppmc) |
194 | { |
195 | MethodContext* mc = new MethodContext(); |
196 | mc->index = loadedCount; |
197 | *ppmc = mc; |
198 | return mc->Initialize(loadedCount, buff, size); |
199 | } |
200 | |
201 | // static |
202 | bool MethodContext::Initialize(int loadedCount, HANDLE hFile, /* OUT */ MethodContext** ppmc) |
203 | { |
204 | MethodContext* mc = new MethodContext(); |
205 | mc->index = loadedCount; |
206 | *ppmc = mc; |
207 | return mc->Initialize(loadedCount, hFile); |
208 | } |
209 | |
210 | bool MethodContext::Initialize(int loadedCount, unsigned char* buff, DWORD size) |
211 | { |
212 | bool result = true; |
213 | |
214 | struct Param |
215 | { |
216 | unsigned char* buff; |
217 | DWORD size; |
218 | MethodContext* pThis; |
219 | } param; |
220 | param.buff = buff; |
221 | param.size = size; |
222 | param.pThis = this; |
223 | |
224 | PAL_TRY(Param*, pParam, ¶m) |
225 | { |
226 | pParam->pThis->MethodInitHelper(pParam->buff, pParam->size); |
227 | } |
228 | PAL_EXCEPT_FILTER(FilterSuperPMIExceptions_CatchMC) |
229 | { |
230 | LogError("Method %d is of low integrity." , loadedCount); |
231 | result = false; |
232 | } |
233 | PAL_ENDTRY |
234 | |
235 | return result; |
236 | } |
237 | |
238 | bool MethodContext::Initialize(int loadedCount, HANDLE hFile) |
239 | { |
240 | bool result = true; |
241 | |
242 | struct Param |
243 | { |
244 | HANDLE hFile; |
245 | MethodContext* pThis; |
246 | } param; |
247 | param.hFile = hFile; |
248 | param.pThis = this; |
249 | |
250 | PAL_TRY(Param*, pParam, ¶m) |
251 | { |
252 | pParam->pThis->MethodInitHelperFile(pParam->hFile); |
253 | } |
254 | PAL_EXCEPT_FILTER(FilterSuperPMIExceptions_CatchMC) |
255 | { |
256 | LogError("Method %d is of low integrity." , loadedCount); |
257 | result = false; |
258 | } |
259 | PAL_ENDTRY |
260 | |
261 | return result; |
262 | } |
263 | |
264 | void MethodContext::MethodInitHelperFile(HANDLE hFile) |
265 | { |
266 | DWORD bytesRead; |
267 | char buff[512]; |
268 | unsigned int totalLen = 0; |
269 | |
270 | AssertCode(ReadFile(hFile, buff, 2 + sizeof(unsigned int), &bytesRead, NULL) == TRUE, |
271 | EXCEPTIONCODE_MC); // Read Magic number and totalLen |
272 | AssertCodeMsg((buff[0] == 'm') && (buff[1] == 'c'), EXCEPTIONCODE_MC, "Didn't find magic number" ); |
273 | memcpy(&totalLen, &buff[2], sizeof(unsigned int)); |
274 | unsigned char* buff2 = new unsigned char[totalLen + 2]; // total + End Canary |
275 | AssertCode(ReadFile(hFile, buff2, totalLen + 2, &bytesRead, NULL) == TRUE, EXCEPTIONCODE_MC); |
276 | AssertCodeMsg((buff2[totalLen] == '4') && (buff2[totalLen + 1] == '2'), EXCEPTIONCODE_MC, "Didn't find end canary" ); |
277 | MethodInitHelper(buff2, totalLen); |
278 | } |
279 | |
280 | void MethodContext::MethodInitHelper(unsigned char* buff2, unsigned int totalLen) |
281 | { |
282 | unsigned int buffIndex = 0; |
283 | unsigned int localsize = 0; |
284 | unsigned char canary = 0xff; |
285 | unsigned char* buff3 = nullptr; |
286 | |
287 | while (buffIndex < totalLen) |
288 | { |
289 | mcPackets packetType = (mcPackets)buff2[buffIndex++]; |
290 | memcpy(&localsize, &buff2[buffIndex], sizeof(unsigned int)); |
291 | buffIndex += 4; |
292 | |
293 | switch (packetType) |
294 | { |
295 | #define LWM(map, key, value) sparseReadFile(map, key, value) |
296 | #define DENSELWM(map, value) sparseReadFileDense(map, value) |
297 | #include "lwmlist.h" |
298 | |
299 | #define LWM(map, key, value) sparseReadFileCR(map, key, value) |
300 | #define DENSELWM(map, value) sparseReadFileCRDense(map, value) |
301 | #include "crlwmlist.h" |
302 | |
303 | default: |
304 | LogException(EXCEPTIONCODE_MC, "Read ran into unknown packet type %u. Are you using a newer recorder?" , |
305 | packetType); |
306 | // break; |
307 | } |
308 | buffIndex += localsize; |
309 | canary = buff2[buffIndex++]; |
310 | AssertCodeMsg(canary == 0x42, EXCEPTIONCODE_MC, "Didn't find trailing canary for map" ); |
311 | } |
312 | AssertCodeMsg((buff2[buffIndex++] == '4') && (buff2[buffIndex++] == '2'), EXCEPTIONCODE_MC, |
313 | "Didn't find trailing canary for map" ); |
314 | delete[] buff2; |
315 | } |
316 | |
317 | #define dumpStat(target) \ |
318 | if (target != nullptr) \ |
319 | { \ |
320 | if (target->GetCount() > 0) \ |
321 | { \ |
322 | int t = sprintf_s(buff, len, "%u", target->GetCount()); \ |
323 | buff += t; \ |
324 | len -= t; \ |
325 | } \ |
326 | } \ |
327 | { \ |
328 | *buff++ = ','; \ |
329 | len--; \ |
330 | } \ |
331 | if (target != nullptr) \ |
332 | { \ |
333 | int t = sprintf_s(buff, len, "%u", target->CalculateArraySize()); \ |
334 | buff += t; \ |
335 | len -= t; \ |
336 | } \ |
337 | { \ |
338 | *buff++ = ','; \ |
339 | len--; \ |
340 | } |
341 | |
342 | // Dump statistics about each LightWeightMap to the buffer: count of elements, and total size in bytes of map. |
343 | int MethodContext::dumpStatToBuffer(char* buff, int len) |
344 | { |
345 | char* obuff = buff; |
346 | // assumption of enough buffer.. :-| |
347 | |
348 | #define LWM(map, key, value) dumpStat(map) |
349 | #include "lwmlist.h" |
350 | |
351 | // Compile Result members |
352 | #define LWM(map, key, value) dumpStat(cr->map); |
353 | #include "crlwmlist.h" |
354 | |
355 | return (int)(buff - obuff); |
356 | } |
357 | int MethodContext::dumpStatTitleToBuffer(char* buff, int len) |
358 | { |
359 | const char* title = |
360 | |
361 | #define LWM(map, key, value) #map "," #map " SZ," |
362 | #include "lwmlist.h" |
363 | |
364 | #define LWM(map, key, value) "CR_" #map ",CR_" #map " SZ," |
365 | #include "crlwmlist.h" |
366 | |
367 | ; |
368 | |
369 | int titleLen = (int)strlen(title); |
370 | if ((titleLen + 1) > len) |
371 | { |
372 | LogError("titleLen is larger than given len" ); |
373 | return 0; |
374 | } |
375 | strcpy_s(buff, len, title); |
376 | return titleLen; |
377 | } |
378 | |
379 | #define softMapEqual(a) \ |
380 | if (a != nullptr) \ |
381 | { \ |
382 | if (other->a == nullptr) \ |
383 | return false; \ |
384 | if (a->GetCount() != other->a->GetCount()) \ |
385 | return false; \ |
386 | } \ |
387 | else if (other->a != nullptr) \ |
388 | return false; |
389 | |
390 | bool MethodContext::Equal(MethodContext* other) |
391 | { |
392 | // returns true if equal. Note this is permissive, that is to say that we may reason that too many things are |
393 | // equal. Adding more detailed checks would cause us to reason more things as unique; |
394 | |
395 | // Compare MethodInfo's first. |
396 | CORINFO_METHOD_INFO otherInfo; |
397 | unsigned otherFlags = 0; |
398 | other->repCompileMethod(&otherInfo, &otherFlags); |
399 | |
400 | CORINFO_METHOD_INFO ourInfo; |
401 | unsigned ourFlags = 0; |
402 | repCompileMethod(&ourInfo, &ourFlags); |
403 | |
404 | if (otherInfo.ILCodeSize != ourInfo.ILCodeSize) |
405 | return false; |
406 | if (otherInfo.args.numArgs != ourInfo.args.numArgs) |
407 | return false; |
408 | if (otherInfo.args.retType != ourInfo.args.retType) |
409 | return false; |
410 | if (otherInfo.locals.numArgs != ourInfo.locals.numArgs) |
411 | return false; |
412 | if (otherInfo.EHcount != ourInfo.EHcount) |
413 | return false; |
414 | if (otherInfo.options != ourInfo.options) |
415 | return false; |
416 | for (unsigned int j = 0; j < otherInfo.ILCodeSize; j++) |
417 | if (otherInfo.ILCode[j] != ourInfo.ILCode[j]) |
418 | return false; |
419 | if (otherInfo.maxStack != ourInfo.maxStack) |
420 | return false; |
421 | if (otherInfo.regionKind != ourInfo.regionKind) |
422 | return false; |
423 | if (otherInfo.args.callConv != ourInfo.args.callConv) |
424 | return false; |
425 | if (otherInfo.args.cbSig != ourInfo.args.cbSig) |
426 | return false; |
427 | if (otherInfo.args.flags != ourInfo.args.flags) |
428 | return false; |
429 | if (otherInfo.locals.cbSig != ourInfo.locals.cbSig) |
430 | return false; |
431 | if (otherFlags != ourFlags) |
432 | return false; |
433 | |
434 | // Now compare the other maps to "estimate" equality. |
435 | |
436 | #define LWM(map, key, value) softMapEqual(map) |
437 | #include "lwmlist.h" |
438 | |
439 | // Compile Result members |
440 | #define LWM(map, key, value) softMapEqual(cr->map) |
441 | #include "crlwmlist.h" |
442 | |
443 | // Base case is we "match" |
444 | return true; |
445 | } |
446 | |
447 | //------------------------------------------------------------------------------ |
448 | // MethodContext::recGlobalContext |
449 | // This method copies any relevant global (i.e. per-JIT-instance) data from |
450 | // the given method context. Currently this is limited to configuration |
451 | // values, but may grow to encompass other information in the future (e.g. |
452 | // any information that is exposed by the ICorJitHost interface and is |
453 | // therefore accessible outside the context of a call to |
454 | // `ICJI::compileMethod`). |
455 | // |
456 | // This method is intended to be called as part of initializing a method |
457 | // during collection. |
458 | void MethodContext::recGlobalContext(const MethodContext& other) |
459 | { |
460 | Assert(GetIntConfigValue == nullptr); |
461 | Assert(GetStringConfigValue == nullptr); |
462 | |
463 | if (other.GetIntConfigValue != nullptr) |
464 | { |
465 | GetIntConfigValue = new LightWeightMap<Agnostic_ConfigIntInfo, DWORD>(*other.GetIntConfigValue); |
466 | } |
467 | |
468 | if (other.GetStringConfigValue != nullptr) |
469 | { |
470 | GetStringConfigValue = new LightWeightMap<DWORD, DWORD>(*other.GetStringConfigValue); |
471 | } |
472 | } |
473 | |
474 | void MethodContext::dumpToConsole(int mcNumber) |
475 | { |
476 | printf("*****************************************" ); |
477 | if (mcNumber != -1) |
478 | { |
479 | printf(" method context #%d" , mcNumber); |
480 | } |
481 | printf("\n" ); |
482 | |
483 | #define LWM(map, key, value) dumpLWM(this, map) |
484 | #define DENSELWM(map, value) dumpLWMDense(this, map) |
485 | #include "lwmlist.h" |
486 | |
487 | // Compile Result members |
488 | #define LWM(map, key, value) dumpLWM(this->cr, map) |
489 | #define DENSELWM(map, value) dumpLWMDense(this->cr, map) |
490 | #include "crlwmlist.h" |
491 | } |
492 | |
493 | const char* toString(CorInfoType cit) |
494 | { |
495 | switch (cit) |
496 | { |
497 | case CORINFO_TYPE_UNDEF: |
498 | return "undef" ; |
499 | case CORINFO_TYPE_VOID: |
500 | return "void" ; |
501 | case CORINFO_TYPE_BOOL: |
502 | return "bool" ; |
503 | case CORINFO_TYPE_CHAR: |
504 | return "char" ; |
505 | case CORINFO_TYPE_BYTE: |
506 | return "byte" ; |
507 | case CORINFO_TYPE_UBYTE: |
508 | return "ubyte" ; |
509 | case CORINFO_TYPE_SHORT: |
510 | return "short" ; |
511 | case CORINFO_TYPE_USHORT: |
512 | return "ushort" ; |
513 | case CORINFO_TYPE_INT: |
514 | return "int" ; |
515 | case CORINFO_TYPE_UINT: |
516 | return "uint" ; |
517 | case CORINFO_TYPE_LONG: |
518 | return "long" ; |
519 | case CORINFO_TYPE_ULONG: |
520 | return "ulong" ; |
521 | case CORINFO_TYPE_NATIVEINT: |
522 | return "nativeint" ; |
523 | case CORINFO_TYPE_NATIVEUINT: |
524 | return "nativeuint" ; |
525 | case CORINFO_TYPE_FLOAT: |
526 | return "float" ; |
527 | case CORINFO_TYPE_DOUBLE: |
528 | return "double" ; |
529 | case CORINFO_TYPE_STRING: |
530 | return "string" ; |
531 | case CORINFO_TYPE_PTR: |
532 | return "ptr" ; |
533 | case CORINFO_TYPE_BYREF: |
534 | return "byref" ; |
535 | case CORINFO_TYPE_VALUECLASS: |
536 | return "valueclass" ; |
537 | case CORINFO_TYPE_CLASS: |
538 | return "class" ; |
539 | case CORINFO_TYPE_REFANY: |
540 | return "refany" ; |
541 | case CORINFO_TYPE_VAR: |
542 | return "var" ; |
543 | default: |
544 | return "UNKNOWN" ; |
545 | } |
546 | } |
547 | |
548 | unsigned int toCorInfoSize(CorInfoType cit) |
549 | { |
550 | switch (cit) |
551 | { |
552 | case CORINFO_TYPE_BOOL: |
553 | case CORINFO_TYPE_BYTE: |
554 | case CORINFO_TYPE_UBYTE: |
555 | return 1; |
556 | |
557 | case CORINFO_TYPE_CHAR: |
558 | case CORINFO_TYPE_SHORT: |
559 | case CORINFO_TYPE_USHORT: |
560 | return 2; |
561 | |
562 | case CORINFO_TYPE_FLOAT: |
563 | case CORINFO_TYPE_INT: |
564 | case CORINFO_TYPE_UINT: |
565 | return 4; |
566 | |
567 | case CORINFO_TYPE_DOUBLE: |
568 | case CORINFO_TYPE_LONG: |
569 | case CORINFO_TYPE_ULONG: |
570 | return 8; |
571 | |
572 | case CORINFO_TYPE_NATIVEINT: |
573 | case CORINFO_TYPE_NATIVEUINT: |
574 | case CORINFO_TYPE_PTR: |
575 | case CORINFO_TYPE_BYREF: |
576 | case CORINFO_TYPE_CLASS: |
577 | return sizeof(void*); |
578 | |
579 | case CORINFO_TYPE_STRING: |
580 | case CORINFO_TYPE_VALUECLASS: |
581 | case CORINFO_TYPE_REFANY: |
582 | case CORINFO_TYPE_UNDEF: |
583 | case CORINFO_TYPE_VOID: |
584 | default: |
585 | __debugbreak(); |
586 | return 0; |
587 | } |
588 | return -1; |
589 | } |
590 | |
591 | void MethodContext::recCompileMethod(CORINFO_METHOD_INFO* info, unsigned flags) |
592 | { |
593 | if (CompileMethod == nullptr) |
594 | CompileMethod = new LightWeightMap<DWORD, Agnostic_CompileMethod>(); |
595 | |
596 | Agnostic_CompileMethod value; |
597 | |
598 | value.info.ftn = (DWORDLONG)info->ftn; |
599 | value.info.scope = (DWORDLONG)info->scope; |
600 | value.info.ILCode_offset = (DWORD)CompileMethod->AddBuffer(info->ILCode, info->ILCodeSize); |
601 | value.info.ILCodeSize = (DWORD)info->ILCodeSize; |
602 | value.info.maxStack = (DWORD)info->maxStack; |
603 | value.info.EHcount = (DWORD)info->EHcount; |
604 | value.info.options = (DWORD)info->options; |
605 | value.info.regionKind = (DWORD)info->regionKind; |
606 | value.info.args.callConv = (DWORD)info->args.callConv; |
607 | value.info.args.retTypeClass = (DWORDLONG)info->args.retTypeClass; |
608 | value.info.args.retTypeSigClass = (DWORDLONG)info->args.retTypeSigClass; |
609 | value.info.args.retType = (DWORD)info->args.retType; |
610 | value.info.args.flags = (DWORD)info->args.flags; |
611 | value.info.args.numArgs = (DWORD)info->args.numArgs; |
612 | value.info.args.sigInst_classInstCount = (DWORD)info->args.sigInst.classInstCount; |
613 | value.info.args.sigInst_classInst_Index = |
614 | CompileMethod->AddBuffer((unsigned char*)info->args.sigInst.classInst, |
615 | info->args.sigInst.classInstCount * 8); // porting issue |
616 | value.info.args.sigInst_methInstCount = (DWORD)info->args.sigInst.methInstCount; |
617 | value.info.args.sigInst_methInst_Index = |
618 | CompileMethod->AddBuffer((unsigned char*)info->args.sigInst.methInst, |
619 | info->args.sigInst.methInstCount * 8); // porting issue |
620 | value.info.args.args = (DWORDLONG)info->args.args; |
621 | value.info.args.cbSig = (DWORD)info->args.cbSig; |
622 | value.info.args.pSig_Index = (DWORD)CompileMethod->AddBuffer((unsigned char*)info->args.pSig, info->args.cbSig); |
623 | value.info.args.scope = (DWORDLONG)info->args.scope; |
624 | value.info.args.token = (DWORD)info->args.token; |
625 | value.info.locals.callConv = (DWORD)info->locals.callConv; |
626 | value.info.locals.retTypeClass = (DWORDLONG)info->locals.retTypeClass; |
627 | value.info.locals.retTypeSigClass = (DWORDLONG)info->locals.retTypeSigClass; |
628 | value.info.locals.retType = (DWORD)info->locals.retType; |
629 | value.info.locals.flags = (DWORD)info->locals.flags; |
630 | value.info.locals.numArgs = (DWORD)info->locals.numArgs; |
631 | value.info.locals.sigInst_classInstCount = (DWORD)info->locals.sigInst.classInstCount; |
632 | value.info.locals.sigInst_classInst_Index = |
633 | CompileMethod->AddBuffer((unsigned char*)info->locals.sigInst.classInst, |
634 | info->locals.sigInst.classInstCount * 8); // porting issue |
635 | value.info.locals.sigInst_methInstCount = (DWORD)info->locals.sigInst.methInstCount; |
636 | value.info.locals.sigInst_methInst_Index = |
637 | CompileMethod->AddBuffer((unsigned char*)info->locals.sigInst.methInst, |
638 | info->locals.sigInst.methInstCount * 8); // porting issue |
639 | value.info.locals.args = (DWORDLONG)info->locals.args; |
640 | value.info.locals.cbSig = (DWORD)info->locals.cbSig; |
641 | value.info.locals.pSig_Index = |
642 | (DWORD)CompileMethod->AddBuffer((unsigned char*)info->locals.pSig, info->locals.cbSig); |
643 | value.info.locals.scope = (DWORDLONG)info->locals.scope; |
644 | value.info.locals.token = (DWORD)info->locals.token; |
645 | value.flags = (DWORD)flags; |
646 | |
647 | CompileMethod->Add(0, value); |
648 | DEBUG_REC(dmpCompileMethod(0, value)); |
649 | } |
650 | void MethodContext::dmpCompileMethod(DWORD key, const Agnostic_CompileMethod& value) |
651 | { |
652 | printf("CompiledMethod key %u, value ftn-%016llX scp-%016llX ilo-%u ils-%u ms-%u ehc-%u opt-%u rk-%u " |
653 | "args{cc-%u rc-%016llX rts-%016llX rt-%u(%s) flg-%08X nA-%u cc-%u ci-%u mc-%u mi-%u arg-%016llX cb-%u " |
654 | "pSig_Index-%u scp-%016llX tok-%08X} " |
655 | "locals{cc-%u rc-%016llX rts-%016llX rt-%u(%s) flg-%08X nA-%u cc-%u ci-%u mc-%u mi-%u arg-%016llX cb-%u " |
656 | "pSig_Index-%u scp-%016llX tok-%08X} " |
657 | "flg-%08X" , |
658 | key, value.info.ftn, value.info.scope, value.info.ILCode_offset, value.info.ILCodeSize, value.info.maxStack, |
659 | value.info.EHcount, value.info.options, value.info.regionKind, value.info.args.callConv, |
660 | value.info.args.retTypeClass, value.info.args.retTypeSigClass, value.info.args.retType, |
661 | toString((CorInfoType)value.info.args.retType), value.info.args.flags, value.info.args.numArgs, |
662 | value.info.args.sigInst_classInstCount, value.info.args.sigInst_classInst_Index, |
663 | value.info.args.sigInst_methInstCount, value.info.args.sigInst_methInst_Index, value.info.args.args, |
664 | value.info.args.cbSig, value.info.args.pSig_Index, value.info.args.scope, value.info.args.token, |
665 | value.info.locals.callConv, value.info.locals.retTypeClass, value.info.locals.retTypeSigClass, |
666 | value.info.locals.retType, toString((CorInfoType)value.info.locals.retType), value.info.locals.flags, |
667 | value.info.locals.numArgs, value.info.locals.sigInst_classInstCount, |
668 | value.info.locals.sigInst_classInst_Index, value.info.locals.sigInst_methInstCount, |
669 | value.info.locals.sigInst_methInst_Index, value.info.locals.args, value.info.locals.cbSig, |
670 | value.info.locals.pSig_Index, value.info.locals.scope, value.info.locals.token, value.flags); |
671 | } |
672 | void MethodContext::repCompileMethod(CORINFO_METHOD_INFO* info, unsigned* flags) |
673 | { |
674 | Agnostic_CompileMethod value; |
675 | |
676 | value = CompileMethod->Get((DWORD)0); // The only item in this set is a single group of inputs to CompileMethod |
677 | |
678 | info->ftn = (CORINFO_METHOD_HANDLE)value.info.ftn; |
679 | info->scope = (CORINFO_MODULE_HANDLE)value.info.scope; |
680 | info->ILCode = CompileMethod->GetBuffer(value.info.ILCode_offset); |
681 | info->ILCodeSize = (unsigned)value.info.ILCodeSize; |
682 | methodSize = info->ILCodeSize; |
683 | info->maxStack = (unsigned)value.info.maxStack; |
684 | info->EHcount = (unsigned)value.info.EHcount; |
685 | info->options = (CorInfoOptions)value.info.options; |
686 | info->regionKind = (CorInfoRegionKind)value.info.regionKind; |
687 | info->args.callConv = (CorInfoCallConv)value.info.args.callConv; |
688 | info->args.retTypeClass = (CORINFO_CLASS_HANDLE)value.info.args.retTypeClass; |
689 | info->args.retTypeSigClass = (CORINFO_CLASS_HANDLE)value.info.args.retTypeSigClass; |
690 | info->args.retType = (CorInfoType)value.info.args.retType; |
691 | info->args.flags = (unsigned)value.info.args.flags; |
692 | info->args.numArgs = (unsigned)value.info.args.numArgs; |
693 | info->args.sigInst.classInstCount = (unsigned)value.info.args.sigInst_classInstCount; |
694 | info->args.sigInst.classInst = |
695 | (CORINFO_CLASS_HANDLE*)CompileMethod->GetBuffer(value.info.args.sigInst_classInst_Index); |
696 | info->args.sigInst.methInstCount = (unsigned)value.info.args.sigInst_methInstCount; |
697 | info->args.sigInst.methInst = |
698 | (CORINFO_CLASS_HANDLE*)CompileMethod->GetBuffer(value.info.args.sigInst_methInst_Index); |
699 | info->args.args = (CORINFO_ARG_LIST_HANDLE)value.info.args.args; |
700 | info->args.cbSig = (unsigned int)value.info.args.cbSig; |
701 | info->args.pSig = (PCCOR_SIGNATURE)CompileMethod->GetBuffer(value.info.args.pSig_Index); |
702 | info->args.scope = (CORINFO_MODULE_HANDLE)value.info.args.scope; |
703 | info->args.token = (mdToken)value.info.args.token; |
704 | info->locals.callConv = (CorInfoCallConv)value.info.locals.callConv; |
705 | info->locals.retTypeClass = (CORINFO_CLASS_HANDLE)value.info.locals.retTypeClass; |
706 | info->locals.retTypeSigClass = (CORINFO_CLASS_HANDLE)value.info.locals.retTypeSigClass; |
707 | info->locals.retType = (CorInfoType)value.info.locals.retType; |
708 | info->locals.flags = (unsigned)value.info.locals.flags; |
709 | info->locals.numArgs = (unsigned)value.info.locals.numArgs; |
710 | info->locals.sigInst.classInstCount = (unsigned)value.info.locals.sigInst_classInstCount; |
711 | info->locals.sigInst.classInst = |
712 | (CORINFO_CLASS_HANDLE*)CompileMethod->GetBuffer(value.info.locals.sigInst_classInst_Index); |
713 | info->locals.sigInst.methInstCount = (unsigned)value.info.locals.sigInst_methInstCount; |
714 | info->locals.sigInst.methInst = |
715 | (CORINFO_CLASS_HANDLE*)CompileMethod->GetBuffer(value.info.locals.sigInst_methInst_Index); |
716 | info->locals.args = (CORINFO_ARG_LIST_HANDLE)value.info.locals.args; |
717 | info->locals.cbSig = (unsigned int)value.info.locals.cbSig; |
718 | info->locals.pSig = (PCCOR_SIGNATURE)CompileMethod->GetBuffer(value.info.locals.pSig_Index); |
719 | info->locals.scope = (CORINFO_MODULE_HANDLE)value.info.locals.scope; |
720 | info->locals.token = (mdToken)value.info.locals.token; |
721 | *flags = (unsigned)value.flags; |
722 | DEBUG_REP(dmpCompileMethod(0, value)); |
723 | } |
724 | |
725 | void MethodContext::recGetMethodClass(CORINFO_METHOD_HANDLE methodHandle, CORINFO_CLASS_HANDLE classHandle) |
726 | { |
727 | if (GetMethodClass == nullptr) |
728 | GetMethodClass = new LightWeightMap<DWORDLONG, DWORDLONG>(); |
729 | |
730 | GetMethodClass->Add((DWORDLONG)methodHandle, (DWORDLONG)classHandle); |
731 | DEBUG_REC(dmpGetMethodClass((DWORDLONG)methodHandle, (DWORDLONG)classHandle)); |
732 | } |
733 | void MethodContext::dmpGetMethodClass(DWORDLONG key, DWORDLONG value) |
734 | { |
735 | printf("GetMethodClass key %016llX, value %016llX" , key, value); |
736 | } |
737 | CORINFO_CLASS_HANDLE MethodContext::repGetMethodClass(CORINFO_METHOD_HANDLE methodHandle) |
738 | { |
739 | AssertCodeMsg(GetMethodClass != nullptr, EXCEPTIONCODE_MC, |
740 | "Found a null GetMethodClass. Probably missing a fatTrigger for %016llX." , (DWORDLONG)methodHandle); |
741 | int index = GetMethodClass->GetIndex((DWORDLONG)methodHandle); |
742 | AssertCodeMsg(index != -1, EXCEPTIONCODE_MC, "Didn't find %016llX. Probably missing a fatTrigger" , |
743 | (DWORDLONG)methodHandle); |
744 | CORINFO_CLASS_HANDLE value = (CORINFO_CLASS_HANDLE)GetMethodClass->Get((DWORDLONG)methodHandle); |
745 | DEBUG_REP(dmpGetMethodClass((DWORDLONG)methodHandle, (DWORDLONG)value)); |
746 | return value; |
747 | } |
748 | |
749 | void MethodContext::recGetClassAttribs(CORINFO_CLASS_HANDLE classHandle, DWORD attribs) |
750 | { |
751 | if (GetClassAttribs == nullptr) |
752 | GetClassAttribs = new LightWeightMap<DWORDLONG, DWORD>(); |
753 | |
754 | GetClassAttribs->Add((DWORDLONG)classHandle, (DWORD)attribs); |
755 | DEBUG_REC(dmpGetClassAttribs((DWORDLONG)classHandle, attribs)); |
756 | } |
757 | void MethodContext::dmpGetClassAttribs(DWORDLONG key, DWORD value) |
758 | { |
759 | printf("GetClassAttribs key %016llX, value %u" , key, value); |
760 | } |
761 | DWORD MethodContext::repGetClassAttribs(CORINFO_CLASS_HANDLE classHandle) |
762 | { |
763 | AssertCodeMsg(GetClassAttribs != nullptr, EXCEPTIONCODE_MC, |
764 | "Found a null GetMethodClass. Probably missing a fatTrigger for %016llX." , (DWORDLONG)classHandle); |
765 | int index = GetClassAttribs->GetIndex((DWORDLONG)classHandle); |
766 | AssertCodeMsg(index != -1, EXCEPTIONCODE_MC, "Didn't find %016llX. Probably missing a fatTrigger" , |
767 | (DWORDLONG)classHandle); |
768 | DWORD value = (DWORD)GetClassAttribs->Get((DWORDLONG)classHandle); |
769 | DEBUG_REP(dmpGetClassAttribs((DWORDLONG)classHandle, value)); |
770 | return value; |
771 | } |
772 | |
773 | void MethodContext::recGetMethodAttribs(CORINFO_METHOD_HANDLE methodHandle, DWORD attribs) |
774 | { |
775 | if (GetMethodAttribs == nullptr) |
776 | GetMethodAttribs = new LightWeightMap<DWORDLONG, DWORD>(); |
777 | |
778 | GetMethodAttribs->Add((DWORDLONG)methodHandle, attribs); |
779 | DEBUG_REC(dmpGetMethodAttribs((DWORDLONG)methodHandle, attribs)); |
780 | } |
781 | void MethodContext::dmpGetMethodAttribs(DWORDLONG key, DWORD value) |
782 | { |
783 | printf("GetMethodAttribs key %016llX, value %u" , key, value); |
784 | } |
785 | DWORD MethodContext::repGetMethodAttribs(CORINFO_METHOD_HANDLE methodHandle) |
786 | { |
787 | AssertCodeMsg(GetMethodAttribs != nullptr, EXCEPTIONCODE_MC, |
788 | "Found a null GetMethodAttribs. Probably missing a fatTrigger for %016llX." , |
789 | (DWORDLONG)methodHandle); |
790 | int index = GetMethodAttribs->GetIndex((DWORDLONG)methodHandle); |
791 | AssertCodeMsg(index != -1, EXCEPTIONCODE_MC, "Didn't find %016llX. Probably missing a fatTrigger" , |
792 | (DWORDLONG)methodHandle); |
793 | DWORD value = (DWORD)GetMethodAttribs->Get((DWORDLONG)methodHandle); |
794 | DEBUG_REP(dmpGetMethodAttribs((DWORDLONG)methodHandle, value)); |
795 | if (cr->repSetMethodAttribs(methodHandle) == CORINFO_FLG_BAD_INLINEE) |
796 | value ^= CORINFO_FLG_DONT_INLINE; |
797 | return value; |
798 | } |
799 | |
800 | // Note - the jit will call freearray on the array we give back.... |
801 | void MethodContext::recGetVars(CORINFO_METHOD_HANDLE ftn, |
802 | ULONG32* cVars, |
803 | ICorDebugInfo::ILVarInfo** vars_in, |
804 | bool* extendOthers) |
805 | { |
806 | if (GetVars == nullptr) |
807 | GetVars = new LightWeightMap<DWORDLONG, Agnostic_GetVars>(); |
808 | |
809 | Agnostic_GetVars value; |
810 | |
811 | value.cVars = (DWORD)*cVars; |
812 | value.vars_offset = |
813 | (DWORD)GetVars->AddBuffer((unsigned char*)*vars_in, sizeof(ICorDebugInfo::ILVarInfo) * (*cVars)); |
814 | |
815 | value.extendOthers = (DWORD)*extendOthers; |
816 | GetVars->Add((DWORDLONG)ftn, value); |
817 | DEBUG_REC(dmpGetVars((DWORDLONG)ftn, value)); |
818 | } |
819 | void MethodContext::dmpGetVars(DWORDLONG key, const Agnostic_GetVars& value) |
820 | { |
821 | ICorDebugInfo::ILVarInfo* vars = (ICorDebugInfo::ILVarInfo*)GetVars->GetBuffer(value.vars_offset); |
822 | printf("GetVars key ftn-%016llX, value cVars-%u extendOthers-%u (" , key, value.cVars, value.extendOthers); |
823 | for (unsigned int i = 0; i < value.cVars; i++) |
824 | printf("(%u %u %u %u)" , i, vars[i].startOffset, vars[i].endOffset, vars[i].varNumber); |
825 | printf(")" ); |
826 | GetVars->Unlock(); |
827 | } |
828 | void MethodContext::repGetVars(CORINFO_METHOD_HANDLE ftn, |
829 | ULONG32* cVars, |
830 | ICorDebugInfo::ILVarInfo** vars_in, |
831 | bool* extendOthers) |
832 | { |
833 | Agnostic_GetVars value; |
834 | if (GetVars == nullptr) |
835 | { |
836 | *cVars = 0; |
837 | return; |
838 | } |
839 | value = GetVars->Get((DWORDLONG)ftn); |
840 | *cVars = (ULONG32)value.cVars; |
841 | if (*cVars > 0) |
842 | *vars_in = (ICorDebugInfo::ILVarInfo*)GetVars->GetBuffer(value.vars_offset); |
843 | *extendOthers = value.extendOthers != 0; |
844 | DEBUG_REP(dmpGetVars((DWORDLONG)ftn, value)); |
845 | } |
846 | |
847 | // Note - the jit will call freearray on the array we give back.... |
848 | void MethodContext::recGetBoundaries(CORINFO_METHOD_HANDLE ftn, |
849 | unsigned int* cILOffsets, |
850 | DWORD** pILOffsets, |
851 | ICorDebugInfo::BoundaryTypes* implictBoundaries) |
852 | { |
853 | if (GetBoundaries == nullptr) |
854 | GetBoundaries = new LightWeightMap<DWORDLONG, Agnostic_GetBoundaries>(); |
855 | |
856 | Agnostic_GetBoundaries value; |
857 | |
858 | value.cILOffsets = (DWORD)*cILOffsets; |
859 | value.pILOffset_offset = |
860 | (DWORD)GetBoundaries->AddBuffer((unsigned char*)*pILOffsets, sizeof(DWORD) * (*cILOffsets)); |
861 | value.implicitBoundaries = *implictBoundaries; |
862 | |
863 | GetBoundaries->Add((DWORDLONG)ftn, value); |
864 | DEBUG_REC(dmpGetBoundaries((DWORDLONG)ftn, value)); |
865 | } |
866 | void MethodContext::dmpGetBoundaries(DWORDLONG key, const Agnostic_GetBoundaries& value) |
867 | { |
868 | printf("GetBoundaries key ftn-%016llX, value cnt-%u imp-%u{" , key, value.cILOffsets, value.implicitBoundaries); |
869 | DWORD* bnd = (DWORD*)GetBoundaries->GetBuffer(value.pILOffset_offset); |
870 | for (unsigned int i = 0; i < value.cILOffsets; i++) |
871 | { |
872 | printf("%u" , bnd[i]); |
873 | if (i < (value.cILOffsets + 1)) |
874 | printf("," ); |
875 | } |
876 | GetBoundaries->Unlock(); |
877 | printf("}" ); |
878 | } |
879 | void MethodContext::repGetBoundaries(CORINFO_METHOD_HANDLE ftn, |
880 | unsigned int* cILOffsets, |
881 | DWORD** pILOffsets, |
882 | ICorDebugInfo::BoundaryTypes* implictBoundaries) |
883 | { |
884 | Agnostic_GetBoundaries value; |
885 | |
886 | value = GetBoundaries->Get((DWORDLONG)ftn); |
887 | |
888 | *cILOffsets = (unsigned int)value.cILOffsets; |
889 | if (*cILOffsets > 0) |
890 | *pILOffsets = (DWORD*)GetBoundaries->GetBuffer(value.pILOffset_offset); |
891 | *implictBoundaries = (ICorDebugInfo::BoundaryTypes)value.implicitBoundaries; |
892 | |
893 | DEBUG_REP(dmpGetBoundaries((DWORDLONG)ftn, value)); |
894 | } |
895 | |
896 | void MethodContext::recInitClass(CORINFO_FIELD_HANDLE field, |
897 | CORINFO_METHOD_HANDLE method, |
898 | CORINFO_CONTEXT_HANDLE context, |
899 | BOOL speculative, |
900 | CorInfoInitClassResult result) |
901 | { |
902 | if (InitClass == nullptr) |
903 | InitClass = new LightWeightMap<Agnostic_InitClass, DWORD>(); |
904 | |
905 | Agnostic_InitClass key; |
906 | ZeroMemory(&key, sizeof(Agnostic_InitClass)); // We use the input structs as a key and use memcmp to compare.. so we |
907 | // need to zero out padding too |
908 | key.field = (DWORDLONG)field; |
909 | key.method = (DWORDLONG)method; |
910 | key.context = (DWORDLONG)context; |
911 | key.speculative = (DWORD)speculative; |
912 | |
913 | InitClass->Add(key, (DWORD)result); |
914 | DEBUG_REC(dmpInitClass(key, (DWORD)result)); |
915 | } |
916 | void MethodContext::dmpInitClass(const Agnostic_InitClass& key, DWORD value) |
917 | { |
918 | printf("InitClass key fld-%016llX meth-%016llX con-%016llX spec-%u, value res-%u" , key.field, key.method, |
919 | key.context, key.speculative, value); |
920 | } |
921 | CorInfoInitClassResult MethodContext::repInitClass(CORINFO_FIELD_HANDLE field, |
922 | CORINFO_METHOD_HANDLE method, |
923 | CORINFO_CONTEXT_HANDLE context, |
924 | BOOL speculative) |
925 | { |
926 | Agnostic_InitClass key; |
927 | ZeroMemory(&key, sizeof(Agnostic_InitClass)); // We use the input structs as a key and use memcmp to compare.. so we |
928 | // need to zero out padding too |
929 | |
930 | key.field = (DWORDLONG)field; |
931 | key.method = (DWORDLONG)method; |
932 | key.context = (DWORDLONG)context; |
933 | key.speculative = (DWORD)speculative; |
934 | |
935 | AssertCodeMsg(InitClass != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , (DWORDLONG)key.method); |
936 | AssertCodeMsg(InitClass->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , (DWORDLONG)key.method); |
937 | CorInfoInitClassResult result = (CorInfoInitClassResult)InitClass->Get(key); |
938 | |
939 | DEBUG_REP(dmpInitClass(key, result)); |
940 | return result; |
941 | } |
942 | |
943 | void MethodContext::recGetMethodName(CORINFO_METHOD_HANDLE ftn, char* methodname, const char** moduleName) |
944 | { |
945 | if (GetMethodName == nullptr) |
946 | GetMethodName = new LightWeightMap<DLD, DD>(); |
947 | DD value; |
948 | DLD key; |
949 | key.A = (DWORDLONG)ftn; |
950 | key.B = (moduleName != nullptr); |
951 | |
952 | if (methodname != nullptr) |
953 | value.A = GetMethodName->AddBuffer((unsigned char*)methodname, (DWORD)strlen(methodname) + 1); |
954 | else |
955 | value.A = (DWORD)-1; |
956 | |
957 | if ((moduleName != nullptr) && (*moduleName != nullptr)) |
958 | value.B = GetMethodName->AddBuffer((unsigned char*)*moduleName, (DWORD)strlen(*moduleName) + 1); |
959 | else |
960 | value.B = (DWORD)-1; |
961 | |
962 | GetMethodName->Add(key, value); |
963 | DEBUG_REC(dmpGetMethodName(key, value)); |
964 | } |
965 | void MethodContext::dmpGetMethodName(DLD key, DD value) |
966 | { |
967 | unsigned char* methodName = (unsigned char*)GetMethodName->GetBuffer(value.A); |
968 | unsigned char* moduleName = (unsigned char*)GetMethodName->GetBuffer(value.B); |
969 | printf("GetMethodName key - ftn-%016llX modNonNull-%u, value meth-'%s', mod-'%s'" , key.A, key.B, methodName, |
970 | moduleName); |
971 | GetMethodName->Unlock(); |
972 | } |
973 | |
974 | const char* MethodContext::repGetMethodName(CORINFO_METHOD_HANDLE ftn, const char** moduleName) |
975 | { |
976 | const char* result = "hackishMethodName" ; |
977 | DD value; |
978 | DLD key; |
979 | key.A = (DWORDLONG)ftn; |
980 | key.B = (moduleName != nullptr); |
981 | |
982 | int itemIndex = -1; |
983 | if (GetMethodName != nullptr) |
984 | itemIndex = GetMethodName->GetIndex(key); |
985 | if (itemIndex < 0) |
986 | { |
987 | if (moduleName != nullptr) |
988 | *moduleName = "hackishModuleName" ; |
989 | } |
990 | else |
991 | { |
992 | value = GetMethodName->Get(key); |
993 | if (moduleName != nullptr) |
994 | *moduleName = (const char*)GetMethodName->GetBuffer(value.B); |
995 | result = (const char*)GetMethodName->GetBuffer(value.A); |
996 | } |
997 | DEBUG_REP(dmpGetMethodName(key, value)); |
998 | return result; |
999 | } |
1000 | |
1001 | void MethodContext::recGetMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, |
1002 | char* methodName, |
1003 | const char** className, |
1004 | const char** namespaceName, |
1005 | const char** enclosingClassName) |
1006 | { |
1007 | if (GetMethodNameFromMetadata == nullptr) |
1008 | GetMethodNameFromMetadata = new LightWeightMap<Agnostic_CORINFO_METHODNAME_TOKENin, Agnostic_CORINFO_METHODNAME_TOKENout>(); |
1009 | Agnostic_CORINFO_METHODNAME_TOKENout value; |
1010 | Agnostic_CORINFO_METHODNAME_TOKENin key; |
1011 | key.ftn = (DWORDLONG)ftn; |
1012 | key.className = (className != nullptr); |
1013 | key.namespaceName = (namespaceName != nullptr); |
1014 | key.enclosingClassName = (enclosingClassName != nullptr); |
1015 | |
1016 | if (methodName != nullptr) |
1017 | value.methodName = GetMethodNameFromMetadata->AddBuffer((unsigned char*)methodName, (DWORD)strlen(methodName) + 1); |
1018 | else |
1019 | value.methodName = (DWORD)-1; |
1020 | |
1021 | if ((className != nullptr) && (*className != nullptr)) |
1022 | value.className = GetMethodNameFromMetadata->AddBuffer((unsigned char*)*className, (DWORD)strlen(*className) + 1); |
1023 | else |
1024 | value.className = (DWORD)-1; |
1025 | |
1026 | if ((namespaceName != nullptr) && (*namespaceName != nullptr)) |
1027 | value.namespaceName = |
1028 | GetMethodNameFromMetadata->AddBuffer((unsigned char*)*namespaceName, (DWORD)strlen(*namespaceName) + 1); |
1029 | else |
1030 | value.namespaceName = (DWORD)-1; |
1031 | |
1032 | if ((enclosingClassName != nullptr) && (*enclosingClassName != nullptr)) |
1033 | value.enclosingClassName = |
1034 | GetMethodNameFromMetadata->AddBuffer((unsigned char*)*enclosingClassName, (DWORD)strlen(*enclosingClassName) + 1); |
1035 | else |
1036 | value.enclosingClassName = (DWORD)-1; |
1037 | |
1038 | GetMethodNameFromMetadata->Add(key, value); |
1039 | DEBUG_REC(dmpGetMethodNameFromMetadata(key, value)); |
1040 | } |
1041 | |
1042 | void MethodContext::dmpGetMethodNameFromMetadata(Agnostic_CORINFO_METHODNAME_TOKENin key, Agnostic_CORINFO_METHODNAME_TOKENout value) |
1043 | { |
1044 | unsigned char* methodName = (unsigned char*)GetMethodName->GetBuffer(value.methodName); |
1045 | unsigned char* className = (unsigned char*)GetMethodName->GetBuffer(value.className); |
1046 | unsigned char* namespaceName = (unsigned char*)GetMethodName->GetBuffer(value.namespaceName); |
1047 | unsigned char* enclosingClassName = (unsigned char*)GetMethodName->GetBuffer(value.enclosingClassName); |
1048 | printf("GetMethodNameFromMetadata key - ftn-%016llX classNonNull-%u namespaceNonNull-%u nclosingClassNonNull-%u, value meth-'%s', " |
1049 | "class-'%s', namespace-'%s' enclosingClass-'%s'" , |
1050 | key.ftn, key.className, key.namespaceName, key.enclosingClassName, methodName, className, namespaceName, enclosingClassName); |
1051 | GetMethodNameFromMetadata->Unlock(); |
1052 | } |
1053 | |
1054 | const char* MethodContext::repGetMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, |
1055 | const char** moduleName, |
1056 | const char** namespaceName, |
1057 | const char** enclosingClassName) |
1058 | { |
1059 | const char* result = nullptr; |
1060 | Agnostic_CORINFO_METHODNAME_TOKENout value; |
1061 | Agnostic_CORINFO_METHODNAME_TOKENin key; |
1062 | key.ftn = (DWORDLONG)ftn; |
1063 | key.className = (moduleName != nullptr); |
1064 | key.namespaceName = (namespaceName != nullptr); |
1065 | key.enclosingClassName = (enclosingClassName != nullptr); |
1066 | |
1067 | int itemIndex = -1; |
1068 | if (GetMethodNameFromMetadata != nullptr) |
1069 | itemIndex = GetMethodNameFromMetadata->GetIndex(key); |
1070 | if (itemIndex < 0) |
1071 | { |
1072 | if (moduleName != nullptr) |
1073 | { |
1074 | *moduleName = nullptr; |
1075 | } |
1076 | } |
1077 | else |
1078 | { |
1079 | value = GetMethodNameFromMetadata->Get(key); |
1080 | result = (const char*)GetMethodNameFromMetadata->GetBuffer(value.methodName); |
1081 | |
1082 | if (moduleName != nullptr) |
1083 | { |
1084 | *moduleName = (const char*)GetMethodNameFromMetadata->GetBuffer(value.className); |
1085 | } |
1086 | |
1087 | if (namespaceName != nullptr) |
1088 | { |
1089 | *namespaceName = (const char*)GetMethodNameFromMetadata->GetBuffer(value.namespaceName); |
1090 | } |
1091 | |
1092 | if (enclosingClassName != nullptr) |
1093 | { |
1094 | *enclosingClassName = (const char*)GetMethodNameFromMetadata->GetBuffer(value.enclosingClassName); |
1095 | } |
1096 | } |
1097 | DEBUG_REP(dmpGetMethodNameFromMetadata(key, value)); |
1098 | return result; |
1099 | } |
1100 | |
1101 | void MethodContext::recGetJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes, DWORD result) |
1102 | { |
1103 | if (GetJitFlags == nullptr) |
1104 | GetJitFlags = new LightWeightMap<DWORD, DD>(); |
1105 | |
1106 | DD value; |
1107 | value.A = (DWORD)GetJitFlags->AddBuffer((unsigned char*)jitFlags, sizeInBytes); |
1108 | value.B = result; |
1109 | |
1110 | // NOTE: getJitFlags() is expected to be idempotent per method, so the mapping key is always |
1111 | // zero. |
1112 | GetJitFlags->Add((DWORD)0, value); |
1113 | DEBUG_REC(dmpGetJitFlags((DWORD)0, value)); |
1114 | } |
1115 | void MethodContext::dmpGetJitFlags(DWORD key, DD value) |
1116 | { |
1117 | CORJIT_FLAGS* jitflags = (CORJIT_FLAGS*)GetJitFlags->GetBuffer(value.A); |
1118 | printf("GetJitFlags key %u sizeInBytes-%u jitFlags-%016llX" , key, value.B, jitflags->GetFlagsRaw()); |
1119 | GetJitFlags->Unlock(); |
1120 | } |
1121 | DWORD MethodContext::repGetJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes) |
1122 | { |
1123 | DD value = GetJitFlags->Get((DWORD)0); |
1124 | CORJIT_FLAGS* resultFlags = (CORJIT_FLAGS*)GetJitFlags->GetBuffer(value.A); |
1125 | memcpy(jitFlags, resultFlags, value.B); |
1126 | DEBUG_REP(dmpGetJitFlags((DWORD)0, value)); |
1127 | return value.B; |
1128 | } |
1129 | |
1130 | void MethodContext::recGetJitTimeLogFilename(LPCWSTR tempFileName) |
1131 | { |
1132 | if (GetJitTimeLogFilename == nullptr) |
1133 | GetJitTimeLogFilename = new LightWeightMap<DWORD, DWORD>(); |
1134 | |
1135 | DWORD name_index = -1; |
1136 | if (tempFileName != nullptr) |
1137 | { |
1138 | name_index = |
1139 | (DWORD)GetJitTimeLogFilename->AddBuffer((unsigned char*)tempFileName, (DWORD)wcslen(tempFileName) + 2); |
1140 | } |
1141 | GetJitTimeLogFilename->Add((DWORD)0, name_index); |
1142 | DEBUG_REC(dmpGetJitTimeLogFilename((DWORD)0, name_index)); |
1143 | } |
1144 | void MethodContext::dmpGetJitTimeLogFilename(DWORD key, DWORD value) |
1145 | { |
1146 | unsigned char* fileName = nullptr; |
1147 | if (value != 0) |
1148 | fileName = (unsigned char*)GetJitTimeLogFilename->GetBuffer(value); |
1149 | printf("GetJitTimeLogFilename key %u, value '%s'" , key, fileName); |
1150 | GetJitTimeLogFilename->Unlock(); |
1151 | } |
1152 | LPCWSTR MethodContext::repGetJitTimeLogFilename() |
1153 | { |
1154 | DWORD offset = GetJitTimeLogFilename->Get((DWORD)0); |
1155 | LPCWSTR value = nullptr; |
1156 | if (offset != 0) |
1157 | value = (LPCWSTR)GetJitTimeLogFilename->GetBuffer(offset); |
1158 | DEBUG_REP(dmpGetJitTimeLogFilename((DWORD)0, offset)); |
1159 | return value; |
1160 | } |
1161 | |
1162 | void MethodContext::recCanInline(CORINFO_METHOD_HANDLE callerHnd, |
1163 | CORINFO_METHOD_HANDLE calleeHnd, |
1164 | DWORD* pRestrictions, |
1165 | CorInfoInline response, |
1166 | DWORD exceptionCode) |
1167 | { |
1168 | if (CanInline == nullptr) |
1169 | CanInline = new LightWeightMap<DLDL, Agnostic_CanInline>(); |
1170 | |
1171 | DLDL key; |
1172 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
1173 | // out padding too |
1174 | Agnostic_CanInline value; |
1175 | |
1176 | key.A = (DWORDLONG)callerHnd; |
1177 | key.B = (DWORDLONG)calleeHnd; |
1178 | |
1179 | if (pRestrictions != nullptr) |
1180 | value.Restrictions = (DWORD)*pRestrictions; |
1181 | else |
1182 | value.Restrictions = (DWORD)0; |
1183 | value.result = (DWORD)response; |
1184 | value.exceptionCode = (DWORD)exceptionCode; |
1185 | |
1186 | CanInline->Add(key, value); |
1187 | DEBUG_REC(dmpCanInline(key, value)); |
1188 | } |
1189 | void MethodContext::dmpCanInline(DLDL key, const Agnostic_CanInline& value) |
1190 | { |
1191 | printf("CanInline key - callerHnd-%016llX calleeHnd-%016llX, value pRestrictions-%u result-%u exceptionCode-%08X" , |
1192 | key.A, key.B, value.Restrictions, value.result, value.exceptionCode); |
1193 | } |
1194 | CorInfoInline MethodContext::repCanInline(CORINFO_METHOD_HANDLE callerHnd, |
1195 | CORINFO_METHOD_HANDLE calleeHnd, |
1196 | DWORD* pRestrictions, |
1197 | DWORD* exceptionCode) |
1198 | { |
1199 | DLDL key; |
1200 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
1201 | // out padding too |
1202 | Agnostic_CanInline value; |
1203 | |
1204 | key.A = (DWORDLONG)callerHnd; |
1205 | key.B = (DWORDLONG)calleeHnd; |
1206 | |
1207 | if ((CanInline == nullptr) || (CanInline->GetIndex(key) == -1)) |
1208 | { |
1209 | #ifdef sparseMC |
1210 | LogDebug("Sparse - repCanInline saying INLINE_FAIL" ); |
1211 | return INLINE_FAIL; // if we have no info, its pretty safe to say we can't inline it. |
1212 | #else |
1213 | LogException(EXCEPTIONCODE_MC, "Didn't find %016llx, %016llx. probably a missing exception in canInline" , |
1214 | key.A, key.B); |
1215 | #endif |
1216 | } |
1217 | |
1218 | value = CanInline->Get(key); |
1219 | |
1220 | *exceptionCode = value.exceptionCode; |
1221 | |
1222 | if (pRestrictions != nullptr) |
1223 | *pRestrictions = (DWORD)value.Restrictions; |
1224 | CorInfoInline response = (CorInfoInline)value.result; |
1225 | DEBUG_REP(dmpCanInline(key, value)); |
1226 | return response; |
1227 | } |
1228 | |
1229 | void MethodContext::recResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken, DWORD exceptionCode) |
1230 | { |
1231 | if (ResolveToken == nullptr) |
1232 | ResolveToken = new LightWeightMap<Agnostic_CORINFO_RESOLVED_TOKENin, ResolveTokenValue>(); |
1233 | |
1234 | Agnostic_CORINFO_RESOLVED_TOKENin key; |
1235 | ZeroMemory(&key, sizeof(Agnostic_CORINFO_RESOLVED_TOKENin)); // We use the input structs as a key and use memcmp to |
1236 | // compare.. so we need to zero out padding too |
1237 | key = SpmiRecordsHelper::CreateAgnostic_CORINFO_RESOLVED_TOKENin(pResolvedToken); |
1238 | |
1239 | ResolveTokenValue value; |
1240 | value.tokenOut = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKENout(pResolvedToken, ResolveToken); |
1241 | value.exceptionCode = (DWORD)exceptionCode; |
1242 | |
1243 | ResolveToken->Add(key, value); |
1244 | DEBUG_REC(dmpResolveToken(key, value)); |
1245 | } |
1246 | void MethodContext::dmpResolveToken(const Agnostic_CORINFO_RESOLVED_TOKENin& key, const ResolveTokenValue& value) |
1247 | { |
1248 | printf("ResolveToken key: %s\n" , SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKENin(key).c_str()); |
1249 | printf(", value: %s excp-%08X" , SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKENout(value.tokenOut).c_str(), |
1250 | value.exceptionCode); |
1251 | } |
1252 | void MethodContext::repResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken, DWORD* exceptionCode) |
1253 | { |
1254 | Agnostic_CORINFO_RESOLVED_TOKENin key; |
1255 | ZeroMemory(&key, sizeof(Agnostic_CORINFO_RESOLVED_TOKENin)); // We use the input structs as a key and use memcmp to |
1256 | // compare.. so we need to zero out padding too |
1257 | key = SpmiRecordsHelper::CreateAgnostic_CORINFO_RESOLVED_TOKENin(pResolvedToken); |
1258 | |
1259 | AssertCodeMsg(ResolveToken->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %x" , pResolvedToken->token); |
1260 | |
1261 | ResolveTokenValue value = ResolveToken->Get(key); |
1262 | |
1263 | SpmiRecordsHelper::Restore_CORINFO_RESOLVED_TOKENout(pResolvedToken, value.tokenOut, ResolveToken); |
1264 | *exceptionCode = (DWORD)value.exceptionCode; |
1265 | DEBUG_REP(dmpResolveToken(key, value)); |
1266 | } |
1267 | |
1268 | void MethodContext::recTryResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool success) |
1269 | { |
1270 | if (TryResolveToken == nullptr) |
1271 | TryResolveToken = new LightWeightMap<Agnostic_CORINFO_RESOLVED_TOKENin, TryResolveTokenValue>(); |
1272 | |
1273 | Agnostic_CORINFO_RESOLVED_TOKENin key; |
1274 | ZeroMemory(&key, sizeof(Agnostic_CORINFO_RESOLVED_TOKENin)); // We use the input structs as a key and use memcmp to |
1275 | // compare.. so we need to zero out padding too |
1276 | key = SpmiRecordsHelper::CreateAgnostic_CORINFO_RESOLVED_TOKENin(pResolvedToken); |
1277 | |
1278 | TryResolveTokenValue value; |
1279 | |
1280 | value.tokenOut = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKENout(pResolvedToken, ResolveToken); |
1281 | value.success = success ? 0 : 1; |
1282 | |
1283 | TryResolveToken->Add(key, value); |
1284 | DEBUG_REC(dmpTryResolveToken(key, value)); |
1285 | } |
1286 | void MethodContext::dmpTryResolveToken(const Agnostic_CORINFO_RESOLVED_TOKENin& key, const TryResolveTokenValue& value) |
1287 | { |
1288 | printf("TryResolveToken key: %s\n" , SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKENin(key).c_str()); |
1289 | printf(", value: %s failed-%u" , SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKENout(value.tokenOut).c_str(), |
1290 | value.success); |
1291 | } |
1292 | bool MethodContext::repTryResolveToken(CORINFO_RESOLVED_TOKEN* pResolvedToken) |
1293 | { |
1294 | Agnostic_CORINFO_RESOLVED_TOKENin key; |
1295 | ZeroMemory(&key, sizeof(Agnostic_CORINFO_RESOLVED_TOKENin)); // We use the input structs as a key and use memcmp to |
1296 | // compare.. so we need to zero out padding too |
1297 | |
1298 | key = SpmiRecordsHelper::CreateAgnostic_CORINFO_RESOLVED_TOKENin(pResolvedToken); |
1299 | |
1300 | TryResolveTokenValue value = TryResolveToken->Get(key); |
1301 | |
1302 | SpmiRecordsHelper::Restore_CORINFO_RESOLVED_TOKENout(pResolvedToken, value.tokenOut, ResolveToken); |
1303 | |
1304 | DEBUG_REP(dmpTryResolveToken(key, value)); |
1305 | return (DWORD)value.success == 0; |
1306 | } |
1307 | |
1308 | void MethodContext::recGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken, |
1309 | CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken, |
1310 | CORINFO_METHOD_HANDLE callerHandle, |
1311 | CORINFO_CALLINFO_FLAGS flags, |
1312 | CORINFO_CALL_INFO* pResult, |
1313 | DWORD exceptionCode) |
1314 | { |
1315 | if (GetCallInfo == nullptr) |
1316 | GetCallInfo = new LightWeightMap<Agnostic_GetCallInfo, Agnostic_CORINFO_CALL_INFO>(); |
1317 | |
1318 | Agnostic_GetCallInfo key; |
1319 | ZeroMemory(&key, sizeof(Agnostic_GetCallInfo)); // We use the input structs as a key and use memcmp to compare.. so |
1320 | // we need to zero out padding too |
1321 | key.ResolvedToken = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, GetCallInfo); |
1322 | |
1323 | if (pConstrainedResolvedToken != nullptr) |
1324 | { |
1325 | key.ConstrainedResolvedToken = |
1326 | SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(pConstrainedResolvedToken, GetCallInfo); |
1327 | } |
1328 | |
1329 | key.callerHandle = (DWORDLONG)callerHandle; |
1330 | key.flags = (DWORD)flags; |
1331 | |
1332 | Agnostic_CORINFO_CALL_INFO value; |
1333 | ZeroMemory(&value, sizeof(Agnostic_CORINFO_CALL_INFO)); // init verSig with 0. |
1334 | |
1335 | if (exceptionCode == 0) |
1336 | { |
1337 | value.hMethod = (DWORDLONG)pResult->hMethod; |
1338 | value.methodFlags = (DWORD)pResult->methodFlags; |
1339 | value.classFlags = (DWORD)pResult->classFlags; |
1340 | value.sig = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(pResult->sig, GetCallInfo); |
1341 | if (flags & CORINFO_CALLINFO_VERIFICATION) |
1342 | { |
1343 | value.verMethodFlags = (DWORD)pResult->verMethodFlags; |
1344 | value.verSig = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(pResult->verSig, GetCallInfo); |
1345 | } |
1346 | |
1347 | value.accessAllowed = (DWORD)pResult->accessAllowed; |
1348 | value.callsiteCalloutHelper.helperNum = (DWORD)pResult->callsiteCalloutHelper.helperNum; |
1349 | value.callsiteCalloutHelper.numArgs = (DWORD)pResult->callsiteCalloutHelper.numArgs; |
1350 | for (int i = 0; i < CORINFO_ACCESS_ALLOWED_MAX_ARGS; i++) |
1351 | { |
1352 | value.callsiteCalloutHelper.args[i].constant = (DWORDLONG)pResult->callsiteCalloutHelper.args[i].constant; |
1353 | value.callsiteCalloutHelper.args[i].argType = (DWORD)pResult->callsiteCalloutHelper.args[i].argType; |
1354 | } |
1355 | value.thisTransform = (DWORD)pResult->thisTransform; |
1356 | |
1357 | value.kind = (DWORD)pResult->kind; |
1358 | value.nullInstanceCheck = (DWORD)pResult->nullInstanceCheck; |
1359 | value.contextHandle = (DWORDLONG)pResult->contextHandle; |
1360 | value.exactContextNeedsRuntimeLookup = (DWORD)pResult->exactContextNeedsRuntimeLookup; |
1361 | |
1362 | value.stubLookup = SpmiRecordsHelper::StoreAgnostic_CORINFO_LOOKUP(&pResult->stubLookup); |
1363 | |
1364 | value.instParamLookup.accessType = (DWORD)pResult->instParamLookup.accessType; |
1365 | value.instParamLookup.handle = (DWORDLONG)pResult->instParamLookup.handle; |
1366 | value.secureDelegateInvoke = (DWORD)pResult->secureDelegateInvoke; |
1367 | } |
1368 | else |
1369 | ZeroMemory(&value, sizeof(Agnostic_CORINFO_CALL_INFO)); |
1370 | value.exceptionCode = (DWORD)exceptionCode; |
1371 | |
1372 | GetCallInfo->Add(key, value); |
1373 | DEBUG_REC(dmpGetCallInfo(key, value)); |
1374 | } |
1375 | void MethodContext::dmpGetCallInfo(const Agnostic_GetCallInfo& key, const Agnostic_CORINFO_CALL_INFO& value) |
1376 | { |
1377 | printf("GetCallInfo key rt{%s} crt{%s} ch-%016llX flg-%08X\n" , |
1378 | SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKEN(key.ResolvedToken).c_str(), |
1379 | SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKEN(key.ConstrainedResolvedToken).c_str(), key.callerHandle, |
1380 | key.flags); |
1381 | printf(", value mth-%016llX, mf-%08X cf-%08X" |
1382 | " sig%s" |
1383 | " vsig%s" |
1384 | " ipl{at-%08X hnd-%016llX}" |
1385 | " sdi-%08X" |
1386 | " excp-%08X" |
1387 | "stubLookup%s" , |
1388 | value.hMethod, value.methodFlags, value.classFlags, |
1389 | SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(value.sig).c_str(), |
1390 | SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(value.verSig).c_str(), value.instParamLookup.accessType, |
1391 | value.instParamLookup.handle, value.secureDelegateInvoke, value.exceptionCode, |
1392 | SpmiDumpHelper::DumpAgnostic_CORINFO_LOOKUP(value.stubLookup).c_str()); |
1393 | } |
1394 | void MethodContext::repGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken, |
1395 | CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken, |
1396 | CORINFO_METHOD_HANDLE callerHandle, |
1397 | CORINFO_CALLINFO_FLAGS flags, |
1398 | CORINFO_CALL_INFO* pResult, |
1399 | DWORD* exceptionCode) |
1400 | { |
1401 | Agnostic_GetCallInfo key; |
1402 | ZeroMemory(&key, sizeof(Agnostic_GetCallInfo)); // We use the input structs as a key and use memcmp to compare.. so |
1403 | // we need to zero out padding too |
1404 | key.ResolvedToken = SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, GetCallInfo); |
1405 | if (pConstrainedResolvedToken != nullptr) |
1406 | { |
1407 | key.ConstrainedResolvedToken = |
1408 | SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKEN(pConstrainedResolvedToken, GetCallInfo); |
1409 | } |
1410 | key.callerHandle = (DWORDLONG)callerHandle; |
1411 | key.flags = (DWORD)flags; |
1412 | |
1413 | AssertCodeMsg(GetCallInfo->GetIndex(key) != -1, EXCEPTIONCODE_MC, |
1414 | "Didn't find %08x, %016llx. Probably a missing exception in GetCallInfo" , |
1415 | key.ResolvedToken.inValue.token, key.ResolvedToken.outValue.hClass); |
1416 | |
1417 | Agnostic_CORINFO_CALL_INFO value; |
1418 | |
1419 | value = GetCallInfo->Get(key); |
1420 | |
1421 | pResult->hMethod = (CORINFO_METHOD_HANDLE)value.hMethod; |
1422 | pResult->methodFlags = (unsigned)value.methodFlags; |
1423 | pResult->classFlags = (unsigned)value.classFlags; |
1424 | pResult->sig = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value.sig, GetCallInfo); |
1425 | if (flags & CORINFO_CALLINFO_VERIFICATION) |
1426 | { |
1427 | pResult->verMethodFlags = (unsigned)value.verMethodFlags; |
1428 | pResult->verSig = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value.verSig, GetCallInfo); |
1429 | } |
1430 | pResult->accessAllowed = (CorInfoIsAccessAllowedResult)value.accessAllowed; |
1431 | pResult->callsiteCalloutHelper.helperNum = (CorInfoHelpFunc)value.callsiteCalloutHelper.helperNum; |
1432 | pResult->callsiteCalloutHelper.numArgs = (unsigned)value.callsiteCalloutHelper.numArgs; |
1433 | for (int i = 0; i < CORINFO_ACCESS_ALLOWED_MAX_ARGS; i++) |
1434 | { |
1435 | pResult->callsiteCalloutHelper.args[i].constant = (size_t)value.callsiteCalloutHelper.args[i].constant; |
1436 | pResult->callsiteCalloutHelper.args[i].argType = |
1437 | (CorInfoAccessAllowedHelperArgType)value.callsiteCalloutHelper.args[i].argType; |
1438 | } |
1439 | pResult->thisTransform = (CORINFO_THIS_TRANSFORM)value.thisTransform; |
1440 | pResult->kind = (CORINFO_CALL_KIND)value.kind; |
1441 | pResult->nullInstanceCheck = (BOOL)value.nullInstanceCheck; |
1442 | pResult->contextHandle = (CORINFO_CONTEXT_HANDLE)value.contextHandle; |
1443 | pResult->exactContextNeedsRuntimeLookup = (BOOL)value.exactContextNeedsRuntimeLookup; |
1444 | pResult->stubLookup.lookupKind.needsRuntimeLookup = value.stubLookup.lookupKind.needsRuntimeLookup != 0; |
1445 | pResult->stubLookup.lookupKind.runtimeLookupKind = |
1446 | (CORINFO_RUNTIME_LOOKUP_KIND)value.stubLookup.lookupKind.runtimeLookupKind; |
1447 | if (pResult->stubLookup.lookupKind.needsRuntimeLookup) |
1448 | { |
1449 | pResult->stubLookup.runtimeLookup.signature = |
1450 | (LPVOID)value.stubLookup.runtimeLookup.signature; // needs to be a more flexible copy based on |
1451 | // valuevalue.stubLookup.runtimeLookup.signature; |
1452 | pResult->stubLookup.runtimeLookup.helper = (CorInfoHelpFunc)value.stubLookup.runtimeLookup.helper; |
1453 | pResult->stubLookup.runtimeLookup.indirections = (WORD)value.stubLookup.runtimeLookup.indirections; |
1454 | pResult->stubLookup.runtimeLookup.testForNull = value.stubLookup.runtimeLookup.testForNull != 0; |
1455 | pResult->stubLookup.runtimeLookup.testForFixup = value.stubLookup.runtimeLookup.testForFixup != 0; |
1456 | pResult->stubLookup.runtimeLookup.indirectFirstOffset = value.stubLookup.runtimeLookup.indirectFirstOffset != 0; |
1457 | pResult->stubLookup.runtimeLookup.indirectSecondOffset = |
1458 | value.stubLookup.runtimeLookup.indirectSecondOffset != 0; |
1459 | for (int i = 0; i < CORINFO_MAXINDIRECTIONS; i++) |
1460 | pResult->stubLookup.runtimeLookup.offsets[i] = (SIZE_T)value.stubLookup.runtimeLookup.offsets[i]; |
1461 | } |
1462 | else |
1463 | { |
1464 | pResult->stubLookup.constLookup.accessType = (InfoAccessType)value.stubLookup.constLookup.accessType; |
1465 | pResult->stubLookup.constLookup.handle = (CORINFO_GENERIC_HANDLE)value.stubLookup.constLookup.handle; |
1466 | } |
1467 | if (pResult->kind == CORINFO_VIRTUALCALL_STUB) |
1468 | { |
1469 | cr->CallTargetTypes->Add((DWORDLONG)pResult->codePointerLookup.constLookup.addr, |
1470 | (DWORD)CORINFO_VIRTUALCALL_STUB); |
1471 | } |
1472 | pResult->instParamLookup.accessType = (InfoAccessType)value.instParamLookup.accessType; |
1473 | pResult->instParamLookup.handle = (CORINFO_GENERIC_HANDLE)value.instParamLookup.handle; |
1474 | pResult->secureDelegateInvoke = (BOOL)value.secureDelegateInvoke; |
1475 | *exceptionCode = (DWORD)value.exceptionCode; |
1476 | |
1477 | DEBUG_REP(dmpGetCallInfo(key, value)); |
1478 | } |
1479 | |
1480 | // |
1481 | // Variant of repGetCallInfo that only requires a method handle, i.e. it performs a reverse lookup to find the |
1482 | // resolved token info that, along with the given method handle, was passed into getCallInfo. |
1483 | // |
1484 | // Arguments: |
1485 | // methodHandle - The method handle to find call info for. |
1486 | // pResult - [out] The call info for the given method. |
1487 | // |
1488 | // Notes: |
1489 | // If this fails to find a recorded call to getCallInfo with the given method handle, this will throw an |
1490 | // exception. |
1491 | // |
1492 | void MethodContext::repGetCallInfoFromMethodHandle(CORINFO_METHOD_HANDLE methodHandle, CORINFO_CALL_INFO* pResult) |
1493 | { |
1494 | if (GetCallInfo != nullptr) |
1495 | { |
1496 | for (unsigned int i = 0; i < GetCallInfo->GetCount(); i++) |
1497 | { |
1498 | Agnostic_GetCallInfo key = GetCallInfo->GetKey(i); |
1499 | Agnostic_CORINFO_CALL_INFO val = GetCallInfo->GetItem(i); |
1500 | |
1501 | if ((CORINFO_METHOD_HANDLE)val.hMethod == methodHandle) |
1502 | { |
1503 | CORINFO_RESOLVED_TOKEN resolvedToken; |
1504 | DWORD exceptionCode; |
1505 | |
1506 | resolvedToken.tokenContext = (CORINFO_CONTEXT_HANDLE)key.ResolvedToken.inValue.tokenContext; |
1507 | resolvedToken.tokenScope = (CORINFO_MODULE_HANDLE)key.ResolvedToken.inValue.tokenScope; |
1508 | resolvedToken.token = (mdToken)key.ResolvedToken.inValue.token; |
1509 | resolvedToken.tokenType = (CorInfoTokenKind)key.ResolvedToken.inValue.tokenType; |
1510 | |
1511 | repResolveToken(&resolvedToken, &exceptionCode); |
1512 | |
1513 | // If the original call to getCallInfo passed in a null constrainedResolvedToken pointer, |
1514 | // then we won't be able to replay it. In that case, we'll need to pass a null pointer into |
1515 | // repGetCallInfo for constrainedResolvedToken, instead of just passing the address of our |
1516 | // local (but meaningless) constrainedResolvedToken struct. |
1517 | CORINFO_RESOLVED_TOKEN constrainedResolvedToken; |
1518 | CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken = nullptr; |
1519 | |
1520 | if (key.ConstrainedResolvedToken.inValue.tokenContext != 0 && |
1521 | key.ConstrainedResolvedToken.inValue.tokenScope != 0) |
1522 | { |
1523 | constrainedResolvedToken.tokenContext = |
1524 | (CORINFO_CONTEXT_HANDLE)key.ConstrainedResolvedToken.inValue.tokenContext; |
1525 | constrainedResolvedToken.tokenScope = |
1526 | (CORINFO_MODULE_HANDLE)key.ConstrainedResolvedToken.inValue.tokenScope; |
1527 | constrainedResolvedToken.token = (mdToken)key.ConstrainedResolvedToken.inValue.token; |
1528 | constrainedResolvedToken.tokenType = |
1529 | (CorInfoTokenKind)key.ConstrainedResolvedToken.inValue.tokenType; |
1530 | pConstrainedResolvedToken = &constrainedResolvedToken; |
1531 | |
1532 | repResolveToken(pConstrainedResolvedToken, &exceptionCode); |
1533 | } |
1534 | |
1535 | repGetCallInfo(&resolvedToken, pConstrainedResolvedToken, (CORINFO_METHOD_HANDLE)key.callerHandle, |
1536 | (CORINFO_CALLINFO_FLAGS)key.flags, pResult, &exceptionCode); |
1537 | return; |
1538 | } |
1539 | } |
1540 | } |
1541 | |
1542 | // If we reached here, we didn't find a key associated with the given method handle |
1543 | LogException(EXCEPTIONCODE_MC, "Didn't find key %016llX." , methodHandle); |
1544 | } |
1545 | |
1546 | void MethodContext::recGetIntrinsicID(CORINFO_METHOD_HANDLE method, bool* pMustExpand, CorInfoIntrinsics result) |
1547 | { |
1548 | if (GetIntrinsicID == nullptr) |
1549 | GetIntrinsicID = new LightWeightMap<DWORDLONG, DD>(); |
1550 | |
1551 | DD value; |
1552 | value.A = (pMustExpand != nullptr) ? (DWORD)(*pMustExpand ? 1 : 0) : (DWORD)0; |
1553 | value.B = (DWORD)result; |
1554 | |
1555 | GetIntrinsicID->Add((DWORDLONG)method, value); |
1556 | DEBUG_REC(dmpGetIntrinsicID((DWORDLONG)method, value)); |
1557 | } |
1558 | void MethodContext::dmpGetIntrinsicID(DWORDLONG key, DD value) |
1559 | { |
1560 | printf("GetIntrinsicID key mth-%016llX, mustExpand-%u, value intr-%u" , key, value.A, value.B); |
1561 | } |
1562 | CorInfoIntrinsics MethodContext::repGetIntrinsicID(CORINFO_METHOD_HANDLE method, bool* pMustExpand) |
1563 | { |
1564 | AssertCodeMsg(GetIntrinsicID != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , (DWORDLONG)method); |
1565 | AssertCodeMsg(GetIntrinsicID->GetIndex((DWORDLONG)method) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
1566 | (DWORDLONG)method); |
1567 | |
1568 | DD value; |
1569 | value = GetIntrinsicID->Get((DWORDLONG)method); |
1570 | if (pMustExpand != nullptr) |
1571 | { |
1572 | *pMustExpand = (value.A == 0) ? false : true; |
1573 | } |
1574 | CorInfoIntrinsics result = (CorInfoIntrinsics)value.B; |
1575 | |
1576 | DEBUG_REP(dmpGetIntrinsicID((DWORDLONG)method, value)); |
1577 | return result; |
1578 | } |
1579 | |
1580 | void MethodContext::recIsInSIMDModule(CORINFO_CLASS_HANDLE cls, BOOL result) |
1581 | { |
1582 | if (IsInSIMDModule == nullptr) |
1583 | IsInSIMDModule = new LightWeightMap<DWORDLONG, DWORD>(); |
1584 | |
1585 | IsInSIMDModule->Add((DWORDLONG)cls, (DWORD)result); |
1586 | DEBUG_REC(dmpIsInSIMDModule((DWORDLONG)cls, (DWORD)result)); |
1587 | } |
1588 | void MethodContext::dmpIsInSIMDModule(DWORDLONG key, DWORD value) |
1589 | { |
1590 | printf("IsInSIMDModule key mth-%016llX, value intr-%u" , key, value); |
1591 | } |
1592 | BOOL MethodContext::repIsInSIMDModule(CORINFO_CLASS_HANDLE cls) |
1593 | { |
1594 | AssertCodeMsg(IsInSIMDModule != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , (DWORDLONG)cls); |
1595 | AssertCodeMsg(IsInSIMDModule->GetIndex((DWORDLONG)cls) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
1596 | (DWORDLONG)cls); |
1597 | BOOL result = (BOOL)IsInSIMDModule->Get((DWORDLONG)cls); |
1598 | DEBUG_REP(dmpIsInSIMDModule((DWORDLONG)cls, (DWORD)result)); |
1599 | return result; |
1600 | } |
1601 | |
1602 | void MethodContext::recGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CorInfoUnmanagedCallConv result) |
1603 | { |
1604 | if (GetUnmanagedCallConv == nullptr) |
1605 | GetUnmanagedCallConv = new LightWeightMap<DWORDLONG, DWORD>(); |
1606 | |
1607 | GetUnmanagedCallConv->Add((DWORDLONG)method, result); |
1608 | DEBUG_REC(dmpGetUnmanagedCallConv((DWORDLONG)method, (DWORD)result)); |
1609 | } |
1610 | void MethodContext::dmpGetUnmanagedCallConv(DWORDLONG key, DWORD result) |
1611 | { |
1612 | printf("GetUnmanagedCallConv key ftn-%016llX, value res-%u" , key, result); |
1613 | } |
1614 | CorInfoUnmanagedCallConv MethodContext::repGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method) |
1615 | { |
1616 | if ((GetUnmanagedCallConv == nullptr) || (GetUnmanagedCallConv->GetIndex((DWORDLONG)method) == -1)) |
1617 | { |
1618 | #ifdef sparseMC |
1619 | LogDebug("Sparse - repGetUnmanagedCallConv returning CORINFO_UNMANAGED_CALLCONV_STDCALL" ); |
1620 | return CORINFO_UNMANAGED_CALLCONV_STDCALL; |
1621 | #else |
1622 | LogException(EXCEPTIONCODE_MC, "Found a null GetUnmanagedCallConv. Probably missing a fatTrigger for %016llX." , |
1623 | (DWORDLONG)method); |
1624 | #endif |
1625 | } |
1626 | CorInfoUnmanagedCallConv result = (CorInfoUnmanagedCallConv)GetUnmanagedCallConv->Get((DWORDLONG)method); |
1627 | DEBUG_REP(dmpGetUnmanagedCallConv((DWORDLONG)method, (DWORD)result)); |
1628 | return result; |
1629 | } |
1630 | |
1631 | void MethodContext::recIsInstantiationOfVerifiedGeneric(CORINFO_METHOD_HANDLE method, |
1632 | CorInfoInstantiationVerification result) |
1633 | { |
1634 | if (IsInstantiationOfVerifiedGeneric == nullptr) |
1635 | IsInstantiationOfVerifiedGeneric = new LightWeightMap<DWORDLONG, DWORD>(); |
1636 | |
1637 | IsInstantiationOfVerifiedGeneric->Add((DWORDLONG)method, result); |
1638 | DEBUG_REC(dmpIsInstantiationOfVerifiedGeneric((DWORDLONG)method, (DWORD)result)); |
1639 | } |
1640 | void MethodContext::dmpIsInstantiationOfVerifiedGeneric(DWORDLONG key, DWORD value) |
1641 | { |
1642 | printf("IsInstantiationOfVerifiedGeneric key ftn-%016llX, value res-%u" , key, value); |
1643 | } |
1644 | CorInfoInstantiationVerification MethodContext::repIsInstantiationOfVerifiedGeneric(CORINFO_METHOD_HANDLE method) |
1645 | { |
1646 | CorInfoInstantiationVerification result = |
1647 | (CorInfoInstantiationVerification)IsInstantiationOfVerifiedGeneric->Get((DWORDLONG)method); |
1648 | DEBUG_REP(dmpIsInstantiationOfVerifiedGeneric((DWORDLONG)method, (DWORD)result)); |
1649 | return result; |
1650 | } |
1651 | |
1652 | void MethodContext::recAsCorInfoType(CORINFO_CLASS_HANDLE cls, CorInfoType result) |
1653 | { |
1654 | if (AsCorInfoType == nullptr) |
1655 | AsCorInfoType = new LightWeightMap<DWORDLONG, DWORD>(); |
1656 | |
1657 | AsCorInfoType->Add((DWORDLONG)cls, (DWORD)result); |
1658 | DEBUG_REC(dmpAsCorInfoType((DWORDLONG)cls, (DWORD)result)); |
1659 | } |
1660 | void MethodContext::dmpAsCorInfoType(DWORDLONG key, DWORD value) |
1661 | { |
1662 | printf("AsCorInfoType key cls-%016llX, value cit-%u(%s)" , key, value, toString((CorInfoType)value)); |
1663 | } |
1664 | CorInfoType MethodContext::repAsCorInfoType(CORINFO_CLASS_HANDLE cls) |
1665 | { |
1666 | AssertCodeMsg((AsCorInfoType != nullptr) && (AsCorInfoType->GetIndex((DWORDLONG)cls) != -1), EXCEPTIONCODE_MC, |
1667 | "Didn't find %016llX. Probable cached value in JIT issue" , (DWORDLONG)cls); |
1668 | CorInfoType result = (CorInfoType)AsCorInfoType->Get((DWORDLONG)cls); |
1669 | DEBUG_REP(dmpAsCorInfoType((DWORDLONG)cls, (DWORD)result)); |
1670 | return result; |
1671 | } |
1672 | |
1673 | void MethodContext::recIsValueClass(CORINFO_CLASS_HANDLE cls, BOOL result) |
1674 | { |
1675 | if (IsValueClass == nullptr) |
1676 | IsValueClass = new LightWeightMap<DWORDLONG, DWORD>(); |
1677 | |
1678 | IsValueClass->Add((DWORDLONG)cls, (DWORD)result); |
1679 | DEBUG_REC(dmpIsValueClass((DWORDLONG)cls, (DWORD)result)); |
1680 | } |
1681 | void MethodContext::dmpIsValueClass(DWORDLONG key, DWORD value) |
1682 | { |
1683 | printf("IsValueClass key cls-%016llX, value res-%u" , key, value); |
1684 | } |
1685 | BOOL MethodContext::repIsValueClass(CORINFO_CLASS_HANDLE cls) |
1686 | { |
1687 | AssertCodeMsg((IsValueClass != nullptr) && (IsValueClass->GetIndex((DWORDLONG)cls) != -1), EXCEPTIONCODE_MC, |
1688 | "Didn't find %016llX" , (DWORDLONG)cls); |
1689 | |
1690 | BOOL result = (BOOL)IsValueClass->Get((DWORDLONG)cls); |
1691 | DEBUG_REP(dmpIsValueClass((DWORDLONG)cls, (DWORD)result)); |
1692 | return result; |
1693 | } |
1694 | |
1695 | void MethodContext::recIsStructRequiringStackAllocRetBuf(CORINFO_CLASS_HANDLE cls, BOOL result) |
1696 | { |
1697 | if (IsStructRequiringStackAllocRetBuf == nullptr) |
1698 | IsStructRequiringStackAllocRetBuf = new LightWeightMap<DWORDLONG, DWORD>(); |
1699 | |
1700 | IsStructRequiringStackAllocRetBuf->Add((DWORDLONG)cls, (DWORD)result); |
1701 | DEBUG_REC(dmpIsStructRequiringStackAllocRetBuf((DWORDLONG)cls, (DWORD)result)); |
1702 | } |
1703 | void MethodContext::dmpIsStructRequiringStackAllocRetBuf(DWORDLONG key, DWORD value) |
1704 | { |
1705 | printf("IsStructRequiringStackAllocRetBuf key cls-%016llX, value res-%u" , key, value); |
1706 | } |
1707 | BOOL MethodContext::repIsStructRequiringStackAllocRetBuf(CORINFO_CLASS_HANDLE cls) |
1708 | { |
1709 | AssertCodeMsg(IsStructRequiringStackAllocRetBuf != nullptr, EXCEPTIONCODE_MC, |
1710 | "Found a null IsStructRequiringStackAllocRetBuf. Probably missing a fatTrigger for %016llX." , |
1711 | (DWORDLONG)cls); |
1712 | AssertCodeMsg(IsStructRequiringStackAllocRetBuf->GetIndex((DWORDLONG)cls) != -1, EXCEPTIONCODE_MC, |
1713 | "Didn't find %016llX" , (DWORDLONG)cls); |
1714 | BOOL result = (BOOL)IsStructRequiringStackAllocRetBuf->Get((DWORDLONG)cls); |
1715 | DEBUG_REP(dmpIsStructRequiringStackAllocRetBuf((DWORDLONG)cls, (DWORD)result)); |
1716 | return result; |
1717 | } |
1718 | |
1719 | void MethodContext::recGetClassSize(CORINFO_CLASS_HANDLE cls, unsigned result) |
1720 | { |
1721 | if (GetClassSize == nullptr) |
1722 | GetClassSize = new LightWeightMap<DWORDLONG, DWORD>(); |
1723 | |
1724 | GetClassSize->Add((DWORDLONG)cls, (DWORD)result); |
1725 | DEBUG_REC(dmpGetClassSize((DWORDLONG)cls, (DWORD)result)); |
1726 | } |
1727 | void MethodContext::dmpGetClassSize(DWORDLONG key, DWORD val) |
1728 | { |
1729 | printf("GetClassSize key %016llX, value %u" , key, val); |
1730 | } |
1731 | unsigned MethodContext::repGetClassSize(CORINFO_CLASS_HANDLE cls) |
1732 | { |
1733 | AssertCodeMsg(GetClassSize != nullptr, EXCEPTIONCODE_MC, "Didn't find %016llX" , (DWORDLONG)cls); |
1734 | AssertCodeMsg(GetClassSize->GetIndex((DWORDLONG)cls) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
1735 | (DWORDLONG)cls); |
1736 | unsigned result = (unsigned)GetClassSize->Get((DWORDLONG)cls); |
1737 | DEBUG_REP(dmpGetClassSize((DWORDLONG)cls, (DWORD)result)); |
1738 | return result; |
1739 | } |
1740 | |
1741 | void MethodContext::recGetHeapClassSize(CORINFO_CLASS_HANDLE cls, unsigned result) |
1742 | { |
1743 | if (GetHeapClassSize == nullptr) |
1744 | GetHeapClassSize = new LightWeightMap<DWORDLONG, DWORD>(); |
1745 | |
1746 | GetHeapClassSize->Add((DWORDLONG)cls, (DWORD)result); |
1747 | DEBUG_REC(dmpGetHeapClassSize((DWORDLONG)cls, (DWORD)result)); |
1748 | } |
1749 | void MethodContext::dmpGetHeapClassSize(DWORDLONG key, DWORD val) |
1750 | { |
1751 | printf("GetHeapClassSize key %016llX, value %u" , key, val); |
1752 | } |
1753 | unsigned MethodContext::repGetHeapClassSize(CORINFO_CLASS_HANDLE cls) |
1754 | { |
1755 | AssertCodeMsg(GetHeapClassSize != nullptr, EXCEPTIONCODE_MC, "Didn't find %016llX" , (DWORDLONG)cls); |
1756 | AssertCodeMsg(GetHeapClassSize->GetIndex((DWORDLONG)cls) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
1757 | (DWORDLONG)cls); |
1758 | unsigned result = (unsigned)GetHeapClassSize->Get((DWORDLONG)cls); |
1759 | DEBUG_REP(dmpGetHeapClassSize((DWORDLONG)cls, (DWORD)result)); |
1760 | return result; |
1761 | } |
1762 | |
1763 | void MethodContext::recCanAllocateOnStack(CORINFO_CLASS_HANDLE cls, BOOL result) |
1764 | { |
1765 | if (CanAllocateOnStack == nullptr) |
1766 | CanAllocateOnStack = new LightWeightMap<DWORDLONG, DWORD>(); |
1767 | |
1768 | CanAllocateOnStack->Add((DWORDLONG)cls, (DWORD)result); |
1769 | DEBUG_REC(dmpCanAllocateOnStack((DWORDLONG)cls, (DWORD)result)); |
1770 | } |
1771 | void MethodContext::dmpCanAllocateOnStack(DWORDLONG key, DWORD val) |
1772 | { |
1773 | printf("CanAllocateOnStack key %016llX, value %u" , key, val); |
1774 | } |
1775 | BOOL MethodContext::repCanAllocateOnStack(CORINFO_CLASS_HANDLE cls) |
1776 | { |
1777 | AssertCodeMsg(CanAllocateOnStack != nullptr, EXCEPTIONCODE_MC, "Didn't find %016llX" , (DWORDLONG)cls); |
1778 | AssertCodeMsg(CanAllocateOnStack->GetIndex((DWORDLONG)cls) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
1779 | (DWORDLONG)cls); |
1780 | BOOL result = (BOOL)CanAllocateOnStack->Get((DWORDLONG)cls); |
1781 | DEBUG_REP(dmpCanAllocateOnStack((DWORDLONG)cls, (DWORD)result)); |
1782 | return result; |
1783 | } |
1784 | |
1785 | void MethodContext::recGetClassNumInstanceFields(CORINFO_CLASS_HANDLE cls, unsigned result) |
1786 | { |
1787 | if (GetClassNumInstanceFields == nullptr) |
1788 | GetClassNumInstanceFields = new LightWeightMap<DWORDLONG, DWORD>(); |
1789 | |
1790 | GetClassNumInstanceFields->Add((DWORDLONG)cls, (DWORD)result); |
1791 | DEBUG_REC(dmpGetClassNumInstanceFields((DWORDLONG)cls, (DWORD)result)); |
1792 | } |
1793 | void MethodContext::dmpGetClassNumInstanceFields(DWORDLONG key, DWORD value) |
1794 | { |
1795 | printf("GetClassNumInstanceFields key cls-%016llX, value res-%u" , key, value); |
1796 | } |
1797 | unsigned MethodContext::repGetClassNumInstanceFields(CORINFO_CLASS_HANDLE cls) |
1798 | { |
1799 | AssertCodeMsg(GetClassNumInstanceFields != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , |
1800 | (DWORDLONG)cls); |
1801 | AssertCodeMsg(GetClassNumInstanceFields->GetIndex((DWORDLONG)cls) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
1802 | (DWORDLONG)cls); |
1803 | |
1804 | unsigned result = (unsigned)GetClassNumInstanceFields->Get((DWORDLONG)cls); |
1805 | DEBUG_REP(dmpGetClassNumInstanceFields((DWORDLONG)cls, (DWORD)result)); |
1806 | return result; |
1807 | } |
1808 | |
1809 | void MethodContext::recGetNewArrHelper(CORINFO_CLASS_HANDLE arrayCls, CorInfoHelpFunc result) |
1810 | { |
1811 | if (GetNewArrHelper == nullptr) |
1812 | GetNewArrHelper = new LightWeightMap<DWORDLONG, DWORD>(); |
1813 | |
1814 | GetNewArrHelper->Add((DWORDLONG)arrayCls, result); |
1815 | DEBUG_REC(dmpGetNewArrHelper((DWORDLONG)arrayCls, (DWORD)result)); |
1816 | } |
1817 | void MethodContext::dmpGetNewArrHelper(DWORDLONG key, DWORD value) |
1818 | { |
1819 | printf("GetNewArrHelper key cls-%016llX, value res-%u" , key, value); |
1820 | } |
1821 | CorInfoHelpFunc MethodContext::repGetNewArrHelper(CORINFO_CLASS_HANDLE arrayCls) |
1822 | { |
1823 | CorInfoHelpFunc result = (CorInfoHelpFunc)GetNewArrHelper->Get((DWORDLONG)arrayCls); |
1824 | DEBUG_REP(dmpGetNewArrHelper((DWORDLONG)arrayCls, (DWORD)result)); |
1825 | return result; |
1826 | } |
1827 | |
1828 | void MethodContext::recGetSharedCCtorHelper(CORINFO_CLASS_HANDLE clsHnd, CorInfoHelpFunc result) |
1829 | { |
1830 | if (GetSharedCCtorHelper == nullptr) |
1831 | GetSharedCCtorHelper = new LightWeightMap<DWORDLONG, DWORD>(); |
1832 | |
1833 | GetSharedCCtorHelper->Add((DWORDLONG)clsHnd, result); |
1834 | DEBUG_REC(dmpGetSharedCCtorHelper((DWORDLONG)clsHnd, (DWORD)result)); |
1835 | } |
1836 | void MethodContext::dmpGetSharedCCtorHelper(DWORDLONG key, DWORD value) |
1837 | { |
1838 | printf("GetSharedCCtorHelper key cls-%016llX, value res-%u" , key, value); |
1839 | } |
1840 | CorInfoHelpFunc MethodContext::repGetSharedCCtorHelper(CORINFO_CLASS_HANDLE clsHnd) |
1841 | { |
1842 | CorInfoHelpFunc result = (CorInfoHelpFunc)GetSharedCCtorHelper->Get((DWORDLONG)clsHnd); |
1843 | DEBUG_REP(dmpGetSharedCCtorHelper((DWORDLONG)clsHnd, (DWORD)result)); |
1844 | return result; |
1845 | } |
1846 | |
1847 | void MethodContext::recGetSecurityPrologHelper(CORINFO_METHOD_HANDLE ftn, CorInfoHelpFunc result) |
1848 | { |
1849 | if (GetSecurityPrologHelper == nullptr) |
1850 | GetSecurityPrologHelper = new LightWeightMap<DWORDLONG, DWORD>(); |
1851 | |
1852 | GetSecurityPrologHelper->Add((DWORDLONG)ftn, result); |
1853 | DEBUG_REC(dmpGetSecurityPrologHelper((DWORDLONG)ftn, (DWORD)result)); |
1854 | } |
1855 | void MethodContext::dmpGetSecurityPrologHelper(DWORDLONG key, DWORD value) |
1856 | { |
1857 | printf("GetSecurityPrologHelper key ftn-%016llX, value res-%u" , key, value); |
1858 | } |
1859 | CorInfoHelpFunc MethodContext::repGetSecurityPrologHelper(CORINFO_METHOD_HANDLE ftn) |
1860 | { |
1861 | CorInfoHelpFunc result = (CorInfoHelpFunc)GetSecurityPrologHelper->Get((DWORDLONG)ftn); |
1862 | DEBUG_REP(dmpGetSecurityPrologHelper((DWORDLONG)ftn, (DWORD)result)); |
1863 | return result; |
1864 | } |
1865 | |
1866 | void MethodContext::recGetTypeForBox(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result) |
1867 | { |
1868 | if (GetTypeForBox == nullptr) |
1869 | GetTypeForBox = new LightWeightMap<DWORDLONG, DWORDLONG>(); |
1870 | |
1871 | GetTypeForBox->Add((DWORDLONG)cls, (DWORDLONG)result); |
1872 | DEBUG_REC(dmpGetTypeForBox((DWORDLONG)cls, (DWORDLONG)result)); |
1873 | } |
1874 | void MethodContext::dmpGetTypeForBox(DWORDLONG key, DWORDLONG value) |
1875 | { |
1876 | printf("GetTypeForBox key cls-%016llX, value res-%016llX" , key, value); |
1877 | } |
1878 | CORINFO_CLASS_HANDLE MethodContext::repGetTypeForBox(CORINFO_CLASS_HANDLE cls) |
1879 | { |
1880 | CORINFO_CLASS_HANDLE result = (CORINFO_CLASS_HANDLE)GetTypeForBox->Get((DWORDLONG)cls); |
1881 | DEBUG_REP(dmpGetTypeForBox((DWORDLONG)cls, (DWORDLONG)result)); |
1882 | return result; |
1883 | } |
1884 | |
1885 | void MethodContext::recGetBoxHelper(CORINFO_CLASS_HANDLE cls, CorInfoHelpFunc result) |
1886 | { |
1887 | if (GetBoxHelper == nullptr) |
1888 | GetBoxHelper = new LightWeightMap<DWORDLONG, DWORD>(); |
1889 | |
1890 | GetBoxHelper->Add((DWORDLONG)cls, result); |
1891 | DEBUG_REC(dmpGetBoxHelper((DWORDLONG)cls, (DWORD)result)); |
1892 | } |
1893 | void MethodContext::dmpGetBoxHelper(DWORDLONG key, DWORD value) |
1894 | { |
1895 | printf("GetBoxHelper key cls-%016llX, value res-%u" , key, value); |
1896 | } |
1897 | CorInfoHelpFunc MethodContext::repGetBoxHelper(CORINFO_CLASS_HANDLE cls) |
1898 | { |
1899 | CorInfoHelpFunc result = (CorInfoHelpFunc)GetBoxHelper->Get((DWORDLONG)cls); |
1900 | DEBUG_REP(dmpGetBoxHelper((DWORDLONG)cls, (DWORD)result)); |
1901 | return result; |
1902 | } |
1903 | |
1904 | void MethodContext::recGetBuiltinClass(CorInfoClassId classId, CORINFO_CLASS_HANDLE result) |
1905 | { |
1906 | if (GetBuiltinClass == nullptr) |
1907 | GetBuiltinClass = new LightWeightMap<DWORD, DWORDLONG>(); |
1908 | |
1909 | GetBuiltinClass->Add((DWORD)classId, (DWORDLONG)result); |
1910 | DEBUG_REC(dmpGetBuiltinClass((DWORDLONG)classId, (DWORDLONG)result)); |
1911 | } |
1912 | void MethodContext::dmpGetBuiltinClass(DWORD key, DWORDLONG value) |
1913 | { |
1914 | printf("GetBuiltinClass key cls-%08X, value cls-%016llX" , key, value); |
1915 | } |
1916 | CORINFO_CLASS_HANDLE MethodContext::repGetBuiltinClass(CorInfoClassId classId) |
1917 | { |
1918 | AssertCodeMsg(GetBuiltinClass != nullptr, EXCEPTIONCODE_MC, "Encountered an empty LWM while looking for %016llX" , |
1919 | (DWORDLONG)classId); |
1920 | AssertCodeMsg(GetBuiltinClass->GetIndex((DWORDLONG)classId) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
1921 | (DWORDLONG)classId); |
1922 | CORINFO_CLASS_HANDLE value = (CORINFO_CLASS_HANDLE)GetBuiltinClass->Get((DWORD)classId); |
1923 | DEBUG_REP(dmpGetBuiltinClass((DWORDLONG)classId, (DWORDLONG)value)); |
1924 | return value; |
1925 | } |
1926 | |
1927 | void MethodContext::recGetTypeForPrimitiveValueClass(CORINFO_CLASS_HANDLE cls, CorInfoType result) |
1928 | { |
1929 | if (GetTypeForPrimitiveValueClass == nullptr) |
1930 | GetTypeForPrimitiveValueClass = new LightWeightMap<DWORDLONG, DWORD>(); |
1931 | |
1932 | GetTypeForPrimitiveValueClass->Add((DWORDLONG)cls, result); |
1933 | DEBUG_REC(dmpGetTypeForPrimitiveValueClass((DWORDLONG)cls, (DWORD)result)); |
1934 | } |
1935 | void MethodContext::dmpGetTypeForPrimitiveValueClass(DWORDLONG key, DWORD value) |
1936 | { |
1937 | printf("GetTypeForPrimitiveValueClass key cls-%016llX, value cit-%u(%s)" , key, value, toString((CorInfoType)value)); |
1938 | } |
1939 | CorInfoType MethodContext::repGetTypeForPrimitiveValueClass(CORINFO_CLASS_HANDLE cls) |
1940 | { |
1941 | AssertCodeMsg(GetTypeForPrimitiveValueClass != nullptr, EXCEPTIONCODE_MC, |
1942 | "Encountered an empty LWM while looking for %016llX" , (DWORDLONG)cls); |
1943 | AssertCodeMsg(GetTypeForPrimitiveValueClass->GetIndex((DWORDLONG)cls) != -1, EXCEPTIONCODE_MC, |
1944 | "Didn't find %016llX" , (DWORDLONG)cls); |
1945 | CorInfoType result = (CorInfoType)GetTypeForPrimitiveValueClass->Get((DWORDLONG)cls); |
1946 | DEBUG_REP(dmpGetTypeForPrimitiveValueClass((DWORDLONG)cls, (DWORD)result)); |
1947 | return result; |
1948 | } |
1949 | |
1950 | void MethodContext::recGetTypeForPrimitiveNumericClass(CORINFO_CLASS_HANDLE cls, CorInfoType result) |
1951 | { |
1952 | if (GetTypeForPrimitiveNumericClass == nullptr) |
1953 | GetTypeForPrimitiveNumericClass = new LightWeightMap<DWORDLONG, DWORD>(); |
1954 | |
1955 | GetTypeForPrimitiveNumericClass->Add((DWORDLONG)cls, result); |
1956 | DEBUG_REC(dmpGetTypeForPrimitiveNumericClass((DWORDLONG)cls, (DWORD)result)); |
1957 | } |
1958 | void MethodContext::dmpGetTypeForPrimitiveNumericClass(DWORDLONG key, DWORD value) |
1959 | { |
1960 | printf("GetTypeForPrimitiveNumericClass key cls-%016llX, value cit-%u(%s)" , key, value, |
1961 | toString((CorInfoType)value)); |
1962 | } |
1963 | CorInfoType MethodContext::repGetTypeForPrimitiveNumericClass(CORINFO_CLASS_HANDLE cls) |
1964 | { |
1965 | AssertCodeMsg(GetTypeForPrimitiveNumericClass != nullptr, EXCEPTIONCODE_MC, |
1966 | "Encountered an empty LWM while looking for %016llX" , (DWORDLONG)cls); |
1967 | AssertCodeMsg(GetTypeForPrimitiveNumericClass->GetIndex((DWORDLONG)cls) != -1, EXCEPTIONCODE_MC, |
1968 | "Didn't find %016llX" , (DWORDLONG)cls); |
1969 | CorInfoType result = (CorInfoType)GetTypeForPrimitiveNumericClass->Get((DWORDLONG)cls); |
1970 | DEBUG_REP(dmpGetTypeForPrimitiveNumericClass((DWORDLONG)cls, (DWORD)result)); |
1971 | return result; |
1972 | } |
1973 | |
1974 | void MethodContext::recGetParentType(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result) |
1975 | { |
1976 | if (GetParentType == nullptr) |
1977 | GetParentType = new LightWeightMap<DWORDLONG, DWORDLONG>(); |
1978 | |
1979 | GetParentType->Add((DWORDLONG)cls, (DWORDLONG)result); |
1980 | } |
1981 | void MethodContext::dmpGetParentType(DWORDLONG key, DWORDLONG value) |
1982 | { |
1983 | printf("GetParentType key cls-%016llX, value cls-%016llX" , key, value); |
1984 | } |
1985 | CORINFO_CLASS_HANDLE MethodContext::repGetParentType(CORINFO_CLASS_HANDLE cls) |
1986 | { |
1987 | CORINFO_CLASS_HANDLE result = (CORINFO_CLASS_HANDLE)GetParentType->Get((DWORDLONG)cls); |
1988 | return result; |
1989 | } |
1990 | |
1991 | void MethodContext::recIsSDArray(CORINFO_CLASS_HANDLE cls, BOOL result) |
1992 | { |
1993 | if (IsSDArray == nullptr) |
1994 | IsSDArray = new LightWeightMap<DWORDLONG, DWORD>(); |
1995 | |
1996 | IsSDArray->Add((DWORDLONG)cls, result); |
1997 | DEBUG_REC(dmpIsSDArray((DWORDLONG)cls, (DWORD)result)); |
1998 | } |
1999 | void MethodContext::dmpIsSDArray(DWORDLONG key, DWORD value) |
2000 | { |
2001 | printf("IsSDArray key cls-%016llX, value res-%u" , key, value); |
2002 | } |
2003 | BOOL MethodContext::repIsSDArray(CORINFO_CLASS_HANDLE cls) |
2004 | { |
2005 | AssertCodeMsg(IsSDArray != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , (DWORDLONG)cls); |
2006 | AssertCodeMsg(IsSDArray->GetIndex((DWORDLONG)cls) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , (DWORDLONG)cls); |
2007 | BOOL temp = (BOOL)IsSDArray->Get((DWORDLONG)cls); |
2008 | DEBUG_REP(dmpIsSDArray((DWORDLONG)cls, (DWORD)temp)); |
2009 | return temp; |
2010 | } |
2011 | |
2012 | void MethodContext::recGetFieldClass(CORINFO_FIELD_HANDLE field, CORINFO_CLASS_HANDLE result) |
2013 | { |
2014 | if (GetFieldClass == nullptr) |
2015 | GetFieldClass = new LightWeightMap<DWORDLONG, DWORDLONG>(); |
2016 | |
2017 | GetFieldClass->Add((DWORDLONG)field, (DWORDLONG)result); |
2018 | DEBUG_REC(dmpGetFieldClass((DWORDLONG)field, (DWORDLONG)result)); |
2019 | } |
2020 | void MethodContext::dmpGetFieldClass(DWORDLONG key, DWORDLONG value) |
2021 | { |
2022 | printf("GetFieldClass key %016llX, value %016llX" , key, value); |
2023 | } |
2024 | CORINFO_CLASS_HANDLE MethodContext::repGetFieldClass(CORINFO_FIELD_HANDLE field) |
2025 | { |
2026 | AssertCodeMsg(GetFieldClass != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , (DWORDLONG)field); |
2027 | AssertCodeMsg(GetFieldClass->GetIndex((DWORDLONG)field) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
2028 | (DWORDLONG)field); |
2029 | CORINFO_CLASS_HANDLE temp = (CORINFO_CLASS_HANDLE)GetFieldClass->Get((DWORDLONG)field); |
2030 | DEBUG_REP(dmpGetFieldClass((DWORDLONG)field, (DWORDLONG)temp)); |
2031 | return temp; |
2032 | } |
2033 | |
2034 | void MethodContext::recGetFieldOffset(CORINFO_FIELD_HANDLE field, unsigned result) |
2035 | { |
2036 | if (GetFieldOffset == nullptr) |
2037 | GetFieldOffset = new LightWeightMap<DWORDLONG, DWORD>(); |
2038 | |
2039 | GetFieldOffset->Add((DWORDLONG)field, result); |
2040 | DEBUG_REC(dmpGetFieldOffset((DWORDLONG)field, (DWORD)result)); |
2041 | } |
2042 | void MethodContext::dmpGetFieldOffset(DWORDLONG key, DWORD value) |
2043 | { |
2044 | printf("GetFieldOffset key FLD-%016llX, value %08X" , key, value); |
2045 | } |
2046 | unsigned MethodContext::repGetFieldOffset(CORINFO_FIELD_HANDLE field) |
2047 | { |
2048 | AssertCodeMsg((GetFieldOffset != nullptr) && (GetFieldOffset->GetIndex((DWORDLONG)field) != -1), EXCEPTIONCODE_MC, |
2049 | "Didn't find %016llX" , (DWORDLONG)field); |
2050 | |
2051 | unsigned temp = (unsigned)GetFieldOffset->Get((DWORDLONG)field); |
2052 | DEBUG_REP(dmpGetFieldOffset((DWORDLONG)field, (DWORD)temp)); |
2053 | return temp; |
2054 | } |
2055 | |
2056 | void MethodContext::recGetLazyStringLiteralHelper(CORINFO_MODULE_HANDLE handle, CorInfoHelpFunc result) |
2057 | { |
2058 | if (GetLazyStringLiteralHelper == nullptr) |
2059 | GetLazyStringLiteralHelper = new LightWeightMap<DWORDLONG, DWORD>(); |
2060 | |
2061 | GetLazyStringLiteralHelper->Add((DWORDLONG)handle, result); |
2062 | DEBUG_REC(dmpGetLazyStringLiteralHelper((DWORDLONG)handle, result)); |
2063 | } |
2064 | |
2065 | void MethodContext::dmpGetLazyStringLiteralHelper(DWORDLONG key, DWORD value) |
2066 | { |
2067 | printf("GetLazyStringLiteralHelper key mod-%016llX, value res-%u" , key, value); |
2068 | } |
2069 | |
2070 | CorInfoHelpFunc MethodContext::repGetLazyStringLiteralHelper(CORINFO_MODULE_HANDLE handle) |
2071 | { |
2072 | AssertCodeMsg(GetLazyStringLiteralHelper != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , |
2073 | (DWORDLONG)handle); |
2074 | AssertCodeMsg(GetLazyStringLiteralHelper->GetIndex((DWORDLONG)handle) != -1, EXCEPTIONCODE_MC, |
2075 | "Didn't find %016llX" , (DWORDLONG)handle); |
2076 | CorInfoHelpFunc temp = (CorInfoHelpFunc)GetLazyStringLiteralHelper->Get((DWORDLONG)handle); |
2077 | DEBUG_REP(dmpGetLazyStringLiteralHelper((DWORDLONG)handle, temp)); |
2078 | return temp; |
2079 | } |
2080 | |
2081 | void MethodContext::recGetUnBoxHelper(CORINFO_CLASS_HANDLE cls, CorInfoHelpFunc result) |
2082 | { |
2083 | if (GetUnBoxHelper == nullptr) |
2084 | GetUnBoxHelper = new LightWeightMap<DWORDLONG, DWORD>(); |
2085 | |
2086 | GetUnBoxHelper->Add((DWORDLONG)cls, result); |
2087 | } |
2088 | void MethodContext::dmpGetUnBoxHelper(DWORDLONG key, DWORD value) |
2089 | { |
2090 | printf("GetUnBoxHelper key cls-%016llX, value res-%u" , key, value); |
2091 | } |
2092 | CorInfoHelpFunc MethodContext::repGetUnBoxHelper(CORINFO_CLASS_HANDLE cls) |
2093 | { |
2094 | CorInfoHelpFunc temp = (CorInfoHelpFunc)GetUnBoxHelper->Get((DWORDLONG)cls); |
2095 | return temp; |
2096 | } |
2097 | |
2098 | void MethodContext::recGetReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, |
2099 | CORINFO_LOOKUP_KIND* pGenericLookupKind, |
2100 | CorInfoHelpFunc id, |
2101 | CORINFO_CONST_LOOKUP* pLookup, |
2102 | bool result) |
2103 | { |
2104 | if (GetReadyToRunHelper == nullptr) |
2105 | GetReadyToRunHelper = new LightWeightMap<GetReadyToRunHelper_TOKENin, GetReadyToRunHelper_TOKENout>(); |
2106 | |
2107 | GetReadyToRunHelper_TOKENin key; |
2108 | ZeroMemory(&key, sizeof(key)); |
2109 | key.ResolvedToken = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, GetReadyToRunHelper); |
2110 | key.GenericLookupKind = SpmiRecordsHelper::CreateAgnostic_CORINFO_LOOKUP_KIND(pGenericLookupKind); |
2111 | key.id = (DWORD)id; |
2112 | GetReadyToRunHelper_TOKENout value; |
2113 | value.Lookup = SpmiRecordsHelper::StoreAgnostic_CORINFO_CONST_LOOKUP(pLookup); |
2114 | value.result = result; |
2115 | |
2116 | GetReadyToRunHelper->Add(key, value); |
2117 | DEBUG_REP(dmpGetReadyToRunHelper(key, value)); |
2118 | } |
2119 | |
2120 | void MethodContext::dmpGetReadyToRunHelper(GetReadyToRunHelper_TOKENin key, GetReadyToRunHelper_TOKENout value) |
2121 | { |
2122 | printf("GetReadyToRunHelper key: tk{%s} kind{%s} id-%u" , |
2123 | SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKEN(key.ResolvedToken).c_str(), |
2124 | SpmiDumpHelper::DumpAgnostic_CORINFO_LOOKUP_KIND(key.GenericLookupKind).c_str(), key.id); |
2125 | printf(", value: lk{ %s } %u" , SpmiDumpHelper::DumpAgnostic_CORINFO_CONST_LOOKUP(value.Lookup).c_str(), |
2126 | value.result); |
2127 | } |
2128 | |
2129 | bool MethodContext::repGetReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, |
2130 | CORINFO_LOOKUP_KIND* pGenericLookupKind, |
2131 | CorInfoHelpFunc id, |
2132 | CORINFO_CONST_LOOKUP* pLookup) |
2133 | { |
2134 | AssertCodeMsg(GetReadyToRunHelper != nullptr, EXCEPTIONCODE_MC, "No GetReadyToRunHelper records" ); |
2135 | |
2136 | GetReadyToRunHelper_TOKENin key; |
2137 | ZeroMemory(&key, sizeof(key)); |
2138 | key.ResolvedToken = SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, GetReadyToRunHelper); |
2139 | key.GenericLookupKind = SpmiRecordsHelper::CreateAgnostic_CORINFO_LOOKUP_KIND(pGenericLookupKind); |
2140 | key.id = (DWORD)id; |
2141 | |
2142 | AssertCodeMsg(GetReadyToRunHelper->GetIndex(key) != -1, EXCEPTIONCODE_MC, |
2143 | "Didn't find a key for GetReadyToRunHelper" ); |
2144 | |
2145 | GetReadyToRunHelper_TOKENout value = GetReadyToRunHelper->Get(key); |
2146 | *pLookup = SpmiRecordsHelper::RestoreCORINFO_CONST_LOOKUP(value.Lookup); |
2147 | return value.result; |
2148 | } |
2149 | |
2150 | void MethodContext::recGetReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod, |
2151 | CORINFO_CLASS_HANDLE delegateType, |
2152 | CORINFO_LOOKUP* pLookup) |
2153 | { |
2154 | if (GetReadyToRunDelegateCtorHelper == nullptr) |
2155 | GetReadyToRunDelegateCtorHelper = |
2156 | new LightWeightMap<GetReadyToRunDelegateCtorHelper_TOKENIn, Agnostic_CORINFO_LOOKUP>(); |
2157 | |
2158 | GetReadyToRunDelegateCtorHelper_TOKENIn key; |
2159 | ZeroMemory(&key, sizeof(key)); |
2160 | key.TargetMethod = |
2161 | SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(pTargetMethod, GetReadyToRunDelegateCtorHelper); |
2162 | key.delegateType = (DWORDLONG)delegateType; |
2163 | Agnostic_CORINFO_LOOKUP value = SpmiRecordsHelper::StoreAgnostic_CORINFO_LOOKUP(pLookup); |
2164 | GetReadyToRunDelegateCtorHelper->Add(key, value); |
2165 | DEBUG_REP(dmpGetReadyToRunDelegateCtorHelper(key, value)); |
2166 | } |
2167 | |
2168 | void MethodContext::dmpGetReadyToRunDelegateCtorHelper(GetReadyToRunDelegateCtorHelper_TOKENIn key, |
2169 | Agnostic_CORINFO_LOOKUP value) |
2170 | { |
2171 | printf("GetReadyToRunDelegateCtorHelper key: method tk{%s} type-%016llX" , |
2172 | SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKEN(key.TargetMethod).c_str(), key.delegateType); |
2173 | printf(", value: %s" , SpmiDumpHelper::DumpAgnostic_CORINFO_LOOKUP(value).c_str()); |
2174 | } |
2175 | |
2176 | void MethodContext::repGetReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod, |
2177 | CORINFO_CLASS_HANDLE delegateType, |
2178 | CORINFO_LOOKUP* pLookup) |
2179 | { |
2180 | AssertCodeMsg(GetReadyToRunDelegateCtorHelper != nullptr, EXCEPTIONCODE_MC, |
2181 | "No GetReadyToRunDelegateCtorHelper records" ); |
2182 | GetReadyToRunDelegateCtorHelper_TOKENIn key; |
2183 | ZeroMemory(&key, sizeof(key)); |
2184 | key.TargetMethod = |
2185 | SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKEN(pTargetMethod, GetReadyToRunDelegateCtorHelper); |
2186 | key.delegateType = (DWORDLONG)delegateType; |
2187 | |
2188 | AssertCodeMsg(GetReadyToRunDelegateCtorHelper->GetIndex(key) != -1, EXCEPTIONCODE_MC, |
2189 | "Didn't find a key for GetReadyToRunDelegateCtorHelper" ); |
2190 | Agnostic_CORINFO_LOOKUP value = GetReadyToRunDelegateCtorHelper->Get(key); |
2191 | *pLookup = SpmiRecordsHelper::RestoreCORINFO_LOOKUP(value); |
2192 | } |
2193 | |
2194 | void MethodContext::recGetHelperFtn(CorInfoHelpFunc ftnNum, void** ppIndirection, void* result) |
2195 | { |
2196 | if (GetHelperFtn == nullptr) |
2197 | GetHelperFtn = new LightWeightMap<DWORD, DLDL>(); |
2198 | |
2199 | DLDL value; |
2200 | value.A = (DWORDLONG)*ppIndirection; |
2201 | value.B = (DWORDLONG)result; |
2202 | |
2203 | if (GetHelperFtn->GetIndex((DWORD)ftnNum) != -1) |
2204 | { |
2205 | DLDL oldValue = GetHelperFtn->Get((DWORD)ftnNum); |
2206 | |
2207 | AssertCodeMsg(oldValue.A == value.A && oldValue.B == oldValue.B, EXCEPTIONCODE_MC, |
2208 | "collision! old: %016llX %016llX, new: %016llX %016llX \n" , oldValue.A, oldValue.B, value.A, |
2209 | value.B); |
2210 | } |
2211 | |
2212 | GetHelperFtn->Add((DWORD)ftnNum, value); |
2213 | DEBUG_REC(dmpGetHelperFtn((DWORD)ftnNum, value)); |
2214 | } |
2215 | void MethodContext::dmpGetHelperFtn(DWORD key, DLDL value) |
2216 | { |
2217 | printf("GetHelperFtn key ftn-%u, value ppi-%016llX res-%016llX" , key, value.A, value.B); |
2218 | } |
2219 | void* MethodContext::repGetHelperFtn(CorInfoHelpFunc ftnNum, void** ppIndirection) |
2220 | { |
2221 | if ((GetHelperFtn == nullptr) || (GetHelperFtn->GetIndex((DWORD)ftnNum) == -1)) |
2222 | { |
2223 | #ifdef sparseMC |
2224 | LogDebug("Sparse - repGetHelperFtn returning nullptr and 0XCAFE0003" ); |
2225 | *ppIndirection = nullptr; |
2226 | return (void*)(size_t)0xCAFE0003; |
2227 | #else |
2228 | LogException(EXCEPTIONCODE_MC, "Encountered an empty LWM while looking for %08X" , (DWORD)ftnNum); |
2229 | #endif |
2230 | } |
2231 | |
2232 | DLDL value = (DLDL)GetHelperFtn->Get((DWORD)ftnNum); |
2233 | *ppIndirection = (void*)value.A; |
2234 | DEBUG_REP(dmpGetHelperFtn((DWORD)ftnNum, value)); |
2235 | return (void*)value.B; |
2236 | } |
2237 | |
2238 | // |
2239 | // Finds the identifier (i.e. the CorInfoHelpFunc enum) of a helper function, based on the address where it |
2240 | // is located in memory. |
2241 | // |
2242 | // Arguments: |
2243 | // functionAddress - The starting address of the helper function in memory. |
2244 | // pResult - [out] Pointer to write out the identifier of the helper function located at the given |
2245 | // address. |
2246 | // |
2247 | // Return Value: |
2248 | // True if there is a helper function associated with the given target address; false otherwise. |
2249 | // |
2250 | // Assumptions: |
2251 | // Only the lower 32 bits of the method address are necessary to identify the method. |
2252 | // |
2253 | // Notes: |
2254 | // - See notes for fndGetFunctionEntryPoint for a more in-depth discussion of why we only match on the |
2255 | // lower 32 bits of the target address. |
2256 | // - This might not work correctly with method contexts recorded via NGen compilation. |
2257 | // |
2258 | bool MethodContext::fndGetHelperFtn(void* functionAddress, CorInfoHelpFunc* pResult) |
2259 | { |
2260 | if (GetHelperFtn != nullptr) |
2261 | { |
2262 | for (unsigned int i = 0; i < GetHelperFtn->GetCount(); i++) |
2263 | { |
2264 | DWORD key = GetHelperFtn->GetKey(i); |
2265 | DLDL val = GetHelperFtn->GetItem(i); |
2266 | |
2267 | // TODO-Cleanup: this only compares the function addresses, and doesn't account for |
2268 | // ppIndirection, which will break if the helper is a dynamic helper function. |
2269 | if (val.B == (DWORDLONG)functionAddress) |
2270 | { |
2271 | *pResult = (CorInfoHelpFunc)key; |
2272 | return true; |
2273 | } |
2274 | } |
2275 | } |
2276 | |
2277 | LogDebug("fndGetHelperFtn - didn't find value %p" , functionAddress); |
2278 | return false; |
2279 | } |
2280 | |
2281 | void MethodContext::recGetJustMyCodeHandle(CORINFO_METHOD_HANDLE method, |
2282 | CORINFO_JUST_MY_CODE_HANDLE** ppIndirection, |
2283 | CORINFO_JUST_MY_CODE_HANDLE result) |
2284 | { |
2285 | if (GetJustMyCodeHandle == nullptr) |
2286 | GetJustMyCodeHandle = new LightWeightMap<DWORDLONG, DLDL>(); |
2287 | DLDL temp; |
2288 | temp.A = (DWORDLONG)*ppIndirection; |
2289 | temp.B = (DWORDLONG)result; |
2290 | GetJustMyCodeHandle->Add((DWORDLONG)method, temp); |
2291 | DEBUG_REC(dmpGetJustMyCodeHandle((DWORDLONG)method, temp)); |
2292 | } |
2293 | void MethodContext::dmpGetJustMyCodeHandle(DWORDLONG key, DLDL value) |
2294 | { |
2295 | printf("GetJustMyCodeHandle key ftn-%016llX, value pp-%016llX, res-%016llX" , key, value.A, value.B); |
2296 | } |
2297 | CORINFO_JUST_MY_CODE_HANDLE MethodContext::repGetJustMyCodeHandle(CORINFO_METHOD_HANDLE method, |
2298 | CORINFO_JUST_MY_CODE_HANDLE** ppIndirection) |
2299 | { |
2300 | DLDL temp = (DLDL)GetJustMyCodeHandle->Get((DWORDLONG)method); |
2301 | *ppIndirection = (CORINFO_JUST_MY_CODE_HANDLE*)temp.A; |
2302 | CORINFO_JUST_MY_CODE_HANDLE result = (CORINFO_JUST_MY_CODE_HANDLE)temp.B; |
2303 | DEBUG_REP(dmpGetJustMyCodeHandle((DWORDLONG)method, temp)); |
2304 | return result; |
2305 | } |
2306 | |
2307 | void MethodContext::recGetFunctionEntryPoint(CORINFO_METHOD_HANDLE ftn, |
2308 | CORINFO_CONST_LOOKUP* pResult, |
2309 | CORINFO_ACCESS_FLAGS accessFlags) |
2310 | { |
2311 | if (GetFunctionEntryPoint == nullptr) |
2312 | GetFunctionEntryPoint = new LightWeightMap<DLD, DLD>(); |
2313 | |
2314 | DLD key; |
2315 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
2316 | // out padding too |
2317 | DLD value; |
2318 | key.A = (DWORDLONG)ftn; |
2319 | key.B = (DWORD)accessFlags; |
2320 | value.A = (DWORDLONG)pResult->addr; // First union member |
2321 | value.B = (DWORD)pResult->accessType; |
2322 | GetFunctionEntryPoint->Add(key, value); |
2323 | DEBUG_REC(dmpGetFunctionEntryPoint(key, value)); |
2324 | } |
2325 | void MethodContext::dmpGetFunctionEntryPoint(DLD key, DLD value) |
2326 | { |
2327 | printf("GetFunctionEntryPoint key ftn-%016llX af-%08X, value add-%016llX at-%u" , key.A, key.B, value.A, value.B); |
2328 | } |
2329 | void MethodContext::repGetFunctionEntryPoint(CORINFO_METHOD_HANDLE ftn, |
2330 | CORINFO_CONST_LOOKUP* pResult, |
2331 | CORINFO_ACCESS_FLAGS accessFlags) |
2332 | { |
2333 | DLD key; |
2334 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
2335 | // out padding too |
2336 | DLD value; |
2337 | key.A = (DWORDLONG)ftn; |
2338 | key.B = (DWORD)accessFlags; |
2339 | |
2340 | if (GetFunctionEntryPoint == nullptr) |
2341 | { |
2342 | #ifdef sparseMC |
2343 | LogDebug("Sparse - repGetFunctionEntryPoint fabricated result for request." ); |
2344 | pResult->accessType = (InfoAccessType)IAT_PVALUE; |
2345 | pResult->addr = (void*)((DWORDLONG)ftn + 0x1c); |
2346 | return; |
2347 | #else |
2348 | LogException(EXCEPTIONCODE_MC, "Didn't find %016llX, %8x" , (DWORDLONG)ftn, accessFlags); |
2349 | #endif |
2350 | } |
2351 | if (GetFunctionEntryPoint->GetIndex(key) == -1) |
2352 | { |
2353 | #ifdef sparseMC |
2354 | key.B ^= (DWORD)CORINFO_ACCESS_NONNULL; |
2355 | if (GetFunctionEntryPoint->GetIndex(key) != -1) |
2356 | { |
2357 | LogDebug("Sparse - repGetFunctionEntryPoint found result with inverted CORINFO_ACCESS_NONNULL" ); |
2358 | } |
2359 | else |
2360 | { |
2361 | LogDebug("Sparse - repGetFunctionEntryPoint fabricated result for request." ); |
2362 | pResult->accessType = (InfoAccessType)IAT_PVALUE; |
2363 | pResult->addr = (void*)((DWORDLONG)ftn + 0x1c); |
2364 | return; |
2365 | } |
2366 | #else |
2367 | LogException(EXCEPTIONCODE_MC, "Didn't find %016llX, %8x" , (DWORDLONG)ftn, accessFlags); |
2368 | #endif |
2369 | } |
2370 | value = GetFunctionEntryPoint->Get(key); |
2371 | |
2372 | pResult->accessType = (InfoAccessType)value.B; |
2373 | pResult->addr = (void*)value.A; |
2374 | DEBUG_REP(dmpGetFunctionEntryPoint(key, value)); |
2375 | } |
2376 | |
2377 | // |
2378 | // Finds the method handle associated with a method, based on the address where its generated code is located |
2379 | // in memory. |
2380 | // |
2381 | // Arguments: |
2382 | // methodAddress - The starting address of the generated code for the method. |
2383 | // pResult - [out] Pointer to a method handle to write into. If this successfully finds a method |
2384 | // handle associated with the given target address, it will be written to here. |
2385 | // |
2386 | // Return Value: |
2387 | // True if there is a helper function associated with the given target address; false otherwise. |
2388 | // |
2389 | // Assumptions: |
2390 | // - The given method address does not point to a jump stub. |
2391 | // - The given method is not a generic method. |
2392 | // - Only the lower 32 bits of the method address are necessary to identify the method. |
2393 | // |
2394 | // Notes: |
2395 | // On 64-bit platforms, this only checks if the lower 32 bits of the method address match a recorded |
2396 | // function entry point because, on AMD64, this only supports reverse lookups for near calls, which |
2397 | // encode their target address as a 32-bit PC-relative displacement. |
2398 | // |
2399 | // Practically speaking, there are two concrete reasons why we ignore the upper 64 bits. First, on |
2400 | // AMD64, when the JIT emits a near call, it records the displacement it encodes into the call with |
2401 | // the EE as a 32-bit relative "relocation". Consequently, this leads to the second reason why we |
2402 | // ignore the upper 64 bits: when SuperPMI is replaying method compilation, it patches up addresses |
2403 | // based on the "relocations" the JIT had previously recorded with the EE. Since these relocations |
2404 | // are only 32-bit deltas, what you'll usually end up seeing is that, after SuperPMI has applied |
2405 | // these fixups, the lower 32 bits of method addresses will match, but the upper 32 bits will differ. |
2406 | // |
2407 | bool MethodContext::fndGetFunctionEntryPoint(DLD value, CORINFO_METHOD_HANDLE* pResult) |
2408 | { |
2409 | if (GetFunctionEntryPoint != nullptr) |
2410 | { |
2411 | for (unsigned int i = 0; i < GetFunctionEntryPoint->GetCount(); i++) |
2412 | { |
2413 | DLD key = GetFunctionEntryPoint->GetKey(i); |
2414 | DLD val = GetFunctionEntryPoint->GetItem(i); |
2415 | |
2416 | // TODO-Cleanup: we should be more conscious of the rest of the information in CORINFO_CONST_LOOKUP |
2417 | if ((DWORD)val.A == (DWORD)value.A) |
2418 | { |
2419 | *pResult = (CORINFO_METHOD_HANDLE)key.A; |
2420 | return true; |
2421 | } |
2422 | } |
2423 | } |
2424 | |
2425 | LogDebug("fndGetFunctionEntryPoint - didn't find value %016llX" , value.A); |
2426 | return false; |
2427 | } |
2428 | |
2429 | void MethodContext::recConstructStringLiteral(CORINFO_MODULE_HANDLE module, |
2430 | mdToken metaTok, |
2431 | void* pValue, |
2432 | InfoAccessType result) |
2433 | { |
2434 | if (ConstructStringLiteral == nullptr) |
2435 | ConstructStringLiteral = new LightWeightMap<DLD, DLD>(); |
2436 | DLD temp; |
2437 | ZeroMemory(&temp, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
2438 | // out padding too |
2439 | DLD temp2; |
2440 | temp.A = (DWORDLONG)module; |
2441 | temp.B = (DWORD)metaTok; |
2442 | temp2.A = (DWORDLONG)pValue; |
2443 | temp2.B = (DWORD)result; |
2444 | |
2445 | ConstructStringLiteral->Add(temp, temp2); |
2446 | DEBUG_REC(dmpConstructStringLiteral(temp, temp2)); |
2447 | } |
2448 | void MethodContext::dmpConstructStringLiteral(DLD key, DLD value) |
2449 | { |
2450 | printf("ConstructStringLiteral key mod-%016llX tok-%08X, value pp-%016llX iat-%u" , key.A, key.B, value.A, value.B); |
2451 | } |
2452 | InfoAccessType MethodContext::repConstructStringLiteral(CORINFO_MODULE_HANDLE module, mdToken metaTok, void** ppValue) |
2453 | { |
2454 | DLD temp; |
2455 | ZeroMemory(&temp, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
2456 | // out padding too |
2457 | DLD temp2; |
2458 | temp.A = (DWORDLONG)module; |
2459 | temp.B = (DWORD)metaTok; |
2460 | AssertCodeMsg(ConstructStringLiteral != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , |
2461 | (DWORDLONG)module); |
2462 | AssertCodeMsg(ConstructStringLiteral->GetIndex(temp) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
2463 | (DWORDLONG)module); |
2464 | temp2 = ConstructStringLiteral->Get(temp); |
2465 | *ppValue = (void*)temp2.A; |
2466 | DEBUG_REP(dmpConstructStringLiteral(temp, temp2)); |
2467 | return (InfoAccessType)temp2.B; |
2468 | } |
2469 | |
2470 | void MethodContext::recConvertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fMustConvert, bool result) |
2471 | { |
2472 | if (ConvertPInvokeCalliToCall == nullptr) |
2473 | ConvertPInvokeCalliToCall = new LightWeightMap<DLD, DWORDLONG>(); |
2474 | |
2475 | DLD key; |
2476 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
2477 | // out padding too |
2478 | key.A = (DWORDLONG)pResolvedToken->tokenScope; |
2479 | key.B = (DWORD)pResolvedToken->token; |
2480 | |
2481 | DWORDLONG value = (DWORDLONG)(result ? pResolvedToken->hMethod : 0); |
2482 | |
2483 | ConvertPInvokeCalliToCall->Add(key, value); |
2484 | DEBUG_REC(dmpConvertPInvokeCalliToCall(key, value)); |
2485 | } |
2486 | void MethodContext::dmpConvertPInvokeCalliToCall(DLD key, DWORDLONG value) |
2487 | { |
2488 | printf("ConvertPInvokeCalliToCall key mod-%016llX tok-%08X, value %016llX" , key.A, key.B, value); |
2489 | } |
2490 | bool MethodContext::repConvertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fMustConvert) |
2491 | { |
2492 | DLD key; |
2493 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
2494 | // out padding too |
2495 | key.A = (DWORDLONG)pResolvedToken->tokenScope; |
2496 | key.B = (DWORD)pResolvedToken->token; |
2497 | |
2498 | DWORDLONG value = ConvertPInvokeCalliToCall->Get(key); |
2499 | DEBUG_REP(dmpGetArgType(key, value)); |
2500 | |
2501 | pResolvedToken->hMethod = (CORINFO_METHOD_HANDLE)value; |
2502 | return value != 0; |
2503 | } |
2504 | |
2505 | void MethodContext::recEmptyStringLiteral(void** pValue, InfoAccessType result) |
2506 | { |
2507 | if (EmptyStringLiteral == nullptr) |
2508 | EmptyStringLiteral = new DenseLightWeightMap<DLD>(); |
2509 | DLD temp2; |
2510 | temp2.A = (DWORDLONG)*pValue; |
2511 | temp2.B = (DWORD)result; |
2512 | |
2513 | EmptyStringLiteral->Append(temp2); |
2514 | } |
2515 | void MethodContext::dmpEmptyStringLiteral(DWORD key, DLD value) |
2516 | { |
2517 | printf("EmptyStringLiteral key %u, value pVal-%016llX res-%u" , key, value.A, value.B); |
2518 | } |
2519 | InfoAccessType MethodContext::repEmptyStringLiteral(void** ppValue) |
2520 | { |
2521 | // TODO-Cleanup: sketchy if someone calls this twice |
2522 | DLD temp2; |
2523 | temp2 = EmptyStringLiteral->Get((DWORD)0); |
2524 | *ppValue = (void*)temp2.A; |
2525 | return (InfoAccessType)temp2.B; |
2526 | } |
2527 | |
2528 | void MethodContext::recGetArgType(CORINFO_SIG_INFO* sig, |
2529 | CORINFO_ARG_LIST_HANDLE args, |
2530 | CORINFO_CLASS_HANDLE* vcTypeRet, |
2531 | CorInfoTypeWithMod result, |
2532 | DWORD exceptionCode) |
2533 | { |
2534 | if (GetArgType == nullptr) |
2535 | GetArgType = new LightWeightMap<GetArgTypeValue, Agnostic_GetArgType_Value>(); |
2536 | |
2537 | GetArgTypeValue key; |
2538 | ZeroMemory(&key, sizeof(GetArgType)); // We use the input structs as a key and use memcmp to compare.. so |
2539 | // we need to zero out padding too |
2540 | // Only setting values for things the EE seems to pay attention to... this is necessary since some of the values |
2541 | // are unset and fail our precise comparisons ... |
2542 | key.flags = (DWORD)sig->flags; |
2543 | key.numArgs = (DWORD)sig->numArgs; |
2544 | key.sigInst_classInstCount = (DWORD)sig->sigInst.classInstCount; |
2545 | key.sigInst_classInst_Index = |
2546 | (DWORD)GetArgType->AddBuffer((unsigned char*)sig->sigInst.classInst, sig->sigInst.classInstCount * 8); |
2547 | key.sigInst_methInstCount = (DWORD)sig->sigInst.methInstCount; |
2548 | key.sigInst_methInst_Index = |
2549 | (DWORD)GetArgType->AddBuffer((unsigned char*)sig->sigInst.methInst, sig->sigInst.methInstCount * 8); |
2550 | key.scope = (DWORDLONG)sig->scope; |
2551 | key.args = (DWORDLONG)args; |
2552 | |
2553 | Agnostic_GetArgType_Value value; |
2554 | value.vcTypeRet = (DWORDLONG)*vcTypeRet; |
2555 | value.result = (DWORD)result; |
2556 | value.exceptionCode = (DWORD)exceptionCode; |
2557 | |
2558 | GetArgType->Add(key, value); |
2559 | DEBUG_REC(dmpGetArgType(key, value)); |
2560 | } |
2561 | void MethodContext::dmpGetArgType(const GetArgTypeValue& key, const Agnostic_GetArgType_Value& value) |
2562 | { |
2563 | printf("GetArgType key flg-%08X na-%u cc-%u ci-%u mc-%u mi-%u scp-%016llX arg-%016llX" , key.flags, key.numArgs, |
2564 | key.sigInst_classInstCount, key.sigInst_classInst_Index, key.sigInst_methInstCount, |
2565 | key.sigInst_methInst_Index, key.scope, key.args); |
2566 | printf(", value rt-%016llX ci-%u excp-%08X" , value.vcTypeRet, value.result, value.exceptionCode); |
2567 | } |
2568 | CorInfoTypeWithMod MethodContext::repGetArgType(CORINFO_SIG_INFO* sig, |
2569 | CORINFO_ARG_LIST_HANDLE args, |
2570 | CORINFO_CLASS_HANDLE* vcTypeRet, |
2571 | DWORD* exceptionCode) |
2572 | { |
2573 | GetArgTypeValue key; |
2574 | ZeroMemory(&key, sizeof(GetArgTypeValue)); // We use the input structs as a key and use memcmp to compare.. so |
2575 | // we need to zero out padding too |
2576 | |
2577 | AssertCodeMsg(GetArgType != nullptr, EXCEPTIONCODE_MC, |
2578 | "Didn't find %016llx, %016llx. probably a missing exception in getArgType" , key.scope, key.args); |
2579 | key.flags = (DWORD)sig->flags; |
2580 | key.numArgs = (DWORD)sig->numArgs; |
2581 | key.sigInst_classInstCount = (DWORD)sig->sigInst.classInstCount; |
2582 | key.sigInst_classInst_Index = |
2583 | (DWORD)GetArgType->Contains((unsigned char*)sig->sigInst.classInst, sig->sigInst.classInstCount * 8); |
2584 | key.sigInst_methInstCount = (DWORD)sig->sigInst.methInstCount; |
2585 | key.sigInst_methInst_Index = |
2586 | (DWORD)GetArgType->Contains((unsigned char*)sig->sigInst.methInst, sig->sigInst.methInstCount * 8); |
2587 | key.scope = (DWORDLONG)sig->scope; |
2588 | key.args = (DWORDLONG)args; |
2589 | |
2590 | AssertCodeMsg(GetArgType->GetIndex(key) != -1, EXCEPTIONCODE_MC, |
2591 | "Didn't find %016llx, %016llx. probably a missing exception in getArgType" , key.scope, key.args); |
2592 | |
2593 | Agnostic_GetArgType_Value value = GetArgType->Get(key); |
2594 | *vcTypeRet = (CORINFO_CLASS_HANDLE)value.vcTypeRet; |
2595 | CorInfoTypeWithMod temp = (CorInfoTypeWithMod)value.result; |
2596 | *exceptionCode = (DWORD)value.exceptionCode; |
2597 | |
2598 | DEBUG_REP(dmpGetArgType(key, value)); |
2599 | return temp; |
2600 | } |
2601 | |
2602 | void MethodContext::recGetArgNext(CORINFO_ARG_LIST_HANDLE args, CORINFO_ARG_LIST_HANDLE result) |
2603 | { |
2604 | if (GetArgNext == nullptr) |
2605 | GetArgNext = new LightWeightMap<DWORDLONG, DWORDLONG>(); |
2606 | |
2607 | GetArgNext->Add((DWORDLONG)args, (DWORDLONG)result); |
2608 | DEBUG_REC(dmpGetArgNext((DWORDLONG)args, (DWORDLONG)result)); |
2609 | } |
2610 | void MethodContext::dmpGetArgNext(DWORDLONG key, DWORDLONG value) |
2611 | { |
2612 | printf("GetArgNext key %016llX, value %016llX" , key, value); |
2613 | } |
2614 | CORINFO_ARG_LIST_HANDLE MethodContext::repGetArgNext(CORINFO_ARG_LIST_HANDLE args) |
2615 | { |
2616 | CORINFO_ARG_LIST_HANDLE temp = (CORINFO_ARG_LIST_HANDLE)GetArgNext->Get((DWORDLONG)args); |
2617 | DEBUG_REP(dmpGetArgNext((DWORDLONG)args, (DWORDLONG)temp)); |
2618 | return temp; |
2619 | } |
2620 | void MethodContext::recGetMethodSig(CORINFO_METHOD_HANDLE ftn, CORINFO_SIG_INFO* sig, CORINFO_CLASS_HANDLE memberParent) |
2621 | { |
2622 | if (GetMethodSig == nullptr) |
2623 | GetMethodSig = new LightWeightMap<DLDL, Agnostic_CORINFO_SIG_INFO>(); |
2624 | |
2625 | DLDL key; |
2626 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
2627 | // out padding too |
2628 | key.A = (DWORDLONG)ftn; |
2629 | key.B = (DWORDLONG)memberParent; |
2630 | |
2631 | Agnostic_CORINFO_SIG_INFO value = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(*sig, GetMethodSig); |
2632 | |
2633 | GetMethodSig->Add(key, value); |
2634 | DEBUG_REC(dmpGetMethodSig(key, value)); |
2635 | } |
2636 | void MethodContext::dmpGetMethodSig(DLDL key, const Agnostic_CORINFO_SIG_INFO& value) |
2637 | { |
2638 | printf("GetMethodSig key ftn-%016llX prt-%016llX, value %s" , key.A, key.B, |
2639 | SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(value).c_str()); |
2640 | } |
2641 | void MethodContext::repGetMethodSig(CORINFO_METHOD_HANDLE ftn, CORINFO_SIG_INFO* sig, CORINFO_CLASS_HANDLE memberParent) |
2642 | { |
2643 | DLDL key; |
2644 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
2645 | // out padding too |
2646 | Agnostic_CORINFO_SIG_INFO value; |
2647 | |
2648 | key.A = (DWORDLONG)ftn; |
2649 | key.B = (DWORDLONG)memberParent; |
2650 | |
2651 | value = GetMethodSig->Get(key); |
2652 | |
2653 | *sig = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value, GetMethodSig); |
2654 | |
2655 | DEBUG_REP(dmpGetMethodSig(key, value)); |
2656 | } |
2657 | |
2658 | void MethodContext::recGetArgClass(CORINFO_SIG_INFO* sig, |
2659 | CORINFO_ARG_LIST_HANDLE args, |
2660 | CORINFO_CLASS_HANDLE result, |
2661 | DWORD exceptionCode) |
2662 | { |
2663 | if (GetArgClass == nullptr) |
2664 | GetArgClass = new LightWeightMap<GetArgClassValue, Agnostic_GetArgClass_Value>(); |
2665 | |
2666 | GetArgClassValue key; |
2667 | ZeroMemory(&key, sizeof(GetArgClassValue)); // We use the input structs as a key and use memcmp to compare.. so |
2668 | // we need to zero out padding too |
2669 | // Only setting values for things the EE seems to pay attention to... this is necessary since some of the values |
2670 | // are unset and fail our precise comparisions... |
2671 | key.sigInst_classInstCount = (DWORD)sig->sigInst.classInstCount; |
2672 | key.sigInst_classInst_Index = |
2673 | (DWORD)GetArgClass->AddBuffer((unsigned char*)sig->sigInst.classInst, sig->sigInst.classInstCount * 8); |
2674 | key.sigInst_methInstCount = (DWORD)sig->sigInst.methInstCount; |
2675 | key.sigInst_methInst_Index = |
2676 | (DWORD)GetArgClass->AddBuffer((unsigned char*)sig->sigInst.methInst, sig->sigInst.methInstCount * 8); |
2677 | key.scope = (DWORDLONG)sig->scope; |
2678 | key.args = (DWORDLONG)args; |
2679 | |
2680 | Agnostic_GetArgClass_Value value; |
2681 | value.result = (DWORDLONG)result; |
2682 | value.exceptionCode = exceptionCode; |
2683 | |
2684 | GetArgClass->Add(key, value); |
2685 | DEBUG_REC(dmpGetArgClass(key, value)); |
2686 | } |
2687 | void MethodContext::dmpGetArgClass(const GetArgClassValue& key, const Agnostic_GetArgClass_Value& value) |
2688 | { |
2689 | printf("GetArgClass key cc-%u ci-%u mc-%u mi-%u scp-%016llX args-%016llX" , key.sigInst_classInstCount, |
2690 | key.sigInst_classInst_Index, key.sigInst_methInstCount, key.sigInst_methInst_Index, key.scope, key.args); |
2691 | printf(", value %016llX excp-%08X" , value.result, value.exceptionCode); |
2692 | } |
2693 | CORINFO_CLASS_HANDLE MethodContext::repGetArgClass(CORINFO_SIG_INFO* sig, |
2694 | CORINFO_ARG_LIST_HANDLE args, |
2695 | DWORD* exceptionCode) |
2696 | { |
2697 | GetArgClassValue key; |
2698 | ZeroMemory(&key, sizeof(GetArgClassValue)); // We use the input structs as a key and use memcmp to compare.. so |
2699 | // we need to zero out padding too |
2700 | |
2701 | AssertCodeMsg(GetArgClass != nullptr, EXCEPTIONCODE_MC, |
2702 | "Didn't find %016llx, %016llx. probably a missing exception in getArgClass" , key.scope, key.args); |
2703 | key.sigInst_classInstCount = (DWORD)sig->sigInst.classInstCount; |
2704 | key.sigInst_classInst_Index = |
2705 | (DWORD)GetArgClass->Contains((unsigned char*)sig->sigInst.classInst, sig->sigInst.classInstCount * 8); |
2706 | key.sigInst_methInstCount = (DWORD)sig->sigInst.methInstCount; |
2707 | key.sigInst_methInst_Index = |
2708 | (DWORD)GetArgClass->Contains((unsigned char*)sig->sigInst.methInst, sig->sigInst.methInstCount * 8); |
2709 | key.scope = (DWORDLONG)sig->scope; |
2710 | key.args = (DWORDLONG)args; |
2711 | |
2712 | AssertCodeMsg(GetArgClass->GetIndex(key) != -1, EXCEPTIONCODE_MC, |
2713 | "Didn't find %016llx, %016llx. probably a missing exception in getArgClass" , key.scope, key.args); |
2714 | |
2715 | Agnostic_GetArgClass_Value value = GetArgClass->Get(key); |
2716 | *exceptionCode = value.exceptionCode; |
2717 | DEBUG_REP(dmpGetArgClass(key, value)); |
2718 | |
2719 | return (CORINFO_CLASS_HANDLE)value.result; |
2720 | } |
2721 | |
2722 | void MethodContext::recGetHFAType(CORINFO_CLASS_HANDLE clsHnd, CorInfoType result) |
2723 | { |
2724 | if (GetHFAType == nullptr) |
2725 | GetHFAType = new LightWeightMap<DWORDLONG, DWORD>(); |
2726 | |
2727 | GetHFAType->Add((DWORDLONG)clsHnd, (DWORD)result); |
2728 | DEBUG_REC(dmpGetHFAType((DWORDLONG)clsHnd, (DWORD)result)); |
2729 | return; |
2730 | } |
2731 | |
2732 | void MethodContext::dmpGetHFAType(DWORDLONG key, DWORD value) |
2733 | { |
2734 | printf("GetHFAType key %016llX, value %u " , key, value); |
2735 | return; |
2736 | } |
2737 | |
2738 | CorInfoType MethodContext::repGetHFAType(CORINFO_CLASS_HANDLE clsHnd) |
2739 | { |
2740 | DWORD value; |
2741 | |
2742 | AssertCodeMsg(GetHFAType != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , (DWORDLONG)clsHnd); |
2743 | AssertCodeMsg(GetHFAType->GetIndex((DWORDLONG)clsHnd) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
2744 | (DWORDLONG)clsHnd); |
2745 | |
2746 | value = GetHFAType->Get((DWORDLONG)clsHnd); |
2747 | DEBUG_REP(dmpGetHFAType((DWORDLONG)clsHnd, value)); |
2748 | return (CorInfoType)value; |
2749 | } |
2750 | |
2751 | void MethodContext::recGetMethodInfo(CORINFO_METHOD_HANDLE ftn, |
2752 | CORINFO_METHOD_INFO* info, |
2753 | bool result, |
2754 | DWORD exceptionCode) |
2755 | { |
2756 | if (GetMethodInfo == nullptr) |
2757 | GetMethodInfo = new LightWeightMap<DWORDLONG, Agnostic_GetMethodInfo>(); |
2758 | |
2759 | Agnostic_GetMethodInfo value; |
2760 | ZeroMemory(&value, sizeof(Agnostic_GetMethodInfo)); |
2761 | |
2762 | if (result) |
2763 | { |
2764 | value.info.ftn = (DWORDLONG)info->ftn; |
2765 | value.info.scope = (DWORDLONG)info->scope; |
2766 | value.info.ILCode_offset = (DWORD)GetMethodInfo->AddBuffer(info->ILCode, info->ILCodeSize); |
2767 | value.info.ILCodeSize = (DWORD)info->ILCodeSize; |
2768 | value.info.maxStack = (DWORD)info->maxStack; |
2769 | value.info.EHcount = (DWORD)info->EHcount; |
2770 | value.info.options = (DWORD)info->options; |
2771 | value.info.regionKind = (DWORD)info->regionKind; |
2772 | value.info.args.callConv = (DWORD)info->args.callConv; |
2773 | value.info.args.retTypeClass = (DWORDLONG)info->args.retTypeClass; |
2774 | value.info.args.retTypeSigClass = (DWORDLONG)info->args.retTypeSigClass; |
2775 | value.info.args.retType = (DWORD)info->args.retType; |
2776 | value.info.args.flags = (DWORD)info->args.flags; |
2777 | value.info.args.numArgs = (DWORD)info->args.numArgs; |
2778 | value.info.args.sigInst_classInstCount = (DWORD)info->args.sigInst.classInstCount; |
2779 | value.info.args.sigInst_classInst_Index = |
2780 | (DWORD)GetMethodInfo->AddBuffer((unsigned char*)info->args.sigInst.classInst, |
2781 | info->args.sigInst.classInstCount * 8); // porting issue |
2782 | value.info.args.sigInst_methInstCount = (DWORD)info->args.sigInst.methInstCount; |
2783 | value.info.args.sigInst_methInst_Index = |
2784 | (DWORD)GetMethodInfo->AddBuffer((unsigned char*)info->args.sigInst.methInst, |
2785 | info->args.sigInst.methInstCount * 8); // porting issue |
2786 | value.info.args.args = (DWORDLONG)info->args.args; |
2787 | value.info.args.cbSig = (DWORD)info->args.cbSig; |
2788 | value.info.args.pSig_Index = (DWORD)GetMethodInfo->AddBuffer((unsigned char*)info->args.pSig, info->args.cbSig); |
2789 | value.info.args.scope = (DWORDLONG)info->args.scope; |
2790 | value.info.args.token = (DWORD)info->args.token; |
2791 | value.info.locals.callConv = (DWORD)info->locals.callConv; |
2792 | value.info.locals.retTypeClass = (DWORDLONG)info->locals.retTypeClass; |
2793 | value.info.locals.retTypeSigClass = (DWORDLONG)info->locals.retTypeSigClass; |
2794 | value.info.locals.retType = (DWORD)info->locals.retType; |
2795 | value.info.locals.flags = (DWORD)info->locals.flags; |
2796 | value.info.locals.numArgs = (DWORD)info->locals.numArgs; |
2797 | value.info.locals.sigInst_classInstCount = (DWORD)info->locals.sigInst.classInstCount; |
2798 | value.info.locals.sigInst_classInst_Index = |
2799 | (DWORD)GetMethodInfo->AddBuffer((unsigned char*)info->locals.sigInst.classInst, |
2800 | info->locals.sigInst.classInstCount * 8); // porting issue |
2801 | value.info.locals.sigInst_methInstCount = (DWORD)info->locals.sigInst.methInstCount; |
2802 | value.info.locals.sigInst_methInst_Index = |
2803 | (DWORD)GetMethodInfo->AddBuffer((unsigned char*)info->locals.sigInst.methInst, |
2804 | info->locals.sigInst.methInstCount * 8); // porting issue |
2805 | value.info.locals.args = (DWORDLONG)info->locals.args; |
2806 | value.info.locals.cbSig = (DWORD)info->locals.cbSig; |
2807 | value.info.locals.pSig_Index = |
2808 | (DWORD)GetMethodInfo->AddBuffer((unsigned char*)info->locals.pSig, info->locals.cbSig); |
2809 | value.info.locals.scope = (DWORDLONG)info->locals.scope; |
2810 | value.info.locals.token = (DWORD)info->locals.token; |
2811 | } |
2812 | value.result = result; |
2813 | value.exceptionCode = (DWORD)exceptionCode; |
2814 | |
2815 | GetMethodInfo->Add((DWORDLONG)ftn, value); |
2816 | DEBUG_REC(dmpGetMethodInfo((DWORDLONG)ftn, value)); |
2817 | } |
2818 | void MethodContext::dmpGetMethodInfo(DWORDLONG key, const Agnostic_GetMethodInfo& value) |
2819 | { |
2820 | printf("GetMethodInfo key ftn-%016llX" , key); |
2821 | printf(", value res-%u ftn-%016llX scp-%016llX ilo-%u ils-%u ms-%u ehc-%u opt-%08X rk-%u " |
2822 | "args{cc-%u rc-%016llX rts-%016llX rt-%u(%s) flg-%08X nA-%u cc-%u ci-%u mc-%u mi-%u arg-%016llX cb-%u " |
2823 | "pSig_Index-%u scp-%016llX tok-%08X} " |
2824 | "locals{cc-%u rc-%016llX rts-%016llX rt-%u(%s) flg-%08X nA-%u cc-%u ci-%u mc-%u mi-%u arg-%016llX cb-%u " |
2825 | "pSig_Index-%u scp-%016llX tok-%08X} " |
2826 | "excp-%08X" , |
2827 | value.result, value.info.ftn, value.info.scope, value.info.ILCode_offset, value.info.ILCodeSize, |
2828 | value.info.maxStack, value.info.EHcount, value.info.options, value.info.regionKind, value.info.args.callConv, |
2829 | value.info.args.retTypeClass, value.info.args.retTypeSigClass, value.info.args.retType, |
2830 | toString((CorInfoType)value.info.args.retType), value.info.args.flags, value.info.args.numArgs, |
2831 | value.info.args.sigInst_classInstCount, value.info.args.sigInst_classInst_Index, |
2832 | value.info.args.sigInst_methInstCount, value.info.args.sigInst_methInst_Index, value.info.args.args, |
2833 | value.info.args.cbSig, value.info.args.pSig_Index, value.info.args.scope, value.info.args.token, |
2834 | value.info.locals.callConv, value.info.locals.retTypeClass, value.info.locals.retTypeSigClass, |
2835 | value.info.locals.retType, toString((CorInfoType)value.info.locals.retType), value.info.locals.flags, |
2836 | value.info.locals.numArgs, value.info.locals.sigInst_classInstCount, |
2837 | value.info.locals.sigInst_classInst_Index, value.info.locals.sigInst_methInstCount, |
2838 | value.info.locals.sigInst_methInst_Index, value.info.locals.args, value.info.locals.cbSig, |
2839 | value.info.locals.pSig_Index, value.info.locals.scope, value.info.locals.token, value.exceptionCode); |
2840 | } |
2841 | bool MethodContext::repGetMethodInfo(CORINFO_METHOD_HANDLE ftn, CORINFO_METHOD_INFO* info, DWORD* exceptionCode) |
2842 | { |
2843 | Agnostic_GetMethodInfo value; |
2844 | AssertCodeMsg(GetMethodInfo != nullptr, EXCEPTIONCODE_MC, |
2845 | "Didn't find %016llx. probably a missing exception in getMethodInfo" , (DWORDLONG)ftn); |
2846 | AssertCodeMsg(GetMethodInfo->GetIndex((DWORDLONG)ftn) != -1, EXCEPTIONCODE_MC, |
2847 | "Didn't find %016llx. probably a missing exception in getMethodInfo" , (DWORDLONG)ftn); |
2848 | |
2849 | value = GetMethodInfo->Get((DWORDLONG)ftn); |
2850 | if (value.result) |
2851 | { |
2852 | info->ftn = (CORINFO_METHOD_HANDLE)value.info.ftn; |
2853 | info->scope = (CORINFO_MODULE_HANDLE)value.info.scope; |
2854 | info->ILCode = GetMethodInfo->GetBuffer(value.info.ILCode_offset); |
2855 | info->ILCodeSize = (unsigned)value.info.ILCodeSize; |
2856 | info->maxStack = (unsigned)value.info.maxStack; |
2857 | info->EHcount = (unsigned)value.info.EHcount; |
2858 | info->options = (CorInfoOptions)value.info.options; |
2859 | info->regionKind = (CorInfoRegionKind)value.info.regionKind; |
2860 | info->args.callConv = (CorInfoCallConv)value.info.args.callConv; |
2861 | info->args.retTypeClass = (CORINFO_CLASS_HANDLE)value.info.args.retTypeClass; |
2862 | info->args.retTypeSigClass = (CORINFO_CLASS_HANDLE)value.info.args.retTypeSigClass; |
2863 | info->args.retType = (CorInfoType)value.info.args.retType; |
2864 | info->args.flags = (unsigned)value.info.args.flags; |
2865 | info->args.numArgs = (unsigned)value.info.args.numArgs; |
2866 | info->args.sigInst.classInstCount = (unsigned)value.info.args.sigInst_classInstCount; |
2867 | info->args.sigInst.classInst = |
2868 | (CORINFO_CLASS_HANDLE*)GetMethodInfo->GetBuffer(value.info.args.sigInst_classInst_Index); |
2869 | info->args.sigInst.methInstCount = (unsigned)value.info.args.sigInst_methInstCount; |
2870 | info->args.sigInst.methInst = |
2871 | (CORINFO_CLASS_HANDLE*)GetMethodInfo->GetBuffer(value.info.args.sigInst_methInst_Index); |
2872 | info->args.args = (CORINFO_ARG_LIST_HANDLE)value.info.args.args; |
2873 | info->args.cbSig = (unsigned int)value.info.args.cbSig; |
2874 | info->args.pSig = (PCCOR_SIGNATURE)GetMethodInfo->GetBuffer(value.info.args.pSig_Index); |
2875 | info->args.scope = (CORINFO_MODULE_HANDLE)value.info.args.scope; |
2876 | info->args.token = (mdToken)value.info.args.token; |
2877 | info->locals.callConv = (CorInfoCallConv)value.info.locals.callConv; |
2878 | info->locals.retTypeClass = (CORINFO_CLASS_HANDLE)value.info.locals.retTypeClass; |
2879 | info->locals.retTypeSigClass = (CORINFO_CLASS_HANDLE)value.info.locals.retTypeSigClass; |
2880 | info->locals.retType = (CorInfoType)value.info.locals.retType; |
2881 | info->locals.flags = (unsigned)value.info.locals.flags; |
2882 | info->locals.numArgs = (unsigned)value.info.locals.numArgs; |
2883 | info->locals.sigInst.classInstCount = (unsigned)value.info.locals.sigInst_classInstCount; |
2884 | info->locals.sigInst.classInst = |
2885 | (CORINFO_CLASS_HANDLE*)GetMethodInfo->GetBuffer(value.info.locals.sigInst_classInst_Index); |
2886 | info->locals.sigInst.methInstCount = (unsigned)value.info.locals.sigInst_methInstCount; |
2887 | info->locals.sigInst.methInst = |
2888 | (CORINFO_CLASS_HANDLE*)GetMethodInfo->GetBuffer(value.info.locals.sigInst_methInst_Index); |
2889 | info->locals.args = (CORINFO_ARG_LIST_HANDLE)value.info.locals.args; |
2890 | info->locals.cbSig = (unsigned int)value.info.locals.cbSig; |
2891 | info->locals.pSig = (PCCOR_SIGNATURE)GetMethodInfo->GetBuffer(value.info.locals.pSig_Index); |
2892 | info->locals.scope = (CORINFO_MODULE_HANDLE)value.info.locals.scope; |
2893 | info->locals.token = (mdToken)value.info.locals.token; |
2894 | } |
2895 | bool result = value.result; |
2896 | *exceptionCode = (DWORD)value.exceptionCode; |
2897 | DEBUG_REP(dmpGetMethodInfo((DWORDLONG)ftn, value)); |
2898 | return result; |
2899 | } |
2900 | |
2901 | void MethodContext::recGetNewHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, |
2902 | CORINFO_METHOD_HANDLE callerHandle, |
2903 | bool* pHasSideEffects, |
2904 | CorInfoHelpFunc result) |
2905 | { |
2906 | if (GetNewHelper == nullptr) |
2907 | GetNewHelper = new LightWeightMap<Agnostic_GetNewHelper, DD>(); |
2908 | |
2909 | Agnostic_GetNewHelper key; |
2910 | ZeroMemory(&key, sizeof(Agnostic_GetNewHelper)); // We use the input structs as a key and use memcmp to compare.. so |
2911 | // we need to zero out padding too |
2912 | key.hClass = (DWORDLONG)pResolvedToken->hClass; |
2913 | key.callerHandle = (DWORDLONG)callerHandle; |
2914 | |
2915 | DD value; |
2916 | value.A = (pHasSideEffects != nullptr) ? (DWORD)(*pHasSideEffects ? 1 : 0) : (DWORD)0; |
2917 | value.B = (DWORD)result; |
2918 | |
2919 | GetNewHelper->Add(key, value); |
2920 | DEBUG_REC(dmpGetNewHelper(key, value)); |
2921 | } |
2922 | void MethodContext::dmpGetNewHelper(const Agnostic_GetNewHelper& key, DD value) |
2923 | { |
2924 | printf("GetNewHelper key cls-%016llX chan-%016llX, hasSideEffects-%u, value res-%u" , key.hClass, key.callerHandle, value.A, value.B); |
2925 | } |
2926 | CorInfoHelpFunc MethodContext::repGetNewHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, |
2927 | CORINFO_METHOD_HANDLE callerHandle, |
2928 | bool* pHasSideEffects) |
2929 | { |
2930 | Agnostic_GetNewHelper key; |
2931 | ZeroMemory(&key, sizeof(Agnostic_GetNewHelper)); // We use the input structs as a key and use memcmp to compare.. so |
2932 | // we need to zero out padding too |
2933 | key.hClass = (DWORDLONG)pResolvedToken->hClass; |
2934 | key.callerHandle = (DWORDLONG)callerHandle; |
2935 | |
2936 | AssertCodeMsg(GetNewHelper != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , (DWORDLONG)key.hClass); |
2937 | AssertCodeMsg(GetNewHelper->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , (DWORDLONG)key.hClass); |
2938 | |
2939 | DD value; |
2940 | value = GetNewHelper->Get(key); |
2941 | if (pHasSideEffects != nullptr) |
2942 | { |
2943 | *pHasSideEffects = (value.A == 0) ? false : true; |
2944 | } |
2945 | CorInfoHelpFunc result = (CorInfoHelpFunc)value.B; |
2946 | |
2947 | DEBUG_REP(dmpGetNewHelper(key, value)); |
2948 | return result; |
2949 | } |
2950 | |
2951 | void MethodContext::recEmbedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, |
2952 | BOOL fEmbedParent, |
2953 | CORINFO_GENERICHANDLE_RESULT* pResult) |
2954 | { |
2955 | if (EmbedGenericHandle == nullptr) |
2956 | EmbedGenericHandle = new LightWeightMap<Agnostic_EmbedGenericHandle, Agnostic_CORINFO_GENERICHANDLE_RESULT>(); |
2957 | |
2958 | Agnostic_EmbedGenericHandle key; |
2959 | ZeroMemory(&key, sizeof(Agnostic_EmbedGenericHandle)); // We use the input structs as a key and use memcmp to |
2960 | // compare.. so we need to zero out padding too |
2961 | key.ResolvedToken = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, EmbedGenericHandle); |
2962 | key.fEmbedParent = (DWORD)fEmbedParent; |
2963 | |
2964 | Agnostic_CORINFO_GENERICHANDLE_RESULT value; |
2965 | value.lookup = SpmiRecordsHelper::StoreAgnostic_CORINFO_LOOKUP(&pResult->lookup); |
2966 | value.compileTimeHandle = (DWORDLONG)pResult->compileTimeHandle; |
2967 | value.handleType = (DWORD)pResult->handleType; |
2968 | |
2969 | EmbedGenericHandle->Add(key, value); |
2970 | DEBUG_REC(dmpEmbedGenericHandle(key, value)); |
2971 | } |
2972 | void MethodContext::dmpEmbedGenericHandle(const Agnostic_EmbedGenericHandle& key, |
2973 | const Agnostic_CORINFO_GENERICHANDLE_RESULT& value) |
2974 | { |
2975 | printf("EmbedGenericHandle key rt{%s} emb-%u\n" , |
2976 | SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKEN(key.ResolvedToken).c_str(), key.fEmbedParent); |
2977 | printf(", value %s" , SpmiDumpHelper::DumpAgnostic_CORINFO_LOOKUP(value.lookup).c_str()); |
2978 | printf(" cth-%016llX ht-%u" , value.compileTimeHandle, value.handleType); |
2979 | } |
2980 | void MethodContext::repEmbedGenericHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, |
2981 | BOOL fEmbedParent, |
2982 | CORINFO_GENERICHANDLE_RESULT* pResult) |
2983 | { |
2984 | Agnostic_EmbedGenericHandle key; |
2985 | ZeroMemory(&key, sizeof(Agnostic_EmbedGenericHandle)); // We use the input structs as a key and use memcmp to |
2986 | // compare.. so we need to zero out padding too |
2987 | |
2988 | AssertCodeMsg(EmbedGenericHandle != nullptr, EXCEPTIONCODE_MC, "Encountered an empty LWM while looking for ..." ); |
2989 | key.ResolvedToken = SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, EmbedGenericHandle); |
2990 | key.fEmbedParent = (DWORD)fEmbedParent; |
2991 | |
2992 | AssertCodeMsg(EmbedGenericHandle->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find ..." ); |
2993 | |
2994 | Agnostic_CORINFO_GENERICHANDLE_RESULT value; |
2995 | value = EmbedGenericHandle->Get(key); |
2996 | |
2997 | pResult->lookup = SpmiRecordsHelper::RestoreCORINFO_LOOKUP(value.lookup); |
2998 | pResult->compileTimeHandle = (CORINFO_GENERIC_HANDLE)value.compileTimeHandle; |
2999 | pResult->handleType = (CorInfoGenericHandleType)value.handleType; |
3000 | |
3001 | DEBUG_REP(dmpEmbedGenericHandle(key, value)); |
3002 | } |
3003 | |
3004 | void MethodContext::recGetEHinfo(CORINFO_METHOD_HANDLE ftn, unsigned EHnumber, CORINFO_EH_CLAUSE* clause) |
3005 | { |
3006 | if (GetEHinfo == nullptr) |
3007 | GetEHinfo = new LightWeightMap<DLD, Agnostic_CORINFO_EH_CLAUSE>(); |
3008 | |
3009 | DLD key; |
3010 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
3011 | // out padding too |
3012 | Agnostic_CORINFO_EH_CLAUSE value; |
3013 | |
3014 | key.A = (DWORDLONG)ftn; |
3015 | key.B = (DWORD)EHnumber; |
3016 | |
3017 | value.Flags = (DWORD)clause->Flags; |
3018 | value.TryOffset = (DWORD)clause->TryOffset; |
3019 | value.TryLength = (DWORD)clause->TryLength; |
3020 | value.HandlerOffset = (DWORD)clause->HandlerOffset; |
3021 | value.HandlerLength = (DWORD)clause->HandlerLength; |
3022 | value.ClassToken = (DWORD)clause->ClassToken; |
3023 | |
3024 | GetEHinfo->Add(key, value); |
3025 | DEBUG_REC(dmpGetEHinfo(key, value)); |
3026 | } |
3027 | void MethodContext::dmpGetEHinfo(DLD key, const Agnostic_CORINFO_EH_CLAUSE& value) |
3028 | { |
3029 | printf("GetEHinfo key ftn-%016llX ehn-%u, value flg-%u to-%u tl-%u ho-%u hl-%u ct-%u" , key.A, key.B, value.Flags, |
3030 | value.TryOffset, value.TryLength, value.HandlerOffset, value.HandlerLength, value.ClassToken); |
3031 | } |
3032 | void MethodContext::repGetEHinfo(CORINFO_METHOD_HANDLE ftn, unsigned EHnumber, CORINFO_EH_CLAUSE* clause) |
3033 | { |
3034 | DLD key; |
3035 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
3036 | // out padding too |
3037 | Agnostic_CORINFO_EH_CLAUSE value; |
3038 | |
3039 | key.A = (DWORDLONG)ftn; |
3040 | key.B = (DWORD)EHnumber; |
3041 | |
3042 | value = GetEHinfo->Get(key); |
3043 | |
3044 | clause->Flags = (CORINFO_EH_CLAUSE_FLAGS)value.Flags; |
3045 | clause->TryOffset = (DWORD)value.TryOffset; |
3046 | clause->TryLength = (DWORD)value.TryLength; |
3047 | clause->HandlerOffset = (DWORD)value.HandlerOffset; |
3048 | clause->HandlerLength = (DWORD)value.HandlerLength; |
3049 | clause->ClassToken = (DWORD)value.ClassToken; |
3050 | DEBUG_REP(dmpGetEHinfo(key, value)); |
3051 | } |
3052 | |
3053 | void MethodContext::recGetMethodVTableOffset(CORINFO_METHOD_HANDLE method, |
3054 | unsigned* offsetOfIndirection, |
3055 | unsigned* offsetAfterIndirection, |
3056 | bool* isRelative) |
3057 | { |
3058 | if (GetMethodVTableOffset == nullptr) |
3059 | GetMethodVTableOffset = new LightWeightMap<DWORDLONG, DDD>(); |
3060 | |
3061 | DDD value; |
3062 | value.A = (DWORD)*offsetOfIndirection; |
3063 | value.B = (DWORD)*offsetAfterIndirection; |
3064 | value.C = *isRelative ? 1 : 0; |
3065 | GetMethodVTableOffset->Add((DWORDLONG)method, value); |
3066 | DEBUG_REC(dmpGetMethodVTableOffset((DWORDLONG)method, value)); |
3067 | } |
3068 | void MethodContext::dmpGetMethodVTableOffset(DWORDLONG key, DDD value) |
3069 | { |
3070 | printf("GetMethodVTableOffset key ftn-%016llX, value offi-%u, offa-%u. offr-%d" , key, value.A, value.B, value.C); |
3071 | } |
3072 | void MethodContext::repGetMethodVTableOffset(CORINFO_METHOD_HANDLE method, |
3073 | unsigned* offsetOfIndirection, |
3074 | unsigned* offsetAfterIndirection, |
3075 | bool* isRelative) |
3076 | { |
3077 | DDD value; |
3078 | |
3079 | AssertCodeMsg(GetMethodVTableOffset != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , |
3080 | (DWORDLONG)method); |
3081 | AssertCodeMsg(GetMethodVTableOffset->GetIndex((DWORDLONG)method) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
3082 | (DWORDLONG)method); |
3083 | value = GetMethodVTableOffset->Get((DWORDLONG)method); |
3084 | |
3085 | *offsetOfIndirection = (unsigned)value.A; |
3086 | *offsetAfterIndirection = (unsigned)value.B; |
3087 | *isRelative = (value.C != 0); |
3088 | DEBUG_REP(dmpGetMethodVTableOffset((DWORDLONG)method, value)); |
3089 | } |
3090 | |
3091 | void MethodContext::recResolveVirtualMethod(CORINFO_METHOD_HANDLE virtMethod, |
3092 | CORINFO_CLASS_HANDLE implClass, |
3093 | CORINFO_CONTEXT_HANDLE ownerType, |
3094 | CORINFO_METHOD_HANDLE result) |
3095 | { |
3096 | if (ResolveVirtualMethod == nullptr) |
3097 | { |
3098 | ResolveVirtualMethod = new LightWeightMap<Agnostic_ResolveVirtualMethod, DWORDLONG>(); |
3099 | } |
3100 | |
3101 | Agnostic_ResolveVirtualMethod key; |
3102 | key.virtualMethod = (DWORDLONG)virtMethod; |
3103 | key.implementingClass = (DWORDLONG)implClass; |
3104 | key.ownerType = (DWORDLONG)ownerType; |
3105 | ResolveVirtualMethod->Add(key, (DWORDLONG)result); |
3106 | DEBUG_REC(dmpResolveVirtualMethod(key, result)); |
3107 | } |
3108 | |
3109 | void MethodContext::dmpResolveVirtualMethod(const Agnostic_ResolveVirtualMethod& key, DWORDLONG value) |
3110 | { |
3111 | printf("ResolveVirtualMethod virtMethod-%016llX, implClass-%016llX, ownerType--%016llX, result-%016llX" , |
3112 | key.virtualMethod, key.implementingClass, key.ownerType, value); |
3113 | } |
3114 | |
3115 | CORINFO_METHOD_HANDLE MethodContext::repResolveVirtualMethod(CORINFO_METHOD_HANDLE virtMethod, |
3116 | CORINFO_CLASS_HANDLE implClass, |
3117 | CORINFO_CONTEXT_HANDLE ownerType) |
3118 | { |
3119 | Agnostic_ResolveVirtualMethod key; |
3120 | key.virtualMethod = (DWORDLONG)virtMethod; |
3121 | key.implementingClass = (DWORDLONG)implClass; |
3122 | key.ownerType = (DWORDLONG)ownerType; |
3123 | |
3124 | AssertCodeMsg(ResolveVirtualMethod != nullptr, EXCEPTIONCODE_MC, |
3125 | "No ResolveVirtualMap map for %016llX-%016llX-%016llX" , key.virtualMethod, key.implementingClass, |
3126 | key.ownerType); |
3127 | AssertCodeMsg(ResolveVirtualMethod->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX-%016llx-%016llX" , |
3128 | key.virtualMethod, key.implementingClass, key.ownerType); |
3129 | DWORDLONG result = ResolveVirtualMethod->Get(key); |
3130 | |
3131 | DEBUG_REP(dmpResolveVirtualMethod(key, result)); |
3132 | |
3133 | return (CORINFO_METHOD_HANDLE)result; |
3134 | } |
3135 | |
3136 | void MethodContext::recGetUnboxedEntry(CORINFO_METHOD_HANDLE ftn, |
3137 | bool* requiresInstMethodTableArg, |
3138 | CORINFO_METHOD_HANDLE result) |
3139 | { |
3140 | if (GetUnboxedEntry == nullptr) |
3141 | { |
3142 | GetUnboxedEntry = new LightWeightMap<DWORDLONG, DLD>(); |
3143 | } |
3144 | |
3145 | DWORDLONG key = (DWORDLONG)ftn; |
3146 | DLD value; |
3147 | value.A = (DWORDLONG)result; |
3148 | if (requiresInstMethodTableArg != nullptr) |
3149 | { |
3150 | value.B = (DWORD)*requiresInstMethodTableArg ? 1 : 0; |
3151 | } |
3152 | else |
3153 | { |
3154 | value.B = 0; |
3155 | } |
3156 | GetUnboxedEntry->Add(key, value); |
3157 | DEBUG_REC(dmpGetUnboxedEntry(key, value)); |
3158 | } |
3159 | |
3160 | void MethodContext::dmpGetUnboxedEntry(DWORDLONG key, DLD value) |
3161 | { |
3162 | printf("GetUnboxedEntry ftn-%016llX, result-%016llX, requires-inst-%u" , key, value.A, value.B); |
3163 | } |
3164 | |
3165 | CORINFO_METHOD_HANDLE MethodContext::repGetUnboxedEntry(CORINFO_METHOD_HANDLE ftn, bool* requiresInstMethodTableArg) |
3166 | { |
3167 | DWORDLONG key = (DWORDLONG)ftn; |
3168 | |
3169 | AssertCodeMsg(GetUnboxedEntry != nullptr, EXCEPTIONCODE_MC, "No GetUnboxedEntry map for %016llX" , key); |
3170 | AssertCodeMsg(GetUnboxedEntry->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , key); |
3171 | DLD result = GetUnboxedEntry->Get(key); |
3172 | |
3173 | DEBUG_REP(dmpGetUnboxedEntry(key, result)); |
3174 | |
3175 | if (requiresInstMethodTableArg != nullptr) |
3176 | { |
3177 | *requiresInstMethodTableArg = (result.B == 1); |
3178 | } |
3179 | |
3180 | return (CORINFO_METHOD_HANDLE)(result.A); |
3181 | } |
3182 | |
3183 | void MethodContext::recGetDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result) |
3184 | { |
3185 | if (GetDefaultEqualityComparerClass == nullptr) |
3186 | GetDefaultEqualityComparerClass = new LightWeightMap<DWORDLONG, DWORDLONG>(); |
3187 | |
3188 | GetDefaultEqualityComparerClass->Add((DWORDLONG)cls, (DWORDLONG)result); |
3189 | } |
3190 | void MethodContext::dmpGetDefaultEqualityComparerClass(DWORDLONG key, DWORDLONG value) |
3191 | { |
3192 | printf("GetDefaultEqualityComparerClass key cls-%016llX, value cls-%016llX" , key, value); |
3193 | } |
3194 | CORINFO_CLASS_HANDLE MethodContext::repGetDefaultEqualityComparerClass(CORINFO_CLASS_HANDLE cls) |
3195 | { |
3196 | CORINFO_CLASS_HANDLE result = (CORINFO_CLASS_HANDLE)GetDefaultEqualityComparerClass->Get((DWORDLONG)cls); |
3197 | return result; |
3198 | } |
3199 | |
3200 | void MethodContext::recGetTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_CLASS_HANDLE result) |
3201 | { |
3202 | if (GetTokenTypeAsHandle == nullptr) |
3203 | GetTokenTypeAsHandle = new LightWeightMap<GetTokenTypeAsHandleValue, DWORDLONG>(); |
3204 | |
3205 | GetTokenTypeAsHandleValue key; |
3206 | ZeroMemory(&key, sizeof(GetTokenTypeAsHandleValue)); // We use the input structs as a key and use memcmp to |
3207 | // compare.. so we need to zero out padding too |
3208 | |
3209 | key.hMethod = (DWORDLONG)pResolvedToken->hMethod; |
3210 | key.hField = (DWORDLONG)pResolvedToken->hField; |
3211 | |
3212 | GetTokenTypeAsHandle->Add(key, (DWORDLONG)result); |
3213 | } |
3214 | void MethodContext::dmpGetTokenTypeAsHandle(const GetTokenTypeAsHandleValue& key, DWORDLONG value) |
3215 | { |
3216 | printf("GetTokenTypeAsHandle key ftn-%016llX fld-%016llX, value cls-%016llX" , key.hMethod, key.hField, value); |
3217 | } |
3218 | CORINFO_CLASS_HANDLE MethodContext::repGetTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken) |
3219 | { |
3220 | GetTokenTypeAsHandleValue key; |
3221 | ZeroMemory(&key, sizeof(GetTokenTypeAsHandleValue)); // We use the input structs as a key and use memcmp to |
3222 | // compare.. so we need to zero out padding too |
3223 | |
3224 | key.hMethod = (DWORDLONG)pResolvedToken->hMethod; |
3225 | key.hField = (DWORDLONG)pResolvedToken->hField; |
3226 | |
3227 | CORINFO_CLASS_HANDLE value = (CORINFO_CLASS_HANDLE)GetTokenTypeAsHandle->Get(key); |
3228 | return value; |
3229 | } |
3230 | |
3231 | void MethodContext::recGetFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken, |
3232 | CORINFO_METHOD_HANDLE callerHandle, |
3233 | CORINFO_ACCESS_FLAGS flags, |
3234 | CORINFO_FIELD_INFO* pResult) |
3235 | { |
3236 | if (GetFieldInfo == nullptr) |
3237 | GetFieldInfo = new LightWeightMap<Agnostic_GetFieldInfo, Agnostic_CORINFO_FIELD_INFO>(); |
3238 | Agnostic_GetFieldInfo key; |
3239 | ZeroMemory(&key, sizeof(Agnostic_GetFieldInfo)); // Since dd has nested structs, and we use memcmp to compare, we |
3240 | // need to zero out the padding bytes too |
3241 | key.ResolvedToken = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, GetFieldInfo); |
3242 | key.callerHandle = (DWORDLONG)callerHandle; |
3243 | key.flags = (DWORD)flags; |
3244 | |
3245 | Agnostic_CORINFO_FIELD_INFO value; |
3246 | value.fieldAccessor = (DWORD)pResult->fieldAccessor; |
3247 | value.fieldFlags = (DWORD)pResult->fieldFlags; |
3248 | value.helper = (DWORD)pResult->helper; |
3249 | value.offset = (DWORD)pResult->offset; |
3250 | value.fieldType = (DWORD)pResult->fieldType; |
3251 | value.structType = (DWORDLONG)pResult->structType; |
3252 | value.accessAllowed = (DWORD)pResult->accessAllowed; |
3253 | value.accessCalloutHelper.helperNum = (DWORD)pResult->accessCalloutHelper.helperNum; |
3254 | value.accessCalloutHelper.numArgs = (DWORD)pResult->accessCalloutHelper.numArgs; |
3255 | value.fieldLookup = SpmiRecordsHelper::StoreAgnostic_CORINFO_CONST_LOOKUP(&pResult->fieldLookup); |
3256 | for (int i = 0; i < CORINFO_ACCESS_ALLOWED_MAX_ARGS; i++) |
3257 | { |
3258 | value.accessCalloutHelper.args[i].constant = (DWORDLONG)pResult->accessCalloutHelper.args[i].constant; |
3259 | value.accessCalloutHelper.args[i].argType = (DWORD)pResult->accessCalloutHelper.args[i].argType; |
3260 | } |
3261 | GetFieldInfo->Add(key, value); |
3262 | DEBUG_REC(dmpGetFieldInfo(key, value)); |
3263 | } |
3264 | void MethodContext::dmpGetFieldInfo(const Agnostic_GetFieldInfo& key, const Agnostic_CORINFO_FIELD_INFO& value) |
3265 | { |
3266 | printf("GetFieldInfo key ch-%016llX flg-%08X rt{%s}\n" , key.callerHandle, key.flags, |
3267 | SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKEN(key.ResolvedToken).c_str()); |
3268 | |
3269 | printf(", value fa-%u fflg-%08X hlp-%u off-%u fT-%u(%s) sT-%016llX aa-%u hnum-%u na-%u {" , value.fieldAccessor, |
3270 | value.fieldFlags, value.helper, value.offset, value.fieldType, toString((CorInfoType)value.fieldType), |
3271 | value.structType, value.accessAllowed, value.accessCalloutHelper.helperNum, |
3272 | value.accessCalloutHelper.numArgs); |
3273 | |
3274 | for (int i = 0; i < CORINFO_ACCESS_ALLOWED_MAX_ARGS; i++) |
3275 | { |
3276 | switch ((CorInfoAccessAllowedHelperArgType)value.accessCalloutHelper.args[i].argType) |
3277 | { |
3278 | default: |
3279 | printf("{%u: illegal}" , i); |
3280 | break; |
3281 | case CORINFO_HELPER_ARG_TYPE_Field: |
3282 | printf("{%u: fld-%016llX}" , i, value.accessCalloutHelper.args[i].constant); |
3283 | break; |
3284 | case CORINFO_HELPER_ARG_TYPE_Method: |
3285 | printf("{%u: mth-%016llX}" , i, value.accessCalloutHelper.args[i].constant); |
3286 | break; |
3287 | case CORINFO_HELPER_ARG_TYPE_Class: |
3288 | printf("{%u: cls-%016llX}" , i, value.accessCalloutHelper.args[i].constant); |
3289 | break; |
3290 | case CORINFO_HELPER_ARG_TYPE_Module: |
3291 | printf("{%u: mod-%016llX}" , i, value.accessCalloutHelper.args[i].constant); |
3292 | break; |
3293 | case CORINFO_HELPER_ARG_TYPE_Const: |
3294 | printf("{%u: const-%016llX}" , i, value.accessCalloutHelper.args[i].constant); |
3295 | break; |
3296 | } |
3297 | } |
3298 | printf(" fl %s}" , SpmiDumpHelper::DumpAgnostic_CORINFO_CONST_LOOKUP(value.fieldLookup).c_str()); |
3299 | } |
3300 | void MethodContext::repGetFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken, |
3301 | CORINFO_METHOD_HANDLE callerHandle, |
3302 | CORINFO_ACCESS_FLAGS flags, |
3303 | CORINFO_FIELD_INFO* pResult) |
3304 | { |
3305 | AssertCodeMsg(GetFieldInfo != nullptr, EXCEPTIONCODE_MC, "Didn't find %x" , pResolvedToken->token); |
3306 | |
3307 | Agnostic_GetFieldInfo key; |
3308 | ZeroMemory(&key, sizeof(Agnostic_GetFieldInfo)); // Since dd has nested structs, and we use memcmp to compare, we |
3309 | // need to zero out the padding bytes too |
3310 | key.ResolvedToken = SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, GetFieldInfo); |
3311 | key.callerHandle = (DWORDLONG)callerHandle; |
3312 | key.flags = (DWORD)flags; |
3313 | |
3314 | DWORD origFlag = key.flags; |
3315 | |
3316 | if (GetFieldInfo->GetIndex(key) == -1) |
3317 | { |
3318 | #ifdef sparseMC |
3319 | key.flags = origFlag ^ (DWORD)CORINFO_ACCESS_UNWRAP; |
3320 | if (GetFieldInfo->GetIndex(key) != -1) |
3321 | { |
3322 | LogDebug("Sparse - repGetFieldInfo found value with inverted CORINFO_ACCESS_UNWRAP" ); |
3323 | } |
3324 | else |
3325 | { |
3326 | key.flags = origFlag ^ ((DWORD)CORINFO_ACCESS_THIS | (DWORD)CORINFO_ACCESS_UNWRAP); |
3327 | if (GetFieldInfo->GetIndex(key) != -1) |
3328 | { |
3329 | LogDebug( |
3330 | "Sparse - repGetFieldInfo found value with inverted CORINFO_ACCESS_UNWRAP|CORINFO_ACCESS_THIS" ); |
3331 | } |
3332 | else |
3333 | { |
3334 | key.flags = origFlag ^ (DWORD)CORINFO_ACCESS_INLINECHECK; |
3335 | if (GetFieldInfo->GetIndex(key) != -1) |
3336 | { |
3337 | LogDebug("Sparse - repGetFieldInfo found value with inverted CORINFO_ACCESS_INLINECHECK" ); |
3338 | } |
3339 | else |
3340 | { |
3341 | LogException(EXCEPTIONCODE_MC, "Didn't find %x" , pResolvedToken->token); |
3342 | } |
3343 | } |
3344 | } |
3345 | #else |
3346 | LogException(EXCEPTIONCODE_MC, "Didn't find %x" , pResolvedToken->token); |
3347 | #endif |
3348 | } |
3349 | |
3350 | Agnostic_CORINFO_FIELD_INFO value = GetFieldInfo->Get(key); |
3351 | |
3352 | pResult->fieldAccessor = (CORINFO_FIELD_ACCESSOR)value.fieldAccessor; |
3353 | pResult->fieldFlags = (unsigned)value.fieldFlags; |
3354 | pResult->helper = (CorInfoHelpFunc)value.helper; |
3355 | pResult->offset = (DWORD)value.offset; |
3356 | pResult->fieldType = (CorInfoType)value.fieldType; |
3357 | pResult->structType = (CORINFO_CLASS_HANDLE)value.structType; |
3358 | pResult->accessAllowed = (CorInfoIsAccessAllowedResult)value.accessAllowed; |
3359 | pResult->accessCalloutHelper.helperNum = (CorInfoHelpFunc)value.accessCalloutHelper.helperNum; |
3360 | pResult->accessCalloutHelper.numArgs = (unsigned)value.accessCalloutHelper.numArgs; |
3361 | pResult->fieldLookup = SpmiRecordsHelper::RestoreCORINFO_CONST_LOOKUP(value.fieldLookup); |
3362 | for (int i = 0; i < CORINFO_ACCESS_ALLOWED_MAX_ARGS; i++) |
3363 | { |
3364 | pResult->accessCalloutHelper.args[i].constant = (size_t)value.accessCalloutHelper.args[i].constant; |
3365 | pResult->accessCalloutHelper.args[i].argType = |
3366 | (CorInfoAccessAllowedHelperArgType)value.accessCalloutHelper.args[i].argType; |
3367 | } |
3368 | DEBUG_REP(dmpGetFieldInfo(key, value)); |
3369 | } |
3370 | |
3371 | void MethodContext::recEmbedMethodHandle(CORINFO_METHOD_HANDLE handle, |
3372 | void** ppIndirection, |
3373 | CORINFO_METHOD_HANDLE result) |
3374 | { |
3375 | if (EmbedMethodHandle == nullptr) |
3376 | EmbedMethodHandle = new LightWeightMap<DWORDLONG, DLDL>(); |
3377 | |
3378 | DLDL value; |
3379 | if (ppIndirection == nullptr) |
3380 | value.A = (DWORDLONG)0; |
3381 | else |
3382 | value.A = (DWORDLONG)*ppIndirection; |
3383 | value.B = (DWORDLONG)result; |
3384 | |
3385 | EmbedMethodHandle->Add((DWORDLONG)handle, value); |
3386 | DEBUG_REC(dmpEmbedMethodHandle((DWORDLONG)handle, value)); |
3387 | } |
3388 | void MethodContext::dmpEmbedMethodHandle(DWORDLONG key, DLDL value) |
3389 | { |
3390 | printf("EmbedMethodHandle key ftn-%016llX, value pp-%016llX res-%016llX" , key, value.A, value.B); |
3391 | } |
3392 | CORINFO_METHOD_HANDLE MethodContext::repEmbedMethodHandle(CORINFO_METHOD_HANDLE handle, void** ppIndirection) |
3393 | { |
3394 | DLDL value; |
3395 | |
3396 | AssertCodeMsg(EmbedMethodHandle != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , |
3397 | (DWORDLONG)handle); |
3398 | AssertCodeMsg(EmbedMethodHandle->GetIndex((DWORDLONG)handle) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
3399 | (DWORDLONG)handle); |
3400 | value = EmbedMethodHandle->Get((DWORDLONG)handle); |
3401 | |
3402 | if (ppIndirection != nullptr) |
3403 | *ppIndirection = (void*)value.A; |
3404 | DEBUG_REP(dmpEmbedMethodHandle((DWORDLONG)handle, value)); |
3405 | return (CORINFO_METHOD_HANDLE)value.B; |
3406 | } |
3407 | |
3408 | void MethodContext::recGetFieldAddress(CORINFO_FIELD_HANDLE field, void** ppIndirection, void* result, CorInfoType cit) |
3409 | { |
3410 | if (GetFieldAddress == nullptr) |
3411 | GetFieldAddress = new LightWeightMap<DWORDLONG, Agnostic_GetFieldAddress>(); |
3412 | |
3413 | Agnostic_GetFieldAddress value; |
3414 | if (ppIndirection == nullptr) |
3415 | value.ppIndirection = (DWORDLONG)0; |
3416 | else |
3417 | value.ppIndirection = (DWORDLONG)*ppIndirection; |
3418 | value.fieldAddress = (DWORDLONG)result; |
3419 | |
3420 | value.fieldValue = (DWORD)-1; |
3421 | |
3422 | // Make an attempt at stashing a copy of the value |
3423 | if (result > (void*)0xffff) // TODO-Cleanup: sometimes there is a field offset? |
3424 | { |
3425 | DWORDLONG scratch = 0x4242424242424242; |
3426 | switch (cit) |
3427 | { |
3428 | case CORINFO_TYPE_BOOL: |
3429 | case CORINFO_TYPE_BYTE: |
3430 | case CORINFO_TYPE_UBYTE: |
3431 | value.fieldValue = |
3432 | (DWORD)GetFieldAddress->AddBuffer((unsigned char*)result, sizeof(BYTE), |
3433 | true); // important to not merge two fields into one address |
3434 | break; |
3435 | case CORINFO_TYPE_CHAR: |
3436 | case CORINFO_TYPE_SHORT: |
3437 | case CORINFO_TYPE_USHORT: |
3438 | value.fieldValue = |
3439 | (DWORD)GetFieldAddress->AddBuffer((unsigned char*)result, sizeof(WORD), |
3440 | true); // important to not merge two fields into one address |
3441 | break; |
3442 | case CORINFO_TYPE_INT: |
3443 | case CORINFO_TYPE_UINT: |
3444 | case CORINFO_TYPE_FLOAT: |
3445 | value.fieldValue = |
3446 | (DWORD)GetFieldAddress->AddBuffer((unsigned char*)result, sizeof(DWORD), |
3447 | true); // important to not merge two fields into one address |
3448 | break; |
3449 | case CORINFO_TYPE_LONG: |
3450 | case CORINFO_TYPE_ULONG: |
3451 | case CORINFO_TYPE_DOUBLE: |
3452 | value.fieldValue = |
3453 | (DWORD)GetFieldAddress->AddBuffer((unsigned char*)result, sizeof(DWORDLONG), |
3454 | true); // important to not merge two fields into one address |
3455 | break; |
3456 | case CORINFO_TYPE_NATIVEINT: |
3457 | case CORINFO_TYPE_NATIVEUINT: |
3458 | case CORINFO_TYPE_PTR: |
3459 | value.fieldValue = |
3460 | (DWORD)GetFieldAddress->AddBuffer((unsigned char*)result, sizeof(size_t), |
3461 | true); // important to not merge two fields into one address |
3462 | GetFieldAddress->AddBuffer((unsigned char*)&scratch, sizeof(DWORD)); // Padding out the data so we can |
3463 | // read it back "safetly" on x64 |
3464 | break; |
3465 | default: |
3466 | break; |
3467 | } |
3468 | } |
3469 | GetFieldAddress->Add((DWORDLONG)field, value); |
3470 | DEBUG_REC(dmpGetFieldAddress((DWORDLONG)field, value)); |
3471 | } |
3472 | void MethodContext::dmpGetFieldAddress(DWORDLONG key, const Agnostic_GetFieldAddress& value) |
3473 | { |
3474 | printf("GetFieldAddress key fld-%016llX, value ppi-%016llX addr-%016llX val-%u" , key, value.ppIndirection, |
3475 | value.fieldAddress, value.fieldValue); |
3476 | } |
3477 | void* MethodContext::repGetFieldAddress(CORINFO_FIELD_HANDLE field, void** ppIndirection) |
3478 | { |
3479 | Agnostic_GetFieldAddress value; |
3480 | |
3481 | value = GetFieldAddress->Get((DWORDLONG)field); |
3482 | |
3483 | if (ppIndirection != nullptr) |
3484 | *ppIndirection = (void*)value.ppIndirection; |
3485 | void* temp; |
3486 | |
3487 | if (value.fieldValue != (DWORD)-1) |
3488 | { |
3489 | temp = (void*)GetFieldAddress->GetBuffer(value.fieldValue); |
3490 | cr->recAddressMap((void*)value.fieldAddress, temp, toCorInfoSize(repGetFieldType(field, nullptr, nullptr))); |
3491 | } |
3492 | else |
3493 | temp = (void*)value.fieldAddress; |
3494 | |
3495 | DEBUG_REP(dmpGetFieldAddress((DWORDLONG)field, value)); |
3496 | return temp; |
3497 | } |
3498 | |
3499 | void MethodContext::recGetStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, |
3500 | bool isSpeculative, |
3501 | CORINFO_CLASS_HANDLE result) |
3502 | { |
3503 | if (GetStaticFieldCurrentClass == nullptr) |
3504 | GetStaticFieldCurrentClass = new LightWeightMap<DWORDLONG, Agnostic_GetStaticFieldCurrentClass>(); |
3505 | |
3506 | Agnostic_GetStaticFieldCurrentClass value; |
3507 | |
3508 | value.classHandle = (DWORDLONG)result; |
3509 | value.isSpeculative = isSpeculative; |
3510 | |
3511 | GetStaticFieldCurrentClass->Add((DWORDLONG)field, value); |
3512 | DEBUG_REC(dmpGetFieldAddress((DWORDLONG)field, value)); |
3513 | } |
3514 | void MethodContext::dmpGetStaticFieldCurrentClass(DWORDLONG key, const Agnostic_GetStaticFieldCurrentClass& value) |
3515 | { |
3516 | printf("GetStaticFieldCurrentClass key fld-%016llX, value clsHnd-%016llX isSpeculative-%u" , key, value.classHandle, |
3517 | value.isSpeculative); |
3518 | } |
3519 | CORINFO_CLASS_HANDLE MethodContext::repGetStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool* pIsSpeculative) |
3520 | { |
3521 | Agnostic_GetStaticFieldCurrentClass value = GetStaticFieldCurrentClass->Get((DWORDLONG)field); |
3522 | |
3523 | if (pIsSpeculative != nullptr) |
3524 | { |
3525 | *pIsSpeculative = value.isSpeculative; |
3526 | } |
3527 | |
3528 | CORINFO_CLASS_HANDLE result = (CORINFO_CLASS_HANDLE)value.classHandle; |
3529 | DEBUG_REP(dmpGetStaticFieldCurrentValue((DWORDLONG)field, value)); |
3530 | return result; |
3531 | } |
3532 | |
3533 | void MethodContext::recGetClassGClayout(CORINFO_CLASS_HANDLE cls, BYTE* gcPtrs, unsigned len, unsigned result) |
3534 | { |
3535 | if (GetClassGClayout == nullptr) |
3536 | GetClassGClayout = new LightWeightMap<DWORDLONG, Agnostic_GetClassGClayout>(); |
3537 | |
3538 | Agnostic_GetClassGClayout value; |
3539 | |
3540 | value.gcPtrs_Index = (DWORD)GetClassGClayout->AddBuffer((unsigned char*)gcPtrs, len * sizeof(BYTE)); |
3541 | value.len = (DWORD)len; |
3542 | value.valCount = (DWORD)result; |
3543 | |
3544 | GetClassGClayout->Add((DWORDLONG)cls, value); |
3545 | DEBUG_REC(dmpGetClassGClayout((DWORDLONG)cls, value)); |
3546 | } |
3547 | void MethodContext::dmpGetClassGClayout(DWORDLONG key, const Agnostic_GetClassGClayout& value) |
3548 | { |
3549 | printf("GetClassGCLayout key %016llX, value len %u cnt %u {" , key, value.len, value.valCount); |
3550 | if (value.gcPtrs_Index != -1) |
3551 | { |
3552 | BYTE* ptr = (BYTE*)GetClassGClayout->GetBuffer(value.gcPtrs_Index); |
3553 | for (unsigned int i = 0; i < value.len; i++) |
3554 | { |
3555 | printf("0x%02x" , ptr[i]); |
3556 | if (i + 1 < value.len) |
3557 | printf("," ); |
3558 | } |
3559 | GetClassGClayout->Unlock(); |
3560 | } |
3561 | printf("}" ); |
3562 | } |
3563 | unsigned MethodContext::repGetClassGClayout(CORINFO_CLASS_HANDLE cls, BYTE* gcPtrs) |
3564 | { |
3565 | Agnostic_GetClassGClayout value; |
3566 | |
3567 | AssertCodeMsg(GetClassGClayout != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , (DWORDLONG)cls); |
3568 | AssertCodeMsg(GetClassGClayout->GetIndex((DWORDLONG)cls) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
3569 | (DWORDLONG)cls); |
3570 | value = GetClassGClayout->Get((DWORDLONG)cls); |
3571 | |
3572 | unsigned int len = (unsigned int)value.len; |
3573 | unsigned int index = (unsigned int)value.gcPtrs_Index; |
3574 | |
3575 | if (index != -1) |
3576 | { |
3577 | BYTE* ptr = (BYTE*)GetClassGClayout->GetBuffer(index); |
3578 | for (unsigned int i = 0; i < len; i++) |
3579 | gcPtrs[i] = ptr[i]; |
3580 | } |
3581 | DEBUG_REP(dmpGetClassGClayout((DWORDLONG)cls, value)); |
3582 | return (unsigned)value.valCount; |
3583 | } |
3584 | |
3585 | void MethodContext::recGetClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint, unsigned result) |
3586 | { |
3587 | if (GetClassAlignmentRequirement == nullptr) |
3588 | GetClassAlignmentRequirement = new LightWeightMap<DLD, DWORD>(); |
3589 | DLD key; |
3590 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
3591 | // out padding too |
3592 | |
3593 | key.A = (DWORDLONG)cls; |
3594 | key.B = (DWORD)fDoubleAlignHint; |
3595 | |
3596 | GetClassAlignmentRequirement->Add(key, (DWORD)result); |
3597 | DEBUG_REC(dmpGetClassAlignmentRequirement(key, result)); |
3598 | } |
3599 | void MethodContext::dmpGetClassAlignmentRequirement(DLD key, DWORD value) |
3600 | { |
3601 | printf("GetClassAlignmentRequirement key %016llX %u, value %u" , key.A, key.B, value); |
3602 | } |
3603 | unsigned MethodContext::repGetClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint) |
3604 | { |
3605 | DLD key; |
3606 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
3607 | // out padding too |
3608 | key.A = (DWORDLONG)cls; |
3609 | key.B = (DWORD)fDoubleAlignHint; |
3610 | |
3611 | unsigned result = (unsigned)GetClassAlignmentRequirement->Get(key); |
3612 | DEBUG_REP(dmpGetClassAlignmentRequirement(key, result)); |
3613 | return result; |
3614 | } |
3615 | |
3616 | void MethodContext::recCanAccessClass(CORINFO_RESOLVED_TOKEN* pResolvedToken, |
3617 | CORINFO_METHOD_HANDLE callerHandle, |
3618 | CORINFO_HELPER_DESC* pAccessHelper, |
3619 | CorInfoIsAccessAllowedResult result) |
3620 | { |
3621 | if (CanAccessClass == nullptr) |
3622 | CanAccessClass = new LightWeightMap<Agnostic_CanAccessClassIn, Agnostic_CanAccessClassOut>(); |
3623 | |
3624 | Agnostic_CanAccessClassIn key; |
3625 | ZeroMemory(&key, sizeof(Agnostic_CanAccessClassIn)); // We use the input structs as a key and use memcmp to |
3626 | // compare.. so we need to zero out padding too |
3627 | key.ResolvedToken = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, CanAccessClass); |
3628 | key.callerHandle = (DWORDLONG)callerHandle; |
3629 | |
3630 | Agnostic_CanAccessClassOut value; |
3631 | value.AccessHelper.helperNum = (DWORD)pAccessHelper->helperNum; |
3632 | value.AccessHelper.numArgs = (DWORD)pAccessHelper->numArgs; |
3633 | for (int i = 0; i < CORINFO_ACCESS_ALLOWED_MAX_ARGS; i++) |
3634 | { |
3635 | value.AccessHelper.args[i].constant = (DWORDLONG)pAccessHelper->args[i].constant; |
3636 | value.AccessHelper.args[i].argType = (DWORD)pAccessHelper->args[i].argType; |
3637 | } |
3638 | value.result = (DWORD)result; |
3639 | |
3640 | CanAccessClass->Add(key, value); |
3641 | DEBUG_REC(dmpCanAccessClass(key, value)); |
3642 | } |
3643 | void MethodContext::dmpCanAccessClass(const Agnostic_CanAccessClassIn& key, const Agnostic_CanAccessClassOut& value) |
3644 | { |
3645 | printf("CanAccessClass key rt{%s}, callerHandle %016llX\n" , |
3646 | SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKEN(key.ResolvedToken).c_str(), key.callerHandle); |
3647 | printf(", value hnum-%u na-%u {" , value.AccessHelper.helperNum, value.AccessHelper.numArgs); |
3648 | for (int i = 0; i < CORINFO_ACCESS_ALLOWED_MAX_ARGS; i++) |
3649 | { |
3650 | printf("{%016llX %u}" , value.AccessHelper.args[i].constant, value.AccessHelper.args[i].argType); |
3651 | } |
3652 | printf("} res-%u" , value.result); |
3653 | } |
3654 | CorInfoIsAccessAllowedResult MethodContext::repCanAccessClass(CORINFO_RESOLVED_TOKEN* pResolvedToken, |
3655 | CORINFO_METHOD_HANDLE callerHandle, |
3656 | CORINFO_HELPER_DESC* pAccessHelper) |
3657 | { |
3658 | AssertCodeMsg(CanAccessClass != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , |
3659 | (DWORDLONG)pResolvedToken->hClass); |
3660 | |
3661 | Agnostic_CanAccessClassIn key; |
3662 | ZeroMemory(&key, sizeof(Agnostic_CanAccessClassIn)); // We use the input structs as a key and use memcmp to |
3663 | // compare.. so we need to zero out padding too |
3664 | key.ResolvedToken = SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKEN(pResolvedToken, CanAccessClass); |
3665 | key.callerHandle = (DWORDLONG)callerHandle; |
3666 | |
3667 | AssertCodeMsg(CanAccessClass->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
3668 | (DWORDLONG)pResolvedToken->hClass); |
3669 | Agnostic_CanAccessClassOut value = CanAccessClass->Get(key); |
3670 | |
3671 | pAccessHelper->helperNum = (CorInfoHelpFunc)value.AccessHelper.helperNum; |
3672 | pAccessHelper->numArgs = (unsigned)value.AccessHelper.numArgs; |
3673 | for (int i = 0; i < CORINFO_ACCESS_ALLOWED_MAX_ARGS; i++) |
3674 | { |
3675 | pAccessHelper->args[i].constant = (size_t)value.AccessHelper.args[i].constant; |
3676 | pAccessHelper->args[i].argType = (CorInfoAccessAllowedHelperArgType)value.AccessHelper.args[i].argType; |
3677 | } |
3678 | CorInfoIsAccessAllowedResult temp = (CorInfoIsAccessAllowedResult)value.result; |
3679 | DEBUG_REP(dmpCanAccessClass(key, value)); |
3680 | return temp; |
3681 | } |
3682 | |
3683 | void MethodContext::recGetCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing, CorInfoHelpFunc result) |
3684 | { |
3685 | if (GetCastingHelper == nullptr) |
3686 | GetCastingHelper = new LightWeightMap<Agnostic_GetCastingHelper, DWORD>(); |
3687 | |
3688 | Agnostic_GetCastingHelper key; |
3689 | ZeroMemory(&key, sizeof(Agnostic_GetCastingHelper)); // We use the input structs as a key and use memcmp to |
3690 | // compare.. so we need to zero out padding too |
3691 | |
3692 | key.hClass = (DWORDLONG)pResolvedToken->hClass; |
3693 | key.fThrowing = (DWORD)fThrowing; |
3694 | |
3695 | GetCastingHelper->Add(key, (DWORD)result); |
3696 | } |
3697 | void MethodContext::dmpGetCastingHelper(const Agnostic_GetCastingHelper& key, DWORD value) |
3698 | { |
3699 | printf("GetCastingHelper key cls-%016llX, thw-%u, value res-%u" , key.hClass, key.fThrowing, value); |
3700 | } |
3701 | CorInfoHelpFunc MethodContext::repGetCastingHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, bool fThrowing) |
3702 | { |
3703 | Agnostic_GetCastingHelper key; |
3704 | ZeroMemory(&key, sizeof(Agnostic_GetCastingHelper)); // We use the input structs as a key and use memcmp to |
3705 | // compare.. so we need to zero out padding too |
3706 | |
3707 | key.hClass = (DWORDLONG)pResolvedToken->hClass; |
3708 | key.fThrowing = (DWORD)fThrowing; |
3709 | |
3710 | CorInfoHelpFunc value = (CorInfoHelpFunc)GetCastingHelper->Get(key); |
3711 | return value; |
3712 | } |
3713 | |
3714 | void MethodContext::recEmbedModuleHandle(CORINFO_MODULE_HANDLE handle, |
3715 | void** ppIndirection, |
3716 | CORINFO_MODULE_HANDLE result) |
3717 | { |
3718 | if (EmbedModuleHandle == nullptr) |
3719 | EmbedModuleHandle = new LightWeightMap<DWORDLONG, DLDL>(); |
3720 | |
3721 | DLDL value; |
3722 | if (ppIndirection != nullptr) |
3723 | value.A = (DWORDLONG)*ppIndirection; |
3724 | else |
3725 | value.A = (DWORDLONG)0; |
3726 | value.B = (DWORDLONG)result; |
3727 | |
3728 | EmbedModuleHandle->Add((DWORDLONG)handle, value); |
3729 | } |
3730 | void MethodContext::dmpEmbedModuleHandle(DWORDLONG key, DLDL value) |
3731 | { |
3732 | printf("EmbedModuleHandle key mod-%016llX, value pp-%016llX res-%016llX" , key, value.A, value.B); |
3733 | } |
3734 | CORINFO_MODULE_HANDLE MethodContext::repEmbedModuleHandle(CORINFO_MODULE_HANDLE handle, void** ppIndirection) |
3735 | { |
3736 | DLDL value; |
3737 | |
3738 | value = EmbedModuleHandle->Get((DWORDLONG)handle); |
3739 | if (ppIndirection != nullptr) |
3740 | *ppIndirection = (void*)value.A; |
3741 | return (CORINFO_MODULE_HANDLE)value.B; |
3742 | } |
3743 | |
3744 | void MethodContext::recEmbedClassHandle(CORINFO_CLASS_HANDLE handle, void** ppIndirection, CORINFO_CLASS_HANDLE result) |
3745 | { |
3746 | if (EmbedClassHandle == nullptr) |
3747 | EmbedClassHandle = new LightWeightMap<DWORDLONG, DLDL>(); |
3748 | |
3749 | DLDL value; |
3750 | if (ppIndirection != nullptr) |
3751 | value.A = (DWORDLONG)*ppIndirection; |
3752 | else |
3753 | value.A = (DWORDLONG)0; |
3754 | value.B = (DWORDLONG)result; |
3755 | |
3756 | EmbedClassHandle->Add((DWORDLONG)handle, value); |
3757 | DEBUG_REC(dmpEmbedClassHandle((DWORDLONG)handle, value)); |
3758 | } |
3759 | void MethodContext::dmpEmbedClassHandle(DWORDLONG key, DLDL value) |
3760 | { |
3761 | printf("EmbedClassHandle key cls-%016llX, value pp-%016llX res-%016llX" , key, value.A, value.B); |
3762 | } |
3763 | CORINFO_CLASS_HANDLE MethodContext::repEmbedClassHandle(CORINFO_CLASS_HANDLE handle, void** ppIndirection) |
3764 | { |
3765 | DLDL value; |
3766 | |
3767 | AssertCodeMsg(EmbedClassHandle != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , (DWORDLONG)handle); |
3768 | AssertCodeMsg(EmbedClassHandle->GetIndex((DWORDLONG)handle) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
3769 | (DWORDLONG)handle); |
3770 | value = EmbedClassHandle->Get((DWORDLONG)handle); |
3771 | if (ppIndirection != nullptr) |
3772 | *ppIndirection = (void*)value.A; |
3773 | DEBUG_REP(dmpEmbedClassHandle((DWORDLONG)handle, value)); |
3774 | return (CORINFO_CLASS_HANDLE)value.B; |
3775 | } |
3776 | |
3777 | void MethodContext::recPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, |
3778 | CORINFO_SIG_INFO* callSiteSig, |
3779 | BOOL result) |
3780 | { |
3781 | if (PInvokeMarshalingRequired == nullptr) |
3782 | PInvokeMarshalingRequired = new LightWeightMap<PInvokeMarshalingRequiredValue, DWORD>(); |
3783 | |
3784 | PInvokeMarshalingRequiredValue key; |
3785 | ZeroMemory(&key, sizeof(PInvokeMarshalingRequiredValue)); // We use the input structs as a key and use memcmp to |
3786 | // compare.. so we need to zero out padding too |
3787 | |
3788 | key.method = (DWORDLONG)method; |
3789 | key.pSig_Index = (DWORD)PInvokeMarshalingRequired->AddBuffer((unsigned char*)callSiteSig->pSig, callSiteSig->cbSig); |
3790 | key.cbSig = (DWORD)callSiteSig->cbSig; |
3791 | key.scope = (DWORDLONG)callSiteSig->scope; |
3792 | |
3793 | PInvokeMarshalingRequired->Add(key, (DWORD)result); |
3794 | DEBUG_REC(dmpPInvokeMarshalingRequired(key, (DWORD)result)); |
3795 | } |
3796 | void MethodContext::dmpPInvokeMarshalingRequired(const PInvokeMarshalingRequiredValue& key, DWORD value) |
3797 | { |
3798 | printf("PInvokeMarshalingRequired key mth-%016llX scp-%016llX sig-%u, value res-%u" , key.method, key.scope, |
3799 | key.pSig_Index, value); |
3800 | } |
3801 | // Note the jit interface implementation seems to only care about scope and pSig from callSiteSig |
3802 | BOOL MethodContext::repPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) |
3803 | { |
3804 | if (PInvokeMarshalingRequired == nullptr) // so when we replay checked on free, we throw from lwm |
3805 | return TRUE; // TODO-Cleanup: hackish... |
3806 | |
3807 | PInvokeMarshalingRequiredValue key; |
3808 | ZeroMemory(&key, sizeof(PInvokeMarshalingRequiredValue)); // We use the input structs as a key and use memcmp to |
3809 | // compare.. so we need to zero out padding too |
3810 | |
3811 | key.method = (DWORDLONG)method; |
3812 | key.pSig_Index = (DWORD)PInvokeMarshalingRequired->Contains((unsigned char*)callSiteSig->pSig, callSiteSig->cbSig); |
3813 | key.cbSig = (DWORD)callSiteSig->cbSig; |
3814 | key.scope = (DWORDLONG)callSiteSig->scope; |
3815 | |
3816 | DWORD value = PInvokeMarshalingRequired->Get(key); |
3817 | DEBUG_REP(dmpPInvokeMarshalingRequired(key, value)); |
3818 | return value; |
3819 | } |
3820 | |
3821 | void MethodContext::recFindSig(CORINFO_MODULE_HANDLE module, |
3822 | unsigned sigTOK, |
3823 | CORINFO_CONTEXT_HANDLE context, |
3824 | CORINFO_SIG_INFO* sig) |
3825 | { |
3826 | if (FindSig == nullptr) |
3827 | FindSig = new LightWeightMap<Agnostic_FindSig, Agnostic_CORINFO_SIG_INFO>(); |
3828 | |
3829 | Agnostic_FindSig key; |
3830 | ZeroMemory(&key, sizeof(Agnostic_FindSig)); // We use the input structs as a key and use memcmp to compare.. so we |
3831 | // need to zero out padding too |
3832 | key.module = (DWORDLONG)module; |
3833 | key.sigTOK = (DWORD)sigTOK; |
3834 | key.context = (DWORDLONG)context; |
3835 | |
3836 | Agnostic_CORINFO_SIG_INFO value = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(*sig, FindSig); |
3837 | |
3838 | FindSig->Add(key, value); |
3839 | DEBUG_REC(dmpFindSig(key, value)); |
3840 | } |
3841 | void MethodContext::dmpFindSig(const Agnostic_FindSig& key, const Agnostic_CORINFO_SIG_INFO& value) |
3842 | { |
3843 | printf("FindSig key module-%016llX sigTOK-%08X context-%016llX" , key.module, key.sigTOK, key.context); |
3844 | printf(", value callConv-%08X retTypeClass-%016llX retTypeSigClass-%016llX retType-%u(%s) flags-%08X numArgs-%08X " |
3845 | "classInstCount-%08X classInd-%08X " |
3846 | "methInstCount-%08X methInd-%08X args-%016llX cbSig-%08X pSig_Index-%08X scope-%016llX token-%08X" , |
3847 | value.callConv, value.retTypeClass, value.retTypeSigClass, value.retType, |
3848 | toString((CorInfoType)value.retType), value.flags, value.numArgs, value.sigInst_classInstCount, |
3849 | value.sigInst_classInst_Index, value.sigInst_methInstCount, value.sigInst_methInst_Index, value.args, |
3850 | value.cbSig, value.pSig_Index, value.scope, value.token); |
3851 | } |
3852 | void MethodContext::repFindSig(CORINFO_MODULE_HANDLE module, |
3853 | unsigned sigTOK, |
3854 | CORINFO_CONTEXT_HANDLE context, |
3855 | CORINFO_SIG_INFO* sig) |
3856 | { |
3857 | Agnostic_FindSig key; |
3858 | ZeroMemory(&key, sizeof(Agnostic_FindSig)); // We use the input structs as a key and use memcmp to compare.. so we |
3859 | // need to zero out padding too |
3860 | Agnostic_CORINFO_SIG_INFO value; |
3861 | |
3862 | key.module = (DWORDLONG)module; |
3863 | key.sigTOK = (DWORD)sigTOK; |
3864 | key.context = (DWORDLONG)context; |
3865 | |
3866 | value = FindSig->Get(key); |
3867 | |
3868 | *sig = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value, FindSig); |
3869 | DEBUG_REP(dmpFindSig(key, value)); |
3870 | } |
3871 | |
3872 | void MethodContext::recGetEEInfo(CORINFO_EE_INFO* pEEInfoOut) |
3873 | { |
3874 | if (GetEEInfo == nullptr) |
3875 | GetEEInfo = new LightWeightMap<DWORD, Agnostic_CORINFO_EE_INFO>(); |
3876 | |
3877 | Agnostic_CORINFO_EE_INFO value; |
3878 | |
3879 | value.inlinedCallFrameInfo.size = (DWORD)pEEInfoOut->inlinedCallFrameInfo.size; |
3880 | value.inlinedCallFrameInfo.offsetOfGSCookie = (DWORD)pEEInfoOut->inlinedCallFrameInfo.offsetOfGSCookie; |
3881 | value.inlinedCallFrameInfo.offsetOfFrameVptr = (DWORD)pEEInfoOut->inlinedCallFrameInfo.offsetOfFrameVptr; |
3882 | value.inlinedCallFrameInfo.offsetOfFrameLink = (DWORD)pEEInfoOut->inlinedCallFrameInfo.offsetOfFrameLink; |
3883 | value.inlinedCallFrameInfo.offsetOfCallSiteSP = (DWORD)pEEInfoOut->inlinedCallFrameInfo.offsetOfCallSiteSP; |
3884 | value.inlinedCallFrameInfo.offsetOfCalleeSavedFP = (DWORD)pEEInfoOut->inlinedCallFrameInfo.offsetOfCalleeSavedFP; |
3885 | value.inlinedCallFrameInfo.offsetOfCallTarget = (DWORD)pEEInfoOut->inlinedCallFrameInfo.offsetOfCallTarget; |
3886 | value.inlinedCallFrameInfo.offsetOfReturnAddress = (DWORD)pEEInfoOut->inlinedCallFrameInfo.offsetOfReturnAddress; |
3887 | value.offsetOfThreadFrame = (DWORD)pEEInfoOut->offsetOfThreadFrame; |
3888 | value.offsetOfGCState = (DWORD)pEEInfoOut->offsetOfGCState; |
3889 | value.offsetOfDelegateInstance = (DWORD)pEEInfoOut->offsetOfDelegateInstance; |
3890 | value.offsetOfDelegateFirstTarget = (DWORD)pEEInfoOut->offsetOfDelegateFirstTarget; |
3891 | value.offsetOfSecureDelegateIndirectCell = (DWORD)pEEInfoOut->offsetOfSecureDelegateIndirectCell; |
3892 | value.offsetOfTransparentProxyRP = (DWORD)pEEInfoOut->offsetOfTransparentProxyRP; |
3893 | value.offsetOfRealProxyServer = (DWORD)pEEInfoOut->offsetOfRealProxyServer; |
3894 | value.offsetOfObjArrayData = (DWORD)pEEInfoOut->offsetOfObjArrayData; |
3895 | value.sizeOfReversePInvokeFrame = (DWORD)pEEInfoOut->sizeOfReversePInvokeFrame; |
3896 | value.osPageSize = (DWORD)pEEInfoOut->osPageSize; |
3897 | value.maxUncheckedOffsetForNullObject = (DWORD)pEEInfoOut->maxUncheckedOffsetForNullObject; |
3898 | value.targetAbi = (DWORD)pEEInfoOut->targetAbi; |
3899 | value.osType = (DWORD)pEEInfoOut->osType; |
3900 | value.osMajor = (DWORD)pEEInfoOut->osMajor; |
3901 | value.osMinor = (DWORD)pEEInfoOut->osMinor; |
3902 | value.osBuild = (DWORD)pEEInfoOut->osBuild; |
3903 | |
3904 | GetEEInfo->Add((DWORD)0, value); |
3905 | DEBUG_REC(dmpGetEEInfo((DWORD)0, value)); |
3906 | } |
3907 | void MethodContext::dmpGetEEInfo(DWORD key, const Agnostic_CORINFO_EE_INFO& value) |
3908 | { |
3909 | printf("GetEEInfo key %u, value icfi{sz-%u ogs-%u ofv-%u ofl-%u ocsp-%u ocsfp-%u oct-%u ora-%u} " |
3910 | "otf-%u ogcs-%u odi-%u odft-%u osdic-%u otrp-%u orps-%u ooad-%u srpf-%u osps-%u muono-%u tabi-%u osType-%u " |
3911 | "osMajor-%u osMinor-%u osBuild-%u" , |
3912 | key, value.inlinedCallFrameInfo.size, value.inlinedCallFrameInfo.offsetOfGSCookie, |
3913 | value.inlinedCallFrameInfo.offsetOfFrameVptr, value.inlinedCallFrameInfo.offsetOfFrameLink, |
3914 | value.inlinedCallFrameInfo.offsetOfCallSiteSP, value.inlinedCallFrameInfo.offsetOfCalleeSavedFP, |
3915 | value.inlinedCallFrameInfo.offsetOfCallTarget, value.inlinedCallFrameInfo.offsetOfReturnAddress, |
3916 | value.offsetOfThreadFrame, value.offsetOfGCState, value.offsetOfDelegateInstance, |
3917 | value.offsetOfDelegateFirstTarget, value.offsetOfSecureDelegateIndirectCell, |
3918 | value.offsetOfTransparentProxyRP, value.offsetOfRealProxyServer, value.offsetOfObjArrayData, |
3919 | value.sizeOfReversePInvokeFrame, value.osPageSize, value.maxUncheckedOffsetForNullObject, value.targetAbi, |
3920 | value.osType, value.osMajor, value.osMinor, value.osBuild); |
3921 | } |
3922 | void MethodContext::repGetEEInfo(CORINFO_EE_INFO* pEEInfoOut) |
3923 | { |
3924 | Agnostic_CORINFO_EE_INFO value; |
3925 | |
3926 | int index = -1; |
3927 | if (GetEEInfo != nullptr) |
3928 | index = GetEEInfo->GetIndex((DWORD)0); |
3929 | if (index >= 0) |
3930 | { |
3931 | value = GetEEInfo->Get((DWORD)0); |
3932 | pEEInfoOut->inlinedCallFrameInfo.size = (unsigned)value.inlinedCallFrameInfo.size; |
3933 | pEEInfoOut->inlinedCallFrameInfo.offsetOfGSCookie = (unsigned)value.inlinedCallFrameInfo.offsetOfGSCookie; |
3934 | pEEInfoOut->inlinedCallFrameInfo.offsetOfFrameVptr = (unsigned)value.inlinedCallFrameInfo.offsetOfFrameVptr; |
3935 | pEEInfoOut->inlinedCallFrameInfo.offsetOfFrameLink = (unsigned)value.inlinedCallFrameInfo.offsetOfFrameLink; |
3936 | pEEInfoOut->inlinedCallFrameInfo.offsetOfCallSiteSP = (unsigned)value.inlinedCallFrameInfo.offsetOfCallSiteSP; |
3937 | pEEInfoOut->inlinedCallFrameInfo.offsetOfCalleeSavedFP = |
3938 | (unsigned)value.inlinedCallFrameInfo.offsetOfCalleeSavedFP; |
3939 | pEEInfoOut->inlinedCallFrameInfo.offsetOfCallTarget = (unsigned)value.inlinedCallFrameInfo.offsetOfCallTarget; |
3940 | pEEInfoOut->inlinedCallFrameInfo.offsetOfReturnAddress = |
3941 | (unsigned)value.inlinedCallFrameInfo.offsetOfReturnAddress; |
3942 | pEEInfoOut->offsetOfThreadFrame = (unsigned)value.offsetOfThreadFrame; |
3943 | pEEInfoOut->offsetOfGCState = (unsigned)value.offsetOfGCState; |
3944 | pEEInfoOut->offsetOfDelegateInstance = (unsigned)value.offsetOfDelegateInstance; |
3945 | pEEInfoOut->offsetOfDelegateFirstTarget = (unsigned)value.offsetOfDelegateFirstTarget; |
3946 | pEEInfoOut->offsetOfSecureDelegateIndirectCell = (unsigned)value.offsetOfSecureDelegateIndirectCell; |
3947 | pEEInfoOut->offsetOfTransparentProxyRP = (unsigned)value.offsetOfTransparentProxyRP; |
3948 | pEEInfoOut->offsetOfRealProxyServer = (unsigned)value.offsetOfRealProxyServer; |
3949 | pEEInfoOut->offsetOfObjArrayData = (unsigned)value.offsetOfObjArrayData; |
3950 | pEEInfoOut->sizeOfReversePInvokeFrame = (unsigned)value.sizeOfReversePInvokeFrame; |
3951 | pEEInfoOut->osPageSize = (size_t)value.osPageSize; |
3952 | pEEInfoOut->maxUncheckedOffsetForNullObject = (size_t)value.maxUncheckedOffsetForNullObject; |
3953 | pEEInfoOut->targetAbi = (CORINFO_RUNTIME_ABI)value.targetAbi; |
3954 | pEEInfoOut->osType = (CORINFO_OS)value.osType; |
3955 | pEEInfoOut->osMajor = (unsigned)value.osMajor; |
3956 | pEEInfoOut->osMinor = (unsigned)value.osMinor; |
3957 | pEEInfoOut->osBuild = (unsigned)value.osBuild; |
3958 | DEBUG_REP(dmpGetEEInfo((DWORD)0, value)); |
3959 | } |
3960 | else |
3961 | { |
3962 | pEEInfoOut->inlinedCallFrameInfo.size = (unsigned)0x40; |
3963 | pEEInfoOut->inlinedCallFrameInfo.offsetOfGSCookie = (unsigned)0; |
3964 | pEEInfoOut->inlinedCallFrameInfo.offsetOfFrameVptr = (unsigned)0x8; |
3965 | pEEInfoOut->inlinedCallFrameInfo.offsetOfFrameLink = (unsigned)0x10; |
3966 | pEEInfoOut->inlinedCallFrameInfo.offsetOfCallSiteSP = (unsigned)0x28; |
3967 | pEEInfoOut->inlinedCallFrameInfo.offsetOfCalleeSavedFP = (unsigned)0x38; |
3968 | pEEInfoOut->inlinedCallFrameInfo.offsetOfCallTarget = (unsigned)0x18; |
3969 | pEEInfoOut->inlinedCallFrameInfo.offsetOfReturnAddress = (unsigned)0x30; |
3970 | pEEInfoOut->offsetOfThreadFrame = (unsigned)0x10; |
3971 | pEEInfoOut->offsetOfGCState = (unsigned)0xc; |
3972 | pEEInfoOut->offsetOfDelegateInstance = (unsigned)0x8; |
3973 | pEEInfoOut->offsetOfDelegateFirstTarget = (unsigned)0x18; |
3974 | pEEInfoOut->offsetOfSecureDelegateIndirectCell = (unsigned)0x40; |
3975 | pEEInfoOut->offsetOfTransparentProxyRP = (unsigned)0x8; |
3976 | pEEInfoOut->offsetOfRealProxyServer = (unsigned)0x18; |
3977 | pEEInfoOut->offsetOfObjArrayData = (unsigned)0x18; |
3978 | pEEInfoOut->sizeOfReversePInvokeFrame = (unsigned)0x8; |
3979 | pEEInfoOut->osPageSize = (size_t)0x1000; |
3980 | pEEInfoOut->maxUncheckedOffsetForNullObject = (size_t)((32 * 1024) - 1); |
3981 | pEEInfoOut->targetAbi = CORINFO_DESKTOP_ABI; |
3982 | pEEInfoOut->osType = (CORINFO_OS)0; |
3983 | pEEInfoOut->osMajor = (unsigned)0; |
3984 | pEEInfoOut->osMinor = (unsigned)0; |
3985 | pEEInfoOut->osBuild = (unsigned)0; |
3986 | } |
3987 | } |
3988 | |
3989 | void MethodContext::recGetGSCookie(GSCookie* pCookieVal, GSCookie** ppCookieVal) |
3990 | { |
3991 | if (GetGSCookie == nullptr) |
3992 | GetGSCookie = new LightWeightMap<DWORD, DLDL>(); |
3993 | |
3994 | DLDL value; |
3995 | |
3996 | if (pCookieVal != nullptr) |
3997 | value.A = (DWORDLONG)*pCookieVal; |
3998 | else |
3999 | value.A = (DWORDLONG)0; |
4000 | |
4001 | if (ppCookieVal != nullptr) |
4002 | value.B = (DWORDLONG)*ppCookieVal; |
4003 | else |
4004 | value.B = (DWORDLONG)0; |
4005 | GetGSCookie->Add((DWORD)0, value); |
4006 | } |
4007 | void MethodContext::dmpGetGSCookie(DWORD key, DLDL value) |
4008 | { |
4009 | printf("GetGSCookie key 0, value pCookieVal-%016llX ppCookieVal-%016llX" , value.A, value.B); |
4010 | } |
4011 | void MethodContext::repGetGSCookie(GSCookie* pCookieVal, GSCookie** ppCookieVal) |
4012 | { |
4013 | DLDL value; |
4014 | |
4015 | value = GetGSCookie->Get((DWORD)0); |
4016 | |
4017 | if (pCookieVal != nullptr) |
4018 | *pCookieVal = (GSCookie)value.A; |
4019 | if (ppCookieVal != nullptr) |
4020 | *ppCookieVal = (GSCookie*)value.B; |
4021 | } |
4022 | |
4023 | void MethodContext::recGetClassModuleIdForStatics(CORINFO_CLASS_HANDLE cls, |
4024 | CORINFO_MODULE_HANDLE* pModule, |
4025 | void** ppIndirection, |
4026 | size_t result) |
4027 | { |
4028 | if (GetClassModuleIdForStatics == nullptr) |
4029 | GetClassModuleIdForStatics = new LightWeightMap<DWORDLONG, Agnostic_GetClassModuleIdForStatics>(); |
4030 | |
4031 | Agnostic_GetClassModuleIdForStatics value; |
4032 | |
4033 | if (pModule != nullptr) |
4034 | value.Module = (DWORDLONG)*pModule; |
4035 | else |
4036 | value.Module = (DWORDLONG)0; |
4037 | if (ppIndirection != nullptr) |
4038 | value.pIndirection = (DWORDLONG)*ppIndirection; |
4039 | else |
4040 | value.pIndirection = (DWORDLONG)0; |
4041 | value.result = (DWORDLONG)result; |
4042 | GetClassModuleIdForStatics->Add((DWORDLONG)cls, value); |
4043 | } |
4044 | void MethodContext::dmpGetClassModuleIdForStatics(DWORDLONG key, const Agnostic_GetClassModuleIdForStatics& value) |
4045 | { |
4046 | printf("GetClassModuleIdForStatics key cls-%016llX, value mod-%016llX pp-%016llX res-%016llX" , key, value.Module, |
4047 | value.pIndirection, value.result); |
4048 | } |
4049 | size_t MethodContext::repGetClassModuleIdForStatics(CORINFO_CLASS_HANDLE cls, |
4050 | CORINFO_MODULE_HANDLE* pModule, |
4051 | void** ppIndirection) |
4052 | { |
4053 | Agnostic_GetClassModuleIdForStatics value; |
4054 | |
4055 | value = GetClassModuleIdForStatics->Get((DWORDLONG)cls); |
4056 | |
4057 | if (pModule != nullptr) |
4058 | *pModule = (CORINFO_MODULE_HANDLE)value.Module; |
4059 | if (ppIndirection != nullptr) |
4060 | *ppIndirection = (void*)value.pIndirection; |
4061 | |
4062 | return (size_t)value.result; |
4063 | } |
4064 | |
4065 | void MethodContext::recGetThreadTLSIndex(void** ppIndirection, DWORD result) |
4066 | { |
4067 | if (GetThreadTLSIndex == nullptr) |
4068 | GetThreadTLSIndex = new LightWeightMap<DWORD, DLD>(); |
4069 | |
4070 | DLD value; |
4071 | |
4072 | if (ppIndirection != nullptr) |
4073 | value.A = (DWORDLONG)*ppIndirection; |
4074 | else |
4075 | value.A = (DWORDLONG)0; |
4076 | value.B = (DWORD)result; |
4077 | |
4078 | GetThreadTLSIndex->Add((DWORD)0, value); |
4079 | } |
4080 | void MethodContext::dmpGetThreadTLSIndex(DWORD key, DLD value) |
4081 | { |
4082 | printf("GetThreadTLSIndex key 0, value ppIndirection-%016llX result-%08X" , value.A, value.B); |
4083 | } |
4084 | DWORD MethodContext::repGetThreadTLSIndex(void** ppIndirection) |
4085 | { |
4086 | DLD value; |
4087 | |
4088 | value = GetThreadTLSIndex->Get((DWORD)0); |
4089 | |
4090 | if (ppIndirection != nullptr) |
4091 | *ppIndirection = (void*)value.A; |
4092 | return (DWORD)value.B; |
4093 | } |
4094 | |
4095 | void MethodContext::recGetInlinedCallFrameVptr(void** ppIndirection, const void* result) |
4096 | { |
4097 | if (GetInlinedCallFrameVptr == nullptr) |
4098 | GetInlinedCallFrameVptr = new LightWeightMap<DWORD, DLDL>(); |
4099 | |
4100 | DLDL value; |
4101 | |
4102 | if (ppIndirection != nullptr) |
4103 | value.A = (DWORDLONG)*ppIndirection; |
4104 | else |
4105 | value.A = (DWORDLONG)0; |
4106 | value.B = (DWORDLONG)result; |
4107 | |
4108 | GetInlinedCallFrameVptr->Add((DWORD)0, value); |
4109 | } |
4110 | void MethodContext::dmpGetInlinedCallFrameVptr(DWORD key, DLDL value) |
4111 | { |
4112 | printf("GetInlinedCallFrameVptr key 0, value ppIndirection-%016llX result-%016llX" , value.A, value.B); |
4113 | } |
4114 | const void* MethodContext::repGetInlinedCallFrameVptr(void** ppIndirection) |
4115 | { |
4116 | DLDL value; |
4117 | |
4118 | value = GetInlinedCallFrameVptr->Get((DWORD)0); |
4119 | |
4120 | if (ppIndirection != nullptr) |
4121 | *ppIndirection = (void*)value.A; |
4122 | return (const void*)value.B; |
4123 | } |
4124 | |
4125 | void MethodContext::recGetAddrOfCaptureThreadGlobal(void** ppIndirection, LONG* result) |
4126 | { |
4127 | if (GetAddrOfCaptureThreadGlobal == nullptr) |
4128 | GetAddrOfCaptureThreadGlobal = new LightWeightMap<DWORD, DLDL>(); |
4129 | |
4130 | DLDL value; |
4131 | |
4132 | if (ppIndirection != nullptr) |
4133 | value.A = (DWORDLONG)*ppIndirection; |
4134 | else |
4135 | value.A = (DWORDLONG)0; |
4136 | value.B = (DWORDLONG)result; |
4137 | |
4138 | GetAddrOfCaptureThreadGlobal->Add((DWORD)0, value); |
4139 | DEBUG_REC(dmpGetAddrOfCaptureThreadGlobal((DWORD)0, value)); |
4140 | } |
4141 | void MethodContext::dmpGetAddrOfCaptureThreadGlobal(DWORD key, DLDL value) |
4142 | { |
4143 | printf("GetAddrOfCaptureThreadGlobal key %u, value ppi-%016llX res-%016llX" , key, value.A, value.B); |
4144 | } |
4145 | LONG* MethodContext::repGetAddrOfCaptureThreadGlobal(void** ppIndirection) |
4146 | { |
4147 | DLDL value; |
4148 | |
4149 | if ((GetAddrOfCaptureThreadGlobal == nullptr) || (GetAddrOfCaptureThreadGlobal->GetIndex((DWORD)0) == -1)) |
4150 | { |
4151 | #ifdef sparseMC |
4152 | LogDebug("Sparse - repGetAddrOfCaptureThreadGlobal returning 0xCAFE0001" ); |
4153 | return (LONG*)(size_t)0xCAFE0001; |
4154 | #else |
4155 | LogException(EXCEPTIONCODE_MC, "Didn't find anything for GetAddrOfCaptureThreadGlobal" , "" ); |
4156 | #endif |
4157 | } |
4158 | value = GetAddrOfCaptureThreadGlobal->Get((DWORD)0); |
4159 | |
4160 | if (ppIndirection != nullptr) |
4161 | *ppIndirection = (void*)value.A; |
4162 | DEBUG_REP(dmpGetAddrOfCaptureThreadGlobal((DWORD)0, value)); |
4163 | return (LONG*)value.B; |
4164 | } |
4165 | |
4166 | void MethodContext::recGetClassDomainID(CORINFO_CLASS_HANDLE cls, void** ppIndirection, unsigned result) |
4167 | { |
4168 | if (GetClassDomainID == nullptr) |
4169 | GetClassDomainID = new LightWeightMap<DWORDLONG, DLD>(); |
4170 | |
4171 | DLD value; |
4172 | |
4173 | if (ppIndirection != nullptr) |
4174 | value.A = (DWORDLONG)*ppIndirection; |
4175 | else |
4176 | value.A = (DWORDLONG)0; |
4177 | value.B = (DWORD)result; |
4178 | |
4179 | GetClassDomainID->Add((DWORDLONG)cls, value); |
4180 | DEBUG_REC(dmpGetClassDomainID((DWORDLONG)cls, value)); |
4181 | } |
4182 | void MethodContext::dmpGetClassDomainID(DWORDLONG key, DLD value) |
4183 | { |
4184 | printf("GetClassDomainID key cls-%016llX, value pp-%016llX res-%u" , key, value.A, value.B); |
4185 | } |
4186 | unsigned MethodContext::repGetClassDomainID(CORINFO_CLASS_HANDLE cls, void** ppIndirection) |
4187 | { |
4188 | DLD value; |
4189 | |
4190 | AssertCodeMsg(GetClassDomainID != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , (DWORDLONG)cls); |
4191 | AssertCodeMsg(GetClassDomainID->GetIndex((DWORDLONG)cls) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
4192 | (DWORDLONG)cls); |
4193 | value = GetClassDomainID->Get((DWORDLONG)cls); |
4194 | if (ppIndirection != nullptr) |
4195 | *ppIndirection = (void*)value.A; |
4196 | DEBUG_REP(dmpGetClassDomainID((DWORDLONG)cls, value)); |
4197 | return (unsigned)value.B; |
4198 | } |
4199 | |
4200 | void MethodContext::recGetLocationOfThisType(CORINFO_METHOD_HANDLE context, CORINFO_LOOKUP_KIND* result) |
4201 | { |
4202 | if (GetLocationOfThisType == nullptr) |
4203 | GetLocationOfThisType = new LightWeightMap<DWORDLONG, Agnostic_CORINFO_LOOKUP_KIND>(); |
4204 | |
4205 | Agnostic_CORINFO_LOOKUP_KIND value = SpmiRecordsHelper::CreateAgnostic_CORINFO_LOOKUP_KIND(result); |
4206 | GetLocationOfThisType->Add((DWORDLONG)context, value); |
4207 | } |
4208 | void MethodContext::dmpGetLocationOfThisType(DWORDLONG key, const Agnostic_CORINFO_LOOKUP_KIND& value) |
4209 | { |
4210 | printf("GetLocationOfThisType key ftn-%016llX, value %s" , key, |
4211 | SpmiDumpHelper::DumpAgnostic_CORINFO_LOOKUP_KIND(value).c_str()); |
4212 | } |
4213 | CORINFO_LOOKUP_KIND MethodContext::repGetLocationOfThisType(CORINFO_METHOD_HANDLE context) |
4214 | { |
4215 | Agnostic_CORINFO_LOOKUP_KIND value = GetLocationOfThisType->Get((DWORDLONG)context); |
4216 | return SpmiRecordsHelper::RestoreCORINFO_LOOKUP_KIND(value); |
4217 | } |
4218 | |
4219 | void MethodContext::recGetDelegateCtor(CORINFO_METHOD_HANDLE methHnd, |
4220 | CORINFO_CLASS_HANDLE clsHnd, |
4221 | CORINFO_METHOD_HANDLE targetMethodHnd, |
4222 | DelegateCtorArgs* pCtorData, |
4223 | CORINFO_METHOD_HANDLE result) |
4224 | { |
4225 | if (GetDelegateCtor == nullptr) |
4226 | GetDelegateCtor = new LightWeightMap<Agnostic_GetDelegateCtorIn, Agnostic_GetDelegateCtorOut>(); |
4227 | |
4228 | Agnostic_GetDelegateCtorIn key; |
4229 | ZeroMemory(&key, sizeof(Agnostic_GetDelegateCtorIn)); // We use the input structs as a key and use memcmp to |
4230 | // compare.. so we need to zero out padding too |
4231 | Agnostic_GetDelegateCtorOut value; |
4232 | |
4233 | key.methHnd = (DWORDLONG)methHnd; |
4234 | key.clsHnd = (DWORDLONG)clsHnd; |
4235 | key.targetMethodHnd = (DWORDLONG)targetMethodHnd; |
4236 | |
4237 | value.CtorData.pMethod = (DWORDLONG)pCtorData->pMethod; |
4238 | value.CtorData.pArg3 = (DWORDLONG)pCtorData->pArg3; |
4239 | value.CtorData.pArg4 = (DWORDLONG)pCtorData->pArg4; |
4240 | value.CtorData.pArg5 = (DWORDLONG)pCtorData->pArg5; |
4241 | value.result = (DWORDLONG)result; |
4242 | |
4243 | GetDelegateCtor->Add(key, value); |
4244 | DEBUG_REC(dmpGetDelegateCtor(key, value)); |
4245 | } |
4246 | void MethodContext::dmpGetDelegateCtor(const Agnostic_GetDelegateCtorIn& key, const Agnostic_GetDelegateCtorOut& value) |
4247 | { |
4248 | printf("GetDelegateCtor key ftn-%016llX cls-%016llX tftn-%016llX, value pm-%016llX a3-%016llX a4-%016llX " |
4249 | "a5-%016llX res-%016llX" , |
4250 | key.methHnd, key.clsHnd, key.targetMethodHnd, value.CtorData.pMethod, value.CtorData.pArg3, |
4251 | value.CtorData.pArg4, value.CtorData.pArg5, value.result); |
4252 | } |
4253 | CORINFO_METHOD_HANDLE MethodContext::repGetDelegateCtor(CORINFO_METHOD_HANDLE methHnd, |
4254 | CORINFO_CLASS_HANDLE clsHnd, |
4255 | CORINFO_METHOD_HANDLE targetMethodHnd, |
4256 | DelegateCtorArgs* pCtorData) |
4257 | { |
4258 | Agnostic_GetDelegateCtorIn key; |
4259 | ZeroMemory(&key, sizeof(Agnostic_GetDelegateCtorIn)); // We use the input structs as a key and use memcmp to |
4260 | // compare.. so we need to zero out padding too |
4261 | Agnostic_GetDelegateCtorOut value; |
4262 | |
4263 | key.methHnd = (DWORDLONG)methHnd; |
4264 | key.clsHnd = (DWORDLONG)clsHnd; |
4265 | key.targetMethodHnd = (DWORDLONG)targetMethodHnd; |
4266 | |
4267 | AssertCodeMsg(GetDelegateCtor != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , |
4268 | (DWORDLONG)key.methHnd); |
4269 | AssertCodeMsg(GetDelegateCtor->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
4270 | (DWORDLONG)key.methHnd); |
4271 | value = GetDelegateCtor->Get(key); |
4272 | |
4273 | pCtorData->pMethod = (void*)value.CtorData.pMethod; |
4274 | pCtorData->pArg3 = (void*)value.CtorData.pArg3; |
4275 | pCtorData->pArg4 = (void*)value.CtorData.pArg4; |
4276 | pCtorData->pArg5 = (void*)value.CtorData.pArg5; |
4277 | DEBUG_REP(dmpGetDelegateCtor(key, value)); |
4278 | return (CORINFO_METHOD_HANDLE)value.result; |
4279 | } |
4280 | |
4281 | void MethodContext::recGetFunctionFixedEntryPoint(CORINFO_METHOD_HANDLE ftn, CORINFO_CONST_LOOKUP* pResult) |
4282 | { |
4283 | if (GetFunctionFixedEntryPoint == nullptr) |
4284 | GetFunctionFixedEntryPoint = new LightWeightMap<DWORDLONG, Agnostic_CORINFO_CONST_LOOKUP>(); |
4285 | |
4286 | Agnostic_CORINFO_CONST_LOOKUP value = SpmiRecordsHelper::StoreAgnostic_CORINFO_CONST_LOOKUP(pResult); |
4287 | |
4288 | GetFunctionFixedEntryPoint->Add((DWORDLONG)ftn, value); |
4289 | } |
4290 | void MethodContext::dmpGetFunctionFixedEntryPoint(DWORDLONG key, const Agnostic_CORINFO_CONST_LOOKUP& value) |
4291 | { |
4292 | printf("GetFunctionFixedEntryPoint key ftn-%016llX, value %s" , key, |
4293 | SpmiDumpHelper::DumpAgnostic_CORINFO_CONST_LOOKUP(value).c_str()); |
4294 | } |
4295 | void MethodContext::repGetFunctionFixedEntryPoint(CORINFO_METHOD_HANDLE ftn, CORINFO_CONST_LOOKUP* pResult) |
4296 | { |
4297 | Agnostic_CORINFO_CONST_LOOKUP value; |
4298 | |
4299 | value = GetFunctionFixedEntryPoint->Get((DWORDLONG)ftn); |
4300 | |
4301 | *pResult = SpmiRecordsHelper::RestoreCORINFO_CONST_LOOKUP(value); |
4302 | } |
4303 | |
4304 | void MethodContext::recGetFieldInClass(CORINFO_CLASS_HANDLE clsHnd, INT num, CORINFO_FIELD_HANDLE result) |
4305 | { |
4306 | if (GetFieldInClass == nullptr) |
4307 | GetFieldInClass = new LightWeightMap<DLD, DWORDLONG>(); |
4308 | |
4309 | DLD key; |
4310 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
4311 | // out padding too |
4312 | |
4313 | key.A = (DWORDLONG)clsHnd; |
4314 | key.B = (DWORD)num; |
4315 | |
4316 | GetFieldInClass->Add(key, (DWORDLONG)result); |
4317 | DEBUG_REC(dmpGetFieldInClass(key, (DWORDLONG)result)); |
4318 | } |
4319 | void MethodContext::dmpGetFieldInClass(DLD key, DWORDLONG value) |
4320 | { |
4321 | printf("GetFieldInClass key cls-%016llX ind-%u, value %016llX" , key.A, key.B, value); |
4322 | } |
4323 | CORINFO_FIELD_HANDLE MethodContext::repGetFieldInClass(CORINFO_CLASS_HANDLE clsHnd, INT num) |
4324 | { |
4325 | DLD key; |
4326 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
4327 | // out padding too |
4328 | |
4329 | key.A = (DWORDLONG)clsHnd; |
4330 | key.B = (DWORD)num; |
4331 | |
4332 | AssertCodeMsg((GetFieldInClass != nullptr) && (GetFieldInClass->GetIndex(key) != -1), EXCEPTIONCODE_MC, |
4333 | "Didn't find %016llX" , (DWORDLONG)key.A); |
4334 | CORINFO_FIELD_HANDLE temp = (CORINFO_FIELD_HANDLE)GetFieldInClass->Get(key); |
4335 | |
4336 | DEBUG_REP(dmpGetFieldInClass(key, (DWORDLONG)temp)); |
4337 | return temp; |
4338 | } |
4339 | |
4340 | void MethodContext::recGetFieldType(CORINFO_FIELD_HANDLE field, |
4341 | CORINFO_CLASS_HANDLE* structType, |
4342 | CORINFO_CLASS_HANDLE memberParent, |
4343 | CorInfoType result) |
4344 | { |
4345 | if (GetFieldType == nullptr) |
4346 | GetFieldType = new LightWeightMap<DLDL, DLD>(); |
4347 | |
4348 | DLDL key; |
4349 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
4350 | // out padding too |
4351 | DLD value; |
4352 | |
4353 | key.A = (DWORDLONG)field; |
4354 | key.B = (DWORDLONG)memberParent; |
4355 | |
4356 | if (structType == nullptr) |
4357 | { |
4358 | value.A = 0; |
4359 | } |
4360 | else |
4361 | { |
4362 | value.A = (DWORDLONG)*structType; |
4363 | } |
4364 | value.B = (DWORD)result; |
4365 | |
4366 | GetFieldType->Add(key, value); |
4367 | DEBUG_REC(dmpGetFieldType(key, value)); |
4368 | } |
4369 | void MethodContext::dmpGetFieldType(DLDL key, DLD value) |
4370 | { |
4371 | printf("GetFieldType key fld-%016llX cls-%016llX, value ch-%016llX cit-%u(%s)" , key.A, key.B, value.A, value.B, |
4372 | toString((CorInfoType)value.B)); |
4373 | } |
4374 | CorInfoType MethodContext::repGetFieldType(CORINFO_FIELD_HANDLE field, |
4375 | CORINFO_CLASS_HANDLE* structType, |
4376 | CORINFO_CLASS_HANDLE memberParent) |
4377 | { |
4378 | DLDL key; |
4379 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
4380 | // out padding too |
4381 | DLD value; |
4382 | |
4383 | key.A = (DWORDLONG)field; |
4384 | key.B = (DWORDLONG)memberParent; |
4385 | |
4386 | AssertCodeMsg(GetFieldType != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , (DWORDLONG)key.A); |
4387 | AssertCodeMsg(GetFieldType->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , (DWORDLONG)key.A); |
4388 | value = GetFieldType->Get(key); |
4389 | |
4390 | if (structType != nullptr) |
4391 | *structType = (CORINFO_CLASS_HANDLE)value.A; |
4392 | |
4393 | DEBUG_REP(dmpGetFieldType(key, value)); |
4394 | return (CorInfoType)value.B; |
4395 | } |
4396 | |
4397 | void MethodContext::recGetFieldName(CORINFO_FIELD_HANDLE ftn, const char** moduleName, const char* result) |
4398 | { |
4399 | if (GetFieldName == nullptr) |
4400 | GetFieldName = new LightWeightMap<DWORDLONG, DD>(); |
4401 | |
4402 | DD value; |
4403 | |
4404 | if (result != nullptr) |
4405 | value.A = GetFieldName->AddBuffer((unsigned char*)result, (DWORD)strlen(result) + 1); |
4406 | else |
4407 | value.A = (DWORD)-1; |
4408 | |
4409 | if ((moduleName != nullptr) && (*moduleName != nullptr)) // protect strlen |
4410 | value.B = (DWORD)GetFieldName->AddBuffer((unsigned char*)*moduleName, (DWORD)strlen(*moduleName) + 1); |
4411 | else |
4412 | value.B = (DWORD)-1; |
4413 | |
4414 | GetFieldName->Add((DWORDLONG)ftn, value); |
4415 | } |
4416 | void MethodContext::dmpGetFieldName(DWORDLONG key, DD value) |
4417 | { |
4418 | unsigned char* fieldName = (unsigned char*)GetFieldName->GetBuffer(value.A); |
4419 | unsigned char* moduleName = (unsigned char*)GetFieldName->GetBuffer(value.B); |
4420 | printf("GetFieldName key - ftn-%016llX, value fld-'%s', mod-'%s'" , key, fieldName, moduleName); |
4421 | GetFieldName->Unlock(); |
4422 | } |
4423 | const char* MethodContext::repGetFieldName(CORINFO_FIELD_HANDLE ftn, const char** moduleName) |
4424 | { |
4425 | DD value; |
4426 | if (GetFieldName == nullptr) |
4427 | { |
4428 | if (moduleName != nullptr) |
4429 | *moduleName = "hackishModuleName" ; |
4430 | return "hackishFieldName" ; |
4431 | } |
4432 | value = GetFieldName->Get((DWORDLONG)ftn); |
4433 | if (moduleName != nullptr) |
4434 | *moduleName = (const char*)GetFieldName->GetBuffer(value.B); |
4435 | return (const char*)GetFieldName->GetBuffer(value.A); |
4436 | } |
4437 | |
4438 | void MethodContext::recCanInlineTypeCheck(CORINFO_CLASS_HANDLE cls, |
4439 | CorInfoInlineTypeCheckSource source, |
4440 | CorInfoInlineTypeCheck result) |
4441 | { |
4442 | if (CanInlineTypeCheck == nullptr) |
4443 | CanInlineTypeCheck = new LightWeightMap<DLD, DWORD>(); |
4444 | |
4445 | DLD key; |
4446 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
4447 | // out padding too |
4448 | |
4449 | key.A = (DWORDLONG)cls; |
4450 | key.B = (DWORD)source; |
4451 | |
4452 | CanInlineTypeCheck->Add(key, (DWORD)result); |
4453 | } |
4454 | void MethodContext::dmpCanInlineTypeCheck(DLD key, DWORD value) |
4455 | { |
4456 | printf("CanInlineTypeCheck key cls-%016llX src-%08X, value res-%u" , key.A, key.B, value); |
4457 | } |
4458 | CorInfoInlineTypeCheck MethodContext::repCanInlineTypeCheck(CORINFO_CLASS_HANDLE cls, |
4459 | CorInfoInlineTypeCheckSource source) |
4460 | { |
4461 | AssertCodeMsg(CanInlineTypeCheck != nullptr, EXCEPTIONCODE_MC, "No map for CanInlineTypeCheck" ); |
4462 | |
4463 | DLD key; |
4464 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
4465 | // out padding too |
4466 | |
4467 | key.A = (DWORDLONG)cls; |
4468 | key.B = (DWORD)source; |
4469 | |
4470 | return (CorInfoInlineTypeCheck)CanInlineTypeCheck->Get(key); |
4471 | } |
4472 | |
4473 | void MethodContext::recCanInlineTypeCheckWithObjectVTable(CORINFO_CLASS_HANDLE cls, BOOL result) |
4474 | { |
4475 | if (CanInlineTypeCheckWithObjectVTable == nullptr) |
4476 | CanInlineTypeCheckWithObjectVTable = new LightWeightMap<DWORDLONG, DWORD>(); |
4477 | |
4478 | CanInlineTypeCheckWithObjectVTable->Add((DWORDLONG)cls, (DWORD)result); |
4479 | } |
4480 | void MethodContext::dmpCanInlineTypeCheckWithObjectVTable(DWORDLONG key, DWORD value) |
4481 | { |
4482 | printf("CanInlineTypeCheckWithObjectVTable key cls-%016llX, value res-%u" , key, value); |
4483 | } |
4484 | BOOL MethodContext::repCanInlineTypeCheckWithObjectVTable(CORINFO_CLASS_HANDLE cls) |
4485 | { |
4486 | AssertCodeMsg(CanInlineTypeCheckWithObjectVTable != nullptr, EXCEPTIONCODE_MC, |
4487 | "No map for CanInlineTypeCheckWithObjectVTable" ); |
4488 | return (BOOL)CanInlineTypeCheckWithObjectVTable->Get((DWORDLONG)cls); |
4489 | } |
4490 | |
4491 | void MethodContext::recSatisfiesMethodConstraints(CORINFO_CLASS_HANDLE parent, |
4492 | CORINFO_METHOD_HANDLE method, |
4493 | BOOL result) |
4494 | { |
4495 | if (SatisfiesMethodConstraints == nullptr) |
4496 | SatisfiesMethodConstraints = new LightWeightMap<DLDL, DWORD>(); |
4497 | |
4498 | DLDL key; |
4499 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
4500 | // out padding too |
4501 | |
4502 | key.A = (DWORDLONG)parent; |
4503 | key.B = (DWORDLONG)method; |
4504 | |
4505 | SatisfiesMethodConstraints->Add(key, (DWORD)result); |
4506 | } |
4507 | void MethodContext::dmpSatisfiesMethodConstraints(DLDL key, DWORD value) |
4508 | { |
4509 | printf("SatisfiesMethodConstraints key cls-%016llX ftn-%016llX, value res-%u" , key.A, key.B, value); |
4510 | } |
4511 | BOOL MethodContext::repSatisfiesMethodConstraints(CORINFO_CLASS_HANDLE parent, CORINFO_METHOD_HANDLE method) |
4512 | { |
4513 | DLDL key; |
4514 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
4515 | // out padding too |
4516 | |
4517 | key.A = (DWORDLONG)parent; |
4518 | key.B = (DWORDLONG)method; |
4519 | |
4520 | BOOL value = (BOOL)SatisfiesMethodConstraints->Get(key); |
4521 | return value; |
4522 | } |
4523 | |
4524 | void MethodContext::recInitConstraintsForVerification(CORINFO_METHOD_HANDLE method, |
4525 | BOOL* pfHasCircularClassConstraints, |
4526 | BOOL* pfHasCircularMethodConstraint) |
4527 | { |
4528 | if (InitConstraintsForVerification == nullptr) |
4529 | InitConstraintsForVerification = new LightWeightMap<DWORDLONG, DD>(); |
4530 | |
4531 | DD value; |
4532 | |
4533 | value.A = (DWORD)*pfHasCircularClassConstraints; |
4534 | value.B = (DWORD)*pfHasCircularMethodConstraint; |
4535 | |
4536 | InitConstraintsForVerification->Add((DWORDLONG)method, value); |
4537 | } |
4538 | void MethodContext::dmpInitConstraintsForVerification(DWORDLONG key, DD value) |
4539 | { |
4540 | printf("InitConstraintsForVerification key ftn-%016llX, value circ-%u cirm-%u" , key, value.A, value.B); |
4541 | } |
4542 | void MethodContext::repInitConstraintsForVerification(CORINFO_METHOD_HANDLE method, |
4543 | BOOL* pfHasCircularClassConstraints, |
4544 | BOOL* pfHasCircularMethodConstraint) |
4545 | { |
4546 | DD value; |
4547 | |
4548 | value = InitConstraintsForVerification->Get((DWORDLONG)method); |
4549 | |
4550 | *pfHasCircularClassConstraints = (BOOL)value.A; |
4551 | *pfHasCircularMethodConstraint = (BOOL)value.B; |
4552 | } |
4553 | |
4554 | void MethodContext::recIsValidStringRef(CORINFO_MODULE_HANDLE module, unsigned metaTOK, BOOL result) |
4555 | { |
4556 | if (IsValidStringRef == nullptr) |
4557 | IsValidStringRef = new LightWeightMap<DLD, DWORD>(); |
4558 | |
4559 | DLD key; |
4560 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
4561 | // out padding too |
4562 | |
4563 | key.A = (DWORDLONG)module; |
4564 | key.B = (DWORD)metaTOK; |
4565 | |
4566 | IsValidStringRef->Add(key, (DWORD)result); |
4567 | } |
4568 | void MethodContext::dmpIsValidStringRef(DLD key, DWORD value) |
4569 | { |
4570 | printf("IsValidStringRef key mod-%016llX tok-%08X, value res-%u" , key.A, key.B, value); |
4571 | } |
4572 | BOOL MethodContext::repIsValidStringRef(CORINFO_MODULE_HANDLE module, unsigned metaTOK) |
4573 | { |
4574 | DLD key; |
4575 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
4576 | // out padding too |
4577 | |
4578 | key.A = (DWORDLONG)module; |
4579 | key.B = (DWORD)metaTOK; |
4580 | |
4581 | BOOL value = (BOOL)IsValidStringRef->Get(key); |
4582 | return value; |
4583 | } |
4584 | |
4585 | void MethodContext::recGetHelperName(CorInfoHelpFunc funcNum, const char* result) |
4586 | { |
4587 | if (GetHelperName == nullptr) |
4588 | GetHelperName = new LightWeightMap<DWORD, DWORD>(); |
4589 | |
4590 | DWORD value = (DWORD)-1; |
4591 | if (result != nullptr) |
4592 | value = (DWORD)GetHelperName->AddBuffer((unsigned char*)result, (DWORD)strlen(result) + 1); |
4593 | |
4594 | GetHelperName->Add((DWORD)funcNum, value); |
4595 | DEBUG_REC(dmpGetHelperName((DWORD)funcNum, value)); |
4596 | } |
4597 | void MethodContext::dmpGetHelperName(DWORD key, DWORD value) |
4598 | { |
4599 | printf("GetHelperName key ftn-%u, value '%s'" , key, (const char*)GetHelperName->GetBuffer(value)); |
4600 | GetHelperName->Unlock(); |
4601 | } |
4602 | const char* MethodContext::repGetHelperName(CorInfoHelpFunc funcNum) |
4603 | { |
4604 | if (GetHelperName == nullptr) |
4605 | return "Yickish helper name" ; |
4606 | |
4607 | int itemIndex = GetHelperName->GetIndex((DWORD)funcNum); |
4608 | if (itemIndex < 0) |
4609 | { |
4610 | return "hackishHelperName" ; |
4611 | } |
4612 | else |
4613 | { |
4614 | unsigned int buffIndex = GetHelperName->Get((DWORD)funcNum); |
4615 | DEBUG_REP(dmpGetHelperName((DWORD)funcNum, buffIndex)); |
4616 | return (const char*)GetHelperName->GetBuffer(buffIndex); |
4617 | } |
4618 | } |
4619 | |
4620 | void MethodContext::recCanCast(CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent, BOOL result) |
4621 | { |
4622 | if (CanCast == nullptr) |
4623 | CanCast = new LightWeightMap<DLDL, DWORD>(); |
4624 | |
4625 | DLDL key; |
4626 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
4627 | // out padding too |
4628 | |
4629 | key.A = (DWORDLONG)child; |
4630 | key.B = (DWORDLONG)parent; |
4631 | |
4632 | CanCast->Add(key, (DWORD)result); |
4633 | DEBUG_REC(dmpCanCast(key, (DWORD)result)); |
4634 | } |
4635 | void MethodContext::dmpCanCast(DLDL key, DWORD value) |
4636 | { |
4637 | printf("CanCast key chd-%016llX par-%016llX, value res-%u" , key.A, key.B, value); |
4638 | } |
4639 | BOOL MethodContext::repCanCast(CORINFO_CLASS_HANDLE child, CORINFO_CLASS_HANDLE parent) |
4640 | { |
4641 | DLDL key; |
4642 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
4643 | // out padding too |
4644 | |
4645 | key.A = (DWORDLONG)child; |
4646 | key.B = (DWORDLONG)parent; |
4647 | |
4648 | AssertCodeMsg(CanCast != nullptr, EXCEPTIONCODE_MC, "Didn't find anything %016llX, %016llX in map" , |
4649 | (DWORDLONG)child, (DWORDLONG)parent); |
4650 | AssertCodeMsg(CanCast->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX, %016llX %u in map" , |
4651 | (DWORDLONG)child, (DWORDLONG)parent, CanCast->GetCount()); |
4652 | BOOL value = (BOOL)CanCast->Get(key); |
4653 | DEBUG_REP(dmpCanCast(key, (DWORD)value)); |
4654 | return value; |
4655 | } |
4656 | |
4657 | void MethodContext::recGetChildType(CORINFO_CLASS_HANDLE clsHnd, CORINFO_CLASS_HANDLE* clsRet, CorInfoType result) |
4658 | { |
4659 | if (GetChildType == nullptr) |
4660 | GetChildType = new LightWeightMap<DWORDLONG, DLD>(); |
4661 | |
4662 | DLD value; |
4663 | |
4664 | value.A = (DWORDLONG)*clsRet; |
4665 | value.B = (DWORD)result; |
4666 | |
4667 | GetChildType->Add((DWORDLONG)clsHnd, value); |
4668 | DEBUG_REC(dmpGetChildType((DWORDLONG)clsHnd, value)); |
4669 | } |
4670 | void MethodContext::dmpGetChildType(DWORDLONG key, DLD value) |
4671 | { |
4672 | printf("GetChildType key cls-%016llX, value clsr-%016llX cit-%u(%s)" , key, value.A, value.B, |
4673 | toString((CorInfoType)value.B)); |
4674 | } |
4675 | CorInfoType MethodContext::repGetChildType(CORINFO_CLASS_HANDLE clsHnd, CORINFO_CLASS_HANDLE* clsRet) |
4676 | { |
4677 | DLD value; |
4678 | |
4679 | AssertCodeMsg(GetChildType != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , (DWORDLONG)clsHnd); |
4680 | AssertCodeMsg(GetChildType->GetIndex((DWORDLONG)clsHnd) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
4681 | (DWORDLONG)clsHnd); |
4682 | value = GetChildType->Get((DWORDLONG)clsHnd); |
4683 | |
4684 | *clsRet = (CORINFO_CLASS_HANDLE)value.A; |
4685 | DEBUG_REP(dmpGetChildType((DWORDLONG)clsHnd, value)); |
4686 | return (CorInfoType)value.B; |
4687 | } |
4688 | |
4689 | void MethodContext::recGetArrayInitializationData(CORINFO_FIELD_HANDLE field, DWORD size, void* result) |
4690 | { |
4691 | if (GetArrayInitializationData == nullptr) |
4692 | GetArrayInitializationData = new LightWeightMap<DLD, DWORDLONG>(); |
4693 | |
4694 | DLD key; |
4695 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
4696 | // out padding too |
4697 | |
4698 | key.A = (DWORDLONG)field; |
4699 | key.B = (DWORD)size; |
4700 | |
4701 | GetArrayInitializationData->Add(key, (DWORDLONG)result); |
4702 | } |
4703 | void MethodContext::dmpGetArrayInitializationData(DLD key, DWORDLONG value) |
4704 | { |
4705 | printf("GetArrayInitializationData key field-%016llX size-%08X, value result-%016llX" , key.A, key.B, value); |
4706 | } |
4707 | void* MethodContext::repGetArrayInitializationData(CORINFO_FIELD_HANDLE field, DWORD size) |
4708 | { |
4709 | DLD key; |
4710 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
4711 | // out padding too |
4712 | |
4713 | key.A = (DWORDLONG)field; |
4714 | key.B = (DWORD)size; |
4715 | |
4716 | void* value = (void*)GetArrayInitializationData->Get(key); |
4717 | return value; |
4718 | } |
4719 | |
4720 | void MethodContext::recFilterException(struct _EXCEPTION_POINTERS* pExceptionPointers, int result) |
4721 | { |
4722 | if (FilterException == nullptr) |
4723 | FilterException = new LightWeightMap<DWORD, DWORD>(); |
4724 | |
4725 | FilterException->Add((DWORD)pExceptionPointers->ExceptionRecord->ExceptionCode, (DWORD)result); |
4726 | } |
4727 | void MethodContext::dmpFilterException(DWORD key, DWORD value) |
4728 | { |
4729 | printf("FilterException key %u, value %u" , key, value); |
4730 | } |
4731 | int MethodContext::repFilterException(struct _EXCEPTION_POINTERS* pExceptionPointers) |
4732 | { |
4733 | if (FilterException == nullptr) |
4734 | return EXCEPTION_CONTINUE_SEARCH; |
4735 | if (FilterException->GetIndex((DWORD)pExceptionPointers->ExceptionRecord->ExceptionCode) < 0) |
4736 | return EXCEPTION_CONTINUE_SEARCH; |
4737 | else |
4738 | { |
4739 | int result = FilterException->Get((DWORD)pExceptionPointers->ExceptionRecord->ExceptionCode); |
4740 | return result; |
4741 | } |
4742 | } |
4743 | |
4744 | void MethodContext::recHandleException(struct _EXCEPTION_POINTERS* pExceptionPointers) |
4745 | { |
4746 | if (HandleException == nullptr) |
4747 | HandleException = new DenseLightWeightMap<DWORD>(); |
4748 | |
4749 | HandleException->Append(pExceptionPointers->ExceptionRecord->ExceptionCode); |
4750 | } |
4751 | void MethodContext::dmpHandleException(DWORD key, DWORD value) |
4752 | { |
4753 | printf("HandleException key %u, value %u" , key, value); |
4754 | } |
4755 | |
4756 | void MethodContext::recGetAddressOfPInvokeFixup(CORINFO_METHOD_HANDLE method, void** ppIndirection, void* result) |
4757 | { |
4758 | if (GetAddressOfPInvokeFixup == nullptr) |
4759 | GetAddressOfPInvokeFixup = new LightWeightMap<DWORDLONG, DLDL>(); |
4760 | |
4761 | DLDL value; |
4762 | |
4763 | if (ppIndirection != nullptr) |
4764 | value.A = (DWORDLONG)*ppIndirection; |
4765 | else |
4766 | value.A = (DWORDLONG)0; |
4767 | value.B = (DWORDLONG)result; |
4768 | |
4769 | GetAddressOfPInvokeFixup->Add((DWORDLONG)method, value); |
4770 | } |
4771 | void MethodContext::dmpGetAddressOfPInvokeFixup(DWORDLONG key, DLDL value) |
4772 | { |
4773 | printf("GetAddressOfPInvokeFixup key ftn-%016llX, value pp-%016llX res-%016llX" , key, value.A, value.B); |
4774 | } |
4775 | void* MethodContext::repGetAddressOfPInvokeFixup(CORINFO_METHOD_HANDLE method, void** ppIndirection) |
4776 | { |
4777 | DLDL value; |
4778 | |
4779 | value = GetAddressOfPInvokeFixup->Get((DWORDLONG)method); |
4780 | |
4781 | if (ppIndirection != nullptr) |
4782 | *ppIndirection = (void*)value.A; |
4783 | return (void*)value.B; |
4784 | } |
4785 | void MethodContext::recGetAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP* pLookup) |
4786 | { |
4787 | if (GetAddressOfPInvokeTarget == nullptr) |
4788 | GetAddressOfPInvokeTarget = new LightWeightMap<DWORDLONG, DLD>(); |
4789 | |
4790 | DLD value; |
4791 | |
4792 | value.A = (DWORDLONG)pLookup->addr; |
4793 | value.B = (DWORD)pLookup->accessType; |
4794 | |
4795 | GetAddressOfPInvokeTarget->Add((DWORDLONG)method, value); |
4796 | } |
4797 | void MethodContext::dmpGetAddressOfPInvokeTarget(DWORDLONG key, DLD value) |
4798 | { |
4799 | printf("GetAddressOfPInvokeTarget key ftn-%016llX, value addr-%016llX at-%u" , key, value.A, value.B); |
4800 | } |
4801 | void MethodContext::repGetAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP* pLookup) |
4802 | { |
4803 | DLD value = GetAddressOfPInvokeTarget->Get((DWORDLONG)method); |
4804 | |
4805 | pLookup->addr = (void*)value.A; |
4806 | pLookup->accessType = (InfoAccessType)value.B; |
4807 | } |
4808 | |
4809 | void MethodContext::recSatisfiesClassConstraints(CORINFO_CLASS_HANDLE cls, BOOL result) |
4810 | { |
4811 | if (SatisfiesClassConstraints == nullptr) |
4812 | SatisfiesClassConstraints = new LightWeightMap<DWORDLONG, DWORD>(); |
4813 | |
4814 | SatisfiesClassConstraints->Add((DWORDLONG)cls, (DWORD)result); |
4815 | } |
4816 | void MethodContext::dmpSatisfiesClassConstraints(DWORDLONG key, DWORD value) |
4817 | { |
4818 | printf("SatisfiesClassConstraints key cls-%016llX, value res-%u" , key, value); |
4819 | } |
4820 | BOOL MethodContext::repSatisfiesClassConstraints(CORINFO_CLASS_HANDLE cls) |
4821 | { |
4822 | return (BOOL)SatisfiesClassConstraints->Get((DWORDLONG)cls); |
4823 | } |
4824 | |
4825 | void MethodContext::recGetMethodHash(CORINFO_METHOD_HANDLE ftn, unsigned result) |
4826 | { |
4827 | if (GetMethodHash == nullptr) |
4828 | GetMethodHash = new LightWeightMap<DWORDLONG, DWORD>(); |
4829 | |
4830 | GetMethodHash->Add((DWORDLONG)ftn, (DWORD)result); |
4831 | DEBUG_REC(dmpGetMethodHash((DWORDLONG)ftn, (DWORD)result)); |
4832 | } |
4833 | void MethodContext::dmpGetMethodHash(DWORDLONG key, DWORD value) |
4834 | { |
4835 | printf("GetMethodHash key %016llX, value %u" , key, value); |
4836 | } |
4837 | unsigned MethodContext::repGetMethodHash(CORINFO_METHOD_HANDLE ftn) |
4838 | { |
4839 | unsigned result = 0x43; |
4840 | if (GetMethodHash != nullptr) |
4841 | if (GetMethodHash->GetIndex((DWORDLONG)ftn) >= 0) |
4842 | result = GetMethodHash->Get((DWORDLONG)ftn); |
4843 | DEBUG_REP(dmpGetMethodHash((DWORDLONG)ftn, (DWORD)result)); |
4844 | return result; |
4845 | } |
4846 | |
4847 | void MethodContext::recCanTailCall(CORINFO_METHOD_HANDLE callerHnd, |
4848 | CORINFO_METHOD_HANDLE declaredCalleeHnd, |
4849 | CORINFO_METHOD_HANDLE exactCalleeHnd, |
4850 | bool fIsTailPrefix, |
4851 | bool result) |
4852 | { |
4853 | if (CanTailCall == nullptr) |
4854 | CanTailCall = new LightWeightMap<Agnostic_CanTailCall, DWORD>(); |
4855 | |
4856 | Agnostic_CanTailCall key; |
4857 | ZeroMemory(&key, sizeof(Agnostic_CanTailCall)); // We use the input structs as a key and use memcmp to compare.. so |
4858 | // we need to zero out padding too |
4859 | |
4860 | key.callerHnd = (DWORDLONG)callerHnd; |
4861 | key.declaredCalleeHnd = (DWORDLONG)declaredCalleeHnd; |
4862 | key.exactCalleeHnd = (DWORDLONG)exactCalleeHnd; |
4863 | key.fIsTailPrefix = (DWORD)fIsTailPrefix; |
4864 | |
4865 | CanTailCall->Add(key, (DWORD)result); |
4866 | DEBUG_REC(dmpCanTailCall(key, (DWORD)result)); |
4867 | } |
4868 | void MethodContext::dmpCanTailCall(const Agnostic_CanTailCall& key, DWORD value) |
4869 | { |
4870 | printf("CanTailCall key clr-%016llX dcle-%016llX ecle-%016llX pfx-%u, value res-%u" , key.callerHnd, |
4871 | key.declaredCalleeHnd, key.exactCalleeHnd, key.fIsTailPrefix, value); |
4872 | } |
4873 | bool MethodContext::repCanTailCall(CORINFO_METHOD_HANDLE callerHnd, |
4874 | CORINFO_METHOD_HANDLE declaredCalleeHnd, |
4875 | CORINFO_METHOD_HANDLE exactCalleeHnd, |
4876 | bool fIsTailPrefix) |
4877 | { |
4878 | Agnostic_CanTailCall key; |
4879 | ZeroMemory(&key, sizeof(Agnostic_CanTailCall)); // We use the input structs as a key and use memcmp to compare.. so |
4880 | // we need to zero out padding too |
4881 | |
4882 | key.callerHnd = (DWORDLONG)callerHnd; |
4883 | key.declaredCalleeHnd = (DWORDLONG)declaredCalleeHnd; |
4884 | key.exactCalleeHnd = (DWORDLONG)exactCalleeHnd; |
4885 | key.fIsTailPrefix = (DWORD)fIsTailPrefix; |
4886 | |
4887 | AssertCodeMsg(CanTailCall != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , |
4888 | (DWORDLONG)key.callerHnd); |
4889 | AssertCodeMsg(CanTailCall->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , (DWORDLONG)key.callerHnd); |
4890 | bool temp = CanTailCall->Get(key) != 0; |
4891 | DEBUG_REP(dmpCanTailCall(key, (DWORD)temp)); |
4892 | return temp; |
4893 | } |
4894 | |
4895 | void MethodContext::recIsCompatibleDelegate(CORINFO_CLASS_HANDLE objCls, |
4896 | CORINFO_CLASS_HANDLE methodParentCls, |
4897 | CORINFO_METHOD_HANDLE method, |
4898 | CORINFO_CLASS_HANDLE delegateCls, |
4899 | BOOL* pfIsOpenDelegate, |
4900 | BOOL result) |
4901 | { |
4902 | if (IsCompatibleDelegate == nullptr) |
4903 | IsCompatibleDelegate = new LightWeightMap<Agnostic_IsCompatibleDelegate, DD>(); |
4904 | Agnostic_IsCompatibleDelegate key; |
4905 | ZeroMemory(&key, sizeof(Agnostic_IsCompatibleDelegate)); // We use the input structs as a key and use memcmp to |
4906 | // compare.. so we need to zero out padding too |
4907 | DD value; |
4908 | |
4909 | key.objCls = (DWORDLONG)objCls; |
4910 | key.methodParentCls = (DWORDLONG)methodParentCls; |
4911 | key.method = (DWORDLONG)method; |
4912 | key.delegateCls = (DWORDLONG)delegateCls; |
4913 | |
4914 | value.A = (DWORD)*pfIsOpenDelegate; |
4915 | value.B = (DWORD)result; |
4916 | |
4917 | IsCompatibleDelegate->Add(key, value); |
4918 | } |
4919 | void MethodContext::dmpIsCompatibleDelegate(const Agnostic_IsCompatibleDelegate& key, DD value) |
4920 | { |
4921 | printf("IsCompatibleDelegate key objCls-%016llX methodParentCls-%016llX method-%016llX delegateCls-%016llX, value " |
4922 | "pfIsOpenDelegate-%08X result-%08X" , |
4923 | key.objCls, key.methodParentCls, key.method, key.delegateCls, value.A, value.B); |
4924 | } |
4925 | BOOL MethodContext::repIsCompatibleDelegate(CORINFO_CLASS_HANDLE objCls, |
4926 | CORINFO_CLASS_HANDLE methodParentCls, |
4927 | CORINFO_METHOD_HANDLE method, |
4928 | CORINFO_CLASS_HANDLE delegateCls, |
4929 | BOOL* pfIsOpenDelegate) |
4930 | { |
4931 | Agnostic_IsCompatibleDelegate key; |
4932 | ZeroMemory(&key, sizeof(Agnostic_IsCompatibleDelegate)); // We use the input structs as a key and use memcmp to |
4933 | // compare.. so we need to zero out padding too |
4934 | DD value; |
4935 | |
4936 | key.objCls = (DWORDLONG)objCls; |
4937 | key.methodParentCls = (DWORDLONG)methodParentCls; |
4938 | key.method = (DWORDLONG)method; |
4939 | key.delegateCls = (DWORDLONG)delegateCls; |
4940 | |
4941 | value = IsCompatibleDelegate->Get(key); |
4942 | |
4943 | *pfIsOpenDelegate = (BOOL)value.A; |
4944 | return (BOOL)value.B; |
4945 | } |
4946 | |
4947 | void MethodContext::recIsDelegateCreationAllowed(CORINFO_CLASS_HANDLE delegateHnd, |
4948 | CORINFO_METHOD_HANDLE calleeHnd, |
4949 | BOOL result) |
4950 | { |
4951 | if (IsDelegateCreationAllowed == nullptr) |
4952 | IsDelegateCreationAllowed = new LightWeightMap<DLDL, DWORD>(); |
4953 | |
4954 | DLDL key; |
4955 | ZeroMemory(&key, sizeof(key)); |
4956 | DWORD value; |
4957 | |
4958 | key.A = (DWORDLONG)delegateHnd; |
4959 | key.B = (DWORDLONG)calleeHnd; |
4960 | |
4961 | value = (DWORD)result; |
4962 | |
4963 | IsDelegateCreationAllowed->Add(key, value); |
4964 | } |
4965 | void MethodContext::dmpIsDelegateCreationAllowed(DLDL key, DWORD value) |
4966 | { |
4967 | printf("IsDelegateCreationAllowed key delegateHnd-%016llX calleeHnd-%016llX result-%08X" , key.A, key.B, value); |
4968 | } |
4969 | BOOL MethodContext::repIsDelegateCreationAllowed(CORINFO_CLASS_HANDLE delegateHnd, CORINFO_METHOD_HANDLE calleeHnd) |
4970 | { |
4971 | DLDL key; |
4972 | ZeroMemory(&key, sizeof(key)); |
4973 | DWORD value; |
4974 | |
4975 | key.A = (DWORDLONG)delegateHnd; |
4976 | key.B = (DWORDLONG)calleeHnd; |
4977 | |
4978 | value = IsDelegateCreationAllowed->Get(key); |
4979 | |
4980 | return (BOOL)value; |
4981 | } |
4982 | |
4983 | void MethodContext::recCanSkipMethodVerification(CORINFO_METHOD_HANDLE ftnHandle, |
4984 | BOOL skip, |
4985 | CorInfoCanSkipVerificationResult result) |
4986 | { |
4987 | if (CanSkipMethodVerification == nullptr) |
4988 | CanSkipMethodVerification = new LightWeightMap<DLD, DWORD>(); |
4989 | |
4990 | DLD key; |
4991 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
4992 | // out padding too |
4993 | |
4994 | key.A = (DWORDLONG)ftnHandle; |
4995 | key.B = (DWORD)skip; |
4996 | |
4997 | CanSkipMethodVerification->Add(key, (DWORD)result); |
4998 | DEBUG_REC(dmpCanSkipMethodVerification(key, (DWORD)result)); |
4999 | } |
5000 | void MethodContext::dmpCanSkipMethodVerification(DLD key, DWORD value) |
5001 | { |
5002 | printf("CanSkipMethodVerification key ftn-%016llX skp-%u, value res-%u" , key.A, key.B, value); |
5003 | } |
5004 | CorInfoCanSkipVerificationResult MethodContext::repCanSkipMethodVerification(CORINFO_METHOD_HANDLE ftnHandle, BOOL skip) |
5005 | { |
5006 | DLD key; |
5007 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
5008 | // out padding too |
5009 | |
5010 | key.A = (DWORDLONG)ftnHandle; |
5011 | key.B = (DWORD)skip; |
5012 | |
5013 | AssertCodeMsg(CanSkipMethodVerification != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , |
5014 | (DWORDLONG)ftnHandle); |
5015 | AssertCodeMsg(CanSkipMethodVerification->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
5016 | (DWORDLONG)ftnHandle); |
5017 | |
5018 | CorInfoCanSkipVerificationResult temp = (CorInfoCanSkipVerificationResult)CanSkipMethodVerification->Get(key); |
5019 | DEBUG_REP(dmpCanSkipMethodVerification(key, (DWORD)temp)); |
5020 | return temp; |
5021 | } |
5022 | |
5023 | void MethodContext::recFindCallSiteSig(CORINFO_MODULE_HANDLE module, |
5024 | unsigned methTOK, |
5025 | CORINFO_CONTEXT_HANDLE context, |
5026 | CORINFO_SIG_INFO* sig) |
5027 | { |
5028 | if (FindCallSiteSig == nullptr) |
5029 | FindCallSiteSig = new LightWeightMap<Agnostic_FindCallSiteSig, Agnostic_CORINFO_SIG_INFO>(); |
5030 | |
5031 | Agnostic_FindCallSiteSig key; |
5032 | ZeroMemory(&key, sizeof(Agnostic_FindCallSiteSig)); // We use the input structs as a key and use memcmp to compare.. |
5033 | // so we need to zero out padding too |
5034 | key.module = (DWORDLONG)module; |
5035 | key.methTok = (DWORD)methTOK; |
5036 | key.context = (DWORDLONG)context; |
5037 | |
5038 | Agnostic_CORINFO_SIG_INFO value = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(*sig, FindCallSiteSig); |
5039 | |
5040 | FindCallSiteSig->Add(key, value); |
5041 | DEBUG_REC(dmpFindCallSiteSig(key, value)); |
5042 | } |
5043 | void MethodContext::dmpFindCallSiteSig(const Agnostic_FindCallSiteSig& key, const Agnostic_CORINFO_SIG_INFO& value) |
5044 | { |
5045 | printf("dmpFindCallSiteSig key module-%016llX methTok-%08X context-%016llX" , key.module, key.methTok, key.context); |
5046 | printf(", value callConv-%08X retTypeClass-%016llX retTypeSigClass-%016llX retType-%u(%s) flags-%08X numArgs-%08X " |
5047 | "classInstCount-%08X classInd-%08X " |
5048 | "methInstCount-%08X methInd-%08X args-%016llX cbSig-%08X pSig_Index-%08X scope-%016llX token-%08X" , |
5049 | value.callConv, value.retTypeClass, value.retTypeSigClass, value.retType, |
5050 | toString((CorInfoType)value.retType), value.flags, value.numArgs, value.sigInst_classInstCount, |
5051 | value.sigInst_classInst_Index, value.sigInst_methInstCount, value.sigInst_methInst_Index, value.args, |
5052 | value.cbSig, value.pSig_Index, value.scope, value.token); |
5053 | } |
5054 | void MethodContext::repFindCallSiteSig(CORINFO_MODULE_HANDLE module, |
5055 | unsigned methTOK, |
5056 | CORINFO_CONTEXT_HANDLE context, |
5057 | CORINFO_SIG_INFO* sig) |
5058 | { |
5059 | Agnostic_FindCallSiteSig key; |
5060 | ZeroMemory(&key, sizeof(Agnostic_FindCallSiteSig)); // We use the input structs as a key and use memcmp to compare.. |
5061 | // so we need to zero out padding too |
5062 | Agnostic_CORINFO_SIG_INFO value; |
5063 | |
5064 | key.module = (DWORDLONG)module; |
5065 | key.methTok = (DWORD)methTOK; |
5066 | key.context = (DWORDLONG)context; |
5067 | |
5068 | AssertCodeMsg(FindCallSiteSig != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %08X" , (DWORD)key.methTok); |
5069 | AssertCodeMsg(FindCallSiteSig->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %08X" , (DWORD)key.methTok); |
5070 | value = FindCallSiteSig->Get(key); |
5071 | |
5072 | *sig = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value, FindCallSiteSig); |
5073 | |
5074 | DEBUG_REP(dmpFindCallSiteSig(key, value)); |
5075 | } |
5076 | |
5077 | void MethodContext::recShouldEnforceCallvirtRestriction(CORINFO_MODULE_HANDLE scope, BOOL result) |
5078 | { |
5079 | if (ShouldEnforceCallvirtRestriction == nullptr) |
5080 | ShouldEnforceCallvirtRestriction = new LightWeightMap<DWORDLONG, DWORD>(); |
5081 | ShouldEnforceCallvirtRestriction->Add((DWORDLONG)scope, (DWORD)result); |
5082 | DEBUG_REC(dmpShouldEnforceCallvirtRestriction((DWORDLONG)scope, (DWORD)result)); |
5083 | } |
5084 | void MethodContext::dmpShouldEnforceCallvirtRestriction(DWORDLONG key, DWORD value) |
5085 | { |
5086 | printf("ShouldEnforceCallvirtRestriction key %016llX, value %u" , key, value); |
5087 | } |
5088 | BOOL MethodContext::repShouldEnforceCallvirtRestriction(CORINFO_MODULE_HANDLE scope) |
5089 | { |
5090 | AssertCodeMsg(ShouldEnforceCallvirtRestriction != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , |
5091 | (DWORDLONG)scope); |
5092 | AssertCodeMsg(ShouldEnforceCallvirtRestriction->GetIndex((DWORDLONG)scope) != -1, EXCEPTIONCODE_MC, |
5093 | "Didn't find %016llX" , (DWORDLONG)scope); |
5094 | BOOL temp = (BOOL)ShouldEnforceCallvirtRestriction->Get((DWORDLONG)scope); |
5095 | DEBUG_REC(dmpShouldEnforceCallvirtRestriction((DWORDLONG)scope, (DWORD)temp)); |
5096 | return temp; |
5097 | } |
5098 | |
5099 | void MethodContext::recGetMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection, void* result) |
5100 | { |
5101 | if (GetMethodSync == nullptr) |
5102 | GetMethodSync = new LightWeightMap<DWORDLONG, DLDL>(); |
5103 | DLDL value; |
5104 | if (ppIndirection != nullptr) |
5105 | value.A = (DWORDLONG)*ppIndirection; |
5106 | else |
5107 | value.A = (DWORDLONG)0; |
5108 | value.B = (DWORDLONG)result; |
5109 | |
5110 | GetMethodSync->Add((DWORDLONG)ftn, value); |
5111 | } |
5112 | void MethodContext::dmpGetMethodSync(DWORDLONG key, DLDL value) |
5113 | { |
5114 | printf("GetMethodSync key %016llX, value pp-%016llX res-%016llX" , key, value.A, value.B); |
5115 | } |
5116 | void* MethodContext::repGetMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection) |
5117 | { |
5118 | DLDL value; |
5119 | |
5120 | value = (DLDL)GetMethodSync->Get((DWORDLONG)ftn); |
5121 | |
5122 | if (ppIndirection != nullptr) |
5123 | *ppIndirection = (void*)value.A; |
5124 | |
5125 | return (void*)value.B; |
5126 | } |
5127 | |
5128 | void MethodContext::recGetVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection, CORINFO_VARARGS_HANDLE result) |
5129 | { |
5130 | if (GetVarArgsHandle == nullptr) |
5131 | GetVarArgsHandle = new LightWeightMap<GetVarArgsHandleValue, DLDL>(); |
5132 | |
5133 | GetVarArgsHandleValue key; |
5134 | ZeroMemory(&key, sizeof(GetVarArgsHandleValue)); // We use the input structs as a key and use memcmp to |
5135 | // compare.. so we need to zero out padding too |
5136 | key.cbSig = (DWORD)pSig->cbSig; |
5137 | key.pSig_Index = (DWORD)GetVarArgsHandle->AddBuffer((unsigned char*)pSig->pSig, pSig->cbSig); |
5138 | key.scope = (DWORDLONG)pSig->scope; |
5139 | key.token = (DWORD)pSig->token; |
5140 | |
5141 | DLDL value; |
5142 | if (ppIndirection != nullptr) |
5143 | value.A = (DWORDLONG)*ppIndirection; |
5144 | else |
5145 | value.A = (DWORDLONG)0; |
5146 | value.B = (DWORDLONG)result; |
5147 | |
5148 | GetVarArgsHandle->Add(key, value); |
5149 | } |
5150 | void MethodContext::dmpGetVarArgsHandle(const GetVarArgsHandleValue& key, DLDL value) |
5151 | { |
5152 | printf("GetVarArgsHandle key cbSig-%08X pSig_Index-%08X scope-%016llX token-%08X" , key.cbSig, key.pSig_Index, |
5153 | key.scope, key.token); |
5154 | printf(", value ppIndirection-%016llX result-%016llX" , value.A, value.B); |
5155 | } |
5156 | CORINFO_VARARGS_HANDLE MethodContext::repGetVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection) |
5157 | { |
5158 | GetVarArgsHandleValue key; |
5159 | ZeroMemory(&key, sizeof(GetVarArgsHandleValue)); // We use the input structs as a key and use memcmp to |
5160 | // compare.. so we need to zero out padding too |
5161 | |
5162 | key.cbSig = (DWORD)pSig->cbSig; |
5163 | key.pSig_Index = (DWORD)GetVarArgsHandle->Contains((unsigned char*)pSig->pSig, pSig->cbSig); |
5164 | key.scope = (DWORDLONG)pSig->scope; |
5165 | key.token = (DWORD)pSig->token; |
5166 | |
5167 | DLDL value = (DLDL)GetVarArgsHandle->Get(key); |
5168 | |
5169 | if (ppIndirection != nullptr) |
5170 | *ppIndirection = (void*)value.A; |
5171 | |
5172 | return (CORINFO_VARARGS_HANDLE)value.B; |
5173 | } |
5174 | |
5175 | void MethodContext::recCanGetVarArgsHandle(CORINFO_SIG_INFO* pSig, bool result) |
5176 | { |
5177 | if (CanGetVarArgsHandle == nullptr) |
5178 | CanGetVarArgsHandle = new LightWeightMap<CanGetVarArgsHandleValue, DWORD>(); |
5179 | |
5180 | CanGetVarArgsHandleValue key; |
5181 | ZeroMemory(&key, sizeof(CanGetVarArgsHandleValue)); // We use the input structs as a key and use memcmp to |
5182 | // compare.. so we need to zero out padding too |
5183 | key.scope = (DWORDLONG)pSig->scope; |
5184 | key.token = (DWORD)pSig->token; |
5185 | |
5186 | CanGetVarArgsHandle->Add(key, (DWORD)result); |
5187 | DEBUG_REC(dmpCanGetVarArgsHandle(key, (DWORD)result)); |
5188 | } |
5189 | void MethodContext::dmpCanGetVarArgsHandle(const CanGetVarArgsHandleValue& key, DWORD value) |
5190 | { |
5191 | printf("CanGetVarArgsHandle key scope-%016llX token-%08X, value result-%08X" , key.scope, key.token, value); |
5192 | } |
5193 | bool MethodContext::repCanGetVarArgsHandle(CORINFO_SIG_INFO* pSig) |
5194 | { |
5195 | CanGetVarArgsHandleValue key; |
5196 | ZeroMemory(&key, sizeof(CanGetVarArgsHandleValue)); // We use the input structs as a key and use memcmp to |
5197 | // compare.. so we need to zero out padding too |
5198 | key.scope = (DWORDLONG)pSig->scope; |
5199 | key.token = (DWORD)pSig->token; |
5200 | |
5201 | AssertCodeMsg(CanGetVarArgsHandle != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , |
5202 | (DWORDLONG)key.token); |
5203 | AssertCodeMsg(CanGetVarArgsHandle->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
5204 | (DWORDLONG)key.token); |
5205 | bool value = CanGetVarArgsHandle->Get(key) != 0; |
5206 | DEBUG_REP(dmpCanGetVarArgsHandle(key, (DWORD)value)); |
5207 | return value; |
5208 | } |
5209 | |
5210 | void MethodContext::recGetFieldThreadLocalStoreID(CORINFO_FIELD_HANDLE field, void** ppIndirection, DWORD result) |
5211 | { |
5212 | if (GetFieldThreadLocalStoreID == nullptr) |
5213 | GetFieldThreadLocalStoreID = new LightWeightMap<DWORDLONG, DLD>(); |
5214 | ; |
5215 | |
5216 | DLD value; |
5217 | |
5218 | if (ppIndirection != nullptr) |
5219 | value.A = (DWORDLONG)*ppIndirection; |
5220 | else |
5221 | value.A = (DWORDLONG)0; |
5222 | value.B = (DWORD)result; |
5223 | |
5224 | GetFieldThreadLocalStoreID->Add((DWORDLONG)field, value); |
5225 | } |
5226 | void MethodContext::dmpGetFieldThreadLocalStoreID(DWORDLONG key, DLD value) |
5227 | { |
5228 | printf("GetFieldThreadLocalStoreID key field-%016llX, value ppIndirection-%016llX result-%08X" , key, value.A, |
5229 | value.B); |
5230 | } |
5231 | DWORD MethodContext::repGetFieldThreadLocalStoreID(CORINFO_FIELD_HANDLE field, void** ppIndirection) |
5232 | { |
5233 | DLD value; |
5234 | value = (DLD)GetFieldThreadLocalStoreID->Get((DWORDLONG)field); |
5235 | if (ppIndirection != nullptr) |
5236 | *ppIndirection = (void*)value.A; |
5237 | return (DWORD)value.B; |
5238 | } |
5239 | |
5240 | void MethodContext::recGetBBProfileData(CORINFO_METHOD_HANDLE ftnHnd, |
5241 | ULONG* count, |
5242 | ICorJitInfo::ProfileBuffer** profileBuffer, |
5243 | ULONG* numRuns, |
5244 | HRESULT result) |
5245 | { |
5246 | if (GetBBProfileData == nullptr) |
5247 | GetBBProfileData = new LightWeightMap<DWORDLONG, Agnostic_GetBBProfileData>(); |
5248 | |
5249 | Agnostic_GetBBProfileData value; |
5250 | |
5251 | value.count = (DWORD)*count; |
5252 | value.profileBuffer_index = |
5253 | GetBBProfileData->AddBuffer((unsigned char*)*profileBuffer, sizeof(ICorJitInfo::ProfileBuffer) * (*count)); |
5254 | value.numRuns = (DWORD)*numRuns; |
5255 | value.result = (DWORD)result; |
5256 | |
5257 | GetBBProfileData->Add((DWORDLONG)ftnHnd, value); |
5258 | } |
5259 | void MethodContext::dmpGetBBProfileData(DWORDLONG key, const Agnostic_GetBBProfileData& value) |
5260 | { |
5261 | printf("GetBBProfileData key ftn-%016llX, value cnt-%u profileBuf-" , key, value.count); |
5262 | ICorJitInfo::ProfileBuffer* pBuf = |
5263 | (ICorJitInfo::ProfileBuffer*)GetBBProfileData->GetBuffer(value.profileBuffer_index); |
5264 | for (DWORD i = 0; i < value.count; i++, pBuf++) |
5265 | { |
5266 | printf("{il-%u,cnt-%u}" , pBuf->ILOffset, pBuf->ExecutionCount); |
5267 | } |
5268 | GetBBProfileData->Unlock(); |
5269 | printf(" numRuns-%u result-%u" , value.numRuns, value.result); |
5270 | } |
5271 | HRESULT MethodContext::repGetBBProfileData(CORINFO_METHOD_HANDLE ftnHnd, |
5272 | ULONG* count, |
5273 | ICorJitInfo::ProfileBuffer** profileBuffer, |
5274 | ULONG* numRuns) |
5275 | { |
5276 | Agnostic_GetBBProfileData tempValue; |
5277 | |
5278 | tempValue = GetBBProfileData->Get((DWORDLONG)ftnHnd); |
5279 | |
5280 | *count = (ULONG)tempValue.count; |
5281 | *profileBuffer = (ICorJitInfo::ProfileBuffer*)GetBBProfileData->GetBuffer(tempValue.profileBuffer_index); |
5282 | *numRuns = (ULONG)tempValue.numRuns; |
5283 | HRESULT result = (HRESULT)tempValue.result; |
5284 | return result; |
5285 | } |
5286 | |
5287 | void MethodContext::recMergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, CORINFO_CLASS_HANDLE result) |
5288 | { |
5289 | if (MergeClasses == nullptr) |
5290 | MergeClasses = new LightWeightMap<DLDL, DWORDLONG>(); |
5291 | DLDL key; |
5292 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
5293 | // out padding too |
5294 | |
5295 | key.A = (DWORDLONG)cls1; |
5296 | key.B = (DWORDLONG)cls2; |
5297 | |
5298 | MergeClasses->Add(key, (DWORDLONG)result); |
5299 | } |
5300 | void MethodContext::dmpMergeClasses(DLDL key, DWORDLONG value) |
5301 | { |
5302 | printf("MergeClasses NYI" ); |
5303 | } |
5304 | CORINFO_CLASS_HANDLE MethodContext::repMergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) |
5305 | { |
5306 | DLDL key; |
5307 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
5308 | // out padding too |
5309 | DWORDLONG value; |
5310 | |
5311 | key.A = (DWORDLONG)cls1; |
5312 | key.B = (DWORDLONG)cls2; |
5313 | |
5314 | AssertCodeMsg(MergeClasses->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX %016llX" , (DWORDLONG)cls1, |
5315 | (DWORDLONG)cls2); |
5316 | value = MergeClasses->Get(key); |
5317 | |
5318 | return (CORINFO_CLASS_HANDLE)value; |
5319 | } |
5320 | |
5321 | void MethodContext::recGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void** ppIndirection, LPVOID result) |
5322 | { |
5323 | if (GetCookieForPInvokeCalliSig == nullptr) |
5324 | GetCookieForPInvokeCalliSig = new LightWeightMap<GetCookieForPInvokeCalliSigValue, DLDL>(); |
5325 | |
5326 | GetCookieForPInvokeCalliSigValue key; |
5327 | ZeroMemory(&key, sizeof(GetCookieForPInvokeCalliSigValue)); // We use the input structs as a key and use memcmp to |
5328 | // compare.. so we need to zero out padding too |
5329 | key.cbSig = (DWORD)szMetaSig->cbSig; |
5330 | key.pSig_Index = (DWORD)GetCookieForPInvokeCalliSig->AddBuffer((unsigned char*)szMetaSig->pSig, szMetaSig->cbSig); |
5331 | key.scope = (DWORDLONG)szMetaSig->scope; |
5332 | key.token = (DWORD)szMetaSig->token; |
5333 | |
5334 | DLDL value; |
5335 | if (ppIndirection != nullptr) |
5336 | value.A = (DWORDLONG)*ppIndirection; |
5337 | else |
5338 | value.A = (DWORDLONG)0; |
5339 | value.B = (DWORDLONG)result; |
5340 | |
5341 | GetCookieForPInvokeCalliSig->Add(key, value); |
5342 | } |
5343 | void MethodContext::dmpGetCookieForPInvokeCalliSig(const GetCookieForPInvokeCalliSigValue& key, DLDL value) |
5344 | { |
5345 | printf("GetCookieForPInvokeCalliSig NYI" ); |
5346 | } |
5347 | LPVOID MethodContext::repGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void** ppIndirection) |
5348 | { |
5349 | GetCookieForPInvokeCalliSigValue key; |
5350 | ZeroMemory(&key, sizeof(GetCookieForPInvokeCalliSigValue)); // We use the input structs as a key and use memcmp to |
5351 | // compare.. so we need to zero out padding too |
5352 | key.cbSig = (DWORD)szMetaSig->cbSig; |
5353 | key.pSig_Index = (DWORD)GetCookieForPInvokeCalliSig->Contains((unsigned char*)szMetaSig->pSig, szMetaSig->cbSig); |
5354 | key.scope = (DWORDLONG)szMetaSig->scope; |
5355 | key.token = (DWORD)szMetaSig->token; |
5356 | |
5357 | DLDL value = (DLDL)GetCookieForPInvokeCalliSig->Get(key); |
5358 | if (ppIndirection != nullptr) |
5359 | *ppIndirection = (void*)value.A; |
5360 | |
5361 | return (CORINFO_VARARGS_HANDLE)value.B; |
5362 | } |
5363 | |
5364 | void MethodContext::recCanGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, bool result) |
5365 | { |
5366 | if (CanGetCookieForPInvokeCalliSig == nullptr) |
5367 | CanGetCookieForPInvokeCalliSig = new LightWeightMap<CanGetCookieForPInvokeCalliSigValue, DWORD>(); |
5368 | |
5369 | CanGetCookieForPInvokeCalliSigValue key; |
5370 | ZeroMemory(&key, |
5371 | sizeof(CanGetCookieForPInvokeCalliSigValue)); // We use the input structs as a key and use memcmp to |
5372 | // compare.. so we need to zero out padding too |
5373 | key.scope = (DWORDLONG)szMetaSig->scope; |
5374 | key.token = (DWORD)szMetaSig->token; |
5375 | |
5376 | CanGetCookieForPInvokeCalliSig->Add(key, (DWORD)result); |
5377 | } |
5378 | void MethodContext::dmpCanGetCookieForPInvokeCalliSig(const CanGetCookieForPInvokeCalliSigValue& key, DWORD value) |
5379 | { |
5380 | printf("CanGetCookieForPInvokeCalliSig key scope-%016llX token-%08X, value result-%08X" , key.scope, key.token, |
5381 | value); |
5382 | } |
5383 | bool MethodContext::repCanGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig) |
5384 | { |
5385 | CanGetCookieForPInvokeCalliSigValue key; |
5386 | ZeroMemory(&key, |
5387 | sizeof(CanGetCookieForPInvokeCalliSigValue)); // We use the input structs as a key and use memcmp to |
5388 | // compare.. so we need to zero out padding too |
5389 | key.scope = (DWORDLONG)szMetaSig->scope; |
5390 | key.token = (DWORD)szMetaSig->token; |
5391 | |
5392 | DWORD temp = CanGetCookieForPInvokeCalliSig->Get(key); |
5393 | return temp != 0; |
5394 | } |
5395 | |
5396 | void MethodContext::recCanAccessFamily(CORINFO_METHOD_HANDLE hCaller, CORINFO_CLASS_HANDLE hInstanceType, BOOL result) |
5397 | { |
5398 | if (CanAccessFamily == nullptr) |
5399 | CanAccessFamily = new LightWeightMap<DLDL, DWORD>(); |
5400 | |
5401 | DLDL key; |
5402 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
5403 | // out padding too |
5404 | |
5405 | key.A = (DWORDLONG)hCaller; |
5406 | key.B = (DWORDLONG)hInstanceType; |
5407 | |
5408 | CanAccessFamily->Add(key, (DWORD)result); |
5409 | } |
5410 | void MethodContext::dmpCanAccessFamily(DLDL key, DWORD value) |
5411 | { |
5412 | printf("CanAccessFamily key cal-%016llX inst-%016llX, value %u" , key.A, key.B, value); |
5413 | } |
5414 | BOOL MethodContext::repCanAccessFamily(CORINFO_METHOD_HANDLE hCaller, CORINFO_CLASS_HANDLE hInstanceType) |
5415 | { |
5416 | DLDL key; |
5417 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
5418 | // out padding too |
5419 | |
5420 | key.A = (DWORDLONG)hCaller; |
5421 | key.B = (DWORDLONG)hInstanceType; |
5422 | |
5423 | DWORD temp = CanAccessFamily->Get(key); |
5424 | return (BOOL)temp; |
5425 | } |
5426 | |
5427 | void MethodContext::recErrorList(const char* error) |
5428 | { |
5429 | if (ErrorList == nullptr) |
5430 | ErrorList = new DenseLightWeightMap<DWORD>(); |
5431 | |
5432 | DWORD temp = (DWORD)-1; |
5433 | |
5434 | if (error != nullptr) |
5435 | temp = (DWORD)ErrorList->AddBuffer((unsigned char*)error, (DWORD)strlen(error) + 1); |
5436 | |
5437 | ErrorList->Append(temp); |
5438 | } |
5439 | void MethodContext::dmpErrorList(DWORD key, DWORD value) |
5440 | { |
5441 | printf("ErrorList NYI" ); |
5442 | } |
5443 | |
5444 | void MethodContext::recGetProfilingHandle(BOOL* pbHookFunction, void** pProfilerHandle, BOOL* pbIndirectedHandles) |
5445 | { |
5446 | if (GetProfilingHandle == nullptr) |
5447 | GetProfilingHandle = new LightWeightMap<DWORD, Agnostic_GetProfilingHandle>(); |
5448 | |
5449 | Agnostic_GetProfilingHandle value; |
5450 | ZeroMemory(&value, sizeof(Agnostic_GetProfilingHandle)); // We use the input structs as a value and use memcmp to |
5451 | // compare.. so we need to zero out padding too |
5452 | |
5453 | value.bHookFunction = (DWORD)*pbHookFunction; |
5454 | value.ProfilerHandle = (DWORDLONG)*pProfilerHandle; |
5455 | value.bIndirectedHandles = (DWORD)*pbIndirectedHandles; |
5456 | GetProfilingHandle->Add((DWORD)0, value); |
5457 | DEBUG_REC(dmpGetProfilingHandle(0, value)); |
5458 | } |
5459 | void MethodContext::dmpGetProfilingHandle(DWORD key, const Agnostic_GetProfilingHandle& value) |
5460 | { |
5461 | printf("GetProfilingHandle key %u, value bHookFtn-%u profHnd-%016llX bIndHnd-%u" , key, value.bHookFunction, |
5462 | value.ProfilerHandle, value.bIndirectedHandles); |
5463 | } |
5464 | void MethodContext::repGetProfilingHandle(BOOL* pbHookFunction, void** pProfilerHandle, BOOL* pbIndirectedHandles) |
5465 | { |
5466 | Agnostic_GetProfilingHandle value; |
5467 | |
5468 | value = GetProfilingHandle->Get((DWORD)0); |
5469 | |
5470 | *pbHookFunction = (BOOL)value.bHookFunction; |
5471 | *pProfilerHandle = (void*)value.ProfilerHandle; |
5472 | *pbIndirectedHandles = (BOOL)value.bIndirectedHandles; |
5473 | DEBUG_REP(dmpGetProfilingHandle(0, value)); |
5474 | } |
5475 | |
5476 | void MethodContext::recEmbedFieldHandle(CORINFO_FIELD_HANDLE handle, void** ppIndirection, CORINFO_FIELD_HANDLE result) |
5477 | { |
5478 | if (EmbedFieldHandle == nullptr) |
5479 | EmbedFieldHandle = new LightWeightMap<DWORDLONG, DLDL>(); |
5480 | |
5481 | DLDL value; |
5482 | if (ppIndirection != nullptr) |
5483 | value.A = (DWORDLONG)*ppIndirection; |
5484 | else |
5485 | value.A = (DWORDLONG)0; |
5486 | value.B = (DWORDLONG)result; |
5487 | |
5488 | EmbedFieldHandle->Add((DWORDLONG)handle, value); |
5489 | } |
5490 | void MethodContext::dmpEmbedFieldHandle(DWORDLONG key, DLDL value) |
5491 | { |
5492 | printf("EmbedFieldHandle NYI" ); |
5493 | } |
5494 | CORINFO_FIELD_HANDLE MethodContext::repEmbedFieldHandle(CORINFO_FIELD_HANDLE handle, void** ppIndirection) |
5495 | { |
5496 | DLDL value; |
5497 | |
5498 | value = EmbedFieldHandle->Get((DWORDLONG)handle); |
5499 | if (ppIndirection != nullptr) |
5500 | *ppIndirection = (void*)value.A; |
5501 | return (CORINFO_FIELD_HANDLE)value.B; |
5502 | } |
5503 | |
5504 | void MethodContext::recAreTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, BOOL result) |
5505 | { |
5506 | if (AreTypesEquivalent == nullptr) |
5507 | AreTypesEquivalent = new LightWeightMap<DLDL, DWORD>(); |
5508 | |
5509 | DLDL key; |
5510 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
5511 | // out padding too |
5512 | |
5513 | key.A = (DWORDLONG)cls1; |
5514 | key.B = (DWORDLONG)cls2; |
5515 | |
5516 | AreTypesEquivalent->Add(key, (DWORD)result); |
5517 | } |
5518 | void MethodContext::dmpAreTypesEquivalent(DLDL key, DWORD value) |
5519 | { |
5520 | printf("AreTypesEquivalent NYI" ); |
5521 | } |
5522 | BOOL MethodContext::repAreTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) |
5523 | { |
5524 | DLDL key; |
5525 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
5526 | // out padding too |
5527 | |
5528 | key.A = (DWORDLONG)cls1; |
5529 | key.B = (DWORDLONG)cls2; |
5530 | |
5531 | AssertCodeMsg(AreTypesEquivalent->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX %016llX" , |
5532 | (DWORDLONG)cls1, (DWORDLONG)cls2); |
5533 | BOOL value = (BOOL)AreTypesEquivalent->Get(key); |
5534 | return value; |
5535 | } |
5536 | |
5537 | void MethodContext::recCompareTypesForCast(CORINFO_CLASS_HANDLE fromClass, |
5538 | CORINFO_CLASS_HANDLE toClass, |
5539 | TypeCompareState result) |
5540 | { |
5541 | if (CompareTypesForCast == nullptr) |
5542 | CompareTypesForCast = new LightWeightMap<DLDL, DWORD>(); |
5543 | |
5544 | DLDL key; |
5545 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
5546 | // out padding too |
5547 | |
5548 | key.A = (DWORDLONG)fromClass; |
5549 | key.B = (DWORDLONG)toClass; |
5550 | |
5551 | CompareTypesForCast->Add(key, (DWORD)result); |
5552 | } |
5553 | void MethodContext::dmpCompareTypesForCast(DLDL key, DWORD value) |
5554 | { |
5555 | printf("CompareTypesForCast key fromClass=%016llX, toClass=%016llx, result=%d" , key.A, key.B, value); |
5556 | } |
5557 | TypeCompareState MethodContext::repCompareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass) |
5558 | { |
5559 | DLDL key; |
5560 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
5561 | // out padding too |
5562 | |
5563 | key.A = (DWORDLONG)fromClass; |
5564 | key.B = (DWORDLONG)toClass; |
5565 | |
5566 | AssertCodeMsg(CompareTypesForCast->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX %016llX" , |
5567 | (DWORDLONG)fromClass, (DWORDLONG)toClass); |
5568 | TypeCompareState value = (TypeCompareState)CompareTypesForCast->Get(key); |
5569 | return value; |
5570 | } |
5571 | |
5572 | void MethodContext::recCompareTypesForEquality(CORINFO_CLASS_HANDLE cls1, |
5573 | CORINFO_CLASS_HANDLE cls2, |
5574 | TypeCompareState result) |
5575 | { |
5576 | if (CompareTypesForEquality == nullptr) |
5577 | CompareTypesForEquality = new LightWeightMap<DLDL, DWORD>(); |
5578 | |
5579 | DLDL key; |
5580 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
5581 | // out padding too |
5582 | |
5583 | key.A = (DWORDLONG)cls1; |
5584 | key.B = (DWORDLONG)cls2; |
5585 | |
5586 | CompareTypesForEquality->Add(key, (DWORD)result); |
5587 | } |
5588 | void MethodContext::dmpCompareTypesForEquality(DLDL key, DWORD value) |
5589 | { |
5590 | printf("CompareTypesForEquality key cls1=%016llX, cls2=%016llx, result=%d" , key.A, key.B, value); |
5591 | } |
5592 | TypeCompareState MethodContext::repCompareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2) |
5593 | { |
5594 | DLDL key; |
5595 | ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
5596 | // out padding too |
5597 | |
5598 | key.A = (DWORDLONG)cls1; |
5599 | key.B = (DWORDLONG)cls2; |
5600 | |
5601 | AssertCodeMsg(CompareTypesForEquality->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX %016llX" , |
5602 | (DWORDLONG)cls1, (DWORDLONG)cls2); |
5603 | TypeCompareState value = (TypeCompareState)CompareTypesForEquality->Get(key); |
5604 | return value; |
5605 | } |
5606 | |
5607 | void MethodContext::recFindNameOfToken( |
5608 | CORINFO_MODULE_HANDLE module, mdToken metaTOK, char* szFQName, size_t FQNameCapacity, size_t result) |
5609 | { |
5610 | if (FindNameOfToken == nullptr) |
5611 | FindNameOfToken = new LightWeightMap<DLD, DLD>(); |
5612 | |
5613 | DLD key; |
5614 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
5615 | // out padding too |
5616 | DLD value; |
5617 | |
5618 | key.A = (DWORDLONG)module; |
5619 | key.B = (DWORD)metaTOK; |
5620 | |
5621 | value.A = result; |
5622 | value.B = FindNameOfToken->AddBuffer((unsigned char*)szFQName, (unsigned int)result); |
5623 | |
5624 | FindNameOfToken->Add(key, value); |
5625 | DEBUG_REC(dmpFindNameOfToken(key, value)); |
5626 | } |
5627 | void MethodContext::dmpFindNameOfToken(DLD key, DLD value) |
5628 | { |
5629 | // practically the name of a token wont be bigger than 4gb... |
5630 | unsigned char* buff = new unsigned char[(unsigned int)value.A + 1]; |
5631 | ZeroMemory(buff, (unsigned int)value.A + 1); |
5632 | memcpy(buff, FindNameOfToken->GetBuffer(value.B), (unsigned int)value.A); |
5633 | FindNameOfToken->Unlock(); |
5634 | printf("FindNameOfToken key mod-%016llX tok-%08X, value '%s'" , key.A, key.B, buff); |
5635 | delete[] buff; |
5636 | } |
5637 | size_t MethodContext::repFindNameOfToken(CORINFO_MODULE_HANDLE module, |
5638 | mdToken metaTOK, |
5639 | char* szFQName, |
5640 | size_t FQNameCapacity) |
5641 | { |
5642 | DLD key; |
5643 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
5644 | // out padding too |
5645 | DLD value; |
5646 | |
5647 | key.A = (DWORDLONG)module; |
5648 | key.B = (DWORD)metaTOK; |
5649 | |
5650 | value = FindNameOfToken->Get(key); |
5651 | |
5652 | unsigned char* temp = nullptr; |
5653 | if (value.B != (DWORD)-1) |
5654 | { |
5655 | temp = FindNameOfToken->GetBuffer(value.B); |
5656 | memcpy(szFQName, temp, (size_t)value.A); |
5657 | } |
5658 | |
5659 | DEBUG_REP(dmpFindNameOfToken(key, value)); |
5660 | return (size_t)value.A; |
5661 | } |
5662 | |
5663 | void MethodContext::recGetSystemVAmd64PassStructInRegisterDescriptor( |
5664 | CORINFO_CLASS_HANDLE structHnd, |
5665 | SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr, |
5666 | bool result) |
5667 | { |
5668 | if (GetSystemVAmd64PassStructInRegisterDescriptor == nullptr) |
5669 | GetSystemVAmd64PassStructInRegisterDescriptor = |
5670 | new LightWeightMap<DWORDLONG, Agnostic_GetSystemVAmd64PassStructInRegisterDescriptor>(); |
5671 | |
5672 | DWORDLONG key; |
5673 | Agnostic_GetSystemVAmd64PassStructInRegisterDescriptor value; |
5674 | |
5675 | key = (DWORDLONG)structHnd; |
5676 | |
5677 | value.passedInRegisters = (DWORD)structPassInRegDescPtr->passedInRegisters; |
5678 | value.eightByteCount = (DWORD)structPassInRegDescPtr->eightByteCount; |
5679 | for (int i = 0; i < CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS; i++) |
5680 | { |
5681 | value.eightByteClassifications[i] = (DWORD)structPassInRegDescPtr->eightByteClassifications[i]; |
5682 | value.eightByteSizes[i] = (DWORD)structPassInRegDescPtr->eightByteSizes[i]; |
5683 | value.eightByteOffsets[i] = (DWORD)structPassInRegDescPtr->eightByteOffsets[i]; |
5684 | } |
5685 | value.result = result ? 1 : 0; |
5686 | |
5687 | GetSystemVAmd64PassStructInRegisterDescriptor->Add(key, value); |
5688 | DEBUG_REC(dmpGetSystemVAmd64PassStructInRegisterDescriptor(key, value)); |
5689 | } |
5690 | void MethodContext::dmpGetSystemVAmd64PassStructInRegisterDescriptor( |
5691 | DWORDLONG key, const Agnostic_GetSystemVAmd64PassStructInRegisterDescriptor& value) |
5692 | { |
5693 | printf("GetSystemVAmd64PassStructInRegisterDescriptor key structHnd-%016llX, value passInReg-%u 8bCount-%u" , key, |
5694 | value.passedInRegisters, value.eightByteCount); |
5695 | for (int i = 0; i < CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS; i++) |
5696 | { |
5697 | printf(" 8bClass[%u]-%u 8bSz[%u]-%u 8bOff[%u]-%u" , i, value.eightByteClassifications[i], i, |
5698 | value.eightByteSizes[i], i, value.eightByteOffsets[i]); |
5699 | } |
5700 | printf(" result %u" , value.result); |
5701 | } |
5702 | bool MethodContext::repGetSystemVAmd64PassStructInRegisterDescriptor( |
5703 | CORINFO_CLASS_HANDLE structHnd, SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr) |
5704 | { |
5705 | DWORDLONG key; |
5706 | Agnostic_GetSystemVAmd64PassStructInRegisterDescriptor value; |
5707 | |
5708 | key = (DWORDLONG)structHnd; |
5709 | |
5710 | value = GetSystemVAmd64PassStructInRegisterDescriptor->Get(key); |
5711 | |
5712 | structPassInRegDescPtr->passedInRegisters = value.passedInRegisters ? true : false; |
5713 | structPassInRegDescPtr->eightByteCount = (unsigned __int8)value.eightByteCount; |
5714 | for (int i = 0; i < CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS; i++) |
5715 | { |
5716 | structPassInRegDescPtr->eightByteClassifications[i] = |
5717 | (SystemVClassificationType)value.eightByteClassifications[i]; |
5718 | structPassInRegDescPtr->eightByteSizes[i] = (unsigned __int8)value.eightByteSizes[i]; |
5719 | structPassInRegDescPtr->eightByteOffsets[i] = (unsigned __int8)value.eightByteOffsets[i]; |
5720 | } |
5721 | |
5722 | DEBUG_REP(dmpGetSystemVAmd64PassStructInRegisterDescriptor(key, value)); |
5723 | return value.result ? true : false; |
5724 | } |
5725 | |
5726 | void MethodContext::recGetRelocTypeHint(void* target, WORD result) |
5727 | { |
5728 | if (GetRelocTypeHint == nullptr) |
5729 | GetRelocTypeHint = new LightWeightMap<DWORDLONG, DWORD>(); |
5730 | |
5731 | GetRelocTypeHint->Add((DWORDLONG)target, (DWORD)result); |
5732 | DEBUG_REC(dmpGetRelocTypeHint((DWORDLONG)target, (DWORD)result)); |
5733 | } |
5734 | void MethodContext::dmpGetRelocTypeHint(DWORDLONG key, DWORD value) |
5735 | { |
5736 | printf("GetRelocTypeHint key tgt-%016llX, value hint-%u" , key, value); |
5737 | } |
5738 | WORD MethodContext::repGetRelocTypeHint(void* target) |
5739 | { |
5740 | if (GetRelocTypeHint == nullptr) |
5741 | { |
5742 | #ifdef sparseMC |
5743 | LogDebug("Sparse - repGetRelocTypeHint yielding fake answer..." ); |
5744 | return 65535; |
5745 | #else |
5746 | LogException(EXCEPTIONCODE_MC, "Didn't find %016llX" , (DWORDLONG)target); |
5747 | #endif |
5748 | } |
5749 | if (GetRelocTypeHint->GetIndex((DWORDLONG)target) == -1) |
5750 | { |
5751 | void* origAddr = cr->repAddressMap((void*)target); |
5752 | if (origAddr != (void*)-1 && origAddr != nullptr) |
5753 | { |
5754 | if (GetRelocTypeHint->GetIndex((DWORDLONG)origAddr) == -1) |
5755 | target = origAddr; |
5756 | } |
5757 | else |
5758 | { |
5759 | #ifdef sparseMC |
5760 | LogDebug("Sparse - repGetRelocTypeHint yielding fake answer..." ); |
5761 | return 65535; |
5762 | #else |
5763 | LogException(EXCEPTIONCODE_MC, "Didn't find %016llX" , (DWORDLONG)target); |
5764 | #endif |
5765 | } |
5766 | } |
5767 | |
5768 | int index = GetRelocTypeHint->GetIndex((DWORDLONG)target); |
5769 | WORD retVal = 0; |
5770 | if (index == -1) |
5771 | { |
5772 | void* subtarget = cr->searchAddressMap(target); |
5773 | |
5774 | int index2 = GetRelocTypeHint->GetIndex((DWORDLONG)subtarget); |
5775 | if (index2 == -1) |
5776 | { |
5777 | // __debugbreak(); // seems like a source of pain |
5778 | retVal = IMAGE_REL_BASED_REL32; |
5779 | } |
5780 | else |
5781 | retVal = (WORD)GetRelocTypeHint->Get((DWORDLONG)subtarget); |
5782 | } |
5783 | else |
5784 | retVal = (WORD)GetRelocTypeHint->Get((DWORDLONG)target); |
5785 | DEBUG_REP(dmpGetRelocTypeHint((DWORDLONG)target, retVal)); |
5786 | return retVal; |
5787 | } |
5788 | |
5789 | void MethodContext::recIsWriteBarrierHelperRequired(CORINFO_FIELD_HANDLE field, bool result) |
5790 | { |
5791 | if (IsWriteBarrierHelperRequired == nullptr) |
5792 | IsWriteBarrierHelperRequired = new LightWeightMap<DWORDLONG, DWORD>(); |
5793 | |
5794 | IsWriteBarrierHelperRequired->Add((DWORDLONG)field, (DWORD)result); |
5795 | DEBUG_REC(dmpIsWriteBarrierHelperRequired((DWORDLONG)field, (DWORD)result)); |
5796 | } |
5797 | void MethodContext::dmpIsWriteBarrierHelperRequired(DWORDLONG key, DWORD value) |
5798 | { |
5799 | printf("IsWriteBarrierHelperRequired key fld-%016llX, value res-%u" , key, value); |
5800 | } |
5801 | bool MethodContext::repIsWriteBarrierHelperRequired(CORINFO_FIELD_HANDLE field) |
5802 | { |
5803 | bool result = IsWriteBarrierHelperRequired->Get((DWORDLONG)field) != 0; |
5804 | DEBUG_REP(dmpIsWriteBarrierHelperRequired((DWORDLONG)field, result)); |
5805 | return result; |
5806 | } |
5807 | |
5808 | void MethodContext::recIsValidToken(CORINFO_MODULE_HANDLE module, unsigned metaTOK, BOOL result) |
5809 | { |
5810 | if (IsValidToken == nullptr) |
5811 | IsValidToken = new LightWeightMap<DLD, DWORD>(); |
5812 | |
5813 | DLD key; |
5814 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
5815 | // out padding too |
5816 | key.A = (DWORDLONG)module; |
5817 | key.B = (DWORD)metaTOK; |
5818 | IsValidToken->Add(key, (DWORD)result); |
5819 | } |
5820 | void MethodContext::dmpIsValidToken(DLD key, DWORD value) |
5821 | { |
5822 | printf("IsValidToken key mod-%016llX tok-%08X, value res-%u" , key.A, key.B, value); |
5823 | } |
5824 | BOOL MethodContext::repIsValidToken(CORINFO_MODULE_HANDLE module, unsigned metaTOK) |
5825 | { |
5826 | DLD key; |
5827 | ZeroMemory(&key, sizeof(DLD)); // We use the input structs as a key and use memcmp to compare.. so we need to zero |
5828 | // out padding too |
5829 | |
5830 | key.A = (DWORDLONG)module; |
5831 | key.B = (DWORD)metaTOK; |
5832 | BOOL value = (BOOL)IsValidToken->Get(key); |
5833 | return value; |
5834 | } |
5835 | |
5836 | void MethodContext::recGetClassName(CORINFO_CLASS_HANDLE cls, const char* result) |
5837 | { |
5838 | if (GetClassName == nullptr) |
5839 | GetClassName = new LightWeightMap<DWORDLONG, DWORD>(); |
5840 | |
5841 | DWORD temp = (DWORD)-1; |
5842 | if (result != nullptr) |
5843 | temp = (DWORD)GetClassName->AddBuffer((unsigned char*)result, (unsigned int)strlen(result) + 1); |
5844 | |
5845 | GetClassName->Add((DWORDLONG)cls, (DWORD)temp); |
5846 | DEBUG_REC(dmpGetClassName((DWORDLONG)cls, (DWORD)temp)); |
5847 | } |
5848 | void MethodContext::dmpGetClassName(DWORDLONG key, DWORD value) |
5849 | { |
5850 | printf("GetClassName key %016llX, value %s" , key, GetClassName->GetBuffer(value)); |
5851 | GetClassName->Unlock(); |
5852 | } |
5853 | const char* MethodContext::repGetClassName(CORINFO_CLASS_HANDLE cls) |
5854 | { |
5855 | if (GetClassName == nullptr) |
5856 | return "hackishClassName" ; |
5857 | int index = GetClassName->GetIndex((DWORDLONG)cls); |
5858 | if (index == -1) |
5859 | return "hackishClassName" ; |
5860 | int offset = GetClassName->Get((DWORDLONG)cls); |
5861 | const char* name = (const char*)GetClassName->GetBuffer(offset); |
5862 | DEBUG_REC(dmpGetClassName((DWORDLONG)cls, (DWORD)offset)); |
5863 | return name; |
5864 | } |
5865 | |
5866 | void MethodContext::recGetClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, char* className, const char** namespaceName) |
5867 | { |
5868 | if (GetClassNameFromMetadata == nullptr) |
5869 | GetClassNameFromMetadata = new LightWeightMap<DLD, DD>(); |
5870 | DD value; |
5871 | DLD key; |
5872 | key.A = (DWORDLONG)cls; |
5873 | key.B = (namespaceName != nullptr); |
5874 | |
5875 | if (className != nullptr) |
5876 | value.A = GetClassNameFromMetadata->AddBuffer((unsigned char*)className, (DWORD)strlen(className) + 1); |
5877 | else |
5878 | value.A = (DWORD)-1; |
5879 | |
5880 | if ((namespaceName != nullptr) && (*namespaceName != nullptr)) |
5881 | value.B = |
5882 | GetClassNameFromMetadata->AddBuffer((unsigned char*)*namespaceName, (DWORD)strlen(*namespaceName) + 1); |
5883 | else |
5884 | value.B = (DWORD)-1; |
5885 | |
5886 | GetClassNameFromMetadata->Add(key, value); |
5887 | DEBUG_REC(dmpGetClassNameFromMetadata(key, value)); |
5888 | } |
5889 | |
5890 | void MethodContext::dmpGetClassNameFromMetadata(DLD key, DD value) |
5891 | { |
5892 | unsigned char* className = (unsigned char*)GetClassNameFromMetadata->GetBuffer(value.A); |
5893 | unsigned char* namespaceName = (unsigned char*)GetClassNameFromMetadata->GetBuffer(value.B); |
5894 | printf("GetClassNameFromMetadata key - classNonNull-%llu namespaceNonNull-%u, value " |
5895 | "class-'%s', namespace-'%s'" , |
5896 | key.A, key.B, className, namespaceName); |
5897 | GetClassNameFromMetadata->Unlock(); |
5898 | } |
5899 | |
5900 | const char* MethodContext::repGetClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName) |
5901 | { |
5902 | const char* result = nullptr; |
5903 | DD value; |
5904 | DLD key; |
5905 | key.A = (DWORDLONG)cls; |
5906 | key.B = (namespaceName != nullptr); |
5907 | |
5908 | int itemIndex = -1; |
5909 | if (GetClassNameFromMetadata != nullptr) |
5910 | itemIndex = GetClassNameFromMetadata->GetIndex(key); |
5911 | if (itemIndex < 0) |
5912 | { |
5913 | if (namespaceName != nullptr) |
5914 | { |
5915 | *namespaceName = nullptr; |
5916 | } |
5917 | } |
5918 | else |
5919 | { |
5920 | value = GetClassNameFromMetadata->Get(key); |
5921 | result = (const char*)GetClassNameFromMetadata->GetBuffer(value.A); |
5922 | |
5923 | if (namespaceName != nullptr) |
5924 | { |
5925 | *namespaceName = (const char*)GetClassNameFromMetadata->GetBuffer(value.B); |
5926 | } |
5927 | } |
5928 | DEBUG_REP(dmpGetClassNameFromMetadata(key, value)); |
5929 | return result; |
5930 | } |
5931 | |
5932 | void MethodContext::recGetTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, |
5933 | CORINFO_CLASS_HANDLE result, |
5934 | unsigned index) |
5935 | { |
5936 | if (GetTypeInstantiationArgument == nullptr) |
5937 | GetTypeInstantiationArgument = new LightWeightMap<DWORDLONG, DWORDLONG>(); |
5938 | |
5939 | DWORDLONG key = (DWORDLONG)cls; |
5940 | |
5941 | GetTypeInstantiationArgument->Add(key, (DWORDLONG)result); |
5942 | DEBUG_REC(dmpGetTypeInstantiationArgument(key, (DWORDLONG)result)); |
5943 | } |
5944 | |
5945 | void MethodContext::dmpGetTypeInstantiationArgument(DWORDLONG key, DWORDLONG value) |
5946 | { |
5947 | printf("GetTypeInstantiationArgument key - classNonNull-%llu, value NonNull-%llu" , key, value); |
5948 | GetTypeInstantiationArgument->Unlock(); |
5949 | } |
5950 | |
5951 | CORINFO_CLASS_HANDLE MethodContext::repGetTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index) |
5952 | { |
5953 | CORINFO_CLASS_HANDLE result = nullptr; |
5954 | DWORDLONG value; |
5955 | DWORDLONG key; |
5956 | key = (DWORDLONG)cls; |
5957 | |
5958 | int itemIndex = -1; |
5959 | if (GetTypeInstantiationArgument != nullptr) |
5960 | itemIndex = GetTypeInstantiationArgument->GetIndex(key); |
5961 | if (itemIndex >= 0) |
5962 | { |
5963 | value = GetTypeInstantiationArgument->Get(key); |
5964 | result = (CORINFO_CLASS_HANDLE)value; |
5965 | } |
5966 | |
5967 | DEBUG_REP(dmpGetTypeInstantiationArgument(key, value)); |
5968 | return result; |
5969 | } |
5970 | |
5971 | void MethodContext::recAppendClassName( |
5972 | CORINFO_CLASS_HANDLE cls, BOOL fNamespace, BOOL fFullInst, BOOL fAssembly, const WCHAR* result) |
5973 | { |
5974 | if (AppendClassName == nullptr) |
5975 | AppendClassName = new LightWeightMap<Agnostic_AppendClassName, DWORD>(); |
5976 | |
5977 | Agnostic_AppendClassName key; |
5978 | ZeroMemory(&key, sizeof(Agnostic_AppendClassName)); // We use the input structs as a key and use memcmp to compare.. |
5979 | // so we need to zero out padding too |
5980 | key.classHandle = (DWORDLONG)cls; |
5981 | key.fNamespace = fNamespace; |
5982 | key.fFullInst = fFullInst; |
5983 | key.fAssembly = fAssembly; |
5984 | |
5985 | DWORD temp = (DWORD)-1; |
5986 | if (result != nullptr) |
5987 | temp = (DWORD)AppendClassName->AddBuffer((unsigned char*)result, (unsigned int)((wcslen(result) * 2) + 2)); |
5988 | |
5989 | AppendClassName->Add(key, (DWORD)temp); |
5990 | DEBUG_REC(dmpAppendClassName(key, (DWORD)temp)); |
5991 | } |
5992 | |
5993 | void MethodContext::dmpAppendClassName(const Agnostic_AppendClassName& key, DWORD value) |
5994 | { |
5995 | printf("AppendClassName key cls-%016llX ns-%u fi-%u as-%u, value %s" , key.classHandle, key.fNamespace, |
5996 | key.fFullInst, key.fAssembly, AppendClassName->GetBuffer(value)); |
5997 | AppendClassName->Unlock(); |
5998 | } |
5999 | |
6000 | const WCHAR* MethodContext::repAppendClassName(CORINFO_CLASS_HANDLE cls, |
6001 | BOOL fNamespace, |
6002 | BOOL fFullInst, |
6003 | BOOL fAssembly) |
6004 | { |
6005 | if (AppendClassName == nullptr) |
6006 | return W("hackishClassName" ); |
6007 | |
6008 | Agnostic_AppendClassName key; |
6009 | ZeroMemory(&key, sizeof(Agnostic_AppendClassName)); // We use the input structs as a key and use memcmp to compare.. |
6010 | // so we need to zero out padding too |
6011 | key.classHandle = (DWORDLONG)cls; |
6012 | key.fNamespace = fNamespace; |
6013 | key.fFullInst = fFullInst; |
6014 | key.fAssembly = fAssembly; |
6015 | |
6016 | int index = AppendClassName->GetIndex(key); |
6017 | if (index == -1) |
6018 | return W("hackishClassName" ); |
6019 | int offset = AppendClassName->Get(key); |
6020 | const WCHAR* name = (const WCHAR*)AppendClassName->GetBuffer(offset); |
6021 | DEBUG_REC(dmpAppendClassName(key, (DWORD)offset)); |
6022 | return name; |
6023 | } |
6024 | |
6025 | void MethodContext::recGetTailCallCopyArgsThunk(CORINFO_SIG_INFO* pSig, |
6026 | CorInfoHelperTailCallSpecialHandling flags, |
6027 | void* result) |
6028 | { |
6029 | if (GetTailCallCopyArgsThunk == nullptr) |
6030 | GetTailCallCopyArgsThunk = new LightWeightMap<Agnostic_GetTailCallCopyArgsThunk, DWORDLONG>(); |
6031 | |
6032 | Agnostic_GetTailCallCopyArgsThunk key; |
6033 | ZeroMemory(&key, sizeof(Agnostic_GetTailCallCopyArgsThunk)); // We use the input structs as a key and use memcmp to |
6034 | // compare.. so we need to zero out padding too |
6035 | key.Sig = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(*pSig, GetTailCallCopyArgsThunk); |
6036 | key.flags = (DWORD)flags; |
6037 | |
6038 | GetTailCallCopyArgsThunk->Add(key, (DWORDLONG)result); |
6039 | DEBUG_REC(dmpGetTailCallCopyArgsThunk(key, (DWORDLONG)result)); |
6040 | } |
6041 | void MethodContext::dmpGetTailCallCopyArgsThunk(const Agnostic_GetTailCallCopyArgsThunk& key, DWORDLONG value) |
6042 | { |
6043 | printf("GetTailCallCopyArgsThunk key sig%s flg-%08X" , |
6044 | SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(key.Sig).c_str(), key.flags); |
6045 | printf(", value res-%016llX" , value); |
6046 | } |
6047 | void* MethodContext::repGetTailCallCopyArgsThunk(CORINFO_SIG_INFO* pSig, CorInfoHelperTailCallSpecialHandling flags) |
6048 | { |
6049 | AssertCodeMsg(GetTailCallCopyArgsThunk != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for ..." ); |
6050 | |
6051 | Agnostic_GetTailCallCopyArgsThunk key; |
6052 | ZeroMemory(&key, sizeof(Agnostic_GetTailCallCopyArgsThunk)); // We use the input structs as a key and use memcmp to |
6053 | // compare.. so we need to zero out padding too |
6054 | key.Sig = SpmiRecordsHelper::RestoreAgnostic_CORINFO_SIG_INFO(*pSig, GetTailCallCopyArgsThunk); |
6055 | key.flags = (DWORD)flags; |
6056 | |
6057 | AssertCodeMsg(GetTailCallCopyArgsThunk->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
6058 | (DWORDLONG)key.Sig.retTypeClass); |
6059 | void* result = (void*)GetTailCallCopyArgsThunk->Get(key); |
6060 | cr->recAddressMap((void*)0x424242, (void*)result, 1); |
6061 | DEBUG_REP(dmpGetTailCallCopyArgsThunk(key, (DWORDLONG)result)); |
6062 | return result; |
6063 | } |
6064 | |
6065 | void MethodContext::recGetMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod, mdMethodDef result) |
6066 | { |
6067 | if (GetMethodDefFromMethod == nullptr) |
6068 | GetMethodDefFromMethod = new LightWeightMap<DWORDLONG, DWORD>(); |
6069 | |
6070 | GetMethodDefFromMethod->Add((DWORDLONG)hMethod, (DWORD)result); |
6071 | } |
6072 | void MethodContext::dmpGetMethodDefFromMethod(DWORDLONG key, DWORD value) |
6073 | { |
6074 | printf("GetMethodDefFromMethod key ftn-%016llX, value res-%u" , key, value); |
6075 | } |
6076 | mdMethodDef MethodContext::repGetMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod) |
6077 | { |
6078 | // Since this is diagnostic, fake up a result if one wasn't recorded. |
6079 | if (GetMethodDefFromMethod == nullptr) |
6080 | return (mdMethodDef)0x06000000; |
6081 | |
6082 | int index = GetMethodDefFromMethod->GetIndex((DWORDLONG)hMethod); |
6083 | if (index < 0) |
6084 | return (mdMethodDef)0x06000001; |
6085 | |
6086 | return (mdMethodDef)GetMethodDefFromMethod->Get((DWORDLONG)hMethod); |
6087 | } |
6088 | |
6089 | void MethodContext::recCheckMethodModifier(CORINFO_METHOD_HANDLE hMethod, LPCSTR modifier, BOOL fOptional, BOOL result) |
6090 | { |
6091 | if (CheckMethodModifier == nullptr) |
6092 | CheckMethodModifier = new LightWeightMap<Agnostic_CheckMethodModifier, DWORD>(); |
6093 | |
6094 | Agnostic_CheckMethodModifier key; |
6095 | ZeroMemory(&key, sizeof(Agnostic_CheckMethodModifier)); // We use the input structs as a key and use memcmp to |
6096 | // compare.. so we need to zero out padding too |
6097 | |
6098 | key.hMethod = (DWORDLONG)hMethod; |
6099 | // If the input matches something already in the buffer, just re-use that slot.. easier than searching for a soft |
6100 | // key on rep. |
6101 | if (modifier != nullptr) |
6102 | key.modifier = |
6103 | (DWORD)CheckMethodModifier->AddBuffer((unsigned char*)modifier, (unsigned int)strlen(modifier) + 1); |
6104 | else |
6105 | key.modifier = (DWORD)-1; |
6106 | |
6107 | key.fOptional = (DWORD)fOptional; |
6108 | |
6109 | CheckMethodModifier->Add(key, (DWORD)result); |
6110 | } |
6111 | void MethodContext::dmpCheckMethodModifier(const Agnostic_CheckMethodModifier& key, DWORD value) |
6112 | { |
6113 | printf("CheckMethodModifier key, ftn-%016llX mod-'%s' opt-%u, value res-%u" , key.hMethod, |
6114 | (unsigned char*)CheckMethodModifier->GetBuffer(key.modifier), key.fOptional, value); |
6115 | CheckMethodModifier->Unlock(); |
6116 | } |
6117 | BOOL MethodContext::repCheckMethodModifier(CORINFO_METHOD_HANDLE hMethod, LPCSTR modifier, BOOL fOptional) |
6118 | { |
6119 | Agnostic_CheckMethodModifier key; |
6120 | ZeroMemory(&key, sizeof(Agnostic_CheckMethodModifier)); // We use the input structs as a key and use memcmp to |
6121 | // compare.. so we need to zero out padding too |
6122 | |
6123 | key.hMethod = (DWORDLONG)hMethod; |
6124 | if (modifier != nullptr) |
6125 | key.modifier = |
6126 | (DWORD)CheckMethodModifier->Contains((unsigned char*)modifier, (unsigned int)strlen(modifier) + 1); |
6127 | else |
6128 | key.modifier = (DWORD)-1; |
6129 | |
6130 | key.fOptional = (DWORD)fOptional; |
6131 | |
6132 | BOOL value = (BOOL)CheckMethodModifier->Get(key); |
6133 | return value; |
6134 | } |
6135 | |
6136 | void MethodContext::recGetPInvokeUnmanagedTarget(CORINFO_METHOD_HANDLE method, void** ppIndirection, void* result) |
6137 | { |
6138 | if (GetPInvokeUnmanagedTarget == nullptr) |
6139 | GetPInvokeUnmanagedTarget = new LightWeightMap<DWORDLONG, DLDL>(); |
6140 | DLDL temp; |
6141 | temp.A = (DWORDLONG)*ppIndirection; |
6142 | temp.B = (DWORDLONG)result; |
6143 | |
6144 | GetPInvokeUnmanagedTarget->Add((DWORDLONG)method, temp); |
6145 | DEBUG_REC(dmpGetPInvokeUnmanagedTarget((DWORDLONG)method, temp)); |
6146 | } |
6147 | void MethodContext::dmpGetPInvokeUnmanagedTarget(DWORDLONG key, DLDL value) |
6148 | { |
6149 | printf("GetPInvokeUnmanagedTarget key ftn-%016llX, value pp-%016llX res-%016llX" , key, value.A, value.B); |
6150 | } |
6151 | void* MethodContext::repGetPInvokeUnmanagedTarget(CORINFO_METHOD_HANDLE method, void** ppIndirection) |
6152 | { |
6153 | DLDL temp = (DLDL)GetPInvokeUnmanagedTarget->Get((DWORDLONG)method); |
6154 | *ppIndirection = (void*)temp.A; |
6155 | DEBUG_REP(dmpGetPInvokeUnmanagedTarget((DWORDLONG)method, temp)); |
6156 | |
6157 | return (void*)temp.B; |
6158 | } |
6159 | |
6160 | void MethodContext::recGetArrayRank(CORINFO_CLASS_HANDLE cls, unsigned result) |
6161 | { |
6162 | if (GetArrayRank == nullptr) |
6163 | GetArrayRank = new LightWeightMap<DWORDLONG, DWORD>(); |
6164 | |
6165 | GetArrayRank->Add((DWORDLONG)cls, (DWORD)result); |
6166 | } |
6167 | void MethodContext::dmpGetArrayRank(DWORDLONG key, DWORD value) |
6168 | { |
6169 | printf("GetArrayRank key %016llX, value %u" , key, value); |
6170 | } |
6171 | unsigned MethodContext::repGetArrayRank(CORINFO_CLASS_HANDLE cls) |
6172 | { |
6173 | return (unsigned)GetArrayRank->Get((DWORDLONG)cls); |
6174 | } |
6175 | |
6176 | void MethodContext::recIsFieldStatic(CORINFO_FIELD_HANDLE fhld, bool result) |
6177 | { |
6178 | if (IsFieldStatic == nullptr) |
6179 | IsFieldStatic = new LightWeightMap<DWORDLONG, DWORD>(); |
6180 | |
6181 | IsFieldStatic->Add((DWORDLONG)fhld, (DWORD)result); |
6182 | DEBUG_REC(dmpIsFieldStatic((DWORDLONG)fhld, (DWORD)result)); |
6183 | } |
6184 | void MethodContext::dmpIsFieldStatic(DWORDLONG key, DWORD value) |
6185 | { |
6186 | printf("IsFieldStatic key %016llX, value %u" , key, value); |
6187 | } |
6188 | bool MethodContext::repIsFieldStatic(CORINFO_FIELD_HANDLE fhld) |
6189 | { |
6190 | AssertCodeMsg(IsFieldStatic != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX" , (DWORDLONG)fhld); |
6191 | AssertCodeMsg(IsFieldStatic->GetIndex((DWORDLONG)fhld) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX" , |
6192 | (DWORDLONG)fhld); |
6193 | bool result = (bool)(IsFieldStatic->Get((DWORDLONG)fhld) != 0); |
6194 | DEBUG_REP(dmpIsFieldStatic((DWORDLONG)fhld, (DWORD)result)); |
6195 | return result; |
6196 | } |
6197 | |
6198 | void MethodContext::recGetIntConfigValue(const wchar_t* name, int defaultValue, int result) |
6199 | { |
6200 | if (GetIntConfigValue == nullptr) |
6201 | GetIntConfigValue = new LightWeightMap<Agnostic_ConfigIntInfo, DWORD>(); |
6202 | |
6203 | AssertCodeMsg(name != nullptr, EXCEPTIONCODE_MC, "Name can not be nullptr" ); |
6204 | |
6205 | Agnostic_ConfigIntInfo key; |
6206 | ZeroMemory(&key, sizeof(Agnostic_ConfigIntInfo)); |
6207 | |
6208 | DWORD index = |
6209 | (DWORD)GetIntConfigValue->AddBuffer((unsigned char*)name, sizeof(wchar_t) * ((unsigned int)wcslen(name) + 1)); |
6210 | |
6211 | key.nameIndex = index; |
6212 | key.defaultValue = defaultValue; |
6213 | |
6214 | GetIntConfigValue->Add(key, result); |
6215 | DEBUG_REC(dmpGetIntConfigValue(key, result)); |
6216 | } |
6217 | |
6218 | void MethodContext::dmpGetIntConfigValue(const Agnostic_ConfigIntInfo& key, int value) |
6219 | { |
6220 | const wchar_t* name = (const wchar_t*)GetIntConfigValue->GetBuffer(key.nameIndex); |
6221 | printf("GetIntConfigValue name %S, default value %d, value %d" , name, key.defaultValue, value); |
6222 | GetIntConfigValue->Unlock(); |
6223 | } |
6224 | |
6225 | int MethodContext::repGetIntConfigValue(const wchar_t* name, int defaultValue) |
6226 | { |
6227 | if (GetIntConfigValue == nullptr) |
6228 | return defaultValue; |
6229 | |
6230 | AssertCodeMsg(name != nullptr, EXCEPTIONCODE_MC, "Name can not be nullptr" ); |
6231 | |
6232 | Agnostic_ConfigIntInfo key; |
6233 | ZeroMemory(&key, sizeof(Agnostic_ConfigIntInfo)); |
6234 | |
6235 | size_t nameLenInBytes = sizeof(wchar_t) * (wcslen(name) + 1); |
6236 | int nameIndex = GetIntConfigValue->Contains((unsigned char*)name, (unsigned int)nameLenInBytes); |
6237 | if (nameIndex == -1) // config name not in map |
6238 | return defaultValue; |
6239 | |
6240 | key.nameIndex = (DWORD)nameIndex; |
6241 | key.defaultValue = defaultValue; |
6242 | |
6243 | DWORD result = GetIntConfigValue->Get(key); |
6244 | DEBUG_REP(dmpGetIntConfigValue(key, result)); |
6245 | return (int)result; |
6246 | } |
6247 | |
6248 | void MethodContext::recGetStringConfigValue(const wchar_t* name, const wchar_t* result) |
6249 | { |
6250 | if (GetStringConfigValue == nullptr) |
6251 | GetStringConfigValue = new LightWeightMap<DWORD, DWORD>(); |
6252 | |
6253 | AssertCodeMsg(name != nullptr, EXCEPTIONCODE_MC, "Name can not be nullptr" ); |
6254 | |
6255 | DWORD nameIndex = (DWORD)GetStringConfigValue->AddBuffer((unsigned char*)name, |
6256 | sizeof(wchar_t) * ((unsigned int)wcslen(name) + 1)); |
6257 | |
6258 | DWORD resultIndex = (DWORD)-1; |
6259 | if (result != nullptr) |
6260 | resultIndex = (DWORD)GetStringConfigValue->AddBuffer((unsigned char*)result, |
6261 | sizeof(wchar_t) * ((unsigned int)wcslen(result) + 1)); |
6262 | |
6263 | GetStringConfigValue->Add(nameIndex, resultIndex); |
6264 | DEBUG_REC(dmpGetStringConfigValue(nameIndex, resultIndex)); |
6265 | } |
6266 | |
6267 | void MethodContext::dmpGetStringConfigValue(DWORD nameIndex, DWORD resultIndex) |
6268 | { |
6269 | const wchar_t* name = (const wchar_t*)GetStringConfigValue->GetBuffer(nameIndex); |
6270 | const wchar_t* result = (const wchar_t*)GetStringConfigValue->GetBuffer(resultIndex); |
6271 | printf("GetStringConfigValue name %S, result %S" , name, result); |
6272 | GetStringConfigValue->Unlock(); |
6273 | } |
6274 | |
6275 | const wchar_t* MethodContext::repGetStringConfigValue(const wchar_t* name) |
6276 | { |
6277 | if (GetStringConfigValue == nullptr) |
6278 | return nullptr; |
6279 | |
6280 | AssertCodeMsg(name != nullptr, EXCEPTIONCODE_MC, "Name can not be nullptr" ); |
6281 | |
6282 | size_t nameLenInBytes = sizeof(wchar_t) * (wcslen(name) + 1); |
6283 | int nameIndex = GetStringConfigValue->Contains((unsigned char*)name, (unsigned int)nameLenInBytes); |
6284 | if (nameIndex == -1) // config name not in map |
6285 | return nullptr; |
6286 | |
6287 | int resultIndex = GetStringConfigValue->Get(nameIndex); |
6288 | const wchar_t* value = (const wchar_t*)GetStringConfigValue->GetBuffer(resultIndex); |
6289 | |
6290 | DEBUG_REP(dmpGetStringConfigValue(nameIndex, resultIndex)); |
6291 | |
6292 | return value; |
6293 | } |
6294 | |
6295 | int MethodContext::dumpMethodIdentityInfoToBuffer(char* buff, int len) |
6296 | { |
6297 | char* obuff = buff; |
6298 | |
6299 | if (len < METHOD_IDENTITY_INFO_SIZE) |
6300 | return -1; |
6301 | |
6302 | // Obtain the Method Info structure for this method |
6303 | CORINFO_METHOD_INFO info; |
6304 | unsigned flags = 0; |
6305 | |
6306 | repCompileMethod(&info, &flags); |
6307 | |
6308 | // Add the Method Signature |
6309 | int t = sprintf_s(buff, len, "%s -- " , CallUtils::GetMethodFullName(this, info.ftn, info.args)); |
6310 | buff += t; |
6311 | len -= t; |
6312 | |
6313 | // Add Calling convention information, CorInfoOptions and CorInfoRegionKind |
6314 | t = sprintf_s(buff, len, "CallingConvention: %d, CorInfoOptions: %d, CorInfoRegionKind: %d " , info.args.callConv, |
6315 | info.options, info.regionKind); |
6316 | buff += t; |
6317 | len -= t; |
6318 | |
6319 | // Hash the IL Code for this method and append it to the ID info |
6320 | char ilHash[MD5_HASH_BUFFER_SIZE]; |
6321 | dumpMD5HashToBuffer(info.ILCode, info.ILCodeSize, ilHash, MD5_HASH_BUFFER_SIZE); |
6322 | t = sprintf_s(buff, len, "ILCode Hash: %s" , ilHash); |
6323 | buff += t; |
6324 | len -= t; |
6325 | |
6326 | return (int)(buff - obuff); |
6327 | } |
6328 | int MethodContext::dumpMethodMD5HashToBuffer(char* buff, int len) |
6329 | { |
6330 | char bufferIdentityInfo[METHOD_IDENTITY_INFO_SIZE]; |
6331 | |
6332 | int cbLen = dumpMethodIdentityInfoToBuffer(bufferIdentityInfo, METHOD_IDENTITY_INFO_SIZE); |
6333 | |
6334 | if (cbLen < 0) |
6335 | return cbLen; |
6336 | |
6337 | cbLen = dumpMD5HashToBuffer((BYTE*)bufferIdentityInfo, cbLen, buff, len); |
6338 | |
6339 | return cbLen; |
6340 | } |
6341 | |
6342 | int MethodContext::dumpMD5HashToBuffer(BYTE* pBuffer, int bufLen, char* hash, int hashLen) |
6343 | { |
6344 | #ifdef FEATURE_PAL |
6345 | |
6346 | MD5HASHDATA md5_hashdata; |
6347 | MD5 md5_hasher; |
6348 | |
6349 | if (hashLen < MD5_HASH_BUFFER_SIZE) |
6350 | return -1; |
6351 | |
6352 | md5_hasher.Hash(pBuffer, (ULONG)bufLen, &md5_hashdata); |
6353 | |
6354 | DWORD md5_hashdata_size = sizeof(md5_hashdata.rgb) / sizeof(BYTE); |
6355 | Assert(md5_hashdata_size == MD5_HASH_BYTE_SIZE); |
6356 | |
6357 | for (DWORD i = 0; i < md5_hashdata_size; i++) |
6358 | { |
6359 | sprintf_s(hash + i * 2, hashLen - i * 2, "%02X" , md5_hashdata.rgb[i]); |
6360 | } |
6361 | |
6362 | return MD5_HASH_BUFFER_SIZE; // if we had success we wrote MD5_HASH_BUFFER_SIZE bytes to the buffer |
6363 | |
6364 | #else // !FEATURE_PAL |
6365 | |
6366 | HCRYPTPROV hProv = NULL; // CryptoProvider |
6367 | HCRYPTHASH hHash = NULL; |
6368 | BYTE bHash[MD5_HASH_BYTE_SIZE]; |
6369 | DWORD cbHash = MD5_HASH_BYTE_SIZE; |
6370 | |
6371 | if (hashLen < MD5_HASH_BUFFER_SIZE) |
6372 | return -1; |
6373 | |
6374 | // Get handle to the crypto provider |
6375 | if (!CryptAcquireContextA(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) |
6376 | goto OnError; |
6377 | |
6378 | if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) |
6379 | goto OnError; |
6380 | |
6381 | if (!CryptHashData(hHash, pBuffer, bufLen, 0)) |
6382 | goto OnError; |
6383 | |
6384 | if (!CryptGetHashParam(hHash, HP_HASHVAL, bHash, &cbHash, 0)) |
6385 | goto OnError; |
6386 | |
6387 | if (cbHash != MD5_HASH_BYTE_SIZE) |
6388 | goto OnError; |
6389 | |
6390 | for (DWORD i = 0; i < MD5_HASH_BYTE_SIZE; i++) |
6391 | { |
6392 | sprintf_s(hash + i * 2, hashLen - i * 2, "%02X" , bHash[i]); |
6393 | } |
6394 | |
6395 | if (hHash != NULL) |
6396 | CryptDestroyHash(hHash); |
6397 | if (hProv != NULL) |
6398 | CryptReleaseContext(hProv, 0); |
6399 | |
6400 | return MD5_HASH_BUFFER_SIZE; // if we had success we wrote MD5_HASH_BUFFER_SIZE bytes to the buffer |
6401 | |
6402 | OnError: |
6403 | AssertMsg(false, "Failed to create a hash using the Crypto API (Error %X)" , GetLastError()); |
6404 | |
6405 | if (hHash != NULL) |
6406 | CryptDestroyHash(hHash); |
6407 | if (hProv != NULL) |
6408 | CryptReleaseContext(hProv, 0); |
6409 | return -1; |
6410 | |
6411 | #endif // !FEATURE_PAL |
6412 | } |
6413 | |
6414 | MethodContext::Environment MethodContext::cloneEnvironment() |
6415 | { |
6416 | MethodContext::Environment env; |
6417 | if (GetIntConfigValue != nullptr) |
6418 | { |
6419 | env.getIntConfigValue = new LightWeightMap<MethodContext::Agnostic_ConfigIntInfo, DWORD>(*GetIntConfigValue); |
6420 | } |
6421 | if (GetStringConfigValue != nullptr) |
6422 | { |
6423 | env.getStingConfigValue = new LightWeightMap<DWORD, DWORD>(*GetStringConfigValue); |
6424 | } |
6425 | return env; |
6426 | } |
6427 | |
6428 | // Check that there is a difference between the current enviroment variables maps and the prevEnv. |
6429 | bool MethodContext::WasEnvironmentChanged(const Environment& prevEnv) |
6430 | { |
6431 | if (!IsEnvironmentHeaderEqual(prevEnv)) |
6432 | { |
6433 | return true; |
6434 | } |
6435 | if (!IsEnvironmentContentEqual(prevEnv)) |
6436 | { |
6437 | return true; |
6438 | } |
6439 | return false; |
6440 | } |
6441 | |
6442 | // Check that environment maps headers are equal to the prevEnv maps headers. |
6443 | bool MethodContext::(const Environment& prevEnv) |
6444 | { |
6445 | if (!AreLWMHeadersEqual(prevEnv.getIntConfigValue, GetIntConfigValue)) |
6446 | { |
6447 | return false; |
6448 | } |
6449 | if (!AreLWMHeadersEqual(prevEnv.getStingConfigValue, GetStringConfigValue)) |
6450 | { |
6451 | return false; |
6452 | } |
6453 | return true; |
6454 | } |
6455 | |
6456 | // Check that environment maps content is equal to the prevEnv content. |
6457 | bool MethodContext::IsEnvironmentContentEqual(const Environment& prevEnv) |
6458 | { |
6459 | if (!IsIntConfigContentEqual(prevEnv.getIntConfigValue, GetIntConfigValue)) |
6460 | { |
6461 | return false; |
6462 | } |
6463 | if (!IsStringContentEqual(prevEnv.getStingConfigValue, GetStringConfigValue)) |
6464 | { |
6465 | return false; |
6466 | } |
6467 | return true; |
6468 | } |
6469 | |
6470 | // Check pointers to be both initizlized or null and number of keys to be equal. |
6471 | template <typename key, typename value> |
6472 | bool MethodContext::(LightWeightMap<key, value>* prev, LightWeightMap<key, value>* curr) |
6473 | { |
6474 | if (prev == nullptr && curr == nullptr) |
6475 | { |
6476 | return true; |
6477 | } |
6478 | if (prev != nullptr && curr != nullptr) |
6479 | { |
6480 | if (prev->GetCount() == curr->GetCount()) |
6481 | { |
6482 | return true; |
6483 | } |
6484 | } |
6485 | return false; |
6486 | } |
6487 | |
6488 | bool MethodContext::IsIntConfigContentEqual(LightWeightMap<Agnostic_ConfigIntInfo, DWORD>* prev, |
6489 | LightWeightMap<Agnostic_ConfigIntInfo, DWORD>* curr) |
6490 | { |
6491 | if (prev != nullptr && curr != nullptr) |
6492 | { |
6493 | if (prev->GetCount() != curr->GetCount()) |
6494 | { |
6495 | return false; |
6496 | } |
6497 | |
6498 | for (unsigned i = 0; i < prev->GetCount(); ++i) |
6499 | { |
6500 | DWORD currValue = curr->GetItem(i); |
6501 | DWORD prevValue = prev->GetItem(i); |
6502 | if (currValue != prevValue) |
6503 | { |
6504 | return false; |
6505 | } |
6506 | |
6507 | Agnostic_ConfigIntInfo currKey = curr->GetKey(i); |
6508 | Agnostic_ConfigIntInfo prevKey = prev->GetKey(i); |
6509 | |
6510 | if (currKey.defaultValue != prevKey.defaultValue) |
6511 | { |
6512 | return false; |
6513 | } |
6514 | |
6515 | DWORD currNameIndex = currKey.nameIndex; |
6516 | LPCSTR currName = (LPCSTR)curr->GetBuffer(currNameIndex); |
6517 | DWORD prevNameIndex = prevKey.nameIndex; |
6518 | LPCSTR prevName = (LPCSTR)prev->GetBuffer(currNameIndex); |
6519 | if (strcmp(currName, prevName) != 0) |
6520 | { |
6521 | return false; |
6522 | } |
6523 | } |
6524 | return true; |
6525 | } |
6526 | else |
6527 | { |
6528 | return (prev == curr); |
6529 | } |
6530 | } |
6531 | |
6532 | bool MethodContext::IsStringContentEqual(LightWeightMap<DWORD, DWORD>* prev, LightWeightMap<DWORD, DWORD>* curr) |
6533 | { |
6534 | if (prev != nullptr && curr != nullptr) |
6535 | { |
6536 | if (prev->GetCount() != curr->GetCount()) |
6537 | { |
6538 | return false; |
6539 | } |
6540 | |
6541 | for (unsigned i = 0; i < curr->GetCount(); ++i) |
6542 | { |
6543 | DWORD currKeyIndex = curr->GetKey(i); |
6544 | LPCSTR currKey = (LPCSTR)curr->GetBuffer(currKeyIndex); |
6545 | DWORD prevKeyIndex = prev->GetKey(i); |
6546 | LPCSTR prevKey = (LPCSTR)prev->GetBuffer(prevKeyIndex); |
6547 | if (strcmp(currKey, prevKey) != 0) |
6548 | { |
6549 | return false; |
6550 | } |
6551 | |
6552 | DWORD currValueIndex = curr->GetItem(i); |
6553 | LPCSTR currValue = (LPCSTR)curr->GetBuffer(currValueIndex); |
6554 | DWORD prevValueIndex = prev->GetItem(i); |
6555 | LPCSTR prevValue = (LPCSTR)prev->GetBuffer(prevValueIndex); |
6556 | if (strcmp(currValue, prevValue) != 0) |
6557 | { |
6558 | return false; |
6559 | } |
6560 | } |
6561 | return true; |
6562 | } |
6563 | else |
6564 | { |
6565 | return (prev == curr); |
6566 | } |
6567 | } |
6568 | |