diff options
author | Andy Ayers <andya@microsoft.com> | 2017-01-30 15:45:11 -0800 |
---|---|---|
committer | Andy Ayers <andya@microsoft.com> | 2017-03-02 07:49:33 -0800 |
commit | 35c23eccfdeaddbd07cd39473fe7544603e67857 (patch) | |
tree | 3f494941727a7d9e8b6a516996946755234555e0 /src/ToolBox | |
parent | 3d76ceaeea4788a949d908b2f9a47f5742ddaadb (diff) | |
download | coreclr-35c23eccfdeaddbd07cd39473fe7544603e67857.tar.gz coreclr-35c23eccfdeaddbd07cd39473fe7544603e67857.tar.bz2 coreclr-35c23eccfdeaddbd07cd39473fe7544603e67857.zip |
Jit interface support for devirtualization
Add new method to jit interface so the jit can determine what derived
method might be called for a given base method, derived class pair.
Implement support in the VM and in other places (zap, spmi).
Diffstat (limited to 'src/ToolBox')
8 files changed, 95 insertions, 2 deletions
diff --git a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h index b847d9bc50..4c1aa3d72d 100644 --- a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h +++ b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h @@ -125,6 +125,13 @@ public: unsigned* offsetAfterIndirection /* OUT */ ); + // Find the virtual method in implementingClass that overrides virtualMethod. + // Return null if devirtualization is not possible. + CORINFO_METHOD_HANDLE resolveVirtualMethod( + CORINFO_METHOD_HANDLE virtualMethod, + CORINFO_CLASS_HANDLE implementingClass + ); + // If a method's attributes have (getMethodAttribs) CORINFO_FLG_INTRINSIC set, // getIntrinsicID() returns the intrinsic ID. // *pMustExpand tells whether or not JIT must expand the intrinsic. diff --git a/src/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/ToolBox/superpmi/superpmi-shared/lwmlist.h index de0db3a9bb..8e19656f18 100644 --- a/src/ToolBox/superpmi/superpmi-shared/lwmlist.h +++ b/src/ToolBox/superpmi/superpmi-shared/lwmlist.h @@ -141,6 +141,7 @@ LWM(IsWriteBarrierHelperRequired, DWORDLONG, DWORD) LWM(MergeClasses, DLDL, DWORDLONG) LWM(PInvokeMarshalingRequired, Agnostic_PInvokeMarshalingRequired, DWORD) LWM(ResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, Agnostic_CORINFO_RESOLVED_TOKENout) +LWM(ResolveVirtualMethod, DLDL, DWORDLONG) LWM(TryResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, Agnostic_CORINFO_RESOLVED_TOKENout) LWM(SatisfiesClassConstraints, DWORDLONG, DWORD) LWM(SatisfiesMethodConstraints, DLDL, DWORD) diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index 5768d38569..c60b593ae0 100644 --- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -3296,6 +3296,40 @@ void MethodContext::repGetMethodVTableOffset(CORINFO_METHOD_HANDLE method, unsig DEBUG_REP(dmpGetMethodVTableOffset((DWORDLONG)method, value)); } +void MethodContext::recResolveVirtualMethod(CORINFO_METHOD_HANDLE virtMethod, CORINFO_CLASS_HANDLE implClass, CORINFO_METHOD_HANDLE result) +{ + if (ResolveVirtualMethod == nullptr) + { + ResolveVirtualMethod = new LightWeightMap<DLDL, DWORDLONG>(); + } + + DLDL key; + key.A = (DWORDLONG)virtMethod; + key.B = (DWORDLONG)implClass; + ResolveVirtualMethod->Add(key, (DWORDLONG) result); + DEBUG_REC(dmpResolveVirtualMethod(key, result)); +} + +void MethodContext::dmpResolveVirtualMethod(DLDL key, DWORDLONG value) +{ + printf("ResolveVirtualMethod virtMethod-%016llX, implClass-%016llX, result-%016llX", key.A, key.B, value); +} + +CORINFO_METHOD_HANDLE MethodContext::repResolveVirtualMethod(CORINFO_METHOD_HANDLE virtMethod, CORINFO_CLASS_HANDLE implClass) +{ + DLDL key; + key.A = (DWORDLONG)virtMethod; + key.B = (DWORDLONG)implClass; + + AssertCodeMsg(ResolveVirtualMethod != nullptr, EXCEPTIONCODE_MC, "No ResolveVirtualMap map for %016llX-%016llX", key.A, key.B); + AssertCodeMsg(ResolveVirtualMethod->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX-%016llx", key.A, key.B); + DWORDLONG result = ResolveVirtualMethod->Get(key); + + DEBUG_REP(dmpResolveVirtualMethod(key, result)); + + return (CORINFO_METHOD_HANDLE)result; +} + void MethodContext::recGetTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_CLASS_HANDLE result) { if (GetTokenTypeAsHandle == nullptr) @@ -6165,7 +6199,7 @@ mdMethodDef MethodContext::repGetMethodDefFromMethod(CORINFO_METHOD_HANDLE hMeth int index = GetMethodDefFromMethod->GetIndex((DWORDLONG)hMethod); if (index < 0) - return (mdMethodDef)0x06000001; + return (mdMethodDef)0x06000001; return (mdMethodDef)GetMethodDefFromMethod->Get((DWORDLONG)hMethod); } diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h index 0d49666e5c..ee2d4ac7c8 100644 --- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h +++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h @@ -698,6 +698,10 @@ public: void dmpGetMethodVTableOffset(DWORDLONG key, DD value); void repGetMethodVTableOffset(CORINFO_METHOD_HANDLE method, unsigned *offsetOfIndirection, unsigned* offsetAfterIndirection); + void recResolveVirtualMethod(CORINFO_METHOD_HANDLE virtMethod, CORINFO_CLASS_HANDLE implClass, CORINFO_METHOD_HANDLE result); + void dmpResolveVirtualMethod(DLDL key, DWORDLONG value); + CORINFO_METHOD_HANDLE repResolveVirtualMethod(CORINFO_METHOD_HANDLE virtMethod, CORINFO_CLASS_HANDLE implClass); + void recGetTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_CLASS_HANDLE result); void dmpGetTokenTypeAsHandle(const Agnostic_CORINFO_RESOLVED_TOKEN& key, DWORDLONG value); CORINFO_CLASS_HANDLE repGetTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken); @@ -1016,7 +1020,7 @@ private: // ********************* Please keep this up-to-date to ease adding more *************** -// Highest packet number: 159 +// Highest packet number: 160 // ************************************************************************************* enum mcPackets { @@ -1151,6 +1155,7 @@ enum mcPackets Packet_MergeClasses = 107, Packet_PInvokeMarshalingRequired = 108, Packet_ResolveToken = 109, + Packet_ResolveVirtualMethod = 160, // Added 2/13/17 Packet_TryResolveToken = 158, //Added 4/26/2016 Packet_SatisfiesClassConstraints = 110, Packet_SatisfiesMethodConstraints = 111, diff --git a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 1813ed29ff..bb19cab455 100644 --- a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -236,6 +236,19 @@ void interceptor_ICJI::getMethodVTableOffset ( mc->recGetMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection); } +// Find the virtual method in implementingClass that overrides virtualMethod. +// Return null if devirtualization is not possible. +CORINFO_METHOD_HANDLE interceptor_ICJI::resolveVirtualMethod( + CORINFO_METHOD_HANDLE virtualMethod, + CORINFO_CLASS_HANDLE implementingClass + ) +{ + mc->cr->AddCall("resolveVirtualMethod"); + CORINFO_METHOD_HANDLE result = original_ICorJitInfo->resolveVirtualMethod(virtualMethod, implementingClass); + mc->recResolveVirtualMethod(virtualMethod, implementingClass, result); + return result; +} + // If a method's attributes have (getMethodAttribs) CORINFO_FLG_INTRINSIC set, // getIntrinsicID() returns the intrinsic ID. CorInfoIntrinsics interceptor_ICJI::getIntrinsicID( diff --git a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp index 448fb1f686..beff1f4e4b 100644 --- a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp +++ b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp @@ -165,6 +165,17 @@ void interceptor_ICJI::getMethodVTableOffset ( original_ICorJitInfo->getMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection); } +// Find the virtual method in implementingClass that overrides virtualMethod. +// Return null if devirtualization is not possible. +CORINFO_METHOD_HANDLE interceptor_ICJI::resolveVirtualMethod( + CORINFO_METHOD_HANDLE virtualMethod, + CORINFO_CLASS_HANDLE implementingClass + ) +{ + mcs->AddCall("resolveVirtualMethod"); + return original_ICorJitInfo->resolveVirtualMethod(virtualMethod, implementingClass); +} + // If a method's attributes have (getMethodAttribs) CORINFO_FLG_INTRINSIC set, // getIntrinsicID() returns the intrinsic ID. CorInfoIntrinsics interceptor_ICJI::getIntrinsicID( diff --git a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp index 4d145f6a41..9e229eeeaf 100644 --- a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp +++ b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp @@ -153,6 +153,16 @@ void interceptor_ICJI::getMethodVTableOffset ( original_ICorJitInfo->getMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection); } +// Find the virtual method in implementingClass that overrides virtualMethod. +// Return null if devirtualization is not possible. +CORINFO_METHOD_HANDLE interceptor_ICJI::resolveVirtualMethod( + CORINFO_METHOD_HANDLE virtualMethod, + CORINFO_CLASS_HANDLE implementingClass + ) +{ + return original_ICorJitInfo->resolveVirtualMethod(virtualMethod, implementingClass); +} + // If a method's attributes have (getMethodAttribs) CORINFO_FLG_INTRINSIC set, // getIntrinsicID() returns the intrinsic ID. CorInfoIntrinsics interceptor_ICJI::getIntrinsicID( diff --git a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp index b746d3f6f7..ae4ba9917c 100644 --- a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp +++ b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp @@ -185,6 +185,18 @@ void MyICJI::getMethodVTableOffset ( jitInstance->mc->repGetMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection); } +// Find the virtual method in implementingClass that overrides virtualMethod. +// Return null if devirtualization is not possible. +CORINFO_METHOD_HANDLE MyICJI::resolveVirtualMethod( + CORINFO_METHOD_HANDLE virtualMethod, + CORINFO_CLASS_HANDLE implementingClass + ) +{ + jitInstance->mc->cr->AddCall("resolveVirtualMethod"); + CORINFO_METHOD_HANDLE result = jitInstance->mc->repResolveVirtualMethod(virtualMethod, implementingClass); + return result; +} + // If a method's attributes have (getMethodAttribs) CORINFO_FLG_INTRINSIC set, // getIntrinsicID() returns the intrinsic ID. CorInfoIntrinsics MyICJI::getIntrinsicID( |