summaryrefslogtreecommitdiff
path: root/src/ToolBox
diff options
context:
space:
mode:
authorAndy Ayers <andya@microsoft.com>2019-02-15 14:39:33 -0800
committerGitHub <noreply@github.com>2019-02-15 14:39:33 -0800
commitbb62718325435a1ad5761c84c06b8b653856e296 (patch)
tree8627cb86b978ea9c4252ef405dd822852aafbe84 /src/ToolBox
parent6f1bdfffb77ba1c95f46e16a7eeff3cfaf2f2f1f (diff)
downloadcoreclr-bb62718325435a1ad5761c84c06b8b653856e296.tar.gz
coreclr-bb62718325435a1ad5761c84c06b8b653856e296.tar.bz2
coreclr-bb62718325435a1ad5761c84c06b8b653856e296.zip
JIT: modify how jit determines when to update a type (#22618)
For single-def locals, the type of a reference seen at the assignment to the local may be a more specific type than the local's declared type. If so the jit would prefer to use the assignment type to describe the local's value, as this will lead to better optimization. For instance in ``` object x = "a string"; // only assignment to x ``` the jit can optimize better if it models the type of `x` as `string`. Instead of relying on `mergeClasses` plus some jit-side screening to decide if the assignment type is a more specific type, implement a new jit interface method `isMoreSpecificType` that tries to answer this question more directly. Added a test case with type equivalence that hit asserts. Closes #22583.
Diffstat (limited to 'src/ToolBox')
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h5
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/lwmlist.h1
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp35
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/methodcontext.h7
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp11
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp7
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp6
-rw-r--r--src/ToolBox/superpmi/superpmi/icorjitinfo.cpp9
8 files changed, 77 insertions, 4 deletions
diff --git a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
index 223e1d89c7..fe4ed6a5ff 100644
--- a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
+++ b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
@@ -461,9 +461,12 @@ TypeCompareState compareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLA
// equal, or the comparison needs to be resolved at runtime.
TypeCompareState compareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
-// returns is the intersection of cls1 and cls2.
+// returns the intersection of cls1 and cls2.
CORINFO_CLASS_HANDLE mergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
+// Returns true if cls2 is known to be a more specific type than cls1.
+BOOL isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
+
// Given a class handle, returns the Parent type.
// For COMObjectType, it returns Class Handle of System.Object.
// Returns 0 if System.Object is passed in.
diff --git a/src/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
index d034bdcd8f..4fe06d2fd7 100644
--- a/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
+++ b/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
@@ -151,6 +151,7 @@ LWM(IsValidToken, DLD, DWORD)
LWM(IsValueClass, DWORDLONG, DWORD)
LWM(IsWriteBarrierHelperRequired, DWORDLONG, DWORD)
LWM(MergeClasses, DLDL, DWORDLONG)
+LWM(IsMoreSpecificType, DLDL, DWORD)
LWM(PInvokeMarshalingRequired, PInvokeMarshalingRequiredValue, DWORD)
LWM(ResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, ResolveTokenValue)
LWM(ResolveVirtualMethod, Agnostic_ResolveVirtualMethod, DWORDLONG)
diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
index 5f4861d544..96ecb8d5f1 100644
--- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
+++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
@@ -5318,6 +5318,41 @@ CORINFO_CLASS_HANDLE MethodContext::repMergeClasses(CORINFO_CLASS_HANDLE cls1, C
return (CORINFO_CLASS_HANDLE)value;
}
+void MethodContext::recIsMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, BOOL result)
+{
+ if (IsMoreSpecificType == nullptr)
+ IsMoreSpecificType = new LightWeightMap<DLDL, DWORD>();
+ DLDL key;
+ ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero
+ // out padding too
+
+ key.A = (DWORDLONG)cls1;
+ key.B = (DWORDLONG)cls2;
+
+ IsMoreSpecificType->Add(key, (DWORD)result);
+}
+void MethodContext::dmpIsMoreSpecificType(DLDL key, DWORD value)
+{
+ printf("IsMoreSpecificType key cls1-%016llX cls2-%016llX, value %u", key.A, key.B, value);
+}
+BOOL MethodContext::repIsMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
+{
+ DLDL key;
+ ZeroMemory(&key, sizeof(DLDL)); // We use the input structs as a key and use memcmp to compare.. so we need to zero
+ // out padding too
+ DWORD value;
+
+ key.A = (DWORDLONG)cls1;
+ key.B = (DWORDLONG)cls2;
+
+ AssertCodeMsg(IsMoreSpecificType->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX %016llX", (DWORDLONG)cls1,
+ (DWORDLONG)cls2);
+
+ value = IsMoreSpecificType->Get(key);
+
+ return (BOOL)value;
+}
+
void MethodContext::recGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void** ppIndirection, LPVOID result)
{
if (GetCookieForPInvokeCalliSig == nullptr)
diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
index 7e20c2bc1a..8de6a070f0 100644
--- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
+++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
@@ -1204,6 +1204,10 @@ public:
void dmpMergeClasses(DLDL key, DWORDLONG value);
CORINFO_CLASS_HANDLE repMergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
+ void recIsMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2, BOOL result);
+ void dmpIsMoreSpecificType(DLDL key, DWORD value);
+ BOOL repIsMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2);
+
void recGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void** ppIndirection, LPVOID result);
void dmpGetCookieForPInvokeCalliSig(const GetCookieForPInvokeCalliSigValue& key, DLDL value);
LPVOID repGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void** ppIndirection);
@@ -1348,7 +1352,7 @@ private:
};
// ********************* Please keep this up-to-date to ease adding more ***************
-// Highest packet number: 173
+// Highest packet number: 174
// *************************************************************************************
enum mcPackets
{
@@ -1494,6 +1498,7 @@ enum mcPackets
Packet_IsValueClass = 105,
Packet_IsWriteBarrierHelperRequired = 106,
Packet_MergeClasses = 107,
+ Packet_IsMoreSpecificType = 174, // Added 2/14/2019
Packet_PInvokeMarshalingRequired = 108,
Packet_ResolveToken = 109,
Packet_ResolveVirtualMethod = 160, // Added 2/13/17
diff --git a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
index 44b08dfe71..79071488a7 100644
--- a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
@@ -987,7 +987,7 @@ TypeCompareState interceptor_ICJI::compareTypesForEquality(CORINFO_CLASS_HANDLE
return temp;
}
-// returns is the intersection of cls1 and cls2.
+// returns the intersection of cls1 and cls2.
CORINFO_CLASS_HANDLE interceptor_ICJI::mergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
{
mc->cr->AddCall("mergeClasses");
@@ -996,6 +996,15 @@ CORINFO_CLASS_HANDLE interceptor_ICJI::mergeClasses(CORINFO_CLASS_HANDLE cls1, C
return temp;
}
+// Returns true if cls2 is known to be a more specific type than cls1.
+BOOL interceptor_ICJI::isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
+{
+ mc->cr->AddCall("isMoreSpecificType");
+ BOOL temp = original_ICorJitInfo->isMoreSpecificType(cls1, cls2);
+ mc->recIsMoreSpecificType(cls1, cls2, temp);
+ return temp;
+}
+
// Given a class handle, returns the Parent type.
// For COMObjectType, it returns Class Handle of System.Object.
// Returns 0 if System.Object is passed in.
diff --git a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
index 5fe6bc367b..044f1f2c4a 100644
--- a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
@@ -776,6 +776,13 @@ CORINFO_CLASS_HANDLE interceptor_ICJI::mergeClasses(CORINFO_CLASS_HANDLE cls1, C
return original_ICorJitInfo->mergeClasses(cls1, cls2);
}
+// Returns true if cls2 is known to be a more specific type than cls1.
+BOOL interceptor_ICJI::isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
+{
+ mcs->AddCall("isMoreSpecificType");
+ return original_ICorJitInfo->isMoreSpecificType(cls1, cls2);
+}
+
// Given a class handle, returns the Parent type.
// For COMObjectType, it returns Class Handle of System.Object.
// Returns 0 if System.Object is passed in.
diff --git a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
index 0455503658..49dd2423e1 100644
--- a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
@@ -692,6 +692,12 @@ CORINFO_CLASS_HANDLE interceptor_ICJI::mergeClasses(CORINFO_CLASS_HANDLE cls1, C
return original_ICorJitInfo->mergeClasses(cls1, cls2);
}
+// Returns true if cls2 is known to be a more specific type than cls1.
+BOOL interceptor_ICJI::isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
+{
+ return original_ICorJitInfo->isMoreSpecificType(cls1, cls2);
+}
+
// Given a class handle, returns the Parent type.
// For COMObjectType, it returns Class Handle of System.Object.
// Returns 0 if System.Object is passed in.
diff --git a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
index bca4cb04fa..377ad1d054 100644
--- a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
@@ -826,13 +826,20 @@ TypeCompareState MyICJI::compareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORI
return jitInstance->mc->repCompareTypesForEquality(cls1, cls2);
}
-// returns is the intersection of cls1 and cls2.
+// returns the intersection of cls1 and cls2.
CORINFO_CLASS_HANDLE MyICJI::mergeClasses(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
{
jitInstance->mc->cr->AddCall("mergeClasses");
return jitInstance->mc->repMergeClasses(cls1, cls2);
}
+// Returns true if cls2 is known to be a more specific type than cls1
+BOOL MyICJI::isMoreSpecificType(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
+{
+ jitInstance->mc->cr->AddCall("isMoreSpecificType");
+ return jitInstance->mc->repIsMoreSpecificType(cls1, cls2);
+}
+
// Given a class handle, returns the Parent type.
// For COMObjectType, it returns Class Handle of System.Object.
// Returns 0 if System.Object is passed in.