1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 // File: pendingload.cpp
12 #include "pendingload.h"
14 #ifndef DACCESS_COMPILE
17 // ============================================================================
18 // Pending type load hash table methods
19 // ============================================================================
20 /*static */ PendingTypeLoadTable* PendingTypeLoadTable::Create(LoaderHeap *pHeap,
22 AllocMemTracker *pamTracker)
27 PRECONDITION(CheckPointer(pHeap));
31 size_t size = sizeof(PendingTypeLoadTable);
33 PendingTypeLoadTable * pThis;
35 _ASSERT( dwNumBuckets >= 0 );
36 S_SIZE_T allocSize = S_SIZE_T( dwNumBuckets )
37 * S_SIZE_T( sizeof(PendingTypeLoadTable::TableEntry*) )
39 if( allocSize.IsOverflow() )
41 ThrowHR(E_INVALIDARG);
43 pMem = (BYTE *) pamTracker->Track(pHeap->AllocMem( allocSize ));
45 pThis = (PendingTypeLoadTable *) pMem;
48 pThis->m_dwDebugMemory = (DWORD)(size + dwNumBuckets*sizeof(PendingTypeLoadTable::TableEntry*));
51 pThis->m_dwNumBuckets = dwNumBuckets;
52 pThis->m_pBuckets = (PendingTypeLoadTable::TableEntry**) (pMem + size);
54 // Don't need to memset() since this was ClrVirtualAlloc()'d memory
55 // memset(pThis->m_pBuckets, 0, dwNumBuckets*sizeof(PendingTypeLoadTable::TableEntry*));
62 PendingTypeLoadTable::TableEntry *PendingTypeLoadTable::AllocNewEntry()
69 INJECT_FAULT( return NULL; );
74 m_dwDebugMemory += (DWORD) (sizeof(PendingTypeLoadTable::TableEntry));
77 return (PendingTypeLoadTable::TableEntry *) new (nothrow) BYTE[sizeof(PendingTypeLoadTable::TableEntry)];
81 void PendingTypeLoadTable::FreeEntry(PendingTypeLoadTable::TableEntry * pEntry)
91 // keep in sync with the allocator used in AllocNewEntry
92 delete[] ((BYTE*)pEntry);
95 m_dwDebugMemory -= (DWORD) (sizeof(PendingTypeLoadTable::TableEntry));
101 // Does not handle duplicates!
103 BOOL PendingTypeLoadTable::InsertValue(PendingTypeLoadEntry *pData)
110 INJECT_FAULT( return FALSE; );
111 PRECONDITION(CheckPointer(pData));
112 PRECONDITION(FindItem(&pData->GetTypeKey()) == NULL);
116 _ASSERTE(m_dwNumBuckets != 0);
118 DWORD dwHash = pData->GetTypeKey().ComputeHash();
119 DWORD dwBucket = dwHash % m_dwNumBuckets;
120 PendingTypeLoadTable::TableEntry * pNewEntry = AllocNewEntry();
121 if (pNewEntry == NULL)
124 // Insert at head of bucket
125 pNewEntry->pNext = m_pBuckets[dwBucket];
126 pNewEntry->pData = pData;
127 pNewEntry->dwHashValue = dwHash;
129 m_pBuckets[dwBucket] = pNewEntry;
135 BOOL PendingTypeLoadTable::DeleteValue(TypeKey *pKey)
143 PRECONDITION(CheckPointer(pKey));
147 _ASSERTE(m_dwNumBuckets != 0);
149 DWORD dwHash = pKey->ComputeHash();
150 DWORD dwBucket = dwHash % m_dwNumBuckets;
151 PendingTypeLoadTable::TableEntry * pSearch;
152 PendingTypeLoadTable::TableEntry **ppPrev = &m_pBuckets[dwBucket];
154 for (pSearch = m_pBuckets[dwBucket]; pSearch; pSearch = pSearch->pNext)
156 TypeKey entryTypeKey = pSearch->pData->GetTypeKey();
157 if (pSearch->dwHashValue == dwHash && TypeKey::Equals(pKey, &entryTypeKey))
159 *ppPrev = pSearch->pNext;
164 ppPrev = &pSearch->pNext;
171 PendingTypeLoadTable::TableEntry *PendingTypeLoadTable::FindItem(TypeKey *pKey)
179 PRECONDITION(CheckPointer(pKey));
183 _ASSERTE(m_dwNumBuckets != 0);
186 DWORD dwHash = pKey->ComputeHash();
187 DWORD dwBucket = dwHash % m_dwNumBuckets;
188 PendingTypeLoadTable::TableEntry * pSearch;
190 for (pSearch = m_pBuckets[dwBucket]; pSearch; pSearch = pSearch->pNext)
192 TypeKey entryTypeKey = pSearch->pData->GetTypeKey();
193 if (pSearch->dwHashValue == dwHash && TypeKey::Equals(pKey, &entryTypeKey))
204 void PendingTypeLoadTable::Dump()
214 LOG((LF_CLASSLOADER, LL_INFO10000, "PHASEDLOAD: table contains:\n"));
215 for (DWORD i = 0; i < m_dwNumBuckets; i++)
217 for (TableEntry *pSearch = m_pBuckets[i]; pSearch; pSearch = pSearch->pNext)
220 TypeKey entryTypeKey = pSearch->pData->GetTypeKey();
221 TypeString::AppendTypeKeyDebug(name, &entryTypeKey);
222 LOG((LF_CLASSLOADER, LL_INFO10000, " Entry %S with handle %p at level %s\n", name.GetUnicode(), pSearch->pData->m_typeHandle.AsPtr(),
223 pSearch->pData->m_typeHandle.IsNull() ? "not-applicable" : classLoadLevelName[pSearch->pData->m_typeHandle.GetLoadLevel()]));
229 PendingTypeLoadEntry* PendingTypeLoadTable::GetValue(TypeKey *pKey)
237 PRECONDITION(CheckPointer(pKey));
241 PendingTypeLoadTable::TableEntry *pItem = FindItem(pKey);
253 #endif // #ifndef DACCESS_COMPILE