summaryrefslogtreecommitdiff
path: root/src/ToolBox
diff options
context:
space:
mode:
authorAndy Ayers <andya@microsoft.com>2017-01-30 15:45:11 -0800
committerAndy Ayers <andya@microsoft.com>2017-03-02 07:49:33 -0800
commit35c23eccfdeaddbd07cd39473fe7544603e67857 (patch)
tree3f494941727a7d9e8b6a516996946755234555e0 /src/ToolBox
parent3d76ceaeea4788a949d908b2f9a47f5742ddaadb (diff)
downloadcoreclr-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')
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h7
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/lwmlist.h1
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp36
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/methodcontext.h7
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp13
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp11
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp10
-rw-r--r--src/ToolBox/superpmi/superpmi/icorjitinfo.cpp12
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(