summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
-rw-r--r--src/inc/corinfo.h22
-rw-r--r--src/jit/lclvars.cpp26
-rw-r--r--src/vm/jitinterface.cpp64
-rw-r--r--src/vm/jitinterface.h7
-rw-r--r--src/zap/zapinfo.cpp7
-rw-r--r--src/zap/zapinfo.h3
14 files changed, 176 insertions, 34 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.
diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h
index 852bf3168b..412a6cee78 100644
--- a/src/inc/corinfo.h
+++ b/src/inc/corinfo.h
@@ -213,11 +213,11 @@ TODO: Talk about initializing strutures before use
#define SELECTANY extern __declspec(selectany)
#endif
-SELECTANY const GUID JITEEVersionIdentifier = { /* 8903fe7b-a82a-4e2e-b691-f58430b485d1 */
- 0x8903fe7b,
- 0xa82a,
- 0x4e2e,
- {0xb6, 0x91, 0xf5, 0x84, 0x30, 0xb4, 0x85, 0xd1}
+SELECTANY const GUID JITEEVersionIdentifier = { /* d609bed1-7831-49fc-bd49-b6f054dd4d46 */
+ 0xd609bed1,
+ 0x7831,
+ 0x49fc,
+ {0xbd, 0x49, 0xb6, 0xf0, 0x54, 0xdd, 0x4d, 0x46}
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -2592,12 +2592,22 @@ public:
CORINFO_CLASS_HANDLE cls2
) = 0;
- // returns is the intersection of cls1 and cls2.
+ // Returns the intersection of cls1 and cls2.
virtual CORINFO_CLASS_HANDLE mergeClasses(
CORINFO_CLASS_HANDLE cls1,
CORINFO_CLASS_HANDLE cls2
) = 0;
+ // Returns true if cls2 is known to be a more specific type
+ // than cls1 (a subtype or more restrictive shared type)
+ // for purposes of jit type tracking. This is a hint to the
+ // jit for optimization; it does not have correctness
+ // implications.
+ virtual BOOL isMoreSpecificType(
+ CORINFO_CLASS_HANDLE cls1,
+ CORINFO_CLASS_HANDLE cls2
+ ) = 0;
+
// 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/jit/lclvars.cpp b/src/jit/lclvars.cpp
index 473ade919d..c691480827 100644
--- a/src/jit/lclvars.cpp
+++ b/src/jit/lclvars.cpp
@@ -2704,27 +2704,7 @@ void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool
// updating exact classes.
if (!varDsc->lvClassIsExact && isNewClass)
{
- // Todo: improve this analysis by adding a new jit interface method
- DWORD newAttrs = info.compCompHnd->getClassAttribs(clsHnd);
- DWORD oldAttrs = info.compCompHnd->getClassAttribs(varDsc->lvClassHnd);
-
- // Avoid funny things with __Canon by only merging if both shared or both unshared
- if ((newAttrs & CORINFO_FLG_SHAREDINST) == (oldAttrs & CORINFO_FLG_SHAREDINST))
- {
- // If we merge types and we get back the old class, the new class is more
- // specific and we should update to it.
- CORINFO_CLASS_HANDLE mergeClass = info.compCompHnd->mergeClasses(clsHnd, varDsc->lvClassHnd);
-
- if (mergeClass == varDsc->lvClassHnd)
- {
- shouldUpdate = true;
- }
- }
- else if ((newAttrs & CORINFO_FLG_SHAREDINST) == 0)
- {
- // Update if we go from shared to unshared
- shouldUpdate = true;
- }
+ shouldUpdate = info.compCompHnd->isMoreSpecificType(varDsc->lvClassHnd, clsHnd);
}
// Else are we attempting to update exactness?
else if (isExact && !varDsc->lvClassIsExact && !isNewClass)
@@ -2736,9 +2716,9 @@ void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool
if (isNewClass || (isExact != varDsc->lvClassIsExact))
{
JITDUMP("\nlvaUpdateClass:%s Updating class for V%02u", shouldUpdate ? "" : " NOT", varNum);
- JITDUMP(" from(%p) %s%s", dspPtr(varDsc->lvClassHnd), info.compCompHnd->getClassName(varDsc->lvClassHnd),
+ JITDUMP(" from (%p) %s%s", dspPtr(varDsc->lvClassHnd), info.compCompHnd->getClassName(varDsc->lvClassHnd),
varDsc->lvClassIsExact ? " [exact]" : "");
- JITDUMP(" to(%p) %s%s\n", dspPtr(clsHnd), info.compCompHnd->getClassName(clsHnd), isExact ? " [exact]" : "");
+ JITDUMP(" to (%p) %s%s\n", dspPtr(clsHnd), info.compCompHnd->getClassName(clsHnd), isExact ? " [exact]" : "");
}
#endif // DEBUG
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index def08c629f..4df43fe86f 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -4706,7 +4706,7 @@ TypeCompareState CEEInfo::compareTypesForEquality(
}
/*********************************************************************/
-// returns is the intersection of cls1 and cls2.
+// returns the intersection of cls1 and cls2.
CORINFO_CLASS_HANDLE CEEInfo::mergeClasses(
CORINFO_CLASS_HANDLE cls1,
CORINFO_CLASS_HANDLE cls2)
@@ -4776,6 +4776,68 @@ CORINFO_CLASS_HANDLE CEEInfo::mergeClasses(
}
/*********************************************************************/
+static BOOL isMoreSpecificTypeHelper(
+ CORINFO_CLASS_HANDLE cls1,
+ CORINFO_CLASS_HANDLE cls2)
+{
+ CONTRACTL {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_PREEMPTIVE;
+ } CONTRACTL_END;
+
+ TypeHandle hnd1 = TypeHandle(cls1);
+ TypeHandle hnd2 = TypeHandle(cls2);
+
+ // We can't really reason about equivalent types. Just
+ // assume the new type is not more specific.
+ if (hnd1.HasTypeEquivalence() || hnd2.HasTypeEquivalence())
+ {
+ return FALSE;
+ }
+
+ // If we have a mixture of shared and unshared types,
+ // consider the unshared type as more specific.
+ BOOL isHnd1CanonSubtype = hnd1.IsCanonicalSubtype();
+ BOOL isHnd2CanonSubtype = hnd2.IsCanonicalSubtype();
+ if (isHnd1CanonSubtype != isHnd2CanonSubtype)
+ {
+ // Only one of hnd1 and hnd2 is shared.
+ // hdn2 is more specific if hnd1 is the shared type.
+ return isHnd1CanonSubtype;
+ }
+
+ // Otherwise both types are either shared or not shared.
+ // Look for a common parent type.
+ TypeHandle merged = TypeHandle::MergeTypeHandlesToCommonParent(hnd1, hnd2);
+
+ // If the common parent is hnd1, then hnd2 is more specific.
+ return merged == hnd1;
+}
+
+// Returns true if cls2 is known to be a more specific type
+// than cls1 (a subtype or more restrictive shared type).
+BOOL CEEInfo::isMoreSpecificType(
+ CORINFO_CLASS_HANDLE cls1,
+ CORINFO_CLASS_HANDLE cls2)
+{
+ CONTRACTL {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_PREEMPTIVE;
+ } CONTRACTL_END;
+
+ BOOL result = FALSE;
+
+ JIT_TO_EE_TRANSITION();
+
+ result = isMoreSpecificTypeHelper(cls1, cls2);
+
+ EE_TO_JIT_TRANSITION();
+ return result;
+}
+
+/*********************************************************************/
// 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/vm/jitinterface.h b/src/vm/jitinterface.h
index c47123d324..fe7dd4a922 100644
--- a/src/vm/jitinterface.h
+++ b/src/vm/jitinterface.h
@@ -601,6 +601,13 @@ public:
CORINFO_CLASS_HANDLE cls2
);
+ // Returns true if cls2 is known to be a more specific type
+ // than cls1 (a subtype or more restrictive shared type).
+ 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/zap/zapinfo.cpp b/src/zap/zapinfo.cpp
index a56004a6b4..8a372828f0 100644
--- a/src/zap/zapinfo.cpp
+++ b/src/zap/zapinfo.cpp
@@ -3199,6 +3199,13 @@ CORINFO_CLASS_HANDLE ZapInfo::mergeClasses(
return m_pEEJitInfo->mergeClasses(cls1, cls2);
}
+BOOL ZapInfo::isMoreSpecificType(
+ CORINFO_CLASS_HANDLE cls1,
+ CORINFO_CLASS_HANDLE cls2)
+{
+ return m_pEEJitInfo->isMoreSpecificType(cls1, cls2);
+}
+
BOOL ZapInfo::shouldEnforceCallvirtRestriction(
CORINFO_MODULE_HANDLE scopeHnd)
{
diff --git a/src/zap/zapinfo.h b/src/zap/zapinfo.h
index eadefe8555..962bbdacd4 100644
--- a/src/zap/zapinfo.h
+++ b/src/zap/zapinfo.h
@@ -591,6 +591,9 @@ public:
CORINFO_CLASS_HANDLE mergeClasses(CORINFO_CLASS_HANDLE cls1,
CORINFO_CLASS_HANDLE cls2);
+ BOOL isMoreSpecificType(CORINFO_CLASS_HANDLE cls1,
+ CORINFO_CLASS_HANDLE cls2);
+
BOOL shouldEnforceCallvirtRestriction(CORINFO_MODULE_HANDLE scope);
CORINFO_CLASS_HANDLE getParentType(CORINFO_CLASS_HANDLE cls);
CorInfoType getChildType (CORINFO_CLASS_HANDLE clsHnd,