diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h | 5 | ||||
-rw-r--r-- | src/ToolBox/superpmi/superpmi-shared/lwmlist.h | 1 | ||||
-rw-r--r-- | src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp | 35 | ||||
-rw-r--r-- | src/ToolBox/superpmi/superpmi-shared/methodcontext.h | 7 | ||||
-rw-r--r-- | src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp | 11 | ||||
-rw-r--r-- | src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp | 7 | ||||
-rw-r--r-- | src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp | 6 | ||||
-rw-r--r-- | src/ToolBox/superpmi/superpmi/icorjitinfo.cpp | 9 | ||||
-rw-r--r-- | src/inc/corinfo.h | 22 | ||||
-rw-r--r-- | src/jit/lclvars.cpp | 26 | ||||
-rw-r--r-- | src/vm/jitinterface.cpp | 64 | ||||
-rw-r--r-- | src/vm/jitinterface.h | 7 | ||||
-rw-r--r-- | src/zap/zapinfo.cpp | 7 | ||||
-rw-r--r-- | src/zap/zapinfo.h | 3 |
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, |