From 08631794ecd7155afa1f2401fe5c7ee1af785a6d Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Thu, 7 Jan 2021 14:13:49 -1000 Subject: [PATCH] Improve SuperPMI handling of CORINFO_SIG_INST handle arrays (#46604) * Improve SuperPMI handling of CORINFO_SIG_INST handle arrays CORINFO_SIG_INST, used by the CORINFO_SIG_INFO struct, contains two pointers to arrays of handles. SuperPMI was saving/restoring these assuming 8-byte pointers. This worked fine for same-bitness record/playback (although on 32-bit it saved/restored twice as much data as it should, reading beyond the actual arrays when saving). However, when recording on 32-bit and replaying on 64-bit, this didn't work. Change the CORINFO_SIG_INST recording to record the handle arrays in a new dense DWORDLONG map, SigInstHandleMap, in "agnostic" format (64-bit pointers), and store an index into this map to the base of the array. The handle array can then be serialized/deserialized properly for cross-bitness scenarios. The map contains only unique array sequences, which is required so when we look up an array we find the unique map index. Create helpers for all the CORINFO_SIG_INST related serialization/deserialization/ dump/formatting. Also, implement record/playback of getExpectedTargetArchitecture(). Added "-simple" option to "mcs -dump" to not print the function name/signature for a method context. Useful for debugging problems where constructing that name/signature causes mcs crashes/asserts. Record on arm, playback on x64, using cross-compiler, now works. * Change the JIT/EE GUID The JIT/EE interface hasn't changed, but the SuperPMI data format has changed incompatibly, so force a recollection that won't be confused with the old collections. * Fix non-Windows build --- src/coreclr/ToolBox/superpmi/mcs/commandline.cpp | 19 +- src/coreclr/ToolBox/superpmi/mcs/commandline.h | 2 + src/coreclr/ToolBox/superpmi/mcs/mcs.cpp | 2 +- src/coreclr/ToolBox/superpmi/mcs/verbdump.cpp | 4 +- src/coreclr/ToolBox/superpmi/mcs/verbdump.h | 2 +- .../superpmi/superpmi-shared/lightweightmap.h | 26 +- .../ToolBox/superpmi/superpmi-shared/lwmlist.h | 7 +- .../superpmi/superpmi-shared/methodcontext.cpp | 486 ++++++++------------- .../superpmi/superpmi-shared/methodcontext.h | 26 +- .../superpmi/superpmi-shared/spmidumphelper.cpp | 68 ++- .../superpmi/superpmi-shared/spmidumphelper.h | 109 ++++- .../superpmi/superpmi-shared/spmirecordhelper.h | 212 +++++++-- .../superpmi-shim-collector/icorjitinfo.cpp | 5 +- .../ToolBox/superpmi/superpmi/icorjitinfo.cpp | 14 +- src/coreclr/inc/jiteeversionguid.h | 10 +- 15 files changed, 599 insertions(+), 393 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/mcs/commandline.cpp b/src/coreclr/ToolBox/superpmi/mcs/commandline.cpp index 58df7b3..d7c519e 100644 --- a/src/coreclr/ToolBox/superpmi/mcs/commandline.cpp +++ b/src/coreclr/ToolBox/superpmi/mcs/commandline.cpp @@ -55,8 +55,9 @@ void CommandLine::DumpHelp(const char* program) printf(" file1 is read and file2 is written\n"); printf(" e.g. -copy a.mch b.mch\n"); printf("\n"); - printf(" -dump {optional range} inputfile\n"); - printf(" Dump details for each methodContext\n"); + printf(" -dump {optional range} inputfile [-simple]\n"); + printf(" Dump details for each methodContext.\n"); + printf(" With -simple, don't display the function name/arguments in the header (useful for debugging mcs itself).\n"); printf(" e.g. -dump a.mc\n"); printf("\n"); printf(" -dumpMap inputfile\n"); @@ -378,6 +379,10 @@ bool CommandLine::Parse(int argc, char* argv[], /* OUT */ Options* o) Logger::OpenLogFile(argv[i]); } + else if ((_strnicmp(&argv[i][1], "simple", argLen) == 0)) + { + o->simple = true; + } else { LogError("CommandLine::Parse() - Unknown verb '%s'", argv[i]); @@ -398,6 +403,16 @@ bool CommandLine::Parse(int argc, char* argv[], /* OUT */ Options* o) } } + if (o->simple) + { + if (!o->actionDump) + { + LogError("CommandLine::Parse() '-simple' requires -dump."); + DumpHelp(argv[0]); + return false; + } + } + if (o->recursive) { if (!o->actionMerge) diff --git a/src/coreclr/ToolBox/superpmi/mcs/commandline.h b/src/coreclr/ToolBox/superpmi/mcs/commandline.h index b791b4c..74ca637 100644 --- a/src/coreclr/ToolBox/superpmi/mcs/commandline.h +++ b/src/coreclr/ToolBox/superpmi/mcs/commandline.h @@ -35,6 +35,7 @@ public: , recursive(false) , dedup(false) , stripCR(false) + , simple(false) , nameOfFile1(nullptr) , nameOfFile2(nullptr) , nameOfFile3(nullptr) @@ -62,6 +63,7 @@ public: bool recursive; bool dedup; bool stripCR; + bool simple; char* nameOfFile1; char* nameOfFile2; char* nameOfFile3; diff --git a/src/coreclr/ToolBox/superpmi/mcs/mcs.cpp b/src/coreclr/ToolBox/superpmi/mcs/mcs.cpp index 52bc21f..f8a0070 100644 --- a/src/coreclr/ToolBox/superpmi/mcs/mcs.cpp +++ b/src/coreclr/ToolBox/superpmi/mcs/mcs.cpp @@ -60,7 +60,7 @@ int __cdecl main(int argc, char* argv[]) } if (o.actionDump) { - exitCode = verbDump::DoWork(o.nameOfFile1, o.indexCount, o.indexes); + exitCode = verbDump::DoWork(o.nameOfFile1, o.indexCount, o.indexes, o.simple); } if (o.actionFracture) { diff --git a/src/coreclr/ToolBox/superpmi/mcs/verbdump.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbdump.cpp index 7a04abc..9740b53 100644 --- a/src/coreclr/ToolBox/superpmi/mcs/verbdump.cpp +++ b/src/coreclr/ToolBox/superpmi/mcs/verbdump.cpp @@ -10,7 +10,7 @@ #include "methodcontextiterator.h" #include "errorhandling.h" -int verbDump::DoWork(const char* nameOfInput, int indexCount, const int* indexes) +int verbDump::DoWork(const char* nameOfInput, int indexCount, const int* indexes, bool simple) { LogVerbose("Dumping '%s' to console", nameOfInput); @@ -23,7 +23,7 @@ int verbDump::DoWork(const char* nameOfInput, int indexCount, const int* indexes while (mci.MoveNext()) { MethodContext* mc = mci.Current(); - mc->dumpToConsole(mci.MethodContextNumber()); + mc->dumpToConsole(mci.MethodContextNumber(), simple); dumpedCount++; } diff --git a/src/coreclr/ToolBox/superpmi/mcs/verbdump.h b/src/coreclr/ToolBox/superpmi/mcs/verbdump.h index 4c0f295..4c1f9ab 100644 --- a/src/coreclr/ToolBox/superpmi/mcs/verbdump.h +++ b/src/coreclr/ToolBox/superpmi/mcs/verbdump.h @@ -12,6 +12,6 @@ class verbDump { public: - static int DoWork(const char* nameofInput, int indexCount, const int* indexes); + static int DoWork(const char* nameofInput, int indexCount, const int* indexes, bool simple); }; #endif diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/lightweightmap.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/lightweightmap.h index 2cc6536..151a1d2 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/lightweightmap.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/lightweightmap.h @@ -116,7 +116,7 @@ public: return &buffer[offset]; } - int Contains(const unsigned char* buff, unsigned int len) + int Contains(const unsigned char* buff, unsigned int len) const { #ifdef DEBUG_LWM LogDebug("New call to Contains %d {", len); @@ -271,7 +271,7 @@ public: "Unknown type" /*typeid(_Item).name()*/, ptr - rawData, size); } - unsigned int CalculateArraySize() + unsigned int CalculateArraySize() const { int size = 4 /* tag */ + sizeof(unsigned int) /* numItems */; if (numItems > 0) @@ -405,7 +405,7 @@ public: pItems[index] = item; } - int GetIndex(_Key key) + int GetIndex(_Key key) const { if (numItems == 0) return -1; @@ -429,19 +429,19 @@ public: return -1; // Didn't find key } - _Item GetItem(int index) + _Item GetItem(int index) const { AssertCodeMsg(index != -1, EXCEPTIONCODE_LWM, "Didn't find Key"); return pItems[index]; // found it. return position ///// } - _Key GetKey(int index) + _Key GetKey(int index) const { AssertCodeMsg(index != -1, EXCEPTIONCODE_LWM, "Didn't find Key (in GetKey)"); return pKeys[index]; } - _Item Get(_Key key) + _Item Get(_Key key) const { int index = GetIndex(key); AssertCodeMsg(index != -1, EXCEPTIONCODE_MC, "Didn't find Item (in Get)"); @@ -458,7 +458,7 @@ public: return pKeys; } - unsigned int GetCount() + unsigned int GetCount() const { return numItems; } @@ -618,7 +618,7 @@ private: } public: - unsigned int CalculateArraySize() + unsigned int CalculateArraySize() const { int size = 4 /* tag */ + sizeof(unsigned int) /* numItems */; if (numItems > 0) @@ -630,7 +630,7 @@ public: return size; } - unsigned int DumpToArray(unsigned char* bytes) + unsigned int DumpToArray(unsigned char* bytes) const { unsigned char* ptr = bytes; unsigned int size = CalculateArraySize(); @@ -683,7 +683,7 @@ public: return true; } - int GetIndex(unsigned int key) + int GetIndex(unsigned int key) const { if (key >= numItems) return -1; @@ -691,13 +691,13 @@ public: return (int)key; } - _Item GetItem(int index) + _Item GetItem(int index) const { AssertCodeMsg(index != -1, EXCEPTIONCODE_LWM, "Didn't find Key"); return pItems[index]; // found it. return position ///// } - _Item Get(unsigned int key) + _Item Get(unsigned int key) const { int index = GetIndex(key); return GetItem(index); @@ -708,7 +708,7 @@ public: return pItems; } - unsigned int GetCount() + unsigned int GetCount() const { return numItems; } diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h index b400fba..1597cf4 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h @@ -49,9 +49,9 @@ LWM(FindNameOfToken, DLD, DLD) LWM(FindSig, Agnostic_FindSig, Agnostic_CORINFO_SIG_INFO) LWM(GetAddressOfPInvokeTarget, DWORDLONG, DLD) LWM(GetAddrOfCaptureThreadGlobal, DWORD, DLDL) -LWM(GetArgClass, GetArgClassValue, Agnostic_GetArgClass_Value) +LWM(GetArgClass, Agnostic_GetArgClass_Key, Agnostic_GetArgClass_Value) LWM(GetArgNext, DWORDLONG, DWORDLONG) -LWM(GetArgType, GetArgTypeValue, Agnostic_GetArgType_Value) +LWM(GetArgType, Agnostic_GetArgType_Key, Agnostic_GetArgType_Value) LWM(GetArrayInitializationData, DLD, DWORDLONG) LWM(GetArrayRank, DWORDLONG, DWORD) LWM(GetMethodBlockCounts, DWORDLONG, Agnostic_GetMethodBlockCounts) @@ -121,6 +121,7 @@ LWM(GetProfilingHandle, DWORD, Agnostic_GetProfilingHandle) LWM(GetReadyToRunHelper, GetReadyToRunHelper_TOKENin, GetReadyToRunHelper_TOKENout) LWM(GetReadyToRunDelegateCtorHelper, GetReadyToRunDelegateCtorHelper_TOKENIn, Agnostic_CORINFO_LOOKUP) LWM(GetRelocTypeHint, DWORDLONG, DWORD) +LWM(GetExpectedTargetArchitecture, DWORD, DWORD) LWM(GetSharedCCtorHelper, DWORDLONG, DWORD) LWM(GetStringConfigValue, DWORD, DWORD) LWM(GetSystemVAmd64PassStructInRegisterDescriptor, DWORDLONG, Agnostic_GetSystemVAmd64PassStructInRegisterDescriptor) @@ -155,7 +156,7 @@ LWM(TryResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, TryResolveTokenValue) LWM(SatisfiesClassConstraints, DWORDLONG, DWORD) LWM(SatisfiesMethodConstraints, DLDL, DWORD) LWM(GetUnmanagedCallConv, MethodOrSigInfoValue, DD) - +DENSELWM(SigInstHandleMap, DWORDLONG) #undef LWM #undef DENSELWM diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index 86d550f..cfb4d49 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -475,7 +475,10 @@ void MethodContext::recGlobalContext(const MethodContext& other) } } -void MethodContext::dumpToConsole(int mcNumber) +// dumpToConsole: Display the method context numbered `mcNumber` to the console. If `simple` is true, +// dump without function name information. This is useful to debug problems with the creation of that +// information, which requires looking at the dumped info. +void MethodContext::dumpToConsole(int mcNumber, bool simple) { printf("*****************************************"); if (mcNumber != -1) @@ -483,12 +486,15 @@ void MethodContext::dumpToConsole(int mcNumber) printf(" method context #%d", mcNumber); } - // Dump method name, etc., to output. - char bufferIdentityInfo[METHOD_IDENTITY_INFO_SIZE]; - int cbLen = dumpMethodIdentityInfoToBuffer(bufferIdentityInfo, METHOD_IDENTITY_INFO_SIZE); - if (cbLen >= 0) + if (!simple) { - printf(" %s", bufferIdentityInfo); + // Dump method name, etc., to output. + char bufferIdentityInfo[METHOD_IDENTITY_INFO_SIZE]; + int cbLen = dumpMethodIdentityInfoToBuffer(bufferIdentityInfo, METHOD_IDENTITY_INFO_SIZE); + if (cbLen >= 0) + { + printf(" %s", bufferIdentityInfo); + } } printf("\n"); @@ -608,79 +614,31 @@ void MethodContext::recCompileMethod(CORINFO_METHOD_INFO* info, unsigned flags) Agnostic_CompileMethod value; - value.info.ftn = CastHandle(info->ftn); - value.info.scope = CastHandle(info->scope); - value.info.ILCode_offset = (DWORD)CompileMethod->AddBuffer(info->ILCode, info->ILCodeSize); - value.info.ILCodeSize = (DWORD)info->ILCodeSize; - value.info.maxStack = (DWORD)info->maxStack; - value.info.EHcount = (DWORD)info->EHcount; - value.info.options = (DWORD)info->options; - value.info.regionKind = (DWORD)info->regionKind; - value.info.args.callConv = (DWORD)info->args.callConv; - value.info.args.retTypeClass = CastHandle(info->args.retTypeClass); - value.info.args.retTypeSigClass = CastHandle(info->args.retTypeSigClass); - value.info.args.retType = (DWORD)info->args.retType; - value.info.args.flags = (DWORD)info->args.flags; - value.info.args.numArgs = (DWORD)info->args.numArgs; - value.info.args.sigInst_classInstCount = (DWORD)info->args.sigInst.classInstCount; - value.info.args.sigInst_classInst_Index = - CompileMethod->AddBuffer((unsigned char*)info->args.sigInst.classInst, - info->args.sigInst.classInstCount * 8); // porting issue - value.info.args.sigInst_methInstCount = (DWORD)info->args.sigInst.methInstCount; - value.info.args.sigInst_methInst_Index = - CompileMethod->AddBuffer((unsigned char*)info->args.sigInst.methInst, - info->args.sigInst.methInstCount * 8); // porting issue - value.info.args.args = CastHandle(info->args.args); - value.info.args.cbSig = (DWORD)info->args.cbSig; - value.info.args.pSig_Index = (DWORD)CompileMethod->AddBuffer((unsigned char*)info->args.pSig, info->args.cbSig); - value.info.args.scope = CastHandle(info->args.scope); - value.info.args.token = (DWORD)info->args.token; - value.info.locals.callConv = (DWORD)info->locals.callConv; - value.info.locals.retTypeClass = CastHandle(info->locals.retTypeClass); - value.info.locals.retTypeSigClass = CastHandle(info->locals.retTypeSigClass); - value.info.locals.retType = (DWORD)info->locals.retType; - value.info.locals.flags = (DWORD)info->locals.flags; - value.info.locals.numArgs = (DWORD)info->locals.numArgs; - value.info.locals.sigInst_classInstCount = (DWORD)info->locals.sigInst.classInstCount; - value.info.locals.sigInst_classInst_Index = - CompileMethod->AddBuffer((unsigned char*)info->locals.sigInst.classInst, - info->locals.sigInst.classInstCount * 8); // porting issue - value.info.locals.sigInst_methInstCount = (DWORD)info->locals.sigInst.methInstCount; - value.info.locals.sigInst_methInst_Index = - CompileMethod->AddBuffer((unsigned char*)info->locals.sigInst.methInst, - info->locals.sigInst.methInstCount * 8); // porting issue - value.info.locals.args = CastHandle(info->locals.args); - value.info.locals.cbSig = (DWORD)info->locals.cbSig; - value.info.locals.pSig_Index = - (DWORD)CompileMethod->AddBuffer((unsigned char*)info->locals.pSig, info->locals.cbSig); - value.info.locals.scope = CastHandle(info->locals.scope); - value.info.locals.token = (DWORD)info->locals.token; - value.flags = (DWORD)flags; + value.info.ftn = CastHandle(info->ftn); + value.info.scope = CastHandle(info->scope); + value.info.ILCode_offset = (DWORD)CompileMethod->AddBuffer(info->ILCode, info->ILCodeSize); + value.info.ILCodeSize = (DWORD)info->ILCodeSize; + value.info.maxStack = (DWORD)info->maxStack; + value.info.EHcount = (DWORD)info->EHcount; + value.info.options = (DWORD)info->options; + value.info.regionKind = (DWORD)info->regionKind; + + value.info.args = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(info->args, CompileMethod, SigInstHandleMap); + value.info.locals = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(info->locals, CompileMethod, SigInstHandleMap); + + value.flags = (DWORD)flags; CompileMethod->Add(0, value); DEBUG_REC(dmpCompileMethod(0, value)); } void MethodContext::dmpCompileMethod(DWORD key, const Agnostic_CompileMethod& value) { - printf("CompiledMethod key %u, value ftn-%016llX scp-%016llX ilo-%u ils-%u ms-%u ehc-%u opt-%u rk-%u " - "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 " - "pSig_Index-%u scp-%016llX tok-%08X} " - "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 " - "pSig_Index-%u scp-%016llX tok-%08X} " - "flg-%08X", + printf("CompileMethod key %u, value ftn-%016llX scp-%016llX ilo-%u ils-%u ms-%u ehc-%u opt-%u rk-%u args-%s locals-%s flg-%08X", key, value.info.ftn, value.info.scope, value.info.ILCode_offset, value.info.ILCodeSize, value.info.maxStack, - value.info.EHcount, value.info.options, value.info.regionKind, value.info.args.callConv, - value.info.args.retTypeClass, value.info.args.retTypeSigClass, value.info.args.retType, - toString((CorInfoType)value.info.args.retType), value.info.args.flags, value.info.args.numArgs, - value.info.args.sigInst_classInstCount, value.info.args.sigInst_classInst_Index, - value.info.args.sigInst_methInstCount, value.info.args.sigInst_methInst_Index, value.info.args.args, - value.info.args.cbSig, value.info.args.pSig_Index, value.info.args.scope, value.info.args.token, - value.info.locals.callConv, value.info.locals.retTypeClass, value.info.locals.retTypeSigClass, - value.info.locals.retType, toString((CorInfoType)value.info.locals.retType), value.info.locals.flags, - value.info.locals.numArgs, value.info.locals.sigInst_classInstCount, - value.info.locals.sigInst_classInst_Index, value.info.locals.sigInst_methInstCount, - value.info.locals.sigInst_methInst_Index, value.info.locals.args, value.info.locals.cbSig, - value.info.locals.pSig_Index, value.info.locals.scope, value.info.locals.token, value.flags); + value.info.EHcount, value.info.options, value.info.regionKind, + SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(value.info.args, CompileMethod, SigInstHandleMap).c_str(), + SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(value.info.locals, CompileMethod, SigInstHandleMap).c_str(), + value.flags); } void MethodContext::repCompileMethod(CORINFO_METHOD_INFO* info, unsigned* flags) { @@ -688,49 +646,18 @@ void MethodContext::repCompileMethod(CORINFO_METHOD_INFO* info, unsigned* flags) value = CompileMethod->Get((DWORD)0); // The only item in this set is a single group of inputs to CompileMethod - info->ftn = (CORINFO_METHOD_HANDLE)value.info.ftn; - info->scope = (CORINFO_MODULE_HANDLE)value.info.scope; - info->ILCode = CompileMethod->GetBuffer(value.info.ILCode_offset); - info->ILCodeSize = (unsigned)value.info.ILCodeSize; - methodSize = info->ILCodeSize; - info->maxStack = (unsigned)value.info.maxStack; - info->EHcount = (unsigned)value.info.EHcount; - info->options = (CorInfoOptions)value.info.options; - info->regionKind = (CorInfoRegionKind)value.info.regionKind; - info->args.callConv = (CorInfoCallConv)value.info.args.callConv; - info->args.retTypeClass = (CORINFO_CLASS_HANDLE)value.info.args.retTypeClass; - info->args.retTypeSigClass = (CORINFO_CLASS_HANDLE)value.info.args.retTypeSigClass; - info->args.retType = (CorInfoType)value.info.args.retType; - info->args.flags = (unsigned)value.info.args.flags; - info->args.numArgs = (unsigned)value.info.args.numArgs; - info->args.sigInst.classInstCount = (unsigned)value.info.args.sigInst_classInstCount; - info->args.sigInst.classInst = - (CORINFO_CLASS_HANDLE*)CompileMethod->GetBuffer(value.info.args.sigInst_classInst_Index); - info->args.sigInst.methInstCount = (unsigned)value.info.args.sigInst_methInstCount; - info->args.sigInst.methInst = - (CORINFO_CLASS_HANDLE*)CompileMethod->GetBuffer(value.info.args.sigInst_methInst_Index); - info->args.args = (CORINFO_ARG_LIST_HANDLE)value.info.args.args; - info->args.cbSig = (unsigned int)value.info.args.cbSig; - info->args.pSig = (PCCOR_SIGNATURE)CompileMethod->GetBuffer(value.info.args.pSig_Index); - info->args.scope = (CORINFO_MODULE_HANDLE)value.info.args.scope; - info->args.token = (mdToken)value.info.args.token; - info->locals.callConv = (CorInfoCallConv)value.info.locals.callConv; - info->locals.retTypeClass = (CORINFO_CLASS_HANDLE)value.info.locals.retTypeClass; - info->locals.retTypeSigClass = (CORINFO_CLASS_HANDLE)value.info.locals.retTypeSigClass; - info->locals.retType = (CorInfoType)value.info.locals.retType; - info->locals.flags = (unsigned)value.info.locals.flags; - info->locals.numArgs = (unsigned)value.info.locals.numArgs; - info->locals.sigInst.classInstCount = (unsigned)value.info.locals.sigInst_classInstCount; - info->locals.sigInst.classInst = - (CORINFO_CLASS_HANDLE*)CompileMethod->GetBuffer(value.info.locals.sigInst_classInst_Index); - info->locals.sigInst.methInstCount = (unsigned)value.info.locals.sigInst_methInstCount; - info->locals.sigInst.methInst = - (CORINFO_CLASS_HANDLE*)CompileMethod->GetBuffer(value.info.locals.sigInst_methInst_Index); - info->locals.args = (CORINFO_ARG_LIST_HANDLE)value.info.locals.args; - info->locals.cbSig = (unsigned int)value.info.locals.cbSig; - info->locals.pSig = (PCCOR_SIGNATURE)CompileMethod->GetBuffer(value.info.locals.pSig_Index); - info->locals.scope = (CORINFO_MODULE_HANDLE)value.info.locals.scope; - info->locals.token = (mdToken)value.info.locals.token; + info->ftn = (CORINFO_METHOD_HANDLE)value.info.ftn; + info->scope = (CORINFO_MODULE_HANDLE)value.info.scope; + info->ILCode = CompileMethod->GetBuffer(value.info.ILCode_offset); + info->ILCodeSize = (unsigned)value.info.ILCodeSize; + methodSize = info->ILCodeSize; + info->maxStack = (unsigned)value.info.maxStack; + info->EHcount = (unsigned)value.info.EHcount; + info->options = (CorInfoOptions)value.info.options; + info->regionKind = (CorInfoRegionKind)value.info.regionKind; + + info->args = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value.info.args, CompileMethod, SigInstHandleMap); + info->locals = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value.info.locals, CompileMethod, SigInstHandleMap); *flags = (unsigned)value.flags; DEBUG_REP(dmpCompileMethod(0, value)); @@ -1374,11 +1301,11 @@ void MethodContext::recGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken, value.hMethod = CastHandle(pResult->hMethod); value.methodFlags = (DWORD)pResult->methodFlags; value.classFlags = (DWORD)pResult->classFlags; - value.sig = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(pResult->sig, GetCallInfo); + value.sig = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(pResult->sig, GetCallInfo, SigInstHandleMap); if (flags & CORINFO_CALLINFO_VERIFICATION) { value.verMethodFlags = (DWORD)pResult->verMethodFlags; - value.verSig = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(pResult->verSig, GetCallInfo); + value.verSig = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(pResult->verSig, GetCallInfo, SigInstHandleMap); } value.accessAllowed = (DWORD)pResult->accessAllowed; @@ -1416,15 +1343,15 @@ void MethodContext::dmpGetCallInfo(const Agnostic_GetCallInfo& key, const Agnost SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKEN(key.ConstrainedResolvedToken).c_str(), key.callerHandle, key.flags); printf(", value mth-%016llX, mf-%08X cf-%08X" - " sig%s" - " vsig%s" + " sig-%s" + " vsig-%s" " ipl{at-%08X hnd-%016llX}" " sdi-%08X" " excp-%08X" " stubLookup{%s}", value.hMethod, value.methodFlags, value.classFlags, - SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(value.sig).c_str(), - SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(value.verSig).c_str(), value.instParamLookup.accessType, + SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(value.sig, GetCallInfo, SigInstHandleMap).c_str(), + SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(value.verSig, GetCallInfo, SigInstHandleMap).c_str(), value.instParamLookup.accessType, value.instParamLookup.handle, value.wrapperDelegateInvoke, value.exceptionCode, SpmiDumpHelper::DumpAgnostic_CORINFO_LOOKUP(value.stubLookup).c_str()); } @@ -1458,11 +1385,11 @@ void MethodContext::repGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken, pResult->hMethod = (CORINFO_METHOD_HANDLE)value.hMethod; pResult->methodFlags = (unsigned)value.methodFlags; pResult->classFlags = (unsigned)value.classFlags; - pResult->sig = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value.sig, GetCallInfo); + pResult->sig = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value.sig, GetCallInfo, SigInstHandleMap); if (flags & CORINFO_CALLINFO_VERIFICATION) { pResult->verMethodFlags = (unsigned)value.verMethodFlags; - pResult->verSig = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value.verSig, GetCallInfo); + pResult->verSig = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value.verSig, GetCallInfo, SigInstHandleMap); } pResult->accessAllowed = (CorInfoIsAccessAllowedResult)value.accessAllowed; pResult->callsiteCalloutHelper.helperNum = (CorInfoHelpFunc)value.callsiteCalloutHelper.helperNum; @@ -2489,21 +2416,20 @@ void MethodContext::recGetArgType(CORINFO_SIG_INFO* sig, DWORD exceptionCode) { if (GetArgType == nullptr) - GetArgType = new LightWeightMap(); + GetArgType = new LightWeightMap(); - GetArgTypeValue key; + Agnostic_GetArgType_Key key; ZeroMemory(&key, sizeof(key)); // We use the input structs as a key and use memcmp to compare.. so // we need to zero out padding too - // Only setting values for things the EE seems to pay attention to... this is necessary since some of the values + + // Only setting values for CORINFO_SIG_INFO things the EE seems to pay attention to... this is necessary since some of the values // are unset and fail our precise comparisons ... key.flags = (DWORD)sig->flags; key.numArgs = (DWORD)sig->numArgs; - key.sigInst_classInstCount = (DWORD)sig->sigInst.classInstCount; - key.sigInst_classInst_Index = - (DWORD)GetArgType->AddBuffer((unsigned char*)sig->sigInst.classInst, sig->sigInst.classInstCount * 8); - key.sigInst_methInstCount = (DWORD)sig->sigInst.methInstCount; - key.sigInst_methInst_Index = - (DWORD)GetArgType->AddBuffer((unsigned char*)sig->sigInst.methInst, sig->sigInst.methInstCount * 8); + + SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INST_HandleArray(sig->sigInst.classInstCount, sig->sigInst.classInst, SigInstHandleMap, &key.sigInst_classInstCount, &key.sigInst_classInst_Index); + SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INST_HandleArray(sig->sigInst.methInstCount, sig->sigInst.methInst, SigInstHandleMap, &key.sigInst_methInstCount, &key.sigInst_methInst_Index); + key.scope = CastHandle(sig->scope); key.args = CastHandle(args); @@ -2515,34 +2441,35 @@ void MethodContext::recGetArgType(CORINFO_SIG_INFO* sig, GetArgType->Add(key, value); DEBUG_REC(dmpGetArgType(key, value)); } -void MethodContext::dmpGetArgType(const GetArgTypeValue& key, const Agnostic_GetArgType_Value& value) +void MethodContext::dmpGetArgType(const Agnostic_GetArgType_Key& key, const Agnostic_GetArgType_Value& value) { - printf("GetArgType key flg-%08X na-%u cc-%u ci-%u mc-%u mi-%u scp-%016llX arg-%016llX", key.flags, key.numArgs, - key.sigInst_classInstCount, key.sigInst_classInst_Index, key.sigInst_methInstCount, - key.sigInst_methInst_Index, key.scope, key.args); - printf(", value rt-%016llX ci-%u excp-%08X", value.vcTypeRet, value.result, value.exceptionCode); + printf("GetArgType key flg-%08X na-%u %s %s scp-%016llX arg-%016llX", key.flags, key.numArgs, + SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INST_Element("", "cc", "ci", key.sigInst_classInstCount, key.sigInst_classInst_Index, SigInstHandleMap).c_str(), + SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INST_Element("", "mc", "mi", key.sigInst_methInstCount, key.sigInst_methInst_Index, SigInstHandleMap).c_str(), + key.scope, key.args); + printf(", value rt-%016llX cit-%u excp-%08X", value.vcTypeRet, value.result, value.exceptionCode); } CorInfoTypeWithMod MethodContext::repGetArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, DWORD* exceptionCode) { - GetArgTypeValue key; - ZeroMemory(&key, sizeof(GetArgTypeValue)); // We use the input structs as a key and use memcmp to compare.. so + Agnostic_GetArgType_Key key; + ZeroMemory(&key, sizeof(Agnostic_GetArgType_Key)); // We use the input structs as a key and use memcmp to compare.. so // we need to zero out padding too AssertCodeMsg(GetArgType != nullptr, EXCEPTIONCODE_MC, "Didn't find %016llx, %016llx. probably a missing exception in getArgType", key.scope, key.args); + key.flags = (DWORD)sig->flags; key.numArgs = (DWORD)sig->numArgs; key.sigInst_classInstCount = (DWORD)sig->sigInst.classInstCount; - key.sigInst_classInst_Index = - (DWORD)GetArgType->Contains((unsigned char*)sig->sigInst.classInst, sig->sigInst.classInstCount * 8); - key.sigInst_methInstCount = (DWORD)sig->sigInst.methInstCount; - key.sigInst_methInst_Index = - (DWORD)GetArgType->Contains((unsigned char*)sig->sigInst.methInst, sig->sigInst.methInstCount * 8); - key.scope = CastHandle(sig->scope); - key.args = CastHandle(args); + key.sigInst_methInstCount = (DWORD)sig->sigInst.methInstCount; + key.scope = CastHandle(sig->scope); + key.args = CastHandle(args); + + key.sigInst_classInst_Index = SpmiRecordsHelper::ContainsHandleMap(sig->sigInst.classInstCount, sig->sigInst.classInst, SigInstHandleMap); + key.sigInst_methInst_Index = SpmiRecordsHelper::ContainsHandleMap(sig->sigInst.methInstCount, sig->sigInst.methInst, SigInstHandleMap); AssertCodeMsg(GetArgType->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llx, %016llx. probably a missing exception in getArgType", key.scope, key.args); @@ -2585,15 +2512,15 @@ void MethodContext::recGetMethodSig(CORINFO_METHOD_HANDLE ftn, CORINFO_SIG_INFO* key.A = CastHandle(ftn); key.B = CastHandle(memberParent); - Agnostic_CORINFO_SIG_INFO value = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(*sig, GetMethodSig); + Agnostic_CORINFO_SIG_INFO value = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(*sig, GetMethodSig, SigInstHandleMap); GetMethodSig->Add(key, value); DEBUG_REC(dmpGetMethodSig(key, value)); } void MethodContext::dmpGetMethodSig(DLDL key, const Agnostic_CORINFO_SIG_INFO& value) { - printf("GetMethodSig key ftn-%016llX prt-%016llX, value %s", key.A, key.B, - SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(value).c_str()); + printf("GetMethodSig key ftn-%016llX prt-%016llX, value-%s", key.A, key.B, + SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(value, GetMethodSig, SigInstHandleMap).c_str()); } void MethodContext::repGetMethodSig(CORINFO_METHOD_HANDLE ftn, CORINFO_SIG_INFO* sig, CORINFO_CLASS_HANDLE memberParent) { @@ -2607,7 +2534,7 @@ void MethodContext::repGetMethodSig(CORINFO_METHOD_HANDLE ftn, CORINFO_SIG_INFO* value = GetMethodSig->Get(key); - *sig = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value, GetMethodSig); + *sig = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value, GetMethodSig, SigInstHandleMap); DEBUG_REP(dmpGetMethodSig(key, value)); } @@ -2618,19 +2545,18 @@ void MethodContext::recGetArgClass(CORINFO_SIG_INFO* sig, DWORD exceptionCode) { if (GetArgClass == nullptr) - GetArgClass = new LightWeightMap(); + GetArgClass = new LightWeightMap(); - GetArgClassValue key; - ZeroMemory(&key, sizeof(GetArgClassValue)); // We use the input structs as a key and use memcmp to compare.. so - // we need to zero out padding too - // Only setting values for things the EE seems to pay attention to... this is necessary since some of the values + Agnostic_GetArgClass_Key key; + ZeroMemory(&key, sizeof(Agnostic_GetArgClass_Key)); // We use the input structs as a key and use memcmp to compare.. so + // we need to zero out padding too + + // Only setting values for CORINFO_SIG_INFO things the EE seems to pay attention to... this is necessary since some of the values // are unset and fail our precise comparisions... - key.sigInst_classInstCount = (DWORD)sig->sigInst.classInstCount; - key.sigInst_classInst_Index = - (DWORD)GetArgClass->AddBuffer((unsigned char*)sig->sigInst.classInst, sig->sigInst.classInstCount * 8); - key.sigInst_methInstCount = (DWORD)sig->sigInst.methInstCount; - key.sigInst_methInst_Index = - (DWORD)GetArgClass->AddBuffer((unsigned char*)sig->sigInst.methInst, sig->sigInst.methInstCount * 8); + + SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INST_HandleArray(sig->sigInst.classInstCount, sig->sigInst.classInst, SigInstHandleMap, &key.sigInst_classInstCount, &key.sigInst_classInst_Index); + SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INST_HandleArray(sig->sigInst.methInstCount, sig->sigInst.methInst, SigInstHandleMap, &key.sigInst_methInstCount, &key.sigInst_methInst_Index); + key.scope = CastHandle(sig->scope); key.args = CastHandle(args); @@ -2641,30 +2567,31 @@ void MethodContext::recGetArgClass(CORINFO_SIG_INFO* sig, GetArgClass->Add(key, value); DEBUG_REC(dmpGetArgClass(key, value)); } -void MethodContext::dmpGetArgClass(const GetArgClassValue& key, const Agnostic_GetArgClass_Value& value) +void MethodContext::dmpGetArgClass(const Agnostic_GetArgClass_Key& key, const Agnostic_GetArgClass_Value& value) { - printf("GetArgClass key cc-%u ci-%u mc-%u mi-%u scp-%016llX args-%016llX", key.sigInst_classInstCount, - key.sigInst_classInst_Index, key.sigInst_methInstCount, key.sigInst_methInst_Index, key.scope, key.args); + printf("GetArgClass key %s %s scp-%016llX args-%016llX", + SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INST_Element("", "cc", "ci", key.sigInst_classInstCount, key.sigInst_classInst_Index, SigInstHandleMap).c_str(), + SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INST_Element("", "mc", "mi", key.sigInst_methInstCount, key.sigInst_methInst_Index, SigInstHandleMap).c_str(), + key.scope, key.args); printf(", value %016llX excp-%08X", value.result, value.exceptionCode); } CORINFO_CLASS_HANDLE MethodContext::repGetArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, DWORD* exceptionCode) { - GetArgClassValue key; - ZeroMemory(&key, sizeof(GetArgClassValue)); // We use the input structs as a key and use memcmp to compare.. so - // we need to zero out padding too + Agnostic_GetArgClass_Key key; + ZeroMemory(&key, sizeof(Agnostic_GetArgClass_Key)); // We use the input structs as a key and use memcmp to compare.. so + // we need to zero out padding too AssertCodeMsg(GetArgClass != nullptr, EXCEPTIONCODE_MC, "Didn't find %016llx, %016llx. probably a missing exception in getArgClass", key.scope, key.args); key.sigInst_classInstCount = (DWORD)sig->sigInst.classInstCount; - key.sigInst_classInst_Index = - (DWORD)GetArgClass->Contains((unsigned char*)sig->sigInst.classInst, sig->sigInst.classInstCount * 8); - key.sigInst_methInstCount = (DWORD)sig->sigInst.methInstCount; - key.sigInst_methInst_Index = - (DWORD)GetArgClass->Contains((unsigned char*)sig->sigInst.methInst, sig->sigInst.methInstCount * 8); - key.scope = CastHandle(sig->scope); - key.args = CastHandle(args); + key.sigInst_methInstCount = (DWORD)sig->sigInst.methInstCount; + key.scope = CastHandle(sig->scope); + key.args = CastHandle(args); + + key.sigInst_classInst_Index = SpmiRecordsHelper::ContainsHandleMap(sig->sigInst.classInstCount, sig->sigInst.classInst, SigInstHandleMap); + key.sigInst_methInst_Index = SpmiRecordsHelper::ContainsHandleMap(sig->sigInst.methInstCount, sig->sigInst.methInst, SigInstHandleMap); AssertCodeMsg(GetArgClass->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llx, %016llx. probably a missing exception in getArgClass", key.scope, key.args); @@ -2718,53 +2645,17 @@ void MethodContext::recGetMethodInfo(CORINFO_METHOD_HANDLE ftn, if (result) { - value.info.ftn = CastHandle(info->ftn); - value.info.scope = CastHandle(info->scope); - value.info.ILCode_offset = (DWORD)GetMethodInfo->AddBuffer(info->ILCode, info->ILCodeSize); - value.info.ILCodeSize = (DWORD)info->ILCodeSize; - value.info.maxStack = (DWORD)info->maxStack; - value.info.EHcount = (DWORD)info->EHcount; - value.info.options = (DWORD)info->options; - value.info.regionKind = (DWORD)info->regionKind; - value.info.args.callConv = (DWORD)info->args.callConv; - value.info.args.retTypeClass = CastHandle(info->args.retTypeClass); - value.info.args.retTypeSigClass = CastHandle(info->args.retTypeSigClass); - value.info.args.retType = (DWORD)info->args.retType; - value.info.args.flags = (DWORD)info->args.flags; - value.info.args.numArgs = (DWORD)info->args.numArgs; - value.info.args.sigInst_classInstCount = (DWORD)info->args.sigInst.classInstCount; - value.info.args.sigInst_classInst_Index = - (DWORD)GetMethodInfo->AddBuffer((unsigned char*)info->args.sigInst.classInst, - info->args.sigInst.classInstCount * 8); // porting issue - value.info.args.sigInst_methInstCount = (DWORD)info->args.sigInst.methInstCount; - value.info.args.sigInst_methInst_Index = - (DWORD)GetMethodInfo->AddBuffer((unsigned char*)info->args.sigInst.methInst, - info->args.sigInst.methInstCount * 8); // porting issue - value.info.args.args = CastHandle(info->args.args); - value.info.args.cbSig = (DWORD)info->args.cbSig; - value.info.args.pSig_Index = (DWORD)GetMethodInfo->AddBuffer((unsigned char*)info->args.pSig, info->args.cbSig); - value.info.args.scope = CastHandle(info->args.scope); - value.info.args.token = (DWORD)info->args.token; - value.info.locals.callConv = (DWORD)info->locals.callConv; - value.info.locals.retTypeClass = CastHandle(info->locals.retTypeClass); - value.info.locals.retTypeSigClass = CastHandle(info->locals.retTypeSigClass); - value.info.locals.retType = (DWORD)info->locals.retType; - value.info.locals.flags = (DWORD)info->locals.flags; - value.info.locals.numArgs = (DWORD)info->locals.numArgs; - value.info.locals.sigInst_classInstCount = (DWORD)info->locals.sigInst.classInstCount; - value.info.locals.sigInst_classInst_Index = - (DWORD)GetMethodInfo->AddBuffer((unsigned char*)info->locals.sigInst.classInst, - info->locals.sigInst.classInstCount * 8); // porting issue - value.info.locals.sigInst_methInstCount = (DWORD)info->locals.sigInst.methInstCount; - value.info.locals.sigInst_methInst_Index = - (DWORD)GetMethodInfo->AddBuffer((unsigned char*)info->locals.sigInst.methInst, - info->locals.sigInst.methInstCount * 8); // porting issue - value.info.locals.args = CastHandle(info->locals.args); - value.info.locals.cbSig = (DWORD)info->locals.cbSig; - value.info.locals.pSig_Index = - (DWORD)GetMethodInfo->AddBuffer((unsigned char*)info->locals.pSig, info->locals.cbSig); - value.info.locals.scope = CastHandle(info->locals.scope); - value.info.locals.token = (DWORD)info->locals.token; + value.info.ftn = CastHandle(info->ftn); + value.info.scope = CastHandle(info->scope); + value.info.ILCode_offset = (DWORD)GetMethodInfo->AddBuffer(info->ILCode, info->ILCodeSize); + value.info.ILCodeSize = (DWORD)info->ILCodeSize; + value.info.maxStack = (DWORD)info->maxStack; + value.info.EHcount = (DWORD)info->EHcount; + value.info.options = (DWORD)info->options; + value.info.regionKind = (DWORD)info->regionKind; + + value.info.args = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(info->args, GetMethodInfo, SigInstHandleMap); + value.info.locals = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(info->locals, GetMethodInfo, SigInstHandleMap); } value.result = result; value.exceptionCode = (DWORD)exceptionCode; @@ -2774,80 +2665,43 @@ void MethodContext::recGetMethodInfo(CORINFO_METHOD_HANDLE ftn, } void MethodContext::dmpGetMethodInfo(DWORDLONG key, const Agnostic_GetMethodInfo& value) { - printf("GetMethodInfo key ftn-%016llX", key); - printf(", value res-%u ftn-%016llX scp-%016llX ilo-%u ils-%u ms-%u ehc-%u opt-%08X rk-%u " - "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 " - "pSig_Index-%u scp-%016llX tok-%08X} " - "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 " - "pSig_Index-%u scp-%016llX tok-%08X} " - "excp-%08X", - value.result, value.info.ftn, value.info.scope, value.info.ILCode_offset, value.info.ILCodeSize, - value.info.maxStack, value.info.EHcount, value.info.options, value.info.regionKind, value.info.args.callConv, - value.info.args.retTypeClass, value.info.args.retTypeSigClass, value.info.args.retType, - toString((CorInfoType)value.info.args.retType), value.info.args.flags, value.info.args.numArgs, - value.info.args.sigInst_classInstCount, value.info.args.sigInst_classInst_Index, - value.info.args.sigInst_methInstCount, value.info.args.sigInst_methInst_Index, value.info.args.args, - value.info.args.cbSig, value.info.args.pSig_Index, value.info.args.scope, value.info.args.token, - value.info.locals.callConv, value.info.locals.retTypeClass, value.info.locals.retTypeSigClass, - value.info.locals.retType, toString((CorInfoType)value.info.locals.retType), value.info.locals.flags, - value.info.locals.numArgs, value.info.locals.sigInst_classInstCount, - value.info.locals.sigInst_classInst_Index, value.info.locals.sigInst_methInstCount, - value.info.locals.sigInst_methInst_Index, value.info.locals.args, value.info.locals.cbSig, - value.info.locals.pSig_Index, value.info.locals.scope, value.info.locals.token, value.exceptionCode); + if (value.result) + { + printf("GetMethodInfo key ftn-%016llX, value res-%u ftn-%016llX scp-%016llX ilo-%u ils-%u ms-%u ehc-%u opt-%08X rk-%u args-%s locals-%s excp-%08X", + key, value.result, value.info.ftn, value.info.scope, value.info.ILCode_offset, value.info.ILCodeSize, + value.info.maxStack, value.info.EHcount, value.info.options, value.info.regionKind, + SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(value.info.args, GetMethodInfo, SigInstHandleMap).c_str(), + SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(value.info.locals, GetMethodInfo, SigInstHandleMap).c_str(), + value.exceptionCode); + } + else + { + printf("GetMethodInfo key ftn-%016llX, value res-%u excp-%08X", + key, value.result, value.exceptionCode); + } } bool MethodContext::repGetMethodInfo(CORINFO_METHOD_HANDLE ftn, CORINFO_METHOD_INFO* info, DWORD* exceptionCode) { Agnostic_GetMethodInfo value; AssertCodeMsg(GetMethodInfo != nullptr, EXCEPTIONCODE_MC, - "Didn't find %016llx. probably a missing exception in getMethodInfo", CastHandle(ftn)); + "Didn't find %016llx. GetMethodInfo == nullptr. probably a missing exception in getMethodInfo", CastHandle(ftn)); AssertCodeMsg(GetMethodInfo->GetIndex(CastHandle(ftn)) != -1, EXCEPTIONCODE_MC, "Didn't find %016llx. probably a missing exception in getMethodInfo", CastHandle(ftn)); value = GetMethodInfo->Get(CastHandle(ftn)); if (value.result) { - info->ftn = (CORINFO_METHOD_HANDLE)value.info.ftn; - info->scope = (CORINFO_MODULE_HANDLE)value.info.scope; - info->ILCode = GetMethodInfo->GetBuffer(value.info.ILCode_offset); - info->ILCodeSize = (unsigned)value.info.ILCodeSize; - info->maxStack = (unsigned)value.info.maxStack; - info->EHcount = (unsigned)value.info.EHcount; - info->options = (CorInfoOptions)value.info.options; - info->regionKind = (CorInfoRegionKind)value.info.regionKind; - info->args.callConv = (CorInfoCallConv)value.info.args.callConv; - info->args.retTypeClass = (CORINFO_CLASS_HANDLE)value.info.args.retTypeClass; - info->args.retTypeSigClass = (CORINFO_CLASS_HANDLE)value.info.args.retTypeSigClass; - info->args.retType = (CorInfoType)value.info.args.retType; - info->args.flags = (unsigned)value.info.args.flags; - info->args.numArgs = (unsigned)value.info.args.numArgs; - info->args.sigInst.classInstCount = (unsigned)value.info.args.sigInst_classInstCount; - info->args.sigInst.classInst = - (CORINFO_CLASS_HANDLE*)GetMethodInfo->GetBuffer(value.info.args.sigInst_classInst_Index); - info->args.sigInst.methInstCount = (unsigned)value.info.args.sigInst_methInstCount; - info->args.sigInst.methInst = - (CORINFO_CLASS_HANDLE*)GetMethodInfo->GetBuffer(value.info.args.sigInst_methInst_Index); - info->args.args = (CORINFO_ARG_LIST_HANDLE)value.info.args.args; - info->args.cbSig = (unsigned int)value.info.args.cbSig; - info->args.pSig = (PCCOR_SIGNATURE)GetMethodInfo->GetBuffer(value.info.args.pSig_Index); - info->args.scope = (CORINFO_MODULE_HANDLE)value.info.args.scope; - info->args.token = (mdToken)value.info.args.token; - info->locals.callConv = (CorInfoCallConv)value.info.locals.callConv; - info->locals.retTypeClass = (CORINFO_CLASS_HANDLE)value.info.locals.retTypeClass; - info->locals.retTypeSigClass = (CORINFO_CLASS_HANDLE)value.info.locals.retTypeSigClass; - info->locals.retType = (CorInfoType)value.info.locals.retType; - info->locals.flags = (unsigned)value.info.locals.flags; - info->locals.numArgs = (unsigned)value.info.locals.numArgs; - info->locals.sigInst.classInstCount = (unsigned)value.info.locals.sigInst_classInstCount; - info->locals.sigInst.classInst = - (CORINFO_CLASS_HANDLE*)GetMethodInfo->GetBuffer(value.info.locals.sigInst_classInst_Index); - info->locals.sigInst.methInstCount = (unsigned)value.info.locals.sigInst_methInstCount; - info->locals.sigInst.methInst = - (CORINFO_CLASS_HANDLE*)GetMethodInfo->GetBuffer(value.info.locals.sigInst_methInst_Index); - info->locals.args = (CORINFO_ARG_LIST_HANDLE)value.info.locals.args; - info->locals.cbSig = (unsigned int)value.info.locals.cbSig; - info->locals.pSig = (PCCOR_SIGNATURE)GetMethodInfo->GetBuffer(value.info.locals.pSig_Index); - info->locals.scope = (CORINFO_MODULE_HANDLE)value.info.locals.scope; - info->locals.token = (mdToken)value.info.locals.token; + info->ftn = (CORINFO_METHOD_HANDLE)value.info.ftn; + info->scope = (CORINFO_MODULE_HANDLE)value.info.scope; + info->ILCode = GetMethodInfo->GetBuffer(value.info.ILCode_offset); + info->ILCodeSize = (unsigned)value.info.ILCodeSize; + info->maxStack = (unsigned)value.info.maxStack; + info->EHcount = (unsigned)value.info.EHcount; + info->options = (CorInfoOptions)value.info.options; + info->regionKind = (CorInfoRegionKind)value.info.regionKind; + + info->args = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value.info.args, GetMethodInfo, SigInstHandleMap); + info->locals = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value.info.locals, GetMethodInfo, SigInstHandleMap); } bool result = value.result; *exceptionCode = (DWORD)value.exceptionCode; @@ -2857,7 +2711,7 @@ bool MethodContext::repGetMethodInfo(CORINFO_METHOD_HANDLE ftn, CORINFO_METHOD_I void MethodContext::recGetNewHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, - bool* pHasSideEffects, + bool* pHasSideEffects, CorInfoHelpFunc result) { if (GetNewHelper == nullptr) @@ -2882,7 +2736,7 @@ void MethodContext::dmpGetNewHelper(const Agnostic_GetNewHelper& key, DD value) } CorInfoHelpFunc MethodContext::repGetNewHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_METHOD_HANDLE callerHandle, - bool* pHasSideEffects) + bool* pHasSideEffects) { Agnostic_GetNewHelper key; ZeroMemory(&key, sizeof(Agnostic_GetNewHelper)); // We use the input structs as a key and use memcmp to compare.. so @@ -3873,7 +3727,7 @@ void MethodContext::recFindSig(CORINFO_MODULE_HANDLE moduleHandle, key.sigTOK = (DWORD)sigTOK; key.context = CastHandle(context); - Agnostic_CORINFO_SIG_INFO value = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(*sig, FindSig); + Agnostic_CORINFO_SIG_INFO value = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(*sig, FindSig, SigInstHandleMap); FindSig->Add(key, value); DEBUG_REC(dmpFindSig(key, value)); @@ -3881,13 +3735,8 @@ void MethodContext::recFindSig(CORINFO_MODULE_HANDLE moduleHandle, void MethodContext::dmpFindSig(const Agnostic_FindSig& key, const Agnostic_CORINFO_SIG_INFO& value) { printf("FindSig key module-%016llX sigTOK-%08X context-%016llX", key.module, key.sigTOK, key.context); - printf(", value callConv-%08X retTypeClass-%016llX retTypeSigClass-%016llX retType-%u(%s) flags-%08X numArgs-%08X " - "classInstCount-%08X classInd-%08X " - "methInstCount-%08X methInd-%08X args-%016llX cbSig-%08X pSig_Index-%08X scope-%016llX token-%08X", - value.callConv, value.retTypeClass, value.retTypeSigClass, value.retType, - toString((CorInfoType)value.retType), value.flags, value.numArgs, value.sigInst_classInstCount, - value.sigInst_classInst_Index, value.sigInst_methInstCount, value.sigInst_methInst_Index, value.args, - value.cbSig, value.pSig_Index, value.scope, value.token); + printf(", value-%s", + SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(value, FindSig, SigInstHandleMap).c_str()); } void MethodContext::repFindSig(CORINFO_MODULE_HANDLE moduleHandle, unsigned sigTOK, @@ -3905,7 +3754,7 @@ void MethodContext::repFindSig(CORINFO_MODULE_HANDLE moduleHandle, value = FindSig->Get(key); - *sig = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value, FindSig); + *sig = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value, FindSig, SigInstHandleMap); DEBUG_REP(dmpFindSig(key, value)); } @@ -5044,7 +4893,7 @@ void MethodContext::recFindCallSiteSig(CORINFO_MODULE_HANDLE module, key.methTok = (DWORD)methTOK; key.context = CastHandle(context); - Agnostic_CORINFO_SIG_INFO value = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(*sig, FindCallSiteSig); + Agnostic_CORINFO_SIG_INFO value = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(*sig, FindCallSiteSig, SigInstHandleMap); FindCallSiteSig->Add(key, value); DEBUG_REC(dmpFindCallSiteSig(key, value)); @@ -5052,13 +4901,8 @@ void MethodContext::recFindCallSiteSig(CORINFO_MODULE_HANDLE module, void MethodContext::dmpFindCallSiteSig(const Agnostic_FindCallSiteSig& key, const Agnostic_CORINFO_SIG_INFO& value) { printf("dmpFindCallSiteSig key module-%016llX methTok-%08X context-%016llX", key.module, key.methTok, key.context); - printf(", value callConv-%08X retTypeClass-%016llX retTypeSigClass-%016llX retType-%u(%s) flags-%08X numArgs-%08X " - "classInstCount-%08X classInd-%08X " - "methInstCount-%08X methInd-%08X args-%016llX cbSig-%08X pSig_Index-%08X scope-%016llX token-%08X", - value.callConv, value.retTypeClass, value.retTypeSigClass, value.retType, - toString((CorInfoType)value.retType), value.flags, value.numArgs, value.sigInst_classInstCount, - value.sigInst_classInst_Index, value.sigInst_methInstCount, value.sigInst_methInst_Index, value.args, - value.cbSig, value.pSig_Index, value.scope, value.token); + printf(", value-%s", + SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(value, FindCallSiteSig, SigInstHandleMap).c_str()); } void MethodContext::repFindCallSiteSig(CORINFO_MODULE_HANDLE module, unsigned methTOK, @@ -5078,7 +4922,7 @@ void MethodContext::repFindCallSiteSig(CORINFO_MODULE_HANDLE module, AssertCodeMsg(FindCallSiteSig->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %08X", (DWORD)key.methTok); value = FindCallSiteSig->Get(key); - *sig = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value, FindCallSiteSig); + *sig = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value, FindCallSiteSig, SigInstHandleMap); DEBUG_REP(dmpFindCallSiteSig(key, value)); } @@ -5896,6 +5740,27 @@ WORD MethodContext::repGetRelocTypeHint(void* target) return retVal; } +void MethodContext::recGetExpectedTargetArchitecture(DWORD result) +{ + if (GetExpectedTargetArchitecture == nullptr) + GetExpectedTargetArchitecture = new LightWeightMap(); + + DWORD key = 0; // There is only ever a single entry to this map + GetExpectedTargetArchitecture->Add(key, result); + DEBUG_REC(dmpGetExpectedTargetArchitecture(key, result)); +} +void MethodContext::dmpGetExpectedTargetArchitecture(DWORD key, DWORD result) +{ + printf("GetExpectedTargetArchitecture key %u, res %u", key, result); +} +DWORD MethodContext::repGetExpectedTargetArchitecture() +{ + DWORD key = 0; + DWORD result = GetExpectedTargetArchitecture->Get(key); + DEBUG_REP(dmpGetExpectedTargetArchitecture(key, result)); + return result; +} + void MethodContext::recIsValidToken(CORINFO_MODULE_HANDLE module, unsigned metaTOK, bool result) { if (IsValidToken == nullptr) @@ -5950,7 +5815,7 @@ const char* MethodContext::repGetClassName(CORINFO_CLASS_HANDLE cls) return "hackishClassName"; int offset = GetClassName->Get(CastHandle(cls)); const char* name = (const char*)GetClassName->GetBuffer(offset); - DEBUG_REC(dmpGetClassName(CastHandle(cls), (DWORD)offset)); + DEBUG_REP(dmpGetClassName(CastHandle(cls), (DWORD)offset)); return name; } @@ -6126,7 +5991,7 @@ void MethodContext::recGetTailCallHelpers( ZeroMemory(&key, sizeof(Agnostic_GetTailCallHelpers)); key.callToken = SpmiRecordsHelper::StoreAgnostic_CORINFO_RESOLVED_TOKEN(callToken, GetTailCallHelpers); - key.sig = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(*sig, GetTailCallHelpers); + key.sig = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(*sig, GetTailCallHelpers, SigInstHandleMap); key.flags = (DWORD)flags; Agnostic_CORINFO_TAILCALL_HELPERS value; @@ -6148,7 +6013,7 @@ void MethodContext::dmpGetTailCallHelpers(const Agnostic_GetTailCallHelpers& key { printf("GetTailCallHelpers key callToken-%s sig-%s flg-%08X", SpmiDumpHelper::DumpAgnostic_CORINFO_RESOLVED_TOKEN(key.callToken).c_str(), - SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(key.sig).c_str(), + SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(key.sig, GetTailCallHelpers, SigInstHandleMap).c_str(), key.flags); printf(", value result-%s flg-%08X hStoreArgs-%016llX hCallTarget-%016llX hDispatcher-%016llX", value.result ? "true" : "false", @@ -6169,7 +6034,7 @@ bool MethodContext::repGetTailCallHelpers( Agnostic_GetTailCallHelpers key; ZeroMemory(&key, sizeof(Agnostic_GetTailCallHelpers)); key.callToken = SpmiRecordsHelper::RestoreAgnostic_CORINFO_RESOLVED_TOKEN(callToken, GetTailCallHelpers); - key.sig = SpmiRecordsHelper::RestoreAgnostic_CORINFO_SIG_INFO(*sig, GetTailCallHelpers); + key.sig = SpmiRecordsHelper::RestoreAgnostic_CORINFO_SIG_INFO(*sig, GetTailCallHelpers, SigInstHandleMap); key.flags = (DWORD)flags; AssertCodeMsg(GetTailCallHelpers->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Could not find matching tail call helper call"); @@ -6391,6 +6256,11 @@ const WCHAR* MethodContext::repGetStringConfigValue(const WCHAR* name) return value; } +void MethodContext::dmpSigInstHandleMap(DWORD key, DWORDLONG value) +{ + printf("SigInstHandleMap key %u, value %016llX", key, value); +} + int MethodContext::dumpMethodIdentityInfoToBuffer(char* buff, int len, bool ignoreMethodName /* = false */, CORINFO_METHOD_INFO* optInfo /* = nullptr */, unsigned optFlags /* = 0 */) { if (len < METHOD_IDENTITY_INFO_SIZE) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h index 666c771..a2b7833 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h @@ -16,6 +16,9 @@ #include "errorhandling.h" #include "hash.h" +// Helper function for dumping. +const char* toString(CorInfoType cit); + #define METHOD_IDENTITY_INFO_SIZE 0x10000 // We assume that the METHOD_IDENTITY_INFO_SIZE will not exceed 64KB class MethodContext @@ -123,7 +126,7 @@ public: DWORD pMethodSpec_Index; DWORD cbMethodSpec; }; - struct GetArgTypeValue + struct Agnostic_GetArgType_Key { DWORD flags; DWORD numArgs; @@ -134,7 +137,7 @@ public: DWORDLONG scope; DWORDLONG args; }; - struct GetArgClassValue + struct Agnostic_GetArgClass_Key { DWORD sigInst_classInstCount; DWORD sigInst_classInst_Index; @@ -613,8 +616,11 @@ public: unsigned int saveToFile(HANDLE hFile); unsigned int calculateFileSize(); unsigned int calculateRawFileSize(); - void dumpToConsole(int mcNumber = -1); // if mcNumber is not -1, display the method context number before the dumped - // info + + // dumpToConsole: If mcNumber is not -1, display the method context number before the dumped info. + // If simple is `true`, don't display the function name/arguments in the header. + void dumpToConsole(int mcNumber = -1, bool simple = false); + int dumpStatToBuffer(char* buff, int len); static int dumpStatTitleToBuffer(char* buff, int len); int methodSize; @@ -872,7 +878,7 @@ public: CORINFO_CLASS_HANDLE* vcTypeRet, CorInfoTypeWithMod result, DWORD exception); - void dmpGetArgType(const GetArgTypeValue& key, const Agnostic_GetArgType_Value& value); + void dmpGetArgType(const Agnostic_GetArgType_Key& key, const Agnostic_GetArgType_Value& value); CorInfoTypeWithMod repGetArgType(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE* vcTypeRet, @@ -890,7 +896,7 @@ public: CORINFO_ARG_LIST_HANDLE args, CORINFO_CLASS_HANDLE result, DWORD exceptionCode); - void dmpGetArgClass(const GetArgClassValue& key, const Agnostic_GetArgClass_Value& value); + void dmpGetArgClass(const Agnostic_GetArgClass_Key& key, const Agnostic_GetArgClass_Value& value); CORINFO_CLASS_HANDLE repGetArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, DWORD* exceptionCode); void recGetHFAType(CORINFO_CLASS_HANDLE clsHnd, CorInfoHFAElemType result); @@ -1276,6 +1282,10 @@ public: void dmpGetRelocTypeHint(DWORDLONG key, DWORD value); WORD repGetRelocTypeHint(void* target); + void recGetExpectedTargetArchitecture(DWORD result); + void dmpGetExpectedTargetArchitecture(DWORD key, DWORD result); + DWORD repGetExpectedTargetArchitecture(); + void recIsValidToken(CORINFO_MODULE_HANDLE module, unsigned metaTOK, bool result); void dmpIsValidToken(DLD key, DWORD value); bool repIsValidToken(CORINFO_MODULE_HANDLE module, unsigned metaTOK); @@ -1333,6 +1343,8 @@ public: void dmpGetStringConfigValue(DWORD nameIndex, DWORD result); const WCHAR* repGetStringConfigValue(const WCHAR* name); + void dmpSigInstHandleMap(DWORD key, DWORDLONG value); + struct Environment { Environment() : getIntConfigValue(nullptr), getStingConfigValue(nullptr) @@ -1500,6 +1512,7 @@ enum mcPackets Packet_GetPInvokeUnmanagedTarget = 82, // Retired 2/18/2020 Packet_GetProfilingHandle = 83, Packet_GetRelocTypeHint = 84, + Packet_GetExpectedTargetArchitecture = 183, // Added 12/18/2020 Packet_GetSecurityPrologHelper = 85, // Retired 2/18/2020 Packet_GetSharedCCtorHelper = 86, Packet_GetTailCallCopyArgsThunk = 87, // Retired 4/27/2020 @@ -1541,6 +1554,7 @@ enum mcPackets Packet_SatisfiesClassConstraints = 110, Packet_SatisfiesMethodConstraints = 111, Packet_ShouldEnforceCallvirtRestriction = 112, // Retired 2/18/2020 + Packet_SigInstHandleMap = 184, PacketCR_AddressMap = 113, PacketCR_AllocGCInfo = 114, diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.cpp index 2d7e8b5..acc8d7d 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.cpp @@ -85,13 +85,71 @@ std::string SpmiDumpHelper::DumpAgnostic_CORINFO_LOOKUP(const MethodContext::Agn return kind + std::string(" ") + lookupDescription; } -std::string SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(const MethodContext::Agnostic_CORINFO_SIG_INFO& sigInfo) +// Dump the consecutive elements of a DenseLightweightMap, which are DWORDLONG, and assumed to represent an array of handles. +void SpmiDumpHelper::FormatHandleArray(char*& pbuf, int& sizeOfBuffer, const DenseLightWeightMap* map, DWORD count, DWORD startIndex) +{ + int cch; + + cch = sprintf_s(pbuf, sizeOfBuffer, "{"); + pbuf += cch; + sizeOfBuffer -= cch; + + const unsigned int maxHandleArrayDisplayElems = 5; // Don't display more than this. + const unsigned int handleArrayDisplayElems = min(maxHandleArrayDisplayElems, count); + + bool first = true; + for (DWORD i = startIndex; i < startIndex + handleArrayDisplayElems; i++) + { + cch = sprintf_s(pbuf, sizeOfBuffer, "%s%016llX", first ? "" : " ", map->Get(i)); + pbuf += cch; + sizeOfBuffer -= cch; + + first = false; + } + + if (handleArrayDisplayElems < count) + { + cch = sprintf_s(pbuf, sizeOfBuffer, " ..."); + pbuf += cch; + sizeOfBuffer -= cch; + } + + cch = sprintf_s(pbuf, sizeOfBuffer, "}"); + pbuf += cch; + sizeOfBuffer -= cch; +} + +void SpmiDumpHelper::FormatAgnostic_CORINFO_SIG_INST_Element( + char*& pbuf, + int& sizeOfBuffer, + const char* prefixStr, + const char* instCountPrefixStr, + const char* instIndexPrefixStr, + unsigned handleInstCount, + unsigned handleInstIndex, + const DenseLightWeightMap* handleMap) +{ + int cch = sprintf_s(pbuf, sizeOfBuffer, "%s%s-%u %s-%u ", prefixStr, instCountPrefixStr, handleInstCount, instIndexPrefixStr, handleInstIndex); + pbuf += cch; + sizeOfBuffer -= cch; + + FormatHandleArray(pbuf, sizeOfBuffer, handleMap, handleInstCount, handleInstIndex); +} + +std::string SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INST_Element( + const char* prefixStr, + const char* instCountPrefixStr, + const char* instIndexPrefixStr, + unsigned handleInstCount, + unsigned handleInstIndex, + const DenseLightWeightMap* handleMap) { char buffer[MAX_BUFFER_SIZE]; - sprintf_s(buffer, MAX_BUFFER_SIZE, "{flg-%08X na-%u cc-%u ci-%u mc-%u mi-%u args-%016llX scp-%016llX tok-%08X}", - sigInfo.flags, sigInfo.numArgs, sigInfo.sigInst_classInstCount, sigInfo.sigInst_classInst_Index, - sigInfo.sigInst_methInstCount, sigInfo.sigInst_methInst_Index, sigInfo.args, sigInfo.scope, - sigInfo.token); + char* pbuf = buffer; + int sizeOfBuffer = sizeof(buffer); + + FormatAgnostic_CORINFO_SIG_INST_Element(pbuf, sizeOfBuffer, prefixStr, instCountPrefixStr, instIndexPrefixStr, handleInstCount, handleInstIndex, handleMap); + return std::string(buffer); } diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.h index 84349c0..c120056 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmidumphelper.h @@ -26,11 +26,118 @@ public: static std::string DumpAgnostic_CORINFO_RUNTIME_LOOKUP( const MethodContext::Agnostic_CORINFO_RUNTIME_LOOKUP& lookup); static std::string DumpAgnostic_CORINFO_LOOKUP(const MethodContext::Agnostic_CORINFO_LOOKUP& lookup); - static std::string DumpAgnostic_CORINFO_SIG_INFO(const MethodContext::Agnostic_CORINFO_SIG_INFO& sigInfo); + + template + static std::string DumpAgnostic_CORINFO_SIG_INFO( + const MethodContext::Agnostic_CORINFO_SIG_INFO& sigInfo, + LightWeightMap* buffers, + const DenseLightWeightMap* handleMap); + + static std::string DumpAgnostic_CORINFO_SIG_INST_Element( + const char* prefixStr, + const char* instCountPrefixStr, + const char* instIndexPrefixStr, + unsigned handleInstCount, + unsigned handleInstIndex, + const DenseLightWeightMap* handleMap); + static std::string DumpCorInfoFlag(CorInfoFlag flags); private: + + static void FormatAgnostic_CORINFO_SIG_INST_Element( + char*& pbuf, + int& sizeOfBuffer, + const char* prefixStr, + const char* instCountPrefixStr, + const char* instIndexPrefixStr, + unsigned handleInstCount, + unsigned handleInstIndex, + const DenseLightWeightMap* handleMap); + + static void FormatHandleArray(char*& pbuf, int& sizeOfBuffer, const DenseLightWeightMap* map, DWORD count, DWORD startIndex); + static const int MAX_BUFFER_SIZE = 1000; }; +template +inline std::string SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO( + const MethodContext::Agnostic_CORINFO_SIG_INFO& sigInfo, + LightWeightMap* buffers, + const DenseLightWeightMap* handleMap) +{ + char buffer[MAX_BUFFER_SIZE]; + char* pbuf = buffer; + int sizeOfBuffer = sizeof(buffer); + int cch; + + cch = sprintf_s(pbuf, sizeOfBuffer, "{callConv-%08X retTypeClass-%016llX retTypeSigClass-%016llX retType-%08X(%s) flg-%08X na-%u", + sigInfo.callConv, sigInfo.retTypeClass, sigInfo.retTypeSigClass, sigInfo.retType, toString((CorInfoType)sigInfo.retType), sigInfo.flags, sigInfo.numArgs); + pbuf += cch; + sizeOfBuffer -= cch; + + FormatAgnostic_CORINFO_SIG_INST_Element(pbuf, sizeOfBuffer, " ", "cc", "ci", sigInfo.sigInst_classInstCount, sigInfo.sigInst_classInst_Index, handleMap); + FormatAgnostic_CORINFO_SIG_INST_Element(pbuf, sizeOfBuffer, " ", "mc", "mi", sigInfo.sigInst_methInstCount, sigInfo.sigInst_methInst_Index, handleMap); + + cch = sprintf_s(pbuf, sizeOfBuffer, " args-%016llX si-%08X, cbSig-%08X", + sigInfo.args, sigInfo.pSig_Index, sigInfo.cbSig); + pbuf += cch; + sizeOfBuffer -= cch; + + // Add the signature bytes to the output. + // Normally, pSig_Index will be -1 if there is no signature. However, in some error cases + // it will be 0 if there are other reasons why it will never be consulted (like a "return value" + // from an API of `false`). So check that cbSig > 0 before calling GetBuffer(), just to be sure + // there is some data to find. + + if (sigInfo.cbSig == 0) + { + cch = sprintf_s(pbuf, sizeOfBuffer, " (SIG SIZE ZERO)"); + pbuf += cch; + sizeOfBuffer -= cch; + } + else + { + PCCOR_SIGNATURE pSig = buffers->GetBuffer(sigInfo.pSig_Index); + if (pSig == nullptr) + { + cch = sprintf_s(pbuf, sizeOfBuffer, " (NO SIG FOUND)"); + pbuf += cch; + sizeOfBuffer -= cch; + } + else + { + cch = sprintf_s(pbuf, sizeOfBuffer, " sig-{"); + pbuf += cch; + sizeOfBuffer -= cch; + + const unsigned int maxSigDisplayBytes = 25; // Don't display more than this. + const unsigned int sigDisplayBytes = min(maxSigDisplayBytes, sigInfo.cbSig); + + for (DWORD i = 0; i < sigDisplayBytes; i++) + { + cch = sprintf_s(pbuf, sizeOfBuffer, "%02X", pSig[i]); + pbuf += cch; + sizeOfBuffer -= cch; + } + + if (sigDisplayBytes < sigInfo.cbSig) + { + cch = sprintf_s(pbuf, sizeOfBuffer, "..."); + pbuf += cch; + sizeOfBuffer -= cch; + } + + cch = sprintf_s(pbuf, sizeOfBuffer, "}"); + pbuf += cch; + sizeOfBuffer -= cch; + } + } + + cch = sprintf_s(pbuf, sizeOfBuffer, " scp-%016llX tok-%08X}", + sigInfo.scope, sigInfo.token); + + return std::string(buffer); +} + #endif diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmirecordhelper.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmirecordhelper.h index 4b0a616..a3842c4 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmirecordhelper.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmirecordhelper.h @@ -45,19 +45,49 @@ public: LightWeightMap* buffers); static MethodContext::Agnostic_CORINFO_SIG_INFO CreateAgnostic_CORINFO_SIG_INFO_without_buffers( - CORINFO_SIG_INFO& sigInfo); + const CORINFO_SIG_INFO& sigInfo); + + static void StoreAgnostic_CORINFO_SIG_INST_HandleArray( + unsigned handleInstCount, + CORINFO_CLASS_HANDLE* handleInstArray, + DenseLightWeightMap*& handleMap, // If we initialize it, the pointer gets updated. + /* OUT */ DWORD* handleInstCountOut, + /* OUT */ DWORD* handleInstIndexOut); template - static MethodContext::Agnostic_CORINFO_SIG_INFO StoreAgnostic_CORINFO_SIG_INFO(CORINFO_SIG_INFO& sigInfo, - LightWeightMap* buffers); + static MethodContext::Agnostic_CORINFO_SIG_INFO StoreAgnostic_CORINFO_SIG_INFO( + const CORINFO_SIG_INFO& sigInfo, + LightWeightMap* buffers, + DenseLightWeightMap*& handleMap); + + static DWORD ContainsHandleMap( + unsigned handleCount, + const CORINFO_CLASS_HANDLE* handleArray, + const DenseLightWeightMap* handleMap); template static MethodContext::Agnostic_CORINFO_SIG_INFO RestoreAgnostic_CORINFO_SIG_INFO( - CORINFO_SIG_INFO& sigInfo, LightWeightMap* buffers); + const CORINFO_SIG_INFO& sigInfo, + LightWeightMap* buffers, + const DenseLightWeightMap* handleMap); + + static void DeserializeCORINFO_SIG_INST_HandleArray( + DWORD handleInstCount, + DWORD handleInstIndex, + const DenseLightWeightMap* handleMap, + /* OUT */ unsigned* handleInstCountOut, + /* OUT */ CORINFO_CLASS_HANDLE** handleInstArrayOut); + + static void DeserializeCORINFO_SIG_INST( + CORINFO_SIG_INFO& sigInfoOut, + const MethodContext::Agnostic_CORINFO_SIG_INFO& sigInfo, + const DenseLightWeightMap* handleMap); template - static CORINFO_SIG_INFO Restore_CORINFO_SIG_INFO(MethodContext::Agnostic_CORINFO_SIG_INFO& sigInfo, - LightWeightMap* buffers); + static CORINFO_SIG_INFO Restore_CORINFO_SIG_INFO( + const MethodContext::Agnostic_CORINFO_SIG_INFO& sigInfo, + LightWeightMap* buffers, + const DenseLightWeightMap* handleMap); static MethodContext::Agnostic_CORINFO_LOOKUP_KIND CreateAgnostic_CORINFO_LOOKUP_KIND( const CORINFO_LOOKUP_KIND* pGenericLookupKind); @@ -174,7 +204,7 @@ inline void SpmiRecordsHelper::Restore_CORINFO_RESOLVED_TOKENout( } inline MethodContext::Agnostic_CORINFO_SIG_INFO SpmiRecordsHelper::CreateAgnostic_CORINFO_SIG_INFO_without_buffers( - CORINFO_SIG_INFO& sigInfo) + const CORINFO_SIG_INFO& sigInfo) { MethodContext::Agnostic_CORINFO_SIG_INFO sig; ZeroMemory(&sig, sizeof(sig)); @@ -193,52 +223,166 @@ inline MethodContext::Agnostic_CORINFO_SIG_INFO SpmiRecordsHelper::CreateAgnosti return sig; } +inline void SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INST_HandleArray( + unsigned handleInstCount, + CORINFO_CLASS_HANDLE* handleInstArray, + DenseLightWeightMap*& handleMap, // If we initialize it, the pointer gets updated. + /* OUT */ DWORD* handleInstCountOut, + /* OUT */ DWORD* handleInstIndexOut) +{ + unsigned handleInstIndex; + + if (handleInstCount > 0) + { + if (handleMap == nullptr) + handleMap = new DenseLightWeightMap(); // this updates the caller + + // If the we already have this array, we need to re-use it, so when we look it up on + // replay we get the same index. It also reduces the amount of data in the handle map, + // since there are typically few handle unique arrays. + handleInstIndex = ContainsHandleMap(handleInstCount, handleInstArray, handleMap); + if (handleInstIndex == (DWORD)-1) + { + handleInstIndex = handleMap->GetCount(); + for (unsigned int i = 0; i < handleInstCount; i++) + { + handleMap->Append(CastHandle(handleInstArray[i])); + } + AssertCodeMsg(handleInstIndex + handleInstCount == handleMap->GetCount(), EXCEPTIONCODE_MC, + "Unexpected size of handleMap"); + } + } + else + { + handleInstIndex = (DWORD)-1; + } + + *handleInstCountOut = handleInstCount; + *handleInstIndexOut = handleInstIndex; +} + template inline MethodContext::Agnostic_CORINFO_SIG_INFO SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO( - CORINFO_SIG_INFO& sigInfo, LightWeightMap* buffers) + const CORINFO_SIG_INFO& sigInfo, + LightWeightMap* buffers, + DenseLightWeightMap*& handleMap) { MethodContext::Agnostic_CORINFO_SIG_INFO sig(CreateAgnostic_CORINFO_SIG_INFO_without_buffers(sigInfo)); - sig.sigInst_classInst_Index = - buffers->AddBuffer((unsigned char*)sigInfo.sigInst.classInst, sigInfo.sigInst.classInstCount * 8); - sig.sigInst_methInst_Index = - buffers->AddBuffer((unsigned char*)sigInfo.sigInst.methInst, sigInfo.sigInst.methInstCount * 8); + + StoreAgnostic_CORINFO_SIG_INST_HandleArray(sigInfo.sigInst.classInstCount, sigInfo.sigInst.classInst, handleMap, &sig.sigInst_classInstCount, &sig.sigInst_classInst_Index); + StoreAgnostic_CORINFO_SIG_INST_HandleArray(sigInfo.sigInst.methInstCount, sigInfo.sigInst.methInst, handleMap, &sig.sigInst_methInstCount, &sig.sigInst_methInst_Index); sig.pSig_Index = (DWORD)buffers->AddBuffer((unsigned char*)sigInfo.pSig, sigInfo.cbSig); + return sig; } +inline DWORD SpmiRecordsHelper::ContainsHandleMap( + unsigned handleCount, + const CORINFO_CLASS_HANDLE* handleArray, + const DenseLightWeightMap* handleMap) +{ + // Special case: no handles isn't found. + if (handleCount == 0) + { + return (DWORD)-1; + } + + for (unsigned mapIndex = 0; mapIndex < handleMap->GetCount(); mapIndex++) + { + if (mapIndex + handleCount > handleMap->GetCount()) + { + // The handles can't be found; it would overflow the handleMap. + return (DWORD)-1; + } + + // See if the handle map starting at `mapIndex` contains all the handles we're looking for, in order. + bool found = true; // Assume we'll find it + for (unsigned handleIndex = 0; handleIndex < handleCount; handleIndex++) + { + if (handleMap->Get(mapIndex + handleIndex) != CastHandle(handleArray[handleIndex])) + { + found = false; + break; + } + } + if (found) + { + return (DWORD)mapIndex; + } + } + return (DWORD)-1; // not found +} + +// RestoreAgnostic_CORINFO_SIG_INFO: from a CORINFO_SIG_INFO, fill out an Agnostic_CORINFO_SIG_INFO from the data already stored. +// Don't create and store a new Agnostic_CORINFO_SIG_INFO. The buffers and indices need to be found in the existing stored data. +// This is used when we need to create an Agnostic_CORINFO_SIG_INFO to be used as a key to look up in an existing map. template inline MethodContext::Agnostic_CORINFO_SIG_INFO SpmiRecordsHelper::RestoreAgnostic_CORINFO_SIG_INFO( - CORINFO_SIG_INFO& sigInfo, LightWeightMap* buffers) + const CORINFO_SIG_INFO& sigInfo, + LightWeightMap* buffers, + const DenseLightWeightMap* handleMap) { MethodContext::Agnostic_CORINFO_SIG_INFO sig(CreateAgnostic_CORINFO_SIG_INFO_without_buffers(sigInfo)); - sig.sigInst_classInst_Index = - buffers->Contains((unsigned char*)sigInfo.sigInst.classInst, sigInfo.sigInst.classInstCount * 8); - sig.sigInst_methInst_Index = - buffers->Contains((unsigned char*)sigInfo.sigInst.methInst, sigInfo.sigInst.methInstCount * 8); + sig.sigInst_classInst_Index = ContainsHandleMap(sigInfo.sigInst.classInstCount, sigInfo.sigInst.classInst, handleMap); + sig.sigInst_methInst_Index = ContainsHandleMap(sigInfo.sigInst.methInstCount, sigInfo.sigInst.methInst, handleMap); sig.pSig_Index = (DWORD)buffers->Contains((unsigned char*)sigInfo.pSig, sigInfo.cbSig); return sig; } +inline void SpmiRecordsHelper::DeserializeCORINFO_SIG_INST_HandleArray( + DWORD handleInstCount, + DWORD handleInstIndex, + const DenseLightWeightMap* handleMap, + /* OUT */ unsigned* handleInstCountOut, + /* OUT */ CORINFO_CLASS_HANDLE** handleInstArrayOut) +{ + CORINFO_CLASS_HANDLE* handleInstArray; + + if (handleInstCount > 0) + { + handleInstArray = new CORINFO_CLASS_HANDLE[handleInstCount]; // memory leak? + for (unsigned int i = 0; i < handleInstCount; i++) + { + DWORD key = handleInstIndex + i; + handleInstArray[i] = (CORINFO_CLASS_HANDLE)handleMap->Get(key); + } + } + else + { + handleInstArray = nullptr; + } + + *handleInstCountOut = handleInstCount; + *handleInstArrayOut = handleInstArray; +} + +inline void SpmiRecordsHelper::DeserializeCORINFO_SIG_INST( + CORINFO_SIG_INFO& sigInfoOut, const MethodContext::Agnostic_CORINFO_SIG_INFO& sigInfo, const DenseLightWeightMap* handleMap) +{ + DeserializeCORINFO_SIG_INST_HandleArray(sigInfo.sigInst_classInstCount, sigInfo.sigInst_classInst_Index, handleMap, &sigInfoOut.sigInst.classInstCount, &sigInfoOut.sigInst.classInst); + DeserializeCORINFO_SIG_INST_HandleArray(sigInfo.sigInst_methInstCount, sigInfo.sigInst_methInst_Index, handleMap, &sigInfoOut.sigInst.methInstCount, &sigInfoOut.sigInst.methInst); +} + template -inline CORINFO_SIG_INFO SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(MethodContext::Agnostic_CORINFO_SIG_INFO& sigInfo, - LightWeightMap* buffers) +inline CORINFO_SIG_INFO SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(const MethodContext::Agnostic_CORINFO_SIG_INFO& sigInfo, + LightWeightMap* buffers, + const DenseLightWeightMap* handleMap) { CORINFO_SIG_INFO sig; - sig.callConv = (CorInfoCallConv)sigInfo.callConv; - sig.retTypeClass = (CORINFO_CLASS_HANDLE)sigInfo.retTypeClass; - sig.retTypeSigClass = (CORINFO_CLASS_HANDLE)sigInfo.retTypeSigClass; - sig.retType = (CorInfoType)sigInfo.retType; - sig.flags = (unsigned)sigInfo.flags; - sig.numArgs = (unsigned)sigInfo.numArgs; - sig.sigInst.classInstCount = (unsigned)sigInfo.sigInst_classInstCount; - sig.sigInst.classInst = (CORINFO_CLASS_HANDLE*)buffers->GetBuffer(sigInfo.sigInst_classInst_Index); - sig.sigInst.methInstCount = (unsigned)sigInfo.sigInst_methInstCount; - sig.sigInst.methInst = (CORINFO_CLASS_HANDLE*)buffers->GetBuffer(sigInfo.sigInst_methInst_Index); - sig.args = (CORINFO_ARG_LIST_HANDLE)sigInfo.args; - sig.cbSig = (unsigned int)sigInfo.cbSig; - sig.pSig = (PCCOR_SIGNATURE)buffers->GetBuffer(sigInfo.pSig_Index); - sig.scope = (CORINFO_MODULE_HANDLE)sigInfo.scope; - sig.token = (mdToken)sigInfo.token; + sig.callConv = (CorInfoCallConv)sigInfo.callConv; + sig.retTypeClass = (CORINFO_CLASS_HANDLE)sigInfo.retTypeClass; + sig.retTypeSigClass = (CORINFO_CLASS_HANDLE)sigInfo.retTypeSigClass; + sig.retType = (CorInfoType)sigInfo.retType; + sig.flags = (unsigned)sigInfo.flags; + sig.numArgs = (unsigned)sigInfo.numArgs; + sig.args = (CORINFO_ARG_LIST_HANDLE)sigInfo.args; + sig.cbSig = (unsigned int)sigInfo.cbSig; + sig.pSig = (PCCOR_SIGNATURE)buffers->GetBuffer(sigInfo.pSig_Index); + sig.scope = (CORINFO_MODULE_HANDLE)sigInfo.scope; + sig.token = (mdToken)sigInfo.token; + + DeserializeCORINFO_SIG_INST(sig, sigInfo, handleMap); + return sig; } diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp index b001578..ed2cfeb 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -2105,7 +2105,10 @@ WORD interceptor_ICJI::getRelocTypeHint(void* target) // DWORD interceptor_ICJI::getExpectedTargetArchitecture() { - return original_ICorJitInfo->getExpectedTargetArchitecture(); + mc->cr->AddCall("getExpectedTargetArchitecture"); + DWORD result = original_ICorJitInfo->getExpectedTargetArchitecture(); + mc->recGetExpectedTargetArchitecture(result); + return result; } bool interceptor_ICJI::notifyInstructionSetUsage(CORINFO_InstructionSet instructionSet, bool supported) diff --git a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp index c210e18..78b0a46 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp @@ -1857,15 +1857,7 @@ WORD MyICJI::getRelocTypeHint(void* target) // DWORD MyICJI::getExpectedTargetArchitecture() { -#if defined(TARGET_X86) - return IMAGE_FILE_MACHINE_I386; -#elif defined(TARGET_AMD64) - return IMAGE_FILE_MACHINE_AMD64; -#elif defined(TARGET_ARM) - return IMAGE_FILE_MACHINE_ARMNT; -#elif defined(TARGET_ARM64) - return IMAGE_FILE_MACHINE_ARM64; -#else - return IMAGE_FILE_MACHINE_UNKNOWN; -#endif + jitInstance->mc->cr->AddCall("getExpectedTargetArchitecture"); + DWORD result = jitInstance->mc->repGetExpectedTargetArchitecture(); + return result; } diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index 7658232..6ee29b5 100644 --- a/src/coreclr/inc/jiteeversionguid.h +++ b/src/coreclr/inc/jiteeversionguid.h @@ -31,11 +31,11 @@ // ////////////////////////////////////////////////////////////////////////////////////////////////////////// -constexpr GUID JITEEVersionIdentifier = { /* 89b87d02-e032-4f00-b5cf-dfdee25bbae2 */ - 0x89b87d02, - 0xe032, - 0x4f00, - {0xb5, 0xcf, 0xdf, 0xde, 0xe2, 0x5b, 0xba, 0xe2} +constexpr GUID JITEEVersionIdentifier = { /* 8e32c24d-62fe-4d78-ae73-eedddb928ee2 */ + 0x8e32c24d, + 0x62fe, + 0x4d78, + {0xae, 0x73, 0xee, 0xdd, 0xdb, 0x92, 0x8e, 0xe2} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// -- 2.7.4