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
6#ifndef _LOADER_ALLOCATOR_I
7#define _LOADER_ALLOCATOR_I
8
9#include "assembly.hpp"
10
11#ifndef DACCESS_COMPILE
12inline LOADERALLOCATORREF LoaderAllocator::GetExposedObject()
13{
14 LIMITED_METHOD_CONTRACT;
15 OBJECTREF loaderAllocatorObject = (m_hLoaderAllocatorObjectHandle != NULL) ? ObjectFromHandle(m_hLoaderAllocatorObjectHandle) : NULL;
16 return (LOADERALLOCATORREF)loaderAllocatorObject;
17}
18#endif
19
20inline void GlobalLoaderAllocator::Init(BaseDomain *pDomain)
21{
22 LoaderAllocator::Init(pDomain, m_ExecutableHeapInstance);
23}
24
25inline void AssemblyLoaderAllocator::Init(AppDomain* pAppDomain)
26{
27 m_Id.Init();
28 LoaderAllocator::Init((BaseDomain *)pAppDomain);
29}
30
31inline BOOL LoaderAllocatorID::Equals(LoaderAllocatorID *pId)
32{
33 LIMITED_METHOD_CONTRACT;
34 if (GetType() != pId->GetType())
35 return false;
36
37 return GetValue() == pId->GetValue();
38}
39
40inline void LoaderAllocatorID::Init()
41{
42 LIMITED_METHOD_CONTRACT;
43 m_type = LAT_Assembly;
44};
45
46inline void LoaderAllocatorID::AddDomainAssembly(DomainAssembly* pAssembly)
47{
48 LIMITED_METHOD_CONTRACT;
49 _ASSERTE(m_type == LAT_Assembly);
50
51 // Link domain assembly together
52 if (m_pDomainAssembly != NULL)
53 {
54 pAssembly->SetNextDomainAssemblyInSameALC(m_pDomainAssembly);
55 }
56 m_pDomainAssembly = pAssembly;
57}
58
59inline VOID* LoaderAllocatorID::GetValue()
60{
61 LIMITED_METHOD_DAC_CONTRACT;
62 return m_pValue;
63}
64
65inline COUNT_T LoaderAllocatorID::Hash()
66{
67 LIMITED_METHOD_DAC_CONTRACT;
68 return (COUNT_T)(SIZE_T)GetValue();
69}
70
71inline LoaderAllocatorType LoaderAllocatorID::GetType()
72{
73 LIMITED_METHOD_DAC_CONTRACT;
74 return m_type;
75}
76
77inline DomainAssemblyIterator LoaderAllocatorID::GetDomainAssemblyIterator()
78{
79 LIMITED_METHOD_DAC_CONTRACT;
80 _ASSERTE(m_type == LAT_Assembly);
81 return DomainAssemblyIterator(m_pDomainAssembly);
82}
83
84inline LoaderAllocatorID* AssemblyLoaderAllocator::Id()
85{
86 LIMITED_METHOD_DAC_CONTRACT;
87 return &m_Id;
88}
89
90inline LoaderAllocatorID* GlobalLoaderAllocator::Id()
91{
92 LIMITED_METHOD_DAC_CONTRACT;
93 return &m_Id;
94}
95
96/* static */
97FORCEINLINE BOOL LoaderAllocator::GetHandleValueFast(LOADERHANDLE handle, OBJECTREF *pValue)
98{
99 LIMITED_METHOD_CONTRACT;
100
101 // If the slot value does have the low bit set, then it is a simple pointer to the value
102 // Otherwise, we will need a more complicated operation to get the value.
103 if ((((UINT_PTR)handle) & 1) != 0)
104 {
105 *pValue = *((OBJECTREF *)(((UINT_PTR)handle) - 1));
106 return TRUE;
107 }
108 else
109 {
110 return FALSE;
111 }
112}
113
114FORCEINLINE BOOL LoaderAllocator::GetHandleValueFastPhase2(LOADERHANDLE handle, OBJECTREF *pValue)
115{
116 SUPPORTS_DAC;
117 STATIC_CONTRACT_NOTHROW;
118 STATIC_CONTRACT_MODE_COOPERATIVE;
119 STATIC_CONTRACT_NOTHROW;
120 STATIC_CONTRACT_GC_NOTRIGGER;
121
122 if (handle == 0)
123 return FALSE;
124
125 /* This is lockless access to the handle table, be careful */
126 OBJECTREF loaderAllocatorAsObjectRef = ObjectFromHandle(m_hLoaderAllocatorObjectHandle);
127
128 // If the managed loader allocator has been collected, then the handles associated with it are dead as well.
129 if (loaderAllocatorAsObjectRef == NULL)
130 return FALSE;
131
132 LOADERALLOCATORREF loaderAllocator = dac_cast<LOADERALLOCATORREF>(loaderAllocatorAsObjectRef);
133 PTRARRAYREF handleTable = loaderAllocator->GetHandleTable();
134 UINT_PTR index = (((UINT_PTR)handle) >> 1) - 1;
135 *pValue = handleTable->GetAt(index);
136
137 return TRUE;
138}
139
140FORCEINLINE OBJECTREF LoaderAllocator::GetHandleValueFastCannotFailType2(LOADERHANDLE handle)
141{
142 SUPPORTS_DAC;
143 STATIC_CONTRACT_NOTHROW;
144 STATIC_CONTRACT_MODE_COOPERATIVE;
145 STATIC_CONTRACT_NOTHROW;
146 STATIC_CONTRACT_GC_NOTRIGGER;
147
148 /* This is lockless access to the handle table, be careful */
149 OBJECTREF loaderAllocatorAsObjectRef = ObjectFromHandle(m_hLoaderAllocatorObjectHandle);
150 LOADERALLOCATORREF loaderAllocator = dac_cast<LOADERALLOCATORREF>(loaderAllocatorAsObjectRef);
151 PTRARRAYREF handleTable = loaderAllocator->GetHandleTable();
152 UINT_PTR index = (((UINT_PTR)handle) >> 1) - 1;
153
154 return handleTable->GetAt(index);
155}
156
157inline bool SegmentedHandleIndexStack::Push(DWORD value)
158{
159 LIMITED_METHOD_CONTRACT;
160
161 if (m_TOSIndex == Segment::Size)
162 {
163 Segment* segment;
164
165 if (m_freeSegment == NULL)
166 {
167 segment = new (nothrow) Segment();
168 if (segment == NULL)
169 {
170 return false;
171 }
172 }
173 else
174 {
175 segment = m_freeSegment;
176 m_freeSegment = NULL;
177 }
178
179 segment->m_prev = m_TOSSegment;
180 m_TOSSegment = segment;
181
182 m_TOSIndex = 0;
183 }
184
185 m_TOSSegment->m_data[m_TOSIndex++] = value;
186 return true;
187}
188
189inline DWORD SegmentedHandleIndexStack::Pop()
190{
191 LIMITED_METHOD_CONTRACT;
192
193 _ASSERTE(!IsEmpty());
194
195 if (m_TOSIndex == 0)
196 {
197 Segment* prevSegment = m_TOSSegment->m_prev;
198 _ASSERTE(prevSegment != NULL);
199
200 delete m_freeSegment;
201 m_freeSegment = m_TOSSegment;
202
203 m_TOSSegment = prevSegment;
204 m_TOSIndex = Segment::Size;
205 }
206
207 return m_TOSSegment->m_data[--m_TOSIndex];
208}
209
210inline bool SegmentedHandleIndexStack::IsEmpty()
211{
212 LIMITED_METHOD_CONTRACT;
213
214 return (m_TOSSegment == NULL) || ((m_TOSIndex == 0) && (m_TOSSegment->m_prev == NULL));
215}
216
217#endif // _LOADER_ALLOCATOR_I
218
219