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 |
12 | inline 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 | |
20 | inline void GlobalLoaderAllocator::Init(BaseDomain *pDomain) |
21 | { |
22 | LoaderAllocator::Init(pDomain, m_ExecutableHeapInstance); |
23 | } |
24 | |
25 | inline void AssemblyLoaderAllocator::Init(AppDomain* pAppDomain) |
26 | { |
27 | m_Id.Init(); |
28 | LoaderAllocator::Init((BaseDomain *)pAppDomain); |
29 | } |
30 | |
31 | inline 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 | |
40 | inline void LoaderAllocatorID::Init() |
41 | { |
42 | LIMITED_METHOD_CONTRACT; |
43 | m_type = LAT_Assembly; |
44 | }; |
45 | |
46 | inline 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 | |
59 | inline VOID* LoaderAllocatorID::GetValue() |
60 | { |
61 | LIMITED_METHOD_DAC_CONTRACT; |
62 | return m_pValue; |
63 | } |
64 | |
65 | inline COUNT_T LoaderAllocatorID::Hash() |
66 | { |
67 | LIMITED_METHOD_DAC_CONTRACT; |
68 | return (COUNT_T)(SIZE_T)GetValue(); |
69 | } |
70 | |
71 | inline LoaderAllocatorType LoaderAllocatorID::GetType() |
72 | { |
73 | LIMITED_METHOD_DAC_CONTRACT; |
74 | return m_type; |
75 | } |
76 | |
77 | inline DomainAssemblyIterator LoaderAllocatorID::GetDomainAssemblyIterator() |
78 | { |
79 | LIMITED_METHOD_DAC_CONTRACT; |
80 | _ASSERTE(m_type == LAT_Assembly); |
81 | return DomainAssemblyIterator(m_pDomainAssembly); |
82 | } |
83 | |
84 | inline LoaderAllocatorID* AssemblyLoaderAllocator::Id() |
85 | { |
86 | LIMITED_METHOD_DAC_CONTRACT; |
87 | return &m_Id; |
88 | } |
89 | |
90 | inline LoaderAllocatorID* GlobalLoaderAllocator::Id() |
91 | { |
92 | LIMITED_METHOD_DAC_CONTRACT; |
93 | return &m_Id; |
94 | } |
95 | |
96 | /* static */ |
97 | FORCEINLINE 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 | |
114 | FORCEINLINE 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 | |
140 | FORCEINLINE 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 | |
157 | inline 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 | |
189 | inline 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 | |
210 | inline 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 |