From b7cce5a59f7c6bd5a33b88f2af252693bbbd7373 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Thu, 7 Sep 2017 14:28:07 -0700 Subject: New jit intrinsic support (#13815) Support for new-style intrinsics where corelib methods can have both IL implementations and optional jit-supplied implementations. Mark such methods with the [Intrinsic] attribute, then recognize the intrinsic methods by name in the jit. Jit currently has a placeholder for the Enum.HasFlag method. --- .../superpmi/superpmi-shared/icorjitinfoimpl.h | 8 +++ src/ToolBox/superpmi/superpmi-shared/lwmlist.h | 1 + .../superpmi/superpmi-shared/methodcontext.cpp | 84 +++++++++++++++++++++- .../superpmi/superpmi-shared/methodcontext.h | 15 +++- .../superpmi-shim-collector/icorjitinfo.cpp | 11 +++ .../superpmi/superpmi-shim-counter/icorjitinfo.cpp | 9 +++ .../superpmi/superpmi-shim-simple/icorjitinfo.cpp | 8 +++ src/ToolBox/superpmi/superpmi/icorjitinfo.cpp | 9 +++ 8 files changed, 141 insertions(+), 4 deletions(-) (limited to 'src/ToolBox') diff --git a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h index ad6b269041..4ce775d177 100644 --- a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h +++ b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h @@ -670,6 +670,14 @@ const char* getMethodName(CORINFO_METHOD_HANDLE ftn, /* IN */ const char** moduleName /* OUT */ ); +// Return method name as in metadata, or nullptr if there is none, +// and optionally return the class name as in metadata. +// Suitable for non-debugging use. +const char* getMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, /* IN */ + const char** className, /* OUT */ + const char** namespaceName /* OUT */ + ); + // this function is for debugging only. It returns a value that // is will always be the same for a given method. It is used // to implement the 'jitRange' functionality diff --git a/src/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/ToolBox/superpmi/superpmi-shared/lwmlist.h index 349b6bf105..898641c790 100644 --- a/src/ToolBox/superpmi/superpmi-shared/lwmlist.h +++ b/src/ToolBox/superpmi/superpmi-shared/lwmlist.h @@ -100,6 +100,7 @@ LWM(GetMethodDefFromMethod, DWORDLONG, DWORD) LWM(GetMethodHash, DWORDLONG, DWORD) LWM(GetMethodInfo, DWORDLONG, Agnostic_GetMethodInfo) LWM(GetMethodName, DLD, DD) +LWM(GetMethodNameFromMetadata, DLDD, DDD) LWM(GetMethodSig, DLDL, Agnostic_CORINFO_SIG_INFO) LWM(GetMethodSync, DWORDLONG, DLDL) LWM(GetMethodVTableOffset, DWORDLONG, DDD) diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index 82a7985ce5..154505632b 100644 --- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -1121,6 +1121,7 @@ void MethodContext::dmpGetMethodName(DLD key, DD value) moduleName); GetMethodName->Unlock(); } + const char* MethodContext::repGetMethodName(CORINFO_METHOD_HANDLE ftn, const char** moduleName) { const char* result = "hackishMethodName"; @@ -1148,6 +1149,85 @@ const char* MethodContext::repGetMethodName(CORINFO_METHOD_HANDLE ftn, const cha return result; } + +void MethodContext::recGetMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, + char* methodName, const char** className, const char **namespaceName) +{ + if (GetMethodNameFromMetadata == nullptr) + GetMethodNameFromMetadata = new LightWeightMap(); + DDD value; + DLDD key; + key.A = (DWORDLONG)ftn; + key.B = (className != nullptr); + key.C = (namespaceName != nullptr); + + if (methodName != nullptr) + value.A = GetMethodNameFromMetadata->AddBuffer((unsigned char*)methodName, (DWORD)strlen(methodName) + 1); + else + value.A = (DWORD)-1; + + if (className != nullptr) + value.B = GetMethodNameFromMetadata->AddBuffer((unsigned char*)*className, (DWORD)strlen(*className) + 1); + else + value.B = (DWORD)-1; + + if (namespaceName != nullptr) + value.C = GetMethodNameFromMetadata->AddBuffer((unsigned char*)*namespaceName, (DWORD)strlen(*namespaceName) + 1); + else + value.C = (DWORD)-1; + + GetMethodNameFromMetadata->Add(key, value); + DEBUG_REC(dmpGetMethodNameFromMetadata(key, value)); +} + +void MethodContext::dmpGetMethodNameFromMetadata(DLDD key, DDD value) +{ + unsigned char* methodName = (unsigned char*)GetMethodName->GetBuffer(value.A); + unsigned char* className = (unsigned char*)GetMethodName->GetBuffer(value.B); + unsigned char* namespaceName = (unsigned char*)GetMethodName->GetBuffer(value.C); + printf("GetMethodNameFromMetadata key - ftn-%016llX classNonNull-%u namespaceNonNull-%u, value meth-'%s', class-'%s', namespace-'%s'", + key.A, key.B, key.C, methodName, className, namespaceName); + GetMethodNameFromMetadata->Unlock(); +} + +const char* MethodContext::repGetMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, const char** moduleName, const char** namespaceName) +{ + const char* result = nullptr; + DDD value; + DLDD key; + key.A = (DWORDLONG)ftn; + key.B = (moduleName != nullptr); + key.C = (namespaceName != nullptr); + + int itemIndex = -1; + if (GetMethodNameFromMetadata != nullptr) + itemIndex = GetMethodNameFromMetadata->GetIndex(key); + if (itemIndex < 0) + { + if (moduleName != nullptr) + { + *moduleName = nullptr; + } + } + else + { + value = GetMethodNameFromMetadata->Get(key); + result = (const char*)GetMethodNameFromMetadata->GetBuffer(value.A); + + if (moduleName != nullptr) + { + *moduleName = (const char*)GetMethodNameFromMetadata->GetBuffer(value.B); + } + + if (namespaceName != nullptr) + { + *namespaceName = (const char*)GetMethodNameFromMetadata->GetBuffer(value.C); + } + } + DEBUG_REP(dmpGetMethodNameFromMetadata(key, value)); + return result; +} + void MethodContext::recGetJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes, DWORD result) { if (GetJitFlags == nullptr) @@ -2980,7 +3060,7 @@ void MethodContext::recGetMethodVTableOffset(CORINFO_METHOD_HANDLE method, DDD value; value.A = (DWORD)*offsetOfIndirection; value.B = (DWORD)*offsetAfterIndirection; - value.C = *isRelative; + value.C = *isRelative ? 1 : 0; GetMethodVTableOffset->Add((DWORDLONG)method, value); DEBUG_REC(dmpGetMethodVTableOffset((DWORDLONG)method, value)); } @@ -3003,7 +3083,7 @@ void MethodContext::repGetMethodVTableOffset(CORINFO_METHOD_HANDLE method, *offsetOfIndirection = (unsigned)value.A; *offsetAfterIndirection = (unsigned)value.B; - *isRelative = value.C; + *isRelative = value.C != 0; DEBUG_REP(dmpGetMethodVTableOffset((DWORDLONG)method, value)); } diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h index 83c16772ae..eec403196b 100644 --- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h +++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h @@ -89,6 +89,12 @@ public: DWORDLONG A; DWORD B; }; + struct DLDD + { + DWORDLONG A; + DWORD B; + DWORD C; + }; struct Agnostic_CORINFO_RESOLVED_TOKENin { DWORDLONG tokenContext; @@ -241,7 +247,7 @@ public: { DWORD A; DWORD B; - bool C; + DWORD C; }; struct Agnostic_CanTailCall { @@ -616,6 +622,10 @@ public: void dmpGetMethodName(DLD key, DD value); const char* repGetMethodName(CORINFO_METHOD_HANDLE ftn, const char** moduleName); + void recGetMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, char* methodname, const char** moduleName, const char** namespaceName); + void dmpGetMethodNameFromMetadata(DLDD key, DDD value); + const char* repGetMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, const char** className, const char** namespaceName); + void recGetJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes, DWORD result); void dmpGetJitFlags(DWORD key, DD value); DWORD repGetJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes); @@ -1247,7 +1257,7 @@ private: }; // ********************* Please keep this up-to-date to ease adding more *************** -// Highest packet number: 160 +// Highest packet number: 161 // ************************************************************************************* enum mcPackets { @@ -1342,6 +1352,7 @@ enum mcPackets Packet_GetMethodHash = 73, Packet_GetMethodInfo = 74, Packet_GetMethodName = 75, + Packet_GetMethodNameFromMetadata = 161, // Added 9/6/17 Packet_GetMethodSig = 76, Packet_GetMethodSync = 77, Packet_GetMethodVTableOffset = 78, diff --git a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp index d79e4ee51a..2a477a07e3 100644 --- a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1367,6 +1367,17 @@ const char* interceptor_ICJI::getMethodName(CORINFO_METHOD_HANDLE ftn, /* return temp; } +const char* interceptor_ICJI::getMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, /* IN */ + const char** className, /* OUT */ + const char** namespaceName /* OUT */ + ) +{ + mc->cr->AddCall("getMethodNameFromMetadata"); + const char* temp = original_ICorJitInfo->getMethodNameFromMetadata(ftn, className, namespaceName); + mc->recGetMethodNameFromMetadata(ftn, (char*)temp, className, namespaceName); + return temp; +} + // this function is for debugging only. It returns a value that // is will always be the same for a given method. It is used // to implement the 'jitRange' functionality diff --git a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp index d731a773f0..a54ead5661 100644 --- a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp +++ b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp @@ -1080,6 +1080,15 @@ const char* interceptor_ICJI::getMethodName(CORINFO_METHOD_HANDLE ftn, /* return original_ICorJitInfo->getMethodName(ftn, moduleName); } +const char* interceptor_ICJI::getMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, /* IN */ + const char** className, /* OUT */ + const char** namespaceName /* OUT */ + ) +{ + mcs->AddCall("getMethodNameFromMetadata"); + return original_ICorJitInfo->getMethodNameFromMetadata(ftn, className, namespaceName); +} + // this function is for debugging only. It returns a value that // is will always be the same for a given method. It is used // to implement the 'jitRange' functionality diff --git a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp index fd45a3c2dc..7e0ded9f0f 100644 --- a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp +++ b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp @@ -974,6 +974,14 @@ const char* interceptor_ICJI::getMethodName(CORINFO_METHOD_HANDLE ftn, /* return original_ICorJitInfo->getMethodName(ftn, moduleName); } +const char* interceptor_ICJI::getMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, /* IN */ + const char** className, /* OUT */ + const char** namespaceName /* OUT */ + ) +{ + return original_ICorJitInfo->getMethodNameFromMetadata(ftn, className, namespaceName); +} + // this function is for debugging only. It returns a value that // is will always be the same for a given method. It is used // to implement the 'jitRange' functionality diff --git a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp index e8b4187a99..2e78113991 100644 --- a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp +++ b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp @@ -1183,6 +1183,15 @@ const char* MyICJI::getMethodName(CORINFO_METHOD_HANDLE ftn, /* IN */ return jitInstance->mc->repGetMethodName(ftn, moduleName); } +const char* MyICJI::getMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, /* IN */ + const char** className, /* OUT */ + const char** namespaceName /* OUT */ + ) +{ + jitInstance->mc->cr->AddCall("getMethodNameFromMetadata"); + return jitInstance->mc->repGetMethodNameFromMetadata(ftn, className, namespaceName); +} + // this function is for debugging only. It returns a value that // is will always be the same for a given method. It is used // to implement the 'jitRange' functionality -- cgit v1.2.3