diff options
Diffstat (limited to 'src/vm/typeequivalencehash.cpp')
-rw-r--r-- | src/vm/typeequivalencehash.cpp | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/src/vm/typeequivalencehash.cpp b/src/vm/typeequivalencehash.cpp new file mode 100644 index 0000000000..ca2ecfdb2d --- /dev/null +++ b/src/vm/typeequivalencehash.cpp @@ -0,0 +1,100 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// +// Hash table associated with each module that records for all types defined in that module the mapping +// between type name and token (or TypeHandle). +// + +#include "common.h" +#include "typeequivalencehash.hpp" +#include "ngenhash.inl" + +#ifdef FEATURE_TYPEEQUIVALENCE +TypeEquivalenceHashTable::EquivalenceMatch TypeEquivalenceHashTable::CheckEquivalence(TypeHandle thA, TypeHandle thB) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_ANY; + } + CONTRACTL_END; + + LookupContext lookupContext; + NgenHashValue hash = TypeEquivalenceEntry::HashTypeHandles(thA, thB); + + PTR_TypeEquivalenceEntry search = BaseFindFirstEntryByHash(hash, &lookupContext); + while (search != NULL) + { + if (search->Match(thA, thB)) + { + return search->GetEquivalence() ? Match : NoMatch; + } + + search = BaseFindNextEntryByHash(&lookupContext); + } + return MatchUnknown; +} + +#ifndef DACCESS_COMPILE +/*static*/ +TypeEquivalenceHashTable *TypeEquivalenceHashTable::Create(AppDomain *pAppDomain, DWORD dwNumBuckets, CrstExplicitInit *pCrst) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_ANY; + INJECT_FAULT(COMPlusThrowOM();); + } + CONTRACTL_END; + + AllocMemTracker amt; + 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. + new (pThis) TypeEquivalenceHashTable(pHeap, dwNumBuckets, pCrst); + amt.SuppressRelease(); + + return pThis; +} + +void TypeEquivalenceHashTable::RecordEquivalence(TypeHandle thA, TypeHandle thB, TypeEquivalenceHashTable::EquivalenceMatch match) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_ANY; + INJECT_FAULT(COMPlusThrowOM();); + PRECONDITION(match != TypeEquivalenceHashTable::MatchUnknown); + } + CONTRACTL_END; + + CrstHolder ch(m_pHashTableCrst); + + // Was there a race in calculating equivalence and this thread lost? + // If so, return + EquivalenceMatch checkedMatch = CheckEquivalence(thA, thB); + if (checkedMatch != TypeEquivalenceHashTable::MatchUnknown) + { + _ASSERTE(checkedMatch == match); + return; + } + + AllocMemTracker amt; + PTR_TypeEquivalenceEntry pNewEntry = BaseAllocateEntry(&amt); + amt.SuppressRelease(); + + pNewEntry->SetData(thA, thB, match == TypeEquivalenceHashTable::Match ? true : false); + NgenHashValue hash = TypeEquivalenceEntry::HashTypeHandles(thA, thB); + + BaseInsertEntry(hash, pNewEntry); +} +#endif // !DACCESS_COMPILE +#endif // FEATURE_TYPEEQUIVALENCE + |