c0e737a1bbac35b7be635e4f40335ab21f1b2be9
[platform/upstream/coreclr.git] / src / vm / dataimage.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
6
7 #include "common.h"
8
9 #ifdef FEATURE_PREJIT
10
11 #include "dataimage.h"
12 #include "compile.h"
13
14 #include "field.h"
15
16 //
17 // Include Zapper infrastructure here
18 //
19 // dataimage.cpp is the only place where Zapper infrasture should be used directly in the VM.
20 // The rest of the VM should never use Zapper infrastructure directly for good layering.
21 // The long term goal is to move all NGen specific parts like Save and Fixup methods out of the VM,
22 // and remove the dataimage.cpp completely.
23 //
24 #include "zapper.h"
25 #include "../zap/zapwriter.h"
26 #include "../zap/zapimage.h"
27 #include "../zap/zapimport.h"
28 #include "inlinetracking.h"
29
30 #define NodeTypeForItemKind(kind) ((ZapNodeType)(ZapNodeType_StoredStructure + kind))
31
32 class ZapStoredStructure : public ZapNode
33 {
34     DWORD  m_dwSize;
35     BYTE    m_kind;
36     BYTE    m_align;
37
38 public:
39     ZapStoredStructure(DWORD dwSize, BYTE kind, BYTE align)
40         : m_dwSize(dwSize), m_kind(kind), m_align(align)
41     {
42     }
43
44     void * GetData()
45     {
46         return this + 1;
47     }
48
49     DataImage::ItemKind GetKind()
50     {
51         return (DataImage::ItemKind)m_kind;
52     }
53
54     virtual DWORD GetSize()
55     {
56         return m_dwSize;
57     }
58
59     virtual UINT GetAlignment()
60     {
61         return m_align;
62     }
63
64     virtual ZapNodeType GetType()
65     {
66         return NodeTypeForItemKind(m_kind);
67     }
68
69     virtual void Save(ZapWriter * pZapWriter);
70 };
71
72 inline ZapStoredStructure * AsStoredStructure(ZapNode * pNode)
73 {
74     // Verify that it is one of the StoredStructure subtypes
75     _ASSERTE(pNode->GetType() >= ZapNodeType_StoredStructure);
76     return (ZapStoredStructure *)pNode;
77 }
78
79 struct InternedStructureKey
80 {
81     InternedStructureKey(const void * data, DWORD dwSize, DataImage::ItemKind kind)
82         : m_data(data), m_dwSize(dwSize), m_kind(kind)
83     {
84     }
85
86     const void *m_data;
87     DWORD       m_dwSize;
88     DataImage::ItemKind    m_kind;
89 };
90
91 class InternedStructureTraits : public NoRemoveSHashTraits< DefaultSHashTraits<ZapStoredStructure *> >
92 {
93 public:
94     typedef InternedStructureKey key_t;
95
96     static key_t GetKey(element_t e) 
97     { 
98         LIMITED_METHOD_CONTRACT;
99         return InternedStructureKey(e->GetData(), e->GetSize(), e->GetKind());
100     }
101     static BOOL Equals(key_t k1, key_t k2) 
102     { 
103         LIMITED_METHOD_CONTRACT;
104         return (k1.m_dwSize == k2.m_dwSize) &&
105                (k1.m_kind == k2.m_kind) &&
106                memcmp(k1.m_data, k2.m_data, k1.m_dwSize) == 0;
107     }
108     static count_t Hash(key_t k) 
109     {
110         LIMITED_METHOD_CONTRACT;
111         return (count_t)k.m_dwSize ^ (count_t)k.m_kind ^ HashBytes((BYTE *)k.m_data, k.m_dwSize);
112     }
113
114     static const element_t Null() { LIMITED_METHOD_CONTRACT; return NULL; }
115     static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e == NULL; }
116 };
117
118 DataImage::DataImage(Module *module, CEEPreloader *preloader)
119     : m_module(module),
120       m_preloader(preloader), 
121       m_iCurrentFixup(0),       // Dev11 bug 181494 instrumentation
122       m_pInternedStructures(NULL), 
123       m_pCurrentAssociatedMethodTable(NULL)
124 {
125     m_pZapImage = m_preloader->GetDataStore()->GetZapImage();
126     m_pZapImage->m_pDataImage = this;
127
128     m_pInternedStructures = new InternedStructureHashTable();
129     m_inlineTrackingMap = new InlineTrackingMap();
130 }
131
132 DataImage::~DataImage()
133 {
134     delete m_pInternedStructures;
135     delete m_inlineTrackingMap;
136 }
137
138 void DataImage::PreSave()
139 {
140 #ifndef ZAP_HASHTABLE_TUNING
141     Preallocate();
142 #endif
143 }
144
145 void DataImage::PostSave()
146 {
147 #ifdef ZAP_HASHTABLE_TUNING
148     // If ZAP_HASHTABLE_TUNING is defined, preallocate is overloaded to print the tunning constants
149     Preallocate();
150 #endif
151 }
152
153 DWORD DataImage::GetMethodProfilingFlags(MethodDesc * pMD)
154 {
155     STANDARD_VM_CONTRACT;
156
157     // We are not differentiating unboxing stubs vs. normal method descs in IBC data yet
158     if (pMD->IsUnboxingStub())
159         pMD = pMD->GetWrappedMethodDesc();
160
161     const MethodProfilingData * pData = m_methodProfilingData.LookupPtr(pMD);
162     return (pData != NULL) ? pData->flags : 0;
163 }
164
165 void DataImage::SetMethodProfilingFlags(MethodDesc * pMD, DWORD flags)
166 {
167     STANDARD_VM_CONTRACT;
168
169     const MethodProfilingData * pData = m_methodProfilingData.LookupPtr(pMD);
170     if (pData != NULL)
171     {
172         const_cast<MethodProfilingData *>(pData)->flags |= flags;
173         return;
174     }
175
176     MethodProfilingData data;
177     data.pMD = pMD;
178     data.flags = flags;
179     m_methodProfilingData.Add(data);
180 }
181
182 void DataImage::Preallocate()
183 {
184     STANDARD_VM_CONTRACT;
185
186     // TODO: Move to ZapImage
187
188     PEDecoder pe((void *)m_module->GetFile()->GetManagedFileContents());
189
190     COUNT_T cbILImage = pe.GetSize();
191
192     // Curb the estimate to handle corner cases gracefuly
193     cbILImage = min(cbILImage, 50000000);
194
195     PREALLOCATE_HASHTABLE(DataImage::m_structures, 0.019, cbILImage);
196     PREALLOCATE_ARRAY(DataImage::m_structuresInOrder, 0.0088, cbILImage);
197     PREALLOCATE_ARRAY(DataImage::m_Fixups, 0.046, cbILImage);
198     PREALLOCATE_HASHTABLE(DataImage::m_surrogates, 0.0025, cbILImage);
199     PREALLOCATE_HASHTABLE((*DataImage::m_pInternedStructures), 0.0007, cbILImage);
200 }
201
202 ZapHeap * DataImage::GetHeap()
203
204     LIMITED_METHOD_CONTRACT; 
205     return m_pZapImage->GetHeap();
206 }
207
208 void DataImage::AddStructureInOrder(ZapNode *pNode, BOOL fMaintainSaveOrder /*=FALSE*/)
209 {
210     WRAPPER_NO_CONTRACT;
211
212     SavedNodeEntry entry;
213     entry.pNode = pNode;
214     entry.dwAssociatedOrder = 0;
215
216     if (fMaintainSaveOrder)
217     {
218         entry.dwAssociatedOrder = MAINTAIN_SAVE_ORDER;
219     }
220     else if (m_pCurrentAssociatedMethodTable)
221     {
222         TypeHandle th = TypeHandle(m_pCurrentAssociatedMethodTable);
223         entry.dwAssociatedOrder = m_pZapImage->LookupClassLayoutOrder(CORINFO_CLASS_HANDLE(th.AsPtr()));
224     }
225
226     m_structuresInOrder.Append(entry);
227 }
228
229 ZapStoredStructure * DataImage::StoreStructureHelper(const void *data, SIZE_T size,
230                        DataImage::ItemKind kind,
231                        int align,
232                        BOOL fMaintainSaveOrder)
233 {
234     STANDARD_VM_CONTRACT;
235
236     S_SIZE_T cbAllocSize = S_SIZE_T(sizeof(ZapStoredStructure)) + S_SIZE_T(size);
237     if(cbAllocSize.IsOverflow())
238         ThrowHR(COR_E_OVERFLOW);
239
240     void * pMemory = new (GetHeap()) BYTE[cbAllocSize.Value()];
241
242     // PE files cannot be larger than 4 GB
243     if (DWORD(size) != size)
244         ThrowHR(E_UNEXPECTED);
245
246     ZapStoredStructure * pStructure = new (pMemory) ZapStoredStructure((DWORD)size, static_cast<BYTE>(kind), static_cast<BYTE>(align));
247
248     if (data != NULL)
249     {
250         CopyMemory(pStructure->GetData(), data, size);
251         BindPointer(data, pStructure, 0);
252     }
253
254     m_pLastLookup = NULL;
255
256     AddStructureInOrder(pStructure, fMaintainSaveOrder);
257
258     return pStructure;
259 }
260
261 // Bind pointer to the relative offset in ZapNode
262 void DataImage::BindPointer(const void *p, ZapNode * pNode, SSIZE_T offset)
263 {
264     STANDARD_VM_CONTRACT;
265
266     _ASSERTE(m_structures.LookupPtr(p) == NULL);
267
268     StructureEntry e;
269     e.ptr = p;
270     e.pNode = pNode;
271     e.offset = offset;
272     m_structures.Add(e);
273
274     m_pLastLookup = NULL;
275 }
276
277 void DataImage::CopyData(ZapStoredStructure * pNode, const void * p, ULONG size)
278 {
279     memcpy(pNode->GetData(), p, size);
280 }
281
282 void DataImage::CopyDataToOffset(ZapStoredStructure * pNode, ULONG offset, const void * p, ULONG size)
283 {
284     SIZE_T target = (SIZE_T) (pNode->GetData());
285     target += offset;
286
287     memcpy((void *) target, p, size);
288 }
289
290 void DataImage::PlaceStructureForAddress(const void * data, CorCompileSection section)
291 {
292     STANDARD_VM_CONTRACT;
293
294     if (data == NULL)
295         return;
296
297     const StructureEntry * pEntry = m_structures.LookupPtr(data);
298     if (pEntry == NULL)
299         return;
300
301     ZapNode * pNode = pEntry->pNode;
302     if (!pNode->IsPlaced())
303     {
304         ZapVirtualSection * pSection = m_pZapImage->GetSection(section);
305         pSection->Place(pNode);
306     }
307 }
308
309 void DataImage::PlaceInternedStructureForAddress(const void * data, CorCompileSection sectionIfReused, CorCompileSection sectionIfSingleton)
310 {
311     STANDARD_VM_CONTRACT;
312
313     if (data == NULL)
314         return;
315
316     const StructureEntry * pEntry = m_structures.LookupPtr(data);
317     if (pEntry == NULL)
318         return;
319
320     ZapNode * pNode = pEntry->pNode;
321     if (!pNode->IsPlaced())
322     {
323         CorCompileSection section = m_reusedStructures.Contains(pNode) ? sectionIfReused : sectionIfSingleton;
324         ZapVirtualSection * pSection = m_pZapImage->GetSection(section);
325         pSection->Place(pNode);
326     }
327 }
328
329 void DataImage::FixupPointerField(PVOID p, SSIZE_T offset)
330 {
331     STANDARD_VM_CONTRACT;
332
333     PVOID pTarget = *(PVOID UNALIGNED *)((BYTE *)p + offset);
334
335     if (pTarget == NULL)
336     {
337         ZeroPointerField(p, offset);
338         return;
339     }
340
341     FixupField(p, offset, pTarget);
342 }
343
344 void DataImage::FixupRelativePointerField(PVOID p, SSIZE_T offset)
345 {
346     STANDARD_VM_CONTRACT;
347
348     PVOID pTarget = RelativePointer<PTR_VOID>::GetValueMaybeNullAtPtr((TADDR)p + offset);
349
350     if (pTarget == NULL)
351     {
352         ZeroPointerField(p, offset);
353         return;
354     }
355
356     FixupField(p, offset, pTarget, 0, IMAGE_REL_BASED_RELPTR);
357 }
358
359 static void EncodeTargetOffset(PVOID pLocation, SSIZE_T targetOffset, ZapRelocationType type)
360 {
361     // Store the targetOffset into the location of the reloc temporarily
362     switch (type)
363     {
364     case IMAGE_REL_BASED_PTR:
365     case IMAGE_REL_BASED_RELPTR:
366         *(UNALIGNED TADDR *)pLocation = (TADDR)targetOffset;
367         break;
368
369     case IMAGE_REL_BASED_ABSOLUTE:
370         *(UNALIGNED DWORD *)pLocation = (DWORD)targetOffset;
371         break;
372
373     case IMAGE_REL_BASED_ABSOLUTE_TAGGED:
374         _ASSERTE(targetOffset == 0);
375         *(UNALIGNED TADDR *)pLocation = 0;
376         break;
377
378 #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
379     case IMAGE_REL_BASED_REL32:
380         *(UNALIGNED INT32 *)pLocation = (INT32)targetOffset;
381         break;
382 #endif // _TARGET_X86_ || _TARGET_AMD64_
383
384     default:
385         _ASSERTE(0);
386     }
387 }
388
389 static SSIZE_T DecodeTargetOffset(PVOID pLocation, ZapRelocationType type)
390 {
391     // Store the targetOffset into the location of the reloc temporarily
392     switch (type)
393     {
394     case IMAGE_REL_BASED_PTR:
395     case IMAGE_REL_BASED_RELPTR:
396         return (SSIZE_T)*(UNALIGNED TADDR *)pLocation;
397
398     case IMAGE_REL_BASED_ABSOLUTE:
399         return *(UNALIGNED DWORD *)pLocation;
400
401     case IMAGE_REL_BASED_ABSOLUTE_TAGGED:
402         _ASSERTE(*(UNALIGNED TADDR *)pLocation == 0);
403         return 0;
404
405 #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
406     case IMAGE_REL_BASED_REL32:
407         return *(UNALIGNED INT32 *)pLocation;
408 #endif // _TARGET_X86_ || _TARGET_AMD64_
409
410     default:
411         _ASSERTE(0);
412         return 0;
413     }
414 }
415
416 void DataImage::FixupField(PVOID p, SSIZE_T offset, PVOID pTarget, SSIZE_T targetOffset, ZapRelocationType type)
417 {
418     STANDARD_VM_CONTRACT;
419
420     m_iCurrentFixup++;      // Dev11 bug 181494 instrumentation
421
422     const StructureEntry * pEntry = m_pLastLookup;
423     if (pEntry == NULL || pEntry->ptr != p)
424     {
425         pEntry = m_structures.LookupPtr(p);
426         _ASSERTE(pEntry != NULL && 
427             "StoreStructure or BindPointer have to be called on all save data.");
428         m_pLastLookup = pEntry;
429     }
430     offset += pEntry->offset;
431     _ASSERTE(0 <= offset && (DWORD)offset < pEntry->pNode->GetSize());
432
433     const StructureEntry * pTargetEntry = m_pLastLookup;
434     if (pTargetEntry == NULL || pTargetEntry->ptr != pTarget)
435     {
436         pTargetEntry = m_structures.LookupPtr(pTarget);
437
438         _ASSERTE(pTargetEntry != NULL &&
439             "The target of the fixup is not saved into the image");
440     }
441     targetOffset += pTargetEntry->offset;
442     _ASSERTE(0 <= targetOffset && (DWORD)targetOffset <= pTargetEntry->pNode->GetSize());
443
444     FixupEntry entry;
445     entry.m_type = type;
446     entry.m_offset = (DWORD)offset;
447     entry.m_pLocation = AsStoredStructure(pEntry->pNode);
448     entry.m_pTargetNode = pTargetEntry->pNode;
449     AppendFixup(entry);
450
451     EncodeTargetOffset((BYTE *)AsStoredStructure(pEntry->pNode)->GetData() + offset, targetOffset, type);
452 }
453
454 void DataImage::FixupFieldToNode(PVOID p, SSIZE_T offset, ZapNode * pTarget, SSIZE_T targetOffset, ZapRelocationType type)
455 {
456     STANDARD_VM_CONTRACT;
457
458     m_iCurrentFixup++;      // Dev11 bug 181494 instrumentation
459
460     const StructureEntry * pEntry = m_pLastLookup;
461     if (pEntry == NULL || pEntry->ptr != p)
462     {
463         pEntry = m_structures.LookupPtr(p);
464         _ASSERTE(pEntry != NULL && 
465             "StoreStructure or BindPointer have to be called on all save data.");
466         m_pLastLookup = pEntry;
467     }
468     offset += pEntry->offset;
469     _ASSERTE(0 <= offset && (DWORD)offset < pEntry->pNode->GetSize());
470
471     _ASSERTE(pTarget != NULL);
472
473     FixupEntry entry;
474     entry.m_type = type;
475     entry.m_offset = (DWORD)offset;
476     entry.m_pLocation = AsStoredStructure(pEntry->pNode);
477     entry.m_pTargetNode = pTarget;
478     AppendFixup(entry);
479
480     EncodeTargetOffset((BYTE *)AsStoredStructure(pEntry->pNode)->GetData() + offset, targetOffset, type);
481 }
482
483 DWORD DataImage::GetRVA(const void *data)
484 {
485     STANDARD_VM_CONTRACT;
486
487     const StructureEntry * pEntry = m_structures.LookupPtr(data);
488     _ASSERTE(pEntry != NULL);
489
490     return pEntry->pNode->GetRVA() + (DWORD)pEntry->offset;
491 }
492
493 void DataImage::ZeroField(PVOID p, SSIZE_T offset, SIZE_T size)
494 {
495     STANDARD_VM_CONTRACT;
496
497     ZeroMemory(GetImagePointer(p, offset), size);
498 }
499
500 void * DataImage::GetImagePointer(ZapStoredStructure * pNode)
501 {
502     return pNode->GetData();
503 }
504
505 void * DataImage::GetImagePointer(PVOID p, SSIZE_T offset)
506 {
507     STANDARD_VM_CONTRACT;
508
509     const StructureEntry * pEntry = m_pLastLookup;
510     if (pEntry == NULL || pEntry->ptr != p)
511     {
512         pEntry = m_structures.LookupPtr(p);
513         _ASSERTE(pEntry != NULL && 
514             "StoreStructure or BindPointer have to be called on all save data.");
515         m_pLastLookup = pEntry;
516     }
517     offset += pEntry->offset;
518     _ASSERTE(0 <= offset && (DWORD)offset < pEntry->pNode->GetSize());
519
520     return (BYTE *)AsStoredStructure(pEntry->pNode)->GetData() + offset;
521 }
522
523 ZapNode * DataImage::GetNodeForStructure(PVOID p, SSIZE_T * pOffset)
524 {
525     const StructureEntry * pEntry = m_pLastLookup;
526     if (pEntry == NULL || pEntry->ptr != p)
527     {
528         pEntry = m_structures.LookupPtr(p);
529         _ASSERTE(pEntry != NULL && 
530             "StoreStructure or BindPointer have to be called on all save data.");
531     }
532     *pOffset = pEntry->offset;
533     return pEntry->pNode;
534 }
535
536 ZapStoredStructure * DataImage::StoreInternedStructure(const void *data, ULONG size,
537                        DataImage::ItemKind kind,
538                        int align)
539 {
540     STANDARD_VM_CONTRACT;
541
542     ZapStoredStructure * pStructure = m_pInternedStructures->Lookup(InternedStructureKey(data, size, kind));
543
544     if (pStructure != NULL)
545     {
546         // Just add a new mapping for to the interned structure
547         BindPointer(data, pStructure, 0);
548
549         // Track that this structure has been successfully reused by interning
550         NoteReusedStructure(data);
551     }
552     else
553     {
554         // We have not seen this structure yet. Create a new one.
555         pStructure = StoreStructure(data, size, kind);
556         m_pInternedStructures->Add(pStructure);
557     }
558
559     return pStructure;  
560 }
561
562 void DataImage::NoteReusedStructure(const void *data)
563 {
564     STANDARD_VM_CONTRACT;
565
566     _ASSERTE(IsStored(data));
567
568     const StructureEntry * pEntry = m_structures.LookupPtr(data);
569
570     if (!m_reusedStructures.Contains(pEntry->pNode))
571     {
572         m_reusedStructures.Add(pEntry->pNode);
573     }
574 }
575
576 // Save the info of an RVA into m_rvaInfoVector.
577 void DataImage::StoreRvaInfo(FieldDesc * pFD,
578                              DWORD      rva,
579                              UINT       size,
580                              UINT       align)
581 {
582     RvaInfoStructure rvaInfo;
583
584     _ASSERTE(m_module == pFD->GetModule());
585     _ASSERTE(m_module == pFD->GetLoaderModule());
586
587     rvaInfo.pFD = pFD;
588     rvaInfo.rva = rva;
589     rvaInfo.size = size;
590     rvaInfo.align = align;
591
592     m_rvaInfoVector.Append(rvaInfo);
593 }
594
595 // qsort compare function.
596 // Primary key: rva (ascending order). Secondary key: size (descending order).
597 int __cdecl DataImage::rvaInfoVectorEntryCmp(const void* a_, const void* b_)
598 {
599     LIMITED_METHOD_CONTRACT;
600     STATIC_CONTRACT_SO_TOLERANT;   
601     DataImage::RvaInfoStructure *a = (DataImage::RvaInfoStructure *)a_;
602     DataImage::RvaInfoStructure *b = (DataImage::RvaInfoStructure *)b_;
603     int rvaComparisonResult = (int)(a->rva - b->rva);
604     if (rvaComparisonResult!=0)
605         return rvaComparisonResult;        // Ascending order on rva
606     return (int)(b->size - a->size); // Descending order on size
607 }
608
609 // Sort the list of RVA statics in an ascending order wrt the RVA and save them.
610 // For RVA structures with the same RVA, we will only store the one with the largest size.
611 void DataImage::SaveRvaStructure()
612 {
613     if (m_rvaInfoVector.IsEmpty())
614         return;  // No RVA static to save
615
616     // Use qsort to sort the m_rvaInfoVector 
617     qsort (&m_rvaInfoVector[0],               // start of array
618            m_rvaInfoVector.GetCount(),        // array size in elements
619            sizeof(RvaInfoStructure),        // element size in bytes
620            rvaInfoVectorEntryCmp);          // comparere function
621
622     RvaInfoStructure * previousRvaInfo = NULL;
623
624     for (COUNT_T i=0; i<m_rvaInfoVector.GetCount(); i++) {
625
626         RvaInfoStructure * rvaInfo = &(m_rvaInfoVector[i]);
627
628         // Verify that rvaInfo->rva are actually monotonically increasing and
629         // rvaInfo->size are monotonically decreasing if rva are the same.
630         _ASSERTE(previousRvaInfo==NULL ||
631                  previousRvaInfo->rva < rvaInfo->rva ||
632                  previousRvaInfo->rva == rvaInfo->rva && previousRvaInfo->size >= rvaInfo->size
633                 );
634
635         if (previousRvaInfo==NULL || previousRvaInfo->rva != rvaInfo->rva) {
636             void * pRVAData = rvaInfo->pFD->GetStaticAddressHandle(NULL);
637
638             // Note that we force the structures to be laid out in the order we save them
639             StoreStructureInOrder(pRVAData, rvaInfo->size,
640                            DataImage::ITEM_RVA_STATICS,
641                            rvaInfo->align);
642         }
643
644         previousRvaInfo = rvaInfo;
645     }
646 }
647
648 void DataImage::RegisterSurrogate(PVOID ptr, PVOID surrogate)
649 {
650     STANDARD_VM_CONTRACT;
651
652     m_surrogates.Add(ptr, surrogate);
653 }
654
655 PVOID DataImage::LookupSurrogate(PVOID ptr)
656 {
657     STANDARD_VM_CONTRACT;
658
659     const KeyValuePair<PVOID, PVOID> * pEntry = m_surrogates.LookupPtr(ptr);
660     if (pEntry == NULL)
661         return NULL;
662     return pEntry->Value();
663 }
664
665 // Please read comments in corcompile.h for ZapVirtualSectionType before
666 // putting data items into sections.
667 FORCEINLINE static CorCompileSection GetSectionForNodeType(ZapNodeType type)
668 {
669     LIMITED_METHOD_CONTRACT;
670
671     switch ((int)type)
672     {
673     // SECTION_MODULE
674     case NodeTypeForItemKind(DataImage::ITEM_MODULE):
675         return CORCOMPILE_SECTION_MODULE;
676
677     // CORCOMPILE_SECTION_WRITE       (Hot Writeable)
678     // things only go in here if they are:
679     //    (a) explicitly identified by profiling data
680     // or (b) if we have no profiling for these items but they are frequently written to
681     case NodeTypeForItemKind(DataImage::ITEM_FILEREF_MAP):
682     case NodeTypeForItemKind(DataImage::ITEM_ASSEMREF_MAP):
683     case NodeTypeForItemKind(DataImage::ITEM_DYNAMIC_STATICS_INFO_TABLE):
684     case NodeTypeForItemKind(DataImage::ITEM_DYNAMIC_STATICS_INFO_ENTRY):
685     case NodeTypeForItemKind(DataImage::ITEM_CER_RESTORE_FLAGS):
686         return CORCOMPILE_SECTION_WRITE;
687
688     // CORCOMPILE_SECTION_WRITEABLE   (Cold Writeable)
689     case NodeTypeForItemKind(DataImage::ITEM_METHOD_TABLE_SPECIAL_WRITEABLE):
690     case NodeTypeForItemKind(DataImage::ITEM_METHOD_TABLE_DATA_COLD_WRITEABLE):
691     case NodeTypeForItemKind(DataImage::ITEM_DICTIONARY_WRITEABLE):
692     case NodeTypeForItemKind(DataImage::ITEM_FROZEN_OBJECTS): // sometimes the objhdr is modified
693         return CORCOMPILE_SECTION_WRITEABLE;
694
695     // SECTION_HOT
696     // Other things go in here if
697     //   (a) identified as reads by the profiling runs
698     //   (b) if we have no profiling for these items but are identified as typically being read
699     case NodeTypeForItemKind(DataImage::ITEM_CER_ROOT_TABLE):
700     case NodeTypeForItemKind(DataImage::ITEM_RID_MAP_HOT):
701     case NodeTypeForItemKind(DataImage::ITEM_BINDER):
702     case NodeTypeForItemKind(DataImage::ITEM_MODULE_SECDESC):
703     case NodeTypeForItemKind(DataImage::ITEM_METHOD_DESC_HOT):
704         return CORCOMPILE_SECTION_HOT;
705
706     case NodeTypeForItemKind(DataImage::ITEM_BINDER_ITEMS):         // these are the guaranteed to be hot items
707         return CORCOMPILE_SECTION_READONLY_SHARED_HOT;
708
709     // SECTION_READONLY_HOT
710     case NodeTypeForItemKind(DataImage::ITEM_GC_STATIC_HANDLES_HOT): // this is assumed to be hot.  it is not written to.
711     case NodeTypeForItemKind(DataImage::ITEM_MODULE_CCTOR_INFO_HOT):
712     case NodeTypeForItemKind(DataImage::ITEM_NGEN_HASH_BUCKETLIST_HOT):
713     case NodeTypeForItemKind(DataImage::ITEM_NGEN_HASH_ENTRIES_RO_HOT):
714         return CORCOMPILE_SECTION_READONLY_HOT;
715
716     // SECTION_HOT_WRITEABLE
717     case NodeTypeForItemKind(DataImage::ITEM_METHOD_DESC_HOT_WRITEABLE):
718     case NodeTypeForItemKind(DataImage::ITEM_METHOD_TABLE_DATA_HOT_WRITEABLE):
719     case NodeTypeForItemKind(DataImage::ITEM_NGEN_HASH_HOT):
720     case NodeTypeForItemKind(DataImage::ITEM_NGEN_HASH_ENTRIES_HOT):
721         return CORCOMPILE_SECTION_HOT_WRITEABLE;
722
723     case NodeTypeForItemKind(DataImage::ITEM_METHOD_PRECODE_HOT_WRITEABLE):
724         return CORCOMPILE_SECTION_METHOD_PRECODE_WRITE;
725
726     case NodeTypeForItemKind(DataImage::ITEM_METHOD_PRECODE_HOT):
727         return CORCOMPILE_SECTION_METHOD_PRECODE_HOT;
728
729     // SECTION_RVA_STATICS
730     case NodeTypeForItemKind(DataImage::ITEM_RVA_STATICS):
731         return CORCOMPILE_SECTION_RVA_STATICS_COLD; // This MUST go in this section
732
733     // SECTION_WARM
734     case NodeTypeForItemKind(DataImage::ITEM_GUID_INFO):
735     case NodeTypeForItemKind(DataImage::ITEM_DICTIONARY_LAYOUT):
736     case NodeTypeForItemKind(DataImage::ITEM_EECLASS_WARM):
737         return CORCOMPILE_SECTION_WARM;
738
739     // SECTION_READONLY_WARM
740     case NodeTypeForItemKind(DataImage::ITEM_METHOD_TABLE):
741     case NodeTypeForItemKind(DataImage::ITEM_INTERFACE_MAP):
742     case NodeTypeForItemKind(DataImage::ITEM_DISPATCH_MAP):
743     case NodeTypeForItemKind(DataImage::ITEM_GENERICS_STATIC_FIELDDESCS):
744     case NodeTypeForItemKind(DataImage::ITEM_GC_STATIC_HANDLES_COLD):
745     case NodeTypeForItemKind(DataImage::ITEM_MODULE_CCTOR_INFO_COLD):
746     case NodeTypeForItemKind(DataImage::ITEM_STORED_METHOD_NAME):
747     case NodeTypeForItemKind(DataImage::ITEM_PROPERTY_NAME_SET):
748     case NodeTypeForItemKind(DataImage::ITEM_STORED_METHOD_SIG_READONLY_WARM):
749         return CORCOMPILE_SECTION_READONLY_WARM;
750
751     case NodeTypeForItemKind(DataImage::ITEM_DICTIONARY):
752         return CORCOMPILE_SECTION_READONLY_DICTIONARY;
753
754     case NodeTypeForItemKind(DataImage::ITEM_VTABLE_CHUNK):
755         return CORCOMPILE_SECTION_READONLY_VCHUNKS;
756
757     // SECTION_CLASS_COLD
758     case NodeTypeForItemKind(DataImage::ITEM_PARAM_TYPEDESC):
759     case NodeTypeForItemKind(DataImage::ITEM_ARRAY_TYPEDESC):
760     case NodeTypeForItemKind(DataImage::ITEM_EECLASS):
761     case NodeTypeForItemKind(DataImage::ITEM_FIELD_MARSHALERS):
762     case NodeTypeForItemKind(DataImage::ITEM_FPTR_TYPEDESC):
763 #ifdef FEATURE_COMINTEROP
764     case NodeTypeForItemKind(DataImage::ITEM_SPARSE_VTABLE_MAP_TABLE):
765 #endif // FEATURE_COMINTEROP
766         return CORCOMPILE_SECTION_CLASS_COLD;
767
768     //SECTION_READONLY_COLD
769     case NodeTypeForItemKind(DataImage::ITEM_FIELD_DESC_LIST):
770     case NodeTypeForItemKind(DataImage::ITEM_ENUM_VALUES):
771     case NodeTypeForItemKind(DataImage::ITEM_ENUM_NAME_POINTERS):
772     case NodeTypeForItemKind(DataImage::ITEM_ENUM_NAME):
773     case NodeTypeForItemKind(DataImage::ITEM_NGEN_HASH_BUCKETLIST_COLD):
774     case NodeTypeForItemKind(DataImage::ITEM_NGEN_HASH_ENTRIES_RO_COLD):
775     case NodeTypeForItemKind(DataImage::ITEM_STORED_METHOD_SIG_READONLY):
776 #ifdef FEATURE_COMINTEROP 
777     case NodeTypeForItemKind(DataImage::ITEM_SPARSE_VTABLE_MAP_ENTRIES):
778 #endif // FEATURE_COMINTEROP
779     case NodeTypeForItemKind(DataImage::ITEM_CLASS_VARIANCE_INFO):
780         return CORCOMPILE_SECTION_READONLY_COLD;
781
782     // SECTION_CROSS_DOMAIN_INFO
783     case NodeTypeForItemKind(DataImage::ITEM_CROSS_DOMAIN_INFO):
784     case NodeTypeForItemKind(DataImage::ITEM_VTS_INFO):
785         return CORCOMPILE_SECTION_CROSS_DOMAIN_INFO;
786
787     // SECTION_METHOD_DESC_COLD
788     case NodeTypeForItemKind(DataImage::ITEM_METHOD_DESC_COLD):
789         return CORCOMPILE_SECTION_METHOD_DESC_COLD;
790
791     case NodeTypeForItemKind(DataImage::ITEM_METHOD_DESC_COLD_WRITEABLE):
792     case NodeTypeForItemKind(DataImage::ITEM_STORED_METHOD_SIG):
793         return CORCOMPILE_SECTION_METHOD_DESC_COLD_WRITEABLE;
794
795     case NodeTypeForItemKind(DataImage::ITEM_METHOD_PRECODE_COLD):
796         return CORCOMPILE_SECTION_METHOD_PRECODE_COLD;
797
798     case NodeTypeForItemKind(DataImage::ITEM_METHOD_PRECODE_COLD_WRITEABLE):
799         return CORCOMPILE_SECTION_METHOD_PRECODE_COLD_WRITEABLE;
800
801     // SECTION_MODULE_COLD
802     case NodeTypeForItemKind(DataImage::ITEM_TYPEDEF_MAP):
803     case NodeTypeForItemKind(DataImage::ITEM_TYPEREF_MAP):
804     case NodeTypeForItemKind(DataImage::ITEM_METHODDEF_MAP):
805     case NodeTypeForItemKind(DataImage::ITEM_FIELDDEF_MAP):
806     case NodeTypeForItemKind(DataImage::ITEM_MEMBERREF_MAP):
807     case NodeTypeForItemKind(DataImage::ITEM_GENERICPARAM_MAP):
808     case NodeTypeForItemKind(DataImage::ITEM_GENERICTYPEDEF_MAP):
809     case NodeTypeForItemKind(DataImage::ITEM_PROPERTYINFO_MAP):
810     case NodeTypeForItemKind(DataImage::ITEM_TYVAR_TYPEDESC):
811     case NodeTypeForItemKind(DataImage::ITEM_EECLASS_COLD):
812     case NodeTypeForItemKind(DataImage::ITEM_CER_METHOD_LIST):
813     case NodeTypeForItemKind(DataImage::ITEM_NGEN_HASH_COLD):
814     case NodeTypeForItemKind(DataImage::ITEM_NGEN_HASH_ENTRIES_COLD):
815         return CORCOMPILE_SECTION_MODULE_COLD;
816
817     // SECTION_DEBUG_COLD
818     case NodeTypeForItemKind(DataImage::ITEM_DEBUG):
819     case NodeTypeForItemKind(DataImage::ITEM_INLINING_DATA):
820         return CORCOMPILE_SECTION_DEBUG_COLD;
821
822     // SECTION_COMPRESSED_MAPS
823     case NodeTypeForItemKind(DataImage::ITEM_COMPRESSED_MAP):
824         return CORCOMPILE_SECTION_COMPRESSED_MAPS;
825
826     default:
827         _ASSERTE(!"Missing mapping between type and section");
828         return CORCOMPILE_SECTION_MODULE_COLD;
829     }
830 }
831
832 static int __cdecl LayoutOrderCmp(const void* a_, const void* b_)
833 {
834     DWORD a = ((DataImage::SavedNodeEntry*)a_)->dwAssociatedOrder;
835     DWORD b = ((DataImage::SavedNodeEntry*)b_)->dwAssociatedOrder;
836
837     if (a > b) 
838     {
839         return 1;
840     }
841     else
842     {
843         return (a < b) ? -1 : 0;
844     }
845 }
846
847 void DataImage::PlaceRemainingStructures()
848 {
849     if (m_pZapImage->HasClassLayoutOrder())
850     {
851         // The structures are currently in save order; since we are going to change
852         // that to class layout order, first place any that require us to maintain save order.
853         // Note that this is necessary because qsort is not stable.
854         for (COUNT_T iStructure = 0; iStructure < m_structuresInOrder.GetCount(); iStructure++)
855         {
856             if (m_structuresInOrder[iStructure].dwAssociatedOrder == MAINTAIN_SAVE_ORDER)
857             {
858                 ZapNode * pStructure = m_structuresInOrder[iStructure].pNode;
859                 if (!pStructure->IsPlaced())
860                 {
861                     ZapVirtualSection * pSection = m_pZapImage->GetSection(GetSectionForNodeType(pStructure->GetType()));
862                     pSection->Place(pStructure);
863                 }
864             }            
865         }
866
867         qsort(&m_structuresInOrder[0], m_structuresInOrder.GetCount(), sizeof(SavedNodeEntry), LayoutOrderCmp);
868     }
869
870     // Place the unplaced structures, which may have been re-sorted according to class-layout order
871     for (COUNT_T iStructure = 0; iStructure < m_structuresInOrder.GetCount(); iStructure++)
872     {
873         ZapNode * pStructure = m_structuresInOrder[iStructure].pNode;
874         if (!pStructure->IsPlaced())
875         {
876             ZapVirtualSection * pSection = m_pZapImage->GetSection(GetSectionForNodeType(pStructure->GetType()));
877             pSection->Place(pStructure);
878         }
879     }
880 }
881
882 int __cdecl DataImage::fixupEntryCmp(const void* a_, const void* b_)
883 {
884     LIMITED_METHOD_CONTRACT;
885     FixupEntry *a = (FixupEntry *)a_;
886     FixupEntry *b = (FixupEntry *)b_;
887     return (a->m_pLocation->GetRVA() + a->m_offset) - (b->m_pLocation->GetRVA() + b->m_offset);
888 }
889
890 void DataImage::FixupRVAs()
891 {
892     STANDARD_VM_CONTRACT;
893
894     FixupModuleRVAs();
895     FixupRvaStructure();
896
897
898     // Dev11 bug 181494 instrumentation
899     if (m_Fixups.GetCount() != m_iCurrentFixup) EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE);
900
901     qsort(&m_Fixups[0], m_Fixups.GetCount(), sizeof(FixupEntry), fixupEntryCmp);
902
903     // Sentinel
904     FixupEntry entry;
905
906     entry.m_type = 0;
907     entry.m_offset = 0;
908     entry.m_pLocation = NULL;
909     entry.m_pTargetNode = NULL;
910
911     m_Fixups.Append(entry);
912
913     // Dev11 bug 181494 instrumentation
914     if (m_Fixups.GetCount() -1 != m_iCurrentFixup) EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE);
915
916     m_iCurrentFixup = 0;
917 }
918
919 void DataImage::SetRVAsForFields(IMetaDataEmit * pEmit)
920 {
921     for (COUNT_T i=0; i<m_rvaInfoVector.GetCount(); i++) {
922
923         RvaInfoStructure * rvaInfo = &(m_rvaInfoVector[i]);
924
925         void * pRVAData = rvaInfo->pFD->GetStaticAddressHandle(NULL);
926
927         DWORD dwOffset = GetRVA(pRVAData);
928
929         pEmit->SetRVA(rvaInfo->pFD->GetMemberDef(), dwOffset);
930     }
931 }
932
933 void ZapStoredStructure::Save(ZapWriter * pWriter)
934 {
935     DataImage * image = ZapImage::GetImage(pWriter)->m_pDataImage;
936
937     DataImage::FixupEntry * pPrevFixupEntry = NULL;
938
939     for (;;)
940     {
941         DataImage::FixupEntry * pFixupEntry = &(image->m_Fixups[image->m_iCurrentFixup]);
942
943         if (pFixupEntry->m_pLocation != this)
944         {
945             _ASSERTE(pFixupEntry->m_pLocation == NULL ||
946                 GetRVA() + GetSize() <= pFixupEntry->m_pLocation->GetRVA());
947             break;
948         }
949
950         PVOID pLocation = (BYTE *)GetData() + pFixupEntry->m_offset;
951
952         if (pPrevFixupEntry == NULL || pPrevFixupEntry->m_offset != pFixupEntry->m_offset)
953         {
954             SSIZE_T targetOffset = DecodeTargetOffset(pLocation, pFixupEntry->m_type);
955
956 #ifdef _DEBUG
957             // All pointers in EE datastructures should be aligned. This is important to
958             // avoid stradling relocations that cause issues with ASLR.
959             if (pFixupEntry->m_type == IMAGE_REL_BASED_PTR)
960             {
961                 _ASSERTE(IS_ALIGNED(pWriter->GetCurrentRVA() + pFixupEntry->m_offset, sizeof(TADDR)));
962             }
963 #endif
964
965             ZapImage::GetImage(pWriter)->WriteReloc(
966                 GetData(),
967                 pFixupEntry->m_offset, 
968                 pFixupEntry->m_pTargetNode,
969                 (int)targetOffset,
970                 pFixupEntry->m_type);
971         }
972         else
973         {
974             // It's fine to have duplicate fixup entries, but they must target the same data.
975             // If this assert fires, Fixup* was called twice on the same field in an NGen'd
976             // structure with different targets, which likely indicates the current structure
977             // was illegally interned or shared.
978             _ASSERTE(pPrevFixupEntry->m_type == pFixupEntry->m_type);
979             _ASSERTE(pPrevFixupEntry->m_pTargetNode== pFixupEntry->m_pTargetNode);
980         }
981         
982         pPrevFixupEntry = pFixupEntry;
983         image->m_iCurrentFixup++;
984     }
985
986     pWriter->Write(GetData(), m_dwSize);
987 }
988
989 void DataImage::FixupSectionRange(SIZE_T offset, ZapNode * pNode)
990 {
991     STANDARD_VM_CONTRACT;
992
993     if (pNode->GetSize() != 0)
994     {
995         FixupFieldToNode(m_module->m_pNGenLayoutInfo, offset, pNode);
996
997         SIZE_T * pSize = (SIZE_T *)((BYTE *)GetImagePointer(m_module->m_pNGenLayoutInfo) + offset + sizeof(TADDR));
998         *pSize = pNode->GetSize();
999     }
1000 }
1001
1002 void DataImage::FixupSectionPtr(SIZE_T offset, ZapNode * pNode)
1003 {
1004     if (pNode->GetSize() != 0)
1005         FixupFieldToNode(m_module->m_pNGenLayoutInfo, offset, pNode);
1006 }
1007
1008 void DataImage::FixupJumpStubPtr(SIZE_T offset, CorInfoHelpFunc ftnNum)
1009 {
1010     ZapNode * pNode = m_pZapImage->GetHelperThunkIfExists(ftnNum);
1011     if (pNode != NULL)
1012         FixupFieldToNode(m_module->m_pNGenLayoutInfo, offset, pNode);
1013 }
1014
1015 void DataImage::FixupModuleRVAs()
1016 {
1017     STANDARD_VM_CONTRACT;
1018
1019     FixupSectionRange(offsetof(NGenLayoutInfo, m_CodeSections[0]), m_pZapImage->m_pHotCodeSection);
1020     FixupSectionRange(offsetof(NGenLayoutInfo, m_CodeSections[1]), m_pZapImage->m_pCodeSection);
1021     FixupSectionRange(offsetof(NGenLayoutInfo, m_CodeSections[2]), m_pZapImage->m_pColdCodeSection);
1022
1023     NGenLayoutInfo * pSavedNGenLayoutInfo = (NGenLayoutInfo *)GetImagePointer(m_module->m_pNGenLayoutInfo);
1024
1025     COUNT_T nHotRuntimeFunctions = m_pZapImage->m_pHotRuntimeFunctionSection->GetNodeCount();
1026     if (nHotRuntimeFunctions != 0)
1027     {
1028         pSavedNGenLayoutInfo->m_nRuntimeFunctions[0] = nHotRuntimeFunctions;
1029
1030         FixupFieldToNode(m_module->m_pNGenLayoutInfo, offsetof(NGenLayoutInfo, m_UnwindInfoLookupTable[0]), m_pZapImage->m_pHotRuntimeFunctionLookupSection);
1031         pSavedNGenLayoutInfo->m_UnwindInfoLookupTableEntryCount[0] = m_pZapImage->m_pHotRuntimeFunctionLookupSection->GetSize() / sizeof(DWORD) - 1;
1032
1033         FixupFieldToNode(m_module->m_pNGenLayoutInfo, offsetof(NGenLayoutInfo, m_MethodDescs[0]), m_pZapImage->m_pHotCodeMethodDescsSection);
1034
1035         FixupFieldToNode(m_module->m_pNGenLayoutInfo, offsetof(NGenLayoutInfo, m_pRuntimeFunctions[0]), m_pZapImage->m_pHotRuntimeFunctionSection);
1036     }
1037
1038     COUNT_T nRuntimeFunctions = m_pZapImage->m_pRuntimeFunctionSection->GetNodeCount();
1039     if (nRuntimeFunctions != 0)
1040     {
1041         pSavedNGenLayoutInfo->m_nRuntimeFunctions[1] = nRuntimeFunctions;
1042
1043         FixupFieldToNode(m_module->m_pNGenLayoutInfo, offsetof(NGenLayoutInfo, m_UnwindInfoLookupTable[1]), m_pZapImage->m_pRuntimeFunctionLookupSection);
1044         pSavedNGenLayoutInfo->m_UnwindInfoLookupTableEntryCount[1] = m_pZapImage->m_pRuntimeFunctionLookupSection->GetSize() / sizeof(DWORD) - 1;
1045
1046         FixupFieldToNode(m_module->m_pNGenLayoutInfo, offsetof(NGenLayoutInfo, m_MethodDescs[1]), m_pZapImage->m_pCodeMethodDescsSection);
1047
1048         FixupFieldToNode(m_module->m_pNGenLayoutInfo, offsetof(NGenLayoutInfo, m_pRuntimeFunctions[1]), m_pZapImage->m_pRuntimeFunctionSection);
1049     }
1050
1051     COUNT_T nColdRuntimeFunctions = m_pZapImage->m_pColdRuntimeFunctionSection->GetNodeCount();
1052     if (nColdRuntimeFunctions != 0)
1053     {
1054         pSavedNGenLayoutInfo->m_nRuntimeFunctions[2] = nColdRuntimeFunctions;
1055
1056         FixupFieldToNode(m_module->m_pNGenLayoutInfo, offsetof(NGenLayoutInfo, m_pRuntimeFunctions[2]), m_pZapImage->m_pColdRuntimeFunctionSection);
1057     }
1058
1059     if (m_pZapImage->m_pColdCodeMapSection->GetNodeCount() != 0)
1060     {
1061         FixupFieldToNode(m_module->m_pNGenLayoutInfo, offsetof(NGenLayoutInfo, m_ColdCodeMap), m_pZapImage->m_pColdCodeMapSection);
1062     }
1063
1064     FixupSectionRange(offsetof(NGenLayoutInfo, m_Precodes[0]), m_pZapImage->GetSection(CORCOMPILE_SECTION_METHOD_PRECODE_HOT));
1065     FixupSectionRange(offsetof(NGenLayoutInfo, m_Precodes[1]), m_pZapImage->GetSection(CORCOMPILE_SECTION_METHOD_PRECODE_COLD));
1066     FixupSectionRange(offsetof(NGenLayoutInfo, m_Precodes[2]), m_pZapImage->GetSection(CORCOMPILE_SECTION_METHOD_PRECODE_WRITE));
1067     FixupSectionRange(offsetof(NGenLayoutInfo, m_Precodes[3]), m_pZapImage->GetSection(CORCOMPILE_SECTION_METHOD_PRECODE_COLD_WRITEABLE));
1068     
1069     FixupSectionRange(offsetof(NGenLayoutInfo, m_JumpStubs), m_pZapImage->m_pHelperTableSection);
1070     FixupSectionRange(offsetof(NGenLayoutInfo, m_StubLinkStubs), m_pZapImage->m_pStubsSection);
1071     FixupSectionRange(offsetof(NGenLayoutInfo, m_VirtualMethodThunks), m_pZapImage->m_pVirtualImportThunkSection);
1072     FixupSectionRange(offsetof(NGenLayoutInfo, m_ExternalMethodThunks), m_pZapImage->m_pExternalMethodThunkSection);
1073
1074     if (m_pZapImage->m_pExceptionInfoLookupTable->GetSize() != 0)
1075         FixupSectionRange(offsetof(NGenLayoutInfo, m_ExceptionInfoLookupTable), m_pZapImage->m_pExceptionInfoLookupTable);
1076
1077     FixupJumpStubPtr(offsetof(NGenLayoutInfo, m_pPrestubJumpStub), CORINFO_HELP_EE_PRESTUB);
1078 #ifdef HAS_FIXUP_PRECODE
1079     FixupJumpStubPtr(offsetof(NGenLayoutInfo, m_pPrecodeFixupJumpStub), CORINFO_HELP_EE_PRECODE_FIXUP);
1080 #endif
1081     FixupJumpStubPtr(offsetof(NGenLayoutInfo, m_pVirtualImportFixupJumpStub), CORINFO_HELP_EE_VTABLE_FIXUP);
1082     FixupJumpStubPtr(offsetof(NGenLayoutInfo, m_pExternalMethodFixupJumpStub), CORINFO_HELP_EE_EXTERNAL_FIXUP);
1083
1084     ZapNode * pFilterPersonalityRoutine = m_pZapImage->GetHelperThunkIfExists(CORINFO_HELP_EE_PERSONALITY_ROUTINE_FILTER_FUNCLET);
1085     if (pFilterPersonalityRoutine != NULL)
1086         FixupFieldToNode(m_module->m_pNGenLayoutInfo, offsetof(NGenLayoutInfo, m_rvaFilterPersonalityRoutine), pFilterPersonalityRoutine, 0, IMAGE_REL_BASED_ABSOLUTE);
1087 }
1088
1089 void DataImage::FixupRvaStructure()
1090 {
1091     STANDARD_VM_CONTRACT;
1092
1093     for (COUNT_T i=0; i<m_rvaInfoVector.GetCount(); i++) {
1094
1095         RvaInfoStructure * rvaInfo = &(m_rvaInfoVector[i]);
1096
1097         void * pRVAData = rvaInfo->pFD->GetStaticAddressHandle(NULL);
1098
1099         DWORD dwOffset = GetRVA(pRVAData);
1100      
1101         FieldDesc * pNewFD = (FieldDesc *)GetImagePointer(rvaInfo->pFD);
1102         pNewFD->SetOffset(dwOffset);
1103     }
1104 }
1105
1106 ZapNode * DataImage::GetCodeAddress(MethodDesc * method)
1107 {
1108     ZapMethodHeader * pMethod = m_pZapImage->GetCompiledMethod((CORINFO_METHOD_HANDLE)method);
1109     return (pMethod != NULL) ? pMethod->GetCode() : NULL;
1110 }
1111
1112 BOOL DataImage::CanDirectCall(MethodDesc * method, CORINFO_ACCESS_FLAGS  accessFlags)
1113 {
1114     return m_pZapImage->canIntraModuleDirectCall(NULL, (CORINFO_METHOD_HANDLE)method, NULL, accessFlags);
1115 }
1116
1117 ZapNode * DataImage::GetFixupList(MethodDesc * method)
1118 {
1119     ZapMethodHeader * pMethod = m_pZapImage->GetCompiledMethod((CORINFO_METHOD_HANDLE)method);
1120     return (pMethod != NULL) ? pMethod->GetFixupList() : NULL;
1121 }
1122
1123 ZapNode * DataImage::GetHelperThunk(CorInfoHelpFunc ftnNum)
1124 {
1125     return m_pZapImage->GetHelperThunk(ftnNum);
1126 }
1127
1128 ZapNode * DataImage::GetTypeHandleImport(TypeHandle th, PVOID pUniqueId)
1129 {
1130     ZapImport * pImport = m_pZapImage->GetImportTable()->GetClassHandleImport(CORINFO_CLASS_HANDLE(th.AsPtr()), pUniqueId);
1131     if (!pImport->IsPlaced())
1132         m_pZapImage->GetImportTable()->PlaceImport(pImport);
1133     return pImport;
1134 }
1135
1136 ZapNode * DataImage::GetMethodHandleImport(MethodDesc * pMD)
1137 {
1138     ZapImport * pImport = m_pZapImage->GetImportTable()->GetMethodHandleImport(CORINFO_METHOD_HANDLE(pMD));
1139     if (!pImport->IsPlaced())
1140         m_pZapImage->GetImportTable()->PlaceImport(pImport);
1141     return pImport;
1142 }
1143
1144 ZapNode * DataImage::GetFieldHandleImport(FieldDesc * pMD)
1145 {
1146     ZapImport * pImport = m_pZapImage->GetImportTable()->GetFieldHandleImport(CORINFO_FIELD_HANDLE(pMD));
1147     if (!pImport->IsPlaced())
1148         m_pZapImage->GetImportTable()->PlaceImport(pImport);
1149     return pImport;
1150 }
1151
1152 ZapNode * DataImage::GetModuleHandleImport(Module * pModule)
1153 {
1154     ZapImport * pImport = m_pZapImage->GetImportTable()->GetModuleHandleImport(CORINFO_MODULE_HANDLE(pModule));
1155     if (!pImport->IsPlaced())
1156         m_pZapImage->GetImportTable()->PlaceImport(pImport);
1157     return pImport;
1158 }
1159
1160 DWORD DataImage::GetModuleImportIndex(Module * pModule)
1161 {
1162     return m_pZapImage->GetImportTable()->GetIndexOfModule((CORINFO_MODULE_HANDLE)pModule);
1163 }
1164
1165 ZapNode * DataImage::GetExistingTypeHandleImport(TypeHandle th)
1166 {
1167     ZapImport * pImport = m_pZapImage->GetImportTable()->GetExistingClassHandleImport(CORINFO_CLASS_HANDLE(th.AsPtr()));
1168     return (pImport != NULL && pImport->IsPlaced()) ? pImport : NULL;
1169 }
1170
1171 ZapNode * DataImage::GetExistingMethodHandleImport(MethodDesc * pMD)
1172 {
1173     ZapImport * pImport = m_pZapImage->GetImportTable()->GetExistingMethodHandleImport(CORINFO_METHOD_HANDLE(pMD));
1174     return (pImport != NULL && pImport->IsPlaced()) ? pImport : NULL;
1175 }
1176
1177 ZapNode * DataImage::GetExistingFieldHandleImport(FieldDesc * pFD)
1178 {
1179     ZapImport * pImport = m_pZapImage->GetImportTable()->GetExistingFieldHandleImport(CORINFO_FIELD_HANDLE(pFD));
1180     return (pImport != NULL && pImport->IsPlaced()) ? pImport : NULL;
1181 }
1182
1183 ZapNode * DataImage::GetVirtualImportThunk(MethodTable * pMT, MethodDesc * pMD, int slotNumber)
1184 {
1185     _ASSERTE(pMD == pMT->GetMethodDescForSlot(slotNumber));
1186     _ASSERTE(!pMD->IsGenericMethodDefinition());
1187
1188     ZapImport * pImport = m_pZapImage->GetImportTable()->GetVirtualImportThunk(CORINFO_METHOD_HANDLE(pMD), slotNumber);
1189     if (!pImport->IsPlaced())
1190         m_pZapImage->GetImportTable()->PlaceVirtualImportThunk(pImport);
1191     return pImport;
1192 }
1193
1194 ZapNode * DataImage::GetGenericSignature(PVOID signature, BOOL fMethod)
1195 {
1196     ZapGenericSignature * pGenericSignature = m_pZapImage->GetImportTable()->GetGenericSignature(signature, fMethod);
1197     if (!pGenericSignature->IsPlaced())
1198         m_pZapImage->GetImportTable()->PlaceBlob(pGenericSignature);
1199     return pGenericSignature;
1200 }
1201
1202 #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
1203
1204 class ZapStubPrecode : public ZapNode
1205 {
1206 protected:
1207     MethodDesc * m_pMD;
1208     DataImage::ItemKind m_kind;
1209
1210 public:
1211     ZapStubPrecode(MethodDesc * pMethod, DataImage::ItemKind kind)
1212         : m_pMD(pMethod), m_kind(kind)
1213     {
1214     }
1215
1216     virtual DWORD GetSize()
1217     {
1218         return sizeof(StubPrecode);
1219     }
1220
1221     virtual UINT GetAlignment()
1222     {
1223         return PRECODE_ALIGNMENT;
1224     }
1225
1226     virtual ZapNodeType GetType()
1227     {
1228         return NodeTypeForItemKind(m_kind);
1229     }
1230
1231     virtual DWORD ComputeRVA(ZapWriter * pZapWriter, DWORD dwPos)
1232     {
1233         dwPos = AlignUp(dwPos, GetAlignment());
1234
1235         // Alignment for straddlers. Need a cast to help gcc choose between AlignmentTrim(UINT,UINT) and (UINT64,UINT).
1236         if (AlignmentTrim(static_cast<UINT>(dwPos + offsetof(StubPrecode, m_pMethodDesc)), RELOCATION_PAGE_SIZE) > RELOCATION_PAGE_SIZE - sizeof(TADDR))
1237             dwPos += GetAlignment();
1238
1239         SetRVA(dwPos);
1240
1241         dwPos += GetSize();
1242
1243         return dwPos;
1244     }
1245
1246     virtual void Save(ZapWriter * pZapWriter)
1247     {
1248         ZapImage * pImage = ZapImage::GetImage(pZapWriter);
1249
1250         StubPrecode precode;
1251
1252         precode.Init(m_pMD);
1253
1254         SSIZE_T offset;
1255         ZapNode * pNode = pImage->m_pDataImage->GetNodeForStructure(m_pMD, &offset);
1256         pImage->WriteReloc(&precode, offsetof(StubPrecode, m_pMethodDesc),
1257             pNode, (int)offset, IMAGE_REL_BASED_PTR);
1258
1259         pImage->WriteReloc(&precode, offsetof(StubPrecode, m_rel32),
1260             pImage->GetHelperThunk(CORINFO_HELP_EE_PRESTUB), 0, IMAGE_REL_BASED_REL32);
1261
1262         pZapWriter->Write(&precode, sizeof(precode));
1263     }
1264 };
1265
1266 #ifdef HAS_NDIRECT_IMPORT_PRECODE
1267 class ZapNDirectImportPrecode : public ZapStubPrecode
1268 {
1269 public:
1270     ZapNDirectImportPrecode(MethodDesc * pMD, DataImage::ItemKind kind)
1271         : ZapStubPrecode(pMD, kind)
1272     {
1273     }
1274
1275     virtual void Save(ZapWriter * pZapWriter)
1276     {
1277         ZapImage * pImage = ZapImage::GetImage(pZapWriter);
1278
1279         StubPrecode precode;
1280
1281         precode.Init(m_pMD);
1282
1283         SSIZE_T offset;
1284         ZapNode * pNode = pImage->m_pDataImage->GetNodeForStructure(m_pMD, &offset);
1285         pImage->WriteReloc(&precode, offsetof(StubPrecode, m_pMethodDesc),
1286             pNode, (int)offset, IMAGE_REL_BASED_PTR);
1287
1288         pImage->WriteReloc(&precode, offsetof(StubPrecode, m_rel32),
1289             pImage->GetHelperThunk(CORINFO_HELP_EE_PINVOKE_FIXUP), 0, IMAGE_REL_BASED_REL32);
1290
1291         pZapWriter->Write(&precode, sizeof(precode));
1292     }
1293 };
1294 #endif // HAS_NDIRECT_IMPORT_PRECODE
1295
1296 #ifdef HAS_REMOTING_PRECODE
1297 class ZapRemotingPrecode : public ZapNode
1298 {
1299     MethodDesc * m_pMD;
1300     DataImage::ItemKind m_kind;
1301     BOOL m_fIsPrebound;
1302
1303 public:
1304     ZapRemotingPrecode(MethodDesc * pMethod, DataImage::ItemKind kind, BOOL fIsPrebound)
1305         : m_pMD(pMethod), m_kind(kind), m_fIsPrebound(fIsPrebound)
1306     {
1307     }
1308
1309     virtual DWORD GetSize()
1310     {
1311         return sizeof(RemotingPrecode);
1312     }
1313
1314     virtual UINT GetAlignment()
1315     {
1316         return PRECODE_ALIGNMENT;
1317     }
1318
1319     virtual ZapNodeType GetType()
1320     {
1321         return NodeTypeForItemKind(m_kind);
1322     }
1323
1324     virtual DWORD ComputeRVA(ZapWriter * pZapWriter, DWORD dwPos)
1325     {
1326         dwPos = AlignUp(dwPos, GetAlignment());
1327
1328         // Alignment for straddlers
1329         if (AlignmentTrim(dwPos + offsetof(RemotingPrecode, m_pMethodDesc), RELOCATION_PAGE_SIZE) > RELOCATION_PAGE_SIZE - sizeof(TADDR))
1330             dwPos += GetAlignment();
1331
1332         SetRVA(dwPos);
1333
1334         dwPos += GetSize();
1335
1336         return dwPos;
1337     }
1338
1339     virtual void Save(ZapWriter * pZapWriter)
1340     {
1341         ZapImage * pImage = ZapImage::GetImage(pZapWriter);
1342
1343         RemotingPrecode precode;
1344
1345         precode.Init(m_pMD);
1346
1347         SSIZE_T offset;
1348         ZapNode * pNode = pImage->m_pDataImage->GetNodeForStructure(m_pMD, &offset);
1349         pImage->WriteReloc(&precode, offsetof(RemotingPrecode, m_pMethodDesc),
1350             pNode, offset, IMAGE_REL_BASED_PTR);
1351
1352         pImage->WriteReloc(&precode, offsetof(RemotingPrecode, m_callRel32),
1353             pImage->GetHelperThunk(CORINFO_HELP_EE_REMOTING_THUNK), 0, IMAGE_REL_BASED_REL32);
1354
1355         if (m_fIsPrebound)
1356         {
1357             pImage->WriteReloc(&precode, offsetof(RemotingPrecode, m_rel32),
1358                 pImage->m_pDataImage->GetCodeAddress(m_pMD), 0, IMAGE_REL_BASED_REL32);
1359         }
1360         else
1361         {
1362             pImage->WriteReloc(&precode, offsetof(RemotingPrecode, m_rel32),
1363                 pImage->GetHelperThunk(CORINFO_HELP_EE_PRESTUB), 0, IMAGE_REL_BASED_REL32);
1364         }
1365
1366         pZapWriter->Write(&precode, sizeof(precode));
1367     }
1368
1369     BOOL IsPrebound(ZapImage * pImage)
1370     {
1371         // This will make sure that when IBC logging is on, the precode goes thru prestub.
1372         if (GetAppDomain()->ToCompilationDomain()->m_fForceInstrument)
1373             return FALSE;
1374
1375         // Prebind the remoting precode if possible
1376         return pImage->m_pDataImage->CanDirectCall(m_pMD, CORINFO_ACCESS_THIS);
1377     }
1378
1379 };
1380 #endif // HAS_REMOTING_PRECODE
1381
1382 void DataImage::SavePrecode(PVOID ptr, MethodDesc * pMD, PrecodeType t, ItemKind kind, BOOL fIsPrebound)
1383 {
1384     ZapNode * pNode = NULL;
1385
1386     switch (t) {
1387     case PRECODE_STUB:
1388         pNode = new (GetHeap()) ZapStubPrecode(pMD, kind);
1389         GetHelperThunk(CORINFO_HELP_EE_PRESTUB);
1390         break;
1391
1392 #ifdef HAS_NDIRECT_IMPORT_PRECODE
1393     case PRECODE_NDIRECT_IMPORT:
1394         pNode = new (GetHeap()) ZapNDirectImportPrecode(pMD, kind);
1395         GetHelperThunk(CORINFO_HELP_EE_PINVOKE_FIXUP);
1396         break;
1397 #endif // HAS_NDIRECT_IMPORT_PRECODE
1398
1399 #ifdef HAS_REMOTING_PRECODE
1400     case PRECODE_REMOTING:
1401         pNode = new (GetHeap()) ZapRemotingPrecode(pMD, kind, fIsPrebound);
1402
1403         GetHelperThunk(CORINFO_HELP_EE_REMOTING_THUNK);
1404
1405         if (!fIsPrebound)
1406         {
1407             GetHelperThunk(CORINFO_HELP_EE_PRESTUB);
1408         }
1409         break;
1410 #endif // HAS_REMOTING_PRECODE
1411
1412     default:
1413         _ASSERTE(!"Unexpected precode type");
1414         break;
1415     }
1416
1417     BindPointer(ptr, pNode, 0);
1418
1419     AddStructureInOrder(pNode);
1420 }
1421
1422 #endif // _TARGET_X86_ || _TARGET_AMD64_
1423
1424 void DataImage::FixupModulePointer(Module * pModule, PVOID p, SSIZE_T offset, ZapRelocationType type)
1425 {
1426     STANDARD_VM_CONTRACT;
1427
1428     if (pModule != NULL)
1429     {
1430         if (CanEagerBindToModule(pModule) && CanHardBindToZapModule(pModule))
1431         {
1432             FixupField(p, offset, pModule, 0, type);
1433         }
1434         else
1435         {
1436             ZapNode * pImport = GetModuleHandleImport(pModule);
1437             FixupFieldToNode(p, offset, pImport, FIXUP_POINTER_INDIRECTION, type);
1438         }
1439     }
1440 }
1441
1442 void DataImage::FixupMethodTablePointer(MethodTable * pMT, PVOID p, SSIZE_T offset, ZapRelocationType type)
1443 {
1444     STANDARD_VM_CONTRACT;
1445
1446     if (pMT != NULL)
1447     {
1448         if (CanEagerBindToMethodTable(pMT) && CanHardBindToZapModule(pMT->GetLoaderModule()))
1449         {
1450             FixupField(p, offset, pMT, 0, type);
1451         }
1452         else
1453         {
1454             ZapNode * pImport = GetTypeHandleImport(pMT);
1455             FixupFieldToNode(p, offset, pImport, FIXUP_POINTER_INDIRECTION, type);
1456         }
1457     }
1458 }
1459
1460 void DataImage::FixupTypeHandlePointer(TypeHandle th, PVOID p, SSIZE_T offset, ZapRelocationType type)
1461 {
1462     STANDARD_VM_CONTRACT;
1463
1464     if (!th.IsNull())
1465     {
1466         if (th.IsTypeDesc())
1467         {
1468             if (CanEagerBindToTypeHandle(th) && CanHardBindToZapModule(th.GetLoaderModule()))
1469             {
1470                 FixupField(p, offset, th.AsTypeDesc(), 2, type);
1471             }
1472             else
1473             {
1474                 ZapNode * pImport = GetTypeHandleImport(th);
1475                 FixupFieldToNode(p, offset, pImport, FIXUP_POINTER_INDIRECTION, type);
1476             }
1477         }
1478         else
1479         {
1480             MethodTable * pMT = th.AsMethodTable();
1481             FixupMethodTablePointer(pMT, p, offset, type);
1482         }
1483     }
1484 }
1485
1486 void DataImage::FixupMethodDescPointer(MethodDesc * pMD, PVOID p, SSIZE_T offset, ZapRelocationType type /*=IMAGE_REL_BASED_PTR*/)
1487 {
1488     STANDARD_VM_CONTRACT;
1489
1490     if (pMD != NULL)
1491     {
1492         if (CanEagerBindToMethodDesc(pMD) && CanHardBindToZapModule(pMD->GetLoaderModule()))
1493         {
1494             FixupField(p, offset, pMD, 0, type);
1495         }
1496         else
1497         {
1498             ZapNode * pImport = GetMethodHandleImport(pMD);
1499             FixupFieldToNode(p, offset, pImport, FIXUP_POINTER_INDIRECTION, type);
1500         }
1501     }
1502 }
1503
1504 void DataImage::FixupFieldDescPointer(FieldDesc * pFD, PVOID p, SSIZE_T offset, ZapRelocationType type /*=IMAGE_REL_BASED_PTR*/)
1505 {
1506     STANDARD_VM_CONTRACT;
1507
1508     if (pFD != NULL)
1509     {
1510         if (CanEagerBindToFieldDesc(pFD) && CanHardBindToZapModule(pFD->GetLoaderModule()))
1511         {
1512             FixupField(p, offset, pFD, 0, type);
1513         }
1514         else
1515         {
1516             ZapNode * pImport = GetFieldHandleImport(pFD);
1517             FixupFieldToNode(p, offset, pImport, FIXUP_POINTER_INDIRECTION, type);
1518         }
1519     }
1520 }
1521
1522 void DataImage::FixupMethodTablePointer(PVOID p, FixupPointer<PTR_MethodTable> * ppMT)
1523 {
1524     FixupMethodTablePointer(ppMT->GetValue(), p, (BYTE *)ppMT - (BYTE *)p, IMAGE_REL_BASED_PTR);
1525 }
1526 void DataImage::FixupTypeHandlePointer(PVOID p, FixupPointer<TypeHandle> * pth)
1527 {
1528     FixupTypeHandlePointer(pth->GetValue(), p, (BYTE *)pth - (BYTE *)p, IMAGE_REL_BASED_PTR);
1529 }
1530 void DataImage::FixupMethodDescPointer(PVOID p, FixupPointer<PTR_MethodDesc> * ppMD)
1531 {
1532     FixupMethodDescPointer(ppMD->GetValue(), p, (BYTE *)ppMD - (BYTE *)p, IMAGE_REL_BASED_PTR);
1533 }
1534 void DataImage::FixupFieldDescPointer(PVOID p, FixupPointer<PTR_FieldDesc> * ppFD)
1535 {
1536     FixupFieldDescPointer(ppFD->GetValue(), p, (BYTE *)ppFD - (BYTE *)p, IMAGE_REL_BASED_PTR);
1537 }
1538
1539 void DataImage::FixupModulePointer(PVOID p, RelativeFixupPointer<PTR_Module> * ppModule)
1540 {
1541     FixupModulePointer(ppModule->GetValueMaybeNull(), p, (BYTE *)ppModule - (BYTE *)p, IMAGE_REL_BASED_RELPTR);
1542 }
1543 void DataImage::FixupMethodTablePointer(PVOID p, RelativeFixupPointer<PTR_MethodTable> * ppMT)
1544 {
1545     FixupMethodTablePointer(ppMT->GetValueMaybeNull(), p, (BYTE *)ppMT - (BYTE *)p, IMAGE_REL_BASED_RELPTR);
1546 }
1547 void DataImage::FixupTypeHandlePointer(PVOID p, RelativeFixupPointer<TypeHandle> * pth)
1548 {
1549     FixupTypeHandlePointer(pth->GetValueMaybeNull(), p, (BYTE *)pth - (BYTE *)p, IMAGE_REL_BASED_RELPTR);
1550 }
1551 void DataImage::FixupMethodDescPointer(PVOID p, RelativeFixupPointer<PTR_MethodDesc> * ppMD)
1552 {
1553     FixupMethodDescPointer(ppMD->GetValueMaybeNull(), p, (BYTE *)ppMD - (BYTE *)p, IMAGE_REL_BASED_RELPTR);
1554 }
1555 void DataImage::FixupFieldDescPointer(PVOID p, RelativeFixupPointer<PTR_FieldDesc> * ppFD)
1556 {
1557     FixupFieldDescPointer(ppFD->GetValueMaybeNull(), p, (BYTE *)ppFD - (BYTE *)p, IMAGE_REL_BASED_RELPTR);
1558 }
1559
1560 BOOL DataImage::CanHardBindToZapModule(Module *targetModule)
1561 {
1562     STANDARD_VM_CONTRACT;
1563
1564     _ASSERTE(targetModule == m_module || targetModule->HasNativeImage());
1565     return targetModule == m_module;
1566 }
1567
1568 BOOL DataImage::CanEagerBindToTypeHandle(TypeHandle th, BOOL fRequirePrerestore, TypeHandleList *pVisited)
1569 {
1570     STANDARD_VM_CONTRACT;
1571
1572     Module * pLoaderModule = th.GetLoaderModule();
1573
1574     BOOL fCanEagerBind;
1575
1576     if (th.IsTypeDesc())
1577     {
1578         fCanEagerBind = CanEagerBindTo(pLoaderModule, Module::GetPreferredZapModuleForTypeDesc(th.AsTypeDesc()), th.AsTypeDesc());
1579     }
1580     else
1581     {
1582         fCanEagerBind = CanEagerBindTo(pLoaderModule, Module::GetPreferredZapModuleForMethodTable(th.AsMethodTable()), th.AsMethodTable());
1583     }
1584
1585     if (GetModule() != th.GetLoaderModule())
1586     {
1587         if (th.IsTypeDesc())
1588         {
1589             return FALSE;
1590         }
1591
1592         // As a performance optimization, don't eager bind to arrays.  They are currently very expensive to
1593         // fixup so we want to do it lazily.
1594
1595         if (th.AsMethodTable()->IsArray())
1596         {
1597             return FALSE;
1598         }
1599
1600         // For correctness in the face of targeted patching, do not eager bind to any instantiation 
1601         // in the target module that might go away.
1602         if (!th.IsTypicalTypeDefinition() &&
1603             !Module::IsAlwaysSavedInPreferredZapModule(th.GetInstantiation(), 
1604                                                        Instantiation()))
1605         {
1606             return FALSE;
1607         }
1608
1609         // #DoNotEagerBindToTypesThatNeedRestore
1610         //
1611         // It is important to avoid eager binding to structures that require restore.  The code here stops
1612         // this from happening for cross-module fixups.  For intra-module cases, eager fixups are allowed to
1613         // (and often do) target types that require restore, even though this is generally prone to all of
1614         // the same problems described below.  Correctness is preserved only because intra-module eager
1615         // fixups are ignored in Module::RunEagerFixups (so their semantics are very close to normal
1616         // non-eager fixups).
1617         //
1618         // For performance, this is the most costly type of eager fixup (and may require otherwise-unneeded
1619         // assemblies to be loaded) and has the lowest benefit, since it does not avoid the need for the
1620         // referencing type to require restore.
1621         //
1622         // More importantly, this kind of fixup can compromise correctness by causing type loads to occur
1623         // during eager fixup resolution.  The system is not designed to cope with this and a variety of
1624         // subtle failures can occur when it happens.  As an example, consider a scenario involving the
1625         // following assemblies and types:
1626         //    o A1: softbinds to A2, contains "class A1!Level2 extends A2!Level1"
1627         //    o A2: hardbinds to A3, contains "class A2!Level1 extends Object", contains methods that use A3!Level3.
1628         //    o A3: softbinds to A1, contains "class A3!Level3 extends A1!Level2"
1629         //
1630         // If eager fixups are allowed to target types that need restore, then it's possible for A2 to end
1631         // up with an eager fixup targeting A3!Level3, setting up this sequence:
1632         //    1 Type load starts for A1!Level2.
1633         //    2 Loading base class A2!Level1 triggers assembly load for A2.
1634         //    3 Loading A2 involves synchronously resolving its eager fixups, including the fixup to A3!Level3.
1635         //    4 A3!Level3 needs restore, so type load starts for A3!Level3.
1636         //    5 Loading A3!Level3 requires loading base class A1!Level2.
1637         //    6 A1!Level2 is already being loaded on this thread (in #1 above), so type load fails.
1638         //    7 Since eager fixup resolution failed, FileLoadException is thrown for A2.
1639         fRequirePrerestore = TRUE;
1640     }
1641
1642     if (fCanEagerBind && fRequirePrerestore)
1643     {
1644         fCanEagerBind = !th.ComputeNeedsRestore(this, pVisited);
1645     }
1646
1647     return fCanEagerBind;
1648 }
1649
1650 BOOL DataImage::CanEagerBindToMethodTable(MethodTable *pMT, BOOL fRequirePrerestore, TypeHandleList *pVisited)
1651 {
1652     WRAPPER_NO_CONTRACT;
1653
1654     TypeHandle th =  TypeHandle(pMT);
1655     return DataImage::CanEagerBindToTypeHandle(th, fRequirePrerestore, pVisited);
1656 }
1657
1658 BOOL DataImage::CanEagerBindToMethodDesc(MethodDesc *pMD, BOOL fRequirePrerestore, TypeHandleList *pVisited)
1659 {
1660     STANDARD_VM_CONTRACT;
1661
1662     BOOL fCanEagerBind = CanEagerBindTo(pMD->GetLoaderModule(), Module::GetPreferredZapModuleForMethodDesc(pMD), pMD);
1663
1664     // Performance optimization -- see comment in CanEagerBindToTypeHandle
1665     if (GetModule() != pMD->GetLoaderModule())
1666     {
1667         // For correctness in the face of targeted patching, do not eager bind to any instantiation 
1668         // in the target module that might go away.
1669         if (!pMD->IsTypicalMethodDefinition() && 
1670             !Module::IsAlwaysSavedInPreferredZapModule(pMD->GetClassInstantiation(), 
1671                                                        pMD->GetMethodInstantiation()))
1672         {
1673             return FALSE;
1674         }
1675
1676         fRequirePrerestore = TRUE;
1677     }
1678
1679     if (fCanEagerBind && fRequirePrerestore)
1680     {
1681         fCanEagerBind = !pMD->ComputeNeedsRestore(this, pVisited);
1682     }
1683
1684     return fCanEagerBind;
1685 }
1686
1687 BOOL DataImage::CanEagerBindToFieldDesc(FieldDesc *pFD, BOOL fRequirePrerestore, TypeHandleList *pVisited)
1688 {
1689     STANDARD_VM_CONTRACT;
1690
1691     if (!CanEagerBindTo(pFD->GetLoaderModule(), Module::GetPreferredZapModuleForFieldDesc(pFD), pFD))
1692         return FALSE;
1693         
1694     MethodTable * pMT = pFD->GetApproxEnclosingMethodTable();
1695     
1696     return CanEagerBindToMethodTable(pMT, fRequirePrerestore, pVisited);
1697 }
1698
1699 BOOL DataImage::CanEagerBindToModule(Module *pModule)
1700 {
1701     STANDARD_VM_CONTRACT;
1702
1703     return GetAppDomain()->ToCompilationDomain()->CanEagerBindToZapFile(pModule);
1704 }
1705
1706 // "address" is a data-structure belonging to pTargetModule.
1707 // This function returns whether the Module currently being ngenned can
1708 // hardbind "address"
1709 /* static */
1710 BOOL DataImage::CanEagerBindTo(Module *pTargetModule, Module *pPreferredZapModule, void *address)
1711 {
1712     STANDARD_VM_CONTRACT;
1713
1714     if (pTargetModule != pPreferredZapModule)
1715         return FALSE;
1716
1717     if (GetModule() == pTargetModule)
1718         return TRUE;
1719
1720     BOOL eagerBindToZap = GetAppDomain()->ToCompilationDomain()->CanEagerBindToZapFile(pTargetModule);
1721     BOOL isPersisted    = pTargetModule->IsPersistedObject(address);
1722
1723     return eagerBindToZap && isPersisted;
1724 }
1725
1726 BOOL DataImage::CanPrerestoreEagerBindToTypeHandle(TypeHandle th, TypeHandleList *pVisited)
1727 {
1728     WRAPPER_NO_CONTRACT;
1729     return CanEagerBindToTypeHandle(th, TRUE, pVisited);
1730 }
1731
1732 BOOL DataImage::CanPrerestoreEagerBindToMethodTable(MethodTable *pMT, TypeHandleList *pVisited)
1733 {
1734     WRAPPER_NO_CONTRACT;
1735     return CanEagerBindToMethodTable(pMT, TRUE, pVisited);
1736 }
1737
1738 BOOL DataImage::CanPrerestoreEagerBindToMethodDesc(MethodDesc *pMD, TypeHandleList *pVisited)
1739 {
1740     WRAPPER_NO_CONTRACT;
1741     return CanEagerBindToMethodDesc(pMD, TRUE, pVisited);
1742 }
1743
1744
1745 void DataImage::HardBindTypeHandlePointer(PVOID p, SSIZE_T offset)
1746 {
1747     CONTRACTL
1748     {
1749         STANDARD_VM_CHECK;
1750         PRECONDITION(CanEagerBindToTypeHandle(*(TypeHandle UNALIGNED*)((BYTE *)p + offset)));
1751     }
1752     CONTRACTL_END;
1753
1754     TypeHandle thCopy = *(TypeHandle UNALIGNED*)((BYTE *)p + offset);
1755
1756     if (!thCopy.IsNull())
1757     {
1758         if (thCopy.IsTypeDesc())
1759         {
1760             FixupField(p, offset, thCopy.AsTypeDesc(), 2);
1761         }
1762         else
1763         {
1764             FixupField(p, offset, thCopy.AsMethodTable());
1765         }
1766     }
1767 }
1768
1769
1770     // This is obsolete in-place fixup that we should get rid of. For now, it is used for:
1771     // - FnPtrTypeDescs. These should not be stored in NGen images at all.
1772     // - stubs-as-il signatures. These should use tokens when stored in NGen image.
1773     //
1774 void DataImage::FixupTypeHandlePointerInPlace(PVOID p, SSIZE_T offset, BOOL fForceFixup /*=FALSE*/)
1775 {
1776     STANDARD_VM_CONTRACT;
1777
1778     TypeHandle thCopy = *(TypeHandle UNALIGNED*)((BYTE *)p + offset);
1779
1780     if (!thCopy.IsNull())
1781     {
1782         if (!fForceFixup &&
1783             CanEagerBindToTypeHandle(thCopy) &&
1784             CanHardBindToZapModule(thCopy.GetLoaderModule()))
1785         {
1786             HardBindTypeHandlePointer(p, offset);
1787         }
1788         else
1789         {
1790             ZapImport * pImport = m_pZapImage->GetImportTable()->GetClassHandleImport((CORINFO_CLASS_HANDLE)thCopy.AsPtr());
1791
1792             ZapNode * pBlob = m_pZapImage->GetImportTable()->PlaceImportBlob(pImport);
1793             FixupFieldToNode(p, offset, pBlob, 0, IMAGE_REL_BASED_ABSOLUTE_TAGGED);
1794         }
1795     }
1796 }
1797
1798 void DataImage::BeginRegion(CorInfoRegionKind regionKind)
1799 {
1800     STANDARD_VM_CONTRACT;
1801
1802     m_pZapImage->BeginRegion(regionKind);
1803 }
1804
1805 void DataImage::EndRegion(CorInfoRegionKind regionKind)
1806 {
1807     STANDARD_VM_CONTRACT;
1808
1809     m_pZapImage->EndRegion(regionKind);
1810 }
1811
1812 void DataImage::ReportInlining(CORINFO_METHOD_HANDLE inliner, CORINFO_METHOD_HANDLE inlinee)
1813 {
1814     STANDARD_VM_CONTRACT;
1815     _ASSERTE(m_inlineTrackingMap);
1816     m_inlineTrackingMap->AddInlining(GetMethod(inliner), GetMethod(inlinee));
1817 }
1818
1819 InlineTrackingMap * DataImage::GetInlineTrackingMap()
1820 {
1821     LIMITED_METHOD_DAC_CONTRACT;
1822     return m_inlineTrackingMap;
1823 }
1824
1825 //
1826 // Compressed LookupMap Support
1827 //
1828 // See the large comment near the top of ceeload.h for a much more detailed discussion of this.
1829 //
1830 // Basically we support a specialized node, ZapCompressedLookupMap, which knows how to compress the array of
1831 // intra-module pointers present in certain types of LookupMap.
1832 //
1833
1834 // A simple class to write a sequential sequence of variable sized bit-fields into a pre-allocated buffer. I
1835 // was going to use the version defined by GcInfoEncoder (the reader side in ceeload.cpp uses GcInfoDecoder's
1836 // BitStreamReader) but unfortunately the code is not currently factored to make this easy and the resources
1837 // were not available to perform a non-trivial refactorization of the code. In any event the writer is fairly
1838 // trivial and doesn't represent a huge duplication of effort.
1839 // The class requires that the input buffer is DWORD-aligned and sized (it uses a DWORD cache and always
1840 // writes data to the buffer in DWORD-sized chunks).
1841 class BitStreamWriter
1842 {
1843 public:
1844     // Initialize a writer and point it at the start of a pre-allocated buffer (large enough to accomodate all
1845     // future writes). The buffer must be DWORD-aligned (we use this for some performance optimization).
1846     BitStreamWriter(DWORD *pStart)
1847     {
1848         LIMITED_METHOD_CONTRACT;
1849
1850         // Buffer must be DWORD-aligned. 
1851         _ASSERTE(((TADDR)pStart & 0x3) == 0);
1852
1853         m_pNext = pStart;   // Point at the start of the buffer
1854         m_dwCurrent = 0;    // We don't have any cached data waiting to write
1855         m_cCurrentBits = 0; // Ditto
1856         m_cBitsWritten = 0; // We haven't written any bits
1857     }
1858
1859     // Write the low-order cBits of dwData to the stream.
1860     void Write(DWORD dwData, DWORD cBits)
1861     {
1862         LIMITED_METHOD_CONTRACT;
1863
1864         // We can only write between 1 and 32 bits of data at a time.
1865         _ASSERTE(cBits > 0 && cBits <= kBitsPerDWORD);
1866
1867         // Check that none of the unused high-order bits of dwData have stale data in them (we can use this to
1868         // optimize paths below). Use two conditions here because << of 32-bits or more (on x86) doesn't
1869         // do what you might expect (the RHS is modulo 32 so "<< 32" is a no-op rather than zero-ing the
1870         // result).
1871         _ASSERTE((cBits == kBitsPerDWORD) || ((dwData & ((1U << cBits) - 1)) == dwData));
1872
1873         // Record the input bits as written (we can't fail and we have multiple exit paths below so it's
1874         // convenient to update our counter here).
1875         m_cBitsWritten += cBits;
1876
1877         // We cache up to a DWORD of data to be written to the stream and only write back to the buffer when
1878         // we have a full DWORD. Calculate how many bits of the input we're going to write first (either the
1879         // rest of the input or the remaining bits of space in the current DWORD cache, whichever is smaller).
1880         DWORD cInitialBits = min(cBits, kBitsPerDWORD - m_cCurrentBits);
1881         if (cInitialBits == kBitsPerDWORD)
1882         {
1883             // Deal with this special case (we're writing all the input, an entire DWORD all at once) since it
1884             // ensures that none of the << operations below have to deal with a LHS that == 32 (see the <<
1885             // comment in one of the asserts above for why this matters).
1886
1887             // Because of the calculations above we should only come here if our DWORD cache was empty and the
1888             // caller is trying to write a full DWORD (which simplifies many things).
1889             _ASSERTE(m_dwCurrent == 0 && m_cCurrentBits == 0 && cBits == kBitsPerDWORD);
1890
1891             *m_pNext++ = dwData;    // Write a full DWORD directly from the input
1892
1893             // That's it, there's no more data to write and the only state update to the write was advancing
1894             // the buffer pointer (cache DWORD is already in the correct state, see asserts above).
1895             return;
1896         }
1897
1898         // Calculate a mask of the low-order bits we're going to extract from the input data.
1899         DWORD dwInitialMask = (1U << cInitialBits) - 1;
1900
1901         // OR those bits into the cache (properly shifted to fit above the data already there).
1902         m_dwCurrent |= (dwData & dwInitialMask) << m_cCurrentBits;
1903
1904         // Update the cache bit counter for the new data.
1905         m_cCurrentBits += cInitialBits;
1906         if (m_cCurrentBits == kBitsPerDWORD)
1907         {
1908             // The cache filled up. Write the DWORD to the buffer and reset the cache state to empty.
1909             *m_pNext++ = m_dwCurrent;
1910             m_dwCurrent = 0;
1911             m_cCurrentBits = 0;
1912         }
1913
1914         // If the bits we just inserted comprised all the input bits we're done.
1915         if (cInitialBits == cBits)
1916             return;
1917
1918         // There's more data to write. But we can only get here if we just flushed the cache. So there is a
1919         // whole DWORD free in the cache and we're guaranteed to have less than a DWORD of data left to write.
1920         // As a result we can simply populate the low-order bits of the cache with our remaining data (simply
1921         // shift down by the number of bits we've already written) and we're done.
1922         _ASSERTE(m_dwCurrent == 0 && m_cCurrentBits == 0);
1923         m_dwCurrent = dwData >>= cInitialBits;
1924         m_cCurrentBits = cBits - cInitialBits;
1925     }
1926
1927     // Because we cache a DWORD of data before writing it it's possible that there are still unwritten bits
1928     // left in the cache once you've finished writing data. Call this operation after all Writes() are
1929     // completed to flush any such data to memory. It's not legal to call Write() again after a Flush().
1930     void Flush()
1931     {
1932         LIMITED_METHOD_CONTRACT;
1933
1934         // Nothing to do if the cache is empty.
1935         if (m_cCurrentBits == 0)
1936             return;
1937
1938         // Write what we have to memory (unused high-order bits will be zero).
1939         *m_pNext = m_dwCurrent;
1940
1941         // Catch any attempt to make a further Write() call.
1942         m_pNext = NULL;
1943     }
1944
1945     // Get the count of bits written so far (logically, this number does not take caching into account).
1946     DWORD GetBitsWritten()
1947     {
1948         LIMITED_METHOD_CONTRACT;
1949
1950         return m_cBitsWritten;
1951     }
1952
1953 private:
1954     enum { kBitsPerDWORD = sizeof(DWORD) * 8 };
1955
1956     DWORD  *m_pNext;        // Pointer to the next DWORD that will be written in the buffer
1957     DWORD   m_dwCurrent;    // We cache up to a DWORD of data before writing it to the buffer
1958     DWORD   m_cCurrentBits; // Count of valid (low-order) bits in the buffer above
1959     DWORD   m_cBitsWritten; // Count of bits given to Write() (ignores caching)
1960 };
1961
1962 // A specialized node used to write the compressed portions of a LookupMap to an ngen image. This is
1963 // (optionally) allocated by a call to DataImage::StoreCompressedLayoutMap from LookupMapBase::Save() and
1964 // handles allocation and initialization of the compressed table and an index used to navigate the table
1965 // efficiently. The allocation of the map itself and any hot item list is still handled externally but this
1966 // node will perform any fixups in the base map required to refer to the new compressed data.
1967 //
1968 // Since the compression algorithm used depends on the precise values of the RVAs referenced by the LookupMap
1969 // the compression doesn't happen until ComputeRVA is called (don't call GetSize() until after ComputeRVA()
1970 // returns). Additionally we must ensure that this node's ComputeRVA() is not called until after that of every
1971 // node on those RVA it depends. Currently this is ensured by placing this node near the end of the .text
1972 // section (after pointers to any read-only data structures referenced by LookupMaps and after the .data
1973 // section containing writeable structures).
1974 class ZapCompressedLookupMap : public ZapNode
1975 {
1976     DataImage      *m_pImage;                                       // Back pointer to the allocating DataImage
1977     LookupMapBase  *m_pMap;                                         // Back pointer to the LookupMap we're compressing
1978     BYTE           *m_pTable;                                       // ComputeRVA allocates a compressed table here
1979     BYTE           *m_pIndex;                                       // ComputeRVA allocates a table index here
1980     DWORD           m_cbTable;                                      // Size (in bytes) of the table above (after ComputeRVA)
1981     DWORD           m_cbIndex;                                      // Size (in bytes) of the index above (after ComputeRVA)
1982     DWORD           m_cBitsPerIndexEntry;                           // Number of bits in each index entry
1983     DWORD           m_rgHistogram[kBitsPerRVA];                     // Table of frequencies of different delta lengths
1984     BYTE            m_rgEncodingLengths[kLookupMapLengthEntries];   // Table of different bit lengths value deltas can take
1985     BYTE            m_eKind;                                        // Item kind (DataImage::ITEM_COMPRESSED_MAP currently)
1986
1987 public:
1988     ZapCompressedLookupMap(DataImage *pImage, LookupMapBase *pMap, BYTE eKind)
1989         : m_pImage(pImage), m_pMap(pMap), m_eKind(eKind)
1990     {
1991         LIMITED_METHOD_CONTRACT;
1992     }
1993
1994     DataImage::ItemKind GetKind()
1995     {
1996         LIMITED_METHOD_CONTRACT;
1997
1998         return (DataImage::ItemKind)m_eKind;
1999     }
2000
2001     virtual DWORD GetSize()
2002     {
2003         LIMITED_METHOD_CONTRACT;
2004
2005         if (!ShouldCompressedMapBeSaved())
2006             return 0;
2007
2008         // This isn't legal until ComputeRVA() is called. Check this by seeing if the compressed version of
2009         // the table is allocated yet.
2010         _ASSERTE(m_pTable != NULL);
2011         return m_cbIndex + m_cbTable;
2012     }
2013
2014     virtual UINT GetAlignment()
2015     {
2016         LIMITED_METHOD_CONTRACT;
2017
2018         if (!ShouldCompressedMapBeSaved())
2019             return 1;
2020
2021         // The table and index have no pointers but do require DWORD alignment.
2022         return sizeof(DWORD);
2023     }
2024
2025     virtual ZapNodeType GetType()
2026     {
2027         STANDARD_VM_CONTRACT;
2028
2029         return NodeTypeForItemKind(m_eKind);
2030     }
2031
2032     virtual DWORD ComputeRVA(ZapWriter *pZapWriter, DWORD dwPos)
2033     {
2034         STANDARD_VM_CONTRACT;
2035
2036         if (ShouldCompressedMapBeSaved())
2037         {
2038
2039             // This is the earliest opportunity at which all data is available in order to compress the table. In
2040             // particular all values in the table (currently MethodTable* or MethodDesc*) point to structures
2041             // which have been assigned final RVAs in the image. We can thus compute a compressed table value that
2042             // relies on the relationship between these RVAs.
2043
2044             // Phase 1: Look through all the entries in the table. Look at the deltas between RVAs for adjacent
2045             // items and build a histogram of how many entries require a specific number to encode their delta
2046             // (using a scheme we we discard non-significant low and high-order zero bits). This call will
2047             // initialize m_rgHistogram so that entry 0 contains the number of entries that require 1 bit to
2048             // encode their delta, entry 1 the count of those that require 2 bits etc. up to the last entry (how
2049             // many entries require the full 32 bits). Note that even on 64-bit platforms we only currently
2050             // support 32-bit RVAs.
2051             DWORD cRids = AnalyzeTable();
2052
2053             // Phase 2: Given the histogram above, calculate the set of delta lengths for the encoding table
2054             // (m_rgEncodingLengths) that will result in optimal table size. We have a fixed size encoding length
2055             // so we don't have to embed a large fixed-size length field for every compressed entry but we can
2056             // still cope with the relatively rare but ever-present worst case entries which require many bits of
2057             // delta entry.
2058             OptimizeEncodingLengths();
2059
2060             // Phase 3: We now have enough data to allocate the final data structures (the compressed table itself
2061             // and an index that bookmarks every kLookupMapIndexStride'th entry). Both structures must start
2062             // DWORD-aligned and have a DWORD-aligned size (requirements of BitStreamWriter).
2063
2064             // PredictCompressedSize() returns its result in bits so we must convert (rounding up) to bytes before
2065             // DWORD aligning.
2066             m_cbTable = AlignUp((PredictCompressedSize(m_rgEncodingLengths) + 7) / 8, sizeof(DWORD));
2067
2068             // Each index entry contains a bit offset into the compressed stream (so we must size for the worst
2069             // case of an offset at the end of the stream) plus an RVA.
2070             m_cBitsPerIndexEntry = BitsRequired(m_cbTable * 8) + kBitsPerRVA;
2071             _ASSERTE(m_cBitsPerIndexEntry > 0);
2072
2073             // Our first index entry is for entry 0 (rather than entry kLookupMapIndexStride) so we must be
2074             // sure to round up the number of index entries we need in order to cover the table.
2075             DWORD cIndexEntries = (cRids + (kLookupMapIndexStride - 1)) / kLookupMapIndexStride;
2076
2077             // Since we calculate the index size in bits we need to round up to bytes before DWORD aligning.
2078             m_cbIndex = AlignUp(((m_cBitsPerIndexEntry * cIndexEntries) + 7) / 8, sizeof(DWORD));
2079
2080             // Allocate both table and index from a single chunk of memory.
2081             BYTE *pMemory = new BYTE[m_cbIndex + m_cbTable];
2082             m_pTable = pMemory;
2083             m_pIndex = pMemory + m_cbTable;
2084
2085             // Phase 4: We've now calculated all the input data we need and allocated memory for the output so we
2086             // can go ahead and fill in the compressed table and index.
2087             InitializeTableAndIndex();
2088
2089             // Phase 5: Go back up update the saved version of the LookupMap (redirect the table pointer to the
2090             // compressed table and fill in the other fields which aren't valid until the table is compressed).
2091             LookupMapBase *pSaveMap = (LookupMapBase*)m_pImage->GetImagePointer(m_pMap);
2092             pSaveMap->pTable = (TADDR*)m_pTable;
2093             pSaveMap->pIndex = m_pIndex;
2094             pSaveMap->cIndexEntryBits = m_cBitsPerIndexEntry;
2095             pSaveMap->cbTable = m_cbTable;
2096             pSaveMap->cbIndex = m_cbIndex;
2097             memcpy(pSaveMap->rgEncodingLengths, m_rgEncodingLengths, sizeof(m_rgEncodingLengths));
2098
2099             // Schedule fixups for the map pointers to the compressed table and index.
2100             m_pImage->FixupFieldToNode(m_pMap, offsetof(LookupMapBase, pTable), this, 0);
2101             m_pImage->FixupFieldToNode(m_pMap, offsetof(LookupMapBase, pIndex), this, m_cbTable);
2102         }
2103
2104         // We're done with generating the compressed table. Now we need to do the work ComputeRVA() is meant
2105         // to do:
2106         dwPos = AlignUp(dwPos, GetAlignment()); // Satisfy our alignment requirements
2107         SetRVA(dwPos);                          // Set the RVA of the node (both table and index)
2108         dwPos += GetSize();                     // Advance the RVA past our node
2109
2110         return dwPos;                       
2111     }
2112
2113     virtual void Save(ZapWriter *pZapWriter)
2114     {
2115         STANDARD_VM_CONTRACT;
2116
2117         if (!ShouldCompressedMapBeSaved())
2118             return;
2119
2120         // Save both the table and index.
2121         pZapWriter->Write(m_pTable, m_cbTable);
2122         pZapWriter->Write(m_pIndex, m_cbIndex);
2123     }
2124
2125 private:
2126
2127     // It's possible that our node has been created and only later the decision is made to store the full 
2128     // uncompressed table.  In this case, we want to early out of our work and make saving our node a no-op.
2129     BOOL ShouldCompressedMapBeSaved()
2130     {
2131         LIMITED_METHOD_CONTRACT;
2132
2133         // To identify whether compression is desired, use the flag from LookupMapBase::Save
2134         return (m_pMap->cIndexEntryBits > 0);
2135     }
2136
2137     // Phase 1: Look through all the entries in the table. Look at the deltas between RVAs for adjacent items
2138     // and build a histogram of how many entries require a specific number to encode their delta (using a
2139     // scheme we we discard non-significant low and high-order zero bits). This call will initialize
2140     // m_rgHistogram so that entry 0 contains the number of entries that require 1 bit to encode their delta,
2141     // entry 1 the count of those that require 2 bits etc. up to the last entry (how many entries require the
2142     // full 32 bits). Note that even on 64-bit platforms we only currently support 32-bit RVAs.
2143     DWORD AnalyzeTable()
2144     {
2145         STANDARD_VM_CONTRACT;
2146
2147         LookupMapBase *pMap = m_pMap;
2148         DWORD dwLastValue = 0;
2149         DWORD cRids = 0;
2150
2151         // Initialize the histogram to all zeroes.
2152         memset(m_rgHistogram, 0, sizeof(m_rgHistogram));
2153
2154         // Walk each node in the map.
2155         while (pMap)
2156         {
2157             // Walk each entry in this node.
2158             for (DWORD i = 0; i < pMap->dwCount; i++)
2159             {
2160                 DWORD dwCurrentValue = ComputeElementRVA(pMap, i);
2161
2162                 // Calculate the delta from the last entry. We split the delta into two-components: a bool
2163                 // indicating whether the RVA was higher or lower and an absolute (non-negative) size. Sort of
2164                 // like a ones-complement signed number.
2165                 bool fIncreasingDelta = dwCurrentValue > dwLastValue;
2166                 DWORD dwDelta = fIncreasingDelta ? (dwCurrentValue - dwLastValue) : (dwLastValue - dwCurrentValue);
2167
2168                 // Determine the minimum number of bits required to represent the delta (by stripping
2169                 // non-significant leading zeros) and update the count in the histogram of the number of
2170                 // deltas that required this many bits. We never encode anything with zero bits (only the
2171                 // value zero would be eligibil and it's not a common value) so the first histogram entry
2172                 // records the number of deltas encodable with one bit and so on.
2173                 m_rgHistogram[BitsRequired(dwDelta) - 1]++;
2174
2175                 dwLastValue = dwCurrentValue;
2176                 cRids++;
2177             }
2178
2179             pMap = pMap->pNext;
2180         }
2181
2182         return cRids;
2183     }
2184
2185     // Phase 2: Given the histogram above, calculate the set of delta lengths for the encoding table
2186     // (m_rgEncodingLengths) that will result in optimal table size. We have a fixed size encoding length so
2187     // we don't have to embed a large fixed-size length field for every compressed entry but we can still cope
2188     // with the relatively rare but ever-present worst case entries which require many bits of delta entry.
2189     void OptimizeEncodingLengths()
2190     {
2191         STANDARD_VM_CONTRACT;
2192
2193         // Find the longest delta (search from the large end of the histogram down for the first non-zero
2194         // entry).
2195         BYTE bMaxBits = 0;
2196 #ifdef _MSC_VER
2197 #pragma warning(suppress:6293) // Prefast doesn't understand the unsigned modulo-8 arithmetic below.
2198 #endif
2199         for (BYTE i = kBitsPerRVA - 1; i < 0xff; i--)
2200             if (m_rgHistogram[i] > 0)
2201             {
2202                 bMaxBits = i + 1;  // +1 because we never encode anything with zero bits.
2203                 break;
2204             }
2205         _ASSERTE(bMaxBits >= 1);
2206
2207         // Now find the smallest delta in a similar fashion.
2208         BYTE bMinBits = bMaxBits;
2209         for (BYTE i = 0; i < kBitsPerRVA; i++)
2210             if (m_rgHistogram[i] > 0)
2211             {
2212                 bMinBits = i + 1;  // +1 because we never encode anything with zero bits.
2213                 break;
2214             }
2215         _ASSERTE(bMinBits <= bMaxBits);
2216
2217         // The encoding lengths table is a sorted list of bit field lengths we can use to encode any
2218         // entry-to-entry delta in the compressed table. We go through a table so we can use a small number of
2219         // bits in the compressed stream (the table index) to express a very flexible range of deltas. The one
2220         // entry we know in advance is the largest (the last). That's because we know we have to be able to
2221         // encode the largest delta we found in the table or else we couldn't be functionally correct.
2222         m_rgEncodingLengths[kLookupMapLengthEntries - 1] = bMaxBits;
2223
2224         // Now find optimal values for the other entries one by one. It doesn't really matter which order we
2225         // do them in. For each entry we'll loop through all the possible encoding lengths, dwMinBits <=
2226         // length < dwMaxBits, setting all the uninitialized entries to the candidate value and calculating
2227         // the resulting compressed size of the table. We don't enforce that the candidate sizes get smaller
2228         // for each entry so in that if the best use of an extra table entry is to add a larger length rather
2229         // than a smaller one then we'll take that. The downside is that we have to sort the table before
2230         // calculating the table size (the sizing algorithm is only fast for a sorted table). Luckily our
2231         // table is very small (currently 4 entries) and we don't have to sort one of the entries (the last is
2232         // always largest) so this isn't such a huge deal.
2233         for (DWORD i = 0; i < kLookupMapLengthEntries - 1; i++)
2234         {
2235             DWORD dwBestSize = 0xffffffff;  // Best overall table size so far
2236             BYTE bBestLength = bMaxBits; // The candidate value that lead to the above
2237
2238             // Iterate over all the values that could generate a good result (no point trying values smaller
2239             // than the smallest delta we have or as large as the maximum table entry we've already fixed).
2240             for (BYTE j = bMinBits; j < bMaxBits; j++)
2241             {
2242                 // Build a temporary (unsorted) encoding table.
2243                 BYTE rgTempBuckets[kLookupMapLengthEntries];
2244
2245                 // Entries before the current one are set to the values we've already determined in previous
2246                 // iterations.
2247                 for (DWORD k = 0; k < i; k++)
2248                     rgTempBuckets[k] = m_rgEncodingLengths[k];
2249
2250                 // The current entry and the remaining uninitialized entries are all set to the current
2251                 // candidate value (this is logically the equivalent of removing the non-current uninitialized
2252                 // entries from the table altogether).
2253                 for (DWORD k = i; k < kLookupMapLengthEntries - 1; k++)
2254                     rgTempBuckets[k] = j;
2255
2256                 // The last entry is always the maximum bit length.
2257                 rgTempBuckets[kLookupMapLengthEntries - 1] = bMaxBits;
2258
2259                 // Sort the temporary table so that the call to PredictCompressedSize() below behaves
2260                 // correctly (and fast).
2261                 SortLengthBuckets(rgTempBuckets);
2262
2263                 // See what size of table this would generate.
2264                 DWORD dwTestSize = PredictCompressedSize(rgTempBuckets);
2265                 if (dwTestSize < dwBestSize)
2266                 {
2267                     // The result is better than our current best, remember it.
2268                     dwBestSize = dwTestSize;
2269                     bBestLength = j;
2270                 }
2271             }
2272
2273             // Set the current entry to the best length we found.
2274             m_rgEncodingLengths[i] = bBestLength;
2275         }
2276
2277         // We've picked optimal values for all entries, but the result is unsorted. Fix that now.
2278         SortLengthBuckets(m_rgEncodingLengths);
2279     }
2280
2281     // Phase 4: We've now calculated all the input data we need and allocated memory for the output so we can
2282     // go ahead and fill in the compressed table and index.
2283     void InitializeTableAndIndex()
2284     {
2285         STANDARD_VM_CONTRACT;
2286
2287         // Initialize bit stream writers to the start of the compressed table and index.
2288         BitStreamWriter sTableStream((DWORD*)m_pTable);
2289         BitStreamWriter sIndexStream((DWORD*)m_pIndex);
2290
2291         DWORD dwRid = 0;
2292         DWORD dwLastValue = 0;
2293         LookupMapBase *pMap = m_pMap;
2294
2295         // Walk each node in the map.
2296         while (pMap)
2297         {
2298             // Walk each entry in this node.
2299             for (DWORD i = 0; i < pMap->dwCount; i++)
2300             {
2301                 DWORD dwCurrentValue = ComputeElementRVA(pMap, i);
2302
2303                 // Calculate the delta from the last entry. We split the delta into two-components: a bool
2304                 // indicating whether the RVA was higher or lower and an absolute (non-negative) size. Sort of
2305                 // like a ones-complement signed number.
2306                 bool fIncreasingDelta = dwCurrentValue > dwLastValue;
2307                 DWORD dwDelta = fIncreasingDelta ? (dwCurrentValue - dwLastValue) : (dwLastValue - dwCurrentValue);
2308
2309                 // As a trade-off we can't store deltas with their most efficient length (because just
2310                 // encoding the length can dominate the space requirement when we have to cope with worst-case
2311                 // deltas). Instead we encode a relatively short index into the table of encoding lengths we
2312                 // calculated back in phase 2. So some deltas will encode in more bits than necessary but
2313                 // overall we'll win due to lowered prefix bit requirements.
2314                 // Look through all the table entries and choose the first that's large enough to accomodate
2315                 // our delta.
2316                 DWORD dwDeltaBitLength = BitsRequired(dwDelta);
2317                 DWORD j;
2318                 for (j = 0; j < kLookupMapLengthEntries; j++)
2319                 {
2320                     if (m_rgEncodingLengths[j] >= dwDeltaBitLength)
2321                     {
2322                         dwDeltaBitLength = m_rgEncodingLengths[j];
2323                         break;
2324                     }
2325                 }
2326                 _ASSERTE(j < kLookupMapLengthEntries);
2327
2328                 // Write the entry into the compressed table.
2329                 sTableStream.Write(j, kLookupMapLengthBits);        // The index for the delta length
2330                 sTableStream.Write(fIncreasingDelta ? 1 : 0, 1);    // The +/- delta indicator
2331                 sTableStream.Write(dwDelta, dwDeltaBitLength);      // The delta itself
2332
2333                 // Is this entry one that requires a corresponding index entry?
2334                 if ((dwRid % kLookupMapIndexStride) == 0)
2335                 {
2336                     // Write an index entry:
2337                     //  * The current (map-relative) RVA.
2338                     //  * The position in the table bit stream of the next entry.
2339                     sIndexStream.Write(dwCurrentValue, kBitsPerRVA);    
2340                     sIndexStream.Write(sTableStream.GetBitsWritten(), m_cBitsPerIndexEntry - kBitsPerRVA);
2341                 }
2342
2343                 dwRid++;
2344
2345                 dwLastValue = dwCurrentValue;
2346             }
2347
2348             pMap = pMap->pNext;
2349         }
2350
2351         // Flush any remaining bits in the caches of the table and index stream writers.
2352         sTableStream.Flush();
2353         sIndexStream.Flush();
2354
2355         // Make sure what we wrote fitted in what we allocated.
2356         _ASSERTE((sTableStream.GetBitsWritten() / 8) <= m_cbTable);
2357         _ASSERTE((sIndexStream.GetBitsWritten() / 8) <= m_cbIndex);
2358
2359         // Also check that we didn't have more than 31 bits of excess space allocated either (we should have
2360         // allocated DWORD aligned lengths).
2361         _ASSERTE(((m_cbTable * 8) - sTableStream.GetBitsWritten()) < 32);
2362         _ASSERTE(((m_cbIndex * 8) - sIndexStream.GetBitsWritten()) < 32);
2363     }
2364
2365     // Determine the final, map-relative RVA of the element at a specified index
2366     DWORD ComputeElementRVA(LookupMapBase *pMap, DWORD index)
2367     {
2368         STANDARD_VM_CONTRACT;
2369
2370         // We base our RVAs on the RVA of the map (rather than the module). This is purely because individual
2371         // maps don't store back pointers to their owning module so it's easier to recover pointer values at
2372         // runtime using the map address instead.
2373         DWORD rvaBase = m_pImage->GetRVA(m_pMap);
2374
2375         // Retrieve the pointer value in the specified entry. This is tricky since the pointer is
2376         // encoded as a RelativePointer.
2377         DWORD dwFinalRVA;
2378         TADDR entry = RelativePointer<TADDR>::GetValueMaybeNullAtPtr((TADDR)&pMap->pTable[index]);
2379         if (entry == 0)
2380         {
2381             // The pointer was null. We encode this as a zero RVA (RVA pointing to the map itself,
2382             // which should never happen otherwise).
2383             dwFinalRVA = 0;
2384         }
2385         else
2386         {
2387             // Non-null pointer, go get the RVA it's been mapped to. Transform this RVA into our
2388             // special map-relative variant by substracting the map base.
2389
2390             // Some of the pointer alignment bits may have been used as flags; preserve them.
2391             DWORD flags = entry & ((1 << kFlagBits) - 1);
2392             entry -= flags;
2393
2394             // We only support compressing maps of pointers to saved objects (e.g. no indirected FixupPointers)
2395             // so there is guaranteed to be a valid RVA at this point.  If this does not hold, GetRVA will assert.
2396             DWORD rvaEntry = m_pImage->GetRVA((void*)entry);
2397
2398             dwFinalRVA = rvaEntry - rvaBase + flags;
2399         }
2400
2401         return dwFinalRVA;
2402     }
2403
2404     // Determine the number of bits required to represent the significant portion of a value (i.e. the value
2405     // without any leading 0s). Always return 1 as a minimum (we do not encode 0 in 0 bits).
2406     DWORD BitsRequired(DWORD dwValue)
2407     {
2408         LIMITED_METHOD_CONTRACT;
2409
2410 #if (defined(_TARGET_X86_) || defined(_TARGET_AMD64_)) && defined(_MSC_VER)
2411
2412         // This this operation could impact the performance of ngen (we call this a *lot*) we'll try and
2413         // optimize this where we can. x86 and amd64 actually have instructions to find the least and most
2414         // significant bits in a DWORD and MSVC exposes this as a builtin.
2415         DWORD dwHighBit;
2416         if (_BitScanReverse(&dwHighBit, dwValue))
2417             return dwHighBit + 1;
2418         else
2419             return 1;
2420
2421 #else // (_TARGET_X86_ || _TARGET_AMD64_) && _MSC_VER
2422
2423         // Otherwise we'll calculate this the slow way. Pick off the 32-bit case first due to avoid the
2424         // usual << problem (x << 32 == x, not 0).
2425         if (dwValue > 0x7fffffff)
2426             return 32;
2427
2428         DWORD cBits = 1;
2429         while (dwValue > ((1U << cBits) - 1))
2430             cBits++;
2431
2432         return cBits;
2433
2434 #endif // (_TARGET_X86_ || _TARGET_AMD64_) && _MSC_VER
2435     }
2436
2437     // Sort the given input array (of kLookupMapLengthEntries entries, where the last entry is already sorted)
2438     // from lowest to highest value.
2439     void SortLengthBuckets(BYTE rgBuckets[])
2440     {
2441         LIMITED_METHOD_CONTRACT;
2442
2443         // This simplistic insertion sort algorithm is probably the fastest for small values of
2444         // kLookupMapLengthEntries.
2445         _ASSERTE(kLookupMapLengthEntries < 10);
2446
2447         // Iterate over every entry apart from the last two, moving the correct sorted value into each in
2448         // turn. Don't do the last value because it's already sorted and the second last because it'll be
2449         // sorted by the time we've done all the rest.
2450         for (DWORD i = 0; i < (kLookupMapLengthEntries - 2); i++)
2451         {
2452             BYTE bLowValue = rgBuckets[i];    // The lowest value we've seen so far
2453             DWORD dwLowIndex = i;               // The index which held that value
2454
2455             // Look through the unsorted entries for the smallest.
2456             for (DWORD j = i + 1; j < (kLookupMapLengthEntries - 1); j++)
2457             {
2458                 if (rgBuckets[j] < bLowValue)
2459                 {
2460                     // Got a bette candidate for smallest.
2461                     bLowValue = rgBuckets[j];
2462                     dwLowIndex = j;
2463                 }
2464             }
2465
2466             // If the original value at the current index wasn't the smallest, swap it with the one that was.
2467             if (dwLowIndex != i)
2468             {
2469                 rgBuckets[dwLowIndex] = rgBuckets[i];
2470                 rgBuckets[i] = bLowValue;
2471             }
2472         }
2473
2474 #ifdef _DEBUG
2475         // Check the table really is sorted.
2476         for (DWORD i = 1; i < kLookupMapLengthEntries; i++)
2477             _ASSERTE(rgBuckets[i] >= rgBuckets[i - 1]);
2478 #endif // _DEBUG        
2479     }
2480
2481     // Given the histogram of the delta lengths and a prospective table of the subset of those lengths that
2482     // we'd utilize to encode the table, return the size (in bits) of the compressed table we'd get as a
2483     // result. The algorithm requires that the encoding length table is sorted (smallest to largest length).
2484     DWORD PredictCompressedSize(BYTE rgBuckets[])
2485     {
2486         LIMITED_METHOD_CONTRACT;
2487
2488         DWORD cTotalBits = 0;
2489
2490         // Iterate over each entry in the histogram (first entry is the number of deltas that can be encoded
2491         // in 1 bit, the second is the number of entries encodable in 2 bits etc.).
2492         for (DWORD i = 0; i < kBitsPerRVA; i++)
2493         {
2494             // Start by assuming that we can encode entries in this bucket with their exact length.
2495             DWORD cBits = i + 1;
2496
2497             // Look through the encoding table to find the first (lowest) encoding length that can encode the
2498             // values for this bucket.
2499             for (DWORD j = 0; j < kLookupMapLengthEntries; j++)
2500             {
2501                 if (cBits <= rgBuckets[j])
2502                 {
2503                     // This is the best encoding we can do. Remember the real cost of all entries in this
2504                     // histogram bucket.
2505                     cBits = rgBuckets[j];
2506                     break;
2507                 }
2508             }
2509
2510             // Each entry for this histogram bucket costs a fixed size index into the encoding length table
2511             // (kLookupMapLengthBits), a single bit of delta sign plus the number of bits of delta magnitude
2512             // that we calculated above.
2513             cTotalBits += (kLookupMapLengthBits + 1 + cBits) * m_rgHistogram[i];
2514         }
2515
2516         return cTotalBits;
2517     }
2518 };
2519
2520 // Allocate a special zap node that will compress the cold rid map associated with the given LookupMap.
2521 void DataImage::StoreCompressedLayoutMap(LookupMapBase *pMap, ItemKind kind)
2522 {
2523     STANDARD_VM_CONTRACT;
2524
2525     ZapNode *pNode = new (GetHeap()) ZapCompressedLookupMap(this, pMap, static_cast<BYTE>(kind));
2526
2527     AddStructureInOrder(pNode);
2528 }
2529
2530 #endif // FEATURE_PREJIT