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
8 // ===========================================================================
11 #ifndef JITINTERFACE_H
12 #define JITINTERFACE_H
16 #include "corcompile.h"
17 #endif // FEATURE_PREJIT
20 #define MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT ((32*1024)-1) // when generating JIT code
22 #define MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT ((GetOsPageSize() / 2) - 1)
23 #endif // !FEATURE_PAL
28 enum RuntimeExceptionKind;
31 #if defined(FEATURE_GDBJIT)
35 #include "genericdict.h"
37 inline FieldDesc* GetField(CORINFO_FIELD_HANDLE fieldHandle)
39 LIMITED_METHOD_CONTRACT;
40 return (FieldDesc*) fieldHandle;
44 bool SigInfoFlagsAreValid (CORINFO_SIG_INFO *sig)
46 LIMITED_METHOD_CONTRACT;
47 return !(sig->flags & ~( CORINFO_SIGFLAG_IS_LOCAL_SIG
48 | CORINFO_SIGFLAG_IL_STUB
53 void InitJITHelpers1();
54 void InitJITHelpers2();
56 PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* header,
57 CORJIT_FLAGS flags, ULONG* sizeOfCode = NULL);
59 void getMethodInfoHelper(MethodDesc * ftn,
60 CORINFO_METHOD_HANDLE ftnHnd,
61 COR_ILMETHOD_DECODER * header,
62 CORINFO_METHOD_INFO * methInfo);
64 void getMethodInfoILMethodHeaderHelper(
65 COR_ILMETHOD_DECODER* header,
66 CORINFO_METHOD_INFO* methInfo
71 BOOL LoadDynamicInfoEntry(Module *currentModule,
74 #endif // FEATURE_PREJIT
77 // The legacy x86 monitor helpers do not need a state argument
79 #if !defined(_TARGET_X86_)
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
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
93 #endif // _TARGET_X86_
97 // JIT HELPER ALIASING FOR PORTABILITY.
99 // The portable helper is used if the platform does not provide optimized implementation.
103 #define JIT_MonEnter JIT_MonEnter_Portable
105 EXTERN_C FCDECL1(void, JIT_MonEnter, Object *obj);
106 EXTERN_C FCDECL1(void, JIT_MonEnter_Portable, Object *obj);
108 #ifndef JIT_MonEnterWorker
109 #define JIT_MonEnterWorker JIT_MonEnterWorker_Portable
111 EXTERN_C FCDECL_MONHELPER(JIT_MonEnterWorker, Object *obj);
112 EXTERN_C FCDECL_MONHELPER(JIT_MonEnterWorker_Portable, Object *obj);
114 #ifndef JIT_MonReliableEnter
115 #define JIT_MonReliableEnter JIT_MonReliableEnter_Portable
117 EXTERN_C FCDECL2(void, JIT_MonReliableEnter, Object* obj, BYTE *tookLock);
118 EXTERN_C FCDECL2(void, JIT_MonReliableEnter_Portable, Object* obj, BYTE *tookLock);
120 #ifndef JIT_MonTryEnter
121 #define JIT_MonTryEnter JIT_MonTryEnter_Portable
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);
127 #define JIT_MonExit JIT_MonExit_Portable
129 EXTERN_C FCDECL1(void, JIT_MonExit, Object *obj);
130 EXTERN_C FCDECL1(void, JIT_MonExit_Portable, Object *obj);
132 #ifndef JIT_MonExitWorker
133 #define JIT_MonExitWorker JIT_MonExitWorker_Portable
135 EXTERN_C FCDECL_MONHELPER(JIT_MonExitWorker, Object *obj);
136 EXTERN_C FCDECL_MONHELPER(JIT_MonExitWorker_Portable, Object *obj);
138 #ifndef JIT_MonEnterStatic
139 #define JIT_MonEnterStatic JIT_MonEnterStatic_Portable
141 EXTERN_C FCDECL_MONHELPER(JIT_MonEnterStatic, AwareLock *lock);
142 EXTERN_C FCDECL_MONHELPER(JIT_MonEnterStatic_Portable, AwareLock *lock);
144 #ifndef JIT_MonExitStatic
145 #define JIT_MonExitStatic JIT_MonExitStatic_Portable
147 EXTERN_C FCDECL_MONHELPER(JIT_MonExitStatic, AwareLock *lock);
148 EXTERN_C FCDECL_MONHELPER(JIT_MonExitStatic_Portable, AwareLock *lock);
151 #ifndef JIT_GetSharedGCStaticBase
152 #define JIT_GetSharedGCStaticBase JIT_GetSharedGCStaticBase_Portable
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);
157 #ifndef JIT_GetSharedNonGCStaticBase
158 #define JIT_GetSharedNonGCStaticBase JIT_GetSharedNonGCStaticBase_Portable
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);
163 #ifndef JIT_GetSharedGCStaticBaseNoCtor
164 #define JIT_GetSharedGCStaticBaseNoCtor JIT_GetSharedGCStaticBaseNoCtor_Portable
166 EXTERN_C FCDECL1(void*, JIT_GetSharedGCStaticBaseNoCtor, SIZE_T moduleDomainID);
167 EXTERN_C FCDECL1(void*, JIT_GetSharedGCStaticBaseNoCtor_Portable, SIZE_T moduleDomainID);
169 #ifndef JIT_GetSharedNonGCStaticBaseNoCtor
170 #define JIT_GetSharedNonGCStaticBaseNoCtor JIT_GetSharedNonGCStaticBaseNoCtor_Portable
172 EXTERN_C FCDECL1(void*, JIT_GetSharedNonGCStaticBaseNoCtor, SIZE_T moduleDomainID);
173 EXTERN_C FCDECL1(void*, JIT_GetSharedNonGCStaticBaseNoCtor_Portable, SIZE_T moduleDomainID);
175 #ifndef JIT_ChkCastClass
176 #define JIT_ChkCastClass JIT_ChkCastClass_Portable
178 EXTERN_C FCDECL2(Object*, JIT_ChkCastClass, MethodTable* pMT, Object* pObject);
179 EXTERN_C FCDECL2(Object*, JIT_ChkCastClass_Portable, MethodTable* pMT, Object* pObject);
181 #ifndef JIT_ChkCastClassSpecial
182 #define JIT_ChkCastClassSpecial JIT_ChkCastClassSpecial_Portable
184 EXTERN_C FCDECL2(Object*, JIT_ChkCastClassSpecial, MethodTable* pMT, Object* pObject);
185 EXTERN_C FCDECL2(Object*, JIT_ChkCastClassSpecial_Portable, MethodTable* pMT, Object* pObject);
187 #ifndef JIT_IsInstanceOfClass
188 #define JIT_IsInstanceOfClass JIT_IsInstanceOfClass_Portable
190 EXTERN_C FCDECL2(Object*, JIT_IsInstanceOfClass, MethodTable* pMT, Object* pObject);
191 EXTERN_C FCDECL2(Object*, JIT_IsInstanceOfClass_Portable, MethodTable* pMT, Object* pObject);
193 #ifndef JIT_ChkCastInterface
194 #define JIT_ChkCastInterface JIT_ChkCastInterface_Portable
196 EXTERN_C FCDECL2(Object*, JIT_ChkCastInterface, MethodTable* pMT, Object* pObject);
197 EXTERN_C FCDECL2(Object*, JIT_ChkCastInterface_Portable, MethodTable* pMT, Object* pObject);
199 #ifndef JIT_IsInstanceOfInterface
200 #define JIT_IsInstanceOfInterface JIT_IsInstanceOfInterface_Portable
202 EXTERN_C FCDECL2(Object*, JIT_IsInstanceOfInterface, MethodTable* pMT, Object* pObject);
203 EXTERN_C FCDECL2(Object*, JIT_IsInstanceOfInterface_Portable, MethodTable* pMT, Object* pObject);
205 extern FCDECL1(Object*, JIT_NewS_MP_FastPortable, CORINFO_CLASS_HANDLE typeHnd_);
206 extern FCDECL1(Object*, JIT_New, CORINFO_CLASS_HANDLE typeHnd_);
208 #ifndef JIT_NewCrossContext
209 #define JIT_NewCrossContext JIT_NewCrossContext_Portable
211 EXTERN_C FCDECL1(Object*, JIT_NewCrossContext, CORINFO_CLASS_HANDLE typeHnd_);
212 EXTERN_C FCDECL1(Object*, JIT_NewCrossContext_Portable, CORINFO_CLASS_HANDLE typeHnd_);
214 extern FCDECL1(StringObject*, AllocateString_MP_FastPortable, DWORD stringLength);
215 extern FCDECL1(StringObject*, UnframedAllocateString, DWORD stringLength);
216 extern FCDECL1(StringObject*, FramedAllocateString, DWORD stringLength);
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);
223 #ifndef JIT_Stelem_Ref
224 #define JIT_Stelem_Ref JIT_Stelem_Ref_Portable
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);
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);
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);
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);
245 FCDECL1(void*, JIT_SafeReturnableByref, void* byref);
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);
251 // Regular checked write barrier.
252 extern "C" FCDECL2(VOID, JIT_CheckedWriteBarrier, Object **dst, Object *ref);
255 extern "C" FCDECL2(VOID, JIT_WriteBarrier, Object **dst, Object *ref);
257 extern "C" FCDECL2(VOID, JIT_WriteBarrierEnsureNonHeapTarget, Object **dst, Object *ref);
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);
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);
267 extern "C" FCDECL1(void, JIT_InternalThrow, unsigned exceptNum);
268 extern "C" FCDECL1(void*, JIT_InternalThrowFromHelper, unsigned exceptNum);
270 #ifdef _TARGET_AMD64_
273 class WriteBarrierManager
276 enum WriteBarrierType
278 WRITE_BARRIER_UNINITIALIZED,
279 WRITE_BARRIER_PREGROW64,
280 WRITE_BARRIER_POSTGROW64,
281 #ifdef FEATURE_SVR_GC
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
294 WriteBarrierManager();
297 void UpdateEphemeralBounds(bool isRuntimeSuspended);
298 void UpdateWriteWatchAndCardTableLocations(bool isRuntimeSuspended, bool bReqUpperBoundsCheck);
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
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);
316 WriteBarrierType m_currentWriteBarrier;
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 |
325 #endif // _TARGET_AMD64_
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);
335 EXTERN_C FCDECL2_VV(INT64, JIT_LMul, INT64 val1, INT64 val2);
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);
343 EXTERN_C FCDECL1_V(INT32, JIT_Dbl2IntOvf, double val);
345 EXTERN_C FCDECL2_VV(float, JIT_FltRem, float dividend, float divisor);
346 EXTERN_C FCDECL2_VV(double, JIT_DblRem, double dividend, double divisor);
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_
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
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
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
386 void STDCALL JIT_WriteBarrierGroup();
387 void STDCALL JIT_WriteBarrierGroup_End();
389 void STDCALL JIT_PatchedWriteBarrierGroup();
390 void STDCALL JIT_PatchedWriteBarrierGroup_End();
393 void ValidateWriteBarrierHelpers();
395 #endif //_TARGET_X86_
399 #ifndef WIN64EXCEPTIONS
400 void STDCALL JIT_EndCatch(); // JIThelp.asm/JIThelp.s
401 #endif // _TARGET_X86_
403 void STDCALL JIT_ByRefWriteBarrier(); // JIThelp.asm/JIThelp.s
405 #if defined(_TARGET_AMD64_) || defined(_TARGET_ARM_)
407 FCDECL2VA(void, JIT_TailCall, PCODE copyArgs, PCODE target);
409 #else // _TARGET_AMD64_ || _TARGET_ARM_
411 void STDCALL JIT_TailCall(); // JIThelp.asm
413 #endif // _TARGET_AMD64_ || _TARGET_ARM_
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);
418 void STDCALL JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle);
423 /*********************************************************************/
424 /*********************************************************************/
425 class CEEInfo : public ICorJitInfo
427 friend class CEEDynamicCodeInfo;
429 const char * __stdcall ICorMethodInfo_Hack_getMethodName(CORINFO_METHOD_HANDLE ftnHnd, const char** scopeName)
432 return getMethodName(ftnHnd, scopeName);
435 mdMethodDef __stdcall ICorClassInfo_Hack_getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod)
438 return getMethodDefFromMethod(hMethod);
442 // ICorClassInfo stuff
443 CorInfoType asCorInfoType (CORINFO_CLASS_HANDLE cls);
444 // This normalizes EE type information into the form expected by the JIT.
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 */ );
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,
462 CORINFO_CLASS_HANDLE cls,
466 BOOL isValueClass (CORINFO_CLASS_HANDLE cls);
467 BOOL canInlineTypeCheckWithObjectVTable (CORINFO_CLASS_HANDLE cls);
469 DWORD getClassAttribs (CORINFO_CLASS_HANDLE cls);
471 // Internal version without JIT-EE transition
472 DWORD getClassAttribsInternal (CORINFO_CLASS_HANDLE cls);
474 BOOL isStructRequiringStackAllocRetBuf(CORINFO_CLASS_HANDLE cls);
476 unsigned getClassSize (CORINFO_CLASS_HANDLE cls);
477 unsigned getClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint);
478 static unsigned getClassAlignmentRequirementStatic(TypeHandle clsHnd);
480 // Used for HFA's on IA64...and later for type based disambiguation
481 CORINFO_FIELD_HANDLE getFieldInClass(CORINFO_CLASS_HANDLE clsHnd, INT num);
483 mdMethodDef getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod);
484 BOOL checkMethodModifier(CORINFO_METHOD_HANDLE hMethod, LPCSTR modifier, BOOL fOptional);
486 unsigned getClassGClayout (CORINFO_CLASS_HANDLE cls, BYTE* gcPtrs); /* really GCType* gcPtrs */
487 unsigned getClassNumInstanceFields(CORINFO_CLASS_HANDLE cls);
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);
494 // Check Visibility rules.
495 // For Protected (family access) members, type of the instance is also
496 // considered when checking visibility rules.
499 CorInfoHelpFunc getNewHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_METHOD_HANDLE callerHandle);
500 static CorInfoHelpFunc getNewHelperStatic(MethodTable * pMT);
502 CorInfoHelpFunc getNewArrHelper(CORINFO_CLASS_HANDLE arrayCls);
503 static CorInfoHelpFunc getNewArrHelperStatic(TypeHandle clsHnd);
505 CorInfoHelpFunc getCastingHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fThrowing);
506 static CorInfoHelpFunc getCastingHelperStatic(TypeHandle clsHnd, bool fThrowing, bool * pfClassMustBeRestored);
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);
514 bool getReadyToRunHelper(
515 CORINFO_RESOLVED_TOKEN * pResolvedToken,
516 CORINFO_LOOKUP_KIND * pGenericLookupKind,
518 CORINFO_CONST_LOOKUP * pLookup
521 void getReadyToRunDelegateCtorHelper(
522 CORINFO_RESOLVED_TOKEN * pTargetMethod,
523 CORINFO_CLASS_HANDLE delegateType,
524 CORINFO_LOOKUP * pLookup
527 CorInfoInitClassResult initClass(
528 CORINFO_FIELD_HANDLE field,
529 CORINFO_METHOD_HANDLE method,
530 CORINFO_CONTEXT_HANDLE context,
531 BOOL speculative = FALSE);
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);
539 // "System.Int32" ==> CORINFO_TYPE_INT..
540 CorInfoType getTypeForPrimitiveValueClass(
541 CORINFO_CLASS_HANDLE cls
544 // TRUE if child is a subtype of parent
545 // if parent is an interface, then does child implement / extend parent
547 CORINFO_CLASS_HANDLE child,
548 CORINFO_CLASS_HANDLE parent
551 // TRUE if cls1 and cls2 are considered equivalent types.
552 BOOL areTypesEquivalent(
553 CORINFO_CLASS_HANDLE cls1,
554 CORINFO_CLASS_HANDLE cls2
557 // returns is the intersection of cls1 and cls2.
558 CORINFO_CLASS_HANDLE mergeClasses(
559 CORINFO_CLASS_HANDLE cls1,
560 CORINFO_CLASS_HANDLE cls2
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
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
579 // Check constraints on type arguments of this class and parent classes
580 BOOL satisfiesClassConstraints(
581 CORINFO_CLASS_HANDLE cls
584 // Check if this is a single dimensional array type
586 CORINFO_CLASS_HANDLE cls
589 // Get the number of dimensions in an array
590 unsigned getArrayRank(
591 CORINFO_CLASS_HANDLE cls
594 // Get static field data for an array
595 void * getArrayInitializationData(
596 CORINFO_FIELD_HANDLE field,
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. */
608 // Returns that compilation flags that are shared between JIT and NGen
609 static CORJIT_FLAGS GetBaseCompileFlags(MethodDesc * ftn);
611 // Resolve metadata token into runtime method handles.
612 void resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken);
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);
618 void getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken,
619 CORINFO_METHOD_HANDLE callerHandle,
620 CORINFO_ACCESS_FLAGS flags,
621 CORINFO_FIELD_INFO *pResult
623 static CorInfoHelpFunc getSharedStaticsHelper(FieldDesc * pField, MethodTable * pFieldMT);
625 bool isFieldStatic(CORINFO_FIELD_HANDLE fldHnd);
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);
632 size_t findNameOfToken (CORINFO_MODULE_HANDLE module, mdToken metaTOK,
633 __out_ecount (FQNameCapacity) char * szFQName, size_t FQNameCapacity);
635 CorInfoCanSkipVerificationResult canSkipVerification(CORINFO_MODULE_HANDLE moduleHnd);
637 // Checks if the given metadata token is valid
639 CORINFO_MODULE_HANDLE module,
642 // Checks if the given metadata token is valid StringRef
643 BOOL isValidStringRef (
644 CORINFO_MODULE_HANDLE module,
647 static size_t findNameOfToken (Module* module, mdToken metaTOK,
648 __out_ecount (FQNameCapacity) char * szFQName, size_t FQNameCapacity);
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);
655 DWORD getMethodAttribs (CORINFO_METHOD_HANDLE ftnHnd);
656 // Internal version without JIT-EE transition
657 DWORD getMethodAttribsInternal (CORINFO_METHOD_HANDLE ftnHnd);
659 void setMethodAttribs (CORINFO_METHOD_HANDLE ftnHnd, CorInfoMethodRuntimeFlags attribs);
662 CORINFO_METHOD_HANDLE ftnHnd,
663 CORINFO_METHOD_INFO* methInfo);
665 CorInfoInline canInline (
666 CORINFO_METHOD_HANDLE callerHnd,
667 CORINFO_METHOD_HANDLE calleeHnd,
668 DWORD* pRestrictions);
670 void reportInliningDecision (CORINFO_METHOD_HANDLE inlinerHnd,
671 CORINFO_METHOD_HANDLE inlineeHnd,
672 CorInfoInline inlineResult,
673 const char * reason);
676 CORINFO_METHOD_HANDLE instantiateMethodAtObject(CORINFO_METHOD_HANDLE method);
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
686 CorInfoInstantiationVerification isInstantiationOfVerifiedGeneric (
687 CORINFO_METHOD_HANDLE methodHnd);
691 CORINFO_METHOD_HANDLE callerHnd,
692 CORINFO_METHOD_HANDLE declaredCalleeHnd,
693 CORINFO_METHOD_HANDLE exactCalleeHnd,
696 void reportTailCallDecision (CORINFO_METHOD_HANDLE callerHnd,
697 CORINFO_METHOD_HANDLE calleeHnd,
699 CorInfoTailCall tailCallResult,
700 const char * reason);
702 CorInfoCanSkipVerificationResult canSkipMethodVerification(
703 CORINFO_METHOD_HANDLE ftnHnd);
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
709 CORINFO_METHOD_HANDLE ftnHnd,
710 CORINFO_SIG_INFO* sigInfo,
711 CORINFO_CLASS_HANDLE owner = NULL
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
721 CORINFO_METHOD_HANDLE ftn,
723 CORINFO_EH_CLAUSE* clause);
725 CORINFO_CLASS_HANDLE getMethodClass (CORINFO_METHOD_HANDLE methodHnd);
726 CORINFO_MODULE_HANDLE getMethodModule (CORINFO_METHOD_HANDLE methodHnd);
728 void getMethodVTableOffset (
729 CORINFO_METHOD_HANDLE methodHnd,
730 unsigned * pOffsetOfIndirection,
731 unsigned * pOffsetAfterIndirection,
734 CORINFO_METHOD_HANDLE resolveVirtualMethod(
735 CORINFO_METHOD_HANDLE virtualMethod,
736 CORINFO_CLASS_HANDLE implementingClass,
737 CORINFO_CONTEXT_HANDLE ownerType
740 CORINFO_METHOD_HANDLE resolveVirtualMethodHelper(
741 CORINFO_METHOD_HANDLE virtualMethod,
742 CORINFO_CLASS_HANDLE implementingClass,
743 CORINFO_CONTEXT_HANDLE ownerType
746 void expandRawHandleIntrinsic(
747 CORINFO_RESOLVED_TOKEN * pResolvedToken,
748 CORINFO_GENERICHANDLE_RESULT * pResult);
750 CorInfoIntrinsics getIntrinsicID(CORINFO_METHOD_HANDLE method,
751 bool * pMustExpand = NULL);
753 bool isInSIMDModule(CORINFO_CLASS_HANDLE classHnd);
755 CorInfoUnmanagedCallConv getUnmanagedCallConv(CORINFO_METHOD_HANDLE method);
756 BOOL pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig);
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);
763 // Check Visibility rules.
765 // should we enforce the new (for whidbey) restrictions on calling virtual methods?
766 BOOL shouldEnforceCallvirtRestriction(
767 CORINFO_MODULE_HANDLE scope);
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
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);
786 // ICorFieldInfo stuff
787 const char* getFieldName (CORINFO_FIELD_HANDLE field,
788 const char** scopeName);
790 CORINFO_CLASS_HANDLE getFieldClass (CORINFO_FIELD_HANDLE field);
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);
797 unsigned getFieldOffset (CORINFO_FIELD_HANDLE field);
799 bool isWriteBarrierHelperRequired(CORINFO_FIELD_HANDLE field);
801 void* getFieldAddress(CORINFO_FIELD_HANDLE field, void **ppIndirection);
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);
818 CorInfoTypeWithMod getArgType (
819 CORINFO_SIG_INFO* sig,
820 CORINFO_ARG_LIST_HANDLE args,
821 CORINFO_CLASS_HANDLE *vcTypeRet
824 CORINFO_CLASS_HANDLE getArgClass (
825 CORINFO_SIG_INFO* sig,
826 CORINFO_ARG_LIST_HANDLE args
829 CorInfoType getHFAType (
830 CORINFO_CLASS_HANDLE hClass
833 CORINFO_ARG_LIST_HANDLE getArgNext (
834 CORINFO_ARG_LIST_HANDLE args
837 // ICorErrorInfo stuff
839 HRESULT GetErrorHRESULT(struct _EXCEPTION_POINTERS *pExceptionPointers);
840 ULONG GetErrorMessage(__out_ecount(bufferLength) LPWSTR buffer,
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);
847 // ICorStaticInfo stuff
848 void getEEInfo(CORINFO_EE_INFO *pEEInfoOut);
850 LPCWSTR getJitTimeLogFilename();
852 //ICorDynamicInfo stuff
853 DWORD getFieldThreadLocalStoreID (CORINFO_FIELD_HANDLE field, void **ppIndirection);
855 // Stub dispatch stuff
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);
867 static void getEHinfoHelper(
868 CORINFO_METHOD_HANDLE ftnHnd,
870 CORINFO_EH_CLAUSE* clause,
871 COR_ILMETHOD_DECODER* pILHeader);
875 return m_fVerifyOnly;
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);
889 void GetProfilingHandle(
890 BOOL *pbHookFunction,
891 void **pProfilerHandle,
892 BOOL *pbIndirectedHandles
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);
899 DWORD getThreadTLSIndex(void **ppIndirection);
900 const void * getInlinedCallFrameVptr(void **ppIndirection);
902 LONG * getAddrOfCaptureThreadGlobal(void **ppIndirection);
903 void* getHelperFtn(CorInfoHelpFunc ftnNum, /* IN */
904 void ** ppIndirection); /* OUT */
906 void* getTailCallCopyArgsThunk(CORINFO_SIG_INFO *pSig,
907 CorInfoHelperTailCallSpecialHandling flags);
909 void getFunctionEntryPoint(CORINFO_METHOD_HANDLE ftn, /* IN */
910 CORINFO_CONST_LOOKUP * pResult, /* OUT */
911 CORINFO_ACCESS_FLAGS accessFlags = CORINFO_ACCESS_ANY);
913 void getFunctionFixedEntryPoint(CORINFO_METHOD_HANDLE ftn,
914 CORINFO_CONST_LOOKUP * pResult);
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);
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);
929 void embedGenericHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken,
931 CORINFO_GENERICHANDLE_RESULT *pResult);
933 CORINFO_LOOKUP_KIND getLocationOfThisType(CORINFO_METHOD_HANDLE context);
936 void setOverride(ICorDynamicInfo *pOverride, CORINFO_METHOD_HANDLE currentMethod)
938 LIMITED_METHOD_CONTRACT;
939 m_pOverride = pOverride;
940 m_pMethodBeingCompiled = (MethodDesc *)currentMethod; // method being compiled
942 m_hMethodForSecurity_Key = NULL;
943 m_pMethodForSecurity_Value = NULL;
946 // Returns whether we are generating code for NGen image.
947 BOOL IsCompilingForNGen()
949 LIMITED_METHOD_CONTRACT;
950 // NGen is the only place where we set the override
951 return this != m_pOverride;
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);
961 void MethodCompileComplete(
962 CORINFO_METHOD_HANDLE methHnd);
965 // ICorJitInfo stuff - none of this should be called on this class
968 IEEMemoryManager* getMemoryManager();
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 */
981 void reserveUnwindInfo (
982 BOOL isFunclet, /* IN */
983 BOOL isColdCode, /* IN */
984 ULONG unwindSize /* IN */
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 */
1001 void yieldExecution();
1004 unsigned cEH /* IN */
1008 unsigned EHnumber, /* IN */
1009 const CORINFO_EH_CLAUSE *clause /* IN */
1012 BOOL logMsg(unsigned level, const char* fmt, va_list args);
1014 int doAssert(const char* szFile, int iLine, const char* szExpr);
1016 void reportFatalError(CorJitResult result);
1018 void logSQMLongJitEvent(unsigned mcycles, unsigned msec, unsigned ilSize, unsigned numBasicBlocks, bool minOpts,
1019 CORINFO_METHOD_HANDLE methodHnd);
1021 HRESULT allocBBProfileBuffer (
1022 ULONG count, // The number of basic blocks that we have
1023 ProfileBuffer ** profileBuffer
1026 HRESULT getBBProfileData(
1027 CORINFO_METHOD_HANDLE ftnHnd,
1028 ULONG * count, // The number of basic blocks that we have
1029 ProfileBuffer ** profileBuffer,
1033 void recordCallSite(
1034 ULONG instrOffset, /* IN */
1035 CORINFO_SIG_INFO * callSig, /* IN */
1036 CORINFO_METHOD_HANDLE methodHandle /* IN */
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 */
1047 WORD getRelocTypeHint(void * target);
1049 void getModuleNativeEntryPointRange(
1050 void ** pStart, /* OUT */
1051 void ** pEnd /* OUT */
1054 DWORD getExpectedTargetArchitecture();
1056 CEEInfo(MethodDesc * fd = NULL, bool fVerifyOnly = false, bool fAllowInlining = true) :
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),
1066 m_allowInlining(fAllowInlining)
1068 LIMITED_METHOD_CONTRACT;
1073 LIMITED_METHOD_CONTRACT;
1076 // Performs any work JIT-related work that should be performed at process shutdown.
1077 void JitProcessShutdownWork();
1079 void setJitFlags(const CORJIT_FLAGS& jitFlags);
1081 DWORD getJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes);
1083 bool runWithErrorTrap(void (*function)(void*), void* param);
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)
1092 #define CLS_STRING_SIZE MAX_CLASSNAME_LENGTH
1093 #define CLS_BUFFER_SIZE MAX_CLASSNAME_LENGTH
1097 InlineSString<MAX_CLASSNAME_LENGTH> ssClsNameBuff;
1098 ScratchBuffer<MAX_CLASSNAME_LENGTH> ssClsNameBuffScratch;
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
1109 PCCOR_SIGNATURE pSig,
1111 CORINFO_MODULE_HANDLE scopeHnd,
1113 CORINFO_SIG_INFO * sigRet,
1114 MethodDesc * context,
1116 TypeHandle owner = TypeHandle());
1118 MethodDesc * GetMethodForSecurity(CORINFO_METHOD_HANDLE callerHandle);
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);
1128 #if defined(FEATURE_GDBJIT)
1129 CalledMethod * GetCalledMethods() { return m_pCalledMethods; }
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;
1140 MethodDesc* m_pMethodBeingCompiled; // Top-level method being compiled
1142 Thread * m_pThread; // Cached current thread for faster JIT-EE transitions
1143 CORJIT_FLAGS m_jitFlags;
1145 CORINFO_METHOD_HANDLE getMethodBeingCompiled()
1147 LIMITED_METHOD_CONTRACT;
1148 return (CORINFO_METHOD_HANDLE)m_pMethodBeingCompiled;
1151 // Cache of last GetMethodForSecurity() lookup
1152 CORINFO_METHOD_HANDLE m_hMethodForSecurity_Key;
1153 MethodDesc * m_pMethodForSecurity_Value;
1155 #if defined(FEATURE_GDBJIT)
1156 CalledMethod * m_pCalledMethods;
1159 bool m_allowInlining;
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);
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);
1176 /*********************************************************************/
1180 typedef struct _hpCodeHdr CodeHeader;
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
1188 // ICorJitInfo stuff
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 */
1201 void reserveUnwindInfo(BOOL isFunclet, BOOL isColdCode, ULONG unwindSize);
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 */
1213 void * allocGCInfo (size_t size);
1215 void setEHcount (unsigned cEH);
1219 const CORINFO_EH_CLAUSE* clause);
1222 CORINFO_METHOD_HANDLE ftn, /* IN */
1223 unsigned EHnumber, /* IN */
1224 CORINFO_EH_CLAUSE* clause /* OUT */
1228 HRESULT allocBBProfileBuffer (
1229 ULONG count, // The number of basic blocks that we have
1230 ICorJitInfo::ProfileBuffer ** profileBuffer
1233 HRESULT getBBProfileData (
1234 CORINFO_METHOD_HANDLE ftnHnd,
1235 ULONG * count, // The number of basic blocks that we have
1236 ICorJitInfo::ProfileBuffer ** profileBuffer,
1240 void recordCallSite(
1241 ULONG instrOffset, /* IN */
1242 CORINFO_SIG_INFO * callSig, /* IN */
1243 CORINFO_METHOD_HANDLE methodHandle /* IN */
1246 void recordRelocation(
1253 WORD getRelocTypeHint(void * target);
1255 void getModuleNativeEntryPointRange(
1259 DWORD getExpectedTargetArchitecture();
1261 CodeHeader* GetCodeHeader()
1263 LIMITED_METHOD_CONTRACT;
1264 return m_CodeHeader;
1267 void SetCodeHeader(CodeHeader* pValue)
1269 LIMITED_METHOD_CONTRACT;
1270 m_CodeHeader = pValue;
1273 void ResetForJitRetry()
1281 m_CodeHeader = NULL;
1283 if (m_pOffsetMapping != NULL)
1284 delete [] ((BYTE*) m_pOffsetMapping);
1286 if (m_pNativeVarInfo != NULL)
1287 delete [] ((BYTE*) m_pNativeVarInfo);
1289 m_iOffsetMapping = 0;
1290 m_pOffsetMapping = NULL;
1291 m_iNativeVarInfo = 0;
1292 m_pNativeVarInfo = NULL;
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
1304 #ifdef _TARGET_AMD64_
1305 void SetAllowRel32(BOOL fAllowRel32)
1307 LIMITED_METHOD_CONTRACT;
1308 m_fAllowRel32 = fAllowRel32;
1311 void SetRel32Overflow(BOOL fRel32Overflow)
1313 LIMITED_METHOD_CONTRACT;
1314 m_fRel32Overflow = fRel32Overflow;
1317 BOOL IsRel32Overflow()
1319 LIMITED_METHOD_CONTRACT;
1320 return m_fRel32Overflow;
1325 LIMITED_METHOD_CONTRACT;
1326 return m_fRel32Overflow;
1331 LIMITED_METHOD_CONTRACT;
1336 CEEJitInfo(MethodDesc* fd, COR_ILMETHOD_DECODER* header,
1337 EEJitManager* jm, bool fVerifyOnly, bool allowInlining = true)
1338 : CEEInfo(fd, fVerifyOnly, allowInlining),
1342 #ifdef WIN64EXCEPTIONS
1344 m_totalUnwindSize(0),
1345 m_usedUnwindSize(0),
1346 m_theUnwindBlock(NULL),
1347 m_totalUnwindInfos(0),
1348 m_usedUnwindInfos(0),
1350 #ifdef _TARGET_AMD64_
1351 m_fAllowRel32(FALSE),
1352 m_fRel32Overflow(FALSE),
1356 m_iOffsetMapping(0),
1357 m_pOffsetMapping(NULL),
1358 m_iNativeVarInfo(0),
1359 m_pNativeVarInfo(NULL),
1381 if (m_pOffsetMapping != NULL)
1382 delete [] ((BYTE*) m_pOffsetMapping);
1384 if (m_pNativeVarInfo != NULL)
1385 delete [] ((BYTE*) m_pNativeVarInfo);
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();
1395 void* getHelperFtn(CorInfoHelpFunc ftnNum, /* IN */
1396 void ** ppIndirection); /* OUT */
1397 static PCODE getHelperFtnStatic(CorInfoHelpFunc ftnNum);
1399 // Override active dependency to talk to loader
1400 void addActiveDependency(CORINFO_MODULE_HANDLE moduleFrom, CORINFO_MODULE_HANDLE moduleTo);
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
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);
1418 void BackoutJitData(EEJitManager * jitMgr);
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;
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.
1440 ULONG m_codeSize; // Code size requested via allocMem
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()
1446 ULONG32 m_iOffsetMapping;
1447 ICorDebugInfo::OffsetMapping * m_pOffsetMapping;
1449 ULONG32 m_iNativeVarInfo;
1450 ICorDebugInfo::NativeVarInfo * m_pNativeVarInfo;
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
1458 GetProfilingHandleCache() :
1459 m_bGphIsCacheValid(false),
1460 m_bGphHookFunction(false),
1461 m_pvGphProfilerHandle(NULL)
1463 LIMITED_METHOD_CONTRACT;
1466 bool m_bGphIsCacheValid : 1; // Tells us whether below values are valid
1467 bool m_bGphHookFunction : 1;
1468 void* m_pvGphProfilerHandle;
1472 #endif // CROSSGEN_COMPILE
1474 /*********************************************************************/
1475 /*********************************************************************/
1484 #if defined(DACCESS_COMPILE)
1486 GARY_DECL(VMHELPDEF, hlpFuncTable, CORINFO_HELP_COUNT);
1490 extern "C" const VMHELPDEF hlpFuncTable[CORINFO_HELP_COUNT];
1494 #if defined(_DEBUG) && (defined(_TARGET_AMD64_) || defined(_TARGET_X86_)) && !defined(FEATURE_PAL)
1496 void* pfnRealHelper;
1497 const char* helperName;
1502 extern "C" VMHELPCOUNTDEF hlpFuncCountTable[CORINFO_HELP_COUNT+1];
1504 void InitJitHelperLogging();
1505 void WriteJitHelperCountToSTRESSLOG();
1507 inline void InitJitHelperLogging() { }
1508 inline void WriteJitHelperCountToSTRESSLOG() { }
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
1520 // GCC complains about duplicate "extern". And it is not needed for the GCC build
1523 GARY_DECL(VMHELPDEF, hlpDynamicFuncTable, DYNAMIC_CORINFO_HELP_COUNT);
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!
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();
1536 // Helper for RtlVirtualUnwind-based tail calls
1537 #if defined(_TARGET_AMD64_) || defined(_TARGET_ARM_)
1539 // The Stub-linker generated assembly routine to copy arguments from the va_list
1540 // into the CONTEXT and the stack.
1542 typedef size_t (*pfnCopyArgs)(va_list, _CONTEXT *, DWORD_PTR *, size_t);
1544 // Forward declaration from Frames.h
1545 class TailCallFrame;
1547 // The shared stub return location
1548 EXTERN_C void JIT_TailCallHelperStub_ReturnAddress();
1550 #endif // _TARGET_AMD64_ || _TARGET_ARM_
1552 void *GenFastGetSharedStaticBase(bool bCheckCCtor);
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
1562 EXTERN_C FCDECL2(LPVOID, ArrayStoreCheck, Object** pElement, PtrArray** pArray);
1564 OBJECTHANDLE ConstructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok);
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);
1572 BOOL ObjIsInstanceOf(Object *pObject, TypeHandle toTypeHnd, BOOL throwCastException = FALSE);
1573 EXTERN_C TypeHandle::CastResult STDCALL ObjIsInstanceOfNoGC(Object *pObject, TypeHandle toTypeHnd);
1576 class InlinedCallFrame;
1577 Thread * __stdcall JIT_InitPInvokeFrame(InlinedCallFrame *pFrame, PTR_VOID StubSecretArg);
1581 extern LONG g_JitCount;
1584 struct VirtualFunctionPointerArgs
1586 CORINFO_CLASS_HANDLE classHnd;
1587 CORINFO_METHOD_HANDLE methodHnd;
1590 FCDECL2(CORINFO_MethodPtr, JIT_VirtualFunctionPointer_Dynamic, Object * objectUNSAFE, VirtualFunctionPointerArgs * pArgs);
1592 typedef HCCALL2_PTR(TADDR, FnStaticBaseHelper, TADDR arg0, TADDR arg1);
1594 struct StaticFieldAddressArgs
1596 FnStaticBaseHelper staticBaseHelper;
1602 FCDECL1(TADDR, JIT_StaticFieldAddress_Dynamic, StaticFieldAddressArgs * pArgs);
1603 FCDECL1(TADDR, JIT_StaticFieldAddressUnbox_Dynamic, StaticFieldAddressArgs * pArgs);
1605 struct GenericHandleArgs
1608 CORINFO_MODULE_HANDLE module;
1609 DWORD dictionaryIndexAndSlot;
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);
1615 CORINFO_GENERIC_HANDLE JIT_GenericHandleWorker(MethodDesc *pMD,
1618 DWORD dictionaryIndexAndSlot = -1,
1619 Module * pModule = NULL);
1621 void ClearJitGenericHandleCache(AppDomain *pDomain);
1625 static FCDECL3(void, UnsafeSetArrayElement, PtrArray* pPtrArray, INT32 index, Object* object);
1628 CORJIT_FLAGS GetDebuggerCompileFlags(Module* pModule, CORJIT_FLAGS flags);
1630 bool __stdcall TrackAllocationsEnabled();
1632 #endif // JITINTERFACE_H