| 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 | |