JIT: Fix bug in finally cloning caused by unsound callfinally reordering
[platform/upstream/coreclr.git] / src / zap / zapinfo.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 // ZapInfo.cpp
6 //
7
8 //
9 // JIT-EE interface for zapping
10 // 
11 // ======================================================================================
12
13 #include "common.h"
14
15 #include "zapcode.h"
16 #include "zapimport.h"
17 #include "zapwrapper.h"
18 #include "zapinnerptr.h"
19 #include "zapmetadata.h"
20
21 #ifdef FEATURE_READYTORUN_COMPILER
22 #include "zapreadytorun.h"
23 #endif
24
25 ZapInfo::ZapInfo(ZapImage * pImage, mdMethodDef md, CORINFO_METHOD_HANDLE handle, CORINFO_MODULE_HANDLE module, unsigned methodProfilingDataFlags)
26     : m_pImage(pImage),
27     m_currentMethodToken(md),
28     m_currentMethodHandle(handle),
29     m_currentMethodModule(module),
30     m_currentMethodProfilingDataFlags(methodProfilingDataFlags),
31
32     m_pNativeVarInfo(NULL),
33     m_iNativeVarInfo(0),
34     m_pOffsetMapping(NULL),
35     m_iOffsetMapping(0),
36     m_pGCInfo(NULL),
37     m_cbGCInfo(0),
38     m_pCode(NULL),
39     m_pColdCode(NULL),
40     m_pROData(NULL),
41 #ifdef WIN64EXCEPTIONS
42     // Unwind info of the main method body. It will get merged with GC info.
43     m_pMainUnwindInfo(NULL),
44     m_cbMainUnwindInfo(0),
45
46     m_pUnwindInfo(NULL),
47     m_pUnwindInfoFragments(NULL),
48 #if defined(_TARGET_AMD64_)
49     m_pChainedColdUnwindInfo(NULL),
50 #endif
51 #endif // WIN64EXCEPTIONS
52     m_pExceptionInfo(NULL),
53     m_pProfileData(NULL),
54     m_pProfilingHandle(NULL),
55
56     m_ClassLoadTable(pImage),
57     m_MethodLoadTable(pImage)
58 {
59     m_zapper = m_pImage->m_zapper;
60
61     m_pEEJitInfo = m_zapper->m_pEEJitInfo;
62     m_pEEJitInfo->setOverride(this, handle);
63
64     m_pEECompileInfo = m_zapper->m_pEECompileInfo;
65 }
66
67 ZapInfo::~ZapInfo()
68 {
69     m_pEEJitInfo->setOverride(NULL, NULL);
70
71     delete [] m_pNativeVarInfo;
72     delete [] m_pOffsetMapping;
73
74     delete [] m_pGCInfo;
75 #ifdef WIN64EXCEPTIONS
76     delete [] m_pMainUnwindInfo;
77 #endif
78 }
79
80 #ifdef ALLOW_SXS_JIT_NGEN
81 // The AltJit failed and we're going to retry. Forget everything the JIT told us and prepare to JIT again.
82 void ZapInfo::ResetForJitRetry()
83 {
84     delete [] m_pNativeVarInfo;
85     m_pNativeVarInfo = NULL;
86
87     m_iNativeVarInfo = 0;
88
89     delete [] m_pOffsetMapping;
90     m_pOffsetMapping = NULL;
91
92     m_iOffsetMapping = 0;
93
94     delete [] m_pGCInfo;
95     m_pGCInfo = NULL;
96
97     m_cbGCInfo = 0;
98
99 #ifdef WIN64EXCEPTIONS
100     delete [] m_pMainUnwindInfo;
101     m_pMainUnwindInfo = NULL;
102
103     m_cbMainUnwindInfo = 0;
104 #endif // WIN64EXCEPTIONS
105
106     // The rest of these pointers are in the ZapWriter's ZapHeap, and will go away when the ZapWriter
107     // goes away. That's ok for altjit fallback; we'll use extra memory until the ZapWriter goes away,
108     // but we won't write anything to the image. We just zero out the pointers and constants, and we're good.
109
110     m_pCode = NULL;
111     m_pColdCode = NULL;
112     m_pROData = NULL;
113
114 #ifdef WIN64EXCEPTIONS
115     m_pUnwindInfoFragments = NULL;
116     m_pUnwindInfo = NULL;
117 #if defined(_TARGET_AMD64_)
118     m_pChainedColdUnwindInfo = NULL;
119 #endif
120 #endif // WIN64EXCEPTIONS
121
122     m_pExceptionInfo = NULL;
123     m_pProfileData = NULL;
124     m_pProfilingHandle = NULL;
125
126     m_ImportSet.RemoveAll();
127     m_Imports.Clear();
128     m_CodeRelocations.Clear();
129 }
130 #endif // ALLOW_SXS_JIT_NGEN
131
132 void ZapInfo::InitMethodName()
133 {
134     const char* szClsName;
135     const char* szMethodName = m_pEEJitInfo->getMethodName(
136                                         m_currentMethodHandle,
137                                         &szClsName);
138
139     m_currentMethodName.SetUTF8(szClsName);
140     m_currentMethodName.AppendUTF8(NAMESPACE_SEPARATOR_STR);
141     m_currentMethodName.AppendUTF8(szMethodName);
142 }
143
144 CORJIT_FLAGS ZapInfo::ComputeJitFlags(CORINFO_METHOD_HANDLE handle)
145 {
146     CORJIT_FLAGS jitFlags = m_zapper->m_pOpt->m_compilerFlags;
147
148     CORJIT_FLAGS flags;
149     IfFailThrow(m_pEECompileInfo->GetBaseJitFlags(handle, &flags));
150     jitFlags.Add(flags);
151
152     // COMPlus_JitFramed specifies the default fpo setting for jitted and NGened code.
153     // You can override the behavior for NGened code using COMPlus_NGenFramed.
154     static ConfigDWORD g_NGenFramed;
155     DWORD dwNGenFramed = g_NGenFramed.val(CLRConfig::UNSUPPORTED_NGenFramed);
156     if (dwNGenFramed == 0) 
157     {
158         // NGened code should enable fpo
159         jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_FRAMED);
160     } 
161     else if (dwNGenFramed == 1) 
162     {
163         // NGened code should disable fpo
164         jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_FRAMED);
165     }
166
167     if (canSkipMethodVerification(m_currentMethodHandle) == CORINFO_VERIFICATION_CAN_SKIP)
168     {
169         jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION);
170     }
171
172     if (m_pImage->m_profileDataSections[MethodBlockCounts].pData && 
173         !m_zapper->m_pOpt->m_ignoreProfileData)
174     {
175         jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_BBOPT);
176     }
177
178     // 
179     // By default we always enable Hot/Cold procedure splitting
180     //
181     jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROCSPLIT);
182
183     if (m_zapper->m_pOpt->m_noProcedureSplitting)
184         jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_PROCSPLIT);
185
186     //never emit inlined polls for NGen'd code.  The extra indirection is not optimal.
187     if (jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_GCPOLL_INLINE))
188     {
189         jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_GCPOLL_INLINE);
190         jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_GCPOLL_CALLS);
191     }
192
193     // If the method is specified for min-opts then turn everything off
194     if (jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MIN_OPT))
195     {
196         jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR);
197         jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_BBOPT);
198         jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_PROCSPLIT);
199     }
200
201     // Rejit is now enabled by default for NGEN'ed code. This costs us
202     // some size in exchange for diagnostic functionality, but we've got
203     // further work planned that should mitigate the size increase.
204     jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_REJIT_NOPS);
205
206 #ifdef FEATURE_READYTORUN_COMPILER
207     if (IsReadyToRunCompilation())
208         jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_READYTORUN);
209 #endif
210
211     return jitFlags;
212 }
213
214 ZapDebugInfo * ZapInfo::EmitDebugInfo()
215 {
216     if (m_iNativeVarInfo == 0 && m_iOffsetMapping == 0)
217     {
218         return NULL;
219     }
220
221     // We create a temporary buffer which is conservatily estimated to be
222     // bigger than we need. We then copy the used portion into the ngen image.
223
224     StackSBuffer debugInfoBuffer;
225     m_pEECompileInfo->CompressDebugInfo( 
226             m_pOffsetMapping, m_iOffsetMapping,
227             m_pNativeVarInfo, m_iNativeVarInfo,
228             &debugInfoBuffer);
229
230     if (IsReadyToRunCompilation())
231         return ZapBlob::NewBlob(m_pImage, &debugInfoBuffer[0], debugInfoBuffer.GetSize());
232
233     return m_pImage->m_pDebugInfoTable->GetDebugInfo(&debugInfoBuffer[0], debugInfoBuffer.GetSize());
234 }
235
236 ZapGCInfo * ZapInfo::EmitGCInfo()
237 {    
238     _ASSERTE(m_pGCInfo != NULL);
239
240 #ifdef WIN64EXCEPTIONS
241     return m_pImage->m_pGCInfoTable->GetGCInfo(m_pGCInfo, m_cbGCInfo, m_pMainUnwindInfo, m_cbMainUnwindInfo);
242 #else
243     return m_pImage->m_pGCInfoTable->GetGCInfo(m_pGCInfo, m_cbGCInfo);
244 #endif // WIN64EXCEPTIONS
245 }
246
247 ZapImport ** ZapInfo::EmitFixupList()
248 {
249     ZapImport ** pFixupList = NULL;
250
251     if (m_Imports.GetCount() != 0)
252     {
253         pFixupList = new (m_pImage->GetHeap()) ZapImport * [m_Imports.GetCount() + 1];
254         memcpy(pFixupList, &(m_Imports[0]), m_Imports.GetCount() * sizeof(ZapImport *));
255     }
256
257     return pFixupList;
258 }
259
260 // Used by qsort
261 int __cdecl ZapInfo::CompareCodeRelocation(const void * a_, const void * b_)
262 {
263     ZapInfo::CodeRelocation * a = (ZapInfo::CodeRelocation *)a_;
264     ZapInfo::CodeRelocation * b = (ZapInfo::CodeRelocation *)b_;
265
266     if (a->m_pNode != b->m_pNode)
267     {
268         return (a->m_pNode > b->m_pNode) ? 1 : -1;
269     }
270
271     return a->m_offset - b->m_offset;
272 }
273
274 void ZapInfo::EmitCodeRelocations()
275 {
276     if (m_CodeRelocations.IsEmpty())
277         return;
278
279     qsort(&m_CodeRelocations[0], m_CodeRelocations.GetCount(), sizeof(CodeRelocation), CompareCodeRelocation);
280
281     COUNT_T startIndex = 0;
282     while (startIndex < m_CodeRelocations.GetCount())
283     {
284         ZapBlobWithRelocs * pNode = m_CodeRelocations[startIndex].m_pNode;
285
286         COUNT_T endIndex = startIndex + 1;
287         for ( ; endIndex < m_CodeRelocations.GetCount(); endIndex++)
288         {
289             if (m_CodeRelocations[endIndex].m_pNode != pNode)
290                 break;
291         }
292
293         ZapReloc * pRelocs = (ZapReloc *)
294             new (m_pImage->GetHeap()) BYTE[sizeof(ZapReloc) * (endIndex - startIndex) + sizeof(ZapRelocationType)];
295
296         for (COUNT_T i = 0; i < endIndex - startIndex; i++)
297             pRelocs[i] = m_CodeRelocations[startIndex + i];
298
299         // Set sentinel
300         static_assert_no_msg(offsetof(ZapReloc, m_type) == 0);
301         *(ZapRelocationType *)(pRelocs + (endIndex - startIndex)) = IMAGE_REL_INVALID;
302
303         pNode->SetRelocs(pRelocs);
304
305         startIndex = endIndex;
306     }
307 }
308
309 void ZapInfo::ProcessReferences()
310 {
311     COUNT_T count = m_CodeRelocations.GetCount();
312     for (COUNT_T i = 0; i < count; i++)
313     {
314         CORINFO_METHOD_HANDLE hMethod = NULL;
315         CORINFO_CLASS_HANDLE hClass = NULL;
316         bool fMaybeConditionalImport = false;
317
318         ZapNode * pTarget = m_CodeRelocations[i].m_pTargetNode;
319
320         ZapNodeType type = pTarget->GetType();
321         if (type == ZapNodeType_InnerPtr)
322         {
323             pTarget = ((ZapInnerPtr *)pTarget)->GetBase();
324             type = pTarget->GetType();
325         }
326
327         switch (type)
328         {
329         case ZapNodeType_MethodEntryPoint:
330             hMethod = ((ZapMethodEntryPoint*)pTarget)->GetHandle();
331
332             if (m_pImage->m_pPreloader->DoesMethodNeedRestoringBeforePrestubIsRun(hMethod))
333             {
334                 methodMustBeLoadedBeforeCodeIsRun(hMethod);
335             }
336             break;
337
338         case ZapNodeType_Import_MethodHandle:
339         case ZapNodeType_Import_FunctionEntry:
340         case ZapNodeType_Import_IndirectPInvokeTarget:
341             hMethod = (CORINFO_METHOD_HANDLE)(((ZapImport *)pTarget)->GetHandle());
342             fMaybeConditionalImport = true;
343             break;
344         case ZapNodeType_Import_ClassHandle:
345         case ZapNodeType_Import_ClassDomainId:
346         case ZapNodeType_Import_SyncLock:
347             hClass = (CORINFO_CLASS_HANDLE)((ZapImport *)pTarget)->GetHandle();
348             fMaybeConditionalImport = true;
349             break;
350         case ZapNodeType_Import_FieldHandle:
351         case ZapNodeType_Import_StaticFieldAddress:
352             hClass = m_pEEJitInfo->getFieldClass((CORINFO_FIELD_HANDLE)(((ZapImport *)pTarget)->GetHandle()));
353             fMaybeConditionalImport = true;
354             break;
355         case ZapNodeType_Import_StringHandle:
356         case ZapNodeType_Import_ModuleHandle:
357         case ZapNodeType_Import_ModuleDomainId:
358         case ZapNodeType_Import_VarArg:
359             fMaybeConditionalImport = true;
360             break;
361
362         case ZapNodeType_MethodHandle:
363             hMethod = (CORINFO_METHOD_HANDLE)(((ZapWrapper *)pTarget)->GetHandle());
364             break;
365
366         case ZapNodeType_ExternalMethodThunk:
367         case ZapNodeType_ExternalMethodCell:
368             hMethod = (CORINFO_METHOD_HANDLE)((ZapImport*)pTarget)->GetHandle();
369             break;
370
371         default:
372             break;
373         }
374
375         if (fMaybeConditionalImport)
376         {
377             const ImportEntry * pExistingEntry = m_ImportSet.LookupPtr((ZapImport *)pTarget);
378             if (pExistingEntry != NULL && pExistingEntry->fConditional)
379             {
380                 const_cast<ImportEntry *>(pExistingEntry)->fConditional = false;
381                 m_Imports.Append((ZapImport *)pTarget);
382
383                 // 'handle' does not have to be added to CORCOMPILE_LOAD_TABLE since we adding
384                 // it to CORCOMPILE_HANDLE_TABLE
385                 if (hMethod != NULL)
386                     m_MethodLoadTable.Load(hMethod, TRUE);
387                 else
388                 if (hClass != NULL)
389                     m_ClassLoadTable.Load(hClass, TRUE);
390             }
391         }
392
393         if (hMethod != NULL)
394         {
395             m_pImage->m_pPreloader->MethodReferencedByCompiledCode(hMethod);
396         }
397     }
398 }
399
400 // Compile a method using the JIT or Module compiler, and emit fixups
401
402 void ZapInfo::CompileMethod()
403 {
404     PRECONDITION(m_zapper->m_pJitCompiler != NULL);
405
406     InitMethodName();
407
408     if (m_zapper->m_pOpt->m_verbose)
409     {
410         // The evaluation of m_currentMethodName.GetUnicode() is expensive
411         // only do it when we are truely logging
412         m_zapper->Info(W("Compiling method %s\n"), m_currentMethodName.GetUnicode());
413     }
414
415     m_currentMethodInfo = CORINFO_METHOD_INFO();
416     if (!getMethodInfo(m_currentMethodHandle, &m_currentMethodInfo))
417     {
418         return;
419     }
420
421     // Method does not have IL (e.g. an abstract method)
422     if (m_currentMethodInfo.ILCodeSize == 0)
423         return;
424
425     // During ngen we look for a hint attribute on the method that indicates
426     // the method should be preprocessed for early
427     // preparation. This normally happens automatically, but for methods that
428     // are prepared explicitly at runtime the needed
429     // information is missing from the ngen image, causing costly overheads
430     // at runtime. When the author of the method knows about
431     // this they can add the hint and reduce the perf cost at runtime.
432     m_pImage->m_pPreloader->PrePrepareMethodIfNecessary(m_currentMethodHandle);
433
434     m_jitFlags = ComputeJitFlags(m_currentMethodHandle);
435
436 #ifdef FEATURE_READYTORUN_COMPILER
437     if (IsReadyToRunCompilation())
438     {
439         // READYTORUN: FUTURE: Producedure spliting
440         m_jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_PROCSPLIT);
441
442         DWORD methodAttribs = getMethodAttribs(m_currentMethodHandle);
443         if (!(methodAttribs & CORINFO_FLG_NOSECURITYWRAP) || (methodAttribs & CORINFO_FLG_SECURITYCHECK))
444         {
445             m_zapper->Warning(W("ReadyToRun: Methods with security checks not supported\n"));
446             ThrowHR(E_NOTIMPL);
447         }
448     }
449 #endif
450
451     if (m_pImage->m_stats)
452     {
453         m_pImage->m_stats->m_methods++;
454         m_pImage->m_stats->m_ilCodeSize += m_currentMethodInfo.ILCodeSize;
455     }
456
457     CorJitResult res = CORJIT_SKIPPED;
458     
459     BYTE *pCode;
460     ULONG cCode;
461
462 #ifdef ALLOW_SXS_JIT_NGEN
463     if (m_zapper->m_alternateJit)
464     {
465         REMOVE_STACK_GUARD;
466
467         res = m_zapper->m_alternateJit->compileMethod( this,
468                                                      &m_currentMethodInfo,
469                                                      CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS,
470                                                      &pCode,
471                                                      &cCode );
472         if (FAILED(res))
473         {
474             // We will fall back to the "main" JIT on failure.
475             ResetForJitRetry();
476         }
477     }
478 #endif // ALLOW_SXS_JIT_NGEN
479
480     if (FAILED(res))
481     {
482         REMOVE_STACK_GUARD;
483
484         ICorJitCompiler * pCompiler = m_zapper->m_pJitCompiler;
485         res = pCompiler->compileMethod(this,
486                                     &m_currentMethodInfo,
487                                     CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS,
488                                     &pCode,
489                                     &cCode);
490
491         if (FAILED(res))
492         {
493             ThrowExceptionForJitResult(res);
494         }
495     }
496     
497     MethodCompileComplete(m_currentMethodInfo.ftn);
498
499 #ifdef _TARGET_X86_
500     // The x86 JIT over estimates the code size. Trim the blob size down to 
501     // the actual size. 
502     // We can do this only for non-split code. Adjusting the code size for split
503     // methods would hose offsets in GC info.
504     if (m_pColdCode == NULL)
505     {
506         m_pCode->AdjustBlobSize(cCode);
507     }
508 #endif
509
510     PublishCompiledMethod();
511 }
512
513 #ifndef FEATURE_FULL_NGEN
514 class MethodCodeComparer
515 {
516     static BOOL NodeEquals(ZapNode * k1, ZapNode * k2)
517     {
518         return k1 == k2;
519     }
520
521     static BOOL BlobEquals(ZapBlob * k1, ZapBlob * k2)
522     {
523         if (k1 == NULL && k2 == NULL)
524             return TRUE;
525         if (k1 == NULL || k2 == NULL)
526             return FALSE;
527
528         if (k1->GetBlobSize() != k2->GetBlobSize())
529             return FALSE;
530         if (memcmp(k1->GetData(), k2->GetData(), k1->GetBlobSize()) != 0)
531             return FALSE;
532
533         return TRUE;
534     }
535
536     typedef ZapNode * EquivalentNodes[4][2];
537
538     static BOOL EquivalentNode(ZapNode * k1, ZapNode * k2, EquivalentNodes & equivalentNodes)
539     {
540         if (k1 == k2)
541             return TRUE;
542
543         for (int i = 0; i < _countof(equivalentNodes); i++)
544         {
545             if (k1 == equivalentNodes[i][0] && k2 == equivalentNodes[i][1])
546                 return TRUE;
547         }
548
549         return FALSE;
550     }
551
552     static BOOL BlobWithRelocsEquals(ZapBlobWithRelocs * k1, ZapBlobWithRelocs * k2, EquivalentNodes & equivalentNodes)
553     {
554         if (k1 == NULL && k2 == NULL)
555             return TRUE;
556         if (k1 == NULL || k2 == NULL)
557             return FALSE;
558
559         if (k1->GetBlobSize() != k2->GetBlobSize())
560             return FALSE;
561         if (memcmp(k1->GetData(), k2->GetData(), k1->GetBlobSize()) != 0)
562             return FALSE;
563
564         ZapReloc * pRelocs1 = k1->GetRelocs();
565         ZapReloc * pRelocs2 = k2->GetRelocs();
566
567         if (pRelocs1 == NULL && pRelocs2 == NULL)
568             return TRUE;
569         if (pRelocs1 == NULL || pRelocs2 == NULL)
570             return FALSE;
571
572         while (pRelocs1->m_type != IMAGE_REL_INVALID || pRelocs2->m_type != IMAGE_REL_INVALID)
573         {
574             if (pRelocs1->m_type != pRelocs2->m_type || pRelocs1->m_offset != pRelocs2->m_offset)
575                 return FALSE;
576
577             if (!EquivalentNode(pRelocs1->m_pTargetNode, pRelocs2->m_pTargetNode, equivalentNodes))
578                 return FALSE;
579
580             pRelocs1++; pRelocs2++;
581         }
582
583         return TRUE;
584     }
585
586     static BOOL UnwindInfoEquals(ZapUnwindInfo * k1, ZapUnwindInfo * k2, EquivalentNodes & equivalentNodes)
587     {
588         if (k1 == NULL && k2 == NULL)
589             return TRUE;
590         if (k1 == NULL || k2 == NULL)
591             return FALSE;
592
593         return (k1->GetStartOffset() == k2->GetStartOffset()) && 
594                (k1->GetEndOffset() == k2->GetEndOffset()) &&
595                (k1->GetUnwindData() == k2->GetUnwindData()) && 
596                EquivalentNode(k1->GetCode(), k2->GetCode(), equivalentNodes);
597     }
598
599     static BOOL UnwindInfoFragmentsEquals(ZapUnwindInfo * k1, ZapUnwindInfo * k2, EquivalentNodes & equivalentNodes)
600     {
601         if (k1 == NULL && k2 == NULL)
602             return TRUE;
603         if (k1 == NULL || k2 == NULL)
604             return FALSE;
605
606         while (k1 != NULL || k2 != NULL)
607         {
608             if (!UnwindInfoEquals(k1, k2, equivalentNodes))
609                 return FALSE;
610
611             k1 = k1->GetNextFragment(); k2 = k2->GetNextFragment();
612         }
613
614         return TRUE;
615     }
616
617     static BOOL FixupListEquals(ZapImport ** k1, ZapImport ** k2)
618     {
619         if (k1 == NULL && k2 == NULL)
620             return TRUE;
621         if (k1 == NULL || k2 == NULL)
622             return FALSE;
623
624         while (*k1 != NULL || *k2 != NULL)
625         {
626             if (*k1 != *k2)
627                 return FALSE;
628             k1++; k2++;
629         }
630
631         return TRUE;
632     }
633
634 public:
635     static BOOL MethodCodeEquals(ZapMethodHeader * k1, ZapMethodHeader * k2)
636     {
637         LIMITED_METHOD_CONTRACT;
638
639         EquivalentNodes equivalentNodes =
640         {
641             { k1->m_pCode, k2->m_pCode },
642             { k1->m_pColdCode, k2->m_pColdCode },
643             { k1->m_pROData, k2->m_pROData },
644             { k1->m_pProfileData, k2->m_pProfileData }
645         };
646
647         if (!BlobWithRelocsEquals(k1->m_pCode, k2->m_pCode, equivalentNodes))
648             return FALSE;
649
650         if (!BlobWithRelocsEquals(k1->m_pColdCode, k2->m_pColdCode, equivalentNodes))
651             return FALSE;
652
653         if (!UnwindInfoEquals(k1->m_pUnwindInfo, k2->m_pUnwindInfo, equivalentNodes))
654             return FALSE;
655
656         if (!UnwindInfoEquals(k1->m_pColdUnwindInfo, k2->m_pColdUnwindInfo, equivalentNodes))
657             return FALSE;
658
659 #ifdef WIN64EXCEPTIONS
660         if (!UnwindInfoFragmentsEquals(k1->m_pUnwindInfoFragments, k2->m_pUnwindInfoFragments, equivalentNodes))
661             return FALSE;
662 #endif
663
664         if (!BlobWithRelocsEquals(k1->m_pROData, k2->m_pROData, equivalentNodes))
665             return FALSE;
666
667         if (!BlobWithRelocsEquals(k1->m_pProfileData, k2->m_pProfileData, equivalentNodes))
668             return FALSE;
669
670         if (!NodeEquals(k1->m_pGCInfo, k2->m_pGCInfo)) // interned
671             return FALSE;
672
673         if (!NodeEquals(k1->m_pDebugInfo, k2->m_pDebugInfo)) // interned
674             return FALSE;
675
676         if (!FixupListEquals(k1->m_pFixupList, k2->m_pFixupList))
677             return FALSE;
678
679         if (!BlobEquals(k1->m_pExceptionInfo, k2->m_pExceptionInfo))
680             return FALSE;
681
682         return TRUE;
683     }
684 };
685
686 extern BOOL CanDeduplicateCode(CORINFO_METHOD_HANDLE method, CORINFO_METHOD_HANDLE duplicateMethod);
687
688 BOOL ZapImage::MethodCodeTraits::Equals(key_t k1, key_t k2)
689 {
690     if (!MethodCodeComparer::MethodCodeEquals(k1, k2))
691         return FALSE;
692
693     // Check additional VM conditions that has to be satisfied for deduplication
694     if (!CanDeduplicateCode(k1->GetHandle(), k2->GetHandle()))
695         return FALSE;
696
697     return TRUE;
698 }
699
700 COUNT_T ZapImage::MethodCodeTraits::Hash(key_t k)
701 {
702     COUNT_T hash = ZapBlob::SHashTraits::Hash(ZapBlob::SHashTraits::GetKey(k->m_pCode));
703
704     ZapReloc * pRelocs = k->m_pCode->GetRelocs();
705     if (pRelocs != NULL)
706     {
707         while (pRelocs->m_type != IMAGE_REL_INVALID)
708         {
709             ZapNode * pTarget = pRelocs->m_pTargetNode;
710             ZapNodeType type = pTarget->GetType();
711
712             if (type == ZapNodeType_InnerPtr)
713             {
714                 pTarget = ((ZapInnerPtr *)pTarget)->GetBase();
715                 type = pTarget->GetType();
716             }
717
718             // The IL stubs code often differs by just a method call or class handle. Include 
719             // these in the hash code.
720             switch (type)
721             {
722             case ZapNodeType_MethodEntryPoint:
723             case ZapNodeType_ExternalMethodThunk:
724             case ZapNodeType_ClassHandle:
725             case ZapNodeType_Import_ClassHandle:
726             case ZapNodeType_MethodHandle:
727             case ZapNodeType_Import_MethodHandle:
728                 hash = ((hash << 5) + hash) ^ (COUNT_T)(pTarget);
729                 break;
730             default:
731                 break;
732             }
733
734             pRelocs++;
735         }
736     }
737
738     return hash;
739 }
740 #endif
741
742 void ZapInfo::PublishCompiledMethod()
743 {
744     EmitCodeRelocations();
745
746     // Go through all references in the code, make sure that we have fixups for them, 
747     // and ensure that they will be otherwise present in the image if necessary
748     ProcessReferences();
749
750     // See if there are load fixups to emit.
751     m_ClassLoadTable.EmitLoadFixups(m_currentMethodHandle, this);
752
753     if (!IsReadyToRunCompilation())
754         m_MethodLoadTable.EmitLoadFixups(m_currentMethodHandle, this);
755
756     ZapMethodHeader * pMethod = new (m_pImage->GetHeap()) ZapMethodHeader();
757
758     pMethod->m_handle = m_currentMethodHandle;
759     pMethod->m_classHandle = getMethodClass(m_currentMethodHandle);
760
761     pMethod->m_pCode = m_pCode;
762     pMethod->m_pColdCode = m_pColdCode;
763     pMethod->m_pROData = m_pROData;
764
765     pMethod->m_pProfileData = m_pProfileData;
766
767     pMethod->m_pExceptionInfo = m_pExceptionInfo;
768
769     pMethod->m_pFixupList = EmitFixupList();
770
771     pMethod->m_pDebugInfo = EmitDebugInfo();
772     pMethod->m_pGCInfo = EmitGCInfo();
773
774 #ifdef WIN64EXCEPTIONS
775     pMethod->m_pUnwindInfoFragments = m_pUnwindInfoFragments;
776
777     // Set the combined GCInfo + UnwindInfo blob
778     m_pUnwindInfo->SetUnwindData(pMethod->m_pGCInfo);
779
780 #if defined(_TARGET_AMD64_)
781     if (m_pChainedColdUnwindInfo != NULL)
782     {
783         // Chain the cold unwind info with the hot unwind info
784         m_pChainedColdUnwindInfo->SetUnwindData(m_pUnwindInfo);
785     }
786 #endif // _TARGET_AMD64_
787
788 #endif // WIN64EXCEPTIONS
789
790 #ifndef FEATURE_FULL_NGEN
791     //
792     // Method code deduplication
793     //
794     // For now, the only methods eligible for de-duplication are IL stubs
795     //
796     if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB))
797     {
798         ZapMethodHeader * pDuplicateMethod = m_pImage->m_CodeDeduplicator.Lookup(pMethod);
799         if (pDuplicateMethod != NULL)
800         {
801             m_pImage->m_pPreloader->NoteDeduplicatedCode(pMethod->m_handle, pDuplicateMethod->m_handle);
802             return;
803         }
804
805         m_pImage->m_CodeDeduplicator.Add(pMethod);
806     }
807 #endif
808
809     // Remember the gc info for IL stubs associated with hot methods so they can be packed well.
810     // Stubs that have no metadata token cannot be tracked by IBC data.
811     if (m_currentMethodProfilingDataFlags & (1 << ReadMethodCode))
812     {
813         if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB))
814             m_pImage->m_PrioritizedGCInfo.Append(pMethod->m_pGCInfo);
815     }
816
817     pMethod->m_ProfilingDataFlags = m_currentMethodProfilingDataFlags;
818
819     COUNT_T methodCompilationOrder = m_pImage->m_MethodCompilationOrder.GetCount();
820     pMethod->m_compilationOrder = methodCompilationOrder;
821
822     // We need to remember the first index into m_MethodCompilationOrder where we saw a method from this class
823     m_pImage->InitializeClassLayoutOrder(pMethod->m_classHandle, methodCompilationOrder);
824
825     m_pImage->m_CompiledMethods.Add(pMethod);
826     m_pImage->m_MethodCompilationOrder.Append(pMethod);
827 }
828
829 void ZapInfo::getGSCookie(GSCookie * pCookieVal, GSCookie ** ppCookieVal)
830 {
831     *pCookieVal = 0;
832
833 #ifdef FEATURE_READYTORUN_COMPILER
834     if (IsReadyToRunCompilation())
835     {
836         *ppCookieVal = (GSCookie *)m_pImage->GetImportTable()->GetHelperImport(READYTORUN_HELPER_GSCookie);
837         return;
838     }
839 #endif
840
841     *ppCookieVal = (GSCookie *)m_pImage->GetInnerPtr(m_pImage->m_pEEInfoTable,
842         offsetof(CORCOMPILE_EE_INFO_TABLE, gsCookie));
843 }
844
845 DWORD ZapInfo::getJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes)
846 {
847     _ASSERTE(jitFlags != NULL);
848     _ASSERTE(sizeInBytes >= sizeof(m_jitFlags));
849
850     *jitFlags = m_jitFlags;
851     return sizeof(m_jitFlags);
852 }
853
854 IEEMemoryManager* ZapInfo::getMemoryManager()
855 {
856     return GetEEMemoryManager();
857 }
858     
859 bool ZapInfo::runWithErrorTrap(void (*function)(void*), void* param)
860 {
861     return m_pEEJitInfo->runWithErrorTrap(function, param);
862 }
863
864 HRESULT ZapInfo::allocBBProfileBuffer (
865     ULONG                         cBlock,
866     ICorJitInfo::ProfileBuffer ** ppBlock
867     )
868 {
869     HRESULT hr;
870
871     if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB))
872     {
873         *ppBlock = NULL;
874         return E_NOTIMPL;
875     }
876
877     // @TODO: support generic methods from other assemblies
878     if (m_currentMethodModule != m_pImage->m_hModule)
879     {
880         *ppBlock = NULL;
881         return E_NOTIMPL;
882     }
883
884     mdMethodDef md = m_currentMethodToken;
885
886     if (IsNilToken(md))
887     {
888         // This must be the non-System.Object instantiation of a generic type/method.
889         IfFailRet(m_zapper->m_pEECompileInfo->GetMethodDef(m_currentMethodHandle, &md));
890     }
891 #ifdef _DEBUG
892     else
893     {
894         mdMethodDef mdTemp;
895         IfFailRet(m_zapper->m_pEECompileInfo->GetMethodDef(m_currentMethodHandle, &mdTemp));
896         _ASSERTE(md == mdTemp);
897     }
898 #endif
899     if (IsNilToken(md))
900     {
901         return E_FAIL;
902     }
903
904     // If the JIT retries the compilation (especially during JIT stress), it can
905     // try to allocate the profiling data multiple times. We will just keep track
906     // of the latest copy in this case.
907     // _ASSERTE(m_pProfileData == NULL);
908
909     DWORD totalSize = (DWORD) (cBlock * sizeof(ICorJitInfo::ProfileBuffer)) + sizeof(CORBBTPROF_METHOD_HEADER);
910     m_pProfileData = ZapBlobWithRelocs::NewAlignedBlob(m_pImage, NULL, totalSize, sizeof(DWORD));
911     CORBBTPROF_METHOD_HEADER * profileData = (CORBBTPROF_METHOD_HEADER *) m_pProfileData->GetData();
912     profileData->size           = totalSize;
913     profileData->cDetail        = 0;
914     profileData->method.token   = md;
915     profileData->method.ILSize  = m_currentMethodInfo.ILCodeSize;
916     profileData->method.cBlock  = cBlock;
917
918     *ppBlock = (ICorJitInfo::ProfileBuffer *)(&profileData->method.block[0]);
919
920     return S_OK;
921 }
922
923 HRESULT ZapInfo::getBBProfileData (
924     CORINFO_METHOD_HANDLE         ftnHnd,
925     ULONG *                       pCount,
926     ICorJitInfo::ProfileBuffer ** ppBlock,
927     ULONG *                       numRuns
928     )
929 {
930     _ASSERTE(ppBlock);
931     _ASSERTE(pCount);
932     _ASSERTE(ftnHnd == m_currentMethodHandle);
933
934     HRESULT hr;
935
936     // Initialize outputs in case we return E_FAIL
937     *ppBlock = NULL;
938     *pCount = 0;
939     if (numRuns)
940     {
941         *numRuns = 0;
942     }
943
944     // For generic instantiations whose IL is in another module,
945     // the profile data is in that module
946     // @TODO: Fetch the profile data from the other module.
947     if ((m_currentMethodModule != m_pImage->m_hModule) ||
948         m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB))
949     {
950         return E_FAIL;
951     }
952
953     ZapImage::ProfileDataSection * DataSection_MethodBlockCounts = & m_pImage->m_profileDataSections[MethodBlockCounts];
954
955     if (!DataSection_MethodBlockCounts->pData)
956     {
957         return E_FAIL;
958     }
959
960     mdMethodDef md = m_currentMethodToken;
961
962     if (IsNilToken(md))
963     {
964         // This must be the non-System.Object instantiation of a generic type/method.
965         IfFailRet(m_zapper->m_pEECompileInfo->GetMethodDef(ftnHnd, &md));
966     }
967 #ifdef _DEBUG
968     else
969     {
970         mdMethodDef mdTemp;
971         IfFailRet(m_zapper->m_pEECompileInfo->GetMethodDef(ftnHnd, &mdTemp));
972         _ASSERTE(md == mdTemp);
973     }
974 #endif
975     if (IsNilToken(md))
976     {
977         return E_FAIL;
978     }
979
980     if (numRuns)
981     {
982         *numRuns =  m_pImage->m_profileDataNumRuns;
983     }
984
985     const ZapImage::ProfileDataHashEntry * foundEntry = m_pImage->profileDataHashTable.LookupPtr(md);
986
987     if (foundEntry == NULL)
988     {
989         return E_FAIL;
990     }
991
992     // The md must match.
993     _ASSERTE(foundEntry->md == md);
994
995     if (foundEntry->pos == 0)
996     {
997         // We might not have profile data and instead only have CompileStatus and flags
998         assert(foundEntry->size == 0);
999         return E_FAIL;
1000     }
1001
1002     //
1003     //
1004     // We found the md. Let's retrieve the profile data.
1005     //
1006     _ASSERTE(foundEntry->size >= sizeof(CORBBTPROF_METHOD_HEADER));   // The size must at least this
1007
1008     ProfileReader profileReader(DataSection_MethodBlockCounts->pData, DataSection_MethodBlockCounts->dataSize);
1009
1010     // Locate the method in interest.
1011     SEEK(foundEntry->pos);     
1012     CORBBTPROF_METHOD_HEADER *  profileData;
1013     READ_SIZE(profileData, CORBBTPROF_METHOD_HEADER, foundEntry->size);
1014     _ASSERTE(profileData->method.token == foundEntry->md);  // We should be looking at the right method
1015     _ASSERTE(profileData->size == foundEntry->size);        // and the cached size must match
1016
1017     *ppBlock = (ICorJitInfo::ProfileBuffer *) &profileData->method.block[0];
1018     *pCount  = profileData->method.cBlock;
1019
1020     // If the ILSize is non-zero the the ILCodeSize also must match
1021     // 
1022     if ((profileData->method.ILSize != 0) && (profileData->method.ILSize != m_currentMethodInfo.ILCodeSize))
1023     {
1024         // IL code for this method does not match the IL code for the method when it was profiled
1025         // in such cases we tell the JIT to discard the profile data by returning E_FAIL
1026         //
1027         return E_FAIL;
1028     }
1029
1030     return S_OK;
1031 }
1032
1033 void ZapInfo::allocMem(
1034     ULONG               hotCodeSize,    /* IN */
1035     ULONG               coldCodeSize,   /* IN */
1036     ULONG               roDataSize,     /* IN */
1037     ULONG               xcptnsCount,    /* IN */    
1038     CorJitAllocMemFlag  flag,           /* IN */
1039     void **             hotCodeBlock,   /* OUT */
1040     void **             coldCodeBlock,  /* OUT */
1041     void **             roDataBlock     /* OUT */
1042     )
1043 {
1044     bool optForSize = m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SIZE_OPT);
1045
1046     UINT align = DEFAULT_CODE_ALIGN;
1047
1048     if ((flag & CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN) && !IsReadyToRunCompilation()) align = max(align, 16);
1049
1050     m_pCode = ZapCodeBlob::NewAlignedBlob(m_pImage, NULL, hotCodeSize, align);
1051     *hotCodeBlock = m_pCode->GetData();
1052
1053     if (coldCodeSize != 0)
1054     {
1055         align = sizeof(DWORD);
1056
1057         m_pColdCode = ZapCodeBlob::NewAlignedBlob(m_pImage, NULL, coldCodeSize, align);
1058         *coldCodeBlock = m_pColdCode->GetData();
1059     }
1060
1061     //
1062     // Allocate data
1063     //
1064
1065     if (roDataSize > 0)
1066     {
1067         if (flag & CORJIT_ALLOCMEM_FLG_RODATA_16BYTE_ALIGN)
1068         {
1069             align = 16;
1070         }
1071         else if (optForSize || (roDataSize < 8))
1072         {
1073             align = sizeof(TADDR);
1074         }
1075         else
1076         {
1077             align = 8;
1078         }
1079         m_pROData = ZapBlobWithRelocs::NewAlignedBlob(m_pImage, NULL, roDataSize, align);
1080         *roDataBlock = m_pROData->GetData();
1081     }
1082
1083     if (m_pImage->m_stats)
1084     {
1085         m_pImage->m_stats->m_nativeCodeSize     += hotCodeSize;
1086         m_pImage->m_stats->m_nativeColdCodeSize += coldCodeSize;
1087         m_pImage->m_stats->m_nativeRODataSize   += roDataSize;
1088
1089         BOOL haveProfileData = CurrentMethodHasProfileData();
1090
1091         if (haveProfileData)
1092         {
1093             m_pImage->m_stats->m_nativeCodeSizeInProfiledMethods     += hotCodeSize;
1094             m_pImage->m_stats->m_nativeColdCodeSizeInProfiledMethods += coldCodeSize;
1095         }
1096
1097         if (coldCodeSize)
1098         {
1099             m_pImage->m_stats->m_NumHotColdAllocations++;
1100
1101             m_pImage->m_stats->m_nativeCodeSizeInSplitMethods     += hotCodeSize;
1102             m_pImage->m_stats->m_nativeColdCodeSizeInSplitMethods += coldCodeSize;
1103
1104             if (haveProfileData)
1105             {
1106                 m_pImage->m_stats->m_nativeCodeSizeInSplitProfiledMethods     += hotCodeSize;
1107                 m_pImage->m_stats->m_nativeColdCodeSizeInSplitProfiledMethods += coldCodeSize;
1108             }
1109         }
1110         else
1111         {
1112             m_pImage->m_stats->m_NumHotAllocations++;
1113         }
1114     }
1115 }
1116
1117 void * ZapInfo::allocGCInfo(size_t size)
1118 {
1119     _ASSERTE(m_pGCInfo == NULL);
1120
1121 #ifdef _WIN64
1122     if (size & 0xFFFFFFFF80000000LL)
1123     {
1124         IfFailThrow(CORJIT_OUTOFMEM);
1125     }
1126 #endif // _WIN64
1127
1128     m_pGCInfo = new BYTE[size];
1129     m_cbGCInfo = size;
1130
1131     return m_pGCInfo;
1132 }
1133
1134 void ZapInfo::yieldExecution()
1135 {
1136     // nothing necessary here
1137 }
1138
1139
1140 void ZapInfo::setEHcount(unsigned cEH)
1141 {
1142     //
1143     // Must call after header has been allocated
1144     //
1145
1146     if (cEH == 0)
1147     {
1148         _ASSERTE(!"Should not be called");
1149         return;
1150     }    
1151
1152     ULONG size = (sizeof(CORCOMPILE_EXCEPTION_CLAUSE) * cEH);
1153
1154     _ASSERTE(m_pExceptionInfo == NULL);
1155     m_pExceptionInfo = ZapBlob::NewAlignedBlob(m_pImage, NULL, size, sizeof(DWORD));
1156 }
1157
1158 void ZapInfo::setEHinfo(unsigned EHnumber,
1159                         const CORINFO_EH_CLAUSE *clause)
1160 {
1161     //
1162     // Must call after EH info has been allocated
1163     //
1164
1165     _ASSERTE(m_pExceptionInfo != NULL);
1166
1167     CORCOMPILE_EXCEPTION_CLAUSE *ehClauseArray = (CORCOMPILE_EXCEPTION_CLAUSE *)m_pExceptionInfo->GetData();
1168     CORCOMPILE_EXCEPTION_CLAUSE *ilClause = &ehClauseArray[EHnumber];
1169
1170     ilClause->TryStartPC    = clause->TryOffset;
1171     ilClause->TryEndPC      = clause->TryLength;
1172     ilClause->HandlerStartPC= clause->HandlerOffset;
1173     ilClause->HandlerEndPC  = clause->HandlerLength;
1174     ilClause->Flags         = (CorExceptionFlag) clause->Flags;
1175
1176     if (clause->Flags & CORINFO_EH_CLAUSE_FILTER)
1177     {
1178         ilClause->FilterOffset = clause->FilterOffset;
1179     }
1180     else
1181     {
1182         ilClause->ClassToken = clause->ClassToken;
1183
1184         if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB) && (clause->ClassToken != 0))
1185         {
1186             // IL stub tokens are 'private' and do not resolve correctly in their parent module's metadata.
1187
1188             // Currently, the only place we are using a token here is for a COM-to-CLR exception-to-HRESULT
1189             // mapping catch clause.  We want this catch clause to catch all exceptions, so we override the
1190             // token to be mdTypeRefNil, which used by the EH system to mean catch(...)
1191
1192 #ifdef _DEBUG
1193             // The proper way to do this, should we ever want to support arbitrary types here, is to "pre-
1194             // resolve" the token and store the TypeHandle in the clause.  But this requires additional 
1195             // infrastructure to ensure the TypeHandle is saved and fixed-up properly.  For now, we will
1196             // simply assert that the original type was System.Object.
1197
1198             CORINFO_RESOLVED_TOKEN resolvedToken = { 0 };
1199             resolvedToken.tokenContext = MAKE_METHODCONTEXT(m_currentMethodInfo.ftn);
1200             resolvedToken.tokenScope = m_currentMethodInfo.scope;
1201             resolvedToken.token = ilClause->ClassToken;
1202             resolvedToken.tokenType = CORINFO_TOKENKIND_Class;
1203
1204             resolveToken(&resolvedToken);
1205
1206             CORINFO_CLASS_HANDLE systemObjectHandle = getBuiltinClass(CLASSID_SYSTEM_OBJECT);
1207             _ASSERTE(systemObjectHandle == resolvedToken.hClass);
1208 #endif // _DEBUG
1209
1210             ilClause->ClassToken = mdTypeRefNil; 
1211         }
1212     }
1213
1214     //
1215     // @TODO: this does not support DynamicMethods
1216     //
1217 }
1218
1219 int ZapInfo::canHandleException(struct _EXCEPTION_POINTERS *pExceptionPointers)
1220 {
1221     return (EXCEPTION_EXECUTE_HANDLER);
1222 }
1223
1224 int ZapInfo::doAssert(const char* szFile, int iLine, const char* szExpr)
1225 {
1226
1227 #if defined(_DEBUG)
1228     return(_DbgBreakCheck(szFile, iLine, szExpr));
1229 #else
1230     return(true);       // break into debugger
1231 #endif
1232
1233 }
1234 void ZapInfo::reportFatalError(CorJitResult result)
1235 {
1236     m_zapper->Info(W("Jit reported error 0x%x while compiling %s\n"), (int)result,
1237                    m_currentMethodName.GetUnicode());
1238 }
1239
1240 // Reserve memory for the method/funclet's unwind information
1241 // Note that this must be called before allocMem, it should be
1242 // called once for the main method, once for every funclet region, and 
1243 // once for every non-funclet cold region for which we will call 
1244 // allocUnwindinfo. 
1245 //
1246 // For prejitted code we need to count how many funclet regions
1247 // we have so that we can allocate and sort a contiguous .rdata block.
1248 //
1249 void ZapInfo::reserveUnwindInfo(BOOL isFunclet, BOOL isColdCode, ULONG unwindSize)
1250 {
1251     // Nothing to do
1252 }
1253
1254
1255 //
1256 // Allocate and initialize the .xdata and .pdata for this method or
1257 // funclet region and get the block of memory needed for the machine-specific
1258 // unwind information (the info for crawling the stack frame).
1259 // Note that allocMem must be called first.
1260 //
1261 // The pHotCode parameter points at the first byte of the code of the method.
1262 // The startOffset and endOffset are the region (main or funclet) that
1263 // we are to allocate and create .xdata and .pdata for.
1264 // The pUnwindBlock is copied and contains the .xdata unwind info.
1265 //
1266 // Parameters:
1267 //
1268 //    pHotCode        main method code buffer, always filled in
1269 //    pColdCode       cold code buffer, only filled in if this is cold code, 
1270 //                      null otherwise
1271 //    startOffset     start of code block, relative to appropriate code buffer
1272 //                      (e.g. pColdCode if cold, pHotCode if hot).
1273 //    endOffset       end of code block, relative to appropriate code buffer
1274 //    unwindSize      size of unwind info pointed to by pUnwindBlock
1275 //    pUnwindBlock    pointer to unwind info
1276 //    funcKind        type of funclet (main method code, handler, filter)
1277 //
1278 void ZapInfo::allocUnwindInfo (
1279         BYTE *              pHotCode,              /* IN */
1280         BYTE *              pColdCode,             /* IN */
1281         ULONG               startOffset,           /* IN */
1282         ULONG               endOffset,             /* IN */
1283         ULONG               unwindSize,            /* IN */
1284         BYTE *              pUnwindBlock,          /* IN */
1285         CorJitFuncKind      funcKind               /* IN */
1286         )
1287 {
1288 #ifdef WIN64EXCEPTIONS
1289     _ASSERTE(pHotCode == m_pCode->GetData());
1290     _ASSERTE(pColdCode == NULL || pColdCode == m_pColdCode->GetData());
1291
1292     ZapNode * pCode = (pColdCode != NULL) ? m_pColdCode : m_pCode;
1293
1294     ZapUnwindInfo * pUnwindInfo = new (m_pImage->GetHeap()) ZapUnwindInfo(pCode, startOffset, endOffset);    
1295
1296     // Prepend the new unwind info to the linked list of all fragments
1297     pUnwindInfo->SetNextFragment(m_pUnwindInfoFragments);
1298     m_pUnwindInfoFragments = pUnwindInfo;
1299
1300     if (funcKind == CORJIT_FUNC_ROOT && pColdCode == NULL && startOffset == 0)
1301     {
1302         //
1303         // Main method unwind data
1304         //
1305
1306         _ASSERTE(m_pMainUnwindInfo == NULL);
1307
1308         m_pMainUnwindInfo = new BYTE[unwindSize];
1309         m_cbMainUnwindInfo = unwindSize;
1310
1311         memcpy(m_pMainUnwindInfo, pUnwindBlock, unwindSize);
1312
1313         // UnwindData Will be set to the combined GCInfo + UnwindInfo blob later as the compiled method is published
1314
1315         _ASSERTE(m_pUnwindInfo == NULL);
1316         m_pUnwindInfo = pUnwindInfo;
1317     }
1318 #if defined(_TARGET_AMD64_)
1319     else
1320     if (funcKind == CORJIT_FUNC_ROOT && pColdCode != NULL)
1321     {
1322         //
1323         // Chained cold code unwind data
1324         //
1325
1326         _ASSERTE(unwindSize == 0);        
1327
1328         // UnwindData Will be chained to the parent unwind info later as the compiled method is published
1329
1330         _ASSERTE(m_pChainedColdUnwindInfo == NULL);
1331         m_pChainedColdUnwindInfo = pUnwindInfo;
1332     }
1333 #endif
1334     else
1335     {
1336
1337         //
1338         // Normal unwind data
1339         //
1340
1341         ZapUnwindData * pUnwindData = m_pImage->m_pUnwindDataTable->GetUnwindData(pUnwindBlock, unwindSize, funcKind == CORJIT_FUNC_FILTER);
1342         pUnwindInfo->SetUnwindData(pUnwindData);
1343     }     
1344 #endif // WIN64EXCEPTIONS
1345 }
1346
1347 BOOL ZapInfo::logMsg(unsigned level, const char *fmt, va_list args)
1348 {
1349     if (HasSvcLogger())
1350     {
1351         if (level <= LL_INFO10)
1352         {
1353             StackSString ss;
1354             ss.VPrintf(fmt,args);
1355             GetSvcLogger()->Log(ss.GetUnicode(), LogLevel_Success);
1356             return TRUE;
1357         }
1358     }
1359
1360 #ifdef LOGGING
1361     if (LoggingOn(LF_JIT, level))
1362     {
1363         LogSpewValist(LF_JIT, level, (char*) fmt, args);
1364         return TRUE;
1365     }
1366 #endif // LOGGING
1367
1368     return FALSE;
1369 }
1370
1371 //
1372 // ICorDynamicInfo
1373 //
1374
1375 DWORD ZapInfo::getThreadTLSIndex(void **ppIndirection)
1376 {
1377     _ASSERTE(ppIndirection != NULL);
1378
1379     *ppIndirection = NULL;
1380     return (DWORD)-1;
1381 }
1382
1383 const void * ZapInfo::getInlinedCallFrameVptr(void **ppIndirection)
1384 {
1385     _ASSERTE(ppIndirection != NULL);
1386
1387     *ppIndirection = m_pImage->GetInnerPtr(m_pImage->m_pEEInfoTable,
1388         offsetof(CORCOMPILE_EE_INFO_TABLE, inlinedCallFrameVptr));
1389     return NULL;
1390 }
1391
1392 LONG * ZapInfo::getAddrOfCaptureThreadGlobal(void **ppIndirection)
1393 {
1394     _ASSERTE(ppIndirection != NULL);
1395
1396     *ppIndirection = (LONG *) m_pImage->GetInnerPtr(m_pImage->m_pEEInfoTable,
1397         offsetof(CORCOMPILE_EE_INFO_TABLE, addrOfCaptureThreadGlobal));
1398     return NULL;
1399 }
1400
1401 // Get slow lazy string literal helper to use (CORINFO_HELP_STRCNS*).
1402 // Returns CORINFO_HELP_UNDEF if lazy string literal helper cannot be used.
1403 CorInfoHelpFunc ZapInfo::getLazyStringLiteralHelper(CORINFO_MODULE_HANDLE handle)
1404 {
1405     if (handle == m_pImage->m_hModule)
1406         return CORINFO_HELP_STRCNS_CURRENT_MODULE;
1407
1408     return CORINFO_HELP_STRCNS;
1409 }
1410
1411 CORINFO_MODULE_HANDLE ZapInfo::embedModuleHandle(CORINFO_MODULE_HANDLE handle,
1412                                                                 void **ppIndirection)
1413 {
1414     _ASSERTE(ppIndirection != NULL);
1415
1416     if (IsReadyToRunCompilation())
1417     {
1418         _ASSERTE(!"embedModuleHandle");
1419         ThrowHR(E_NOTIMPL);
1420     }
1421
1422     BOOL fHardbound = m_pImage->m_pPreloader->CanEmbedModuleHandle(handle);
1423     if (fHardbound)
1424     {
1425         if (handle == m_pImage->m_hModule)
1426         {
1427             // If the handle is the module we are currently ngening, we will
1428             // assume that Module is the very first thing in the preload section
1429             *ppIndirection = NULL;
1430             return (CORINFO_MODULE_HANDLE)m_pImage->m_pPreloadSections[CORCOMPILE_SECTION_MODULE];
1431         }
1432
1433         *ppIndirection = m_pImage->GetImportTable()->GetModuleHandleImport(handle);
1434     }
1435     else
1436     {
1437         ZapImport * pImport = m_pImage->GetImportTable()->GetModuleHandleImport(handle);
1438         AppendConditionalImport(pImport);
1439         
1440         *ppIndirection = pImport;
1441     }
1442     return NULL;
1443 }
1444
1445 //
1446 // The following functions indicate whether a handle can be directly embedded into
1447 // the code being compiled, or if it needs to be accessed with a (fixable) indirection.
1448 // Embeddable handles are those that will be persisted in the zap image.
1449 //
1450 // These functions are gradually being all moved across to ceeload.cpp and compile.cpp.
1451 //
1452
1453 CORINFO_CLASS_HANDLE ZapInfo::embedClassHandle(CORINFO_CLASS_HANDLE handle,
1454                                                          void **ppIndirection)
1455 {
1456     _ASSERTE(ppIndirection != NULL);
1457
1458     if (IsReadyToRunCompilation())
1459     {
1460         _ASSERTE(!"embedClassHandle");
1461         ThrowHR(E_NOTIMPL);
1462     }
1463
1464     m_pImage->m_pPreloader->AddTypeToTransitiveClosureOfInstantiations(handle);
1465
1466     BOOL fHardbound = m_pImage->m_pPreloader->CanEmbedClassHandle(handle); 
1467     if (fHardbound)
1468     {
1469         CORINFO_MODULE_HANDLE moduleHandle = m_pEECompileInfo->GetLoaderModuleForEmbeddableType(handle);
1470
1471         if (moduleHandle == m_pImage->m_hModule)
1472         {
1473             // If the handle is the module we are currently ngening, we can
1474             // embed it after its resolved. So use a deferred reloc
1475
1476             *ppIndirection = NULL;
1477             return CORINFO_CLASS_HANDLE(m_pImage->GetWrappers()->GetClassHandle(handle));
1478         }
1479
1480         *ppIndirection = m_pImage->GetImportTable()->GetClassHandleImport(handle);
1481     }
1482     else
1483     {
1484         ZapImport * pImport = m_pImage->GetImportTable()->GetClassHandleImport(handle);
1485         AppendConditionalImport(pImport);
1486
1487         *ppIndirection = pImport;
1488     }
1489     return NULL;
1490 }
1491
1492 CORINFO_FIELD_HANDLE ZapInfo::embedFieldHandle(CORINFO_FIELD_HANDLE handle,
1493                                                void **ppIndirection)
1494 {
1495     _ASSERTE(ppIndirection != NULL);
1496
1497     if (IsReadyToRunCompilation())
1498     {
1499         _ASSERTE(!"embedFieldHandle");
1500         ThrowHR(E_NOTIMPL);
1501     }
1502
1503     m_pImage->m_pPreloader->AddTypeToTransitiveClosureOfInstantiations(m_pEEJitInfo->getFieldClass(handle));
1504
1505     BOOL fHardbound = m_pImage->m_pPreloader->CanEmbedFieldHandle(handle); 
1506     if (fHardbound)
1507     {
1508         CORINFO_MODULE_HANDLE moduleHandle = m_pEECompileInfo->GetLoaderModuleForEmbeddableField(handle);
1509
1510         if (moduleHandle == m_pImage->m_hModule)
1511         {
1512             // If the handle is the module we are currently ngening, we can
1513             // embed it after its resolved. So use a deferred reloc
1514
1515             *ppIndirection = NULL;
1516             return CORINFO_FIELD_HANDLE(m_pImage->GetWrappers()->GetFieldHandle(handle));
1517         }
1518     }
1519
1520
1521     ZapImport * pImport = m_pImage->GetImportTable()->GetFieldHandleImport(handle);
1522     AppendConditionalImport(pImport);
1523
1524     *ppIndirection = pImport;
1525     return NULL;
1526 }
1527
1528 CORINFO_METHOD_HANDLE ZapInfo::embedMethodHandle(CORINFO_METHOD_HANDLE handle,
1529                                                  void **ppIndirection)
1530 {
1531     _ASSERTE(ppIndirection != NULL);
1532
1533     if (IsReadyToRunCompilation())
1534     {
1535         // READYTORUN FUTURE: Handle this case correctly
1536         ThrowHR(E_NOTIMPL);
1537     }
1538
1539     CORINFO_MODULE_HANDLE moduleHandle = m_pEECompileInfo->GetLoaderModuleForEmbeddableMethod(handle);
1540     if (moduleHandle == m_pImage->m_hModule 
1541         && m_pImage->m_pPreloader->CanEmbedMethodHandle(handle, m_currentMethodHandle))
1542     {
1543         // If the handle is the module we are currently ngening, we can
1544         // embed it after its resolved. So use a deferred reloc
1545
1546         *ppIndirection = NULL;
1547         return CORINFO_METHOD_HANDLE(m_pImage->GetWrappers()->GetMethodHandle(handle));
1548     }
1549
1550     ZapImport * pImport = m_pImage->GetImportTable()->GetMethodHandleImport(handle);
1551     AppendConditionalImport(pImport);
1552     
1553     *ppIndirection = pImport;
1554     return NULL;
1555 }
1556
1557 CORINFO_CLASS_HANDLE ZapInfo::getTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken)
1558 {
1559     return m_pEEJitInfo->getTokenTypeAsHandle(pResolvedToken);
1560 }
1561
1562 CORINFO_LOOKUP_KIND
1563 ZapInfo::getLocationOfThisType(CORINFO_METHOD_HANDLE   context)
1564 {
1565     return m_pEEJitInfo->getLocationOfThisType(context);
1566 }
1567
1568 void
1569 ZapInfo::embedGenericHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken,
1570                             BOOL                     fEmbedParent,
1571                             CORINFO_GENERICHANDLE_RESULT *pResult)
1572 {
1573     _ASSERTE(pResult);
1574
1575     m_pEEJitInfo->embedGenericHandle( pResolvedToken,
1576                                       fEmbedParent,
1577                                       pResult);
1578
1579     _ASSERTE(pResult->compileTimeHandle);
1580
1581     if (pResult->lookup.lookupKind.needsRuntimeLookup)
1582     {
1583         if (!IsReadyToRunCompilation())
1584             embedGenericSignature(&pResult->lookup);
1585
1586         if (pResult->handleType == CORINFO_HANDLETYPE_METHOD)
1587         {
1588             // There is no easy way to detect method referenced via generic lookups in generated code.
1589             // Report this method reference unconditionally.
1590             m_pImage->m_pPreloader->MethodReferencedByCompiledCode((CORINFO_METHOD_HANDLE)pResult->compileTimeHandle);
1591         }
1592     }
1593     else
1594     {
1595         void *pIndirection = 0;
1596         CORINFO_GENERIC_HANDLE handle = 0;
1597
1598         switch (pResult->handleType)
1599         {
1600         case CORINFO_HANDLETYPE_CLASS:
1601             if (IsReadyToRunCompilation())
1602             {
1603                 ZapImport * pImport = m_pImage->GetImportTable()->GetClassImport(ENCODE_TYPE_HANDLE, pResolvedToken);
1604                 AppendConditionalImport(pImport);
1605                 pIndirection = pImport;
1606                 handle = NULL;
1607             }
1608             else
1609             {
1610                 CORINFO_CLASS_HANDLE clsHnd = (CORINFO_CLASS_HANDLE) pResult->compileTimeHandle;
1611                 handle = CORINFO_GENERIC_HANDLE(embedClassHandle(clsHnd, &pIndirection));
1612             }
1613             break;
1614
1615         case CORINFO_HANDLETYPE_METHOD:
1616             if (IsReadyToRunCompilation())
1617             {
1618                 ZapImport * pImport = m_pImage->GetImportTable()->GetMethodImport(ENCODE_METHOD_HANDLE, (CORINFO_METHOD_HANDLE)pResult->compileTimeHandle, pResolvedToken);
1619                 AppendConditionalImport(pImport);
1620                 pIndirection = pImport;
1621                 handle = NULL;
1622             }
1623             else
1624             {
1625                 CORINFO_METHOD_HANDLE methHnd = (CORINFO_METHOD_HANDLE) pResult->compileTimeHandle;
1626                 handle =  CORINFO_GENERIC_HANDLE(embedMethodHandle(methHnd, &pIndirection));
1627             }
1628             break;
1629
1630         case CORINFO_HANDLETYPE_FIELD:
1631             if (IsReadyToRunCompilation())
1632             {
1633                 ZapImport * pImport = m_pImage->GetImportTable()->GetFieldImport(ENCODE_FIELD_HANDLE, (CORINFO_FIELD_HANDLE)pResult->compileTimeHandle, pResolvedToken);
1634                 AppendConditionalImport(pImport);
1635                 pIndirection = pImport;
1636                 handle = NULL;
1637             }
1638             else
1639             {
1640                 CORINFO_FIELD_HANDLE fldHnd = (CORINFO_FIELD_HANDLE) pResult->compileTimeHandle;
1641                 handle = CORINFO_GENERIC_HANDLE(embedFieldHandle(fldHnd, &pIndirection));
1642             }
1643             break;
1644
1645         default:
1646             ThrowHR(COR_E_BADIMAGEFORMAT, BFA_INVALID_TOKEN_TYPE);
1647         }
1648
1649         if (handle)
1650         {
1651             pResult->lookup.constLookup.accessType   = IAT_VALUE;
1652             pResult->lookup.constLookup.handle       = CORINFO_GENERIC_HANDLE(handle);
1653         }
1654         else
1655         {
1656             pResult->lookup.constLookup.accessType   = IAT_PVALUE;
1657             pResult->lookup.constLookup.addr         = pIndirection;
1658         }
1659     }
1660 }
1661
1662 void ZapInfo::embedGenericSignature(CORINFO_LOOKUP * pLookup)
1663 {
1664     _ASSERTE(pLookup->lookupKind.needsRuntimeLookup);
1665
1666     if (IsReadyToRunCompilation())
1667     {
1668                 UNREACHABLE_MSG("We should never get here for the ReadyToRun compilation.");
1669         ThrowHR(E_NOTIMPL);
1670     }
1671
1672     if (pLookup->runtimeLookup.signature != NULL)
1673     {
1674         pLookup->runtimeLookup.signature = m_pImage->GetImportTable()->GetGenericSignature(
1675             pLookup->runtimeLookup.signature, pLookup->lookupKind.runtimeLookupKind == CORINFO_LOOKUP_METHODPARAM);
1676     }
1677 }
1678
1679 void* ZapInfo::getTailCallCopyArgsThunk (
1680                     CORINFO_SIG_INFO       *pSig,
1681                     CorInfoHelperTailCallSpecialHandling flags)
1682 {
1683     void * pStub = m_pEEJitInfo->getTailCallCopyArgsThunk(pSig, flags);
1684     if (pStub == NULL)
1685         return NULL;
1686     return m_pImage->GetWrappers()->GetStub(pStub);
1687 }
1688
1689 #ifdef FEATURE_READYTORUN_COMPILER
1690 ReadyToRunHelper MapReadyToRunHelper(CorInfoHelpFunc func, bool * pfOptimizeForSize)
1691 {
1692     switch (func)
1693     {
1694 #define OPTIMIZEFORSIZE *pfOptimizeForSize = true;
1695 #define HELPER(readyToRunHelper, corInfoHelpFunc, flags) \
1696     case corInfoHelpFunc: flags return readyToRunHelper;
1697 #include "readytorunhelpers.h"
1698
1699     case CORINFO_HELP_STRCNS_CURRENT_MODULE:
1700         *pfOptimizeForSize = true;
1701         return READYTORUN_HELPER_GetString;
1702
1703     default:
1704         return READYTORUN_HELPER_Invalid;
1705     }
1706 }
1707 #endif // FEATURE_READYTORUN_COMPILER
1708
1709 void * ZapInfo::getHelperFtn (CorInfoHelpFunc ftnNum, void **ppIndirection)
1710 {
1711     _ASSERTE(ppIndirection != NULL);
1712     *ppIndirection = NULL;
1713
1714 #ifdef FEATURE_READYTORUN_COMPILER
1715     if (IsReadyToRunCompilation())
1716     {
1717         bool fOptimizeForSize = false;
1718         ReadyToRunHelper helperNum = MapReadyToRunHelper(ftnNum, &fOptimizeForSize);
1719
1720         if (helperNum == READYTORUN_HELPER_Invalid)
1721         {
1722             m_zapper->Warning(W("ReadyToRun: JIT helper not supported: %S\n"), m_pEEJitInfo->getHelperName(ftnNum));
1723             ThrowHR(E_NOTIMPL);
1724         }
1725
1726         if (fOptimizeForSize)
1727         {
1728             *ppIndirection = NULL;
1729             return m_pImage->GetImportTable()->GetIndirectHelperThunk(helperNum);
1730         }
1731         else
1732         {
1733             *ppIndirection = m_pImage->GetImportTable()->GetHelperImport(helperNum);
1734             return NULL;
1735         }
1736     }
1737 #endif
1738
1739     DWORD dwHelper = ftnNum;
1740
1741     switch (ftnNum)
1742     {
1743     case CORINFO_HELP_PROF_FCN_ENTER:
1744         *ppIndirection = m_pImage->GetInnerPtr(GetProfilingHandleImport(), kZapProfilingHandleImportValueIndexEnterAddr * sizeof(TADDR));
1745         return NULL;
1746     case CORINFO_HELP_PROF_FCN_LEAVE:
1747         *ppIndirection = m_pImage->GetInnerPtr(GetProfilingHandleImport(), kZapProfilingHandleImportValueIndexLeaveAddr * sizeof(TADDR));
1748         return NULL;
1749     case CORINFO_HELP_PROF_FCN_TAILCALL:
1750         *ppIndirection = m_pImage->GetInnerPtr(GetProfilingHandleImport(), kZapProfilingHandleImportValueIndexTailcallAddr * sizeof(TADDR));
1751         return NULL;
1752 #ifdef _TARGET_AMD64_
1753     case CORINFO_HELP_STOP_FOR_GC:
1754         // Force all calls in ngen images for this helper to use an indirect call.
1755         // We cannot use a jump stub to reach this helper because 
1756         // the RAX register can contain a return value.
1757         dwHelper |= CORCOMPILE_HELPER_PTR;
1758    break;
1759 #endif
1760     default:
1761         break;
1762     }
1763
1764     if (m_pImage->m_pHelperThunks[ftnNum] == NULL)
1765     {
1766         ZapNode * pHelperThunk;
1767         if (ftnNum == CORINFO_HELP_STRCNS_CURRENT_MODULE)
1768         {
1769             pHelperThunk = new (m_pImage->GetHeap()) ZapLazyHelperThunk(CORINFO_HELP_STRCNS);
1770         }            
1771         else
1772         {
1773             pHelperThunk = new (m_pImage->GetHeap()) ZapHelperThunk(dwHelper);
1774         }
1775 #if defined(_TARGET_ARM_)
1776         if ((dwHelper & CORCOMPILE_HELPER_PTR) == 0)
1777             pHelperThunk = m_pImage->GetInnerPtr(pHelperThunk, THUMB_CODE);
1778 #endif
1779         m_pImage->m_pHelperThunks[ftnNum] = pHelperThunk;
1780     }
1781
1782     void * ptr = m_pImage->m_pHelperThunks[ftnNum];
1783
1784     if (dwHelper & CORCOMPILE_HELPER_PTR)
1785     {
1786         *ppIndirection = ptr;
1787         return NULL;
1788     }
1789
1790     return ptr;
1791 }
1792
1793 ULONG ZapInfo::GetNumFixups()
1794 {
1795     return m_Imports.GetCount();
1796 }
1797
1798 void ZapInfo::AppendConditionalImport(ZapImport * pImport)
1799 {
1800     if (m_ImportSet.LookupPtr(pImport) != NULL)
1801         return;
1802
1803     ImportEntry entry;
1804     entry.pImport = pImport;
1805     entry.fConditional = true;
1806     m_ImportSet.Add(entry);
1807 }
1808
1809 void ZapInfo::AppendImport(ZapImport * pImport)
1810 {
1811     const ImportEntry * pExistingEntry = m_ImportSet.LookupPtr(pImport);
1812     if (pExistingEntry != NULL)
1813     {
1814         if (!pExistingEntry->fConditional)
1815             return;
1816         const_cast<ImportEntry *>(pExistingEntry)->fConditional = false;
1817     }
1818     else
1819     {
1820         ImportEntry entry;
1821         entry.pImport = pImport;
1822         entry.fConditional = false;
1823         m_ImportSet.Add(entry);
1824     }
1825
1826     m_Imports.Append(pImport);  
1827 }
1828
1829 //
1830 // This function indicates whether a method entry point be directly embedded into
1831 // the code being compiled, or if we can use a (fixable) cross module thunk.
1832 // If we can't use either of these then we return NULL and we will use an 
1833 // (fixable) indirection cell to perform the call.
1834 // 
1835 PVOID ZapInfo::embedDirectCall(CORINFO_METHOD_HANDLE ftn,
1836                                CORINFO_ACCESS_FLAGS accessFlags, 
1837                                BOOL fAllowThunk)
1838 {
1839     if (!m_pImage->m_pPreloader->CanEmbedFunctionEntryPoint(ftn, m_currentMethodHandle, accessFlags))
1840     {
1841         return NULL;
1842     }
1843
1844     ZapNode * pEntryPointOrThunkToEmbed = NULL;
1845
1846     //
1847     // If it's in the same module then we can call it directly
1848     //
1849     CORINFO_MODULE_HANDLE moduleHandle = m_pEECompileInfo->GetLoaderModuleForEmbeddableMethod(ftn);
1850     if (moduleHandle == m_pImage->m_hModule 
1851         && m_pImage->m_pPreloader->CanEmbedMethodHandle(ftn, m_currentMethodHandle))
1852     {
1853         pEntryPointOrThunkToEmbed = m_pImage->m_pMethodEntryPoints->GetMethodEntryPoint(ftn, accessFlags);
1854     }
1855     else  // otherwise we are calling into an external module
1856     {
1857         if (!fAllowThunk)
1858         {
1859             return NULL;
1860         }
1861
1862         pEntryPointOrThunkToEmbed = m_pImage->GetImportTable()->GetExternalMethodThunk(ftn);
1863     }
1864
1865 #ifdef _TARGET_ARM_
1866     pEntryPointOrThunkToEmbed = m_pImage->GetInnerPtr(pEntryPointOrThunkToEmbed, THUMB_CODE);
1867 #endif
1868
1869     return pEntryPointOrThunkToEmbed;
1870 }
1871
1872 void ZapInfo::getFunctionEntryPoint(
1873                                 CORINFO_METHOD_HANDLE   ftn,                 /* IN  */
1874                                 CORINFO_CONST_LOOKUP *  pResult,             /* OUT */
1875                                 CORINFO_ACCESS_FLAGS    accessFlags/*=CORINFO_ACCESS_ANY*/)
1876 {
1877     if (IsReadyToRunCompilation())
1878     {
1879         // READYTORUN: FUTURE: JIT still calls this for tail. and jmp instructions
1880         m_zapper->Warning(W("ReadyToRun: Method entrypoint cannot be encoded\n"));
1881         ThrowHR(E_NOTIMPL);
1882     }
1883
1884     // Must deal with methods that are methodImpl'd within their own type.
1885     ftn = mapMethodDeclToMethodImpl(ftn);
1886
1887     m_pImage->m_pPreloader->AddMethodToTransitiveClosureOfInstantiations(ftn);
1888
1889     void * entryPointOrThunkToEmbed = embedDirectCall(ftn, accessFlags, TRUE);
1890     if (entryPointOrThunkToEmbed != NULL)
1891     {
1892         pResult->accessType = IAT_VALUE;
1893         pResult->addr       = entryPointOrThunkToEmbed;
1894     }
1895     else
1896     {
1897         ZapImport * pImport = m_pImage->GetImportTable()->GetFunctionEntryImport(ftn);
1898         AppendConditionalImport(pImport);
1899
1900         // Tell the JIT to use an indirections
1901         pResult->accessType   = IAT_PVALUE;
1902         pResult->addr         = pImport;
1903     }
1904 }
1905
1906 void ZapInfo::getFunctionFixedEntryPoint(CORINFO_METHOD_HANDLE   ftn,
1907                                          CORINFO_CONST_LOOKUP *  pResult)
1908 {
1909     _ASSERTE(pResult);
1910
1911     m_pImage->m_pPreloader->AddMethodToTransitiveClosureOfInstantiations(ftn);
1912
1913     // We can only embed entrypoints from the module being NGened since we do not support mapping of external 
1914     // import thunks to MethodDesc. It should be ok since the delegate targets are typically from the same module.
1915     void * entryPointToEmbed = embedDirectCall(ftn, CORINFO_ACCESS_ANY, FALSE);
1916
1917     if (entryPointToEmbed != NULL)
1918     {
1919         pResult->accessType   = IAT_VALUE;
1920         pResult->addr         = entryPointToEmbed;
1921     }
1922     else
1923     {
1924         ZapImport * pImport = m_pImage->GetImportTable()->GetFunctionEntryImport(ftn);
1925         AppendConditionalImport(pImport);
1926         
1927         pResult->accessType   = IAT_PVALUE;
1928         pResult->addr         = pImport;
1929     }
1930 }
1931
1932 void * ZapInfo::getMethodSync(CORINFO_METHOD_HANDLE ftn,
1933                                             void **ppIndirection)
1934 {
1935     _ASSERTE(ppIndirection != NULL);
1936
1937     CORINFO_CLASS_HANDLE classHandle = getMethodClass(ftn);
1938
1939     ZapImport * pImport = m_pImage->GetImportTable()->GetSyncLockImport(classHandle);
1940     AppendConditionalImport(pImport);
1941
1942     *ppIndirection = pImport;
1943     return NULL;
1944 }
1945
1946 void * ZapInfo::getPInvokeUnmanagedTarget(CORINFO_METHOD_HANDLE method, void **ppIndirection)
1947 {
1948     // We will never be able to return this directly in prejit mode.
1949     _ASSERTE(ppIndirection != NULL);
1950
1951     *ppIndirection = NULL;
1952     return NULL;
1953 }
1954
1955 void * ZapInfo::getAddressOfPInvokeFixup(CORINFO_METHOD_HANDLE method,void **ppIndirection)
1956 {
1957     _ASSERTE(ppIndirection != NULL);
1958
1959     m_pImage->m_pPreloader->AddMethodToTransitiveClosureOfInstantiations(method);
1960
1961     CORINFO_MODULE_HANDLE moduleHandle = m_pEECompileInfo->GetLoaderModuleForEmbeddableMethod(method);
1962     if (moduleHandle == m_pImage->m_hModule 
1963         && m_pImage->m_pPreloader->CanEmbedMethodHandle(method, m_currentMethodHandle))
1964     {
1965         *ppIndirection = NULL;
1966         return PVOID(m_pImage->GetWrappers()->GetAddrOfPInvokeFixup(method));
1967     }
1968
1969     //
1970     // Note we could a fixup to a direct call site, rather than to
1971     // the indirection.  This would saves us an extra indirection, but changes the
1972     // semantics slightly (so that the pinvoke will be bound when the calling
1973     // method is first run, not at the exact moment of the first pinvoke.)
1974     //
1975
1976     ZapImport * pImport = m_pImage->GetImportTable()->GetIndirectPInvokeTargetImport(method);
1977     AppendConditionalImport(pImport);
1978
1979     *ppIndirection = pImport;
1980     return NULL;
1981 }
1982
1983 void ZapInfo::getAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP *pLookup)
1984 {
1985     _ASSERTE(pLookup != NULL);
1986
1987     void * pIndirection;
1988     void * pResult = getAddressOfPInvokeFixup(method, &pIndirection);
1989     if (pResult != NULL)
1990     {
1991         pLookup->accessType = IAT_PVALUE;
1992         pLookup->addr = pResult;
1993         return;
1994     }
1995
1996     pLookup->accessType = IAT_PPVALUE;
1997     pLookup->addr = pIndirection;
1998 }
1999
2000 CORINFO_JUST_MY_CODE_HANDLE ZapInfo::getJustMyCodeHandle(
2001     CORINFO_METHOD_HANDLE method,
2002     CORINFO_JUST_MY_CODE_HANDLE **ppIndirection)
2003 {
2004     _ASSERTE(ppIndirection != NULL);
2005
2006     if (IsReadyToRunCompilation())
2007     {
2008         *ppIndirection = NULL;
2009         return NULL;
2010     }
2011
2012     *ppIndirection = (CORINFO_JUST_MY_CODE_HANDLE *)m_pImage->GetInnerPtr(m_pImage->m_pEEInfoTable,
2013         offsetof(CORCOMPILE_EE_INFO_TABLE, addrOfJMCFlag));
2014     return NULL;
2015 }
2016
2017 ZapImport * ZapInfo::GetProfilingHandleImport()
2018 {
2019     if (m_pProfilingHandle == NULL)
2020     {
2021         ZapImport * pImport = m_pImage->GetImportTable()->GetProfilingHandleImport(m_currentMethodHandle);
2022         AppendImport(pImport);
2023
2024         m_pProfilingHandle = pImport;
2025     }
2026
2027     return m_pProfilingHandle;
2028 }
2029
2030 void ZapInfo::GetProfilingHandle(BOOL                      *pbHookFunction,
2031                                  void                     **pProfilerHandle,
2032                                  BOOL                      *pbIndirectedHandles)
2033 {
2034     //
2035     // Return the location within the fixup table
2036     //
2037     // Profiling handle is opaque token. It does not have to be aligned thus we can not store it in the same location as token.
2038     //
2039     *pProfilerHandle = m_pImage->GetInnerPtr(GetProfilingHandleImport(), kZapProfilingHandleImportValueIndexClientData * sizeof(TADDR));
2040
2041     // All functions get hooked in ngen /Profile
2042     *pbHookFunction = TRUE;
2043
2044     //
2045     // This is the NGEN case, where we always do indirection on the handle so we can fix it up at load time.
2046     //
2047     *pbIndirectedHandles = TRUE;
2048 }
2049
2050 //return a callable stub that will do the virtual or interface call
2051
2052
2053 void ZapInfo::getCallInfo(CORINFO_RESOLVED_TOKEN * pResolvedToken,
2054                           CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken,
2055                           CORINFO_METHOD_HANDLE   callerHandle,
2056                           CORINFO_CALLINFO_FLAGS  flags,
2057                           CORINFO_CALL_INFO       *pResult)
2058 {
2059     void * pTarget = NULL;
2060
2061     _ASSERTE(pResult);
2062
2063     // Fill in the kind of the virtual call.
2064     // We set kindOnly=true since we don't want the EE to actually give us
2065     // a call stub - instead we want to generate an indirection ourselves.
2066     m_pEEJitInfo->getCallInfo(pResolvedToken,
2067                               pConstrainedResolvedToken,
2068                               callerHandle,
2069                               /* REVISIT_TODO
2070                                * Addition of this flag.
2071                                */
2072                               (CORINFO_CALLINFO_FLAGS)(flags | CORINFO_CALLINFO_KINDONLY),
2073                               pResult);
2074
2075 #ifdef FEATURE_READYTORUN_COMPILER
2076     if (IsReadyToRunCompilation())
2077     {
2078         if (pResult->sig.isVarArg())
2079         {
2080             m_zapper->Warning(W("ReadyToRun: VarArg methods not supported\n"));
2081             ThrowHR(E_NOTIMPL);
2082         }
2083
2084         if (pResult->accessAllowed != CORINFO_ACCESS_ALLOWED)
2085         {
2086             m_zapper->Warning(W("ReadyToRun: Runtime method access checks not supported\n"));
2087             ThrowHR(E_NOTIMPL);
2088         }
2089
2090         if (pResult->methodFlags & CORINFO_FLG_SECURITYCHECK)
2091         {
2092             m_zapper->Warning(W("ReadyToRun: Methods with security checks not supported\n"));
2093             ThrowHR(E_NOTIMPL);
2094         }
2095
2096         if (GetCompileInfo()->IsNativeCallableMethod(pResult->hMethod))
2097         {
2098             m_zapper->Warning(W("ReadyToRun: References to methods with NativeCallableAttribute not supported\n"));
2099             ThrowHR(E_NOTIMPL);
2100         }
2101     }
2102 #endif
2103
2104     if (flags & CORINFO_CALLINFO_KINDONLY)
2105         return;
2106
2107     if (IsReadyToRunCompilation())
2108     {
2109         if (pResult->thisTransform == CORINFO_BOX_THIS)
2110         {
2111             // READYTORUN: FUTURE: Optionally create boxing stub at runtime
2112             ThrowHR(E_NOTIMPL);
2113         }
2114     }
2115
2116     // OK, if the EE said we're not doing a stub dispatch then just return the kind to
2117     // the caller.  No other kinds of virtual calls have extra information attached.
2118     switch (pResult->kind)
2119     {
2120     case CORINFO_VIRTUALCALL_STUB:
2121         {
2122             if (pResult->stubLookup.lookupKind.needsRuntimeLookup)
2123             {
2124                                 if (!IsReadyToRunCompilation())
2125                                         embedGenericSignature(&pResult->stubLookup);
2126                 return;
2127             }
2128
2129 #ifdef FEATURE_READYTORUN_COMPILER
2130             if (IsReadyToRunCompilation())
2131             {
2132                 ZapImport * pImport = m_pImage->GetImportTable()->GetStubDispatchCell(pResolvedToken);
2133
2134                 pResult->stubLookup.constLookup.accessType   = IAT_PVALUE;
2135                 pResult->stubLookup.constLookup.addr         = pImport;
2136                 break;
2137             }
2138 #endif
2139
2140             CORINFO_CLASS_HANDLE calleeOwner = pResolvedToken->hClass;
2141             CORINFO_METHOD_HANDLE callee = pResolvedToken->hMethod;
2142             _ASSERTE(callee == pResult->hMethod);
2143
2144             //
2145             // Create the indirection cell
2146             //
2147             pTarget = m_pImage->GetImportTable()->GetStubDispatchCell(calleeOwner, callee);
2148
2149             pResult->stubLookup.constLookup.accessType = IAT_PVALUE;
2150
2151             pResult->stubLookup.constLookup.addr = pTarget;
2152         }
2153         break;
2154
2155
2156     case CORINFO_CALL_CODE_POINTER:
2157         _ASSERTE(pResult->codePointerLookup.lookupKind.needsRuntimeLookup);
2158                 if (!IsReadyToRunCompilation())
2159                         embedGenericSignature(&pResult->codePointerLookup);
2160
2161         // There is no easy way to detect method referenced via generic lookups in generated code.
2162         // Report this method reference unconditionally.
2163         m_pImage->m_pPreloader->MethodReferencedByCompiledCode(pResult->hMethod);
2164         return;
2165
2166     case CORINFO_CALL:
2167 #ifdef FEATURE_READYTORUN_COMPILER
2168         if (IsReadyToRunCompilation())
2169         {
2170             // Constrained token is not interesting with this transforms
2171             if (pResult->thisTransform != CORINFO_NO_THIS_TRANSFORM)
2172                 pConstrainedResolvedToken = NULL;
2173
2174             ZapImport * pImport;
2175
2176             if (flags & (CORINFO_CALLINFO_LDFTN | CORINFO_CALLINFO_ATYPICAL_CALLSITE))
2177             {
2178                 pImport = m_pImage->GetImportTable()->GetMethodImport(ENCODE_METHOD_ENTRY, pResult->hMethod, pResolvedToken, pConstrainedResolvedToken);
2179
2180                 AppendConditionalImport(pImport);
2181             }
2182             else
2183             {
2184                 pImport = m_pImage->GetImportTable()->GetExternalMethodCell(pResult->hMethod, pResolvedToken, pConstrainedResolvedToken);
2185             }
2186
2187             // READYTORUN: FUTURE: Direct calls if possible
2188             pResult->codePointerLookup.constLookup.accessType   = IAT_PVALUE;
2189             pResult->codePointerLookup.constLookup.addr         = pImport;
2190         }
2191 #endif
2192         break;
2193
2194     case CORINFO_VIRTUALCALL_VTABLE:
2195         _ASSERTE(!IsReadyToRunCompilation());
2196         break;
2197
2198     case CORINFO_VIRTUALCALL_LDVIRTFTN:
2199 #ifdef FEATURE_READYTORUN_COMPILER
2200                 if (IsReadyToRunCompilation() && !pResult->exactContextNeedsRuntimeLookup)
2201                 {
2202                         DWORD fAtypicalCallsite = (flags & CORINFO_CALLINFO_ATYPICAL_CALLSITE) ? CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE : 0;
2203
2204                         ZapImport * pImport = m_pImage->GetImportTable()->GetDynamicHelperCell(
2205                                 (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_VIRTUAL_ENTRY | fAtypicalCallsite), pResult->hMethod, pResolvedToken);
2206
2207                         pResult->codePointerLookup.constLookup.accessType = IAT_PVALUE;
2208                         pResult->codePointerLookup.constLookup.addr = pImport;
2209
2210                         _ASSERTE(!pResult->sig.hasTypeArg());
2211                 }
2212 #endif
2213
2214         // Include the declaring instantiation of virtual generic methods in the NGen image.
2215         m_pImage->m_pPreloader->AddMethodToTransitiveClosureOfInstantiations(pResult->hMethod);
2216         break;
2217
2218     default:
2219         _ASSERTE(!"Unknown call type");
2220         break;
2221     }
2222
2223 #ifdef FEATURE_READYTORUN_COMPILER
2224     if (IsReadyToRunCompilation() && pResult->sig.hasTypeArg())
2225     {
2226         if (pResult->exactContextNeedsRuntimeLookup)
2227         {
2228                         // Nothing to do... The generic handle lookup gets embedded in to the codegen
2229                         // during the jitting of the call.
2230                         // (Note: The generic lookup in R2R is performed by a call to a helper at runtime, not by
2231                         // codegen emitted at crossgen time)
2232         }
2233         else
2234         {
2235             ZapImport * pImport;
2236             if (((SIZE_T)pResult->contextHandle & CORINFO_CONTEXTFLAGS_MASK) == CORINFO_CONTEXTFLAGS_METHOD)
2237             {
2238                 CORINFO_METHOD_HANDLE exactMethodHandle = (CORINFO_METHOD_HANDLE)((SIZE_T)pResult->contextHandle & ~CORINFO_CONTEXTFLAGS_MASK);
2239
2240                 pImport = m_pImage->GetImportTable()->GetMethodImport(ENCODE_METHOD_DICTIONARY, exactMethodHandle, 
2241                     pResolvedToken, pConstrainedResolvedToken);
2242             }
2243             else
2244             {
2245                 pImport = m_pImage->GetImportTable()->GetClassImport(ENCODE_TYPE_DICTIONARY,
2246                     (pConstrainedResolvedToken != NULL) ? pConstrainedResolvedToken : pResolvedToken);
2247             }
2248
2249             pResult->instParamLookup.accessType   = IAT_PVALUE;
2250             pResult->instParamLookup.addr         = pImport;
2251
2252             AppendConditionalImport(pImport);
2253         }
2254     }
2255 #endif
2256 }
2257 BOOL ZapInfo::canAccessFamily(CORINFO_METHOD_HANDLE hCaller,
2258                               CORINFO_CLASS_HANDLE hInstanceType)
2259 {
2260     return m_pEEJitInfo->canAccessFamily(hCaller, hInstanceType);
2261 }
2262
2263 BOOL ZapInfo::isRIDClassDomainID (CORINFO_CLASS_HANDLE cls)
2264 {
2265     return m_pEEJitInfo->isRIDClassDomainID(cls);
2266 }
2267
2268
2269 unsigned ZapInfo::getClassDomainID (CORINFO_CLASS_HANDLE cls, void **ppIndirection)
2270 {
2271     _ASSERTE(ppIndirection != NULL);
2272
2273     m_pImage->m_pPreloader->AddTypeToTransitiveClosureOfInstantiations(cls);
2274
2275     if (!m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE))
2276     {
2277         if (isRIDClassDomainID(cls))
2278         {
2279             // Token is invariant to loading order, so we can go ahead and use it
2280             
2281             // Ensure that 'cls' gets added to CORCOMPILE_LOAD_TABLE, unless
2282             // someone else adds some other type of fixup for 'cls'.
2283             m_ClassLoadTable.Load(cls, FALSE);
2284             
2285             return m_pEEJitInfo->getClassDomainID(cls, ppIndirection);
2286         }
2287
2288         if (m_pImage->m_pPreloader->CanEmbedClassID(cls))
2289         {
2290             // Ensure that 'cls' gets added to CORCOMPILE_LOAD_TABLE, unless
2291             // someone else adds some other type of fixup for 'cls'.
2292             m_ClassLoadTable.Load(cls, FALSE);
2293             return m_pEEJitInfo->getClassDomainID(cls, ppIndirection);
2294         }
2295     }
2296     
2297     // We will have to insert a fixup
2298     ZapImport * pImport = m_pImage->GetImportTable()->GetClassDomainIdImport(cls);
2299     AppendConditionalImport(pImport);
2300
2301     *ppIndirection = pImport;
2302     return NULL;
2303 }
2304
2305 void * ZapInfo::getFieldAddress(CORINFO_FIELD_HANDLE field, void **ppIndirection)
2306 {
2307     _ASSERTE(ppIndirection != NULL);
2308
2309     CORINFO_CLASS_HANDLE hClass = m_pEEJitInfo->getFieldClass(field);
2310
2311     m_pImage->m_pPreloader->AddTypeToTransitiveClosureOfInstantiations(hClass);
2312
2313     ZapImport * pImport = m_pImage->GetImportTable()->GetStaticFieldAddressImport(field);
2314     AppendConditionalImport(pImport);
2315
2316     // Field address is not aligned thus we can not store it in the same location as token.
2317     *ppIndirection = m_pImage->GetInnerPtr(pImport, sizeof(TADDR));
2318
2319     return NULL;
2320 }
2321
2322 DWORD ZapInfo::getFieldThreadLocalStoreID(CORINFO_FIELD_HANDLE field,
2323                                           void **ppIndirection)
2324 {
2325     _ASSERTE(ppIndirection != NULL);
2326
2327     *ppIndirection = m_pImage->GetInnerPtr(m_pImage->m_pEEInfoTable,
2328         offsetof(CORCOMPILE_EE_INFO_TABLE, rvaStaticTlsIndex));
2329     return NULL;
2330 }
2331
2332 CORINFO_VARARGS_HANDLE ZapInfo::getVarArgsHandle(CORINFO_SIG_INFO *sig,
2333                                                  void **ppIndirection)
2334 {
2335     _ASSERTE(ppIndirection != NULL);
2336
2337     // Zapper does not support embedding these as they are created dynamically
2338
2339     if (sig->scope != m_pImage->m_hModule || sig->token == mdTokenNil)
2340     {
2341         _ASSERTE(!"Don't have enough info to be able to create a sig token.");
2342
2343         *ppIndirection = NULL;
2344         return NULL;
2345     }
2346
2347     // @perf: If the sig cookie construction code actually will restore the value types in
2348     // the sig, we should call LoadClass on all of those types to avoid redundant
2349     // restore cookies.
2350
2351     ZapImport * pImport = m_pImage->GetImportTable()->GetVarArgImport(sig->scope, sig->token);
2352     AppendConditionalImport(pImport);
2353
2354     *ppIndirection = pImport;
2355     return NULL;
2356 }
2357
2358 bool ZapInfo::canGetVarArgsHandle(CORINFO_SIG_INFO *sig)
2359 {
2360     // Zapper does not support embedding these as they are created dynamically
2361     if (sig->scope != m_pImage->m_hModule || sig->token == mdTokenNil)
2362     {
2363         return false;
2364     }
2365
2366     return true;
2367 }
2368
2369 void ZapInfo::setOverride(ICorDynamicInfo *pOverride, CORINFO_METHOD_HANDLE currentMethod)
2370 {
2371     UNREACHABLE();
2372 }
2373
2374 void ZapInfo::addActiveDependency(CORINFO_MODULE_HANDLE moduleFrom, CORINFO_MODULE_HANDLE moduleTo)
2375 {
2376     if (IsReadyToRunCompilation())
2377         return;
2378
2379     _ASSERT(moduleFrom != moduleTo);
2380
2381     if (m_pImage->m_pPreloader->CanSkipDependencyActivation(m_currentMethodHandle, moduleFrom, moduleTo))
2382     {
2383         // No need to add dependency fixup since we will have an unconditional dependency
2384         // already
2385     }
2386     else if (!GetCompileInfo()->IsInCurrentVersionBubble(moduleTo))
2387     {
2388     }
2389     else
2390     {
2391         ZapImport * pImport = m_pImage->GetImportTable()->GetActiveDependencyImport(moduleFrom, moduleTo);
2392         AppendImport(pImport);
2393
2394         CORINFO_DEPENDENCY dep;
2395         dep.moduleFrom = moduleFrom;
2396         dep.moduleTo   = moduleTo;
2397     }
2398 }
2399
2400
2401 InfoAccessType
2402     ZapInfo::constructStringLiteral(CORINFO_MODULE_HANDLE tokenScope,
2403                                          unsigned metaTok, void **ppValue)
2404 {
2405     if (m_pEECompileInfo->IsEmptyString(metaTok, tokenScope))
2406     {
2407         return emptyStringLiteral(ppValue);
2408     }
2409
2410     ZapImport * pImport = m_pImage->GetImportTable()->GetStringHandleImport(tokenScope, metaTok);
2411     AppendConditionalImport(pImport);
2412
2413     *ppValue = pImport;
2414
2415     return IAT_PPVALUE;
2416 }
2417
2418 InfoAccessType ZapInfo::emptyStringLiteral(void **ppValue)
2419 {
2420 #ifdef FEATURE_READYTORUN_COMPILER
2421     if (IsReadyToRunCompilation())
2422     {
2423         ZapImport * pImport = m_pImage->GetImportTable()->GetStringHandleImport(m_pImage->m_hModule, mdtString);
2424         *ppValue = pImport;
2425         return IAT_PPVALUE;
2426     }
2427 #endif
2428
2429     *ppValue = m_pImage->GetInnerPtr(m_pImage->m_pEEInfoTable,
2430         offsetof(CORCOMPILE_EE_INFO_TABLE, emptyString));
2431
2432     return IAT_PPVALUE;
2433 }
2434
2435 void ZapInfo::recordCallSite(ULONG instrOffset, CORINFO_SIG_INFO *callSig, CORINFO_METHOD_HANDLE methodHandle)
2436 {
2437     return;
2438 }
2439
2440 void ZapInfo::recordRelocation(void *location, void *target,
2441                                WORD fRelocType, WORD slotNum, INT32 addlDelta)
2442 {
2443     // Factor slotNum into the location address
2444     switch (fRelocType)
2445     {
2446     case IMAGE_REL_BASED_ABSOLUTE:
2447     case IMAGE_REL_BASED_PTR:
2448 #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
2449     case IMAGE_REL_BASED_REL32:
2450 #endif // _TARGET_X86_ || _TARGET_AMD64_
2451         location = (PBYTE)location + slotNum;
2452         break;
2453
2454 #if defined(_TARGET_ARM_)
2455     case IMAGE_REL_BASED_THUMB_MOV32:
2456     case IMAGE_REL_BASED_REL_THUMB_MOV32_PCREL:
2457     case IMAGE_REL_BASED_THUMB_BRANCH24:
2458
2459 # ifdef _DEBUG
2460     {
2461         CORJIT_FLAGS jitFlags = m_zapper->m_pOpt->m_compilerFlags;
2462
2463         if (jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_RELATIVE_CODE_RELOCS))
2464         {
2465             _ASSERTE(fRelocType == IMAGE_REL_BASED_REL_THUMB_MOV32_PCREL
2466                      || fRelocType == IMAGE_REL_BASED_THUMB_BRANCH24);
2467         }
2468         else
2469         {
2470             _ASSERTE(fRelocType == IMAGE_REL_BASED_THUMB_MOV32
2471                      || fRelocType == IMAGE_REL_BASED_THUMB_BRANCH24);
2472         }
2473     }
2474 # endif // _DEBUG
2475         break;
2476 #endif
2477
2478 #if defined(_TARGET_ARM64_)
2479     case IMAGE_REL_ARM64_BRANCH26:
2480     case IMAGE_REL_ARM64_PAGEBASE_REL21:
2481     case IMAGE_REL_ARM64_PAGEOFFSET_12A:
2482         break;
2483 #endif
2484
2485     default:
2486         _ASSERTE(!"Unknown reloc type");
2487         break;
2488     }
2489
2490     ZapBlobWithRelocs * knownNodes[] =
2491     {
2492         m_pCode,
2493         m_pColdCode,
2494         m_pROData,
2495         m_pProfileData
2496     };
2497
2498     //
2499     // The location of the relocation reported by the JIT has to fall into one of the code or data blobs
2500     //
2501
2502     CodeRelocation r;
2503
2504     ZapBlobWithRelocs * pSrcNode = NULL;
2505     for (size_t i = 0; i < _countof(knownNodes); i++)
2506     {
2507         ZapBlobWithRelocs * pNode = knownNodes[i];
2508         if (pNode == NULL)
2509             continue;
2510
2511         if (pNode->GetData() <= location && location < pNode->GetData() + pNode->GetSize())
2512         {
2513             pSrcNode = pNode;
2514             break;
2515         }
2516     }
2517     PREFIX_ASSUME(pSrcNode != NULL);
2518     r.m_pNode = pSrcNode;
2519     r.m_offset = (DWORD)((PBYTE)location - (PBYTE)pSrcNode->GetData());
2520
2521     //
2522     // The target of the relocation reported by the JIT can be one of:
2523     //  - Inner pointer into into one of the code or data blobs. We can detect this case by searching
2524     //    through the blobs.
2525     //  - Hardbound target. We can detect this case by searching through all hardbound assemblies.
2526     //  - Otherwise, it has to be ZapNode *.
2527     //
2528
2529     ZapNode * pTargetNode = NULL;
2530     INT32 targetOffset = 0;
2531     for (size_t i = 0; i < _countof(knownNodes); i++)
2532     {
2533         ZapBlobWithRelocs * pNode = knownNodes[i];
2534         if (pNode == NULL)
2535             continue;
2536
2537         if (pNode->GetData() <= target && target < pNode->GetData() + pNode->GetSize())
2538         {
2539             pTargetNode = pNode;
2540             targetOffset = (INT32)((PBYTE)target - (PBYTE)pNode->GetData());
2541             break;
2542         }
2543     }
2544
2545     if (pTargetNode != NULL)
2546     {
2547         r.m_pTargetNode = pTargetNode;
2548     }
2549     else
2550     {
2551         // Must be ZapNode otherwise
2552         pTargetNode = (ZapNode *)target;
2553         _ASSERTE(pTargetNode->GetType() != ZapNodeType_Unknown);
2554         r.m_pTargetNode = pTargetNode;
2555     }
2556
2557     r.m_type = (ZapRelocationType)fRelocType;
2558
2559     switch (fRelocType)
2560     {
2561     case IMAGE_REL_BASED_ABSOLUTE:
2562         *(UNALIGNED DWORD *)location = (DWORD)targetOffset;
2563         break;
2564
2565     case IMAGE_REL_BASED_PTR:
2566         *(UNALIGNED TADDR *)location = (TADDR)targetOffset;
2567         break;
2568
2569 #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
2570     case IMAGE_REL_BASED_REL32:
2571         *(UNALIGNED INT32 *)location = targetOffset + addlDelta;
2572         break;
2573 #endif // _TARGET_X86_ || _TARGET_AMD64_
2574
2575 #if defined(_TARGET_ARM_)
2576     case IMAGE_REL_BASED_THUMB_MOV32:
2577     case IMAGE_REL_BASED_REL_THUMB_MOV32_PCREL:
2578         PutThumb2Mov32((UINT16 *)location, targetOffset);
2579         break;
2580
2581     case IMAGE_REL_BASED_THUMB_BRANCH24:
2582         if (!FitsInThumb2BlRel24(targetOffset))
2583             ThrowHR(COR_E_OVERFLOW);
2584         PutThumb2BlRel24((UINT16 *)location, targetOffset);
2585         break;
2586 #endif
2587
2588 #if defined(_TARGET_ARM64_)
2589     case IMAGE_REL_ARM64_BRANCH26:
2590         if (!FitsInRel28(targetOffset))
2591             ThrowHR(COR_E_OVERFLOW);
2592         PutArm64Rel28((UINT32 *)location, targetOffset);
2593         break;
2594     case IMAGE_REL_ARM64_PAGEBASE_REL21:
2595         if (!FitsInRel21(targetOffset))
2596             ThrowHR(COR_E_OVERFLOW);
2597         PutArm64Rel21((UINT32 *)location, targetOffset);
2598         break;
2599
2600     case IMAGE_REL_ARM64_PAGEOFFSET_12A:
2601         if (!FitsInRel12(targetOffset))
2602             ThrowHR(COR_E_OVERFLOW);
2603         PutArm64Rel12((UINT32 *)location, targetOffset);
2604         break;
2605 #endif
2606
2607     default:
2608         _ASSERTE(!"Unknown reloc type");
2609         break;
2610     }
2611
2612     if (m_CodeRelocations.IsEmpty())
2613     {
2614         SIZE_T totalCodeSize = m_pCode->GetSize() + ((m_pColdCode != NULL) ? m_pColdCode->GetSize() : 0);
2615
2616         // Prealocate relocations (assume that every other pointer may need relocation)
2617         COUNT_T nEstimatedRelocations = (COUNT_T)(totalCodeSize / (2 * sizeof(TADDR)));
2618         if (nEstimatedRelocations > 1)
2619             m_CodeRelocations.Preallocate(nEstimatedRelocations);
2620     }
2621
2622     m_CodeRelocations.Append(r);
2623 }
2624
2625 WORD ZapInfo::getRelocTypeHint(void * target)
2626 {
2627 #ifdef _TARGET_AMD64_
2628     // There should be no external pointers
2629     return IMAGE_REL_BASED_REL32;
2630 #elif defined(_TARGET_ARM_)
2631     // Use full 32-bit branch targets when retrying compilation on ARM
2632     if (m_zapper->m_pOpt->m_fNGenLastRetry)
2633         return (WORD)-1;
2634     return IMAGE_REL_BASED_THUMB_BRANCH24;
2635 #elif defined(_TARGET_ARM64_)
2636     return IMAGE_REL_ARM64_BRANCH26;
2637 #else
2638     // No hints
2639     return (WORD)-1;
2640 #endif
2641 }
2642
2643 void ZapInfo::getModuleNativeEntryPointRange(void** pStart, void** pEnd)
2644 {
2645     ULONG rvaStart, rvaEnd;
2646
2647     // Initialize outparams to default range of (0,0).
2648     *pStart = 0;
2649     *pEnd = 0;
2650 }
2651
2652 DWORD ZapInfo::getExpectedTargetArchitecture()
2653 {
2654     return IMAGE_FILE_MACHINE_NATIVE;
2655 }
2656
2657 CORINFO_METHOD_HANDLE ZapInfo::GetDelegateCtor(CORINFO_METHOD_HANDLE   methHnd,
2658                                                CORINFO_CLASS_HANDLE    clsHnd,
2659                                                CORINFO_METHOD_HANDLE   targetMethodHnd,
2660                                                DelegateCtorArgs *      pCtorData)
2661 {
2662     // For ReadyToRun, this optimization is done via ZapInfo::getReadyToRunDelegateCtorHelper
2663     if (IsReadyToRunCompilation())
2664         return methHnd;
2665
2666     // forward the call to the standard GetDelegateCtor
2667     CORINFO_METHOD_HANDLE delegateCtor = m_pEEJitInfo->GetDelegateCtor(methHnd, clsHnd, targetMethodHnd, pCtorData);
2668     if (delegateCtor != methHnd)
2669     {
2670         if (pCtorData->pArg4)
2671         {
2672             // cannot optimize any secure delegate, give up
2673             delegateCtor = methHnd;
2674         }
2675         else if (pCtorData->pArg3)
2676         {
2677             pCtorData->pArg3 = m_pImage->GetWrappers()->GetStub(pCtorData->pArg3);
2678         }
2679     }
2680     return delegateCtor;
2681 }
2682
2683 void ZapInfo::MethodCompileComplete(
2684             CORINFO_METHOD_HANDLE methHnd)
2685 {
2686     m_pEEJitInfo->MethodCompileComplete(methHnd);
2687 }
2688
2689
2690 //
2691 // ICorStaticInfo
2692 //
2693
2694 void ZapInfo::getEEInfo(CORINFO_EE_INFO *pEEInfoOut)
2695 {
2696     m_pEEJitInfo->getEEInfo(pEEInfoOut);
2697 }
2698
2699 LPCWSTR ZapInfo::getJitTimeLogFilename()
2700 {
2701     return m_pEEJitInfo->getJitTimeLogFilename();
2702 }
2703
2704 //
2705 // ICorArgInfo
2706 //
2707
2708 CORINFO_ARG_LIST_HANDLE ZapInfo::getArgNext(CORINFO_ARG_LIST_HANDLE args)
2709 {
2710     return m_pEEJitInfo->getArgNext(args);
2711 }
2712
2713 CorInfoTypeWithMod ZapInfo::getArgType(CORINFO_SIG_INFO* sig,
2714                                                CORINFO_ARG_LIST_HANDLE args,
2715                                                 CORINFO_CLASS_HANDLE *vcTypeRet)
2716 {
2717     return m_pEEJitInfo->getArgType(sig, args, vcTypeRet);
2718 }
2719
2720 CORINFO_CLASS_HANDLE ZapInfo::getArgClass(CORINFO_SIG_INFO* sig,
2721                                            CORINFO_ARG_LIST_HANDLE args)
2722 {
2723     return m_pEEJitInfo->getArgClass(sig, args);
2724 }
2725
2726 CorInfoType ZapInfo::getHFAType(CORINFO_CLASS_HANDLE hClass)
2727 {
2728     return m_pEEJitInfo->getHFAType(hClass);
2729 }
2730
2731 //
2732 // ICorDebugInfo
2733 //
2734
2735 void ZapInfo::getBoundaries(CORINFO_METHOD_HANDLE ftn, unsigned int *cILOffsets,
2736                              DWORD **pILOffsets, ICorDebugInfo::BoundaryTypes *implicitBoundaries)
2737 {
2738     m_pEEJitInfo->getBoundaries(ftn, cILOffsets, pILOffsets,
2739                                               implicitBoundaries);
2740 }
2741
2742 void ZapInfo::setBoundaries(CORINFO_METHOD_HANDLE ftn, ULONG32 cMap,
2743                                            ICorDebugInfo::OffsetMapping *pMap)
2744 {
2745     _ASSERTE(ftn == m_currentMethodHandle);
2746
2747     if (cMap == 0)
2748         return;
2749
2750     m_pOffsetMapping = pMap;
2751     m_iOffsetMapping = cMap;
2752     return;
2753 }
2754
2755 void ZapInfo::getVars(CORINFO_METHOD_HANDLE ftn,
2756                                     ULONG32 *cVars,
2757                                     ICorDebugInfo::ILVarInfo **vars,
2758                                     bool *extendOthers)
2759 {
2760     m_pEEJitInfo->getVars(ftn, cVars, vars, extendOthers);
2761 }
2762
2763 void ZapInfo::setVars(CORINFO_METHOD_HANDLE ftn,
2764                                     ULONG32 cVars,
2765                                     ICorDebugInfo::NativeVarInfo * vars)
2766 {
2767     _ASSERTE(ftn == m_currentMethodHandle);
2768
2769     if (cVars == 0)
2770         return;
2771
2772     m_pNativeVarInfo = vars;
2773     m_iNativeVarInfo = cVars;
2774
2775     return;
2776 }
2777
2778 void * ZapInfo::allocateArray(ULONG cBytes)
2779 {
2780     return new BYTE[cBytes];
2781 }
2782
2783 void ZapInfo::freeArray(void *array)
2784 {
2785     delete [] ((BYTE*) array);
2786 }
2787
2788 //
2789 // ICorFieldInfo
2790 //
2791
2792 const char* ZapInfo::getFieldName(CORINFO_FIELD_HANDLE ftn, const char **moduleName)
2793 {
2794     return m_pEEJitInfo->getFieldName(ftn, moduleName);
2795 }
2796
2797 CORINFO_CLASS_HANDLE ZapInfo::getFieldClass(CORINFO_FIELD_HANDLE field)
2798 {
2799     return m_pEEJitInfo->getFieldClass(field);
2800 }
2801
2802 CorInfoType ZapInfo::getFieldType(CORINFO_FIELD_HANDLE field,
2803                                   CORINFO_CLASS_HANDLE *structType,
2804                                   CORINFO_CLASS_HANDLE memberParent)
2805
2806 {
2807     return m_pEEJitInfo->getFieldType(field, structType, memberParent);
2808 }
2809
2810 unsigned ZapInfo::getFieldOffset(CORINFO_FIELD_HANDLE field)
2811 {
2812     return m_pEEJitInfo->getFieldOffset(field);
2813 }
2814
2815 bool ZapInfo::isWriteBarrierHelperRequired(
2816                         CORINFO_FIELD_HANDLE    field)
2817 {
2818     return m_pEEJitInfo->isWriteBarrierHelperRequired(field);
2819 }
2820
2821 void ZapInfo::getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken,
2822                             CORINFO_METHOD_HANDLE  callerHandle,
2823                             CORINFO_ACCESS_FLAGS   flags,
2824                             CORINFO_FIELD_INFO    *pResult)
2825 {
2826     m_pEEJitInfo->getFieldInfo(pResolvedToken, callerHandle, flags, pResult);
2827
2828 #ifdef FEATURE_READYTORUN_COMPILER
2829     CORINFO_EE_INFO eeInfo;
2830     m_pEEJitInfo->getEEInfo(&eeInfo);
2831
2832     if (IsReadyToRunCompilation())
2833     {
2834         if (pResult->accessAllowed != CORINFO_ACCESS_ALLOWED)
2835         {
2836             m_zapper->Warning(W("ReadyToRun: Runtime field access checks not supported\n"));
2837             ThrowHR(E_NOTIMPL);
2838         }
2839
2840         DWORD fAtypicalCallsite = (flags & CORINFO_ACCESS_ATYPICAL_CALLSITE) ? CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE : 0;
2841
2842         switch (pResult->fieldAccessor)
2843         {
2844         case CORINFO_FIELD_INSTANCE:
2845             {
2846                 DWORD dwBaseOffset = (DWORD)-1;
2847                 CORCOMPILE_FIXUP_BLOB_KIND fixupKind = m_pImage->GetCompileInfo()->GetFieldBaseOffset(pResolvedToken->hClass, &dwBaseOffset);
2848
2849                 switch (fixupKind)
2850                 {
2851                 case ENCODE_FIELD_OFFSET:
2852                     {
2853                         ZapImport * pImport = m_pImage->GetImportTable()->GetFieldImport(ENCODE_FIELD_OFFSET, pResolvedToken->hField, pResolvedToken);
2854
2855                         if (pResult->offset > eeInfo.maxUncheckedOffsetForNullObject / 2)
2856                         {
2857                             m_zapper->Warning(W("ReadyToRun: Cross-module instance fields with large offsets not supported\n"));
2858                             ThrowHR(E_NOTIMPL);
2859                         }
2860                         pResult->offset = 0;
2861
2862                         pResult->fieldAccessor = CORINFO_FIELD_INSTANCE_WITH_BASE;
2863
2864                         pResult->fieldLookup.accessType = IAT_PVALUE;
2865                         pResult->fieldLookup.addr = pImport;
2866
2867                         AppendImport(pImport);
2868                     }
2869                     break;
2870
2871                 case ENCODE_CHECK_FIELD_OFFSET:
2872                     {
2873                         ZapImport * pImport = m_pImage->GetImportTable()->GetCheckFieldOffsetImport(pResolvedToken->hField, pResolvedToken, pResult->offset);
2874                         AppendImport(pImport);
2875                     }
2876                     break;
2877
2878                 case ENCODE_FIELD_BASE_OFFSET:
2879                     {
2880                         ZapImport * pImport = m_pImage->GetImportTable()->GetClassImport(ENCODE_FIELD_BASE_OFFSET, pResolvedToken);
2881
2882                         if (pResult->offset > eeInfo.maxUncheckedOffsetForNullObject / 2)
2883                         {
2884                             m_zapper->Warning(W("ReadyToRun: Large objects crossing module boundaries not supported\n"));
2885                             ThrowHR(E_NOTIMPL);
2886                         }
2887                         _ASSERTE(pResult->offset >= dwBaseOffset);
2888                         pResult->offset -= dwBaseOffset;
2889
2890                         pResult->fieldAccessor = CORINFO_FIELD_INSTANCE_WITH_BASE;
2891
2892                         pResult->fieldLookup.accessType = IAT_PVALUE;
2893                         pResult->fieldLookup.addr = pImport;
2894
2895                         AppendImport(pImport);
2896                     }
2897                     break;
2898
2899                 case ENCODE_NONE:
2900                     break;
2901
2902                 default:
2903                     UNREACHABLE_MSG("Unexpected field base fixup");
2904                 }
2905             }
2906             break;
2907
2908         case CORINFO_FIELD_INSTANCE_HELPER:
2909         case CORINFO_FIELD_INSTANCE_ADDR_HELPER:
2910             m_zapper->Warning(W("ReadyToRun: Special instance fields not supported\n"));
2911             ThrowHR(E_NOTIMPL);
2912             break;
2913
2914         case CORINFO_FIELD_STATIC_SHARED_STATIC_HELPER:
2915             {
2916                 if (m_pImage->GetCompileInfo()->IsInCurrentVersionBubble(m_pEEJitInfo->getClassModule(pResolvedToken->hClass)))
2917                 {
2918                     CORCOMPILE_FIXUP_BLOB_KIND kind;
2919
2920                     switch (pResult->helper)
2921                     {
2922                     case CORINFO_HELP_GETSHARED_GCSTATIC_BASE:
2923                     case CORINFO_HELP_GETSHARED_GCSTATIC_BASE_NOCTOR:
2924                     case CORINFO_HELP_GETSHARED_GCSTATIC_BASE_DYNAMICCLASS:
2925                         kind = ENCODE_STATIC_BASE_GC_HELPER;
2926                         break;
2927                     case CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE:
2928                     case CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_NOCTOR:
2929                     case CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_DYNAMICCLASS:
2930                         kind = ENCODE_STATIC_BASE_NONGC_HELPER;
2931                         break;
2932                     case CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE:
2933                     case CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR:
2934                     case CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_DYNAMICCLASS:
2935                         kind = ENCODE_THREAD_STATIC_BASE_GC_HELPER;
2936                         break;
2937                     case CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE:
2938                     case CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR:
2939                     case CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_DYNAMICCLASS:
2940                         kind = ENCODE_THREAD_STATIC_BASE_NONGC_HELPER;
2941                         break;
2942                     default:
2943                         UNREACHABLE_MSG("Unexpected static helper");
2944                     }
2945
2946                     ZapImport * pImport = m_pImage->GetImportTable()->GetDynamicHelperCell(
2947                         (CORCOMPILE_FIXUP_BLOB_KIND)(kind | fAtypicalCallsite), pResolvedToken->hClass);
2948
2949                     pResult->fieldLookup.accessType = IAT_PVALUE;
2950                     pResult->fieldLookup.addr = pImport;
2951
2952                     pResult->helper = CORINFO_HELP_READYTORUN_STATIC_BASE;
2953                 }
2954                 else
2955                 {
2956                     ZapImport * pImport = m_pImage->GetImportTable()->GetDynamicHelperCell(
2957                         (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_FIELD_ADDRESS | fAtypicalCallsite), pResolvedToken->hField, pResolvedToken);
2958
2959                     pResult->fieldLookup.accessType = IAT_PVALUE;
2960                     pResult->fieldLookup.addr = pImport;
2961
2962                     pResult->helper = CORINFO_HELP_READYTORUN_STATIC_BASE;
2963
2964                     pResult->offset = 0;
2965                     pResult->fieldFlags &= ~CORINFO_FLG_FIELD_STATIC_IN_HEAP; // The dynamic helper takes care of the unboxing
2966                 }
2967             }
2968             break;
2969
2970         case CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER:
2971                 {
2972                         // Nothing to do... The generic handle lookup gets embedded in to the codegen
2973                         // during the jitting of the field lookup.
2974                         // (Note: The generic lookup in R2R is performed by a call to a helper at runtime, not by
2975                         // codegen emitted at crossgen time)
2976                         // TODO: replace the call to the generic lookup helper and the call to the static helper function
2977                         // with a single call to a R2R cell that performs:
2978                         //      1) Generic handle lookup
2979                         //      2) Computes the statics base address
2980                         //      3) Generates a stub for subsequent lookups that includes dictionary access
2981                         // (For perf reasons)
2982                 }
2983             break;
2984
2985         case CORINFO_FIELD_STATIC_ADDRESS:           // field at given address
2986         case CORINFO_FIELD_STATIC_RVA_ADDRESS:       // RVA field at given address
2987         case CORINFO_FIELD_STATIC_ADDR_HELPER:       // static field accessed using address-of helper (argument is FieldDesc *)
2988         case CORINFO_FIELD_STATIC_TLS:
2989             m_zapper->Warning(W("ReadyToRun: Rare kinds of static fields not supported\n"));
2990             ThrowHR(E_NOTIMPL);
2991             break;
2992
2993         case CORINFO_FIELD_INTRINSIC_ZERO:
2994         case CORINFO_FIELD_INTRINSIC_EMPTY_STRING:
2995         case CORINFO_FIELD_INTRINSIC_ISLITTLEENDIAN:
2996             break;
2997
2998         default:
2999             UNREACHABLE_MSG("Unexpected field acccess type");
3000         }
3001     }
3002 #endif // FEATURE_READYTORUN_COMPILER
3003 }
3004
3005 bool ZapInfo::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd)
3006 {
3007     return m_pEEJitInfo->isFieldStatic(fldHnd);
3008 }
3009
3010 //
3011 // ICorClassInfo
3012 //
3013
3014 CorInfoType ZapInfo::asCorInfoType(CORINFO_CLASS_HANDLE cls)
3015 {
3016     return m_pEEJitInfo->asCorInfoType(cls);
3017 }
3018
3019 const char* ZapInfo::getClassName(CORINFO_CLASS_HANDLE cls)
3020 {
3021     return m_pEEJitInfo->getClassName(cls);
3022 }
3023
3024 const char* ZapInfo::getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName)
3025 {
3026     return m_pEEJitInfo->getClassNameFromMetadata(cls, namespaceName);
3027 }
3028
3029 CORINFO_CLASS_HANDLE ZapInfo::getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index)
3030 {
3031     return m_pEEJitInfo->getTypeInstantiationArgument(cls, index);
3032 }
3033
3034 const char* ZapInfo::getHelperName(CorInfoHelpFunc func)
3035 {
3036     return m_pEEJitInfo->getHelperName(func);
3037 }
3038
3039 int ZapInfo::appendClassName(__deref_inout_ecount(*pnBufLen) WCHAR** ppBuf, int* pnBufLen,
3040                              CORINFO_CLASS_HANDLE    cls,
3041                              BOOL fNamespace,
3042                              BOOL fFullInst,
3043                              BOOL fAssembly)
3044 {
3045     return m_pEEJitInfo->appendClassName(ppBuf,pnBufLen,cls,fNamespace,fFullInst,fAssembly);
3046 }
3047
3048 BOOL ZapInfo::isValueClass(CORINFO_CLASS_HANDLE cls)
3049 {
3050     return m_pEEJitInfo->isValueClass(cls);
3051 }
3052
3053 BOOL ZapInfo::canInlineTypeCheckWithObjectVTable (CORINFO_CLASS_HANDLE cls)
3054 {
3055     return m_pEEJitInfo->canInlineTypeCheckWithObjectVTable(cls);
3056 }
3057
3058 DWORD ZapInfo::getClassAttribs(CORINFO_CLASS_HANDLE cls)
3059 {
3060     return m_pEEJitInfo->getClassAttribs(cls);
3061 }
3062
3063 BOOL ZapInfo::isStructRequiringStackAllocRetBuf(CORINFO_CLASS_HANDLE cls)
3064 {
3065     return m_pEEJitInfo->isStructRequiringStackAllocRetBuf(cls);
3066 }
3067
3068 CorInfoInitClassResult ZapInfo::initClass(
3069             CORINFO_FIELD_HANDLE    field,
3070             CORINFO_METHOD_HANDLE   method,
3071             CORINFO_CONTEXT_HANDLE  context,
3072             BOOL                    speculative)
3073 {
3074     return m_pEEJitInfo->initClass(field, method, context, speculative);
3075 }
3076
3077 void ZapInfo::classMustBeLoadedBeforeCodeIsRun(CORINFO_CLASS_HANDLE cls)
3078 {
3079     // This adds an entry to the table of fixups.  The table gets iterated later
3080     // to add entries to the delayed fixup list for the code being generated.
3081     m_ClassLoadTable.Load(cls, FALSE);
3082 }
3083
3084 CORINFO_METHOD_HANDLE ZapInfo::mapMethodDeclToMethodImpl(CORINFO_METHOD_HANDLE methHnd)
3085 {
3086     return (CORINFO_METHOD_HANDLE)m_pEEJitInfo->mapMethodDeclToMethodImpl(methHnd);
3087 }
3088
3089 void ZapInfo::methodMustBeLoadedBeforeCodeIsRun(CORINFO_METHOD_HANDLE meth)
3090 {
3091     // This adds an entry to the table of fixups.  The table gets iterated later
3092     // to add entries to the delayed fixup list for the code being generated.
3093     m_MethodLoadTable.Load(meth, FALSE);
3094 }
3095
3096 CORINFO_CLASS_HANDLE ZapInfo::getBuiltinClass(CorInfoClassId classId)
3097 {
3098     return m_pEEJitInfo->getBuiltinClass(classId);
3099 }
3100
3101 CorInfoType ZapInfo::getTypeForPrimitiveValueClass(CORINFO_CLASS_HANDLE cls)
3102 {
3103     return m_pEEJitInfo->getTypeForPrimitiveValueClass(cls);
3104 }
3105
3106 CorInfoType ZapInfo::getTypeForPrimitiveNumericClass(CORINFO_CLASS_HANDLE cls)
3107 {
3108     return m_pEEJitInfo->getTypeForPrimitiveNumericClass(cls);
3109 }
3110
3111 BOOL ZapInfo::canCast(CORINFO_CLASS_HANDLE child,
3112                                 CORINFO_CLASS_HANDLE parent)
3113 {
3114     return m_pEEJitInfo->canCast(child, parent);
3115 }
3116
3117 BOOL ZapInfo::areTypesEquivalent(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
3118 {
3119     return m_pEEJitInfo->areTypesEquivalent(cls1, cls2);
3120 }
3121
3122 TypeCompareState ZapInfo::compareTypesForCast(CORINFO_CLASS_HANDLE fromClass, CORINFO_CLASS_HANDLE toClass)
3123 {
3124     return m_pEEJitInfo->compareTypesForCast(fromClass, toClass);
3125 }
3126
3127 TypeCompareState ZapInfo::compareTypesForEquality(CORINFO_CLASS_HANDLE cls1, CORINFO_CLASS_HANDLE cls2)
3128 {
3129     return m_pEEJitInfo->compareTypesForEquality(cls1, cls2);
3130 }
3131
3132 CORINFO_CLASS_HANDLE ZapInfo::mergeClasses(
3133                                 CORINFO_CLASS_HANDLE cls1,
3134                                 CORINFO_CLASS_HANDLE cls2)
3135 {
3136     return m_pEEJitInfo->mergeClasses(cls1, cls2);
3137 }
3138
3139 BOOL ZapInfo::shouldEnforceCallvirtRestriction(
3140         CORINFO_MODULE_HANDLE scopeHnd)
3141 {
3142     return m_zapper->m_pEEJitInfo->shouldEnforceCallvirtRestriction(scopeHnd);
3143 }
3144
3145 CORINFO_CLASS_HANDLE ZapInfo::getParentType (
3146                                 CORINFO_CLASS_HANDLE       cls)
3147 {
3148     return m_pEEJitInfo->getParentType(cls);
3149 }
3150
3151 CorInfoType ZapInfo::getChildType (
3152             CORINFO_CLASS_HANDLE       clsHnd,
3153             CORINFO_CLASS_HANDLE       *clsRet)
3154 {
3155     return m_pEEJitInfo->getChildType(clsHnd, clsRet);
3156 }
3157
3158 BOOL ZapInfo::satisfiesClassConstraints(
3159             CORINFO_CLASS_HANDLE cls)
3160 {
3161     return m_pEEJitInfo->satisfiesClassConstraints(cls);
3162 }
3163
3164 BOOL ZapInfo::isSDArray(CORINFO_CLASS_HANDLE cls)
3165 {
3166     return m_pEEJitInfo->isSDArray(cls);
3167 }
3168
3169 unsigned ZapInfo::getArrayRank(CORINFO_CLASS_HANDLE cls)
3170 {
3171     return m_pEEJitInfo->getArrayRank(cls);
3172 }
3173
3174 void * ZapInfo::getArrayInitializationData(CORINFO_FIELD_HANDLE field, DWORD size)
3175 {
3176     if (m_pEEJitInfo->getClassModule(m_pEEJitInfo->getFieldClass(field)) != m_pImage->m_hModule)
3177         return NULL;
3178
3179     void * arrayData = m_pEEJitInfo->getArrayInitializationData(field, size);
3180     if (!arrayData)
3181         return NULL;
3182
3183 #ifdef FEATURE_READYTORUN_COMPILER
3184     if (IsReadyToRunCompilation())
3185         return m_pImage->m_pILMetaData->GetRVAField(arrayData);
3186 #endif
3187
3188     return (void *) m_pImage->GetWrappers()->GetGenericHandle(CORINFO_GENERIC_HANDLE(arrayData));
3189 }
3190
3191 CorInfoIsAccessAllowedResult ZapInfo::canAccessClass( CORINFO_RESOLVED_TOKEN * pResolvedToken,
3192                                                       CORINFO_METHOD_HANDLE   callerHandle,
3193                                                       CORINFO_HELPER_DESC    *throwHelper)
3194 {
3195     CorInfoIsAccessAllowedResult ret = m_pEEJitInfo->canAccessClass(pResolvedToken, callerHandle, throwHelper);
3196
3197 #ifdef FEATURE_READYTORUN_COMPILER
3198     if (ret != CORINFO_ACCESS_ALLOWED)
3199     {
3200         m_zapper->Warning(W("ReadyToRun: Runtime access checks not supported\n"));
3201         ThrowHR(E_NOTIMPL);
3202     }
3203 #endif
3204
3205     return ret;
3206 }
3207
3208
3209 CORINFO_MODULE_HANDLE ZapInfo::getClassModule(CORINFO_CLASS_HANDLE cls)
3210 {
3211     return m_pEEJitInfo->getClassModule(cls);
3212 }
3213
3214 CORINFO_ASSEMBLY_HANDLE ZapInfo::getModuleAssembly(CORINFO_MODULE_HANDLE mod)
3215 {
3216     return m_pEEJitInfo->getModuleAssembly(mod);
3217 }
3218
3219 const char* ZapInfo::getAssemblyName(CORINFO_ASSEMBLY_HANDLE assem)
3220 {
3221     return m_pEEJitInfo->getAssemblyName(assem);
3222 }
3223
3224 void* ZapInfo::LongLifetimeMalloc(size_t sz)
3225 {
3226     return m_pEEJitInfo->LongLifetimeMalloc(sz);
3227 }
3228
3229 void ZapInfo::LongLifetimeFree(void* obj)
3230 {
3231     return m_pEEJitInfo->LongLifetimeFree(obj);
3232 }
3233
3234 size_t ZapInfo::getClassModuleIdForStatics(CORINFO_CLASS_HANDLE cls, CORINFO_MODULE_HANDLE *pModule, void **ppIndirection)
3235 {
3236     if (IsReadyToRunCompilation())
3237     {
3238         _ASSERTE(!"getClassModuleIdForStatics");
3239         ThrowHR(E_NOTIMPL);
3240     }
3241
3242     _ASSERTE(ppIndirection != NULL);
3243     _ASSERTE(pModule == NULL);
3244     CORINFO_MODULE_HANDLE module;
3245     size_t moduleId = m_pEEJitInfo->getClassModuleIdForStatics(cls, &module, ppIndirection);
3246     CORINFO_MODULE_HANDLE pzmModule = m_pImage->m_pPreloader->GetPreferredZapModuleForClassHandle(cls);
3247
3248     if (module == pzmModule)
3249     {
3250         // Use the module for the moduleid lookup if we have to do so. This causes us to have fewer fixups than
3251         // if the fixups were exclusively based on the moduleforstatics lookup
3252         cls = NULL;
3253
3254
3255         if (module == m_pImage->m_hModule)
3256         {
3257             // If the handle is the module we are currently ngening, we use
3258             // an indirection to the slot where the module pointer gets
3259             // stored when the module gets reloaded.
3260
3261             *ppIndirection = PVOID(m_pImage->GetWrappers()->GetModuleIDHandle(module));
3262             return NULL;
3263         }
3264
3265         // Fall through to regular import
3266     }
3267     else
3268     {
3269         // Use the class for the moduleid lookup. This causes us to generate a fixup for the ModuleForStatics explicitly.
3270         module = NULL;
3271     }
3272
3273     ZapImport * pImport = m_pImage->GetImportTable()->GetModuleDomainIdImport(module, cls);
3274     AppendConditionalImport(pImport);
3275
3276     *ppIndirection = pImport;
3277     return NULL;
3278 }
3279
3280 unsigned ZapInfo::getClassSize(CORINFO_CLASS_HANDLE cls)
3281 {
3282     DWORD size = m_pEEJitInfo->getClassSize(cls);
3283
3284 #ifdef FEATURE_READYTORUN_COMPILER
3285     if (IsReadyToRunCompilation())
3286     {
3287         if (m_pEECompileInfo->NeedsTypeLayoutCheck(cls))
3288         {
3289             ZapImport * pImport = m_pImage->GetImportTable()->GetCheckTypeLayoutImport(cls);
3290             AppendImport(pImport);
3291
3292             m_ClassLoadTable.Load(cls, TRUE);
3293         }
3294     }
3295 #endif
3296
3297     return size;
3298 }
3299
3300 unsigned ZapInfo::getClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint)
3301 {
3302     return m_pEEJitInfo->getClassAlignmentRequirement(cls, fDoubleAlignHint);
3303 }
3304
3305 CORINFO_FIELD_HANDLE ZapInfo::getFieldInClass(CORINFO_CLASS_HANDLE clsHnd, INT num)
3306 {
3307     return m_pEEJitInfo->getFieldInClass(clsHnd,num);
3308 }
3309
3310 mdMethodDef ZapInfo::getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod)
3311 {
3312     return m_pEEJitInfo->getMethodDefFromMethod(hMethod);
3313 }
3314
3315 BOOL ZapInfo::checkMethodModifier(CORINFO_METHOD_HANDLE hMethod, LPCSTR modifier, BOOL fOptional)
3316 {
3317     return m_pEEJitInfo->checkMethodModifier(hMethod, modifier, fOptional);
3318 }
3319
3320 unsigned ZapInfo::getClassGClayout(CORINFO_CLASS_HANDLE cls, BYTE *gcPtrs)
3321 {
3322     return m_pEEJitInfo->getClassGClayout(cls, gcPtrs);
3323 }
3324
3325 // returns the enregister info for a struct based on type of fields, alignment, etc..
3326 bool ZapInfo::getSystemVAmd64PassStructInRegisterDescriptor(
3327     /*IN*/  CORINFO_CLASS_HANDLE _structHnd,
3328     /*OUT*/ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr)
3329 {
3330     return m_pEEJitInfo->getSystemVAmd64PassStructInRegisterDescriptor(_structHnd, structPassInRegDescPtr);
3331 }
3332
3333 unsigned ZapInfo::getClassNumInstanceFields(CORINFO_CLASS_HANDLE cls)
3334 {
3335     return m_pEEJitInfo->getClassNumInstanceFields(cls);
3336 }
3337
3338
3339 CorInfoHelpFunc ZapInfo::getNewHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_METHOD_HANDLE callerHandle)
3340 {
3341         if (IsReadyToRunCompilation())
3342                 return CORINFO_HELP_NEWFAST;
3343
3344         classMustBeLoadedBeforeCodeIsRun(pResolvedToken->hClass);
3345         return m_pEEJitInfo->getNewHelper(pResolvedToken, callerHandle);
3346 }
3347
3348 CorInfoHelpFunc ZapInfo::getSharedCCtorHelper(CORINFO_CLASS_HANDLE clsHnd)
3349 {
3350         return m_pEEJitInfo->getSharedCCtorHelper(clsHnd);
3351 }
3352
3353 CorInfoHelpFunc ZapInfo::getSecurityPrologHelper(CORINFO_METHOD_HANDLE ftn)
3354 {
3355         return m_pEEJitInfo->getSecurityPrologHelper(ftn);
3356 }
3357
3358 CORINFO_CLASS_HANDLE  ZapInfo::getTypeForBox(CORINFO_CLASS_HANDLE  cls)
3359 {
3360         return m_pEEJitInfo->getTypeForBox(cls);
3361 }
3362
3363 CorInfoHelpFunc ZapInfo::getBoxHelper(CORINFO_CLASS_HANDLE cls)
3364 {
3365         return m_pEEJitInfo->getBoxHelper(cls);
3366 }
3367
3368 CorInfoHelpFunc ZapInfo::getUnBoxHelper(CORINFO_CLASS_HANDLE cls)
3369 {
3370         return m_pEEJitInfo->getUnBoxHelper(cls);
3371 }
3372
3373 CorInfoHelpFunc ZapInfo::getCastingHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fThrowing)
3374 {
3375         if (IsReadyToRunCompilation())
3376                 return (fThrowing ? CORINFO_HELP_CHKCASTANY : CORINFO_HELP_ISINSTANCEOFANY);
3377
3378         return m_pEEJitInfo->getCastingHelper(pResolvedToken, fThrowing);
3379 }
3380
3381 CorInfoHelpFunc ZapInfo::getNewArrHelper(CORINFO_CLASS_HANDLE arrayCls)
3382 {
3383         if (IsReadyToRunCompilation())
3384                 return CORINFO_HELP_NEWARR_1_R2R_DIRECT;
3385
3386         return m_pEEJitInfo->getNewArrHelper(arrayCls);
3387 }
3388
3389 bool ZapInfo::getReadyToRunHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken,
3390         CORINFO_LOOKUP_KIND * pGenericLookupKind,
3391         CorInfoHelpFunc id,
3392         CORINFO_CONST_LOOKUP * pLookup)
3393 {
3394 #ifdef FEATURE_READYTORUN_COMPILER
3395         _ASSERTE(IsReadyToRunCompilation());
3396
3397         ZapImport * pImport = NULL;
3398
3399         DWORD fAtypicalCallsite = (id & CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE);
3400         id = (CorInfoHelpFunc)(id & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE);
3401
3402         switch (id)
3403         {
3404         case CORINFO_HELP_READYTORUN_NEW:
3405         // Call CEEInfo::getNewHelper to validate the request (e.g., check for abstract class).
3406         m_pEEJitInfo->getNewHelper(pResolvedToken, m_currentMethodHandle);
3407
3408                 if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0)
3409                         return false;   // Requires runtime lookup.
3410                 pImport = m_pImage->GetImportTable()->GetDynamicHelperCell(
3411                         (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_NEW_HELPER | fAtypicalCallsite), pResolvedToken->hClass);
3412                 break;
3413
3414         case CORINFO_HELP_READYTORUN_NEWARR_1:
3415                 if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0)
3416                         return false;   // Requires runtime lookup.
3417                 pImport = m_pImage->GetImportTable()->GetDynamicHelperCell(
3418                         (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_NEW_ARRAY_HELPER | fAtypicalCallsite), pResolvedToken->hClass);
3419                 break;
3420
3421         case CORINFO_HELP_READYTORUN_ISINSTANCEOF:
3422                 if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0)
3423                         return false;   // Requires runtime lookup.
3424                 pImport = m_pImage->GetImportTable()->GetDynamicHelperCell(
3425                         (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_ISINSTANCEOF_HELPER | fAtypicalCallsite), pResolvedToken->hClass);
3426                 break;
3427
3428         case CORINFO_HELP_READYTORUN_CHKCAST:
3429                 if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0)
3430                         return false;   // Requires runtime lookup.
3431                 pImport = m_pImage->GetImportTable()->GetDynamicHelperCell(
3432                         (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_CHKCAST_HELPER | fAtypicalCallsite), pResolvedToken->hClass);
3433                 break;
3434
3435         case CORINFO_HELP_READYTORUN_STATIC_BASE:
3436                 if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0)
3437                         return false;   // Requires runtime lookup.
3438                 if (m_pImage->GetCompileInfo()->IsInCurrentVersionBubble(m_pEEJitInfo->getClassModule(pResolvedToken->hClass)))
3439                 {
3440                         pImport = m_pImage->GetImportTable()->GetDynamicHelperCell(
3441                                 (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_CCTOR_TRIGGER | fAtypicalCallsite), pResolvedToken->hClass);
3442                 }
3443                 else
3444                 {
3445                         // READYTORUN: FUTURE: Cross-module static cctor triggers
3446                         m_zapper->Warning(W("ReadyToRun: Cross-module static cctor triggers not supported\n"));
3447                         ThrowHR(E_NOTIMPL);
3448                 }
3449                 break;
3450
3451         case CORINFO_HELP_READYTORUN_GENERIC_HANDLE:
3452                 _ASSERTE(pGenericLookupKind != NULL && pGenericLookupKind->needsRuntimeLookup);
3453                 if (pGenericLookupKind->runtimeLookupKind == CORINFO_LOOKUP_METHODPARAM)
3454                 {
3455                         pImport = m_pImage->GetImportTable()->GetDictionaryLookupCell(
3456                                 (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_DICTIONARY_LOOKUP_METHOD | fAtypicalCallsite), pResolvedToken, pGenericLookupKind);
3457                 }
3458         else if (pGenericLookupKind->runtimeLookupKind == CORINFO_LOOKUP_THISOBJ)
3459         {
3460             pImport = m_pImage->GetImportTable()->GetDictionaryLookupCell(
3461                 (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_DICTIONARY_LOOKUP_THISOBJ | fAtypicalCallsite), pResolvedToken, pGenericLookupKind);
3462         }
3463                 else
3464                 {
3465                         _ASSERTE(pGenericLookupKind->runtimeLookupKind == CORINFO_LOOKUP_CLASSPARAM);
3466                         pImport = m_pImage->GetImportTable()->GetDictionaryLookupCell(
3467                                 (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_DICTIONARY_LOOKUP_TYPE | fAtypicalCallsite), pResolvedToken, pGenericLookupKind);
3468                 }
3469                 break;
3470
3471         default:
3472                 _ASSERTE(false);
3473                 ThrowHR(E_NOTIMPL);
3474         }
3475
3476         pLookup->accessType = IAT_PVALUE;
3477         pLookup->addr = pImport;
3478         return true;
3479 #else
3480         return false;
3481 #endif
3482 }
3483
3484 void ZapInfo::getReadyToRunDelegateCtorHelper(
3485         CORINFO_RESOLVED_TOKEN * pTargetMethod,
3486         CORINFO_CLASS_HANDLE     delegateType,
3487         CORINFO_LOOKUP *   pLookup
3488         )
3489 {
3490 #ifdef FEATURE_READYTORUN_COMPILER
3491     _ASSERTE(IsReadyToRunCompilation());
3492     pLookup->lookupKind.needsRuntimeLookup = false;
3493     pLookup->constLookup.accessType = IAT_PVALUE;
3494     pLookup->constLookup.addr = m_pImage->GetImportTable()->GetDynamicHelperCell(
3495             (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_DELEGATE_CTOR), pTargetMethod->hMethod, pTargetMethod, delegateType);
3496 #endif
3497 }
3498
3499
3500 //
3501 // ICorModuleInfo
3502 //
3503
3504 //-----------------------------------------------------------------------------
3505 void ZapInfo::resolveToken(CORINFO_RESOLVED_TOKEN * pResolvedToken)
3506 {
3507     m_pEEJitInfo->resolveToken(pResolvedToken);
3508 }
3509
3510 //-----------------------------------------------------------------------------
3511 bool ZapInfo::tryResolveToken(CORINFO_RESOLVED_TOKEN * pResolvedToken)
3512 {
3513     return m_pEEJitInfo->tryResolveToken(pResolvedToken);
3514 }
3515
3516 //-----------------------------------------------------------------------------
3517 void ZapInfo::findSig(CORINFO_MODULE_HANDLE tokenScope,
3518                       unsigned sigTOK,
3519                       CORINFO_CONTEXT_HANDLE tokenContext,
3520                       CORINFO_SIG_INFO *sig)
3521 {
3522     m_pEEJitInfo->findSig(tokenScope, sigTOK, tokenContext, sig);
3523 }
3524
3525 void ZapInfo::findCallSiteSig(CORINFO_MODULE_HANDLE tokenScope,
3526                                            unsigned methTOK,
3527                                            CORINFO_CONTEXT_HANDLE tokenContext, CORINFO_SIG_INFO *sig)
3528 {
3529     m_pEEJitInfo->findCallSiteSig(tokenScope, methTOK, tokenContext, sig);
3530 }
3531
3532 size_t ZapInfo::findNameOfToken(CORINFO_MODULE_HANDLE tokenScope,
3533                                        unsigned token,
3534                                        __out_ecount (FQNameCapacity) char * szFQName,
3535                                        size_t FQNameCapacity)
3536 {
3537     return m_pEEJitInfo->findNameOfToken(tokenScope, token, szFQName, FQNameCapacity);
3538 }
3539
3540 CorInfoCanSkipVerificationResult ZapInfo::canSkipVerification (
3541         CORINFO_MODULE_HANDLE tokenScope)
3542 {
3543     return m_pEEJitInfo->canSkipVerification(tokenScope);
3544 }
3545
3546 BOOL ZapInfo::isValidToken (
3547             CORINFO_MODULE_HANDLE       tokenScope,
3548             unsigned                    token)
3549 {
3550     return m_pEEJitInfo->isValidToken(tokenScope, token);
3551 }
3552
3553 BOOL ZapInfo::isValidStringRef (
3554             CORINFO_MODULE_HANDLE       tokenScope,
3555             unsigned                    token)
3556 {
3557     return m_pEEJitInfo->isValidStringRef(tokenScope, token);
3558 }
3559
3560
3561 //
3562 // ICorMethodInfo
3563 //
3564
3565 const char* ZapInfo::getMethodName(CORINFO_METHOD_HANDLE ftn, const char **moduleName)
3566 {
3567     return m_pEEJitInfo->getMethodName(ftn, moduleName);
3568 }
3569
3570 const char* ZapInfo::getMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftn, const char **className, const char** namespaceName)
3571 {
3572     return m_pEEJitInfo->getMethodNameFromMetadata(ftn, className, namespaceName);
3573 }
3574
3575 unsigned ZapInfo::getMethodHash(CORINFO_METHOD_HANDLE ftn)
3576 {
3577     return m_pEEJitInfo->getMethodHash(ftn);
3578 }
3579
3580 DWORD ZapInfo::getMethodAttribs(CORINFO_METHOD_HANDLE ftn)
3581 {
3582     return m_pEEJitInfo->getMethodAttribs(ftn);
3583 }
3584
3585 void ZapInfo::setMethodAttribs(CORINFO_METHOD_HANDLE ftn, CorInfoMethodRuntimeFlags attribs)
3586 {
3587     m_pEEJitInfo->setMethodAttribs(ftn, attribs);
3588 }
3589
3590 void ZapInfo::getMethodSig(CORINFO_METHOD_HANDLE ftn, CORINFO_SIG_INFO *sig,CORINFO_CLASS_HANDLE memberParent)
3591 {
3592     m_pEEJitInfo->getMethodSig(ftn, sig, memberParent);
3593 }
3594
3595 bool ZapInfo::getMethodInfo(CORINFO_METHOD_HANDLE ftn,CORINFO_METHOD_INFO* info)
3596 {
3597     bool result = m_pImage->m_pPreloader->GetMethodInfo(m_currentMethodToken, ftn, info);
3598     info->regionKind = m_pImage->GetCurrentRegionKind();
3599     return result;
3600 }
3601
3602 CorInfoInline ZapInfo::canInline(CORINFO_METHOD_HANDLE caller,
3603                                            CORINFO_METHOD_HANDLE callee,
3604                                            DWORD* pRestrictions)
3605 {
3606     return m_pEEJitInfo->canInline(caller, callee, pRestrictions);
3607
3608 }
3609
3610 void ZapInfo::reportInliningDecision (CORINFO_METHOD_HANDLE inlinerHnd,
3611                                                 CORINFO_METHOD_HANDLE inlineeHnd,
3612                                                 CorInfoInline inlineResult,
3613                                                 const char * reason)
3614 {
3615     if (!dontInline(inlineResult) && inlineeHnd != NULL)
3616     {
3617         // We deliberately report  m_currentMethodHandle (not inlinerHnd) as inliner, because
3618         // if m_currentMethodHandle != inlinerHnd, it simply means that inlinerHnd is intermediate link 
3619         // in inlining into m_currentMethodHandle, and we have no interest to track those intermediate links now.
3620         m_pImage->m_pPreloader->ReportInlining(m_currentMethodHandle, inlineeHnd);
3621     }
3622     return m_pEEJitInfo->reportInliningDecision(inlinerHnd, inlineeHnd, inlineResult, reason);
3623 }
3624
3625
3626 CorInfoInstantiationVerification ZapInfo::isInstantiationOfVerifiedGeneric(
3627         CORINFO_METHOD_HANDLE method)
3628 {
3629     return m_pEEJitInfo->isInstantiationOfVerifiedGeneric(method);
3630 }
3631
3632
3633 void ZapInfo::initConstraintsForVerification(CORINFO_METHOD_HANDLE method,
3634                                                             BOOL *pfHasCircularClassConstraints,
3635                                                             BOOL *pfHasCircularMethodConstraints)
3636 {
3637      m_pEEJitInfo->
3638               initConstraintsForVerification(method,pfHasCircularClassConstraints,pfHasCircularMethodConstraints);
3639 }
3640
3641 bool ZapInfo::canTailCall(CORINFO_METHOD_HANDLE caller,
3642                                          CORINFO_METHOD_HANDLE declaredCallee,
3643                                          CORINFO_METHOD_HANDLE exactCallee,
3644                                          bool fIsTailPrefix)
3645 {
3646 #ifdef FEATURE_READYTORUN_COMPILER
3647     // READYTORUN: FUTURE: Delay load fixups for tailcalls
3648     if (IsReadyToRunCompilation())
3649     {
3650         if (fIsTailPrefix)
3651         {
3652             m_zapper->Warning(W("ReadyToRun: Explicit tailcalls not supported\n"));
3653             ThrowHR(E_NOTIMPL);
3654         }
3655
3656         return false;
3657     }
3658 #endif
3659
3660     return m_pEEJitInfo->canTailCall(caller, declaredCallee, exactCallee, fIsTailPrefix);
3661 }
3662
3663 void ZapInfo::reportTailCallDecision(CORINFO_METHOD_HANDLE callerHnd,
3664                                                CORINFO_METHOD_HANDLE calleeHnd,
3665                                                bool fIsTailPrefix,
3666                                                CorInfoTailCall tailCallResult,
3667                                                const char * reason)
3668 {
3669     return m_pEEJitInfo->reportTailCallDecision(callerHnd, calleeHnd, fIsTailPrefix, tailCallResult, reason);
3670 }
3671
3672
3673 CorInfoCanSkipVerificationResult ZapInfo::canSkipMethodVerification (
3674         CORINFO_METHOD_HANDLE ftnHandle)
3675 {
3676     // ILStubs are generated internally by the CLR. There is no need to
3677     // verify it, or any of its callees.
3678     if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB))
3679         return CORINFO_VERIFICATION_CAN_SKIP;
3680
3681     CorInfoCanSkipVerificationResult canSkipVer =
3682         m_pEEJitInfo->canSkipMethodVerification(ftnHandle);
3683
3684     if (canSkipVer == CORINFO_VERIFICATION_RUNTIME_CHECK)
3685     {
3686         // Transparent code could be partial trust, but we don't know at NGEN time.
3687         // Since the JIT is not hardened against unverifiable/illegal code, tell it
3688         // to just not jit the method if it hits unverifiable code, rathern than
3689         // injecting a runtime callout and continuing trying to JIT the method.
3690         canSkipVer = CORINFO_VERIFICATION_DONT_JIT;
3691     }
3692
3693     return canSkipVer;
3694 }
3695
3696 void ZapInfo::getEHinfo(CORINFO_METHOD_HANDLE ftn,
3697                          unsigned EHnumber, CORINFO_EH_CLAUSE* clause)
3698 {
3699     m_pEEJitInfo->getEHinfo(ftn, EHnumber, clause);
3700 }
3701
3702 CORINFO_CLASS_HANDLE ZapInfo::getMethodClass(CORINFO_METHOD_HANDLE method)
3703 {
3704     return m_pEEJitInfo->getMethodClass(method);
3705 }
3706
3707 CORINFO_MODULE_HANDLE ZapInfo::getMethodModule(CORINFO_METHOD_HANDLE method)
3708 {
3709     return m_pEEJitInfo->getMethodModule(method);
3710 }
3711
3712 void ZapInfo::getMethodVTableOffset(CORINFO_METHOD_HANDLE method,
3713                                     unsigned * pOffsetOfIndirection,
3714                                     unsigned * pOffsetAfterIndirection,
3715                                     bool * isRelative)
3716 {
3717     m_pEEJitInfo->getMethodVTableOffset(method, pOffsetOfIndirection, pOffsetAfterIndirection, isRelative);
3718 }
3719
3720 CORINFO_METHOD_HANDLE ZapInfo::resolveVirtualMethod(
3721         CORINFO_METHOD_HANDLE virtualMethod,
3722         CORINFO_CLASS_HANDLE implementingClass,
3723         CORINFO_CONTEXT_HANDLE ownerType)
3724 {
3725     return m_pEEJitInfo->resolveVirtualMethod(virtualMethod, implementingClass, ownerType);
3726 }
3727
3728 CORINFO_METHOD_HANDLE ZapInfo::getUnboxedEntry(
3729     CORINFO_METHOD_HANDLE ftn,
3730     bool* requiresInstMethodTableArg)
3731 {
3732     return m_pEEJitInfo->getUnboxedEntry(ftn, requiresInstMethodTableArg);
3733 }
3734
3735 CORINFO_CLASS_HANDLE ZapInfo::getDefaultEqualityComparerClass(
3736     CORINFO_CLASS_HANDLE elemType)
3737 {
3738     return m_pEEJitInfo->getDefaultEqualityComparerClass(elemType);
3739 }
3740
3741 void ZapInfo::expandRawHandleIntrinsic(
3742     CORINFO_RESOLVED_TOKEN *        pResolvedToken,
3743     CORINFO_GENERICHANDLE_RESULT *  pResult)
3744 {
3745     m_pEEJitInfo->expandRawHandleIntrinsic(pResolvedToken, pResult);
3746 }
3747
3748 CorInfoIntrinsics ZapInfo::getIntrinsicID(CORINFO_METHOD_HANDLE method,
3749                                           bool * pMustExpand)
3750 {
3751     return m_pEEJitInfo->getIntrinsicID(method, pMustExpand);
3752 }
3753
3754 bool ZapInfo::isInSIMDModule(CORINFO_CLASS_HANDLE classHnd)
3755 {
3756     return m_pEEJitInfo->isInSIMDModule(classHnd);
3757 }
3758
3759 CorInfoUnmanagedCallConv ZapInfo::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method)
3760 {
3761     return m_pEEJitInfo->getUnmanagedCallConv(method);
3762 }
3763
3764 BOOL ZapInfo::pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method,
3765                                                        CORINFO_SIG_INFO* sig)
3766 {
3767     // READYTORUN: FUTURE: P/Invoke
3768     if (IsReadyToRunCompilation())
3769         return TRUE;
3770
3771     return m_pEEJitInfo->pInvokeMarshalingRequired(method, sig);
3772 }
3773
3774 LPVOID ZapInfo::GetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig,
3775                                                  void ** ppIndirection)
3776 {
3777     return getVarArgsHandle(szMetaSig, ppIndirection);
3778 }
3779
3780 bool ZapInfo::canGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig)
3781 {
3782     return canGetVarArgsHandle(szMetaSig);
3783 }
3784
3785 BOOL ZapInfo::satisfiesMethodConstraints(
3786             CORINFO_CLASS_HANDLE        parent,
3787             CORINFO_METHOD_HANDLE       method)
3788 {
3789     return m_pEEJitInfo->satisfiesMethodConstraints(parent, method);
3790 }
3791
3792
3793 BOOL ZapInfo::isCompatibleDelegate(
3794             CORINFO_CLASS_HANDLE objCls,
3795             CORINFO_CLASS_HANDLE methodParentCls,
3796             CORINFO_METHOD_HANDLE method,
3797             CORINFO_CLASS_HANDLE delegateCls,
3798             BOOL* pfIsOpenDelegate)
3799 {
3800     return m_pEEJitInfo->isCompatibleDelegate(objCls, methodParentCls, method, delegateCls, pfIsOpenDelegate);
3801 }
3802
3803 //
3804 // ICorErrorInfo
3805 //
3806
3807 HRESULT ZapInfo::GetErrorHRESULT(struct _EXCEPTION_POINTERS *pExceptionPointers)
3808 {
3809     return m_pEEJitInfo->GetErrorHRESULT(pExceptionPointers);
3810 }
3811
3812 ULONG ZapInfo::GetErrorMessage(__in_ecount(bufferLength) LPWSTR buffer, ULONG bufferLength)
3813 {
3814     return m_pEEJitInfo->GetErrorMessage(buffer, bufferLength);
3815 }
3816
3817 int ZapInfo::FilterException(struct _EXCEPTION_POINTERS *pExceptionPointers)
3818 {
3819     // Continue unwinding if fatal error was hit.
3820     if (FAILED(g_hrFatalError))
3821         return EXCEPTION_CONTINUE_SEARCH;
3822
3823     return m_pEEJitInfo->FilterException(pExceptionPointers);
3824 }
3825
3826 void ZapInfo::HandleException(struct _EXCEPTION_POINTERS *pExceptionPointers)
3827 {
3828     m_pEEJitInfo->HandleException(pExceptionPointers);
3829 }
3830
3831 void ZapInfo::ThrowExceptionForJitResult(HRESULT result)
3832 {
3833     m_pEEJitInfo->ThrowExceptionForJitResult(result);
3834 }
3835 void ZapInfo::ThrowExceptionForHelper(const CORINFO_HELPER_DESC * throwHelper)
3836 {
3837     m_pEEJitInfo->ThrowExceptionForHelper(throwHelper);
3838 }
3839
3840 template<> void LoadTable<CORINFO_CLASS_HANDLE>::EmitLoadFixups(CORINFO_METHOD_HANDLE currentMethodHandle, ZapInfo * pZapInfo)
3841 {
3842     //
3843     // Find all of our un-fixed entries, and emit a restore fixup for each of them.
3844     // Note that we don't need a restore fixups for prerestored classes.
3845     //
3846
3847     InlineSArray<LoadEntry, 4> unfixed;
3848
3849     for (LoadEntryHashTable::Iterator i = m_entries.Begin(), end = m_entries.End(); i != end; i++)
3850     {
3851         if (i->order == -1
3852             || m_pModule->m_pPreloader->CanPrerestoreEmbedClassHandle(i->handle)
3853             // @TODO: Skip transitive closure of currentMethodHandle (parents, instantiations, etc.)
3854             || m_pModule->GetJitInfo()->getMethodClass(currentMethodHandle) == i->handle)
3855             continue;
3856
3857         unfixed.Append(*i);
3858     }
3859
3860     //
3861     // Now clear the table.
3862     //
3863
3864     m_entries.RemoveAll();
3865
3866     if (unfixed.IsEmpty())
3867         return;
3868
3869     // Save the fixups in the order they got emited for determinism
3870     qsort(&unfixed[0], unfixed.GetCount(), sizeof(LoadEntry), LoadEntryCmp);
3871
3872     for(COUNT_T j = 0; j < unfixed.GetCount(); j++)
3873     {
3874         CORINFO_CLASS_HANDLE handle = unfixed[j].handle;
3875         m_pModule->m_pPreloader->AddTypeToTransitiveClosureOfInstantiations(handle);
3876         ZapImport * pImport = m_pModule->GetImportTable()->GetClassHandleImport(handle);
3877         pZapInfo->AppendImport(pImport);
3878     }
3879 }
3880
3881
3882 template<> void LoadTable<CORINFO_METHOD_HANDLE>::EmitLoadFixups(CORINFO_METHOD_HANDLE currentMethodHandle, ZapInfo * pZapInfo)
3883 {
3884     //
3885     // Find all of our un-fixed entries, and emit a restore fixup for each of them.
3886     // Note that we don't need a restore fixups for prerestored methods.
3887     //
3888
3889     InlineSArray<LoadEntry, 4> unfixed;
3890
3891     for (LoadEntryHashTable::Iterator i = m_entries.Begin(), end = m_entries.End(); i != end; i++)
3892     {
3893         if (i->order == -1
3894             || m_pModule->m_pPreloader->CanPrerestoreEmbedMethodHandle(i->handle)
3895             || currentMethodHandle == i->handle)
3896             continue;
3897
3898         unfixed.Append(*i);
3899     }
3900
3901     //
3902     // Now clear the table.
3903     //
3904
3905     m_entries.RemoveAll();
3906
3907     if (unfixed.IsEmpty())
3908         return;
3909
3910     // Save the fixups in the order they got emited for determinism
3911     qsort(&unfixed[0], unfixed.GetCount(), sizeof(LoadEntry), LoadEntryCmp);
3912
3913     for(COUNT_T j = 0; j < unfixed.GetCount(); j++)
3914     {
3915         CORINFO_METHOD_HANDLE handle = unfixed[j].handle;
3916         m_pModule->m_pPreloader->AddMethodToTransitiveClosureOfInstantiations(handle);
3917         ZapImport * pImport = m_pModule->GetImportTable()->GetMethodHandleImport(handle);
3918         pZapInfo->AppendImport(pImport);
3919     }
3920 }
3921
3922 BOOL ZapInfo::CurrentMethodHasProfileData()
3923 {
3924     WRAPPER_NO_CONTRACT;
3925     ULONG size;
3926     ICorJitInfo::ProfileBuffer * profileBuffer;
3927     return SUCCEEDED(getBBProfileData(m_currentMethodHandle, &size, &profileBuffer, NULL));
3928 }
3929