[Tizen] Unify dnetmemoryenumlib terms to match the codebase (#291)
[platform/upstream/coreclr.git] / src / vm / pendingload.cpp
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.
4 //
5 // File: pendingload.cpp
6 //
7
8 //
9
10 #include "common.h"
11 #include "excep.h"
12 #include "pendingload.h"
13
14 #ifndef DACCESS_COMPILE
15
16
17 // ============================================================================
18 // Pending type load hash table methods
19 // ============================================================================
20 /*static */ PendingTypeLoadTable* PendingTypeLoadTable::Create(LoaderHeap *pHeap, 
21                                                                DWORD dwNumBuckets, 
22                                                                AllocMemTracker *pamTracker)
23 {
24     CONTRACTL
25     {
26         STANDARD_VM_CHECK;
27         PRECONDITION(CheckPointer(pHeap));
28     }
29     CONTRACTL_END;
30
31     size_t                  size = sizeof(PendingTypeLoadTable);
32     BYTE *                  pMem;
33     PendingTypeLoadTable * pThis;
34
35     _ASSERT( dwNumBuckets >= 0 );
36     S_SIZE_T allocSize = S_SIZE_T( dwNumBuckets ) 
37                                         * S_SIZE_T( sizeof(PendingTypeLoadTable::TableEntry*) )
38                                         + S_SIZE_T( size );
39     if( allocSize.IsOverflow() )
40     {
41         ThrowHR(E_INVALIDARG);
42     }
43     pMem = (BYTE *) pamTracker->Track(pHeap->AllocMem( allocSize ));
44
45     pThis = (PendingTypeLoadTable *) pMem;
46
47 #ifdef _DEBUG
48     pThis->m_dwDebugMemory = (DWORD)(size + dwNumBuckets*sizeof(PendingTypeLoadTable::TableEntry*));
49 #endif
50
51     pThis->m_dwNumBuckets = dwNumBuckets;
52     pThis->m_pBuckets = (PendingTypeLoadTable::TableEntry**) (pMem + size);
53
54     // Don't need to memset() since this was ClrVirtualAlloc()'d memory
55     // memset(pThis->m_pBuckets, 0, dwNumBuckets*sizeof(PendingTypeLoadTable::TableEntry*));
56
57     return pThis;
58 }
59
60
61
62 PendingTypeLoadTable::TableEntry *PendingTypeLoadTable::AllocNewEntry()
63 {
64     CONTRACTL
65     {
66         NOTHROW;
67         GC_NOTRIGGER;
68         MODE_ANY;
69         INJECT_FAULT( return NULL; );
70     }
71     CONTRACTL_END
72
73 #ifdef _DEBUG
74     m_dwDebugMemory += (DWORD) (sizeof(PendingTypeLoadTable::TableEntry));
75 #endif
76
77     return (PendingTypeLoadTable::TableEntry *) new (nothrow) BYTE[sizeof(PendingTypeLoadTable::TableEntry)];
78 }
79
80
81 void PendingTypeLoadTable::FreeEntry(PendingTypeLoadTable::TableEntry * pEntry)
82 {
83     CONTRACTL
84     {
85         NOTHROW;
86         GC_NOTRIGGER;
87         MODE_ANY;
88     }
89     CONTRACTL_END
90
91     // keep in sync with the allocator used in AllocNewEntry
92     delete[] ((BYTE*)pEntry);
93
94 #ifdef _DEBUG
95     m_dwDebugMemory -= (DWORD) (sizeof(PendingTypeLoadTable::TableEntry));
96 #endif
97 }
98
99
100 //
101 // Does not handle duplicates!
102 //
103 BOOL PendingTypeLoadTable::InsertValue(PendingTypeLoadEntry *pData)
104 {
105     CONTRACTL
106     {
107         NOTHROW;
108         GC_NOTRIGGER;
109         MODE_ANY;
110         INJECT_FAULT( return FALSE; );
111         PRECONDITION(CheckPointer(pData));
112         PRECONDITION(FindItem(&pData->GetTypeKey()) == NULL);
113     }
114     CONTRACTL_END
115
116     _ASSERTE(m_dwNumBuckets != 0);
117
118     DWORD           dwHash = pData->GetTypeKey().ComputeHash();
119     DWORD           dwBucket = dwHash % m_dwNumBuckets;
120     PendingTypeLoadTable::TableEntry * pNewEntry = AllocNewEntry();
121     if (pNewEntry == NULL)
122         return FALSE;
123
124     // Insert at head of bucket
125     pNewEntry->pNext        = m_pBuckets[dwBucket];
126     pNewEntry->pData        = pData;
127     pNewEntry->dwHashValue  = dwHash;
128
129     m_pBuckets[dwBucket] = pNewEntry;
130
131     return TRUE;
132 }
133
134
135 BOOL PendingTypeLoadTable::DeleteValue(TypeKey *pKey)
136 {
137     CONTRACTL
138     {
139         NOTHROW;
140         GC_NOTRIGGER;
141         MODE_ANY;
142         FORBID_FAULT;
143         PRECONDITION(CheckPointer(pKey));
144     }
145     CONTRACTL_END
146
147     _ASSERTE(m_dwNumBuckets != 0);
148
149     DWORD           dwHash = pKey->ComputeHash();
150     DWORD           dwBucket = dwHash % m_dwNumBuckets;
151     PendingTypeLoadTable::TableEntry * pSearch;
152     PendingTypeLoadTable::TableEntry **ppPrev = &m_pBuckets[dwBucket];
153
154     for (pSearch = m_pBuckets[dwBucket]; pSearch; pSearch = pSearch->pNext)
155     {
156         TypeKey entryTypeKey = pSearch->pData->GetTypeKey();
157         if (pSearch->dwHashValue == dwHash && TypeKey::Equals(pKey, &entryTypeKey))
158         {
159             *ppPrev = pSearch->pNext;
160             FreeEntry(pSearch);
161             return TRUE;
162         }
163
164         ppPrev = &pSearch->pNext;
165     }
166
167     return FALSE;
168 }
169
170
171 PendingTypeLoadTable::TableEntry *PendingTypeLoadTable::FindItem(TypeKey *pKey)
172 {
173     CONTRACTL
174     {
175         NOTHROW;
176         GC_NOTRIGGER;
177         MODE_ANY;
178         FORBID_FAULT;
179         PRECONDITION(CheckPointer(pKey));
180     }
181     CONTRACTL_END
182
183     _ASSERTE(m_dwNumBuckets != 0);
184
185
186     DWORD           dwHash = pKey->ComputeHash();
187     DWORD           dwBucket = dwHash % m_dwNumBuckets;
188     PendingTypeLoadTable::TableEntry * pSearch;
189
190     for (pSearch = m_pBuckets[dwBucket]; pSearch; pSearch = pSearch->pNext)
191     {
192         TypeKey entryTypeKey = pSearch->pData->GetTypeKey();
193         if (pSearch->dwHashValue == dwHash && TypeKey::Equals(pKey, &entryTypeKey))
194         {
195             return pSearch;
196         }
197     }
198
199     return NULL;
200 }
201
202
203 #ifdef _DEBUG
204 void PendingTypeLoadTable::Dump()
205 {
206     CONTRACTL
207     {
208         THROWS;
209         GC_TRIGGERS;
210         MODE_ANY;
211     }
212     CONTRACTL_END
213
214     LOG((LF_CLASSLOADER, LL_INFO10000, "PHASEDLOAD: table contains:\n"));
215     for (DWORD i = 0; i < m_dwNumBuckets; i++)
216     {
217         for (TableEntry *pSearch = m_pBuckets[i]; pSearch; pSearch = pSearch->pNext)
218         {
219             SString name;
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()]));            
224         }
225     }
226 }
227 #endif
228
229 PendingTypeLoadEntry* PendingTypeLoadTable::GetValue(TypeKey *pKey)
230 {
231     CONTRACTL
232     {
233         NOTHROW;
234         GC_NOTRIGGER;
235         MODE_ANY;
236         FORBID_FAULT;
237         PRECONDITION(CheckPointer(pKey));
238     }
239     CONTRACTL_END
240
241     PendingTypeLoadTable::TableEntry *pItem = FindItem(pKey);
242
243     if (pItem != NULL)
244     {
245         return pItem->pData;
246     }
247     else
248     {
249         return NULL;
250     }
251 }
252
253 #endif // #ifndef DACCESS_COMPILE
254