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
39MethodContext::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
50MethodContext::~MethodContext()
51{
52 Destroy();
53}
54
55void 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
133unsigned 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
151unsigned 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
157unsigned 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
193bool 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
202bool 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
210bool 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, &param)
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
238bool 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, &param)
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
264void 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
280void 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.
343int 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}
357int 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
390bool 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.
458void 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
474void 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
493const 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
548unsigned 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
591void 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}
650void 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}
672void 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
725void 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}
733void MethodContext::dmpGetMethodClass(DWORDLONG key, DWORDLONG value)
734{
735 printf("GetMethodClass key %016llX, value %016llX", key, value);
736}
737CORINFO_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
749void 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}
757void MethodContext::dmpGetClassAttribs(DWORDLONG key, DWORD value)
758{
759 printf("GetClassAttribs key %016llX, value %u", key, value);
760}
761DWORD 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
773void 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}
781void MethodContext::dmpGetMethodAttribs(DWORDLONG key, DWORD value)
782{
783 printf("GetMethodAttribs key %016llX, value %u", key, value);
784}
785DWORD 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....
801void 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}
819void 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}
828void 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....
848void 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}
866void 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}
879void 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
896void 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}
916void 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}
921CorInfoInitClassResult 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
943void 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}
965void 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
974const 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
1001void 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
1042void 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
1054const 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
1101void 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}
1115void 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}
1121DWORD 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
1130void 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}
1144void 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}
1152LPCWSTR 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
1162void 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}
1189void 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}
1194CorInfoInline 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
1229void 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}
1246void 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}
1252void 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
1268void 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}
1286void 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}
1292bool 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
1308void 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}
1375void 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}
1394void 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//
1492void 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
1546void 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}
1558void MethodContext::dmpGetIntrinsicID(DWORDLONG key, DD value)
1559{
1560 printf("GetIntrinsicID key mth-%016llX, mustExpand-%u, value intr-%u", key, value.A, value.B);
1561}
1562CorInfoIntrinsics 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
1580void 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}
1588void MethodContext::dmpIsInSIMDModule(DWORDLONG key, DWORD value)
1589{
1590 printf("IsInSIMDModule key mth-%016llX, value intr-%u", key, value);
1591}
1592BOOL 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
1602void 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}
1610void MethodContext::dmpGetUnmanagedCallConv(DWORDLONG key, DWORD result)
1611{
1612 printf("GetUnmanagedCallConv key ftn-%016llX, value res-%u", key, result);
1613}
1614CorInfoUnmanagedCallConv 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
1631void 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}
1640void MethodContext::dmpIsInstantiationOfVerifiedGeneric(DWORDLONG key, DWORD value)
1641{
1642 printf("IsInstantiationOfVerifiedGeneric key ftn-%016llX, value res-%u", key, value);
1643}
1644CorInfoInstantiationVerification 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
1652void 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}
1660void MethodContext::dmpAsCorInfoType(DWORDLONG key, DWORD value)
1661{
1662 printf("AsCorInfoType key cls-%016llX, value cit-%u(%s)", key, value, toString((CorInfoType)value));
1663}
1664CorInfoType 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
1673void 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}
1681void MethodContext::dmpIsValueClass(DWORDLONG key, DWORD value)
1682{
1683 printf("IsValueClass key cls-%016llX, value res-%u", key, value);
1684}
1685BOOL 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
1695void 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}
1703void MethodContext::dmpIsStructRequiringStackAllocRetBuf(DWORDLONG key, DWORD value)
1704{
1705 printf("IsStructRequiringStackAllocRetBuf key cls-%016llX, value res-%u", key, value);
1706}
1707BOOL 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
1719void 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}
1727void MethodContext::dmpGetClassSize(DWORDLONG key, DWORD val)
1728{
1729 printf("GetClassSize key %016llX, value %u", key, val);
1730}
1731unsigned 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
1741void 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}
1749void MethodContext::dmpGetHeapClassSize(DWORDLONG key, DWORD val)
1750{
1751 printf("GetHeapClassSize key %016llX, value %u", key, val);
1752}
1753unsigned 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
1763void 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}
1771void MethodContext::dmpCanAllocateOnStack(DWORDLONG key, DWORD val)
1772{
1773 printf("CanAllocateOnStack key %016llX, value %u", key, val);
1774}
1775BOOL 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
1785void 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}
1793void MethodContext::dmpGetClassNumInstanceFields(DWORDLONG key, DWORD value)
1794{
1795 printf("GetClassNumInstanceFields key cls-%016llX, value res-%u", key, value);
1796}
1797unsigned 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
1809void 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}
1817void MethodContext::dmpGetNewArrHelper(DWORDLONG key, DWORD value)
1818{
1819 printf("GetNewArrHelper key cls-%016llX, value res-%u", key, value);
1820}
1821CorInfoHelpFunc 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
1828void 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}
1836void MethodContext::dmpGetSharedCCtorHelper(DWORDLONG key, DWORD value)
1837{
1838 printf("GetSharedCCtorHelper key cls-%016llX, value res-%u", key, value);
1839}
1840CorInfoHelpFunc 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
1847void 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}
1855void MethodContext::dmpGetSecurityPrologHelper(DWORDLONG key, DWORD value)
1856{
1857 printf("GetSecurityPrologHelper key ftn-%016llX, value res-%u", key, value);
1858}
1859CorInfoHelpFunc 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
1866void 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}
1874void MethodContext::dmpGetTypeForBox(DWORDLONG key, DWORDLONG value)
1875{
1876 printf("GetTypeForBox key cls-%016llX, value res-%016llX", key, value);
1877}
1878CORINFO_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
1885void 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}
1893void MethodContext::dmpGetBoxHelper(DWORDLONG key, DWORD value)
1894{
1895 printf("GetBoxHelper key cls-%016llX, value res-%u", key, value);
1896}
1897CorInfoHelpFunc 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
1904void 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}
1912void MethodContext::dmpGetBuiltinClass(DWORD key, DWORDLONG value)
1913{
1914 printf("GetBuiltinClass key cls-%08X, value cls-%016llX", key, value);
1915}
1916CORINFO_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
1927void 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}
1935void MethodContext::dmpGetTypeForPrimitiveValueClass(DWORDLONG key, DWORD value)
1936{
1937 printf("GetTypeForPrimitiveValueClass key cls-%016llX, value cit-%u(%s)", key, value, toString((CorInfoType)value));
1938}
1939CorInfoType 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
1950void 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}
1958void MethodContext::dmpGetTypeForPrimitiveNumericClass(DWORDLONG key, DWORD value)
1959{
1960 printf("GetTypeForPrimitiveNumericClass key cls-%016llX, value cit-%u(%s)", key, value,
1961 toString((CorInfoType)value));
1962}
1963CorInfoType 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
1974void 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}
1981void MethodContext::dmpGetParentType(DWORDLONG key, DWORDLONG value)
1982{
1983 printf("GetParentType key cls-%016llX, value cls-%016llX", key, value);
1984}
1985CORINFO_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
1991void 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}
1999void MethodContext::dmpIsSDArray(DWORDLONG key, DWORD value)
2000{
2001 printf("IsSDArray key cls-%016llX, value res-%u", key, value);
2002}
2003BOOL 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
2012void 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}
2020void MethodContext::dmpGetFieldClass(DWORDLONG key, DWORDLONG value)
2021{
2022 printf("GetFieldClass key %016llX, value %016llX", key, value);
2023}
2024CORINFO_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
2034void 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}
2042void MethodContext::dmpGetFieldOffset(DWORDLONG key, DWORD value)
2043{
2044 printf("GetFieldOffset key FLD-%016llX, value %08X", key, value);
2045}
2046unsigned 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
2056void 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
2065void MethodContext::dmpGetLazyStringLiteralHelper(DWORDLONG key, DWORD value)
2066{
2067 printf("GetLazyStringLiteralHelper key mod-%016llX, value res-%u", key, value);
2068}
2069
2070CorInfoHelpFunc 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
2081void 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}
2088void MethodContext::dmpGetUnBoxHelper(DWORDLONG key, DWORD value)
2089{
2090 printf("GetUnBoxHelper key cls-%016llX, value res-%u", key, value);
2091}
2092CorInfoHelpFunc MethodContext::repGetUnBoxHelper(CORINFO_CLASS_HANDLE cls)
2093{
2094 CorInfoHelpFunc temp = (CorInfoHelpFunc)GetUnBoxHelper->Get((DWORDLONG)cls);
2095 return temp;
2096}
2097
2098void 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
2120void 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
2129bool 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
2150void 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
2168void 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
2176void 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
2194void 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}
2215void MethodContext::dmpGetHelperFtn(DWORD key, DLDL value)
2216{
2217 printf("GetHelperFtn key ftn-%u, value ppi-%016llX res-%016llX", key, value.A, value.B);
2218}
2219void* 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//
2258bool 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
2281void 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}
2293void MethodContext::dmpGetJustMyCodeHandle(DWORDLONG key, DLDL value)
2294{
2295 printf("GetJustMyCodeHandle key ftn-%016llX, value pp-%016llX, res-%016llX", key, value.A, value.B);
2296}
2297CORINFO_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
2307void 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}
2325void 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}
2329void 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//
2407bool 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
2429void 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}
2448void 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}
2452InfoAccessType 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
2470void 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}
2486void MethodContext::dmpConvertPInvokeCalliToCall(DLD key, DWORDLONG value)
2487{
2488 printf("ConvertPInvokeCalliToCall key mod-%016llX tok-%08X, value %016llX", key.A, key.B, value);
2489}
2490bool 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
2505void 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}
2515void MethodContext::dmpEmptyStringLiteral(DWORD key, DLD value)
2516{
2517 printf("EmptyStringLiteral key %u, value pVal-%016llX res-%u", key, value.A, value.B);
2518}
2519InfoAccessType 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
2528void 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}
2561void 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}
2568CorInfoTypeWithMod 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
2602void 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}
2610void MethodContext::dmpGetArgNext(DWORDLONG key, DWORDLONG value)
2611{
2612 printf("GetArgNext key %016llX, value %016llX", key, value);
2613}
2614CORINFO_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}
2620void 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}
2636void 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}
2641void 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
2658void 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}
2687void 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}
2693CORINFO_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
2722void 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
2732void MethodContext::dmpGetHFAType(DWORDLONG key, DWORD value)
2733{
2734 printf("GetHFAType key %016llX, value %u ", key, value);
2735 return;
2736}
2737
2738CorInfoType 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
2751void 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}
2818void 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}
2841bool 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
2901void 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}
2922void 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}
2926CorInfoHelpFunc 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
2951void 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}
2972void 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}
2980void 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
3004void 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}
3027void 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}
3032void 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
3053void 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}
3068void 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}
3072void 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
3091void 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
3109void 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
3115CORINFO_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
3136void 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
3160void MethodContext::dmpGetUnboxedEntry(DWORDLONG key, DLD value)
3161{
3162 printf("GetUnboxedEntry ftn-%016llX, result-%016llX, requires-inst-%u", key, value.A, value.B);
3163}
3164
3165CORINFO_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
3183void 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}
3190void MethodContext::dmpGetDefaultEqualityComparerClass(DWORDLONG key, DWORDLONG value)
3191{
3192 printf("GetDefaultEqualityComparerClass key cls-%016llX, value cls-%016llX", key, value);
3193}
3194CORINFO_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
3200void 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}
3214void 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}
3218CORINFO_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
3231void 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}
3264void 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}
3300void 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
3371void 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}
3388void MethodContext::dmpEmbedMethodHandle(DWORDLONG key, DLDL value)
3389{
3390 printf("EmbedMethodHandle key ftn-%016llX, value pp-%016llX res-%016llX", key, value.A, value.B);
3391}
3392CORINFO_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
3408void 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}
3472void 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}
3477void* 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
3499void 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}
3514void 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}
3519CORINFO_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
3533void 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}
3547void 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}
3563unsigned 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
3585void 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}
3599void MethodContext::dmpGetClassAlignmentRequirement(DLD key, DWORD value)
3600{
3601 printf("GetClassAlignmentRequirement key %016llX %u, value %u", key.A, key.B, value);
3602}
3603unsigned 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
3616void 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}
3643void 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}
3654CorInfoIsAccessAllowedResult 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
3683void 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}
3697void 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}
3701CorInfoHelpFunc 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
3714void 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}
3730void MethodContext::dmpEmbedModuleHandle(DWORDLONG key, DLDL value)
3731{
3732 printf("EmbedModuleHandle key mod-%016llX, value pp-%016llX res-%016llX", key, value.A, value.B);
3733}
3734CORINFO_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
3744void 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}
3759void MethodContext::dmpEmbedClassHandle(DWORDLONG key, DLDL value)
3760{
3761 printf("EmbedClassHandle key cls-%016llX, value pp-%016llX res-%016llX", key, value.A, value.B);
3762}
3763CORINFO_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
3777void 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}
3796void 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
3802BOOL 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
3821void 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}
3841void 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}
3852void 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
3872void 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}
3907void 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}
3922void 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
3989void 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}
4007void MethodContext::dmpGetGSCookie(DWORD key, DLDL value)
4008{
4009 printf("GetGSCookie key 0, value pCookieVal-%016llX ppCookieVal-%016llX", value.A, value.B);
4010}
4011void 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
4023void 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}
4044void 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}
4049size_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
4065void 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}
4080void MethodContext::dmpGetThreadTLSIndex(DWORD key, DLD value)
4081{
4082 printf("GetThreadTLSIndex key 0, value ppIndirection-%016llX result-%08X", value.A, value.B);
4083}
4084DWORD 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
4095void 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}
4110void MethodContext::dmpGetInlinedCallFrameVptr(DWORD key, DLDL value)
4111{
4112 printf("GetInlinedCallFrameVptr key 0, value ppIndirection-%016llX result-%016llX", value.A, value.B);
4113}
4114const 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
4125void 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}
4141void MethodContext::dmpGetAddrOfCaptureThreadGlobal(DWORD key, DLDL value)
4142{
4143 printf("GetAddrOfCaptureThreadGlobal key %u, value ppi-%016llX res-%016llX", key, value.A, value.B);
4144}
4145LONG* 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
4166void 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}
4182void MethodContext::dmpGetClassDomainID(DWORDLONG key, DLD value)
4183{
4184 printf("GetClassDomainID key cls-%016llX, value pp-%016llX res-%u", key, value.A, value.B);
4185}
4186unsigned 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
4200void 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}
4208void 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}
4213CORINFO_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
4219void 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}
4246void 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}
4253CORINFO_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
4281void 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}
4290void 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}
4295void 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
4304void 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}
4319void MethodContext::dmpGetFieldInClass(DLD key, DWORDLONG value)
4320{
4321 printf("GetFieldInClass key cls-%016llX ind-%u, value %016llX", key.A, key.B, value);
4322}
4323CORINFO_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
4340void 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}
4369void 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}
4374CorInfoType 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
4397void 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}
4416void 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}
4423const 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
4438void 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}
4454void MethodContext::dmpCanInlineTypeCheck(DLD key, DWORD value)
4455{
4456 printf("CanInlineTypeCheck key cls-%016llX src-%08X, value res-%u", key.A, key.B, value);
4457}
4458CorInfoInlineTypeCheck 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
4473void 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}
4480void MethodContext::dmpCanInlineTypeCheckWithObjectVTable(DWORDLONG key, DWORD value)
4481{
4482 printf("CanInlineTypeCheckWithObjectVTable key cls-%016llX, value res-%u", key, value);
4483}
4484BOOL 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
4491void 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}
4507void MethodContext::dmpSatisfiesMethodConstraints(DLDL key, DWORD value)
4508{
4509 printf("SatisfiesMethodConstraints key cls-%016llX ftn-%016llX, value res-%u", key.A, key.B, value);
4510}
4511BOOL 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
4524void 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}
4538void MethodContext::dmpInitConstraintsForVerification(DWORDLONG key, DD value)
4539{
4540 printf("InitConstraintsForVerification key ftn-%016llX, value circ-%u cirm-%u", key, value.A, value.B);
4541}
4542void 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
4554void 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}
4568void MethodContext::dmpIsValidStringRef(DLD key, DWORD value)
4569{
4570 printf("IsValidStringRef key mod-%016llX tok-%08X, value res-%u", key.A, key.B, value);
4571}
4572BOOL 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
4585void 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}
4597void 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}
4602const 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
4620void 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}
4635void MethodContext::dmpCanCast(DLDL key, DWORD value)
4636{
4637 printf("CanCast key chd-%016llX par-%016llX, value res-%u", key.A, key.B, value);
4638}
4639BOOL 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
4657void 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}
4670void 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}
4675CorInfoType 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
4689void 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}
4703void MethodContext::dmpGetArrayInitializationData(DLD key, DWORDLONG value)
4704{
4705 printf("GetArrayInitializationData key field-%016llX size-%08X, value result-%016llX", key.A, key.B, value);
4706}
4707void* 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
4720void 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}
4727void MethodContext::dmpFilterException(DWORD key, DWORD value)
4728{
4729 printf("FilterException key %u, value %u", key, value);
4730}
4731int 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
4744void MethodContext::recHandleException(struct _EXCEPTION_POINTERS* pExceptionPointers)
4745{
4746 if (HandleException == nullptr)
4747 HandleException = new DenseLightWeightMap<DWORD>();
4748
4749 HandleException->Append(pExceptionPointers->ExceptionRecord->ExceptionCode);
4750}
4751void MethodContext::dmpHandleException(DWORD key, DWORD value)
4752{
4753 printf("HandleException key %u, value %u", key, value);
4754}
4755
4756void 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}
4771void MethodContext::dmpGetAddressOfPInvokeFixup(DWORDLONG key, DLDL value)
4772{
4773 printf("GetAddressOfPInvokeFixup key ftn-%016llX, value pp-%016llX res-%016llX", key, value.A, value.B);
4774}
4775void* 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}
4785void 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}
4797void MethodContext::dmpGetAddressOfPInvokeTarget(DWORDLONG key, DLD value)
4798{
4799 printf("GetAddressOfPInvokeTarget key ftn-%016llX, value addr-%016llX at-%u", key, value.A, value.B);
4800}
4801void 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
4809void 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}
4816void MethodContext::dmpSatisfiesClassConstraints(DWORDLONG key, DWORD value)
4817{
4818 printf("SatisfiesClassConstraints key cls-%016llX, value res-%u", key, value);
4819}
4820BOOL MethodContext::repSatisfiesClassConstraints(CORINFO_CLASS_HANDLE cls)
4821{
4822 return (BOOL)SatisfiesClassConstraints->Get((DWORDLONG)cls);
4823}
4824
4825void 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}
4833void MethodContext::dmpGetMethodHash(DWORDLONG key, DWORD value)
4834{
4835 printf("GetMethodHash key %016llX, value %u", key, value);
4836}
4837unsigned 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
4847void 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}
4868void 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}
4873bool 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
4895void 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}
4919void 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}
4925BOOL 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
4947void 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}
4965void MethodContext::dmpIsDelegateCreationAllowed(DLDL key, DWORD value)
4966{
4967 printf("IsDelegateCreationAllowed key delegateHnd-%016llX calleeHnd-%016llX result-%08X", key.A, key.B, value);
4968}
4969BOOL 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
4983void 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}
5000void MethodContext::dmpCanSkipMethodVerification(DLD key, DWORD value)
5001{
5002 printf("CanSkipMethodVerification key ftn-%016llX skp-%u, value res-%u", key.A, key.B, value);
5003}
5004CorInfoCanSkipVerificationResult 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
5023void 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}
5043void 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}
5054void 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
5077void 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}
5084void MethodContext::dmpShouldEnforceCallvirtRestriction(DWORDLONG key, DWORD value)
5085{
5086 printf("ShouldEnforceCallvirtRestriction key %016llX, value %u", key, value);
5087}
5088BOOL 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
5099void 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}
5112void MethodContext::dmpGetMethodSync(DWORDLONG key, DLDL value)
5113{
5114 printf("GetMethodSync key %016llX, value pp-%016llX res-%016llX", key, value.A, value.B);
5115}
5116void* 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
5128void 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}
5150void 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}
5156CORINFO_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
5175void 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}
5189void 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}
5193bool 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
5210void 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}
5226void 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}
5231DWORD 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
5240void 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}
5259void 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}
5271HRESULT 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
5287void 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}
5300void MethodContext::dmpMergeClasses(DLDL key, DWORDLONG value)
5301{
5302 printf("MergeClasses NYI");
5303}
5304CORINFO_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
5321void 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}
5343void MethodContext::dmpGetCookieForPInvokeCalliSig(const GetCookieForPInvokeCalliSigValue& key, DLDL value)
5344{
5345 printf("GetCookieForPInvokeCalliSig NYI");
5346}
5347LPVOID 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
5364void 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}
5378void 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}
5383bool 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
5396void 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}
5410void MethodContext::dmpCanAccessFamily(DLDL key, DWORD value)
5411{
5412 printf("CanAccessFamily key cal-%016llX inst-%016llX, value %u", key.A, key.B, value);
5413}
5414BOOL 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
5427void 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}
5439void MethodContext::dmpErrorList(DWORD key, DWORD value)
5440{
5441 printf("ErrorList NYI");
5442}
5443
5444void 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}
5459void 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}
5464void 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
5476void 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}
5490void MethodContext::dmpEmbedFieldHandle(DWORDLONG key, DLDL value)
5491{
5492 printf("EmbedFieldHandle NYI");
5493}
5494CORINFO_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
5504void 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}
5518void MethodContext::dmpAreTypesEquivalent(DLDL key, DWORD value)
5519{
5520 printf("AreTypesEquivalent NYI");
5521}
5522BOOL 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
5537void 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}
5553void MethodContext::dmpCompareTypesForCast(DLDL key, DWORD value)
5554{
5555 printf("CompareTypesForCast key fromClass=%016llX, toClass=%016llx, result=%d", key.A, key.B, value);
5556}
5557TypeCompareState 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
5572void 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}
5588void MethodContext::dmpCompareTypesForEquality(DLDL key, DWORD value)
5589{
5590 printf("CompareTypesForEquality key cls1=%016llX, cls2=%016llx, result=%d", key.A, key.B, value);
5591}
5592TypeCompareState 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
5607void 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}
5627void 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}
5637size_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
5663void 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}
5690void 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}
5702bool 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
5726void 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}
5734void MethodContext::dmpGetRelocTypeHint(DWORDLONG key, DWORD value)
5735{
5736 printf("GetRelocTypeHint key tgt-%016llX, value hint-%u", key, value);
5737}
5738WORD 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
5789void 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}
5797void MethodContext::dmpIsWriteBarrierHelperRequired(DWORDLONG key, DWORD value)
5798{
5799 printf("IsWriteBarrierHelperRequired key fld-%016llX, value res-%u", key, value);
5800}
5801bool 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
5808void 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}
5820void MethodContext::dmpIsValidToken(DLD key, DWORD value)
5821{
5822 printf("IsValidToken key mod-%016llX tok-%08X, value res-%u", key.A, key.B, value);
5823}
5824BOOL 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
5836void 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}
5848void MethodContext::dmpGetClassName(DWORDLONG key, DWORD value)
5849{
5850 printf("GetClassName key %016llX, value %s", key, GetClassName->GetBuffer(value));
5851 GetClassName->Unlock();
5852}
5853const 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
5866void 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
5890void 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
5900const 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
5932void 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
5945void MethodContext::dmpGetTypeInstantiationArgument(DWORDLONG key, DWORDLONG value)
5946{
5947 printf("GetTypeInstantiationArgument key - classNonNull-%llu, value NonNull-%llu", key, value);
5948 GetTypeInstantiationArgument->Unlock();
5949}
5950
5951CORINFO_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
5971void 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
5993void 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
6000const 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
6025void 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}
6041void 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}
6047void* 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
6065void 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}
6072void MethodContext::dmpGetMethodDefFromMethod(DWORDLONG key, DWORD value)
6073{
6074 printf("GetMethodDefFromMethod key ftn-%016llX, value res-%u", key, value);
6075}
6076mdMethodDef 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
6089void 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}
6111void 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}
6117BOOL 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
6136void 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}
6147void MethodContext::dmpGetPInvokeUnmanagedTarget(DWORDLONG key, DLDL value)
6148{
6149 printf("GetPInvokeUnmanagedTarget key ftn-%016llX, value pp-%016llX res-%016llX", key, value.A, value.B);
6150}
6151void* 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
6160void 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}
6167void MethodContext::dmpGetArrayRank(DWORDLONG key, DWORD value)
6168{
6169 printf("GetArrayRank key %016llX, value %u", key, value);
6170}
6171unsigned MethodContext::repGetArrayRank(CORINFO_CLASS_HANDLE cls)
6172{
6173 return (unsigned)GetArrayRank->Get((DWORDLONG)cls);
6174}
6175
6176void 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}
6184void MethodContext::dmpIsFieldStatic(DWORDLONG key, DWORD value)
6185{
6186 printf("IsFieldStatic key %016llX, value %u", key, value);
6187}
6188bool 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
6198void 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
6218void 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
6225int 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
6248void 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
6267void 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
6275const 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
6295int 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}
6328int 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
6342int 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
6402OnError:
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
6414MethodContext::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.
6429bool 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.
6443bool MethodContext::IsEnvironmentHeaderEqual(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.
6457bool 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.
6471template <typename key, typename value>
6472bool MethodContext::AreLWMHeadersEqual(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
6488bool 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
6532bool 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