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 unsigned getMethodHash (CORINFO_METHOD_HANDLE ftnHnd);
654 DWORD getMethodAttribs (CORINFO_METHOD_HANDLE ftnHnd);
655 // Internal version without JIT-EE transition
656 DWORD getMethodAttribsInternal (CORINFO_METHOD_HANDLE ftnHnd);
658 void setMethodAttribs (CORINFO_METHOD_HANDLE ftnHnd, CorInfoMethodRuntimeFlags attribs);
661 CORINFO_METHOD_HANDLE ftnHnd,
662 CORINFO_METHOD_INFO* methInfo);
664 CorInfoInline canInline (
665 CORINFO_METHOD_HANDLE callerHnd,
666 CORINFO_METHOD_HANDLE calleeHnd,
667 DWORD* pRestrictions);
669 void reportInliningDecision (CORINFO_METHOD_HANDLE inlinerHnd,
670 CORINFO_METHOD_HANDLE inlineeHnd,
671 CorInfoInline inlineResult,
672 const char * reason);
675 CORINFO_METHOD_HANDLE instantiateMethodAtObject(CORINFO_METHOD_HANDLE method);
677 // Loads the constraints on a typical method definition, detecting cycles;
678 // used by verifiers.
679 void initConstraintsForVerification(
680 CORINFO_METHOD_HANDLE method,
681 BOOL *pfHasCircularClassConstraints,
682 BOOL *pfHasCircularMethodConstraints
685 CorInfoInstantiationVerification isInstantiationOfVerifiedGeneric (
686 CORINFO_METHOD_HANDLE methodHnd);
690 CORINFO_METHOD_HANDLE callerHnd,
691 CORINFO_METHOD_HANDLE declaredCalleeHnd,
692 CORINFO_METHOD_HANDLE exactCalleeHnd,
695 void reportTailCallDecision (CORINFO_METHOD_HANDLE callerHnd,
696 CORINFO_METHOD_HANDLE calleeHnd,
698 CorInfoTailCall tailCallResult,
699 const char * reason);
701 CorInfoCanSkipVerificationResult canSkipMethodVerification(
702 CORINFO_METHOD_HANDLE ftnHnd);
704 // Given a method descriptor ftnHnd, extract signature information into sigInfo
705 // Obtain (representative) instantiation information from ftnHnd's owner class
706 //@GENERICSVER: added explicit owner parameter
708 CORINFO_METHOD_HANDLE ftnHnd,
709 CORINFO_SIG_INFO* sigInfo,
710 CORINFO_CLASS_HANDLE owner = NULL
712 // Internal version without JIT-EE transition
713 void getMethodSigInternal (
714 CORINFO_METHOD_HANDLE ftnHnd,
715 CORINFO_SIG_INFO* sigInfo,
716 CORINFO_CLASS_HANDLE owner = NULL
720 CORINFO_METHOD_HANDLE ftn,
722 CORINFO_EH_CLAUSE* clause);
724 CORINFO_CLASS_HANDLE getMethodClass (CORINFO_METHOD_HANDLE methodHnd);
725 CORINFO_MODULE_HANDLE getMethodModule (CORINFO_METHOD_HANDLE methodHnd);
727 void getMethodVTableOffset (
728 CORINFO_METHOD_HANDLE methodHnd,
729 unsigned * pOffsetOfIndirection,
730 unsigned * pOffsetAfterIndirection,
733 CORINFO_METHOD_HANDLE resolveVirtualMethod(
734 CORINFO_METHOD_HANDLE virtualMethod,
735 CORINFO_CLASS_HANDLE implementingClass,
736 CORINFO_CONTEXT_HANDLE ownerType
739 CORINFO_METHOD_HANDLE resolveVirtualMethodHelper(
740 CORINFO_METHOD_HANDLE virtualMethod,
741 CORINFO_CLASS_HANDLE implementingClass,
742 CORINFO_CONTEXT_HANDLE ownerType
745 void expandRawHandleIntrinsic(
746 CORINFO_RESOLVED_TOKEN * pResolvedToken,
747 CORINFO_GENERICHANDLE_RESULT * pResult);
749 CorInfoIntrinsics getIntrinsicID(CORINFO_METHOD_HANDLE method,
750 bool * pMustExpand = NULL);
752 bool isInSIMDModule(CORINFO_CLASS_HANDLE classHnd);
754 CorInfoUnmanagedCallConv getUnmanagedCallConv(CORINFO_METHOD_HANDLE method);
755 BOOL pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig);
757 // Generate a cookie based on the signature that would needs to be passed
758 // to the above generic stub
759 LPVOID GetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void ** ppIndirection);
760 bool canGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig);
762 // Check Visibility rules.
764 // should we enforce the new (for whidbey) restrictions on calling virtual methods?
765 BOOL shouldEnforceCallvirtRestriction(
766 CORINFO_MODULE_HANDLE scope);
768 // Check constraints on method type arguments (only).
769 // The parent class should be checked separately using satisfiesClassConstraints(parent).
770 BOOL satisfiesMethodConstraints(
771 CORINFO_CLASS_HANDLE parent, // the exact parent of the method
772 CORINFO_METHOD_HANDLE method
775 // Given a Delegate type and a method, check if the method signature
776 // is Compatible with the Invoke method of the delegate.
777 //@GENERICSVER: new (suitable for generics)
778 BOOL isCompatibleDelegate(
779 CORINFO_CLASS_HANDLE objCls,
780 CORINFO_CLASS_HANDLE methodParentCls,
781 CORINFO_METHOD_HANDLE method,
782 CORINFO_CLASS_HANDLE delegateCls,
783 BOOL* pfIsOpenDelegate);
785 // ICorFieldInfo stuff
786 const char* getFieldName (CORINFO_FIELD_HANDLE field,
787 const char** scopeName);
789 CORINFO_CLASS_HANDLE getFieldClass (CORINFO_FIELD_HANDLE field);
791 //@GENERICSVER: added owner parameter
792 CorInfoType getFieldType (CORINFO_FIELD_HANDLE field, CORINFO_CLASS_HANDLE* structType,CORINFO_CLASS_HANDLE owner = NULL);
793 // Internal version without JIT-EE transition
794 CorInfoType getFieldTypeInternal (CORINFO_FIELD_HANDLE field, CORINFO_CLASS_HANDLE* structType,CORINFO_CLASS_HANDLE owner = NULL);
796 unsigned getFieldOffset (CORINFO_FIELD_HANDLE field);
798 bool isWriteBarrierHelperRequired(CORINFO_FIELD_HANDLE field);
800 void* getFieldAddress(CORINFO_FIELD_HANDLE field, void **ppIndirection);
802 // ICorDebugInfo stuff
803 void * allocateArray(ULONG cBytes);
804 void freeArray(void *array);
805 void getBoundaries(CORINFO_METHOD_HANDLE ftn,
806 unsigned int *cILOffsets, DWORD **pILOffsets,
807 ICorDebugInfo::BoundaryTypes *implictBoundaries);
808 void setBoundaries(CORINFO_METHOD_HANDLE ftn,
809 ULONG32 cMap, ICorDebugInfo::OffsetMapping *pMap);
810 void getVars(CORINFO_METHOD_HANDLE ftn, ULONG32 *cVars,
811 ICorDebugInfo::ILVarInfo **vars, bool *extendOthers);
812 void setVars(CORINFO_METHOD_HANDLE ftn, ULONG32 cVars,
813 ICorDebugInfo::NativeVarInfo *vars);
817 CorInfoTypeWithMod getArgType (
818 CORINFO_SIG_INFO* sig,
819 CORINFO_ARG_LIST_HANDLE args,
820 CORINFO_CLASS_HANDLE *vcTypeRet
823 CORINFO_CLASS_HANDLE getArgClass (
824 CORINFO_SIG_INFO* sig,
825 CORINFO_ARG_LIST_HANDLE args
828 CorInfoType getHFAType (
829 CORINFO_CLASS_HANDLE hClass
832 CORINFO_ARG_LIST_HANDLE getArgNext (
833 CORINFO_ARG_LIST_HANDLE args
836 // ICorErrorInfo stuff
838 HRESULT GetErrorHRESULT(struct _EXCEPTION_POINTERS *pExceptionPointers);
839 ULONG GetErrorMessage(__out_ecount(bufferLength) LPWSTR buffer,
841 int FilterException(struct _EXCEPTION_POINTERS *pExceptionPointers);
842 void HandleException(struct _EXCEPTION_POINTERS *pExceptionPointers);
843 void ThrowExceptionForJitResult(HRESULT result);
844 void ThrowExceptionForHelper(const CORINFO_HELPER_DESC * throwHelper);
846 // ICorStaticInfo stuff
847 void getEEInfo(CORINFO_EE_INFO *pEEInfoOut);
849 LPCWSTR getJitTimeLogFilename();
851 //ICorDynamicInfo stuff
852 DWORD getFieldThreadLocalStoreID (CORINFO_FIELD_HANDLE field, void **ppIndirection);
854 // Stub dispatch stuff
856 CORINFO_RESOLVED_TOKEN * pResolvedToken,
857 CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken,
858 CORINFO_METHOD_HANDLE callerHandle,
859 CORINFO_CALLINFO_FLAGS flags,
860 CORINFO_CALL_INFO *pResult /*out */);
861 BOOL canAccessFamily(CORINFO_METHOD_HANDLE hCaller,
862 CORINFO_CLASS_HANDLE hInstanceType);
866 static void getEHinfoHelper(
867 CORINFO_METHOD_HANDLE ftnHnd,
869 CORINFO_EH_CLAUSE* clause,
870 COR_ILMETHOD_DECODER* pILHeader);
874 return m_fVerifyOnly;
879 BOOL isRIDClassDomainID(CORINFO_CLASS_HANDLE cls);
880 unsigned getClassDomainID (CORINFO_CLASS_HANDLE cls, void **ppIndirection);
881 CORINFO_VARARGS_HANDLE getVarArgsHandle(CORINFO_SIG_INFO *sig, void **ppIndirection);
882 bool canGetVarArgsHandle(CORINFO_SIG_INFO *sig);
883 void* getPInvokeUnmanagedTarget(CORINFO_METHOD_HANDLE method, void **ppIndirection);
884 void* getAddressOfPInvokeFixup(CORINFO_METHOD_HANDLE method, void **ppIndirection);
885 void getAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP *pLookup);
886 CORINFO_JUST_MY_CODE_HANDLE getJustMyCodeHandle(CORINFO_METHOD_HANDLE method, CORINFO_JUST_MY_CODE_HANDLE **ppIndirection);
888 void GetProfilingHandle(
889 BOOL *pbHookFunction,
890 void **pProfilerHandle,
891 BOOL *pbIndirectedHandles
894 InfoAccessType constructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok, void **ppValue);
895 InfoAccessType emptyStringLiteral(void ** ppValue);
896 void* getMethodSync(CORINFO_METHOD_HANDLE ftnHnd, void **ppIndirection);
898 DWORD getThreadTLSIndex(void **ppIndirection);
899 const void * getInlinedCallFrameVptr(void **ppIndirection);
901 LONG * getAddrOfCaptureThreadGlobal(void **ppIndirection);
902 void* getHelperFtn(CorInfoHelpFunc ftnNum, /* IN */
903 void ** ppIndirection); /* OUT */
905 void* getTailCallCopyArgsThunk(CORINFO_SIG_INFO *pSig,
906 CorInfoHelperTailCallSpecialHandling flags);
908 void getFunctionEntryPoint(CORINFO_METHOD_HANDLE ftn, /* IN */
909 CORINFO_CONST_LOOKUP * pResult, /* OUT */
910 CORINFO_ACCESS_FLAGS accessFlags = CORINFO_ACCESS_ANY);
912 void getFunctionFixedEntryPoint(CORINFO_METHOD_HANDLE ftn,
913 CORINFO_CONST_LOOKUP * pResult);
915 // get slow lazy string literal helper to use (CORINFO_HELP_STRCNS*).
916 // Returns CORINFO_HELP_UNDEF if lazy string literal helper cannot be used.
917 CorInfoHelpFunc getLazyStringLiteralHelper(CORINFO_MODULE_HANDLE handle);
919 CORINFO_MODULE_HANDLE embedModuleHandle(CORINFO_MODULE_HANDLE handle,
920 void **ppIndirection);
921 CORINFO_CLASS_HANDLE embedClassHandle(CORINFO_CLASS_HANDLE handle,
922 void **ppIndirection);
923 CORINFO_FIELD_HANDLE embedFieldHandle(CORINFO_FIELD_HANDLE handle,
924 void **ppIndirection);
925 CORINFO_METHOD_HANDLE embedMethodHandle(CORINFO_METHOD_HANDLE handle,
926 void **ppIndirection);
928 void embedGenericHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken,
930 CORINFO_GENERICHANDLE_RESULT *pResult);
932 CORINFO_LOOKUP_KIND getLocationOfThisType(CORINFO_METHOD_HANDLE context);
935 void setOverride(ICorDynamicInfo *pOverride, CORINFO_METHOD_HANDLE currentMethod)
937 LIMITED_METHOD_CONTRACT;
938 m_pOverride = pOverride;
939 m_pMethodBeingCompiled = (MethodDesc *)currentMethod; // method being compiled
941 m_hMethodForSecurity_Key = NULL;
942 m_pMethodForSecurity_Value = NULL;
945 // Returns whether we are generating code for NGen image.
946 BOOL IsCompilingForNGen()
948 LIMITED_METHOD_CONTRACT;
949 // NGen is the only place where we set the override
950 return this != m_pOverride;
953 void addActiveDependency(CORINFO_MODULE_HANDLE moduleFrom, CORINFO_MODULE_HANDLE moduleTo);
954 CORINFO_METHOD_HANDLE GetDelegateCtor(
955 CORINFO_METHOD_HANDLE methHnd,
956 CORINFO_CLASS_HANDLE clsHnd,
957 CORINFO_METHOD_HANDLE targetMethodHnd,
958 DelegateCtorArgs * pCtorData);
960 void MethodCompileComplete(
961 CORINFO_METHOD_HANDLE methHnd);
964 // ICorJitInfo stuff - none of this should be called on this class
967 IEEMemoryManager* getMemoryManager();
970 ULONG hotCodeSize, /* IN */
971 ULONG coldCodeSize, /* IN */
972 ULONG roDataSize, /* IN */
973 ULONG xcptnsCount, /* IN */
974 CorJitAllocMemFlag flag, /* IN */
975 void ** hotCodeBlock, /* OUT */
976 void ** coldCodeBlock, /* OUT */
977 void ** roDataBlock /* OUT */
980 void reserveUnwindInfo (
981 BOOL isFunclet, /* IN */
982 BOOL isColdCode, /* IN */
983 ULONG unwindSize /* IN */
986 void allocUnwindInfo (
987 BYTE * pHotCode, /* IN */
988 BYTE * pColdCode, /* IN */
989 ULONG startOffset, /* IN */
990 ULONG endOffset, /* IN */
991 ULONG unwindSize, /* IN */
992 BYTE * pUnwindBlock, /* IN */
993 CorJitFuncKind funcKind /* IN */
1000 void yieldExecution();
1003 unsigned cEH /* IN */
1007 unsigned EHnumber, /* IN */
1008 const CORINFO_EH_CLAUSE *clause /* IN */
1011 BOOL logMsg(unsigned level, const char* fmt, va_list args);
1013 int doAssert(const char* szFile, int iLine, const char* szExpr);
1015 void reportFatalError(CorJitResult result);
1017 void logSQMLongJitEvent(unsigned mcycles, unsigned msec, unsigned ilSize, unsigned numBasicBlocks, bool minOpts,
1018 CORINFO_METHOD_HANDLE methodHnd);
1020 HRESULT allocBBProfileBuffer (
1021 ULONG count, // The number of basic blocks that we have
1022 ProfileBuffer ** profileBuffer
1025 HRESULT getBBProfileData(
1026 CORINFO_METHOD_HANDLE ftnHnd,
1027 ULONG * count, // The number of basic blocks that we have
1028 ProfileBuffer ** profileBuffer,
1032 void recordCallSite(
1033 ULONG instrOffset, /* IN */
1034 CORINFO_SIG_INFO * callSig, /* IN */
1035 CORINFO_METHOD_HANDLE methodHandle /* IN */
1038 void recordRelocation(
1039 void * location, /* IN */
1040 void * target, /* IN */
1041 WORD fRelocType, /* IN */
1042 WORD slotNum = 0, /* IN */
1043 INT32 addlDelta = 0 /* IN */
1046 WORD getRelocTypeHint(void * target);
1048 void getModuleNativeEntryPointRange(
1049 void ** pStart, /* OUT */
1050 void ** pEnd /* OUT */
1053 DWORD getExpectedTargetArchitecture();
1055 CEEInfo(MethodDesc * fd = NULL, bool fVerifyOnly = false, bool fAllowInlining = true) :
1057 m_pMethodBeingCompiled(fd),
1058 m_fVerifyOnly(fVerifyOnly),
1059 m_pThread(GetThread()),
1060 m_hMethodForSecurity_Key(NULL),
1061 m_pMethodForSecurity_Value(NULL),
1062 #if defined(FEATURE_GDBJIT)
1063 m_pCalledMethods(NULL),
1065 m_allowInlining(fAllowInlining)
1067 LIMITED_METHOD_CONTRACT;
1072 LIMITED_METHOD_CONTRACT;
1075 // Performs any work JIT-related work that should be performed at process shutdown.
1076 void JitProcessShutdownWork();
1078 void setJitFlags(const CORJIT_FLAGS& jitFlags);
1080 DWORD getJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes);
1082 bool runWithErrorTrap(void (*function)(void*), void* param);
1085 // Shrinking these buffers drastically reduces the amount of stack space
1086 // required for each instance of the interpreter, and thereby reduces SOs.
1087 #ifdef FEATURE_INTERPRETER
1088 #define CLS_STRING_SIZE 8 // force heap allocation
1089 #define CLS_BUFFER_SIZE SBUFFER_PADDED_SIZE(8)
1091 #define CLS_STRING_SIZE MAX_CLASSNAME_LENGTH
1092 #define CLS_BUFFER_SIZE MAX_CLASSNAME_LENGTH
1096 InlineSString<MAX_CLASSNAME_LENGTH> ssClsNameBuff;
1097 ScratchBuffer<MAX_CLASSNAME_LENGTH> ssClsNameBuffScratch;
1103 // The method handle is used to instantiate method and class type parameters
1104 // It's also used to determine whether an extra dictionary parameter is required
1108 PCCOR_SIGNATURE pSig,
1110 CORINFO_MODULE_HANDLE scopeHnd,
1112 CORINFO_SIG_INFO * sigRet,
1113 MethodDesc * context,
1115 TypeHandle owner = TypeHandle());
1117 MethodDesc * GetMethodForSecurity(CORINFO_METHOD_HANDLE callerHandle);
1119 // Prepare the information about how to do a runtime lookup of the handle with shared
1120 // generic variables.
1121 void ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entryKind,
1122 CORINFO_RESOLVED_TOKEN * pResolvedToken,
1123 CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken /* for ConstrainedMethodEntrySlot */,
1124 MethodDesc * pTemplateMD /* for method-based slots */,
1125 CORINFO_LOOKUP *pResultLookup);
1127 #if defined(FEATURE_GDBJIT)
1128 CalledMethod * GetCalledMethods() { return m_pCalledMethods; }
1132 // NGen provides its own modifications to EE-JIT interface. From technical reason it cannot simply inherit
1133 // from code:CEEInfo class (because it has dependencies on VM that NGen does not want).
1134 // Therefore the "normal" EE-JIT interface has code:m_pOverride hook that is set either to
1135 // * 'this' (code:CEEInfo) at runtime, or to
1136 // * code:ZapInfo - the NGen specific implementation of the interface.
1137 ICorDynamicInfo * m_pOverride;
1139 MethodDesc* m_pMethodBeingCompiled; // Top-level method being compiled
1141 Thread * m_pThread; // Cached current thread for faster JIT-EE transitions
1142 CORJIT_FLAGS m_jitFlags;
1144 CORINFO_METHOD_HANDLE getMethodBeingCompiled()
1146 LIMITED_METHOD_CONTRACT;
1147 return (CORINFO_METHOD_HANDLE)m_pMethodBeingCompiled;
1150 // Cache of last GetMethodForSecurity() lookup
1151 CORINFO_METHOD_HANDLE m_hMethodForSecurity_Key;
1152 MethodDesc * m_pMethodForSecurity_Value;
1154 #if defined(FEATURE_GDBJIT)
1155 CalledMethod * m_pCalledMethods;
1158 bool m_allowInlining;
1160 // Tracking of module activation dependencies. We have two flavors:
1161 // - Fast one that gathers generic arguments from EE handles, but does not work inside generic context.
1162 // - Slow one that operates on typespec and methodspecs from metadata.
1163 void ScanForModuleDependencies(Module* pModule, SigPointer psig);
1164 void ScanMethodSpec(Module * pModule, PCCOR_SIGNATURE pMethodSpec, ULONG cbMethodSpec);
1165 // Returns true if it is ok to proceed with scan of parent chain
1166 BOOL ScanTypeSpec(Module * pModule, PCCOR_SIGNATURE pTypeSpec, ULONG cbTypeSpec);
1167 void ScanInstantiation(Module * pModule, Instantiation inst);
1169 // The main entrypoints for module activation tracking
1170 void ScanToken(Module * pModule, CORINFO_RESOLVED_TOKEN * pResolvedToken, TypeHandle th, MethodDesc * pMD = NULL);
1171 void ScanTokenForDynamicScope(CORINFO_RESOLVED_TOKEN * pResolvedToken, TypeHandle th, MethodDesc * pMD = NULL);
1175 /*********************************************************************/
1179 typedef struct _hpCodeHdr CodeHeader;
1181 #ifndef CROSSGEN_COMPILE
1182 // CEEJitInfo is the concrete implementation of callbacks that the EE must provide for the JIT to do its
1183 // work. See code:ICorJitInfo#JitToEEInterface for more on this interface.
1184 class CEEJitInfo : public CEEInfo
1187 // ICorJitInfo stuff
1190 ULONG hotCodeSize, /* IN */
1191 ULONG coldCodeSize, /* IN */
1192 ULONG roDataSize, /* IN */
1193 ULONG xcptnsCount, /* IN */
1194 CorJitAllocMemFlag flag, /* IN */
1195 void ** hotCodeBlock, /* OUT */
1196 void ** coldCodeBlock, /* OUT */
1197 void ** roDataBlock /* OUT */
1200 void reserveUnwindInfo(BOOL isFunclet, BOOL isColdCode, ULONG unwindSize);
1202 void allocUnwindInfo (
1203 BYTE * pHotCode, /* IN */
1204 BYTE * pColdCode, /* IN */
1205 ULONG startOffset, /* IN */
1206 ULONG endOffset, /* IN */
1207 ULONG unwindSize, /* IN */
1208 BYTE * pUnwindBlock, /* IN */
1209 CorJitFuncKind funcKind /* IN */
1212 void * allocGCInfo (size_t size);
1214 void setEHcount (unsigned cEH);
1218 const CORINFO_EH_CLAUSE* clause);
1221 CORINFO_METHOD_HANDLE ftn, /* IN */
1222 unsigned EHnumber, /* IN */
1223 CORINFO_EH_CLAUSE* clause /* OUT */
1227 HRESULT allocBBProfileBuffer (
1228 ULONG count, // The number of basic blocks that we have
1229 ICorJitInfo::ProfileBuffer ** profileBuffer
1232 HRESULT getBBProfileData (
1233 CORINFO_METHOD_HANDLE ftnHnd,
1234 ULONG * count, // The number of basic blocks that we have
1235 ICorJitInfo::ProfileBuffer ** profileBuffer,
1239 void recordCallSite(
1240 ULONG instrOffset, /* IN */
1241 CORINFO_SIG_INFO * callSig, /* IN */
1242 CORINFO_METHOD_HANDLE methodHandle /* IN */
1245 void recordRelocation(
1252 WORD getRelocTypeHint(void * target);
1254 void getModuleNativeEntryPointRange(
1258 DWORD getExpectedTargetArchitecture();
1260 CodeHeader* GetCodeHeader()
1262 LIMITED_METHOD_CONTRACT;
1263 return m_CodeHeader;
1266 void SetCodeHeader(CodeHeader* pValue)
1268 LIMITED_METHOD_CONTRACT;
1269 m_CodeHeader = pValue;
1272 void ResetForJitRetry()
1280 m_CodeHeader = NULL;
1282 if (m_pOffsetMapping != NULL)
1283 delete [] ((BYTE*) m_pOffsetMapping);
1285 if (m_pNativeVarInfo != NULL)
1286 delete [] ((BYTE*) m_pNativeVarInfo);
1288 m_iOffsetMapping = 0;
1289 m_pOffsetMapping = NULL;
1290 m_iNativeVarInfo = 0;
1291 m_pNativeVarInfo = NULL;
1293 #ifdef WIN64EXCEPTIONS
1294 m_moduleBase = NULL;
1295 m_totalUnwindSize = 0;
1296 m_usedUnwindSize = 0;
1297 m_theUnwindBlock = NULL;
1298 m_totalUnwindInfos = 0;
1299 m_usedUnwindInfos = 0;
1300 #endif // WIN64EXCEPTIONS
1303 #ifdef _TARGET_AMD64_
1304 void SetAllowRel32(BOOL fAllowRel32)
1306 LIMITED_METHOD_CONTRACT;
1307 m_fAllowRel32 = fAllowRel32;
1310 void SetRel32Overflow(BOOL fRel32Overflow)
1312 LIMITED_METHOD_CONTRACT;
1313 m_fRel32Overflow = fRel32Overflow;
1316 BOOL IsRel32Overflow()
1318 LIMITED_METHOD_CONTRACT;
1319 return m_fRel32Overflow;
1324 LIMITED_METHOD_CONTRACT;
1325 return m_fRel32Overflow;
1330 LIMITED_METHOD_CONTRACT;
1335 CEEJitInfo(MethodDesc* fd, COR_ILMETHOD_DECODER* header,
1336 EEJitManager* jm, bool fVerifyOnly, bool allowInlining = true)
1337 : CEEInfo(fd, fVerifyOnly, allowInlining),
1341 #ifdef WIN64EXCEPTIONS
1343 m_totalUnwindSize(0),
1344 m_usedUnwindSize(0),
1345 m_theUnwindBlock(NULL),
1346 m_totalUnwindInfos(0),
1347 m_usedUnwindInfos(0),
1349 #ifdef _TARGET_AMD64_
1350 m_fAllowRel32(FALSE),
1351 m_fRel32Overflow(FALSE),
1355 m_iOffsetMapping(0),
1356 m_pOffsetMapping(NULL),
1357 m_iNativeVarInfo(0),
1358 m_pNativeVarInfo(NULL),
1380 if (m_pOffsetMapping != NULL)
1381 delete [] ((BYTE*) m_pOffsetMapping);
1383 if (m_pNativeVarInfo != NULL)
1384 delete [] ((BYTE*) m_pNativeVarInfo);
1387 // ICorDebugInfo stuff.
1388 void setBoundaries(CORINFO_METHOD_HANDLE ftn,
1389 ULONG32 cMap, ICorDebugInfo::OffsetMapping *pMap);
1390 void setVars(CORINFO_METHOD_HANDLE ftn, ULONG32 cVars,
1391 ICorDebugInfo::NativeVarInfo *vars);
1392 void CompressDebugInfo();
1394 void* getHelperFtn(CorInfoHelpFunc ftnNum, /* IN */
1395 void ** ppIndirection); /* OUT */
1396 static PCODE getHelperFtnStatic(CorInfoHelpFunc ftnNum);
1398 // Override active dependency to talk to loader
1399 void addActiveDependency(CORINFO_MODULE_HANDLE moduleFrom, CORINFO_MODULE_HANDLE moduleTo);
1401 // Override of CEEInfo::GetProfilingHandle. The first time this is called for a
1402 // method desc, it calls through to CEEInfo::GetProfilingHandle and caches the
1403 // result in CEEJitInfo::GetProfilingHandleCache. Thereafter, this wrapper regurgitates the cached values
1404 // rather than calling into CEEInfo::GetProfilingHandle each time. This avoids
1405 // making duplicate calls into the profiler's FunctionIDMapper callback.
1406 void GetProfilingHandle(
1407 BOOL *pbHookFunction,
1408 void **pProfilerHandle,
1409 BOOL *pbIndirectedHandles
1412 InfoAccessType constructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok, void **ppValue);
1413 InfoAccessType emptyStringLiteral(void ** ppValue);
1414 void* getFieldAddress(CORINFO_FIELD_HANDLE field, void **ppIndirection);
1415 void* getMethodSync(CORINFO_METHOD_HANDLE ftnHnd, void **ppIndirection);
1417 void BackoutJitData(EEJitManager * jitMgr);
1420 EEJitManager* m_jitManager; // responsible for allocating memory
1421 CodeHeader* m_CodeHeader; // descriptor for JITTED code
1422 COR_ILMETHOD_DECODER * m_ILHeader; // the code header as exist in the file
1423 #ifdef WIN64EXCEPTIONS
1424 TADDR m_moduleBase; // Base for unwind Infos
1425 ULONG m_totalUnwindSize; // Total reserved unwind space
1426 ULONG m_usedUnwindSize; // used space in m_theUnwindBlock
1427 BYTE * m_theUnwindBlock; // start of the unwind memory block
1428 ULONG m_totalUnwindInfos; // Number of RUNTIME_FUNCTION needed
1429 ULONG m_usedUnwindInfos;
1432 #ifdef _TARGET_AMD64_
1433 BOOL m_fAllowRel32; // Use 32-bit PC relative address modes
1434 BOOL m_fRel32Overflow; // Overflow while trying to use encode 32-bit PC relative address.
1435 // The code will need to be regenerated with m_fRel32Allowed == FALSE.
1439 ULONG m_codeSize; // Code size requested via allocMem
1442 size_t m_GCinfo_len; // Cached copy of GCinfo_len so we can backout in BackoutJitData()
1443 size_t m_EHinfo_len; // Cached copy of EHinfo_len so we can backout in BackoutJitData()
1445 ULONG32 m_iOffsetMapping;
1446 ICorDebugInfo::OffsetMapping * m_pOffsetMapping;
1448 ULONG32 m_iNativeVarInfo;
1449 ICorDebugInfo::NativeVarInfo * m_pNativeVarInfo;
1451 // The first time a call is made to CEEJitInfo::GetProfilingHandle() from this thread
1452 // for this method, these values are filled in. Thereafter, these values are used
1453 // in lieu of calling into the base CEEInfo::GetProfilingHandle() again. This protects the
1454 // profiler from duplicate calls to its FunctionIDMapper() callback.
1455 struct GetProfilingHandleCache
1457 GetProfilingHandleCache() :
1458 m_bGphIsCacheValid(false),
1459 m_bGphHookFunction(false),
1460 m_pvGphProfilerHandle(NULL)
1462 LIMITED_METHOD_CONTRACT;
1465 bool m_bGphIsCacheValid : 1; // Tells us whether below values are valid
1466 bool m_bGphHookFunction : 1;
1467 void* m_pvGphProfilerHandle;
1471 #endif // CROSSGEN_COMPILE
1473 /*********************************************************************/
1474 /*********************************************************************/
1483 #if defined(DACCESS_COMPILE)
1485 GARY_DECL(VMHELPDEF, hlpFuncTable, CORINFO_HELP_COUNT);
1489 extern "C" const VMHELPDEF hlpFuncTable[CORINFO_HELP_COUNT];
1493 #if defined(_DEBUG) && (defined(_TARGET_AMD64_) || defined(_TARGET_X86_)) && !defined(FEATURE_PAL)
1495 void* pfnRealHelper;
1496 const char* helperName;
1501 extern "C" VMHELPCOUNTDEF hlpFuncCountTable[CORINFO_HELP_COUNT+1];
1503 void InitJitHelperLogging();
1504 void WriteJitHelperCountToSTRESSLOG();
1506 inline void InitJitHelperLogging() { }
1507 inline void WriteJitHelperCountToSTRESSLOG() { }
1510 // enum for dynamically assigned helper calls
1511 enum DynamicCorInfoHelpFunc {
1512 #define JITHELPER(code, pfnHelper, sig)
1513 #define DYNAMICJITHELPER(code, pfnHelper, sig) DYNAMIC_##code,
1514 #include "jithelpers.h"
1515 DYNAMIC_CORINFO_HELP_COUNT
1519 // GCC complains about duplicate "extern". And it is not needed for the GCC build
1522 GARY_DECL(VMHELPDEF, hlpDynamicFuncTable, DYNAMIC_CORINFO_HELP_COUNT);
1524 #define SetJitHelperFunction(ftnNum, pFunc) _SetJitHelperFunction(DYNAMIC_##ftnNum, (void*)(pFunc))
1525 void _SetJitHelperFunction(DynamicCorInfoHelpFunc ftnNum, void * pFunc);
1526 #ifdef ENABLE_FAST_GCPOLL_HELPER
1527 //These should only be called from ThreadStore::TrapReturningThreads!
1529 //Called when the VM wants to suspend one or more threads.
1530 void EnableJitGCPoll();
1531 //Called when there are no threads to suspend.
1532 void DisableJitGCPoll();
1535 // Helper for RtlVirtualUnwind-based tail calls
1536 #if defined(_TARGET_AMD64_) || defined(_TARGET_ARM_)
1538 // The Stub-linker generated assembly routine to copy arguments from the va_list
1539 // into the CONTEXT and the stack.
1541 typedef size_t (*pfnCopyArgs)(va_list, _CONTEXT *, DWORD_PTR *, size_t);
1543 // Forward declaration from Frames.h
1544 class TailCallFrame;
1546 // The shared stub return location
1547 EXTERN_C void JIT_TailCallHelperStub_ReturnAddress();
1549 #endif // _TARGET_AMD64_ || _TARGET_ARM_
1551 void *GenFastGetSharedStaticBase(bool bCheckCCtor);
1554 void SetupGcCoverage(MethodDesc* pMD, BYTE* nativeCode);
1555 void SetupGcCoverageForNativeImage(Module* module);
1556 bool IsGcCoverageInterrupt(LPVOID ip);
1557 BOOL OnGcCoverageInterrupt(PT_CONTEXT regs);
1558 void DoGcStress (PT_CONTEXT regs, MethodDesc *pMD);
1559 #endif //HAVE_GCCOVER
1561 EXTERN_C FCDECL2(LPVOID, ArrayStoreCheck, Object** pElement, PtrArray** pArray);
1563 OBJECTHANDLE ConstructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok);
1565 FCDECL2(Object*, JIT_Box, CORINFO_CLASS_HANDLE type, void* data);
1566 FCDECL0(VOID, JIT_PollGC);
1567 #ifdef ENABLE_FAST_GCPOLL_HELPER
1568 EXTERN_C FCDECL0(VOID, JIT_PollGC_Nop);
1571 BOOL ObjIsInstanceOf(Object *pObject, TypeHandle toTypeHnd, BOOL throwCastException = FALSE);
1572 EXTERN_C TypeHandle::CastResult STDCALL ObjIsInstanceOfNoGC(Object *pObject, TypeHandle toTypeHnd);
1575 class InlinedCallFrame;
1576 Thread * __stdcall JIT_InitPInvokeFrame(InlinedCallFrame *pFrame, PTR_VOID StubSecretArg);
1580 extern LONG g_JitCount;
1583 struct VirtualFunctionPointerArgs
1585 CORINFO_CLASS_HANDLE classHnd;
1586 CORINFO_METHOD_HANDLE methodHnd;
1589 FCDECL2(CORINFO_MethodPtr, JIT_VirtualFunctionPointer_Dynamic, Object * objectUNSAFE, VirtualFunctionPointerArgs * pArgs);
1591 typedef HCCALL2_PTR(TADDR, FnStaticBaseHelper, TADDR arg0, TADDR arg1);
1593 struct StaticFieldAddressArgs
1595 FnStaticBaseHelper staticBaseHelper;
1601 FCDECL1(TADDR, JIT_StaticFieldAddress_Dynamic, StaticFieldAddressArgs * pArgs);
1602 FCDECL1(TADDR, JIT_StaticFieldAddressUnbox_Dynamic, StaticFieldAddressArgs * pArgs);
1604 struct GenericHandleArgs
1607 CORINFO_MODULE_HANDLE module;
1608 DWORD dictionaryIndexAndSlot;
1611 FCDECL2(CORINFO_GENERIC_HANDLE, JIT_GenericHandleMethodWithSlotAndModule, CORINFO_METHOD_HANDLE methodHnd, GenericHandleArgs * pArgs);
1612 FCDECL2(CORINFO_GENERIC_HANDLE, JIT_GenericHandleClassWithSlotAndModule, CORINFO_CLASS_HANDLE classHnd, GenericHandleArgs * pArgs);
1614 CORINFO_GENERIC_HANDLE JIT_GenericHandleWorker(MethodDesc *pMD,
1617 DWORD dictionaryIndexAndSlot = -1,
1618 Module * pModule = NULL);
1620 void ClearJitGenericHandleCache(AppDomain *pDomain);
1624 static FCDECL3(void, UnsafeSetArrayElement, PtrArray* pPtrArray, INT32 index, Object* object);
1627 CORJIT_FLAGS GetDebuggerCompileFlags(Module* pModule, CORJIT_FLAGS flags);
1629 bool __stdcall TrackAllocationsEnabled();
1631 #endif // JITINTERFACE_H