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 | |
7 | #ifndef _DATAIMAGE_H_ |
8 | #define _DATAIMAGE_H_ |
9 | |
10 | #if defined(FEATURE_PREJIT) && !defined(DACCESS_COMPILE) |
11 | |
12 | // All we really need is to pre-declare the PrecodeType enum, but g++ doesn't |
13 | // support enum pre-declaration, so we need to include the declaration itself. |
14 | /*#include "cgensys.h" // needed to include precode.h*/ |
15 | #include "precode.h" |
16 | |
17 | typedef BYTE ZapRelocationType; // IMAGE_REL_XXX enum |
18 | |
19 | // IMAGE_REL_BASED_PTR is architecture specific reloc of virtual address |
20 | #ifdef _TARGET_64BIT_ |
21 | #define IMAGE_REL_BASED_PTR IMAGE_REL_BASED_DIR64 |
22 | #else // !_TARGET_64BIT_ |
23 | #define IMAGE_REL_BASED_PTR IMAGE_REL_BASED_HIGHLOW |
24 | #endif // !_TARGET_64BIT_ |
25 | |
26 | // Special NGEN-specific relocation type for relative pointer (used to make NGen relocation section smaller) |
27 | #define IMAGE_REL_BASED_RELPTR 0x7D |
28 | |
29 | class CEEPreloader; |
30 | |
31 | class ZapImage; |
32 | class TypeHandleList; |
33 | |
34 | class ZapNode; |
35 | class ZapStoredStructure; |
36 | |
37 | class ZapHeap; |
38 | void *operator new(size_t size, ZapHeap * pZapHeap); |
39 | void *operator new[](size_t size, ZapHeap * pZapHeap); |
40 | |
41 | class InternedStructureTraits; |
42 | typedef SHash<InternedStructureTraits> InternedStructureHashTable; |
43 | |
44 | struct LookupMapBase; |
45 | class InlineTrackingMap; |
46 | |
47 | class DataImage |
48 | { |
49 | public: |
50 | // |
51 | // As items are recorded for saving we note some information about the item |
52 | // to help guide later heuristics. |
53 | // |
54 | enum ItemKind |
55 | { |
56 | #define DEFINE_ITEM_KIND(id) id, |
57 | #include "dataimagesection.h" |
58 | |
59 | ITEM_COUNT, |
60 | }; |
61 | |
62 | Module *m_module; |
63 | CEEPreloader *m_preloader; |
64 | ZapImage * m_pZapImage; |
65 | |
66 | struct StructureEntry |
67 | { |
68 | const void * ptr; |
69 | ZapNode * pNode; |
70 | SSIZE_T offset; |
71 | }; |
72 | |
73 | class StructureTraits : public NoRemoveSHashTraits< DefaultSHashTraits<StructureEntry> > |
74 | { |
75 | public: |
76 | typedef const void * key_t; |
77 | |
78 | static key_t GetKey(element_t e) |
79 | { |
80 | LIMITED_METHOD_CONTRACT; |
81 | return e.ptr; |
82 | } |
83 | static BOOL Equals(key_t k1, key_t k2) |
84 | { |
85 | LIMITED_METHOD_CONTRACT; |
86 | return (k1 == k2); |
87 | } |
88 | static count_t Hash(key_t k) |
89 | { |
90 | LIMITED_METHOD_CONTRACT; |
91 | return (count_t)(size_t)k; |
92 | } |
93 | |
94 | static const element_t Null() { LIMITED_METHOD_CONTRACT; StructureEntry e; e.ptr = NULL; return e; } |
95 | static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e.ptr == NULL; } |
96 | }; |
97 | typedef SHash<StructureTraits> StructureHashTable; |
98 | |
99 | StructureHashTable m_structures; |
100 | const StructureEntry * m_pLastLookup; // Cached result of last lookup |
101 | |
102 | #define MAINTAIN_SAVE_ORDER (0xFFFFFFFF) |
103 | |
104 | struct SavedNodeEntry |
105 | { |
106 | ZapNode * pNode; |
107 | DWORD dwAssociatedOrder; |
108 | }; |
109 | |
110 | // These are added in save order, however after PlaceRemainingStructures they may have been |
111 | // rearranged based on the class layout order stored in the dwAssociatedOrder field. |
112 | SArray<SavedNodeEntry> m_structuresInOrder; |
113 | |
114 | void AddStructureInOrder(ZapNode *pNode, BOOL fMaintainSaveOrder = FALSE); |
115 | |
116 | struct FixupEntry |
117 | { |
118 | ZapRelocationType m_type; |
119 | DWORD m_offset; |
120 | #ifdef _DEBUG |
121 | DWORD m_ordinal; |
122 | #endif // _DEBUG |
123 | |
124 | ZapStoredStructure * m_pLocation; |
125 | ZapNode * m_pTargetNode; |
126 | }; |
127 | |
128 | SArray<FixupEntry> m_Fixups; |
129 | COUNT_T m_iCurrentFixup; |
130 | |
131 | void AppendFixup(FixupEntry entry) |
132 | { |
133 | #ifdef _DEBUG |
134 | static DWORD s_ordinal = 1; |
135 | entry.m_ordinal = s_ordinal++; |
136 | #endif // _DEBUG |
137 | m_Fixups.Append(entry); |
138 | } |
139 | |
140 | static int __cdecl fixupEntryCmp(const void* a_, const void* b_); |
141 | |
142 | void FixupSectionRange(SIZE_T offset, ZapNode * pNode); |
143 | void FixupSectionPtr(SIZE_T offset, ZapNode * pNode); |
144 | void FixupJumpStubPtr(SIZE_T offset, CorInfoHelpFunc ftnNum); |
145 | |
146 | void FixupModuleRVAs(); |
147 | |
148 | InternedStructureHashTable * m_pInternedStructures; |
149 | SetSHash<ZapNode *> m_reusedStructures; |
150 | |
151 | struct RvaInfoStructure |
152 | { |
153 | FieldDesc * pFD; |
154 | DWORD rva; |
155 | UINT size; |
156 | UINT align; |
157 | }; |
158 | |
159 | SArray<RvaInfoStructure> m_rvaInfoVector; |
160 | |
161 | static int __cdecl rvaInfoVectorEntryCmp(const void* a_, const void* b_); |
162 | |
163 | MapSHash<PVOID,PVOID> m_surrogates; |
164 | |
165 | // Often set while a class is being saved in order to associate |
166 | // stored structures with the class, and therefore its layout order. |
167 | // Note that it is a best guess and not always set. |
168 | MethodTable * m_pCurrentAssociatedMethodTable; |
169 | |
170 | struct MethodProfilingData |
171 | { |
172 | MethodDesc *pMD; |
173 | DWORD flags; |
174 | }; |
175 | |
176 | class MethodProfilingDataTraits : public NoRemoveSHashTraits< DefaultSHashTraits<MethodProfilingData> > |
177 | { |
178 | public: |
179 | typedef const MethodDesc * key_t; |
180 | |
181 | static key_t GetKey(element_t e) |
182 | { |
183 | LIMITED_METHOD_CONTRACT; |
184 | return e.pMD; |
185 | } |
186 | static BOOL Equals(key_t k1, key_t k2) |
187 | { |
188 | LIMITED_METHOD_CONTRACT; |
189 | return (k1 == k2); |
190 | } |
191 | static count_t Hash(key_t k) |
192 | { |
193 | LIMITED_METHOD_CONTRACT; |
194 | return (count_t)(size_t)k; |
195 | } |
196 | |
197 | static const element_t Null() { LIMITED_METHOD_CONTRACT; MethodProfilingData e; e.pMD = NULL; e.flags = 0; return e; } |
198 | static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e.pMD == NULL; } |
199 | }; |
200 | typedef SHash<MethodProfilingDataTraits> MethodProfilingDataHashTable; |
201 | |
202 | MethodProfilingDataHashTable m_methodProfilingData; |
203 | |
204 | // This is a hashmap from inlinee method to an array of inliner methods |
205 | // So it can answer question: "where did this method get inlined ?" |
206 | InlineTrackingMap *m_inlineTrackingMap; |
207 | |
208 | public: |
209 | DataImage(Module *module, CEEPreloader *preloader); |
210 | ~DataImage(); |
211 | |
212 | void Preallocate(); |
213 | |
214 | void PreSave(); |
215 | void PostSave(); |
216 | |
217 | Module *GetModule() { LIMITED_METHOD_CONTRACT; return m_module; } |
218 | |
219 | DWORD GetMethodProfilingFlags(MethodDesc * pMD); |
220 | void SetMethodProfilingFlags(MethodDesc * pMD, DWORD flags); |
221 | |
222 | CEEPreloader *GetPreloader() { LIMITED_METHOD_CONTRACT; return m_preloader; } |
223 | |
224 | ZapHeap * GetHeap(); |
225 | |
226 | // |
227 | // Data is stored in the image store in three phases. |
228 | // |
229 | |
230 | // |
231 | // In the first phase, all objects are assigned locations in the |
232 | // data store. This is done by calling StoreStructure on all |
233 | // structures which are being stored into the image. |
234 | // |
235 | // This would typically done by methods on the objects themselves, |
236 | // each of which stores itself and any objects it references. |
237 | // Reference loops must be explicitly tested for using IsStored. |
238 | // (Each structure can be stored only once.) |
239 | // |
240 | // Note that StoreStructure makes no guarantees about layout order. |
241 | // If you want structures of a particular kind to be laid out in |
242 | // the order they are saved, use StoreStructureInOrder. |
243 | // |
244 | |
245 | inline ZapStoredStructure * StoreStructure(const void *data, SIZE_T size, |
246 | ItemKind kind, |
247 | int align = sizeof(TADDR)) |
248 | { |
249 | return StoreStructureHelper(data, size, kind, align, FALSE); |
250 | } |
251 | |
252 | inline ZapStoredStructure * StoreStructureInOrder(const void *data, SIZE_T size, |
253 | ItemKind kind, |
254 | int align = sizeof(TADDR)) |
255 | { |
256 | return StoreStructureHelper(data, size, kind, align, TRUE); |
257 | } |
258 | |
259 | ZapStoredStructure * StoreStructureHelper(const void *data, SIZE_T size, |
260 | ItemKind kind, |
261 | int align, |
262 | BOOL fMaintainSaveOrder); |
263 | |
264 | // Often set while a class is being saved in order to associate |
265 | // stored structures with the class, and therefore its layout order. |
266 | // Note that it is a best guess and not always set. |
267 | inline void BeginAssociatingStoredObjectsWithMethodTable(MethodTable *pMT) |
268 | { |
269 | m_pCurrentAssociatedMethodTable = pMT; |
270 | } |
271 | |
272 | inline void EndAssociatingStoredObjectsWithMethodTable() |
273 | { |
274 | m_pCurrentAssociatedMethodTable = NULL; |
275 | } |
276 | |
277 | // Bind pointer to the relative offset in ZapNode |
278 | void BindPointer(const void *p, ZapNode * pNode, SSIZE_T offset); |
279 | |
280 | void BindPointer(const void *p, ZapStoredStructure * pNode, SSIZE_T offset) |
281 | { |
282 | BindPointer(p, (ZapNode *)pNode, offset); |
283 | } |
284 | |
285 | void CopyData(ZapStoredStructure * pNode, const void * p, ULONG size); |
286 | void CopyDataToOffset(ZapStoredStructure * pNode, ULONG offset, const void * p, ULONG size); |
287 | |
288 | // |
289 | // In the second phase, data is arranged in the image by successive calls |
290 | // to PlaceMappedRange. Items are arranged using pointers to data structures in the |
291 | // original heap, or by giving a StoredStructure along with the original |
292 | // mapping. |
293 | // |
294 | |
295 | // Concrete mapped ranges are the ones that actually correspond to allocations |
296 | // of new space within the image. They should be placed first. We do not |
297 | // necessarily populate the space in the image (i.e. copy the data to the image) |
298 | // from the concrete range: for example the space associated with a |
299 | // combo structure gets filled by copying the data from the individual items |
300 | // that make up the parts of the combo structure. |
301 | // |
302 | // These can tolerate placing the same item multiple times |
303 | // PlaceInternedStructureForAddress allows a different section to be used depending on |
304 | // whether an interned structure actually had duplicates in this image. |
305 | // |
306 | void PlaceStructureForAddress(const void * data, CorCompileSection section); |
307 | void PlaceInternedStructureForAddress(const void * data, CorCompileSection sectionIfReused, CorCompileSection sectionIfSingleton); |
308 | |
309 | void FixupPointerField(PVOID p, SSIZE_T offset); |
310 | void FixupRelativePointerField(PVOID p, SSIZE_T offset); |
311 | |
312 | template<typename T, typename PT> |
313 | void FixupPlainOrRelativePointerField(const T *base, const RelativePointer<PT> T::* pPointerFieldMember) |
314 | { |
315 | STANDARD_VM_CONTRACT; |
316 | SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; |
317 | FixupRelativePointerField((PVOID)base, offset); |
318 | } |
319 | |
320 | template<typename T, typename C, typename PT> |
321 | void FixupPlainOrRelativePointerField(const T *base, const C T::* pFirstPointerFieldMember, const RelativePointer<PT> C::* pSecondPointerFieldMember) |
322 | { |
323 | STANDARD_VM_CONTRACT; |
324 | const RelativePointer<PT> *ptr = &(base->*pFirstPointerFieldMember.*pSecondPointerFieldMember); |
325 | SSIZE_T offset = (SSIZE_T) ptr - (SSIZE_T) base; |
326 | FixupRelativePointerField((PVOID)base, offset); |
327 | } |
328 | |
329 | template<typename T, typename PT> |
330 | void FixupPlainOrRelativePointerField(const T *base, const PlainPointer<PT> T::* pPointerFieldMember) |
331 | { |
332 | STANDARD_VM_CONTRACT; |
333 | SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; |
334 | FixupPointerField((PVOID)base, offset); |
335 | } |
336 | |
337 | template<typename T, typename C, typename PT> |
338 | void FixupPlainOrRelativePointerField(const T *base, const C T::* pFirstPointerFieldMember, const PlainPointer<PT> C::* pSecondPointerFieldMember) |
339 | { |
340 | STANDARD_VM_CONTRACT; |
341 | const PlainPointer<PT> *ptr = &(base->*pFirstPointerFieldMember.*pSecondPointerFieldMember); |
342 | SSIZE_T offset = (SSIZE_T) ptr - (SSIZE_T) base; |
343 | FixupPointerField((PVOID)base, offset); |
344 | } |
345 | |
346 | void FixupField(PVOID p, SSIZE_T offset, PVOID pTarget, SSIZE_T targetOffset = 0, ZapRelocationType type = IMAGE_REL_BASED_PTR); |
347 | |
348 | template<typename T, typename PT> |
349 | void FixupPlainOrRelativeField(const T *base, const RelativePointer<PT> T::* pPointerFieldMember, PVOID pTarget, SSIZE_T targetOffset = 0) |
350 | { |
351 | STANDARD_VM_CONTRACT; |
352 | SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; |
353 | FixupField((PVOID)base, offset, pTarget, targetOffset, IMAGE_REL_BASED_RELPTR); |
354 | } |
355 | |
356 | template<typename T, typename PT> |
357 | void FixupPlainOrRelativeField(const T *base, const PlainPointer<PT> T::* pPointerFieldMember, PVOID pTarget, SSIZE_T targetOffset = 0) |
358 | { |
359 | STANDARD_VM_CONTRACT; |
360 | SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; |
361 | FixupField((PVOID)base, offset, pTarget, targetOffset, IMAGE_REL_BASED_PTR); |
362 | } |
363 | |
364 | void FixupFieldToNode(PVOID p, SSIZE_T offset, ZapNode * pTarget, SSIZE_T targetOffset = 0, ZapRelocationType type = IMAGE_REL_BASED_PTR); |
365 | |
366 | void FixupFieldToNode(PVOID p, SSIZE_T offset, ZapStoredStructure * pTarget, SSIZE_T targetOffset = 0, ZapRelocationType type = IMAGE_REL_BASED_PTR) |
367 | { |
368 | return FixupFieldToNode(p, offset, (ZapNode *)pTarget, targetOffset, type); |
369 | } |
370 | |
371 | template<typename T, typename PT> |
372 | void FixupPlainOrRelativeFieldToNode(const T *base, const RelativePointer<PT> T::* pPointerFieldMember, ZapNode * pTarget, SSIZE_T targetOffset = 0) |
373 | { |
374 | STANDARD_VM_CONTRACT; |
375 | SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; |
376 | FixupFieldToNode((PVOID)base, offset, pTarget, targetOffset, IMAGE_REL_BASED_RELPTR); |
377 | } |
378 | |
379 | template<typename T, typename PT> |
380 | void FixupPlainOrRelativeFieldToNode(const T *base, const RelativePointer<PT> T::* pPointerFieldMember, ZapStoredStructure * pTarget, SSIZE_T targetOffset = 0) |
381 | { |
382 | return FixupPlainOrRelativeFieldToNode(base, pPointerFieldMember, (ZapNode *)pTarget, targetOffset); |
383 | } |
384 | |
385 | template<typename T, typename PT> |
386 | void FixupPlainOrRelativeFieldToNode(const T *base, const PlainPointer<PT> T::* pPointerFieldMember, ZapNode * pTarget, SSIZE_T targetOffset = 0) |
387 | { |
388 | STANDARD_VM_CONTRACT; |
389 | SSIZE_T offset = (SSIZE_T) &(base->*pPointerFieldMember) - (SSIZE_T) base; |
390 | FixupFieldToNode((PVOID)base, offset, pTarget, targetOffset, IMAGE_REL_BASED_PTR); |
391 | } |
392 | |
393 | template<typename T, typename PT> |
394 | void FixupPlainOrRelativeFieldToNode(const T *base, const PlainPointer<PT> T::* pPointerFieldMember, ZapStoredStructure * pTarget, SSIZE_T targetOffset = 0) |
395 | { |
396 | return FixupPlainOrRelativeFieldToNode(base, pPointerFieldMember, (ZapNode *)pTarget, targetOffset); |
397 | } |
398 | |
399 | BOOL IsStored(const void *data) |
400 | { WRAPPER_NO_CONTRACT; return m_structures.LookupPtr(data) != NULL; } |
401 | |
402 | DWORD GetRVA(const void *data); |
403 | |
404 | void ZeroField(PVOID p, SSIZE_T offset, SIZE_T size); |
405 | void *GetImagePointer(ZapStoredStructure * pNode); |
406 | void *GetImagePointer(PVOID p, SSIZE_T offset = 0); |
407 | ZapNode * GetNodeForStructure(PVOID p, SSIZE_T * pOffset); |
408 | |
409 | void ZeroPointerField(PVOID p, SSIZE_T offset) |
410 | { WRAPPER_NO_CONTRACT; ZeroField(p, offset, sizeof(void*)); } |
411 | |
412 | |
413 | ZapStoredStructure * StoreInternedStructure(const void *data, ULONG size, |
414 | ItemKind kind, |
415 | int align = sizeof(TADDR)); |
416 | |
417 | void NoteReusedStructure(const void *data); |
418 | |
419 | void StoreRvaInfo(FieldDesc * pFD, |
420 | DWORD rva, |
421 | UINT size, |
422 | UINT align); |
423 | |
424 | void SaveRvaStructure(); |
425 | void FixupRvaStructure(); |
426 | |
427 | // Surrogates are used to reorganize the data before they are saved. RegisterSurrogate and LookupSurrogate |
428 | // maintains mapping from the original data to the reorganized data. |
429 | void RegisterSurrogate(PVOID ptr, PVOID surrogate); |
430 | PVOID LookupSurrogate(PVOID ptr); |
431 | |
432 | void PlaceRemainingStructures(); |
433 | |
434 | void FixupRVAs(); |
435 | |
436 | void SetRVAsForFields(IMetaDataEmit * pEmit); |
437 | |
438 | // Called when data contains a function address. The data store |
439 | // can return a fixed compiled code address if it is compiling |
440 | // code for the module. |
441 | ZapNode * GetCodeAddress(MethodDesc * method); |
442 | |
443 | // Returns TRUE if the method can be called directly without going through prestub |
444 | BOOL CanDirectCall(MethodDesc * method, CORINFO_ACCESS_FLAGS accessFlags = CORINFO_ACCESS_ANY); |
445 | |
446 | // Returns the method fixup info if it has one, NULL if method has no fixup info |
447 | ZapNode * GetFixupList(MethodDesc * method); |
448 | |
449 | ZapNode * GetHelperThunk(CorInfoHelpFunc ftnNum); |
450 | |
451 | // pUniqueId is used to allocate unique cells for cases where we cannot use the shared cell. |
452 | ZapNode * GetTypeHandleImport(TypeHandle th, PVOID pUniqueId = NULL); |
453 | ZapNode * GetMethodHandleImport(MethodDesc * pMD); |
454 | ZapNode * GetFieldHandleImport(FieldDesc * pFD); |
455 | ZapNode * GetModuleHandleImport(Module * pModule); |
456 | DWORD GetModuleImportIndex(Module * pModule); |
457 | |
458 | ZapNode * GetExistingTypeHandleImport(TypeHandle th); |
459 | ZapNode * GetExistingMethodHandleImport(MethodDesc * pMD); |
460 | ZapNode * GetExistingFieldHandleImport(FieldDesc * pFD); |
461 | |
462 | ZapNode * GetVirtualImportThunk(MethodTable * pMT, MethodDesc * pMD, int slotNumber); |
463 | |
464 | ZapNode * GetGenericSignature(PVOID signature, BOOL fMethod); |
465 | |
466 | void SavePrecode(PVOID ptr, MethodDesc * pMD, PrecodeType t, ItemKind kind, BOOL fIsPrebound = FALSE); |
467 | |
468 | void StoreCompressedLayoutMap(LookupMapBase *pMap, ItemKind kind); |
469 | |
470 | // "Fixup" here means "save the pointer either as a poiter or indirection" |
471 | void FixupModulePointer(Module * pModule, PVOID p, SSIZE_T offset, ZapRelocationType type); |
472 | void FixupMethodTablePointer(MethodTable * pMT, PVOID p, SSIZE_T offset, ZapRelocationType type); |
473 | void FixupTypeHandlePointer(TypeHandle th, PVOID p, SSIZE_T offset, ZapRelocationType type); |
474 | void FixupMethodDescPointer(MethodDesc * pMD, PVOID p, SSIZE_T offset, ZapRelocationType type); |
475 | void FixupFieldDescPointer(FieldDesc * pFD, PVOID p, SSIZE_T offset, ZapRelocationType type); |
476 | |
477 | void FixupModulePointer(PVOID p, FixupPointer<PTR_Module> * ppModule); |
478 | void FixupMethodTablePointer(PVOID p, FixupPointer<PTR_MethodTable> * ppMT); |
479 | void FixupTypeHandlePointer(PVOID p, FixupPointer<TypeHandle> * pth); |
480 | void FixupMethodDescPointer(PVOID p, FixupPointer<PTR_MethodDesc> * ppMD); |
481 | void FixupFieldDescPointer(PVOID p, FixupPointer<PTR_FieldDesc> * ppFD); |
482 | |
483 | void FixupModulePointer(PVOID p, RelativeFixupPointer<PTR_Module> * ppModule); |
484 | void FixupMethodTablePointer(PVOID p, RelativeFixupPointer<PTR_MethodTable> * ppMT); |
485 | void FixupTypeHandlePointer(PVOID p, RelativeFixupPointer<TypeHandle> * pth); |
486 | void FixupMethodDescPointer(PVOID p, RelativeFixupPointer<PTR_MethodDesc> * ppMD); |
487 | void FixupFieldDescPointer(PVOID p, RelativeFixupPointer<PTR_FieldDesc> * ppFD); |
488 | |
489 | // "HardBind" here means "save a reference using a (relocatable) pointer, |
490 | // where the object we're referring to lives either in an external hard-bound DLL |
491 | // or in the image currently being saved" |
492 | // |
493 | BOOL CanHardBindToZapModule(Module *targetModule); |
494 | |
495 | void ReportInlining(CORINFO_METHOD_HANDLE inliner, CORINFO_METHOD_HANDLE inlinee); |
496 | InlineTrackingMap *GetInlineTrackingMap(); |
497 | |
498 | private: |
499 | BOOL CanEagerBindTo(Module *targetModule, Module *pPreferredZapModule, void *address); |
500 | |
501 | public: |
502 | // "EagerBind" here means "save a reference using pointer in the image currently being saved |
503 | // or indirection cell refering to to external DLL |
504 | BOOL CanEagerBindToTypeHandle(TypeHandle th, BOOL fRequirePrerestore = FALSE, TypeHandleList *pVisited = NULL); |
505 | BOOL CanEagerBindToMethodTable(MethodTable *pMT, BOOL fRequirePrerestore = FALSE, TypeHandleList *pVisited = NULL); |
506 | BOOL CanEagerBindToMethodDesc(MethodDesc *pMD, BOOL fRequirePrerestore = FALSE, TypeHandleList *pVisited = NULL); |
507 | BOOL CanEagerBindToFieldDesc(FieldDesc *pFD, BOOL fRequirePrerestore = FALSE, TypeHandleList *pVisited = NULL); |
508 | BOOL CanEagerBindToModule(Module *pModule); |
509 | |
510 | // These also check that the target object doesn't need a restore action |
511 | // upon reload. |
512 | BOOL CanPrerestoreEagerBindToTypeHandle(TypeHandle th, TypeHandleList *pVisited); |
513 | BOOL CanPrerestoreEagerBindToMethodTable(MethodTable *pMT, TypeHandleList *pVisited); |
514 | BOOL CanPrerestoreEagerBindToMethodDesc(MethodDesc *pMD, TypeHandleList *pVisited); |
515 | |
516 | void HardBindTypeHandlePointer(PVOID p, SSIZE_T offset); |
517 | |
518 | // This is obsolete in-place fixup that we should get rid of. For now, it is used for: |
519 | // - FnPtrTypeDescs. These should not be stored in NGen images at all. |
520 | // - stubs-as-il signatures. These should use tokens when stored in NGen image. |
521 | void FixupTypeHandlePointerInPlace(PVOID p, SSIZE_T offset, BOOL fForceFixup = FALSE); |
522 | |
523 | void BeginRegion(CorInfoRegionKind regionKind); |
524 | void EndRegion(CorInfoRegionKind regionKind); |
525 | }; |
526 | |
527 | #endif // FEATURE_PREJIT && !DACCESS_COMPILE |
528 | |
529 | #endif // _DATAIMAGE_H_ |
530 | |