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