diff options
author | Aaron Robinson <arobins@microsoft.com> | 2018-11-29 12:44:04 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-29 12:44:04 -0800 |
commit | 11d1b645f0dede73ded0030b56d7c506150b0741 (patch) | |
tree | 279600e72cf717e3133210765f99541afd59341f /src | |
parent | 211d963a42c8988770afa4d2edcbe9be0ed0b8a8 (diff) | |
download | coreclr-11d1b645f0dede73ded0030b56d7c506150b0741.tar.gz coreclr-11d1b645f0dede73ded0030b56d7c506150b0741.tar.bz2 coreclr-11d1b645f0dede73ded0030b56d7c506150b0741.zip |
Enable type equivalence (#21265)
* Enable TypeEquivalence feature for Windows platform
* Basic test - verified test exercises TypeEquivalence code paths
Diffstat (limited to 'src')
-rw-r--r-- | src/vm/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/vm/appdomain.cpp | 5 | ||||
-rw-r--r-- | src/vm/class.h | 4 | ||||
-rw-r--r-- | src/vm/crossgen/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/vm/method.cpp | 11 | ||||
-rw-r--r-- | src/vm/method.hpp | 15 | ||||
-rw-r--r-- | src/vm/method.inl | 8 | ||||
-rw-r--r-- | src/vm/methodtable.cpp | 74 | ||||
-rw-r--r-- | src/vm/methodtable.h | 28 | ||||
-rw-r--r-- | src/vm/methodtablebuilder.cpp | 7 | ||||
-rw-r--r-- | src/vm/siginfo.cpp | 44 | ||||
-rw-r--r-- | src/vm/typeequivalencehash.cpp | 4 | ||||
-rw-r--r-- | src/vm/typeequivalencehash.hpp | 41 |
13 files changed, 113 insertions, 132 deletions
diff --git a/src/vm/CMakeLists.txt b/src/vm/CMakeLists.txt index 06532b30f2..c5873ee4ed 100644 --- a/src/vm/CMakeLists.txt +++ b/src/vm/CMakeLists.txt @@ -114,6 +114,7 @@ set(VM_SOURCES_DAC_AND_WKS_COMMON tieredcompilation.cpp typectxt.cpp typedesc.cpp + typeequivalencehash.cpp typehandle.cpp typehash.cpp typestring.cpp @@ -220,6 +221,7 @@ set(VM_HEADERS_DAC_AND_WKS_COMMON typectxt.h typedesc.h typedesc.inl + typeequivalencehash.hpp typehandle.h typehandle.inl typehash.h diff --git a/src/vm/appdomain.cpp b/src/vm/appdomain.cpp index 0a5e9de23c..b0cb03bcb3 100644 --- a/src/vm/appdomain.cpp +++ b/src/vm/appdomain.cpp @@ -52,9 +52,8 @@ #include "rcwrefcache.h" #include "olecontexthelpers.h" #endif // FEATURE_COMINTEROP -#ifdef FEATURE_TYPEEQUIVALENCE + #include "typeequivalencehash.hpp" -#endif #include "appdomain.inl" #include "typeparse.h" @@ -8826,7 +8825,7 @@ TypeEquivalenceHashTable * AppDomain::GetTypeEquivalenceCache() #endif if (m_pTypeEquivalenceTable.Load() == NULL) { - m_pTypeEquivalenceTable = TypeEquivalenceHashTable::Create(this, 12, &m_TypeEquivalenceCrst); + m_pTypeEquivalenceTable = TypeEquivalenceHashTable::Create(this, /* bucket count */ 12, &m_TypeEquivalenceCrst); } } return m_pTypeEquivalenceTable; diff --git a/src/vm/class.h b/src/vm/class.h index 34aac07e3e..54253ea70d 100644 --- a/src/vm/class.h +++ b/src/vm/class.h @@ -1127,13 +1127,13 @@ public: return m_VMFlags & VMFLAG_IS_EQUIVALENT_TYPE; } -#ifdef FEATURE_COMINTEROP +#ifdef FEATURE_TYPEEQUIVALENCE inline void SetIsEquivalentType() { LIMITED_METHOD_CONTRACT; m_VMFlags |= VMFLAG_IS_EQUIVALENT_TYPE; } -#endif +#endif // FEATURE_TYPEEQUIVALENCE /* * Number of static handles allocated diff --git a/src/vm/crossgen/CMakeLists.txt b/src/vm/crossgen/CMakeLists.txt index 1d1eb23dab..8c9bfc58c2 100644 --- a/src/vm/crossgen/CMakeLists.txt +++ b/src/vm/crossgen/CMakeLists.txt @@ -76,6 +76,7 @@ set(VM_CROSSGEN_SOURCES ../stublink.cpp ../typectxt.cpp ../typedesc.cpp + ../typeequivalencehash.cpp ../typehandle.cpp ../typehash.cpp ../typeparse.cpp @@ -172,6 +173,7 @@ set(VM_CROSSGEN_HEADERS ../typectxt.h ../typedesc.h ../typedesc.inl + ../typeequivalencehash.hpp ../typehandle.h ../typehandle.inl ../typehash.h diff --git a/src/vm/method.cpp b/src/vm/method.cpp index 3c2ba7d17f..9c19c688ac 100644 --- a/src/vm/method.cpp +++ b/src/vm/method.cpp @@ -5407,7 +5407,7 @@ moveToNextToken: #ifdef FEATURE_TYPEEQUIVALENCE -void CheckForEquivalenceAndLoadType(Module *pModule, mdToken token, Module *pDefModule, mdToken defToken, const SigParser *ptr, SigTypeContext *pTypeContext, void *pData) +static void CheckForEquivalenceAndLoadType(Module *pModule, mdToken token, Module *pDefModule, mdToken defToken, const SigParser *ptr, SigTypeContext *pTypeContext, void *pData) { CONTRACTL { @@ -5426,9 +5426,11 @@ void CheckForEquivalenceAndLoadType(Module *pModule, mdToken token, Module *pDef TypeHandle th = sigPtr.GetTypeHandleThrowing(pModule, pTypeContext); } } +#endif // FEATURE_TYPEEQUIVALENCE BOOL MethodDesc::HasTypeEquivalentStructParameters() { +#ifdef FEATURE_TYPEEQUIVALENCE CONTRACTL { THROWS; @@ -5447,9 +5449,14 @@ BOOL MethodDesc::HasTypeEquivalentStructParameters() SetDoesNotHaveEquivalentValuetypeParameters(); return fHasTypeEquivalentStructParameters; -} + +#else + LIMITED_METHOD_CONTRACT; + return FALSE; #endif // FEATURE_TYPEEQUIVALENCE +} + PrecodeType MethodDesc::GetPrecodeType() { diff --git a/src/vm/method.hpp b/src/vm/method.hpp index 529064d0ea..8b136e6fd3 100644 --- a/src/vm/method.hpp +++ b/src/vm/method.hpp @@ -1615,15 +1615,8 @@ public: VOID GetMethodInfoNoSig(SString &namespaceOrClassName, SString &methodName); VOID GetFullMethodInfo(SString& fullMethodSigName); - BOOL HasTypeEquivalentStructParameters() -#ifndef FEATURE_TYPEEQUIVALENCE - { - LIMITED_METHOD_CONTRACT; - return FALSE; - } -#else - ; -#endif + BOOL HasTypeEquivalentStructParameters(); + typedef void (*WalkValueTypeParameterFnPtr)(Module *pModule, mdToken token, Module *pDefModule, mdToken tkDefToken, const SigParser *ptr, SigTypeContext *pTypeContext, void *pData); void WalkValueTypeParameters(MethodTable *pMT, WalkValueTypeParameterFnPtr function, void *pData); @@ -1749,7 +1742,7 @@ public: WORD InterlockedUpdateFlags3(WORD wMask, BOOL fSet); -#ifdef FEATURE_COMINTEROP +#ifdef FEATURE_TYPEEQUIVALENCE inline BOOL DoesNotHaveEquivalentValuetypeParameters() { LIMITED_METHOD_DAC_CONTRACT; @@ -1761,7 +1754,7 @@ public: LIMITED_METHOD_CONTRACT; InterlockedUpdateFlags3(enum_flag3_DoesNotHaveEquivalentValuetypeParameters, TRUE); } -#endif //FEATURE_COMINTEROP +#endif // FEATURE_TYPEEQUIVALENCE inline BOOL HasForwardedValuetypeParameter() { diff --git a/src/vm/method.inl b/src/vm/method.inl index ca9a17a715..9d55ae9260 100644 --- a/src/vm/method.inl +++ b/src/vm/method.inl @@ -170,14 +170,6 @@ inline ComPlusCallInfo *ComPlusCallInfo::FromMethodDesc(MethodDesc *pMD) #endif //FEATURE_COMINTEROP -#ifndef FEATURE_TYPEEQUIVALENCE -inline BOOL HasTypeEquivalentStructParameters() -{ - LIMITED_METHOD_CONTRACT; - return FALSE; -} -#endif // FEATURE_TYPEEQUIVALENCE - #ifdef FEATURE_CODE_VERSIONING inline CodeVersionManager * MethodDesc::GetCodeVersionManager() { diff --git a/src/vm/methodtable.cpp b/src/vm/methodtable.cpp index d83e62d450..5ed91d1fe2 100644 --- a/src/vm/methodtable.cpp +++ b/src/vm/methodtable.cpp @@ -56,9 +56,7 @@ #include "winrttypenameconverter.h" #endif // FEATURE_COMINTEROP -#ifdef FEATURE_TYPEEQUIVALENCE #include "typeequivalencehash.hpp" -#endif #include "generics.h" #include "genericdict.h" @@ -604,14 +602,6 @@ void MethodTable::SetComObjectType() SetFlag(enum_flag_ComObject); } -#if defined(FEATURE_TYPEEQUIVALENCE) -void MethodTable::SetHasTypeEquivalence() -{ - LIMITED_METHOD_CONTRACT; - SetFlag(enum_flag_HasTypeEquivalence); -} -#endif - #ifdef FEATURE_ICASTABLE void MethodTable::SetICastable() { @@ -1397,10 +1387,12 @@ BOOL MethodTable::IsEquivalentTo_WorkerInner(MethodTable *pOtherMT COMMA_INDEBUG } CONTRACTL_END; + TypeEquivalenceHashTable *typeHashTable = NULL; AppDomain *pDomain = GetAppDomain(); if (pDomain != NULL) { - TypeEquivalenceHashTable::EquivalenceMatch match = pDomain->GetTypeEquivalenceCache()->CheckEquivalence(TypeHandle(this), TypeHandle(pOtherMT)); + typeHashTable = pDomain->GetTypeEquivalenceCache(); + TypeEquivalenceHashTable::EquivalenceMatch match = typeHashTable->CheckEquivalence(TypeHandle(this), TypeHandle(pOtherMT)); switch (match) { case TypeEquivalenceHashTable::Match: @@ -1417,9 +1409,10 @@ BOOL MethodTable::IsEquivalentTo_WorkerInner(MethodTable *pOtherMT COMMA_INDEBUG BOOL fEquivalent = FALSE; + // Check if type is generic if (HasInstantiation()) { - // we limit variance on generics only to interfaces + // Limit variance on generics only to interfaces if (!IsInterface() || !pOtherMT->IsInterface()) { fEquivalent = FALSE; @@ -1430,12 +1423,14 @@ BOOL MethodTable::IsEquivalentTo_WorkerInner(MethodTable *pOtherMT COMMA_INDEBUG Instantiation inst1 = GetInstantiation(); Instantiation inst2 = pOtherMT->GetInstantiation(); + // Verify generic argument count if (inst1.GetNumArgs() != inst2.GetNumArgs()) { fEquivalent = FALSE; goto EquivalenceCalculated; } + // Verify each generic argument type for (DWORD i = 0; i < inst1.GetNumArgs(); i++) { if (!inst1[i].IsEquivalentTo(inst2[i] COMMA_INDEBUG(pVisited))) @@ -1467,22 +1462,23 @@ BOOL MethodTable::IsEquivalentTo_WorkerInner(MethodTable *pOtherMT COMMA_INDEBUG } // arrays of structures have their own unshared MTs and will take this path - fEquivalent = (GetApproxArrayElementTypeHandle().IsEquivalentTo(pOtherMT->GetApproxArrayElementTypeHandle() COMMA_INDEBUG(pVisited))); + TypeHandle elementType1 = GetApproxArrayElementTypeHandle(); + TypeHandle elementType2 = pOtherMT->GetApproxArrayElementTypeHandle(); + fEquivalent = elementType1.IsEquivalentTo(elementType2 COMMA_INDEBUG(pVisited)); goto EquivalenceCalculated; } fEquivalent = CompareTypeDefsForEquivalence(GetCl(), pOtherMT->GetCl(), GetModule(), pOtherMT->GetModule(), NULL); EquivalenceCalculated: - // Only record equivalence matches if we are in an AppDomain - if (pDomain != NULL) + // Record equivalence matches if a table exists + if (typeHashTable != NULL) { // Collectible type results will not get cached. - if ((!this->Collectible() && !pOtherMT->Collectible())) + if ((!Collectible() && !pOtherMT->Collectible())) { - TypeEquivalenceHashTable::EquivalenceMatch match; - match = fEquivalent ? TypeEquivalenceHashTable::Match : TypeEquivalenceHashTable::NoMatch; - pDomain->GetTypeEquivalenceCache()->RecordEquivalence(TypeHandle(this), TypeHandle(pOtherMT), match); + auto match = fEquivalent ? TypeEquivalenceHashTable::Match : TypeEquivalenceHashTable::NoMatch; + typeHashTable->RecordEquivalence(TypeHandle(this), TypeHandle(pOtherMT), match); } } @@ -5363,12 +5359,12 @@ VOID DoAccessibilityCheckForConstraints(MethodTable *pAskingMT, TypeVarTypeDesc // Used so that we can have one valuetype walking algorithm used for type equivalence walking of the parameters of the method. struct DoFullyLoadLocals { - DoFullyLoadLocals(DFLPendingList *pPendingParam, ClassLoadLevel levelParam, MethodTable *pMT, Generics::RecursionGraph *pVisited) : - newVisited(pVisited, TypeHandle(pMT)), - pPending(pPendingParam), - level(levelParam), - fBailed(FALSE) -#ifdef FEATURE_COMINTEROP + DoFullyLoadLocals(DFLPendingList *pPendingParam, ClassLoadLevel levelParam, MethodTable *pMT, Generics::RecursionGraph *pVisited) + : newVisited(pVisited, TypeHandle(pMT)) + , pPending(pPendingParam) + , level(levelParam) + , fBailed(FALSE) +#ifdef FEATURE_TYPEEQUIVALENCE , fHasEquivalentStructParameter(FALSE) #endif , fHasTypeForwarderDependentStructParameter(FALSE) @@ -5381,7 +5377,7 @@ struct DoFullyLoadLocals DFLPendingList * const pPending; const ClassLoadLevel level; BOOL fBailed; -#ifdef FEATURE_COMINTEROP +#ifdef FEATURE_TYPEEQUIVALENCE BOOL fHasEquivalentStructParameter; #endif BOOL fHasTypeForwarderDependentStructParameter; @@ -6677,7 +6673,7 @@ MethodTable *MethodTable::GetDefaultWinRTInterface() #endif // !DACCESS_COMPILE #endif // FEATURE_COMINTEROP -#ifdef FEATURE_COMINTEROP +#ifdef FEATURE_TYPEEQUIVALENCE #ifndef DACCESS_COMPILE WORD GetEquivalentMethodSlot(MethodTable * pOldMT, MethodTable * pNewMT, WORD wMTslot, BOOL *pfFound) @@ -6687,20 +6683,15 @@ WORD GetEquivalentMethodSlot(MethodTable * pOldMT, MethodTable * pNewMT, WORD wM GC_NOTRIGGER; } CONTRACTL_END; - MethodDesc * pMDRet = NULL; *pfFound = FALSE; + WORD wVTslot = wMTslot; + +#ifdef FEATURE_COMINTEROP // Get the COM vtable slot corresponding to the given MT slot - WORD wVTslot; if (pOldMT->IsSparseForCOMInterop()) - { wVTslot = pOldMT->GetClass()->GetSparseCOMInteropVTableMap()->LookupVTSlot(wMTslot); - } - else - { - wVTslot = wMTslot; - } - + // If the other MT is not sparse, we can return the COM slot directly if (!pNewMT->IsSparseForCOMInterop()) { @@ -6722,9 +6713,18 @@ WORD GetEquivalentMethodSlot(MethodTable * pOldMT, MethodTable * pNewMT, WORD wM _ASSERTE(!*pfFound); return 0; + +#else + // No COM means there is no sparse interface + if (wVTslot < pNewMT->GetNumVirtuals()) + *pfFound = TRUE; + + return wVTslot; + +#endif // FEATURE_COMINTEROP } #endif // #ifdef DACCESS_COMPILE -#endif // #ifdef FEATURE_COMINTEROP +#endif // #ifdef FEATURE_TYPEEQUIVALENCE //========================================================================================== BOOL diff --git a/src/vm/methodtable.h b/src/vm/methodtable.h index b0dc5e7575..72482f29fe 100644 --- a/src/vm/methodtable.h +++ b/src/vm/methodtable.h @@ -746,11 +746,6 @@ public: BOOL IsExtensibleRCW(); -#if defined(FEATURE_TYPEEQUIVALENCE) - // mark the type as opted into type equivalence - void SetHasTypeEquivalence(); -#endif - // Helper to get parent class skipping over COM class in // the hierarchy MethodTable* GetComPlusParentMethodTable(); @@ -822,19 +817,24 @@ public: BOOL IsICastable(); // This type implements ICastable interface #ifdef FEATURE_TYPEEQUIVALENCE - // type has opted into type equivalence or is instantiated by/derived from a type that is - BOOL HasTypeEquivalence() + // mark the type as opted into type equivalence + void SetHasTypeEquivalence() { LIMITED_METHOD_CONTRACT; - return GetFlag(enum_flag_HasTypeEquivalence); + SetFlag(enum_flag_HasTypeEquivalence); } -#else +#endif // FEATURE_TYPEEQUIVALENCE + + // type has opted into type equivalence or is instantiated by/derived from a type that is BOOL HasTypeEquivalence() { LIMITED_METHOD_CONTRACT; +#ifdef FEATURE_TYPEEQUIVALENCE + return GetFlag(enum_flag_HasTypeEquivalence); +#else return FALSE; +#endif // FEATURE_TYPEEQUIVALENCE } -#endif //------------------------------------------------------------------- // DYNAMIC ADDITION OF INTERFACES FOR COM INTEROP @@ -2019,12 +2019,12 @@ public: #ifndef DACCESS_COMPILE FORCEINLINE BOOL IsEquivalentTo(MethodTable *pOtherMT COMMA_INDEBUG(TypeHandlePairList *pVisited = NULL)); -#ifdef FEATURE_COMINTEROP +#ifdef FEATURE_TYPEEQUIVALENCE // This method is public so that TypeHandle has direct access to it BOOL IsEquivalentTo_Worker(MethodTable *pOtherMT COMMA_INDEBUG(TypeHandlePairList *pVisited)); // out-of-line part, SO tolerant private: BOOL IsEquivalentTo_WorkerInner(MethodTable *pOtherMT COMMA_INDEBUG(TypeHandlePairList *pVisited)); // out-of-line part, SO intolerant -#endif // FEATURE_COMINTEROP +#endif // FEATURE_TYPEEQUIVALENCE #endif public: @@ -4168,9 +4168,9 @@ public: #ifndef CROSSBITNESS_COMPILE static_assert_no_msg(sizeof(MethodTable) == SIZEOF__MethodTable_); #endif -#if defined(FEATURE_COMINTEROP) && !defined(DACCESS_COMPILE) +#if defined(FEATURE_TYPEEQUIVALENCE) && !defined(DACCESS_COMPILE) WORD GetEquivalentMethodSlot(MethodTable * pOldMT, MethodTable * pNewMT, WORD wMTslot, BOOL *pfFound); -#endif // defined(FEATURE_COMINTEROP) && !defined(DACCESS_COMPILE) +#endif // defined(FEATURE_TYPEEQUIVALENCE) && !defined(DACCESS_COMPILE) MethodTable* CreateMinimalMethodTable(Module* pContainingModule, LoaderHeap* pCreationHeap, diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp index 105ffb2737..7c52ebcb3c 100644 --- a/src/vm/methodtablebuilder.cpp +++ b/src/vm/methodtablebuilder.cpp @@ -11433,7 +11433,12 @@ void MethodTableBuilder::CheckForTypeEquivalence( if (bmtProp->fIsTypeEquivalent) { - BOOL fTypeEquivalentNotPermittedDueToType = !(((IsComImport() || bmtProp->fComEventItfType) && IsInterface()) || IsValueClass() || IsDelegate()); + BOOL comImportOrEventInterface = IsComImport(); +#ifdef FEATURE_COMINTEROP + comImportOrEventInterface = comImportOrEventInterface || bmtProp->fComEventItfType; +#endif // FEATURE_COMINTEROP + + BOOL fTypeEquivalentNotPermittedDueToType = !((comImportOrEventInterface && IsInterface()) || IsValueClass() || IsDelegate()); BOOL fTypeEquivalentNotPermittedDueToGenerics = bmtGenerics->HasInstantiation(); if (fTypeEquivalentNotPermittedDueToType || fTypeEquivalentNotPermittedDueToGenerics) diff --git a/src/vm/siginfo.cpp b/src/vm/siginfo.cpp index 1995d51515..0a9599edc9 100644 --- a/src/vm/siginfo.cpp +++ b/src/vm/siginfo.cpp @@ -2795,7 +2795,11 @@ HRESULT TypeIdentifierData::Init(Module *pModule, mdToken tk) else { // no TypeIdentifierAttribute -> the assembly must be a type library - bool has_eq = !pModule->GetAssembly()->IsDynamic() && pModule->GetAssembly()->IsPIAOrImportedFromTypeLib(); + bool has_eq = !pModule->GetAssembly()->IsDynamic(); + +#ifdef FEATURE_COMINTEROP + has_eq = has_eq && pModule->GetAssembly()->IsPIAOrImportedFromTypeLib(); +#endif // FEATURE_COMINTEROP if (!has_eq) { @@ -2900,33 +2904,6 @@ BOOL TypeIdentifierData::IsEqual(const TypeIdentifierData & data) const (memcmp(m_pchIdentifierName, data.m_pchIdentifierName + m_cbIdentifierNamespace + 1, m_cbIdentifierName) == 0); } -#endif //FEATURE_TYPEEQUIVALENCE -#ifdef FEATURE_COMINTEROP - -//--------------------------------------------------------------------------------------- -// -static CorElementType GetFieldSigElementType(PCCOR_SIGNATURE pSig, DWORD cbSig) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END - - SigPointer sigptr(pSig, cbSig); - - ULONG data; - IfFailThrow(sigptr.GetCallingConv(&data)); - _ASSERTE(data == IMAGE_CEE_CS_CALLCONV_FIELD); - - CorElementType etype; - IfFailThrow(sigptr.GetElemType(&etype)); - - return etype; -} - //--------------------------------------------------------------------------------------- // static BOOL CompareStructuresForEquivalence(mdToken tk1, mdToken tk2, Module *pModule1, Module *pModule2, BOOL fEnumMode, TokenPairList *pVisited) @@ -3073,7 +3050,7 @@ static BOOL CompareDelegatesForEquivalence(mdToken tk1, mdToken tk2, Module *pMo return MetaSig::CompareMethodSigs(pSig1, cbSig1, pModule1, NULL, pSig2, cbSig2, pModule2, NULL, pVisited); } -#endif // FEATURE_COMINTEROP +#endif // FEATURE_TYPEEQUIVALENCE #endif // #ifndef DACCESS_COMPILE #ifndef DACCESS_COMPILE @@ -3178,7 +3155,12 @@ BOOL IsTypeDefEquivalent(mdToken tk, Module *pModule) // 1. Type is within assembly marked with ImportedFromTypeLibAttribute or PrimaryInteropAssemblyAttribute if (hr != S_OK) { - bool has_eq = !pModule->GetAssembly()->IsDynamic() && pModule->GetAssembly()->IsPIAOrImportedFromTypeLib(); + // no TypeIdentifierAttribute -> the assembly must be a type library + bool has_eq = !pModule->GetAssembly()->IsDynamic(); + +#ifdef FEATURE_COMINTEROP + has_eq = has_eq && pModule->GetAssembly()->IsPIAOrImportedFromTypeLib(); +#endif // FEATURE_COMINTEROP if (!has_eq) return FALSE; @@ -3426,7 +3408,7 @@ BOOL CompareTypeDefsForEquivalence(mdToken tk1, mdToken tk2, Module *pModule1, M } return TRUE; -#else //!defined(DACCESS_COMPILE) && defined(FEATURE_COMINTEROP) +#else //!defined(DACCESS_COMPILE) && defined(FEATURE_TYPEEQUIVALENCE) #ifdef DACCESS_COMPILE // We shouldn't execute this code in dac builds. diff --git a/src/vm/typeequivalencehash.cpp b/src/vm/typeequivalencehash.cpp index ca2ecfdb2d..90b2c2749e 100644 --- a/src/vm/typeequivalencehash.cpp +++ b/src/vm/typeequivalencehash.cpp @@ -55,8 +55,8 @@ TypeEquivalenceHashTable *TypeEquivalenceHashTable::Create(AppDomain *pAppDomain LoaderHeap *pHeap = pAppDomain->GetLowFrequencyHeap(); TypeEquivalenceHashTable *pThis = (TypeEquivalenceHashTable*)amt.Track(pHeap->AllocMem((S_SIZE_T)sizeof(TypeEquivalenceHashTable))); - // The base class get initialized through chaining of constructors. We allocated the hash instance via the - // loader heap instead of new so use an in-place new to call the constructors now. + // The base class gets initialized through chaining of constructors. + // Use in-place new to create instance. new (pThis) TypeEquivalenceHashTable(pHeap, dwNumBuckets, pCrst); amt.SuppressRelease(); diff --git a/src/vm/typeequivalencehash.hpp b/src/vm/typeequivalencehash.hpp index 3ce5231ac9..d750ff0659 100644 --- a/src/vm/typeequivalencehash.hpp +++ b/src/vm/typeequivalencehash.hpp @@ -10,13 +10,13 @@ #ifndef __TYPEEQUIVALENCE_HASH_INCLUDED #define __TYPEEQUIVALENCE_HASH_INCLUDED -#include "ngenhash.h" - #ifdef FEATURE_TYPEEQUIVALENCE +#include "ngenhash.h" + // The type of each entry in the hash. typedef DPTR(struct TypeEquivalenceEntry) PTR_TypeEquivalenceEntry; -typedef struct TypeEquivalenceEntry +struct TypeEquivalenceEntry { static NgenHashValue HashTypeHandles(TypeHandle thA, TypeHandle thB) { @@ -33,8 +33,8 @@ typedef struct TypeEquivalenceEntry { LIMITED_METHOD_CONTRACT; - return (((thA == m_thA) && (thB == m_thB)) || - ((thB == m_thA) && (thA == m_thB))); + return (((thA == m_thA) && (thB == m_thB)) + || ((thB == m_thA) && (thA == m_thB))); } void SetData(TypeHandle thA, TypeHandle thB, bool fEquivalent) @@ -53,11 +53,10 @@ typedef struct TypeEquivalenceEntry } private: - TypeHandle m_thA; TypeHandle m_thB; bool m_fEquivalent; -} TypeEquivalenceEntry_t; +}; // The hash type itself. All common logic is provided by the NgenHashTable templated base class. See // NgenHash.h for details. @@ -70,7 +69,7 @@ class TypeEquivalenceHashTable : public NgenHashTable<TypeEquivalenceHashTable, #endif public: - typedef enum EquivalenceMatch + enum EquivalenceMatch { MatchUnknown, Match, @@ -88,29 +87,29 @@ public: EquivalenceMatch CheckEquivalence(TypeHandle thA, TypeHandle thB); #ifdef DACCESS_COMPILE - void EnumMemoryRegionsForEntry(TypeEquivalenceEntry_t *pEntry, CLRDataEnumMemoryFlags flags) { return; } + void EnumMemoryRegionsForEntry(TypeEquivalenceEntry *pEntry, CLRDataEnumMemoryFlags flags) { return; } #endif #if defined(FEATURE_PREJIT) && !defined(DACCESS_COMPILE) private: - - bool ShouldSave(DataImage *pImage, TypeEquivalenceEntry_t *pEntry) { return false; } - bool IsHotEntry(TypeEquivalenceEntry_t *pEntry, CorProfileData *pProfileData) { return false; } - bool SaveEntry(DataImage *pImage, CorProfileData *pProfileData, TypeEquivalenceEntry_t *pOldEntry, TypeEquivalenceEntry_t *pNewEntry, EntryMappingTable *pMap) { return true; } - void FixupEntry(DataImage *pImage, TypeEquivalenceEntry_t *pEntry, void *pFixupBase, DWORD cbFixupOffset) { return; } + // Override operations from NgenHashTable - see ngenhash.h + bool ShouldSave(DataImage *pImage, TypeEquivalenceEntry *pEntry) { return false; } + bool IsHotEntry(TypeEquivalenceEntry *pEntry, CorProfileData *pProfileData) { return false; } + bool SaveEntry(DataImage *pImage, CorProfileData *pProfileData, TypeEquivalenceEntry *pOldEntry, TypeEquivalenceEntry *pNewEntry, EntryMappingTable *pMap) { return true; } + void FixupEntry(DataImage *pImage, TypeEquivalenceEntry *pEntry, void *pFixupBase, DWORD cbFixupOffset) { return; } #endif // FEATURE_PREJIT && !DACCESS_COMPILE private: #ifndef DACCESS_COMPILE - TypeEquivalenceHashTable(LoaderHeap *pHeap, DWORD cInitialBuckets, CrstExplicitInit *pCrst) : - NgenHashTable<TypeEquivalenceHashTable, TypeEquivalenceEntry, 4>(NULL, pHeap, cInitialBuckets), - m_pHashTableCrst(pCrst) + TypeEquivalenceHashTable(LoaderHeap *pHeap, DWORD cInitialBuckets, CrstExplicitInit *pCrst) + : NgenHashTable<TypeEquivalenceHashTable, TypeEquivalenceEntry, 4>(NULL, pHeap, cInitialBuckets) + , m_pHashTableCrst(pCrst) { } -#endif - CrstExplicitInit* m_pHashTableCrst; +#endif // DACCESS_COMPILE + + CrstExplicitInit* m_pHashTableCrst; }; #endif // FEATURE_TYPEEQUIVALENCE - -#endif // !__CLASS_HASH_INCLUDED +#endif // !__TYPEEQUIVALENCE_HASH_INCLUDED |