New jit intrinsic support (#13815)
[platform/upstream/coreclr.git] / src / vm / jitinterface.h
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 // File: JITinterface.H
6 //
7
8 // ===========================================================================
9
10
11 #ifndef JITINTERFACE_H
12 #define JITINTERFACE_H
13
14 #include "corjit.h"
15 #ifdef FEATURE_PREJIT
16 #include "corcompile.h"
17 #endif // FEATURE_PREJIT
18
19 #ifndef FEATURE_PAL
20 #define MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT ((32*1024)-1)   // when generating JIT code
21 #else // !FEATURE_PAL
22 #define MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT ((GetOsPageSize() / 2) - 1)
23 #endif // !FEATURE_PAL
24
25 class Stub;
26 class MethodDesc;
27 class FieldDesc;
28 enum RuntimeExceptionKind;
29 class AwareLock;
30 class PtrArray;
31 #if defined(FEATURE_GDBJIT)
32 class CalledMethod;
33 #endif
34
35 #include "genericdict.h"
36
37 inline FieldDesc* GetField(CORINFO_FIELD_HANDLE fieldHandle)
38 {
39     LIMITED_METHOD_CONTRACT;
40     return (FieldDesc*) fieldHandle;
41 }
42
43 inline
44 bool SigInfoFlagsAreValid (CORINFO_SIG_INFO *sig)
45 {
46     LIMITED_METHOD_CONTRACT;
47     return !(sig->flags & ~(  CORINFO_SIGFLAG_IS_LOCAL_SIG
48                             | CORINFO_SIGFLAG_IL_STUB
49                             ));
50 }
51
52
53 void InitJITHelpers1();
54 void InitJITHelpers2();
55
56 PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* header,
57                         CORJIT_FLAGS flags, ULONG* sizeOfCode = NULL);
58
59 void getMethodInfoHelper(MethodDesc * ftn,
60                          CORINFO_METHOD_HANDLE ftnHnd,
61                          COR_ILMETHOD_DECODER * header,
62                          CORINFO_METHOD_INFO *  methInfo);
63
64 void getMethodInfoILMethodHeaderHelper(
65     COR_ILMETHOD_DECODER* header,
66     CORINFO_METHOD_INFO* methInfo
67     );
68
69
70 #ifdef FEATURE_PREJIT
71 BOOL LoadDynamicInfoEntry(Module *currentModule,
72                           RVA fixupRva,
73                           SIZE_T *entry);
74 #endif // FEATURE_PREJIT
75
76 //
77 // The legacy x86 monitor helpers do not need a state argument
78 //
79 #if !defined(_TARGET_X86_)
80
81 #define FCDECL_MONHELPER(funcname, arg) FCDECL2(void, funcname, arg, BYTE* pbLockTaken)
82 #define HCIMPL_MONHELPER(funcname, arg) HCIMPL2(void, funcname, arg, BYTE* pbLockTaken)
83 #define MONHELPER_STATE(x) x
84 #define MONHELPER_ARG pbLockTaken
85
86 #else
87
88 #define FCDECL_MONHELPER(funcname, arg) FCDECL1(void, funcname, arg)
89 #define HCIMPL_MONHELPER(funcname, arg) HCIMPL1(void, funcname, arg)
90 #define MONHELPER_STATE(x)
91 #define MONHELPER_ARG NULL
92
93 #endif // _TARGET_X86_
94
95
96 //
97 // JIT HELPER ALIASING FOR PORTABILITY.
98 //
99 // The portable helper is used if the platform does not provide optimized implementation.
100 //
101
102 #ifndef JIT_MonEnter
103 #define JIT_MonEnter JIT_MonEnter_Portable
104 #endif
105 EXTERN_C FCDECL1(void, JIT_MonEnter, Object *obj);
106 EXTERN_C FCDECL1(void, JIT_MonEnter_Portable, Object *obj);
107
108 #ifndef JIT_MonEnterWorker
109 #define JIT_MonEnterWorker JIT_MonEnterWorker_Portable
110 #endif
111 EXTERN_C FCDECL_MONHELPER(JIT_MonEnterWorker, Object *obj);
112 EXTERN_C FCDECL_MONHELPER(JIT_MonEnterWorker_Portable, Object *obj);
113
114 #ifndef JIT_MonReliableEnter
115 #define JIT_MonReliableEnter JIT_MonReliableEnter_Portable
116 #endif
117 EXTERN_C FCDECL2(void, JIT_MonReliableEnter, Object* obj, BYTE *tookLock);
118 EXTERN_C FCDECL2(void, JIT_MonReliableEnter_Portable, Object* obj, BYTE *tookLock);
119
120 #ifndef JIT_MonTryEnter
121 #define JIT_MonTryEnter JIT_MonTryEnter_Portable
122 #endif
123 EXTERN_C FCDECL3(void, JIT_MonTryEnter, Object *obj, INT32 timeout, BYTE* pbLockTaken);
124 EXTERN_C FCDECL3(void, JIT_MonTryEnter_Portable, Object *obj, INT32 timeout, BYTE* pbLockTaken);
125
126 #ifndef JIT_MonExit
127 #define JIT_MonExit JIT_MonExit_Portable
128 #endif
129 EXTERN_C FCDECL1(void, JIT_MonExit, Object *obj);
130 EXTERN_C FCDECL1(void, JIT_MonExit_Portable, Object *obj);
131
132 #ifndef JIT_MonExitWorker
133 #define JIT_MonExitWorker JIT_MonExitWorker_Portable
134 #endif
135 EXTERN_C FCDECL_MONHELPER(JIT_MonExitWorker, Object *obj);
136 EXTERN_C FCDECL_MONHELPER(JIT_MonExitWorker_Portable, Object *obj);
137
138 #ifndef JIT_MonEnterStatic
139 #define JIT_MonEnterStatic JIT_MonEnterStatic_Portable  
140 #endif
141 EXTERN_C FCDECL_MONHELPER(JIT_MonEnterStatic, AwareLock *lock);
142 EXTERN_C FCDECL_MONHELPER(JIT_MonEnterStatic_Portable, AwareLock *lock);
143
144 #ifndef JIT_MonExitStatic
145 #define JIT_MonExitStatic JIT_MonExitStatic_Portable
146 #endif
147 EXTERN_C FCDECL_MONHELPER(JIT_MonExitStatic, AwareLock *lock);
148 EXTERN_C FCDECL_MONHELPER(JIT_MonExitStatic_Portable, AwareLock *lock);
149
150
151 #ifndef JIT_GetSharedGCStaticBase
152 #define JIT_GetSharedGCStaticBase JIT_GetSharedGCStaticBase_Portable
153 #endif
154 EXTERN_C FCDECL2(void*, JIT_GetSharedGCStaticBase, SIZE_T moduleDomainID, DWORD dwModuleClassID);
155 EXTERN_C FCDECL2(void*, JIT_GetSharedGCStaticBase_Portable, SIZE_T moduleDomainID, DWORD dwModuleClassID);
156
157 #ifndef JIT_GetSharedNonGCStaticBase
158 #define JIT_GetSharedNonGCStaticBase JIT_GetSharedNonGCStaticBase_Portable
159 #endif
160 EXTERN_C FCDECL2(void*, JIT_GetSharedNonGCStaticBase, SIZE_T moduleDomainID, DWORD dwModuleClassID);
161 EXTERN_C FCDECL2(void*, JIT_GetSharedNonGCStaticBase_Portable, SIZE_T moduleDomainID, DWORD dwModuleClassID);
162
163 #ifndef JIT_GetSharedGCStaticBaseNoCtor
164 #define JIT_GetSharedGCStaticBaseNoCtor JIT_GetSharedGCStaticBaseNoCtor_Portable
165 #endif
166 EXTERN_C FCDECL1(void*, JIT_GetSharedGCStaticBaseNoCtor, SIZE_T moduleDomainID);
167 EXTERN_C FCDECL1(void*, JIT_GetSharedGCStaticBaseNoCtor_Portable, SIZE_T moduleDomainID);
168
169 #ifndef JIT_GetSharedNonGCStaticBaseNoCtor
170 #define JIT_GetSharedNonGCStaticBaseNoCtor JIT_GetSharedNonGCStaticBaseNoCtor_Portable
171 #endif
172 EXTERN_C FCDECL1(void*, JIT_GetSharedNonGCStaticBaseNoCtor, SIZE_T moduleDomainID);
173 EXTERN_C FCDECL1(void*, JIT_GetSharedNonGCStaticBaseNoCtor_Portable, SIZE_T moduleDomainID);
174
175 #ifndef JIT_ChkCastClass
176 #define JIT_ChkCastClass JIT_ChkCastClass_Portable
177 #endif
178 EXTERN_C FCDECL2(Object*, JIT_ChkCastClass, MethodTable* pMT, Object* pObject);
179 EXTERN_C FCDECL2(Object*, JIT_ChkCastClass_Portable, MethodTable* pMT, Object* pObject);
180
181 #ifndef JIT_ChkCastClassSpecial
182 #define JIT_ChkCastClassSpecial JIT_ChkCastClassSpecial_Portable
183 #endif
184 EXTERN_C FCDECL2(Object*, JIT_ChkCastClassSpecial, MethodTable* pMT, Object* pObject);
185 EXTERN_C FCDECL2(Object*, JIT_ChkCastClassSpecial_Portable, MethodTable* pMT, Object* pObject);
186
187 #ifndef JIT_IsInstanceOfClass
188 #define JIT_IsInstanceOfClass JIT_IsInstanceOfClass_Portable
189 #endif
190 EXTERN_C FCDECL2(Object*, JIT_IsInstanceOfClass, MethodTable* pMT, Object* pObject);
191 EXTERN_C FCDECL2(Object*, JIT_IsInstanceOfClass_Portable, MethodTable* pMT, Object* pObject);
192
193 #ifndef JIT_ChkCastInterface
194 #define JIT_ChkCastInterface JIT_ChkCastInterface_Portable
195 #endif
196 EXTERN_C FCDECL2(Object*, JIT_ChkCastInterface, MethodTable* pMT, Object* pObject);
197 EXTERN_C FCDECL2(Object*, JIT_ChkCastInterface_Portable, MethodTable* pMT, Object* pObject);
198
199 #ifndef JIT_IsInstanceOfInterface
200 #define JIT_IsInstanceOfInterface JIT_IsInstanceOfInterface_Portable
201 #endif
202 EXTERN_C FCDECL2(Object*, JIT_IsInstanceOfInterface, MethodTable* pMT, Object* pObject);
203 EXTERN_C FCDECL2(Object*, JIT_IsInstanceOfInterface_Portable, MethodTable* pMT, Object* pObject);
204
205 extern FCDECL1(Object*, JIT_NewS_MP_FastPortable, CORINFO_CLASS_HANDLE typeHnd_);
206 extern FCDECL1(Object*, JIT_New, CORINFO_CLASS_HANDLE typeHnd_);
207
208 #ifndef JIT_NewCrossContext
209 #define JIT_NewCrossContext JIT_NewCrossContext_Portable
210 #endif
211 EXTERN_C FCDECL1(Object*, JIT_NewCrossContext, CORINFO_CLASS_HANDLE typeHnd_);
212 EXTERN_C FCDECL1(Object*, JIT_NewCrossContext_Portable, CORINFO_CLASS_HANDLE typeHnd_);
213
214 extern FCDECL1(StringObject*, AllocateString_MP_FastPortable, DWORD stringLength);
215 extern FCDECL1(StringObject*, UnframedAllocateString, DWORD stringLength);
216 extern FCDECL1(StringObject*, FramedAllocateString, DWORD stringLength);
217
218 extern FCDECL2(Object*, JIT_NewArr1VC_MP_FastPortable, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size);
219 extern FCDECL2(Object*, JIT_NewArr1OBJ_MP_FastPortable, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size);
220 extern FCDECL2(Object*, JIT_NewArr1_R2R, CORINFO_CLASS_HANDLE arrayTypeHnd_, INT_PTR size);
221 extern FCDECL2(Object*, JIT_NewArr1, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size);
222
223 #ifndef JIT_Stelem_Ref
224 #define JIT_Stelem_Ref JIT_Stelem_Ref_Portable
225 #endif
226 EXTERN_C FCDECL3(void, JIT_Stelem_Ref, PtrArray* array, unsigned idx, Object* val);
227 EXTERN_C FCDECL3(void, JIT_Stelem_Ref_Portable, PtrArray* array, unsigned idx, Object* val);
228
229 EXTERN_C FCDECL_MONHELPER(JITutil_MonEnterWorker, Object* obj);
230 EXTERN_C FCDECL2(void, JITutil_MonReliableEnter, Object* obj, BYTE* pbLockTaken);
231 EXTERN_C FCDECL3(void, JITutil_MonTryEnter, Object* obj, INT32 timeOut, BYTE* pbLockTaken);
232 EXTERN_C FCDECL_MONHELPER(JITutil_MonExitWorker, Object* obj);
233 EXTERN_C FCDECL_MONHELPER(JITutil_MonSignal, AwareLock* lock);
234 EXTERN_C FCDECL_MONHELPER(JITutil_MonContention, AwareLock* awarelock);
235 EXTERN_C FCDECL2(void, JITutil_MonReliableContention, AwareLock* awarelock, BYTE* pbLockTaken);
236
237 // Slow versions to tail call if the fast version fails
238 EXTERN_C FCDECL2(void*, JIT_GetSharedNonGCStaticBase_Helper, DomainLocalModule *pLocalModule, DWORD dwClassDomainID);
239 EXTERN_C FCDECL2(void*, JIT_GetSharedGCStaticBase_Helper, DomainLocalModule *pLocalModule, DWORD dwClassDomainID);
240
241 EXTERN_C void DoJITFailFast ();
242 EXTERN_C FCDECL0(void, JIT_FailFast);
243 extern FCDECL3(void, JIT_ThrowAccessException, RuntimeExceptionKind, CORINFO_METHOD_HANDLE caller, void * callee);
244
245 FCDECL1(void*, JIT_SafeReturnableByref, void* byref);
246
247 #if !defined(FEATURE_USE_ASM_GC_WRITE_BARRIERS) && defined(FEATURE_COUNT_GC_WRITE_BARRIERS)
248 // Extra argument for the classification of the checked barriers.
249 extern "C" FCDECL3(VOID, JIT_CheckedWriteBarrier, Object **dst, Object *ref, CheckedWriteBarrierKinds kind);
250 #else
251 // Regular checked write barrier.
252 extern "C" FCDECL2(VOID, JIT_CheckedWriteBarrier, Object **dst, Object *ref);
253 #endif
254
255 extern "C" FCDECL2(VOID, JIT_WriteBarrier, Object **dst, Object *ref);
256
257 extern "C" FCDECL2(VOID, JIT_WriteBarrierEnsureNonHeapTarget, Object **dst, Object *ref);
258
259 extern "C" FCDECL2(Object*, JIT_ChkCastAny, CORINFO_CLASS_HANDLE type, Object *pObject);   // JITInterfaceX86.cpp, etc.
260 extern "C" FCDECL2(Object*, JIT_IsInstanceOfAny, CORINFO_CLASS_HANDLE type, Object *pObject);
261
262 extern "C" FCDECL2(Object*, JITutil_ChkCastInterface, MethodTable *pInterfaceMT, Object *obj);
263 extern "C" FCDECL2(Object*, JITutil_IsInstanceOfInterface, MethodTable *pInterfaceMT, Object *obj);
264 extern "C" FCDECL2(Object*, JITutil_ChkCastAny, CORINFO_CLASS_HANDLE type, Object *obj);
265 extern "C" FCDECL2(Object*, JITutil_IsInstanceOfAny, CORINFO_CLASS_HANDLE type, Object *obj);
266
267 extern "C" FCDECL1(void, JIT_InternalThrow, unsigned exceptNum);
268 extern "C" FCDECL1(void*, JIT_InternalThrowFromHelper, unsigned exceptNum);
269
270 #ifdef _TARGET_AMD64_
271
272
273 class WriteBarrierManager
274 {
275 public:
276     enum WriteBarrierType
277     {
278         WRITE_BARRIER_UNINITIALIZED,
279         WRITE_BARRIER_PREGROW64,
280         WRITE_BARRIER_POSTGROW64,
281 #ifdef FEATURE_SVR_GC
282         WRITE_BARRIER_SVR64,
283 #endif // FEATURE_SVR_GC
284 #ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
285         WRITE_BARRIER_WRITE_WATCH_PREGROW64,
286         WRITE_BARRIER_WRITE_WATCH_POSTGROW64,
287 #ifdef FEATURE_SVR_GC
288         WRITE_BARRIER_WRITE_WATCH_SVR64,
289 #endif // FEATURE_SVR_GC
290 #endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
291         WRITE_BARRIER_BUFFER
292     };
293
294     WriteBarrierManager();
295     void Initialize();
296     
297     void UpdateEphemeralBounds(bool isRuntimeSuspended);
298     void UpdateWriteWatchAndCardTableLocations(bool isRuntimeSuspended, bool bReqUpperBoundsCheck);
299
300 #ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
301     void SwitchToWriteWatchBarrier(bool isRuntimeSuspended);
302     void SwitchToNonWriteWatchBarrier(bool isRuntimeSuspended);
303 #endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
304
305 protected:
306     size_t GetCurrentWriteBarrierSize();
307     size_t GetSpecificWriteBarrierSize(WriteBarrierType writeBarrier);
308     PBYTE  CalculatePatchLocation(LPVOID base, LPVOID label, int offset);
309     PCODE  GetCurrentWriteBarrierCode();
310     void   ChangeWriteBarrierTo(WriteBarrierType newWriteBarrier, bool isRuntimeSuspended);
311     bool   NeedDifferentWriteBarrier(bool bReqUpperBoundsCheck, WriteBarrierType* pNewWriteBarrierType);
312
313 private:    
314     void Validate();
315     
316     WriteBarrierType    m_currentWriteBarrier;
317
318     PBYTE   m_pWriteWatchTableImmediate;    // PREGROW | POSTGROW | SVR | WRITE_WATCH |
319     PBYTE   m_pLowerBoundImmediate;         // PREGROW | POSTGROW |     | WRITE_WATCH |
320     PBYTE   m_pCardTableImmediate;          // PREGROW | POSTGROW | SVR | WRITE_WATCH |
321     PBYTE   m_pCardBundleTableImmediate;    // PREGROW | POSTGROW | SVR | WRITE_WATCH |
322     PBYTE   m_pUpperBoundImmediate;         //         | POSTGROW |     | WRITE_WATCH |
323 };
324
325 #endif // _TARGET_AMD64_
326
327 #ifdef _WIN64
328 EXTERN_C FCDECL1(Object*, JIT_TrialAllocSFastMP_InlineGetThread, CORINFO_CLASS_HANDLE typeHnd_);
329 EXTERN_C FCDECL2(Object*, JIT_BoxFastMP_InlineGetThread, CORINFO_CLASS_HANDLE type, void* data);
330 EXTERN_C FCDECL2(Object*, JIT_NewArr1VC_MP_InlineGetThread, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size);
331 EXTERN_C FCDECL2(Object*, JIT_NewArr1OBJ_MP_InlineGetThread, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size);
332
333 #endif // _WIN64
334
335 EXTERN_C FCDECL2_VV(INT64, JIT_LMul, INT64 val1, INT64 val2);
336
337 EXTERN_C FCDECL1_V(INT64, JIT_Dbl2Lng, double val);
338 EXTERN_C FCDECL1_V(INT64, JIT_Dbl2IntSSE2, double val);
339 EXTERN_C FCDECL1_V(INT64, JIT_Dbl2LngP4x87, double val);
340 EXTERN_C FCDECL1_V(INT64, JIT_Dbl2LngSSE3, double val);
341 EXTERN_C FCDECL1_V(INT64, JIT_Dbl2LngOvf, double val);
342
343 EXTERN_C FCDECL1_V(INT32, JIT_Dbl2IntOvf, double val);
344
345 EXTERN_C FCDECL2_VV(float, JIT_FltRem, float dividend, float divisor);
346 EXTERN_C FCDECL2_VV(double, JIT_DblRem, double dividend, double divisor);
347
348 #ifndef BIT64
349 #ifdef _TARGET_X86_
350 // JIThelp.asm
351 EXTERN_C void STDCALL JIT_LLsh();
352 EXTERN_C void STDCALL JIT_LRsh();
353 EXTERN_C void STDCALL JIT_LRsz();
354 #else // _TARGET_X86_
355 EXTERN_C FCDECL2_VV(UINT64, JIT_LLsh, UINT64 num, int shift);
356 EXTERN_C FCDECL2_VV(INT64, JIT_LRsh, INT64 num, int shift);
357 EXTERN_C FCDECL2_VV(UINT64, JIT_LRsz, UINT64 num, int shift);
358 #endif // !_TARGET_X86_
359 #endif // !BIT64
360
361 #ifdef _TARGET_X86_
362
363 extern "C"
364 {
365     void STDCALL JIT_CheckedWriteBarrierEAX(); // JIThelp.asm/JIThelp.s
366     void STDCALL JIT_CheckedWriteBarrierEBX(); // JIThelp.asm/JIThelp.s
367     void STDCALL JIT_CheckedWriteBarrierECX(); // JIThelp.asm/JIThelp.s
368     void STDCALL JIT_CheckedWriteBarrierESI(); // JIThelp.asm/JIThelp.s
369     void STDCALL JIT_CheckedWriteBarrierEDI(); // JIThelp.asm/JIThelp.s
370     void STDCALL JIT_CheckedWriteBarrierEBP(); // JIThelp.asm/JIThelp.s
371
372     void STDCALL JIT_DebugWriteBarrierEAX(); // JIThelp.asm/JIThelp.s
373     void STDCALL JIT_DebugWriteBarrierEBX(); // JIThelp.asm/JIThelp.s
374     void STDCALL JIT_DebugWriteBarrierECX(); // JIThelp.asm/JIThelp.s
375     void STDCALL JIT_DebugWriteBarrierESI(); // JIThelp.asm/JIThelp.s
376     void STDCALL JIT_DebugWriteBarrierEDI(); // JIThelp.asm/JIThelp.s
377     void STDCALL JIT_DebugWriteBarrierEBP(); // JIThelp.asm/JIThelp.s
378
379     void STDCALL JIT_WriteBarrierEAX();        // JIThelp.asm/JIThelp.s
380     void STDCALL JIT_WriteBarrierEBX();        // JIThelp.asm/JIThelp.s
381     void STDCALL JIT_WriteBarrierECX();        // JIThelp.asm/JIThelp.s
382     void STDCALL JIT_WriteBarrierESI();        // JIThelp.asm/JIThelp.s
383     void STDCALL JIT_WriteBarrierEDI();        // JIThelp.asm/JIThelp.s
384     void STDCALL JIT_WriteBarrierEBP();        // JIThelp.asm/JIThelp.s
385
386     void STDCALL JIT_WriteBarrierGroup();
387     void STDCALL JIT_WriteBarrierGroup_End();
388
389     void STDCALL JIT_PatchedWriteBarrierGroup();
390     void STDCALL JIT_PatchedWriteBarrierGroup_End();
391 }
392
393 void ValidateWriteBarrierHelpers();
394
395 #endif //_TARGET_X86_
396
397 extern "C"
398 {
399 #ifndef WIN64EXCEPTIONS
400     void STDCALL JIT_EndCatch();               // JIThelp.asm/JIThelp.s
401 #endif // _TARGET_X86_
402
403     void STDCALL JIT_ByRefWriteBarrier();      // JIThelp.asm/JIThelp.s
404
405 #if defined(_TARGET_AMD64_) || defined(_TARGET_ARM_)
406
407     FCDECL2VA(void, JIT_TailCall, PCODE copyArgs, PCODE target);
408
409 #else // _TARGET_AMD64_ || _TARGET_ARM_
410
411     void STDCALL JIT_TailCall();                    // JIThelp.asm
412
413 #endif // _TARGET_AMD64_ || _TARGET_ARM_
414
415     void STDCALL JIT_MemSet(void *dest, int c, SIZE_T count);
416     void STDCALL JIT_MemCpy(void *dest, const void *src, SIZE_T count);
417
418     void STDCALL JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle);
419 };
420
421
422
423 /*********************************************************************/
424 /*********************************************************************/
425 class CEEInfo : public ICorJitInfo
426 {
427     friend class CEEDynamicCodeInfo;
428     
429     const char * __stdcall ICorMethodInfo_Hack_getMethodName(CORINFO_METHOD_HANDLE ftnHnd, const char** scopeName)
430     {
431         WRAPPER_NO_CONTRACT;
432         return getMethodName(ftnHnd, scopeName);
433     }
434
435     mdMethodDef __stdcall ICorClassInfo_Hack_getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod)
436     {
437         WRAPPER_NO_CONTRACT;
438         return getMethodDefFromMethod(hMethod);
439     }
440     
441 public:
442     // ICorClassInfo stuff
443     CorInfoType asCorInfoType (CORINFO_CLASS_HANDLE cls);
444     // This normalizes EE type information into the form expected by the JIT.
445     //
446     // If typeHnd contains exact type information, then *clsRet will contain
447     // the normalized CORINFO_CLASS_HANDLE information on return.
448     static CorInfoType asCorInfoType (CorElementType cet, 
449                                       TypeHandle typeHnd = TypeHandle() /* optional in */,
450                                       CORINFO_CLASS_HANDLE *clsRet = NULL /* optional out */ );
451
452     CORINFO_MODULE_HANDLE getClassModule(CORINFO_CLASS_HANDLE clsHnd);
453     CORINFO_ASSEMBLY_HANDLE getModuleAssembly(CORINFO_MODULE_HANDLE mod);
454     const char* getAssemblyName(CORINFO_ASSEMBLY_HANDLE assem);
455     void* LongLifetimeMalloc(size_t sz);
456     void LongLifetimeFree(void* obj);
457     size_t getClassModuleIdForStatics(CORINFO_CLASS_HANDLE clsHnd, CORINFO_MODULE_HANDLE *pModuleHandle, void **ppIndirection);
458     const char* getClassName (CORINFO_CLASS_HANDLE cls);
459     const char* getHelperName(CorInfoHelpFunc ftnNum);
460     int appendClassName(__deref_inout_ecount(*pnBufLen) WCHAR** ppBuf,
461                                   int* pnBufLen,
462                                   CORINFO_CLASS_HANDLE    cls,
463                                   BOOL fNamespace,
464                                   BOOL fFullInst,
465                                   BOOL fAssembly);
466     BOOL isValueClass (CORINFO_CLASS_HANDLE cls);
467     BOOL canInlineTypeCheckWithObjectVTable (CORINFO_CLASS_HANDLE cls);
468
469     DWORD getClassAttribs (CORINFO_CLASS_HANDLE cls);
470
471     // Internal version without JIT-EE transition
472     DWORD getClassAttribsInternal (CORINFO_CLASS_HANDLE cls);
473
474     BOOL isStructRequiringStackAllocRetBuf(CORINFO_CLASS_HANDLE cls);
475
476     unsigned getClassSize (CORINFO_CLASS_HANDLE cls);
477     unsigned getClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint);
478     static unsigned getClassAlignmentRequirementStatic(TypeHandle clsHnd);
479
480     // Used for HFA's on IA64...and later for type based disambiguation
481     CORINFO_FIELD_HANDLE getFieldInClass(CORINFO_CLASS_HANDLE clsHnd, INT num);
482
483     mdMethodDef getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod);
484     BOOL checkMethodModifier(CORINFO_METHOD_HANDLE hMethod, LPCSTR modifier, BOOL fOptional);
485
486     unsigned getClassGClayout (CORINFO_CLASS_HANDLE cls, BYTE* gcPtrs); /* really GCType* gcPtrs */
487     unsigned getClassNumInstanceFields(CORINFO_CLASS_HANDLE cls);
488
489     // returns the enregister info for a struct based on type of fields, alignment, etc.
490     bool getSystemVAmd64PassStructInRegisterDescriptor(
491         /*IN*/  CORINFO_CLASS_HANDLE _structHnd,
492         /*OUT*/ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr);
493
494     // Check Visibility rules.
495     // For Protected (family access) members, type of the instance is also
496     // considered when checking visibility rules.
497     
498
499     CorInfoHelpFunc getNewHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_METHOD_HANDLE callerHandle);
500     static CorInfoHelpFunc getNewHelperStatic(MethodTable * pMT);
501
502     CorInfoHelpFunc getNewArrHelper(CORINFO_CLASS_HANDLE arrayCls);
503     static CorInfoHelpFunc getNewArrHelperStatic(TypeHandle clsHnd);
504
505     CorInfoHelpFunc getCastingHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fThrowing);
506     static CorInfoHelpFunc getCastingHelperStatic(TypeHandle clsHnd, bool fThrowing, bool * pfClassMustBeRestored);
507
508     CorInfoHelpFunc getSharedCCtorHelper(CORINFO_CLASS_HANDLE clsHnd);
509     CorInfoHelpFunc getSecurityPrologHelper(CORINFO_METHOD_HANDLE ftn);
510     CORINFO_CLASS_HANDLE getTypeForBox(CORINFO_CLASS_HANDLE  cls); 
511     CorInfoHelpFunc getBoxHelper(CORINFO_CLASS_HANDLE cls);
512     CorInfoHelpFunc getUnBoxHelper(CORINFO_CLASS_HANDLE cls);
513
514     bool getReadyToRunHelper(
515             CORINFO_RESOLVED_TOKEN * pResolvedToken,
516             CORINFO_LOOKUP_KIND *    pGenericLookupKind,
517             CorInfoHelpFunc          id,
518             CORINFO_CONST_LOOKUP *   pLookup
519             );
520
521     void getReadyToRunDelegateCtorHelper(
522             CORINFO_RESOLVED_TOKEN * pTargetMethod,
523             CORINFO_CLASS_HANDLE     delegateType,
524             CORINFO_LOOKUP *   pLookup
525             );
526
527     CorInfoInitClassResult initClass(
528             CORINFO_FIELD_HANDLE    field,
529             CORINFO_METHOD_HANDLE   method,
530             CORINFO_CONTEXT_HANDLE  context,
531             BOOL                    speculative = FALSE);
532
533     void classMustBeLoadedBeforeCodeIsRun (CORINFO_CLASS_HANDLE cls);
534     void methodMustBeLoadedBeforeCodeIsRun (CORINFO_METHOD_HANDLE meth);
535     CORINFO_METHOD_HANDLE mapMethodDeclToMethodImpl(CORINFO_METHOD_HANDLE methHnd);
536     CORINFO_CLASS_HANDLE getBuiltinClass(CorInfoClassId classId);
537     void getGSCookie(GSCookie * pCookieVal, GSCookie ** ppCookieVal);
538
539     // "System.Int32" ==> CORINFO_TYPE_INT..
540     CorInfoType getTypeForPrimitiveValueClass(
541             CORINFO_CLASS_HANDLE        cls
542             );
543
544     // TRUE if child is a subtype of parent
545     // if parent is an interface, then does child implement / extend parent
546     BOOL canCast(
547             CORINFO_CLASS_HANDLE        child,
548             CORINFO_CLASS_HANDLE        parent
549             );
550
551     // TRUE if cls1 and cls2 are considered equivalent types.
552     BOOL areTypesEquivalent(
553             CORINFO_CLASS_HANDLE        cls1,
554             CORINFO_CLASS_HANDLE        cls2
555             );
556
557     // returns is the intersection of cls1 and cls2.
558     CORINFO_CLASS_HANDLE mergeClasses(
559             CORINFO_CLASS_HANDLE        cls1,
560             CORINFO_CLASS_HANDLE        cls2
561             );
562
563     // Given a class handle, returns the Parent type.
564     // For COMObjectType, it returns Class Handle of System.Object.
565     // Returns 0 if System.Object is passed in.
566     CORINFO_CLASS_HANDLE getParentType (
567             CORINFO_CLASS_HANDLE        cls
568             );
569
570     // Returns the CorInfoType of the "child type". If the child type is
571     // not a primitive type, *clsRet will be set.
572     // Given an Array of Type Foo, returns Foo.
573     // Given BYREF Foo, returns Foo
574     CorInfoType getChildType (
575             CORINFO_CLASS_HANDLE       clsHnd,
576             CORINFO_CLASS_HANDLE       *clsRet
577             );
578
579     // Check constraints on type arguments of this class and parent classes
580     BOOL satisfiesClassConstraints(
581             CORINFO_CLASS_HANDLE cls
582             );
583
584     // Check if this is a single dimensional array type
585     BOOL isSDArray(
586             CORINFO_CLASS_HANDLE        cls
587             );
588
589     // Get the number of dimensions in an array 
590     unsigned getArrayRank(
591             CORINFO_CLASS_HANDLE        cls
592             );
593
594     // Get static field data for an array
595     void * getArrayInitializationData(
596             CORINFO_FIELD_HANDLE        field,
597             DWORD                       size
598             );
599
600     // Check Visibility rules.
601     CorInfoIsAccessAllowedResult canAccessClass(
602             CORINFO_RESOLVED_TOKEN * pResolvedToken,
603             CORINFO_METHOD_HANDLE   callerHandle,
604             CORINFO_HELPER_DESC    *pAccessHelper /* If canAccessClass returns something other
605                                                      than ALLOWED, then this is filled in. */
606             );
607
608     // Returns that compilation flags that are shared between JIT and NGen
609     static CORJIT_FLAGS GetBaseCompileFlags(MethodDesc * ftn);
610
611     // Resolve metadata token into runtime method handles.
612     void resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken);
613
614     // Attempt to resolve a metadata token into a runtime method handle. Returns true
615     // if resolution succeeded and false otherwise.
616     bool tryResolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken);
617
618     void getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken,
619                        CORINFO_METHOD_HANDLE  callerHandle,
620                        CORINFO_ACCESS_FLAGS   flags,
621                        CORINFO_FIELD_INFO    *pResult
622                       );
623     static CorInfoHelpFunc getSharedStaticsHelper(FieldDesc * pField, MethodTable * pFieldMT);
624
625     bool isFieldStatic(CORINFO_FIELD_HANDLE fldHnd);
626
627     // Given a signature token sigTOK, use class/method instantiation in context to instantiate any type variables in the signature and return a new signature
628     void findSig(CORINFO_MODULE_HANDLE scopeHnd, unsigned sigTOK, CORINFO_CONTEXT_HANDLE context, CORINFO_SIG_INFO* sig);
629     void findCallSiteSig(CORINFO_MODULE_HANDLE scopeHnd, unsigned methTOK, CORINFO_CONTEXT_HANDLE context, CORINFO_SIG_INFO* sig);
630     CORINFO_CLASS_HANDLE getTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken);
631
632     size_t findNameOfToken (CORINFO_MODULE_HANDLE module, mdToken metaTOK,
633                                       __out_ecount (FQNameCapacity) char * szFQName, size_t FQNameCapacity);
634
635     CorInfoCanSkipVerificationResult canSkipVerification(CORINFO_MODULE_HANDLE moduleHnd);
636
637     // Checks if the given metadata token is valid
638     BOOL isValidToken (
639             CORINFO_MODULE_HANDLE       module,
640             mdToken                    metaTOK);
641
642     // Checks if the given metadata token is valid StringRef
643     BOOL isValidStringRef (
644             CORINFO_MODULE_HANDLE       module,
645             mdToken                    metaTOK);
646
647     static size_t findNameOfToken (Module* module, mdToken metaTOK, 
648                             __out_ecount (FQNameCapacity) char * szFQName, size_t FQNameCapacity);
649
650     // ICorMethodInfo stuff
651     const char* getMethodName (CORINFO_METHOD_HANDLE ftnHnd, const char** scopeName);
652     const char* getMethodNameFromMetadata (CORINFO_METHOD_HANDLE ftnHnd, const char** className, const char** namespaceName);
653     unsigned getMethodHash (CORINFO_METHOD_HANDLE ftnHnd);
654
655     DWORD getMethodAttribs (CORINFO_METHOD_HANDLE ftnHnd);
656     // Internal version without JIT-EE transition
657     DWORD getMethodAttribsInternal (CORINFO_METHOD_HANDLE ftnHnd);
658
659     void setMethodAttribs (CORINFO_METHOD_HANDLE ftnHnd, CorInfoMethodRuntimeFlags attribs);
660
661     bool getMethodInfo (
662             CORINFO_METHOD_HANDLE ftnHnd,
663             CORINFO_METHOD_INFO*  methInfo);
664
665     CorInfoInline canInline (
666             CORINFO_METHOD_HANDLE  callerHnd,
667             CORINFO_METHOD_HANDLE  calleeHnd,
668             DWORD*                 pRestrictions);
669
670     void reportInliningDecision (CORINFO_METHOD_HANDLE inlinerHnd,
671                                  CORINFO_METHOD_HANDLE inlineeHnd,
672                                  CorInfoInline inlineResult,
673                                  const char * reason);
674
675     // Used by ngen
676     CORINFO_METHOD_HANDLE instantiateMethodAtObject(CORINFO_METHOD_HANDLE method);
677
678     // Loads the constraints on a typical method definition, detecting cycles;
679     // used by verifiers.
680     void initConstraintsForVerification(
681             CORINFO_METHOD_HANDLE   method,
682             BOOL *pfHasCircularClassConstraints,
683             BOOL *pfHasCircularMethodConstraints
684             );
685
686     CorInfoInstantiationVerification isInstantiationOfVerifiedGeneric (
687             CORINFO_METHOD_HANDLE  methodHnd);
688
689
690     bool canTailCall (
691             CORINFO_METHOD_HANDLE  callerHnd,
692             CORINFO_METHOD_HANDLE  declaredCalleeHnd,
693             CORINFO_METHOD_HANDLE  exactCalleeHnd,
694             bool fIsTailPrefix);
695
696     void reportTailCallDecision (CORINFO_METHOD_HANDLE callerHnd,
697                                  CORINFO_METHOD_HANDLE calleeHnd,
698                                  bool fIsTailPrefix,
699                                  CorInfoTailCall tailCallResult,
700                                  const char * reason);
701
702     CorInfoCanSkipVerificationResult canSkipMethodVerification(
703         CORINFO_METHOD_HANDLE ftnHnd);
704     
705     // Given a method descriptor ftnHnd, extract signature information into sigInfo
706     // Obtain (representative) instantiation information from ftnHnd's owner class
707     //@GENERICSVER: added explicit owner parameter
708     void getMethodSig (
709             CORINFO_METHOD_HANDLE ftnHnd,
710             CORINFO_SIG_INFO* sigInfo,
711             CORINFO_CLASS_HANDLE owner = NULL
712             );
713     // Internal version without JIT-EE transition
714     void getMethodSigInternal (
715             CORINFO_METHOD_HANDLE ftnHnd,
716             CORINFO_SIG_INFO* sigInfo,
717             CORINFO_CLASS_HANDLE owner = NULL
718             );
719
720     void getEHinfo(
721             CORINFO_METHOD_HANDLE ftn,
722             unsigned      EHnumber,
723             CORINFO_EH_CLAUSE* clause);
724
725     CORINFO_CLASS_HANDLE getMethodClass (CORINFO_METHOD_HANDLE methodHnd);
726     CORINFO_MODULE_HANDLE getMethodModule (CORINFO_METHOD_HANDLE methodHnd);
727
728     void getMethodVTableOffset (
729             CORINFO_METHOD_HANDLE methodHnd,
730             unsigned * pOffsetOfIndirection,
731             unsigned * pOffsetAfterIndirection,
732             bool * isRelative);
733
734     CORINFO_METHOD_HANDLE resolveVirtualMethod(
735         CORINFO_METHOD_HANDLE virtualMethod,
736         CORINFO_CLASS_HANDLE implementingClass,
737         CORINFO_CONTEXT_HANDLE ownerType
738         );
739
740     CORINFO_METHOD_HANDLE resolveVirtualMethodHelper(
741         CORINFO_METHOD_HANDLE virtualMethod,
742         CORINFO_CLASS_HANDLE implementingClass,
743         CORINFO_CONTEXT_HANDLE ownerType
744         );
745
746     void expandRawHandleIntrinsic(
747         CORINFO_RESOLVED_TOKEN *        pResolvedToken,
748         CORINFO_GENERICHANDLE_RESULT *  pResult);
749
750     CorInfoIntrinsics getIntrinsicID(CORINFO_METHOD_HANDLE method,
751                                      bool * pMustExpand = NULL);
752
753     bool isInSIMDModule(CORINFO_CLASS_HANDLE classHnd);
754
755     CorInfoUnmanagedCallConv getUnmanagedCallConv(CORINFO_METHOD_HANDLE method);
756     BOOL pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig);
757
758     // Generate a cookie based on the signature that would needs to be passed
759     //  to the above generic stub
760     LPVOID GetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void ** ppIndirection);
761     bool canGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig);
762     
763     // Check Visibility rules.
764
765     // should we enforce the new (for whidbey) restrictions on calling virtual methods?
766     BOOL shouldEnforceCallvirtRestriction(
767             CORINFO_MODULE_HANDLE   scope);
768
769     // Check constraints on method type arguments (only).
770     // The parent class should be checked separately using satisfiesClassConstraints(parent).
771     BOOL satisfiesMethodConstraints(
772             CORINFO_CLASS_HANDLE        parent, // the exact parent of the method
773             CORINFO_METHOD_HANDLE       method
774             );
775
776     // Given a Delegate type and a method, check if the method signature
777     // is Compatible with the Invoke method of the delegate.
778     //@GENERICSVER: new (suitable for generics)
779     BOOL isCompatibleDelegate(
780             CORINFO_CLASS_HANDLE        objCls,
781             CORINFO_CLASS_HANDLE        methodParentCls,
782             CORINFO_METHOD_HANDLE       method,
783             CORINFO_CLASS_HANDLE        delegateCls,
784             BOOL*                       pfIsOpenDelegate);
785
786     // ICorFieldInfo stuff
787     const char* getFieldName (CORINFO_FIELD_HANDLE field,
788                               const char** scopeName);
789
790     CORINFO_CLASS_HANDLE getFieldClass (CORINFO_FIELD_HANDLE field);
791
792     //@GENERICSVER: added owner parameter
793     CorInfoType getFieldType (CORINFO_FIELD_HANDLE field, CORINFO_CLASS_HANDLE* structType,CORINFO_CLASS_HANDLE owner = NULL);
794     // Internal version without JIT-EE transition
795     CorInfoType getFieldTypeInternal (CORINFO_FIELD_HANDLE field, CORINFO_CLASS_HANDLE* structType,CORINFO_CLASS_HANDLE owner = NULL);
796
797     unsigned getFieldOffset (CORINFO_FIELD_HANDLE field);
798
799     bool isWriteBarrierHelperRequired(CORINFO_FIELD_HANDLE field);
800
801     void* getFieldAddress(CORINFO_FIELD_HANDLE field, void **ppIndirection);
802
803     // ICorDebugInfo stuff
804     void * allocateArray(ULONG cBytes);
805     void freeArray(void *array);
806     void getBoundaries(CORINFO_METHOD_HANDLE ftn,
807                        unsigned int *cILOffsets, DWORD **pILOffsets,
808                        ICorDebugInfo::BoundaryTypes *implictBoundaries);
809     void setBoundaries(CORINFO_METHOD_HANDLE ftn,
810                        ULONG32 cMap, ICorDebugInfo::OffsetMapping *pMap);
811     void getVars(CORINFO_METHOD_HANDLE ftn, ULONG32 *cVars,
812                  ICorDebugInfo::ILVarInfo **vars, bool *extendOthers);
813     void setVars(CORINFO_METHOD_HANDLE ftn, ULONG32 cVars,
814                  ICorDebugInfo::NativeVarInfo *vars);
815
816     // ICorArgInfo stuff
817
818     CorInfoTypeWithMod getArgType (
819             CORINFO_SIG_INFO*       sig,
820             CORINFO_ARG_LIST_HANDLE    args,
821             CORINFO_CLASS_HANDLE       *vcTypeRet
822             );
823
824     CORINFO_CLASS_HANDLE getArgClass (
825             CORINFO_SIG_INFO*       sig,
826             CORINFO_ARG_LIST_HANDLE    args
827             );
828
829     CorInfoType getHFAType (
830             CORINFO_CLASS_HANDLE hClass
831             );
832
833     CORINFO_ARG_LIST_HANDLE getArgNext (
834             CORINFO_ARG_LIST_HANDLE args
835             );
836
837     // ICorErrorInfo stuff
838
839     HRESULT GetErrorHRESULT(struct _EXCEPTION_POINTERS *pExceptionPointers);
840     ULONG GetErrorMessage(__out_ecount(bufferLength) LPWSTR buffer,
841                           ULONG bufferLength);
842     int FilterException(struct _EXCEPTION_POINTERS *pExceptionPointers);
843     void HandleException(struct _EXCEPTION_POINTERS *pExceptionPointers);
844     void ThrowExceptionForJitResult(HRESULT result);
845     void ThrowExceptionForHelper(const CORINFO_HELPER_DESC * throwHelper);
846
847     // ICorStaticInfo stuff
848     void getEEInfo(CORINFO_EE_INFO *pEEInfoOut);
849
850     LPCWSTR getJitTimeLogFilename();
851
852     //ICorDynamicInfo stuff
853     DWORD getFieldThreadLocalStoreID (CORINFO_FIELD_HANDLE field, void **ppIndirection);
854
855     // Stub dispatch stuff
856     void getCallInfo(
857                         CORINFO_RESOLVED_TOKEN * pResolvedToken,
858                         CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken,
859                         CORINFO_METHOD_HANDLE   callerHandle,
860                         CORINFO_CALLINFO_FLAGS  flags,
861                         CORINFO_CALL_INFO      *pResult /*out */);
862     BOOL canAccessFamily(CORINFO_METHOD_HANDLE hCaller,
863                          CORINFO_CLASS_HANDLE hInstanceType);
864
865 protected:
866
867     static void getEHinfoHelper(
868         CORINFO_METHOD_HANDLE   ftnHnd,
869         unsigned                EHnumber,
870         CORINFO_EH_CLAUSE*      clause,
871         COR_ILMETHOD_DECODER*   pILHeader);
872
873     bool isVerifyOnly()
874     {
875         return m_fVerifyOnly;
876     }
877
878 public:
879
880     BOOL isRIDClassDomainID(CORINFO_CLASS_HANDLE cls);
881     unsigned getClassDomainID (CORINFO_CLASS_HANDLE   cls, void **ppIndirection);
882     CORINFO_VARARGS_HANDLE getVarArgsHandle(CORINFO_SIG_INFO *sig, void **ppIndirection);
883     bool canGetVarArgsHandle(CORINFO_SIG_INFO *sig);
884     void* getPInvokeUnmanagedTarget(CORINFO_METHOD_HANDLE method, void **ppIndirection);
885     void* getAddressOfPInvokeFixup(CORINFO_METHOD_HANDLE method, void **ppIndirection);
886     void getAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP *pLookup);
887     CORINFO_JUST_MY_CODE_HANDLE getJustMyCodeHandle(CORINFO_METHOD_HANDLE method, CORINFO_JUST_MY_CODE_HANDLE **ppIndirection);
888
889     void GetProfilingHandle(
890                     BOOL                      *pbHookFunction,
891                     void                     **pProfilerHandle,
892                     BOOL                      *pbIndirectedHandles
893                     );
894
895     InfoAccessType constructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok, void **ppValue);
896     InfoAccessType emptyStringLiteral(void ** ppValue);
897     void* getMethodSync(CORINFO_METHOD_HANDLE ftnHnd, void **ppIndirection);
898
899     DWORD getThreadTLSIndex(void **ppIndirection);
900     const void * getInlinedCallFrameVptr(void **ppIndirection);
901
902     LONG * getAddrOfCaptureThreadGlobal(void **ppIndirection);
903     void* getHelperFtn(CorInfoHelpFunc    ftnNum,                 /* IN  */
904                        void **            ppIndirection);         /* OUT */
905
906     void* getTailCallCopyArgsThunk(CORINFO_SIG_INFO       *pSig,
907                                    CorInfoHelperTailCallSpecialHandling flags);
908
909     void getFunctionEntryPoint(CORINFO_METHOD_HANDLE   ftn,                 /* IN  */
910                                CORINFO_CONST_LOOKUP *  pResult,             /* OUT */
911                                CORINFO_ACCESS_FLAGS    accessFlags = CORINFO_ACCESS_ANY);
912
913     void getFunctionFixedEntryPoint(CORINFO_METHOD_HANDLE   ftn,
914                                     CORINFO_CONST_LOOKUP *  pResult);
915
916     // get slow lazy string literal helper to use (CORINFO_HELP_STRCNS*). 
917     // Returns CORINFO_HELP_UNDEF if lazy string literal helper cannot be used.
918     CorInfoHelpFunc getLazyStringLiteralHelper(CORINFO_MODULE_HANDLE handle);
919
920     CORINFO_MODULE_HANDLE embedModuleHandle(CORINFO_MODULE_HANDLE handle,
921                                             void **ppIndirection);
922     CORINFO_CLASS_HANDLE embedClassHandle(CORINFO_CLASS_HANDLE handle,
923                                           void **ppIndirection);
924     CORINFO_FIELD_HANDLE embedFieldHandle(CORINFO_FIELD_HANDLE handle,
925                                           void **ppIndirection);
926     CORINFO_METHOD_HANDLE embedMethodHandle(CORINFO_METHOD_HANDLE handle,
927                                             void **ppIndirection);
928
929         void embedGenericHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken,
930                 BOOL                     fEmbedParent,
931                 CORINFO_GENERICHANDLE_RESULT *pResult);
932
933     CORINFO_LOOKUP_KIND getLocationOfThisType(CORINFO_METHOD_HANDLE context);
934
935
936     void setOverride(ICorDynamicInfo *pOverride, CORINFO_METHOD_HANDLE currentMethod)
937     {
938         LIMITED_METHOD_CONTRACT;
939         m_pOverride = pOverride;
940         m_pMethodBeingCompiled = (MethodDesc *)currentMethod;     // method being compiled
941
942         m_hMethodForSecurity_Key = NULL;
943         m_pMethodForSecurity_Value = NULL;
944     }
945
946     // Returns whether we are generating code for NGen image.
947     BOOL IsCompilingForNGen()
948     {
949         LIMITED_METHOD_CONTRACT;
950         // NGen is the only place where we set the override
951         return this != m_pOverride;
952     }
953
954     void addActiveDependency(CORINFO_MODULE_HANDLE moduleFrom, CORINFO_MODULE_HANDLE moduleTo);
955     CORINFO_METHOD_HANDLE GetDelegateCtor(
956                         CORINFO_METHOD_HANDLE       methHnd,
957                         CORINFO_CLASS_HANDLE        clsHnd,
958                         CORINFO_METHOD_HANDLE       targetMethodHnd,
959                         DelegateCtorArgs *          pCtorData);
960
961     void MethodCompileComplete(
962                 CORINFO_METHOD_HANDLE methHnd);
963
964     //
965     // ICorJitInfo stuff - none of this should be called on this class
966     //
967
968     IEEMemoryManager* getMemoryManager();
969
970     void allocMem (
971             ULONG               hotCodeSize,    /* IN */
972             ULONG               coldCodeSize,   /* IN */
973             ULONG               roDataSize,     /* IN */
974             ULONG               xcptnsCount,    /* IN */
975             CorJitAllocMemFlag  flag,           /* IN */
976             void **             hotCodeBlock,   /* OUT */
977             void **             coldCodeBlock,  /* OUT */
978             void **             roDataBlock     /* OUT */
979             );
980
981     void reserveUnwindInfo (
982             BOOL                isFunclet,             /* IN */
983             BOOL                isColdCode,            /* IN */
984             ULONG               unwindSize             /* IN */
985             );
986
987     void allocUnwindInfo (
988             BYTE *              pHotCode,              /* IN */
989             BYTE *              pColdCode,             /* IN */
990             ULONG               startOffset,           /* IN */
991             ULONG               endOffset,             /* IN */
992             ULONG               unwindSize,            /* IN */
993             BYTE *              pUnwindBlock,          /* IN */
994             CorJitFuncKind      funcKind               /* IN */
995             );
996
997     void * allocGCInfo (
998             size_t                  size        /* IN */
999             );
1000
1001     void yieldExecution();
1002
1003     void setEHcount (
1004             unsigned                 cEH    /* IN */
1005             );
1006
1007     void setEHinfo (
1008             unsigned                 EHnumber,   /* IN  */
1009             const CORINFO_EH_CLAUSE *clause      /* IN */
1010             );
1011
1012     BOOL logMsg(unsigned level, const char* fmt, va_list args);
1013
1014     int doAssert(const char* szFile, int iLine, const char* szExpr);
1015     
1016     void reportFatalError(CorJitResult result);
1017
1018     void logSQMLongJitEvent(unsigned mcycles, unsigned msec, unsigned ilSize, unsigned numBasicBlocks, bool minOpts, 
1019                             CORINFO_METHOD_HANDLE methodHnd);
1020
1021     HRESULT allocBBProfileBuffer (
1022             ULONG                 count,           // The number of basic blocks that we have
1023             ProfileBuffer **      profileBuffer
1024             );
1025
1026     HRESULT getBBProfileData(
1027             CORINFO_METHOD_HANDLE ftnHnd,
1028             ULONG *               count,           // The number of basic blocks that we have
1029             ProfileBuffer **      profileBuffer,
1030             ULONG *               numRuns
1031             );
1032
1033     void recordCallSite(
1034             ULONG                 instrOffset,  /* IN */
1035             CORINFO_SIG_INFO *    callSig,      /* IN */
1036             CORINFO_METHOD_HANDLE methodHandle  /* IN */
1037             );
1038
1039     void recordRelocation(
1040             void *                 location,   /* IN  */
1041             void *                 target,     /* IN  */
1042             WORD                   fRelocType, /* IN  */
1043             WORD                   slotNum = 0,  /* IN  */
1044             INT32                  addlDelta = 0 /* IN  */
1045             );
1046
1047     WORD getRelocTypeHint(void * target);
1048
1049     void getModuleNativeEntryPointRange(
1050             void ** pStart, /* OUT */
1051             void ** pEnd    /* OUT */
1052             );
1053
1054     DWORD getExpectedTargetArchitecture();
1055
1056     CEEInfo(MethodDesc * fd = NULL, bool fVerifyOnly = false, bool fAllowInlining = true) :
1057         m_pOverride(NULL),
1058         m_pMethodBeingCompiled(fd),
1059         m_fVerifyOnly(fVerifyOnly),
1060         m_pThread(GetThread()),
1061         m_hMethodForSecurity_Key(NULL),
1062         m_pMethodForSecurity_Value(NULL),
1063 #if defined(FEATURE_GDBJIT)
1064         m_pCalledMethods(NULL),
1065 #endif
1066         m_allowInlining(fAllowInlining)
1067     {
1068         LIMITED_METHOD_CONTRACT;
1069     }
1070
1071     virtual ~CEEInfo()
1072     {
1073         LIMITED_METHOD_CONTRACT;
1074     }
1075
1076     // Performs any work JIT-related work that should be performed at process shutdown.
1077     void JitProcessShutdownWork();
1078
1079     void setJitFlags(const CORJIT_FLAGS& jitFlags);
1080
1081     DWORD getJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes);
1082
1083     bool runWithErrorTrap(void (*function)(void*), void* param);
1084
1085 private:
1086     // Shrinking these buffers drastically reduces the amount of stack space
1087     // required for each instance of the interpreter, and thereby reduces SOs.
1088 #ifdef FEATURE_INTERPRETER
1089 #define CLS_STRING_SIZE 8  // force heap allocation
1090 #define CLS_BUFFER_SIZE SBUFFER_PADDED_SIZE(8)
1091 #else
1092 #define CLS_STRING_SIZE MAX_CLASSNAME_LENGTH
1093 #define CLS_BUFFER_SIZE MAX_CLASSNAME_LENGTH
1094 #endif
1095
1096 #ifdef _DEBUG
1097     InlineSString<MAX_CLASSNAME_LENGTH> ssClsNameBuff;
1098     ScratchBuffer<MAX_CLASSNAME_LENGTH> ssClsNameBuffScratch;
1099 #endif
1100
1101 public:
1102
1103     //@GENERICS:
1104     // The method handle is used to instantiate method and class type parameters
1105     // It's also used to determine whether an extra dictionary parameter is required
1106     static 
1107     void 
1108     ConvToJitSig(
1109         PCCOR_SIGNATURE       pSig, 
1110         DWORD                 cbSig, 
1111         CORINFO_MODULE_HANDLE scopeHnd, 
1112         mdToken               token, 
1113         CORINFO_SIG_INFO *    sigRet, 
1114         MethodDesc *          context, 
1115         bool                  localSig, 
1116         TypeHandle            owner = TypeHandle());
1117
1118     MethodDesc * GetMethodForSecurity(CORINFO_METHOD_HANDLE callerHandle);
1119
1120     // Prepare the information about how to do a runtime lookup of the handle with shared
1121     // generic variables.
1122     void ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entryKind,
1123                                                    CORINFO_RESOLVED_TOKEN * pResolvedToken,
1124                                                    CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken /* for ConstrainedMethodEntrySlot */,
1125                                                    MethodDesc * pTemplateMD /* for method-based slots */,
1126                                                    CORINFO_LOOKUP *pResultLookup);
1127
1128 #if defined(FEATURE_GDBJIT)
1129     CalledMethod * GetCalledMethods() { return m_pCalledMethods; }
1130 #endif
1131
1132 protected:
1133     // NGen provides its own modifications to EE-JIT interface. From technical reason it cannot simply inherit 
1134     // from code:CEEInfo class (because it has dependencies on VM that NGen does not want).
1135     // Therefore the "normal" EE-JIT interface has code:m_pOverride hook that is set either to 
1136     //   * 'this' (code:CEEInfo) at runtime, or to 
1137     //   *  code:ZapInfo - the NGen specific implementation of the interface.
1138     ICorDynamicInfo * m_pOverride;
1139     
1140     MethodDesc*             m_pMethodBeingCompiled;             // Top-level method being compiled
1141     bool                    m_fVerifyOnly;
1142     Thread *                m_pThread;                          // Cached current thread for faster JIT-EE transitions
1143     CORJIT_FLAGS            m_jitFlags;
1144
1145     CORINFO_METHOD_HANDLE getMethodBeingCompiled()
1146     {
1147         LIMITED_METHOD_CONTRACT;
1148         return (CORINFO_METHOD_HANDLE)m_pMethodBeingCompiled;
1149     }
1150
1151     // Cache of last GetMethodForSecurity() lookup
1152     CORINFO_METHOD_HANDLE   m_hMethodForSecurity_Key;
1153     MethodDesc *            m_pMethodForSecurity_Value;
1154
1155 #if defined(FEATURE_GDBJIT)
1156     CalledMethod *          m_pCalledMethods;
1157 #endif
1158
1159     bool                    m_allowInlining;
1160
1161     // Tracking of module activation dependencies. We have two flavors: 
1162     // - Fast one that gathers generic arguments from EE handles, but does not work inside generic context.
1163     // - Slow one that operates on typespec and methodspecs from metadata.
1164     void ScanForModuleDependencies(Module* pModule, SigPointer psig);
1165     void ScanMethodSpec(Module * pModule, PCCOR_SIGNATURE pMethodSpec, ULONG cbMethodSpec);
1166     // Returns true if it is ok to proceed with scan of parent chain
1167     BOOL ScanTypeSpec(Module * pModule, PCCOR_SIGNATURE pTypeSpec, ULONG cbTypeSpec);
1168     void ScanInstantiation(Module * pModule, Instantiation inst);
1169
1170     // The main entrypoints for module activation tracking
1171     void ScanToken(Module * pModule, CORINFO_RESOLVED_TOKEN * pResolvedToken, TypeHandle th, MethodDesc * pMD = NULL);
1172     void ScanTokenForDynamicScope(CORINFO_RESOLVED_TOKEN * pResolvedToken, TypeHandle th, MethodDesc * pMD = NULL);
1173 };
1174
1175
1176 /*********************************************************************/
1177
1178 class  EEJitManager;
1179 struct _hpCodeHdr;
1180 typedef struct _hpCodeHdr CodeHeader;
1181
1182 #ifndef CROSSGEN_COMPILE
1183 // CEEJitInfo is the concrete implementation of callbacks that the EE must provide for the JIT to do its
1184 // work.   See code:ICorJitInfo#JitToEEInterface for more on this interface. 
1185 class CEEJitInfo : public CEEInfo
1186 {
1187 public:
1188     // ICorJitInfo stuff
1189
1190     void allocMem (
1191             ULONG               hotCodeSize,    /* IN */
1192             ULONG               coldCodeSize,   /* IN */
1193             ULONG               roDataSize,     /* IN */
1194             ULONG               xcptnsCount,    /* IN */
1195             CorJitAllocMemFlag  flag,           /* IN */
1196             void **             hotCodeBlock,   /* OUT */
1197             void **             coldCodeBlock,  /* OUT */
1198             void **             roDataBlock     /* OUT */
1199             );
1200
1201     void reserveUnwindInfo(BOOL isFunclet, BOOL isColdCode, ULONG unwindSize);
1202
1203     void allocUnwindInfo (
1204             BYTE * pHotCode,              /* IN */
1205             BYTE * pColdCode,             /* IN */
1206             ULONG  startOffset,           /* IN */
1207             ULONG  endOffset,             /* IN */
1208             ULONG  unwindSize,            /* IN */
1209             BYTE * pUnwindBlock,          /* IN */
1210             CorJitFuncKind funcKind       /* IN */
1211             );
1212
1213     void * allocGCInfo (size_t  size);
1214
1215     void setEHcount (unsigned cEH);
1216
1217     void setEHinfo (
1218             unsigned      EHnumber,
1219             const CORINFO_EH_CLAUSE* clause);
1220
1221     void getEHinfo(
1222             CORINFO_METHOD_HANDLE ftn,              /* IN  */
1223             unsigned      EHnumber,                 /* IN */
1224             CORINFO_EH_CLAUSE* clause               /* OUT */
1225             );
1226
1227
1228     HRESULT allocBBProfileBuffer (
1229         ULONG                         count,            // The number of basic blocks that we have
1230         ICorJitInfo::ProfileBuffer ** profileBuffer
1231     );
1232
1233     HRESULT getBBProfileData (
1234         CORINFO_METHOD_HANDLE         ftnHnd,
1235         ULONG *                       count,            // The number of basic blocks that we have
1236         ICorJitInfo::ProfileBuffer ** profileBuffer,
1237         ULONG *                       numRuns
1238     );
1239
1240     void recordCallSite(
1241             ULONG                     instrOffset,  /* IN */
1242             CORINFO_SIG_INFO *        callSig,      /* IN */
1243             CORINFO_METHOD_HANDLE     methodHandle  /* IN */
1244             );
1245
1246     void recordRelocation(
1247             void                    *location,
1248             void                    *target,
1249             WORD                     fRelocType,
1250             WORD                     slot,
1251             INT32                    addlDelta);
1252
1253     WORD getRelocTypeHint(void * target);
1254
1255     void getModuleNativeEntryPointRange(
1256             void**                   pStart,
1257             void**                   pEnd);
1258
1259     DWORD getExpectedTargetArchitecture();
1260
1261     CodeHeader* GetCodeHeader()
1262     {
1263         LIMITED_METHOD_CONTRACT;
1264         return m_CodeHeader;
1265     }
1266
1267     void SetCodeHeader(CodeHeader* pValue)
1268     {
1269         LIMITED_METHOD_CONTRACT;
1270         m_CodeHeader = pValue;
1271     }
1272
1273     void ResetForJitRetry()
1274     {
1275         CONTRACTL {
1276             SO_TOLERANT;
1277             NOTHROW;
1278             GC_NOTRIGGER;
1279         } CONTRACTL_END;
1280
1281         m_CodeHeader = NULL;
1282
1283         if (m_pOffsetMapping != NULL)
1284             delete [] ((BYTE*) m_pOffsetMapping);
1285
1286         if (m_pNativeVarInfo != NULL)
1287             delete [] ((BYTE*) m_pNativeVarInfo);
1288
1289         m_iOffsetMapping = 0;
1290         m_pOffsetMapping = NULL;
1291         m_iNativeVarInfo = 0;
1292         m_pNativeVarInfo = NULL;
1293
1294 #ifdef WIN64EXCEPTIONS
1295         m_moduleBase = NULL;
1296         m_totalUnwindSize = 0;
1297         m_usedUnwindSize = 0;
1298         m_theUnwindBlock = NULL;
1299         m_totalUnwindInfos = 0;
1300         m_usedUnwindInfos = 0;
1301 #endif // WIN64EXCEPTIONS
1302     }
1303
1304 #ifdef _TARGET_AMD64_
1305     void SetAllowRel32(BOOL fAllowRel32)
1306     {
1307         LIMITED_METHOD_CONTRACT;
1308         m_fAllowRel32 = fAllowRel32;
1309     }
1310
1311     void SetRel32Overflow(BOOL fRel32Overflow)
1312     {
1313         LIMITED_METHOD_CONTRACT;
1314         m_fRel32Overflow = fRel32Overflow;
1315     }
1316
1317     BOOL IsRel32Overflow()
1318     {
1319         LIMITED_METHOD_CONTRACT;
1320         return m_fRel32Overflow;
1321     }
1322
1323     BOOL JitAgain()
1324     {
1325         LIMITED_METHOD_CONTRACT;
1326         return m_fRel32Overflow;
1327     }
1328 #else
1329     BOOL JitAgain()
1330     {
1331         LIMITED_METHOD_CONTRACT;
1332         return FALSE;
1333     }
1334 #endif
1335
1336     CEEJitInfo(MethodDesc* fd,  COR_ILMETHOD_DECODER* header, 
1337                EEJitManager* jm, bool fVerifyOnly, bool allowInlining = true)
1338         : CEEInfo(fd, fVerifyOnly, allowInlining),
1339           m_jitManager(jm),
1340           m_CodeHeader(NULL),
1341           m_ILHeader(header),
1342 #ifdef WIN64EXCEPTIONS
1343           m_moduleBase(NULL),
1344           m_totalUnwindSize(0),
1345           m_usedUnwindSize(0),
1346           m_theUnwindBlock(NULL),
1347           m_totalUnwindInfos(0),
1348           m_usedUnwindInfos(0),
1349 #endif
1350 #ifdef _TARGET_AMD64_
1351           m_fAllowRel32(FALSE),
1352           m_fRel32Overflow(FALSE),
1353 #endif
1354           m_GCinfo_len(0),
1355           m_EHinfo_len(0),
1356           m_iOffsetMapping(0),
1357           m_pOffsetMapping(NULL),
1358           m_iNativeVarInfo(0),
1359           m_pNativeVarInfo(NULL),
1360           m_gphCache()
1361     {
1362         CONTRACTL
1363         {
1364             NOTHROW;
1365             GC_NOTRIGGER;
1366             MODE_ANY;
1367         } CONTRACTL_END;
1368
1369         m_pOverride = this;
1370     }
1371
1372     ~CEEJitInfo()
1373     {
1374         CONTRACTL
1375         {
1376             NOTHROW;
1377             GC_NOTRIGGER;
1378             MODE_ANY;
1379         } CONTRACTL_END;
1380
1381         if (m_pOffsetMapping != NULL)
1382             delete [] ((BYTE*) m_pOffsetMapping);
1383
1384         if (m_pNativeVarInfo != NULL)
1385             delete [] ((BYTE*) m_pNativeVarInfo);
1386     }
1387
1388     // ICorDebugInfo stuff.
1389     void setBoundaries(CORINFO_METHOD_HANDLE ftn,
1390                        ULONG32 cMap, ICorDebugInfo::OffsetMapping *pMap);
1391     void setVars(CORINFO_METHOD_HANDLE ftn, ULONG32 cVars,
1392                  ICorDebugInfo::NativeVarInfo *vars);
1393     void CompressDebugInfo();
1394
1395     void* getHelperFtn(CorInfoHelpFunc    ftnNum,                 /* IN  */
1396                        void **            ppIndirection);         /* OUT */
1397     static PCODE getHelperFtnStatic(CorInfoHelpFunc ftnNum);
1398
1399     // Override active dependency to talk to loader
1400     void addActiveDependency(CORINFO_MODULE_HANDLE moduleFrom, CORINFO_MODULE_HANDLE moduleTo);
1401
1402     // Override of CEEInfo::GetProfilingHandle.  The first time this is called for a
1403     // method desc, it calls through to CEEInfo::GetProfilingHandle and caches the
1404     // result in CEEJitInfo::GetProfilingHandleCache.  Thereafter, this wrapper regurgitates the cached values
1405     // rather than calling into CEEInfo::GetProfilingHandle each time.  This avoids
1406     // making duplicate calls into the profiler's FunctionIDMapper callback.
1407     void GetProfilingHandle(
1408                     BOOL                      *pbHookFunction,
1409                     void                     **pProfilerHandle,
1410                     BOOL                      *pbIndirectedHandles
1411                     );
1412
1413     InfoAccessType constructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok, void **ppValue);
1414     InfoAccessType emptyStringLiteral(void ** ppValue);
1415     void* getFieldAddress(CORINFO_FIELD_HANDLE field, void **ppIndirection);
1416     void* getMethodSync(CORINFO_METHOD_HANDLE ftnHnd, void **ppIndirection);
1417
1418     void BackoutJitData(EEJitManager * jitMgr);
1419
1420 protected :
1421     EEJitManager*           m_jitManager;   // responsible for allocating memory
1422     CodeHeader*             m_CodeHeader;   // descriptor for JITTED code
1423     COR_ILMETHOD_DECODER *  m_ILHeader;     // the code header as exist in the file
1424 #ifdef WIN64EXCEPTIONS
1425     TADDR                   m_moduleBase;       // Base for unwind Infos
1426     ULONG                   m_totalUnwindSize;  // Total reserved unwind space
1427     ULONG                   m_usedUnwindSize;   // used space in m_theUnwindBlock
1428     BYTE *                  m_theUnwindBlock;   // start of the unwind memory block
1429     ULONG                   m_totalUnwindInfos; // Number of RUNTIME_FUNCTION needed
1430     ULONG                   m_usedUnwindInfos;
1431 #endif
1432
1433 #ifdef _TARGET_AMD64_
1434     BOOL                    m_fAllowRel32;      // Use 32-bit PC relative address modes
1435     BOOL                    m_fRel32Overflow;   // Overflow while trying to use encode 32-bit PC relative address. 
1436                                                 // The code will need to be regenerated with m_fRel32Allowed == FALSE.
1437 #endif
1438
1439 #if defined(_DEBUG)
1440     ULONG                   m_codeSize;     // Code size requested via allocMem
1441 #endif
1442
1443     size_t                  m_GCinfo_len;   // Cached copy of GCinfo_len so we can backout in BackoutJitData()
1444     size_t                  m_EHinfo_len;   // Cached copy of EHinfo_len so we can backout in BackoutJitData()
1445
1446     ULONG32                 m_iOffsetMapping;
1447     ICorDebugInfo::OffsetMapping * m_pOffsetMapping;
1448
1449     ULONG32                 m_iNativeVarInfo;
1450     ICorDebugInfo::NativeVarInfo * m_pNativeVarInfo;
1451
1452     // The first time a call is made to CEEJitInfo::GetProfilingHandle() from this thread
1453     // for this method, these values are filled in.   Thereafter, these values are used
1454     // in lieu of calling into the base CEEInfo::GetProfilingHandle() again.  This protects the
1455     // profiler from duplicate calls to its FunctionIDMapper() callback.
1456     struct GetProfilingHandleCache
1457     {
1458         GetProfilingHandleCache() :
1459             m_bGphIsCacheValid(false),
1460             m_bGphHookFunction(false),
1461             m_pvGphProfilerHandle(NULL)
1462         {
1463             LIMITED_METHOD_CONTRACT;
1464         }
1465           
1466         bool                    m_bGphIsCacheValid : 1;        // Tells us whether below values are valid
1467         bool                    m_bGphHookFunction : 1;
1468         void*                   m_pvGphProfilerHandle;
1469     } m_gphCache;
1470
1471 };
1472 #endif // CROSSGEN_COMPILE
1473
1474 /*********************************************************************/
1475 /*********************************************************************/
1476
1477 typedef struct {
1478     void * pfnHelper;
1479 #ifdef _DEBUG
1480     const char* name;
1481 #endif
1482 } VMHELPDEF;
1483
1484 #if defined(DACCESS_COMPILE)
1485
1486 GARY_DECL(VMHELPDEF, hlpFuncTable, CORINFO_HELP_COUNT);
1487
1488 #else
1489
1490 extern "C" const VMHELPDEF hlpFuncTable[CORINFO_HELP_COUNT];
1491
1492 #endif
1493
1494 #if defined(_DEBUG) && (defined(_TARGET_AMD64_) || defined(_TARGET_X86_)) && !defined(FEATURE_PAL)
1495 typedef struct {
1496     void*       pfnRealHelper;
1497     const char* helperName;
1498     LONG        count;
1499     LONG        helperSize;
1500 } VMHELPCOUNTDEF;
1501
1502 extern "C" VMHELPCOUNTDEF hlpFuncCountTable[CORINFO_HELP_COUNT+1];
1503
1504 void InitJitHelperLogging();
1505 void WriteJitHelperCountToSTRESSLOG();
1506 #else
1507 inline void InitJitHelperLogging() { }
1508 inline void WriteJitHelperCountToSTRESSLOG() { }
1509 #endif
1510
1511 // enum for dynamically assigned helper calls
1512 enum DynamicCorInfoHelpFunc {
1513 #define JITHELPER(code, pfnHelper, sig)
1514 #define DYNAMICJITHELPER(code, pfnHelper, sig) DYNAMIC_##code,
1515 #include "jithelpers.h"
1516     DYNAMIC_CORINFO_HELP_COUNT
1517 };
1518
1519 #ifdef _MSC_VER
1520 // GCC complains about duplicate "extern". And it is not needed for the GCC build
1521 extern "C"
1522 #endif
1523 GARY_DECL(VMHELPDEF, hlpDynamicFuncTable, DYNAMIC_CORINFO_HELP_COUNT);
1524
1525 #define SetJitHelperFunction(ftnNum, pFunc) _SetJitHelperFunction(DYNAMIC_##ftnNum, (void*)(pFunc))
1526 void    _SetJitHelperFunction(DynamicCorInfoHelpFunc ftnNum, void * pFunc);
1527 #ifdef ENABLE_FAST_GCPOLL_HELPER
1528 //These should only be called from ThreadStore::TrapReturningThreads!
1529
1530 //Called when the VM wants to suspend one or more threads.
1531 void    EnableJitGCPoll();
1532 //Called when there are no threads to suspend.
1533 void    DisableJitGCPoll();
1534 #endif
1535
1536 // Helper for RtlVirtualUnwind-based tail calls
1537 #if defined(_TARGET_AMD64_) || defined(_TARGET_ARM_)
1538
1539 // The Stub-linker generated assembly routine to copy arguments from the va_list
1540 // into the CONTEXT and the stack.
1541 //
1542 typedef size_t (*pfnCopyArgs)(va_list, _CONTEXT *, DWORD_PTR *, size_t);
1543
1544 // Forward declaration from Frames.h
1545 class TailCallFrame;
1546
1547 // The shared stub return location
1548 EXTERN_C void JIT_TailCallHelperStub_ReturnAddress();
1549
1550 #endif // _TARGET_AMD64_ || _TARGET_ARM_
1551
1552 void *GenFastGetSharedStaticBase(bool bCheckCCtor);
1553
1554 #ifdef HAVE_GCCOVER
1555 void SetupGcCoverage(MethodDesc* pMD, BYTE* nativeCode);
1556 void SetupGcCoverageForNativeImage(Module* module);
1557 bool IsGcCoverageInterrupt(LPVOID ip);
1558 BOOL OnGcCoverageInterrupt(PT_CONTEXT regs);
1559 void DoGcStress (PT_CONTEXT regs, MethodDesc *pMD);
1560 #endif //HAVE_GCCOVER
1561
1562 EXTERN_C FCDECL2(LPVOID, ArrayStoreCheck, Object** pElement, PtrArray** pArray);
1563
1564 OBJECTHANDLE ConstructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok);
1565
1566 FCDECL2(Object*, JIT_Box, CORINFO_CLASS_HANDLE type, void* data);
1567 FCDECL0(VOID, JIT_PollGC);
1568 #ifdef ENABLE_FAST_GCPOLL_HELPER
1569 EXTERN_C FCDECL0(VOID, JIT_PollGC_Nop);
1570 #endif
1571
1572 BOOL ObjIsInstanceOf(Object *pObject, TypeHandle toTypeHnd, BOOL throwCastException = FALSE);
1573 EXTERN_C TypeHandle::CastResult STDCALL ObjIsInstanceOfNoGC(Object *pObject, TypeHandle toTypeHnd);
1574
1575 #ifdef _WIN64
1576 class InlinedCallFrame;
1577 Thread * __stdcall JIT_InitPInvokeFrame(InlinedCallFrame *pFrame, PTR_VOID StubSecretArg);
1578 #endif
1579
1580 #ifdef _DEBUG
1581 extern LONG g_JitCount;
1582 #endif
1583
1584 struct VirtualFunctionPointerArgs
1585 {
1586     CORINFO_CLASS_HANDLE classHnd;
1587     CORINFO_METHOD_HANDLE methodHnd;
1588 };
1589
1590 FCDECL2(CORINFO_MethodPtr, JIT_VirtualFunctionPointer_Dynamic, Object * objectUNSAFE, VirtualFunctionPointerArgs * pArgs);
1591
1592 typedef HCCALL2_PTR(TADDR, FnStaticBaseHelper, TADDR arg0, TADDR arg1);
1593
1594 struct StaticFieldAddressArgs
1595 {
1596     FnStaticBaseHelper staticBaseHelper;
1597     TADDR arg0;
1598     TADDR arg1;
1599     SIZE_T offset;
1600 };
1601
1602 FCDECL1(TADDR, JIT_StaticFieldAddress_Dynamic, StaticFieldAddressArgs * pArgs);
1603 FCDECL1(TADDR, JIT_StaticFieldAddressUnbox_Dynamic, StaticFieldAddressArgs * pArgs);
1604
1605 struct GenericHandleArgs
1606 {
1607     LPVOID signature;
1608     CORINFO_MODULE_HANDLE module;
1609     DWORD dictionaryIndexAndSlot;
1610 };
1611
1612 FCDECL2(CORINFO_GENERIC_HANDLE, JIT_GenericHandleMethodWithSlotAndModule, CORINFO_METHOD_HANDLE  methodHnd, GenericHandleArgs * pArgs);
1613 FCDECL2(CORINFO_GENERIC_HANDLE, JIT_GenericHandleClassWithSlotAndModule, CORINFO_CLASS_HANDLE classHnd, GenericHandleArgs * pArgs);
1614
1615 CORINFO_GENERIC_HANDLE JIT_GenericHandleWorker(MethodDesc   *pMD,
1616                                                MethodTable  *pMT,
1617                                                LPVOID        signature,
1618                                                DWORD         dictionaryIndexAndSlot = -1,
1619                                                Module *      pModule = NULL);
1620
1621 void ClearJitGenericHandleCache(AppDomain *pDomain);
1622
1623 class JitHelpers {
1624 public:
1625     static FCDECL3(void, UnsafeSetArrayElement, PtrArray* pPtrArray, INT32 index, Object* object);
1626 };
1627
1628 CORJIT_FLAGS GetDebuggerCompileFlags(Module* pModule, CORJIT_FLAGS flags);
1629
1630 bool __stdcall TrackAllocationsEnabled();
1631
1632 #endif // JITINTERFACE_H