diff options
author | Pat Gavlin <pagavlin@microsoft.com> | 2016-05-19 19:05:53 -0700 |
---|---|---|
committer | Pat Gavlin <pagavlin@microsoft.com> | 2016-05-19 19:05:53 -0700 |
commit | aa752704910dd2322be7733f0f648e3733522f42 (patch) | |
tree | 3d98bc47c3111d6d5be6bb4b629560c5129f40d5 /src | |
parent | c61b67485a363ee38e9882cc25d3a83f5239db49 (diff) | |
download | coreclr-aa752704910dd2322be7733f0f648e3733522f42.tar.gz coreclr-aa752704910dd2322be7733f0f648e3733522f42.tar.bz2 coreclr-aa752704910dd2322be7733f0f648e3733522f42.zip |
Add some quirk and versioning flags and change some preprocessor symbols into fields of CORINFO_EE_INFO.
The quirk flags--CORJIT_FLG2_JIT32_QUIRKS and CORJIT_FLG2_JIT64_QUIRKS--are passed by the EE to request that the JIT
generate appropriately compatible executable code. These flags are only passed on x86/Windows and x64/Desktop/Windows,
respectively.
Version numbers for GC and EH info have been added to CORINFO_EE_INFO. The EE sets these versions to indicate the
formats of the aforementioned data that it supports.
CORINFO_PAGE_SIZE and MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT have been converted to fields on CORINFO_EE_INFO.
[tfs-changeset: 1606533]
Diffstat (limited to 'src')
-rw-r--r-- | src/inc/corinfo.h | 36 | ||||
-rw-r--r-- | src/inc/corjit.h | 6 | ||||
-rw-r--r-- | src/jit/compiler.cpp | 11 | ||||
-rw-r--r-- | src/jit/compiler.h | 35 | ||||
-rw-r--r-- | src/jit/unwindamd64.cpp | 18 | ||||
-rw-r--r-- | src/vm/jitinterface.cpp | 59 | ||||
-rw-r--r-- | src/vm/jitinterface.h | 3359 | ||||
-rw-r--r-- | src/zap/zapinfo.cpp | 292 | ||||
-rw-r--r-- | src/zap/zapinfo.h | 2 |
9 files changed, 1958 insertions, 1860 deletions
diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h index 6ea69bbe87..59b5b0773f 100644 --- a/src/inc/corinfo.h +++ b/src/inc/corinfo.h @@ -231,11 +231,11 @@ TODO: Talk about initializing strutures before use #if COR_JIT_EE_VERSION > 460 // Update this one -SELECTANY const GUID JITEEVersionIdentifier = { /* 7a6aa61a-78b1-4dfb-9e06-655fb4774d7f */ - 0x7a6aa61a, - 0x78b1, - 0x4dfb, - { 0x9e, 0x6, 0x65, 0x5f, 0xb4, 0x77, 0x4d, 0x7f } +SELECTANY const GUID JITEEVersionIdentifier = { /* c635d9d7-ab32-4393-8a86-a69e0ee4beae */ + 0xc635d9d7, + 0xab32, + 0x4393, + { 0x8a, 0x86, 0xa6, 0x9e, 0x0e, 0xe4, 0xbe, 0xae } }; #else @@ -1776,6 +1776,13 @@ struct CORINFO_CPU DWORD dwExtendedFeatures; }; +enum CORINFO_RUNTIME_ABI +{ + CORINFO_DESKTOP_ABI = 0x100, + CORINFO_CORECLR_ABI = 0x200, + CORINFO_CORERT_ABI = 0x300, +}; + // For some highly optimized paths, the JIT must generate code that directly // manipulates internal EE data structures. The getEEInfo() helper returns // this structure containing the needed offsets and values. @@ -1815,6 +1822,16 @@ struct CORINFO_EE_INFO #if COR_JIT_EE_VERSION > 460 // Reverse PInvoke offsets unsigned sizeOfReversePInvokeFrame; + + // OS Page size + size_t osPageSize; + + // Null object offset + size_t maxUncheckedOffsetForNullObject; + + // Target ABI. Combined with target architecture and OS to determine + // GC, EH, and unwind styles. + CORINFO_RUNTIME_ABI targetAbi; #endif CORINFO_OS osType; @@ -1831,11 +1848,10 @@ enum { LCL_FINALLY_MARK = 0xFC }; // FC = "Finally Call" * The following is the internal structure of an object that the compiler knows about * when it generates code **********************************************************************************/ -#include <pshpack4.h> -#define CORINFO_PAGE_SIZE 0x1000 // the page size on the machine +#if COR_JIT_EE_VERSION <= 460 -// <TODO>@TODO: put this in the CORINFO_EE_INFO data structure</TODO> +#define CORINFO_PAGE_SIZE 0x1000 // the page size on the machine #ifndef FEATURE_PAL #define MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT ((32*1024)-1) // when generating JIT code @@ -1843,6 +1859,10 @@ enum { LCL_FINALLY_MARK = 0xFC }; // FC = "Finally Call" #define MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT ((OS_PAGE_SIZE / 2) - 1) #endif // !FEATURE_PAL +#endif // COR_JIT_EE_VERISION <= 460 + +#include <pshpack4.h> + typedef void* CORINFO_MethodPtr; // a generic method pointer struct CORINFO_Object diff --git a/src/inc/corjit.h b/src/inc/corjit.h index 8481d9acda..a091bdb95b 100644 --- a/src/inc/corjit.h +++ b/src/inc/corjit.h @@ -114,7 +114,6 @@ enum CorJitFlag #endif // !defined(_TARGET_X86_) && !defined(_TARGET_AMD64_) - CORJIT_FLG_CFI_UNWIND = 0x00004000, // Emit CFI unwind info CORJIT_FLG_MAKEFINALCODE = 0x00008000, // Use the final code generator, i.e., not the interpreter. CORJIT_FLG_READYTORUN = 0x00010000, // Use version-resilient code generation @@ -147,13 +146,14 @@ enum CorJitFlag2 #if COR_JIT_EE_VERSION > 460 CORJIT_FLG2_USE_PINVOKE_HELPERS = 0x00000002, // The JIT should use the PINVOKE_{BEGIN,END} helpers instead of emitting inline transitions CORJIT_FLG2_REVERSE_PINVOKE = 0x00000004, // The JIT should insert REVERSE_PINVOKE_{ENTER,EXIT} helpers into method prolog/epilog + CORJIT_FLG2_DESKTOP_QUIRKS = 0x00000008, // The JIT should generate desktop-quirk-compatible code #endif }; struct CORJIT_FLAGS { - unsigned corJitFlags; // Values are from CorJitFlag - unsigned corJitFlags2; // Values are from CorJitFlag2 + unsigned corJitFlags; // Values are from CorJitFlag + unsigned corJitFlags2; // Values are from CorJitFlag2 }; /***************************************************************************** diff --git a/src/jit/compiler.cpp b/src/jit/compiler.cpp index f2d4dff93f..529c4a5b56 100644 --- a/src/jit/compiler.cpp +++ b/src/jit/compiler.cpp @@ -1328,8 +1328,6 @@ void Compiler::compInit(ArenaAllocator * pAlloc, InlineInfo * inl //Used by fgFindJumpTargets for inlining heuristics. opts.instrCount = 0; - compMaxUncheckedOffsetForNullObject = MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT; - for (unsigned i = 0; i < MAX_LOOP_NUM; i++) { AllVarSetOps::AssignNoCopy(this, optLoopTable[i].lpAsgVars, AllVarSetOps::UninitVal()); @@ -2767,8 +2765,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags) // Now, set compMaxUncheckedOffsetForNullObject for STRESS_NULL_OBJECT_CHECK if (compStressCompile(STRESS_NULL_OBJECT_CHECK, 30)) { - compMaxUncheckedOffsetForNullObject = - (unsigned) JitConfig.JitMaxUncheckedOffset(); + compMaxUncheckedOffsetForNullObject = (size_t)JitConfig.JitMaxUncheckedOffset(); if (verbose) { printf("STRESS_NULL_OBJECT_CHECK: compMaxUncheckedOffsetForNullObject=0x%X\n", compMaxUncheckedOffsetForNullObject); } @@ -4148,6 +4145,12 @@ int Compiler::compCompile(CORINFO_METHOD_HANDLE methodHnd, info.compMatchedVM = false; #endif // UNIX_AMD64_ABI +#if COR_JIT_EE_VERSION > 460 + compMaxUncheckedOffsetForNullObject = eeGetEEInfo()->maxUncheckedOffsetForNullObject; +#else // COR_JIT_EE_VERSION <= 460 + compMaxUncheckedOffsetForNullObject = MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT; +#endif // COR_JIT_EE_VERSION > 460 + // Set the context for token lookup. if (compIsForInlining()) { diff --git a/src/jit/compiler.h b/src/jit/compiler.h index a3f1279484..fd90ff6b73 100644 --- a/src/jit/compiler.h +++ b/src/jit/compiler.h @@ -6362,13 +6362,17 @@ public : GenTreePtr eeGetPInvokeCookie(CORINFO_SIG_INFO *szMetaSig); // Returns the page size for the target machine as reported by the EE. - inline size_t eeGetPageSize() const + inline size_t eeGetPageSize() { +#if COR_JIT_EE_VERSION > 460 + return eeGetEEInfo()->osPageSize; +#else // COR_JIT_EE_VERSION <= 460 return CORINFO_PAGE_SIZE; +#endif // COR_JIT_EE_VERSION > 460 } // Returns the frame size at which we will generate a loop to probe the stack. - inline size_t getVeryLargeFrameSize() const + inline size_t getVeryLargeFrameSize() { #ifdef _TARGET_ARM_ // The looping probe code is 40 bytes, whereas the straight-line probing for @@ -6380,6 +6384,15 @@ public : #endif } + inline bool generateCFIUnwindCodes() + { +#if COR_JIT_EE_VERSION > 460 && defined(UNIX_AMD64_ABI) + return eeGetEEInfo()->targetAbi == CORINFO_CORERT_ABI; +#else + return false; +#endif + } + // Exceptions unsigned eeGetEHcount (CORINFO_METHOD_HANDLE handle); @@ -7491,10 +7504,22 @@ public : #endif } - // true if we must generate compatible code with Jit64 quirks + // true if we must generate code compatible with JIT32 quirks + inline bool IsJit32Compat() + { +#if defined(_TARGET_X86_) && COR_JIT_EE_VERSION > 460 + return (jitFlags->corJitFlags2 & CORJIT_FLG2_DESKTOP_QUIRKS) != 0; +#else + return false; +#endif + } + + // true if we must generate code compatible with Jit64 quirks inline bool IsJit64Compat() { -#if defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR) +#if defined(_TARGET_AMD64_) && COR_JIT_EE_VERSION > 460 + return (jitFlags->corJitFlags2 & CORJIT_FLG2_DESKTOP_QUIRKS) != 0; +#elif defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR) return true; #else return false; @@ -8277,7 +8302,7 @@ public: protected: - unsigned compMaxUncheckedOffsetForNullObject; + size_t compMaxUncheckedOffsetForNullObject; void compInitOptions (CORJIT_FLAGS* compileFlags); diff --git a/src/jit/unwindamd64.cpp b/src/jit/unwindamd64.cpp index 6a5b199a07..6c8833bfc0 100644 --- a/src/jit/unwindamd64.cpp +++ b/src/jit/unwindamd64.cpp @@ -104,7 +104,7 @@ UNATIVE_OFFSET Compiler::unwindGetCurrentOffset(FuncInfoDsc* func) void Compiler::unwindBegProlog() { #ifdef UNIX_AMD64_ABI - if ((opts.eeFlags & CORJIT_FLG_CFI_UNWIND) != 0) + if (generateCFIUnwindCodes()) { unwindBegPrologCFI(); } @@ -206,12 +206,12 @@ void Compiler::unwindEndEpilog() void Compiler::unwindPush(regNumber reg) { #ifdef UNIX_AMD64_ABI - if ((opts.eeFlags & CORJIT_FLG_CFI_UNWIND) != 0) + if (generateCFIUnwindCodes()) { unwindPushCFI(reg); } else -#endif +#endif // UNIX_AMD64_ABI { unwindPushWindows(reg); } @@ -287,7 +287,7 @@ void Compiler::unwindPushCFI(regNumber reg) void Compiler::unwindAllocStack(unsigned size) { #ifdef UNIX_AMD64_ABI - if ((opts.eeFlags & CORJIT_FLG_CFI_UNWIND) != 0) + if (generateCFIUnwindCodes()) { unwindAllocStackCFI(size); } @@ -361,7 +361,7 @@ void Compiler::unwindAllocStackCFI(unsigned size) void Compiler::unwindSetFrameReg(regNumber reg, unsigned offset) { #ifdef UNIX_AMD64_ABI - if ((opts.eeFlags & CORJIT_FLG_CFI_UNWIND) != 0) + if (generateCFIUnwindCodes()) { unwindSetFrameRegCFI(reg, offset); } @@ -444,7 +444,7 @@ void Compiler::unwindSetFrameRegCFI(regNumber reg, unsigned offset) void Compiler::unwindSaveReg(regNumber reg, unsigned offset) { #ifdef UNIX_AMD64_ABI - if ((opts.eeFlags & CORJIT_FLG_CFI_UNWIND) != 0) + if (generateCFIUnwindCodes()) { unwindSaveRegCFI(reg, offset); } @@ -775,7 +775,7 @@ void Compiler::unwindReserveFuncHelper(FuncInfoDsc* func, bool isHotCode) if (isHotCode) { #ifdef UNIX_AMD64_ABI - if ((opts.eeFlags & CORJIT_FLG_CFI_UNWIND) != 0) + if (generateCFIUnwindCodes()) { unwindCodeBytes = func->cfiCodes->size() * sizeof(CFI_CODE); } @@ -873,7 +873,7 @@ void Compiler::unwindEmitFuncHelper(FuncInfoDsc* func, void* pHotCode, void* pCo } #ifdef UNIX_AMD64_ABI - if ((opts.eeFlags & CORJIT_FLG_CFI_UNWIND) != 0) + if (generateCFIUnwindCodes()) { int size = func->cfiCodes->size(); if (size > 0) @@ -924,7 +924,7 @@ void Compiler::unwindEmitFuncHelper(FuncInfoDsc* func, void* pHotCode, void* pCo if (opts.dspUnwind) { #ifdef UNIX_AMD64_ABI - if ((opts.eeFlags & CORJIT_FLG_CFI_UNWIND) != 0) + if (generateCFIUnwindCodes()) { DumpCfiInfo(isHotCode, startOffset, endOffset, unwindCodeBytes, (const CFI_CODE * const)pUnwindBlock); } diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp index df141f4eee..64a33f7819 100644 --- a/src/vm/jitinterface.cpp +++ b/src/vm/jitinterface.cpp @@ -3054,7 +3054,6 @@ static BOOL IsTypeSpecForTypicalInstantiation(SigPointer sigptr) return IsSignatureForTypicalInstantiation(sigptr, ELEMENT_TYPE_VAR, ntypars); } - void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entryKind, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken, @@ -3066,12 +3065,12 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr PRECONDITION(CheckPointer(pResultLookup)); } CONTRACTL_END; + // We should never get here when we are only verifying _ASSERTE(!isVerifyOnly()); pResultLookup->lookupKind.needsRuntimeLookup = true; pResultLookup->lookupKind.runtimeLookupFlags = 0; - #ifdef FEATURE_READYTORUN_COMPILER if (IsReadyToRunCompilation()) { @@ -3080,6 +3079,7 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr ThrowHR(E_NOTIMPL); #endif + switch (entryKind) { case TypeHandleSlot: @@ -9665,6 +9665,14 @@ void CEEInfo::getEEInfo(CORINFO_EE_INFO *pEEInfoOut) pEEInfoOut->sizeOfReversePInvokeFrame = (DWORD)-1; + pEEInfoOut->osPageSize = OS_PAGE_SIZE; + pEEInfoOut->maxUncheckedOffsetForNullObject = MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT; +#if defined(FEATURE_CORECLR) + pEEInfoOut->targetAbi = CORINFO_CORECLR_ABI; +#else + pEEInfoOut->targetAbi = CORINFO_DESKTOP_ABI; +#endif + OSVERSIONINFO sVerInfo; sVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetOSVersion(&sVerInfo); @@ -10157,6 +10165,14 @@ CORINFO_METHOD_HANDLE CEEInfo::embedMethodHandle(CORINFO_METHOD_HANDLE handle, } /*********************************************************************/ +void CEEInfo::setJitFlags(const CORJIT_FLAGS& jitFlags) +{ + LIMITED_METHOD_CONTRACT; + + m_jitFlags = jitFlags; +} + +/*********************************************************************/ DWORD CEEInfo::getJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes) { CONTRACTL { @@ -10168,9 +10184,12 @@ DWORD CEEInfo::getJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes) JIT_TO_EE_TRANSITION_LEAF(); + _ASSERTE(sizeInBytes >= sizeof(m_jitFlags)); + *jitFlags = m_jitFlags; + EE_TO_JIT_TRANSITION_LEAF(); - return 0; + return sizeof(m_jitFlags); } /*********************************************************************/ @@ -11665,9 +11684,7 @@ static CorJitResult CompileMethodWithEtwWrapper(EEJitManager *jitMgr, #endif // FEATURE_INTERPRETER // -// Helper function because can't have dtors in BEGIN_SO_TOLERANT_CODE -// flags2 is not passed on to the JIT (yet) through the JITInterface. -// It is extra flags that can be passed on within the VM. +// Helper function because can't have dtors in BEGIN_SO_TOLERANT_CODE. // CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, CEEInfo *comp, @@ -11684,6 +11701,17 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, CorJitResult ret = CORJIT_SKIPPED; // Note that CORJIT_SKIPPED is an error exit status code + CORJIT_FLAGS jitFlags = { 0 }; + jitFlags.corJitFlags = flags; + jitFlags.corJitFlags2 = flags2; + +#if !defined(FEATURE_CORECLR) + // Ask the JIT to generate desktop-quirk-compatible code. + jitFlags.corJitFlags2 |= CORJIT_FLG2_DESKTOP_QUIRKS; +#endif + + comp->setJitFlags(jitFlags); + #ifdef FEATURE_STACK_SAMPLING // SO_INTOLERANT due to init affecting global state. static ConfigDWORD s_stackSamplingEnabled; @@ -11695,7 +11723,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, #if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR) ret = getJit()->compileMethod( comp, info, - flags, + CORJIT_FLG_CALL_GETJITFLAGS, nativeEntry, nativeSizeOfCode); @@ -11704,18 +11732,18 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, #if defined(ALLOW_SXS_JIT) && !defined(CROSSGEN_COMPILE) if (FAILED(ret) && jitMgr->m_alternateJit #ifdef FEATURE_STACK_SAMPLING - && (!samplingEnabled || (flags2 & CORJIT_FLG2_SAMPLING_JIT_BACKGROUND)) + && (!samplingEnabled || (jitFlags.corJitFlags2 & CORJIT_FLG2_SAMPLING_JIT_BACKGROUND)) #endif ) { ret = jitMgr->m_alternateJit->compileMethod( comp, info, - flags, + CORJIT_FLG_CALL_GETJITFLAGS, nativeEntry, nativeSizeOfCode ); #ifdef FEATURE_STACK_SAMPLING - if (flags2 & CORJIT_FLG2_SAMPLING_JIT_BACKGROUND) + if (jitFlags.corJitFlags2 & CORJIT_FLG2_SAMPLING_JIT_BACKGROUND) { // Don't bother with failures if we couldn't collect a trace. ret = CORJIT_OK; @@ -11742,7 +11770,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, { // If we're doing an "import_only" compilation, it's for verification, so don't interpret. // (We assume that importation is completely architecture-independent, or at least nearly so.) - if (FAILED(ret) && (flags & (CORJIT_FLG_IMPORT_ONLY | CORJIT_FLG_MAKEFINALCODE)) == 0) + if (FAILED(ret) && (jitFlags.corJitFlags & (CORJIT_FLG_IMPORT_ONLY | CORJIT_FLG_MAKEFINALCODE)) == 0) { ret = Interpreter::GenerateInterpreterStub(comp, info, nativeEntry, nativeSizeOfCode); } @@ -11753,7 +11781,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, ret = CompileMethodWithEtwWrapper(jitMgr, comp, info, - flags, + CORJIT_FLG_CALL_GETJITFLAGS, nativeEntry, nativeSizeOfCode); } @@ -11762,7 +11790,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, { // If we're doing an "import_only" compilation, it's for verification, so don't interpret. // (We assume that importation is completely architecture-independent, or at least nearly so.) - if (FAILED(ret) && (flags & (CORJIT_FLG_IMPORT_ONLY | CORJIT_FLG_MAKEFINALCODE)) == 0) + if (FAILED(ret) && (jitFlags.corJitFlags & (CORJIT_FLG_IMPORT_ONLY | CORJIT_FLG_MAKEFINALCODE)) == 0) { ret = Interpreter::GenerateInterpreterStub(comp, info, nativeEntry, nativeSizeOfCode); } @@ -11772,7 +11800,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, { ret = jitMgr->m_jit->compileMethod( comp, info, - flags, + CORJIT_FLG_CALL_GETJITFLAGS, nativeEntry, nativeSizeOfCode); } @@ -11784,7 +11812,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, // If the JIT fails we keep the IL around and will // try reJIT the same IL. VSW 525059 // - if (SUCCEEDED(ret) && !(flags & CORJIT_FLG_IMPORT_ONLY) && !((CEEJitInfo*)comp)->JitAgain()) + if (SUCCEEDED(ret) && !(jitFlags.corJitFlags & CORJIT_FLG_IMPORT_ONLY) && !((CEEJitInfo*)comp)->JitAgain()) { ((CEEJitInfo*)comp)->CompressDebugInfo(); @@ -14060,4 +14088,3 @@ LPVOID EECodeInfo::findNextFunclet (LPVOID pvFuncletStart, SIZE_T } #endif // defined(_DEBUG) && !defined(HAVE_GCCOVER) #endif // defined(_TARGET_AMD64_) - diff --git a/src/vm/jitinterface.h b/src/vm/jitinterface.h index 08721ae2df..71d15644f3 100644 --- a/src/vm/jitinterface.h +++ b/src/vm/jitinterface.h @@ -1,1675 +1,1684 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -// =========================================================================== -// File: JITinterface.H -// - -// =========================================================================== - - -#ifndef JITINTERFACE_H -#define JITINTERFACE_H - -#include "corjit.h" -#ifdef FEATURE_PREJIT -#include "corcompile.h" -#endif // FEATURE_PREJIT - -class Stub; -class MethodDesc; -class FieldDesc; -enum RuntimeExceptionKind; -class AwareLock; -class PtrArray; - -#include "genericdict.h" - -inline FieldDesc* GetField(CORINFO_FIELD_HANDLE fieldHandle) -{ - LIMITED_METHOD_CONTRACT; - return (FieldDesc*) fieldHandle; -} - -inline -bool SigInfoFlagsAreValid (CORINFO_SIG_INFO *sig) -{ - LIMITED_METHOD_CONTRACT; - return !(sig->flags & ~( CORINFO_SIGFLAG_IS_LOCAL_SIG - | CORINFO_SIGFLAG_IL_STUB - )); -} - - -void InitJITHelpers1(); -void InitJITHelpers2(); - -PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* header, - DWORD flags, DWORD flags2, ULONG* sizeOfCode = NULL); - -void getMethodInfoHelper(MethodDesc * ftn, - CORINFO_METHOD_HANDLE ftnHnd, - COR_ILMETHOD_DECODER * header, - CORINFO_METHOD_INFO * methInfo); - -void getMethodInfoILMethodHeaderHelper( - COR_ILMETHOD_DECODER* header, - CORINFO_METHOD_INFO* methInfo - ); - - -#ifdef FEATURE_PREJIT -BOOL LoadDynamicInfoEntry(Module *currentModule, - RVA fixupRva, - SIZE_T *entry); -#endif // FEATURE_PREJIT - -// -// The legacy x86 monitor helpers do not need a state argument -// -#if !defined(_TARGET_X86_) - -#define FCDECL_MONHELPER(funcname, arg) FCDECL2(void, funcname, arg, BYTE* pbLockTaken) -#define HCIMPL_MONHELPER(funcname, arg) HCIMPL2(void, funcname, arg, BYTE* pbLockTaken) -#define MONHELPER_STATE(x) x -#define MONHELPER_ARG pbLockTaken - -#else - -#define FCDECL_MONHELPER(funcname, arg) FCDECL1(void, funcname, arg) -#define HCIMPL_MONHELPER(funcname, arg) HCIMPL1(void, funcname, arg) -#define MONHELPER_STATE(x) -#define MONHELPER_ARG NULL - -#endif // _TARGET_X86_ - - -// -// JIT HELPER ALIASING FOR PORTABILITY. -// -// The portable helper is used if the platform does not provide optimized implementation. -// - -#ifndef JIT_MonEnter -#define JIT_MonEnter JIT_MonEnter_Portable -#endif -EXTERN_C FCDECL1(void, JIT_MonEnter, Object *obj); -EXTERN_C FCDECL1(void, JIT_MonEnter_Portable, Object *obj); - -#ifndef JIT_MonEnterWorker -#define JIT_MonEnterWorker JIT_MonEnterWorker_Portable -#endif -EXTERN_C FCDECL_MONHELPER(JIT_MonEnterWorker, Object *obj); -EXTERN_C FCDECL_MONHELPER(JIT_MonEnterWorker_Portable, Object *obj); - -#ifndef JIT_MonReliableEnter -#define JIT_MonReliableEnter JIT_MonReliableEnter_Portable -#endif -EXTERN_C FCDECL2(void, JIT_MonReliableEnter, Object* obj, BYTE *tookLock); -EXTERN_C FCDECL2(void, JIT_MonReliableEnter_Portable, Object* obj, BYTE *tookLock); - -#ifndef JIT_MonTryEnter -#define JIT_MonTryEnter JIT_MonTryEnter_Portable -#endif -EXTERN_C FCDECL3(void, JIT_MonTryEnter, Object *obj, INT32 timeout, BYTE* pbLockTaken); -EXTERN_C FCDECL3(void, JIT_MonTryEnter_Portable, Object *obj, INT32 timeout, BYTE* pbLockTaken); - -#ifndef JIT_MonExit -#define JIT_MonExit JIT_MonExit_Portable -#endif -EXTERN_C FCDECL1(void, JIT_MonExit, Object *obj); -EXTERN_C FCDECL1(void, JIT_MonExit_Portable, Object *obj); - -#ifndef JIT_MonExitWorker -#define JIT_MonExitWorker JIT_MonExitWorker_Portable -#endif -EXTERN_C FCDECL_MONHELPER(JIT_MonExitWorker, Object *obj); -EXTERN_C FCDECL_MONHELPER(JIT_MonExitWorker_Portable, Object *obj); - -#ifndef JIT_MonEnterStatic -#define JIT_MonEnterStatic JIT_MonEnterStatic_Portable -#endif -EXTERN_C FCDECL_MONHELPER(JIT_MonEnterStatic, AwareLock *lock); -EXTERN_C FCDECL_MONHELPER(JIT_MonEnterStatic_Portable, AwareLock *lock); - -#ifndef JIT_MonExitStatic -#define JIT_MonExitStatic JIT_MonExitStatic_Portable -#endif -EXTERN_C FCDECL_MONHELPER(JIT_MonExitStatic, AwareLock *lock); -EXTERN_C FCDECL_MONHELPER(JIT_MonExitStatic_Portable, AwareLock *lock); - - -#ifndef JIT_GetSharedGCStaticBase -#define JIT_GetSharedGCStaticBase JIT_GetSharedGCStaticBase_Portable -#endif -EXTERN_C FCDECL2(void*, JIT_GetSharedGCStaticBase, SIZE_T moduleDomainID, DWORD dwModuleClassID); -EXTERN_C FCDECL2(void*, JIT_GetSharedGCStaticBase_Portable, SIZE_T moduleDomainID, DWORD dwModuleClassID); - -#ifndef JIT_GetSharedNonGCStaticBase -#define JIT_GetSharedNonGCStaticBase JIT_GetSharedNonGCStaticBase_Portable -#endif -EXTERN_C FCDECL2(void*, JIT_GetSharedNonGCStaticBase, SIZE_T moduleDomainID, DWORD dwModuleClassID); -EXTERN_C FCDECL2(void*, JIT_GetSharedNonGCStaticBase_Portable, SIZE_T moduleDomainID, DWORD dwModuleClassID); - -#ifndef JIT_GetSharedGCStaticBaseNoCtor -#define JIT_GetSharedGCStaticBaseNoCtor JIT_GetSharedGCStaticBaseNoCtor_Portable -#endif -EXTERN_C FCDECL1(void*, JIT_GetSharedGCStaticBaseNoCtor, SIZE_T moduleDomainID); -EXTERN_C FCDECL1(void*, JIT_GetSharedGCStaticBaseNoCtor_Portable, SIZE_T moduleDomainID); - -#ifndef JIT_GetSharedNonGCStaticBaseNoCtor -#define JIT_GetSharedNonGCStaticBaseNoCtor JIT_GetSharedNonGCStaticBaseNoCtor_Portable -#endif -EXTERN_C FCDECL1(void*, JIT_GetSharedNonGCStaticBaseNoCtor, SIZE_T moduleDomainID); -EXTERN_C FCDECL1(void*, JIT_GetSharedNonGCStaticBaseNoCtor_Portable, SIZE_T moduleDomainID); - -#ifndef JIT_ChkCastClass -#define JIT_ChkCastClass JIT_ChkCastClass_Portable -#endif -EXTERN_C FCDECL2(Object*, JIT_ChkCastClass, MethodTable* pMT, Object* pObject); -EXTERN_C FCDECL2(Object*, JIT_ChkCastClass_Portable, MethodTable* pMT, Object* pObject); - -#ifndef JIT_ChkCastClassSpecial -#define JIT_ChkCastClassSpecial JIT_ChkCastClassSpecial_Portable -#endif -EXTERN_C FCDECL2(Object*, JIT_ChkCastClassSpecial, MethodTable* pMT, Object* pObject); -EXTERN_C FCDECL2(Object*, JIT_ChkCastClassSpecial_Portable, MethodTable* pMT, Object* pObject); - -#ifndef JIT_IsInstanceOfClass -#define JIT_IsInstanceOfClass JIT_IsInstanceOfClass_Portable -#endif -EXTERN_C FCDECL2(Object*, JIT_IsInstanceOfClass, MethodTable* pMT, Object* pObject); -EXTERN_C FCDECL2(Object*, JIT_IsInstanceOfClass_Portable, MethodTable* pMT, Object* pObject); - -#ifndef JIT_ChkCastInterface -#define JIT_ChkCastInterface JIT_ChkCastInterface_Portable -#endif -EXTERN_C FCDECL2(Object*, JIT_ChkCastInterface, MethodTable* pMT, Object* pObject); -EXTERN_C FCDECL2(Object*, JIT_ChkCastInterface_Portable, MethodTable* pMT, Object* pObject); - -#ifndef JIT_IsInstanceOfInterface -#define JIT_IsInstanceOfInterface JIT_IsInstanceOfInterface_Portable -#endif -EXTERN_C FCDECL2(Object*, JIT_IsInstanceOfInterface, MethodTable* pMT, Object* pObject); -EXTERN_C FCDECL2(Object*, JIT_IsInstanceOfInterface_Portable, MethodTable* pMT, Object* pObject); - -extern FCDECL1(Object*, JIT_NewS_MP_FastPortable, CORINFO_CLASS_HANDLE typeHnd_); -extern FCDECL1(Object*, JIT_New, CORINFO_CLASS_HANDLE typeHnd_); - -#ifndef JIT_NewCrossContext -#define JIT_NewCrossContext JIT_NewCrossContext_Portable -#endif -EXTERN_C FCDECL1(Object*, JIT_NewCrossContext, CORINFO_CLASS_HANDLE typeHnd_); -EXTERN_C FCDECL1(Object*, JIT_NewCrossContext_Portable, CORINFO_CLASS_HANDLE typeHnd_); - -extern FCDECL1(StringObject*, AllocateString_MP_FastPortable, DWORD stringLength); -extern FCDECL1(StringObject*, UnframedAllocateString, DWORD stringLength); -extern FCDECL1(StringObject*, FramedAllocateString, DWORD stringLength); - -extern FCDECL2(Object*, JIT_NewArr1VC_MP_FastPortable, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size); -extern FCDECL2(Object*, JIT_NewArr1OBJ_MP_FastPortable, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size); -extern FCDECL2(Object*, JIT_NewArr1, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size); - -#ifndef JIT_Stelem_Ref -#define JIT_Stelem_Ref JIT_Stelem_Ref_Portable -#endif -EXTERN_C FCDECL3(void, JIT_Stelem_Ref, PtrArray* array, unsigned idx, Object* val); -EXTERN_C FCDECL3(void, JIT_Stelem_Ref_Portable, PtrArray* array, unsigned idx, Object* val); - -EXTERN_C FCDECL_MONHELPER(JITutil_MonEnterWorker, Object* obj); -EXTERN_C FCDECL2(void, JITutil_MonReliableEnter, Object* obj, BYTE* pbLockTaken); -EXTERN_C FCDECL3(void, JITutil_MonTryEnter, Object* obj, INT32 timeOut, BYTE* pbLockTaken); -EXTERN_C FCDECL_MONHELPER(JITutil_MonExitWorker, Object* obj); -EXTERN_C FCDECL_MONHELPER(JITutil_MonSignal, AwareLock* lock); -EXTERN_C FCDECL_MONHELPER(JITutil_MonContention, AwareLock* awarelock); -EXTERN_C FCDECL2(void, JITutil_MonReliableContention, AwareLock* awarelock, BYTE* pbLockTaken); - -// Slow versions to tail call if the fast version fails -EXTERN_C FCDECL2(void*, JIT_GetSharedNonGCStaticBase_Helper, DomainLocalModule *pLocalModule, DWORD dwClassDomainID); -EXTERN_C FCDECL2(void*, JIT_GetSharedGCStaticBase_Helper, DomainLocalModule *pLocalModule, DWORD dwClassDomainID); - -EXTERN_C void DoJITFailFast (); -EXTERN_C FCDECL0(void, JIT_FailFast); -extern FCDECL3(void, JIT_ThrowAccessException, RuntimeExceptionKind, CORINFO_METHOD_HANDLE caller, void * callee); - -FCDECL1(void*, JIT_SafeReturnableByref, void* byref); - -#if !defined(FEATURE_USE_ASM_GC_WRITE_BARRIERS) && defined(FEATURE_COUNT_GC_WRITE_BARRIERS) -// Extra argument for the classification of the checked barriers. -extern "C" FCDECL3(VOID, JIT_CheckedWriteBarrier, Object **dst, Object *ref, CheckedWriteBarrierKinds kind); -#else -// Regular checked write barrier. -extern "C" FCDECL2(VOID, JIT_CheckedWriteBarrier, Object **dst, Object *ref); -#endif - -extern "C" FCDECL2(VOID, JIT_WriteBarrier, Object **dst, Object *ref); - -extern "C" FCDECL2(VOID, JIT_WriteBarrierEnsureNonHeapTarget, Object **dst, Object *ref); - -extern "C" FCDECL2(Object*, JIT_ChkCastAny, CORINFO_CLASS_HANDLE type, Object *pObject); // JITInterfaceX86.cpp, etc. -extern "C" FCDECL2(Object*, JIT_IsInstanceOfAny, CORINFO_CLASS_HANDLE type, Object *pObject); - -extern "C" FCDECL2(Object*, JITutil_ChkCastInterface, MethodTable *pInterfaceMT, Object *obj); -extern "C" FCDECL2(Object*, JITutil_IsInstanceOfInterface, MethodTable *pInterfaceMT, Object *obj); -extern "C" FCDECL2(Object*, JITutil_ChkCastAny, CORINFO_CLASS_HANDLE type, Object *obj); -extern "C" FCDECL2(Object*, JITutil_IsInstanceOfAny, CORINFO_CLASS_HANDLE type, Object *obj); - -extern "C" FCDECL1(void, JIT_InternalThrow, unsigned exceptNum); -extern "C" FCDECL1(void*, JIT_InternalThrowFromHelper, unsigned exceptNum); - -#ifdef _TARGET_AMD64_ - - -class WriteBarrierManager -{ -public: - enum WriteBarrierType - { - WRITE_BARRIER_UNINITIALIZED, - WRITE_BARRIER_PREGROW64, - WRITE_BARRIER_POSTGROW64, -#ifdef FEATURE_SVR_GC - WRITE_BARRIER_SVR64, -#endif // FEATURE_SVR_GC -#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP - WRITE_BARRIER_WRITE_WATCH_PREGROW64, - WRITE_BARRIER_WRITE_WATCH_POSTGROW64, -#ifdef FEATURE_SVR_GC - WRITE_BARRIER_WRITE_WATCH_SVR64, -#endif // FEATURE_SVR_GC -#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP - WRITE_BARRIER_BUFFER - }; - - WriteBarrierManager(); - void Initialize(); - - void UpdateEphemeralBounds(bool isRuntimeSuspended); - void UpdateWriteWatchAndCardTableLocations(bool isRuntimeSuspended, bool bReqUpperBoundsCheck); - -#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP - void SwitchToWriteWatchBarrier(bool isRuntimeSuspended); - void SwitchToNonWriteWatchBarrier(bool isRuntimeSuspended); -#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP - -protected: - size_t GetCurrentWriteBarrierSize(); - size_t GetSpecificWriteBarrierSize(WriteBarrierType writeBarrier); - PBYTE CalculatePatchLocation(LPVOID base, LPVOID label, int offset); - PCODE GetCurrentWriteBarrierCode(); - void ChangeWriteBarrierTo(WriteBarrierType newWriteBarrier, bool isRuntimeSuspended); - bool NeedDifferentWriteBarrier(bool bReqUpperBoundsCheck, WriteBarrierType* pNewWriteBarrierType); - -private: - void Validate(); - - WriteBarrierType m_currentWriteBarrier; - - PBYTE m_pWriteWatchTableImmediate; // PREGROW | POSTGROW | SVR | WRITE_WATCH | - PBYTE m_pLowerBoundImmediate; // PREGROW | POSTGROW | | WRITE_WATCH | - PBYTE m_pCardTableImmediate; // PREGROW | POSTGROW | SVR | WRITE_WATCH | - PBYTE m_pUpperBoundImmediate; // | POSTGROW | | WRITE_WATCH | -}; - -#endif // _TARGET_AMD64_ - -#ifdef _WIN64 -EXTERN_C FCDECL1(Object*, JIT_TrialAllocSFastMP_InlineGetThread, CORINFO_CLASS_HANDLE typeHnd_); -EXTERN_C FCDECL2(Object*, JIT_BoxFastMP_InlineGetThread, CORINFO_CLASS_HANDLE type, void* data); -EXTERN_C FCDECL2(Object*, JIT_NewArr1VC_MP_InlineGetThread, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size); -EXTERN_C FCDECL2(Object*, JIT_NewArr1OBJ_MP_InlineGetThread, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size); - -#endif // _WIN64 - -EXTERN_C FCDECL2_VV(INT64, JIT_LMul, INT64 val1, INT64 val2); - -EXTERN_C FCDECL1_V(INT64, JIT_Dbl2Lng, double val); -EXTERN_C FCDECL1_V(INT64, JIT_Dbl2IntSSE2, double val); -EXTERN_C FCDECL1_V(INT64, JIT_Dbl2LngP4x87, double val); -EXTERN_C FCDECL1_V(INT64, JIT_Dbl2LngSSE3, double val); -EXTERN_C FCDECL1_V(INT64, JIT_Dbl2LngOvf, double val); - -EXTERN_C FCDECL1_V(INT32, JIT_Dbl2IntOvf, double val); - -EXTERN_C FCDECL2_VV(float, JIT_FltRem, float dividend, float divisor); -EXTERN_C FCDECL2_VV(double, JIT_DblRem, double dividend, double divisor); - -#if !defined(_WIN64) && !defined(_TARGET_X86_) -EXTERN_C FCDECL2_VV(UINT64, JIT_LLsh, UINT64 num, int shift); -EXTERN_C FCDECL2_VV(INT64, JIT_LRsh, INT64 num, int shift); -EXTERN_C FCDECL2_VV(UINT64, JIT_LRsz, UINT64 num, int shift); -#endif - -#ifdef _TARGET_X86_ - -extern "C" -{ - void STDCALL JIT_LLsh(); // JIThelp.asm - void STDCALL JIT_LRsh(); // JIThelp.asm - void STDCALL JIT_LRsz(); // JIThelp.asm - - void STDCALL JIT_CheckedWriteBarrierEAX(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_CheckedWriteBarrierEBX(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_CheckedWriteBarrierECX(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_CheckedWriteBarrierESI(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_CheckedWriteBarrierEDI(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_CheckedWriteBarrierEBP(); // JIThelp.asm/JIThelp.s - - void STDCALL JIT_DebugWriteBarrierEAX(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_DebugWriteBarrierEBX(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_DebugWriteBarrierECX(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_DebugWriteBarrierESI(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_DebugWriteBarrierEDI(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_DebugWriteBarrierEBP(); // JIThelp.asm/JIThelp.s - - void STDCALL JIT_WriteBarrierEAX(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_WriteBarrierEBX(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_WriteBarrierECX(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_WriteBarrierESI(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_WriteBarrierEDI(); // JIThelp.asm/JIThelp.s - void STDCALL JIT_WriteBarrierEBP(); // JIThelp.asm/JIThelp.s - - void STDCALL JIT_WriteBarrierStart(); - void STDCALL JIT_WriteBarrierLast(); - - void STDCALL JIT_PatchedWriteBarrierStart(); - void STDCALL JIT_PatchedWriteBarrierLast(); -} - -void ValidateWriteBarrierHelpers(); - -#endif //_TARGET_X86_ - -extern "C" -{ - void STDCALL JIT_EndCatch(); // JIThelp.asm/JIThelp.s - - void STDCALL JIT_ByRefWriteBarrier(); // JIThelp.asm/JIThelp.s - -#if defined(_TARGET_AMD64_) || defined(_TARGET_ARM_) - - FCDECL2VA(void, JIT_TailCall, PCODE copyArgs, PCODE target); - -#else // _TARGET_AMD64_ || _TARGET_ARM_ - - void STDCALL JIT_TailCall(); // JIThelp.asm - -#endif // _TARGET_AMD64_ || _TARGET_ARM_ - - void STDCALL JIT_MemSet(void *dest, int c, SIZE_T count); - void STDCALL JIT_MemCpy(void *dest, const void *src, SIZE_T count); - - void STDCALL JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle); -}; - -#ifndef FEATURE_CORECLR -// -// Obfluscators that are hacking into the JIT expect certain methods to exist in certain places of CEEInfo vtable. Add artifical slots -// to the vtable to avoid breaking apps by .NET 4.5 in-place update. -// - -class ICorMethodInfo_Hack -{ -public: - virtual const char* __stdcall ICorMethodInfo_Hack_getMethodName (CORINFO_METHOD_HANDLE ftnHnd, const char** scopeName) = 0; -}; - -class ICorModuleInfo_Hack -{ -public: - virtual void ICorModuleInfo_Hack_dummy() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); }; -}; - -class ICorClassInfo_Hack -{ -public: - virtual void ICorClassInfo_Hack_dummy1() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); }; - virtual void ICorClassInfo_Hack_dummy2() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); }; - virtual void ICorClassInfo_Hack_dummy3() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); }; - virtual void ICorClassInfo_Hack_dummy4() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); }; - virtual void ICorClassInfo_Hack_dummy5() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); }; - virtual void ICorClassInfo_Hack_dummy6() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); }; - virtual void ICorClassInfo_Hack_dummy7() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); }; - virtual void ICorClassInfo_Hack_dummy8() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); }; - virtual void ICorClassInfo_Hack_dummy9() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); }; - virtual void ICorClassInfo_Hack_dummy10() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); }; - virtual void ICorClassInfo_Hack_dummy11() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); }; - virtual void ICorClassInfo_Hack_dummy12() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); }; - virtual void ICorClassInfo_Hack_dummy13() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); }; - virtual void ICorClassInfo_Hack_dummy14() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); }; - - virtual mdMethodDef __stdcall ICorClassInfo_Hack_getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod) = 0; -}; - -class ICorStaticInfo_Hack : public virtual ICorMethodInfo_Hack, public virtual ICorModuleInfo_Hack, public virtual ICorClassInfo_Hack -{ - virtual void ICorStaticInfo_Hack_dummy() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); }; -}; - -#endif // FEATURE_CORECLR - - -/*********************************************************************/ -/*********************************************************************/ -class CEEInfo : public ICorJitInfo -#ifndef FEATURE_CORECLR - , public virtual ICorStaticInfo_Hack -#endif -{ - friend class CEEDynamicCodeInfo; - - const char * __stdcall ICorMethodInfo_Hack_getMethodName(CORINFO_METHOD_HANDLE ftnHnd, const char** scopeName) - { - WRAPPER_NO_CONTRACT; - return getMethodName(ftnHnd, scopeName); - } - - mdMethodDef __stdcall ICorClassInfo_Hack_getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod) - { - WRAPPER_NO_CONTRACT; - return getMethodDefFromMethod(hMethod); - } - -public: - // ICorClassInfo stuff - CorInfoType asCorInfoType (CORINFO_CLASS_HANDLE cls); - // This normalizes EE type information into the form expected by the JIT. - // - // If typeHnd contains exact type information, then *clsRet will contain - // the normalized CORINFO_CLASS_HANDLE information on return. - static CorInfoType asCorInfoType (CorElementType cet, - TypeHandle typeHnd = TypeHandle() /* optional in */, - CORINFO_CLASS_HANDLE *clsRet = NULL /* optional out */ ); - - CORINFO_MODULE_HANDLE getClassModule(CORINFO_CLASS_HANDLE clsHnd); - CORINFO_ASSEMBLY_HANDLE getModuleAssembly(CORINFO_MODULE_HANDLE mod); - const char* getAssemblyName(CORINFO_ASSEMBLY_HANDLE assem); - void* LongLifetimeMalloc(size_t sz); - void LongLifetimeFree(void* obj); - size_t getClassModuleIdForStatics(CORINFO_CLASS_HANDLE clsHnd, CORINFO_MODULE_HANDLE *pModuleHandle, void **ppIndirection); - const char* getClassName (CORINFO_CLASS_HANDLE cls); - const char* getHelperName(CorInfoHelpFunc ftnNum); - int appendClassName(__deref_inout_ecount(*pnBufLen) WCHAR** ppBuf, - int* pnBufLen, - CORINFO_CLASS_HANDLE cls, - BOOL fNamespace, - BOOL fFullInst, - BOOL fAssembly); - BOOL isValueClass (CORINFO_CLASS_HANDLE cls); - BOOL canInlineTypeCheckWithObjectVTable (CORINFO_CLASS_HANDLE cls); - - DWORD getClassAttribs (CORINFO_CLASS_HANDLE cls); - - // Internal version without JIT-EE transition - DWORD getClassAttribsInternal (CORINFO_CLASS_HANDLE cls); - - BOOL isStructRequiringStackAllocRetBuf(CORINFO_CLASS_HANDLE cls); - - unsigned getClassSize (CORINFO_CLASS_HANDLE cls); - unsigned getClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint); - static unsigned getClassAlignmentRequirementStatic(TypeHandle clsHnd); - - // Used for HFA's on IA64...and later for type based disambiguation - CORINFO_FIELD_HANDLE getFieldInClass(CORINFO_CLASS_HANDLE clsHnd, INT num); - - mdMethodDef getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod); - BOOL checkMethodModifier(CORINFO_METHOD_HANDLE hMethod, LPCSTR modifier, BOOL fOptional); - - unsigned getClassGClayout (CORINFO_CLASS_HANDLE cls, BYTE* gcPtrs); /* really GCType* gcPtrs */ - unsigned getClassNumInstanceFields(CORINFO_CLASS_HANDLE cls); - - // returns the enregister info for a struct based on type of fields, alignment, etc. - bool getSystemVAmd64PassStructInRegisterDescriptor( - /*IN*/ CORINFO_CLASS_HANDLE _structHnd, - /*OUT*/ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr); - - // Check Visibility rules. - // For Protected (family access) members, type of the instance is also - // considered when checking visibility rules. - - - CorInfoHelpFunc getNewHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_METHOD_HANDLE callerHandle); - static CorInfoHelpFunc getNewHelperStatic(MethodTable * pMT); - - CorInfoHelpFunc getNewArrHelper(CORINFO_CLASS_HANDLE arrayCls); - static CorInfoHelpFunc getNewArrHelperStatic(TypeHandle clsHnd); - - CorInfoHelpFunc getCastingHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fThrowing); - static CorInfoHelpFunc getCastingHelperStatic(TypeHandle clsHnd, bool fThrowing, bool * pfClassMustBeRestored); - - CorInfoHelpFunc getSharedCCtorHelper(CORINFO_CLASS_HANDLE clsHnd); - CorInfoHelpFunc getSecurityPrologHelper(CORINFO_METHOD_HANDLE ftn); - CORINFO_CLASS_HANDLE getTypeForBox(CORINFO_CLASS_HANDLE cls); - CorInfoHelpFunc getBoxHelper(CORINFO_CLASS_HANDLE cls); - CorInfoHelpFunc getUnBoxHelper(CORINFO_CLASS_HANDLE cls); - - bool getReadyToRunHelper( - CORINFO_RESOLVED_TOKEN * pResolvedToken, - CORINFO_LOOKUP_KIND * pGenericLookupKind, - CorInfoHelpFunc id, - CORINFO_CONST_LOOKUP * pLookup - ); - - void getReadyToRunDelegateCtorHelper( - CORINFO_RESOLVED_TOKEN * pTargetMethod, - CORINFO_CLASS_HANDLE delegateType, - CORINFO_CONST_LOOKUP * pLookup - ); - - CorInfoInitClassResult initClass( - CORINFO_FIELD_HANDLE field, - CORINFO_METHOD_HANDLE method, - CORINFO_CONTEXT_HANDLE context, - BOOL speculative = FALSE); - - void classMustBeLoadedBeforeCodeIsRun (CORINFO_CLASS_HANDLE cls); - void methodMustBeLoadedBeforeCodeIsRun (CORINFO_METHOD_HANDLE meth); - CORINFO_METHOD_HANDLE mapMethodDeclToMethodImpl(CORINFO_METHOD_HANDLE methHnd); - CORINFO_CLASS_HANDLE getBuiltinClass(CorInfoClassId classId); - void getGSCookie(GSCookie * pCookieVal, GSCookie ** ppCookieVal); - - // "System.Int32" ==> CORINFO_TYPE_INT.. - CorInfoType getTypeForPrimitiveValueClass( - CORINFO_CLASS_HANDLE cls - ); - - // TRUE if child is a subtype of parent - // if parent is an interface, then does child implement / extend parent - BOOL canCast( - CORINFO_CLASS_HANDLE child, - CORINFO_CLASS_HANDLE parent - ); - - // TRUE if cls1 and cls2 are considered equivalent types. - BOOL areTypesEquivalent( - CORINFO_CLASS_HANDLE cls1, - CORINFO_CLASS_HANDLE cls2 - ); - - // returns is the intersection of cls1 and cls2. - CORINFO_CLASS_HANDLE mergeClasses( - CORINFO_CLASS_HANDLE cls1, - CORINFO_CLASS_HANDLE cls2 - ); - - // Given a class handle, returns the Parent type. - // For COMObjectType, it returns Class Handle of System.Object. - // Returns 0 if System.Object is passed in. - CORINFO_CLASS_HANDLE getParentType ( - CORINFO_CLASS_HANDLE cls - ); - - // Returns the CorInfoType of the "child type". If the child type is - // not a primitive type, *clsRet will be set. - // Given an Array of Type Foo, returns Foo. - // Given BYREF Foo, returns Foo - CorInfoType getChildType ( - CORINFO_CLASS_HANDLE clsHnd, - CORINFO_CLASS_HANDLE *clsRet - ); - - // Check constraints on type arguments of this class and parent classes - BOOL satisfiesClassConstraints( - CORINFO_CLASS_HANDLE cls - ); - - // Check if this is a single dimensional array type - BOOL isSDArray( - CORINFO_CLASS_HANDLE cls - ); - - // Get the number of dimensions in an array - unsigned getArrayRank( - CORINFO_CLASS_HANDLE cls - ); - - // Get static field data for an array - void * getArrayInitializationData( - CORINFO_FIELD_HANDLE field, - DWORD size - ); - - // Check Visibility rules. - CorInfoIsAccessAllowedResult canAccessClass( - CORINFO_RESOLVED_TOKEN * pResolvedToken, - CORINFO_METHOD_HANDLE callerHandle, - CORINFO_HELPER_DESC *pAccessHelper /* If canAccessClass returns something other - than ALLOWED, then this is filled in. */ - ); - - // Returns that compilation flags that are shared between JIT and NGen - static DWORD GetBaseCompileFlags(MethodDesc * ftn); - - // Resolve metadata token into runtime method handles. - void resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken); - - // Attempt to resolve a metadata token into a runtime method handle. Returns true - // if resolution succeeded and false otherwise. - bool tryResolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken); - - void getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken, - CORINFO_METHOD_HANDLE callerHandle, - CORINFO_ACCESS_FLAGS flags, - CORINFO_FIELD_INFO *pResult - ); - static CorInfoHelpFunc getSharedStaticsHelper(FieldDesc * pField, MethodTable * pFieldMT); - - bool isFieldStatic(CORINFO_FIELD_HANDLE fldHnd); - - // Given a signature token sigTOK, use class/method instantiation in context to instantiate any type variables in the signature and return a new signature - void findSig(CORINFO_MODULE_HANDLE scopeHnd, unsigned sigTOK, CORINFO_CONTEXT_HANDLE context, CORINFO_SIG_INFO* sig); - void findCallSiteSig(CORINFO_MODULE_HANDLE scopeHnd, unsigned methTOK, CORINFO_CONTEXT_HANDLE context, CORINFO_SIG_INFO* sig); - CORINFO_CLASS_HANDLE getTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken); - - size_t findNameOfToken (CORINFO_MODULE_HANDLE module, mdToken metaTOK, - __out_ecount (FQNameCapacity) char * szFQName, size_t FQNameCapacity); - - CorInfoCanSkipVerificationResult canSkipVerification(CORINFO_MODULE_HANDLE moduleHnd); - - // Checks if the given metadata token is valid - BOOL isValidToken ( - CORINFO_MODULE_HANDLE module, - mdToken metaTOK); - - // Checks if the given metadata token is valid StringRef - BOOL isValidStringRef ( - CORINFO_MODULE_HANDLE module, - mdToken metaTOK); - - static size_t findNameOfToken (Module* module, mdToken metaTOK, - __out_ecount (FQNameCapacity) char * szFQName, size_t FQNameCapacity); - - // ICorMethodInfo stuff - const char* getMethodName (CORINFO_METHOD_HANDLE ftnHnd, const char** scopeName); - unsigned getMethodHash (CORINFO_METHOD_HANDLE ftnHnd); - - DWORD getMethodAttribs (CORINFO_METHOD_HANDLE ftnHnd); - // Internal version without JIT-EE transition - DWORD getMethodAttribsInternal (CORINFO_METHOD_HANDLE ftnHnd); - - void setMethodAttribs (CORINFO_METHOD_HANDLE ftnHnd, CorInfoMethodRuntimeFlags attribs); - - bool getMethodInfo ( - CORINFO_METHOD_HANDLE ftnHnd, - CORINFO_METHOD_INFO* methInfo); - - CorInfoInline canInline ( - CORINFO_METHOD_HANDLE callerHnd, - CORINFO_METHOD_HANDLE calleeHnd, - DWORD* pRestrictions); - - void reportInliningDecision (CORINFO_METHOD_HANDLE inlinerHnd, - CORINFO_METHOD_HANDLE inlineeHnd, - CorInfoInline inlineResult, - const char * reason); - - // Used by ngen - CORINFO_METHOD_HANDLE instantiateMethodAtObject(CORINFO_METHOD_HANDLE method); - - // Loads the constraints on a typical method definition, detecting cycles; - // used by verifiers. - void initConstraintsForVerification( - CORINFO_METHOD_HANDLE method, - BOOL *pfHasCircularClassConstraints, - BOOL *pfHasCircularMethodConstraints - ); - - CorInfoInstantiationVerification isInstantiationOfVerifiedGeneric ( - CORINFO_METHOD_HANDLE methodHnd); - - - bool canTailCall ( - CORINFO_METHOD_HANDLE callerHnd, - CORINFO_METHOD_HANDLE declaredCalleeHnd, - CORINFO_METHOD_HANDLE exactCalleeHnd, - bool fIsTailPrefix); - - void reportTailCallDecision (CORINFO_METHOD_HANDLE callerHnd, - CORINFO_METHOD_HANDLE calleeHnd, - bool fIsTailPrefix, - CorInfoTailCall tailCallResult, - const char * reason); - - CorInfoCanSkipVerificationResult canSkipMethodVerification( - CORINFO_METHOD_HANDLE ftnHnd); - - // Given a method descriptor ftnHnd, extract signature information into sigInfo - // Obtain (representative) instantiation information from ftnHnd's owner class - //@GENERICSVER: added explicit owner parameter - void getMethodSig ( - CORINFO_METHOD_HANDLE ftnHnd, - CORINFO_SIG_INFO* sigInfo, - CORINFO_CLASS_HANDLE owner = NULL - ); - // Internal version without JIT-EE transition - void getMethodSigInternal ( - CORINFO_METHOD_HANDLE ftnHnd, - CORINFO_SIG_INFO* sigInfo, - CORINFO_CLASS_HANDLE owner = NULL - ); - - void getEHinfo( - CORINFO_METHOD_HANDLE ftn, - unsigned EHnumber, - CORINFO_EH_CLAUSE* clause); - - CORINFO_CLASS_HANDLE getMethodClass (CORINFO_METHOD_HANDLE methodHnd); - CORINFO_MODULE_HANDLE getMethodModule (CORINFO_METHOD_HANDLE methodHnd); - - void getMethodVTableOffset ( - CORINFO_METHOD_HANDLE methodHnd, - unsigned * pOffsetOfIndirection, - unsigned * pOffsetAfterIndirection - ); - - CorInfoIntrinsics getIntrinsicID(CORINFO_METHOD_HANDLE method, - bool * pMustExpand = NULL); - - bool isInSIMDModule(CORINFO_CLASS_HANDLE classHnd); - - CorInfoUnmanagedCallConv getUnmanagedCallConv(CORINFO_METHOD_HANDLE method); - BOOL pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); - - // Generate a cookie based on the signature that would needs to be passed - // to the above generic stub - LPVOID GetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void ** ppIndirection); - bool canGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig); - - // Check Visibility rules. - - // should we enforce the new (for whidbey) restrictions on calling virtual methods? - BOOL shouldEnforceCallvirtRestriction( - CORINFO_MODULE_HANDLE scope); - - // Check constraints on method type arguments (only). - // The parent class should be checked separately using satisfiesClassConstraints(parent). - BOOL satisfiesMethodConstraints( - CORINFO_CLASS_HANDLE parent, // the exact parent of the method - CORINFO_METHOD_HANDLE method - ); - - // Given a Delegate type and a method, check if the method signature - // is Compatible with the Invoke method of the delegate. - //@GENERICSVER: new (suitable for generics) - BOOL isCompatibleDelegate( - CORINFO_CLASS_HANDLE objCls, - CORINFO_CLASS_HANDLE methodParentCls, - CORINFO_METHOD_HANDLE method, - CORINFO_CLASS_HANDLE delegateCls, - BOOL* pfIsOpenDelegate); - - // Determines whether the delegate creation obeys security transparency rules - BOOL isDelegateCreationAllowed ( - CORINFO_CLASS_HANDLE delegateHnd, - CORINFO_METHOD_HANDLE calleeHnd); - - // ICorFieldInfo stuff - const char* getFieldName (CORINFO_FIELD_HANDLE field, - const char** scopeName); - - CORINFO_CLASS_HANDLE getFieldClass (CORINFO_FIELD_HANDLE field); - - //@GENERICSVER: added owner parameter - CorInfoType getFieldType (CORINFO_FIELD_HANDLE field, CORINFO_CLASS_HANDLE* structType,CORINFO_CLASS_HANDLE owner = NULL); - // Internal version without JIT-EE transition - CorInfoType getFieldTypeInternal (CORINFO_FIELD_HANDLE field, CORINFO_CLASS_HANDLE* structType,CORINFO_CLASS_HANDLE owner = NULL); - - unsigned getFieldOffset (CORINFO_FIELD_HANDLE field); - - bool isWriteBarrierHelperRequired(CORINFO_FIELD_HANDLE field); - - void* getFieldAddress(CORINFO_FIELD_HANDLE field, void **ppIndirection); - - // ICorDebugInfo stuff - void * allocateArray(ULONG cBytes); - void freeArray(void *array); - void getBoundaries(CORINFO_METHOD_HANDLE ftn, - unsigned int *cILOffsets, DWORD **pILOffsets, - ICorDebugInfo::BoundaryTypes *implictBoundaries); - void setBoundaries(CORINFO_METHOD_HANDLE ftn, - ULONG32 cMap, ICorDebugInfo::OffsetMapping *pMap); - void getVars(CORINFO_METHOD_HANDLE ftn, ULONG32 *cVars, - ICorDebugInfo::ILVarInfo **vars, bool *extendOthers); - void setVars(CORINFO_METHOD_HANDLE ftn, ULONG32 cVars, - ICorDebugInfo::NativeVarInfo *vars); - - // ICorArgInfo stuff - - CorInfoTypeWithMod getArgType ( - CORINFO_SIG_INFO* sig, - CORINFO_ARG_LIST_HANDLE args, - CORINFO_CLASS_HANDLE *vcTypeRet - ); - - CORINFO_CLASS_HANDLE getArgClass ( - CORINFO_SIG_INFO* sig, - CORINFO_ARG_LIST_HANDLE args - ); - - CorInfoType getHFAType ( - CORINFO_CLASS_HANDLE hClass - ); - - CORINFO_ARG_LIST_HANDLE getArgNext ( - CORINFO_ARG_LIST_HANDLE args - ); - - // ICorErrorInfo stuff - - HRESULT GetErrorHRESULT(struct _EXCEPTION_POINTERS *pExceptionPointers); - ULONG GetErrorMessage(__out_ecount(bufferLength) LPWSTR buffer, - ULONG bufferLength); - int FilterException(struct _EXCEPTION_POINTERS *pExceptionPointers); - void HandleException(struct _EXCEPTION_POINTERS *pExceptionPointers); - void ThrowExceptionForJitResult(HRESULT result); - void ThrowExceptionForHelper(const CORINFO_HELPER_DESC * throwHelper); - - // ICorStaticInfo stuff - void getEEInfo(CORINFO_EE_INFO *pEEInfoOut); - - LPCWSTR getJitTimeLogFilename(); - - //ICorDynamicInfo stuff - DWORD getFieldThreadLocalStoreID (CORINFO_FIELD_HANDLE field, void **ppIndirection); - - // Stub dispatch stuff - void getCallInfo( - CORINFO_RESOLVED_TOKEN * pResolvedToken, - CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken, - CORINFO_METHOD_HANDLE callerHandle, - CORINFO_CALLINFO_FLAGS flags, - CORINFO_CALL_INFO *pResult /*out */); - BOOL canAccessFamily(CORINFO_METHOD_HANDLE hCaller, - CORINFO_CLASS_HANDLE hInstanceType); - -protected: - - static void getEHinfoHelper( - CORINFO_METHOD_HANDLE ftnHnd, - unsigned EHnumber, - CORINFO_EH_CLAUSE* clause, - COR_ILMETHOD_DECODER* pILHeader); - - bool isVerifyOnly() - { - return m_fVerifyOnly; - } - -public: - - BOOL isRIDClassDomainID(CORINFO_CLASS_HANDLE cls); - unsigned getClassDomainID (CORINFO_CLASS_HANDLE cls, void **ppIndirection); - CORINFO_VARARGS_HANDLE getVarArgsHandle(CORINFO_SIG_INFO *sig, void **ppIndirection); - bool canGetVarArgsHandle(CORINFO_SIG_INFO *sig); - void* getPInvokeUnmanagedTarget(CORINFO_METHOD_HANDLE method, void **ppIndirection); - void* getAddressOfPInvokeFixup(CORINFO_METHOD_HANDLE method, void **ppIndirection); - void getAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP *pLookup); - CORINFO_JUST_MY_CODE_HANDLE getJustMyCodeHandle(CORINFO_METHOD_HANDLE method, CORINFO_JUST_MY_CODE_HANDLE **ppIndirection); - - void GetProfilingHandle( - BOOL *pbHookFunction, - void **pProfilerHandle, - BOOL *pbIndirectedHandles - ); - - InfoAccessType constructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok, void **ppValue); - InfoAccessType emptyStringLiteral(void ** ppValue); - void* getMethodSync(CORINFO_METHOD_HANDLE ftnHnd, void **ppIndirection); - - DWORD getThreadTLSIndex(void **ppIndirection); - const void * getInlinedCallFrameVptr(void **ppIndirection); - - // Returns the address of the domain neutral module id. This only makes sense for domain neutral (shared) - // modules - SIZE_T* getAddrModuleDomainID(CORINFO_MODULE_HANDLE module); - - LONG * getAddrOfCaptureThreadGlobal(void **ppIndirection); - void* getHelperFtn(CorInfoHelpFunc ftnNum, /* IN */ - void ** ppIndirection); /* OUT */ - - void* getTailCallCopyArgsThunk(CORINFO_SIG_INFO *pSig, - CorInfoHelperTailCallSpecialHandling flags); - - void getFunctionEntryPoint(CORINFO_METHOD_HANDLE ftn, /* IN */ - CORINFO_CONST_LOOKUP * pResult, /* OUT */ - CORINFO_ACCESS_FLAGS accessFlags = CORINFO_ACCESS_ANY); - - void getFunctionFixedEntryPoint(CORINFO_METHOD_HANDLE ftn, - CORINFO_CONST_LOOKUP * pResult); - - // get slow lazy string literal helper to use (CORINFO_HELP_STRCNS*). - // Returns CORINFO_HELP_UNDEF if lazy string literal helper cannot be used. - CorInfoHelpFunc getLazyStringLiteralHelper(CORINFO_MODULE_HANDLE handle); - - CORINFO_MODULE_HANDLE embedModuleHandle(CORINFO_MODULE_HANDLE handle, - void **ppIndirection); - CORINFO_CLASS_HANDLE embedClassHandle(CORINFO_CLASS_HANDLE handle, - void **ppIndirection); - CORINFO_FIELD_HANDLE embedFieldHandle(CORINFO_FIELD_HANDLE handle, - void **ppIndirection); - CORINFO_METHOD_HANDLE embedMethodHandle(CORINFO_METHOD_HANDLE handle, - void **ppIndirection); - - void embedGenericHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken, - BOOL fEmbedParent, - CORINFO_GENERICHANDLE_RESULT *pResult); - - CORINFO_LOOKUP_KIND getLocationOfThisType(CORINFO_METHOD_HANDLE context); - - - void setOverride(ICorDynamicInfo *pOverride, CORINFO_METHOD_HANDLE currentMethod) - { - LIMITED_METHOD_CONTRACT; - m_pOverride = pOverride; - m_pMethodBeingCompiled = (MethodDesc *)currentMethod; // method being compiled - - m_hMethodForSecurity_Key = NULL; - m_pMethodForSecurity_Value = NULL; - } - - // Returns whether we are generating code for NGen image. - BOOL IsCompilingForNGen() - { - LIMITED_METHOD_CONTRACT; - // NGen is the only place where we set the override - return this != m_pOverride; - } - - void addActiveDependency(CORINFO_MODULE_HANDLE moduleFrom, CORINFO_MODULE_HANDLE moduleTo); - CORINFO_METHOD_HANDLE GetDelegateCtor( - CORINFO_METHOD_HANDLE methHnd, - CORINFO_CLASS_HANDLE clsHnd, - CORINFO_METHOD_HANDLE targetMethodHnd, - DelegateCtorArgs * pCtorData); - - void MethodCompileComplete( - CORINFO_METHOD_HANDLE methHnd); - - // - // ICorJitInfo stuff - none of this should be called on this class - // - - IEEMemoryManager* getMemoryManager(); - - void allocMem ( - ULONG hotCodeSize, /* IN */ - ULONG coldCodeSize, /* IN */ - ULONG roDataSize, /* IN */ - ULONG xcptnsCount, /* IN */ - CorJitAllocMemFlag flag, /* IN */ - void ** hotCodeBlock, /* OUT */ - void ** coldCodeBlock, /* OUT */ - void ** roDataBlock /* OUT */ - ); - - void reserveUnwindInfo ( - BOOL isFunclet, /* IN */ - BOOL isColdCode, /* IN */ - ULONG unwindSize /* IN */ - ); - - void allocUnwindInfo ( - BYTE * pHotCode, /* IN */ - BYTE * pColdCode, /* IN */ - ULONG startOffset, /* IN */ - ULONG endOffset, /* IN */ - ULONG unwindSize, /* IN */ - BYTE * pUnwindBlock, /* IN */ - CorJitFuncKind funcKind /* IN */ - ); - - void * allocGCInfo ( - size_t size /* IN */ - ); - - void yieldExecution(); - - void setEHcount ( - unsigned cEH /* IN */ - ); - - void setEHinfo ( - unsigned EHnumber, /* IN */ - const CORINFO_EH_CLAUSE *clause /* IN */ - ); - - BOOL logMsg(unsigned level, const char* fmt, va_list args); - - int doAssert(const char* szFile, int iLine, const char* szExpr); - - void reportFatalError(CorJitResult result); - - void logSQMLongJitEvent(unsigned mcycles, unsigned msec, unsigned ilSize, unsigned numBasicBlocks, bool minOpts, - CORINFO_METHOD_HANDLE methodHnd); - - HRESULT allocBBProfileBuffer ( - ULONG count, // The number of basic blocks that we have - ProfileBuffer ** profileBuffer - ); - - HRESULT getBBProfileData( - CORINFO_METHOD_HANDLE ftnHnd, - ULONG * count, // The number of basic blocks that we have - ProfileBuffer ** profileBuffer, - ULONG * numRuns - ); - - void recordCallSite( - ULONG instrOffset, /* IN */ - CORINFO_SIG_INFO * callSig, /* IN */ - CORINFO_METHOD_HANDLE methodHandle /* IN */ - ); - - void recordRelocation( - void * location, /* IN */ - void * target, /* IN */ - WORD fRelocType, /* IN */ - WORD slotNum = 0, /* IN */ - INT32 addlDelta = 0 /* IN */ - ); - - WORD getRelocTypeHint(void * target); - - void getModuleNativeEntryPointRange( - void ** pStart, /* OUT */ - void ** pEnd /* OUT */ - ); - - DWORD getExpectedTargetArchitecture(); - - CEEInfo(MethodDesc * fd = NULL, bool fVerifyOnly = false) : - m_pOverride(NULL), - m_pMethodBeingCompiled(fd), - m_fVerifyOnly(fVerifyOnly), - m_pThread(GetThread()), - m_hMethodForSecurity_Key(NULL), - m_pMethodForSecurity_Value(NULL) - { - LIMITED_METHOD_CONTRACT; - } - - virtual ~CEEInfo() - { - LIMITED_METHOD_CONTRACT; - } - - // Performs any work JIT-related work that should be performed at process shutdown. - void JitProcessShutdownWork(); - - DWORD getJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes); - - bool runWithErrorTrap(void (*function)(void*), void* param); - -private: - // Shrinking these buffers drastically reduces the amount of stack space - // required for each instance of the interpreter, and thereby reduces SOs. -#ifdef FEATURE_INTERPRETER -#define CLS_STRING_SIZE 8 // force heap allocation -#define CLS_BUFFER_SIZE SBUFFER_PADDED_SIZE(8) -#else -#define CLS_STRING_SIZE MAX_CLASSNAME_LENGTH -#define CLS_BUFFER_SIZE MAX_CLASSNAME_LENGTH -#endif - -#ifdef _DEBUG - InlineSString<MAX_CLASSNAME_LENGTH> ssClsNameBuff; - ScratchBuffer<MAX_CLASSNAME_LENGTH> ssClsNameBuffScratch; -#endif - -public: - - //@GENERICS: - // The method handle is used to instantiate method and class type parameters - // It's also used to determine whether an extra dictionary parameter is required - static - void - ConvToJitSig( - PCCOR_SIGNATURE pSig, - DWORD cbSig, - CORINFO_MODULE_HANDLE scopeHnd, - mdToken token, - CORINFO_SIG_INFO * sigRet, - MethodDesc * context, - bool localSig, - TypeHandle owner = TypeHandle()); - - MethodDesc * GetMethodForSecurity(CORINFO_METHOD_HANDLE callerHandle); - - // Prepare the information about how to do a runtime lookup of the handle with shared - // generic variables. - void ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entryKind, - CORINFO_RESOLVED_TOKEN * pResolvedToken, - CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken /* for ConstrainedMethodEntrySlot */, - MethodDesc * pTemplateMD /* for method-based slots */, - CORINFO_LOOKUP *pResultLookup); - - static void ComputeRuntimeLookupForSharedGenericTokenStatic(DictionaryEntryKind entryKind, - CORINFO_RESOLVED_TOKEN * pResolvedToken, - CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken /* for ConstrainedMethodEntrySlot */, - MethodDesc * pTemplateMD /* for method-based slots */, - LoaderAllocator* pAllocator, - DWORD numGenericArgs, - DictionaryLayout* pDictionaryLayout, - DWORD typeDictionaryIndex, - CORINFO_LOOKUP *pResultLookup, - BOOL fEnableTypeHandleLookupOptimization, - BOOL fInstrument); - -protected: - // NGen provides its own modifications to EE-JIT interface. From technical reason it cannot simply inherit - // from code:CEEInfo class (because it has dependencies on VM that NGen does not want). - // Therefore the "normal" EE-JIT interface has code:m_pOverride hook that is set either to - // * 'this' (code:CEEInfo) at runtime, or to - // * code:ZapInfo - the NGen specific implementation of the interface. - ICorDynamicInfo * m_pOverride; - - MethodDesc* m_pMethodBeingCompiled; // Top-level method being compiled - bool m_fVerifyOnly; - Thread * m_pThread; // Cached current thread for faster JIT-EE transitions - - CORINFO_METHOD_HANDLE getMethodBeingCompiled() - { - LIMITED_METHOD_CONTRACT; - return (CORINFO_METHOD_HANDLE)m_pMethodBeingCompiled; - } - - // Cache of last GetMethodForSecurity() lookup - CORINFO_METHOD_HANDLE m_hMethodForSecurity_Key; - MethodDesc * m_pMethodForSecurity_Value; - - // Tracking of module activation dependencies. We have two flavors: - // - Fast one that gathers generic arguments from EE handles, but does not work inside generic context. - // - Slow one that operates on typespec and methodspecs from metadata. - void ScanForModuleDependencies(Module* pModule, SigPointer psig); - void ScanMethodSpec(Module * pModule, PCCOR_SIGNATURE pMethodSpec, ULONG cbMethodSpec); - // Returns true if it is ok to proceed with scan of parent chain - BOOL ScanTypeSpec(Module * pModule, PCCOR_SIGNATURE pTypeSpec, ULONG cbTypeSpec); - void ScanInstantiation(Module * pModule, Instantiation inst); - - // The main entrypoints for module activation tracking - void ScanToken(Module * pModule, CORINFO_RESOLVED_TOKEN * pResolvedToken, TypeHandle th, MethodDesc * pMD = NULL); - void ScanTokenForDynamicScope(CORINFO_RESOLVED_TOKEN * pResolvedToken, TypeHandle th, MethodDesc * pMD = NULL); -}; - - -/*********************************************************************/ - -class EEJitManager; -struct _hpCodeHdr; -typedef struct _hpCodeHdr CodeHeader; - -#ifndef CROSSGEN_COMPILE -// CEEJitInfo is the concrete implementation of callbacks that the EE must provide for the JIT to do its -// work. See code:ICorJitInfo#JitToEEInterface for more on this interface. -class CEEJitInfo : public CEEInfo -{ -public: - // ICorJitInfo stuff - - void allocMem ( - ULONG hotCodeSize, /* IN */ - ULONG coldCodeSize, /* IN */ - ULONG roDataSize, /* IN */ - ULONG xcptnsCount, /* IN */ - CorJitAllocMemFlag flag, /* IN */ - void ** hotCodeBlock, /* OUT */ - void ** coldCodeBlock, /* OUT */ - void ** roDataBlock /* OUT */ - ); - - void reserveUnwindInfo(BOOL isFunclet, BOOL isColdCode, ULONG unwindSize); - - void allocUnwindInfo ( - BYTE * pHotCode, /* IN */ - BYTE * pColdCode, /* IN */ - ULONG startOffset, /* IN */ - ULONG endOffset, /* IN */ - ULONG unwindSize, /* IN */ - BYTE * pUnwindBlock, /* IN */ - CorJitFuncKind funcKind /* IN */ - ); - - void * allocGCInfo (size_t size); - - void setEHcount (unsigned cEH); - - void setEHinfo ( - unsigned EHnumber, - const CORINFO_EH_CLAUSE* clause); - - void getEHinfo( - CORINFO_METHOD_HANDLE ftn, /* IN */ - unsigned EHnumber, /* IN */ - CORINFO_EH_CLAUSE* clause /* OUT */ - ); - - - HRESULT allocBBProfileBuffer ( - ULONG count, // The number of basic blocks that we have - ICorJitInfo::ProfileBuffer ** profileBuffer - ); - - HRESULT getBBProfileData ( - CORINFO_METHOD_HANDLE ftnHnd, - ULONG * count, // The number of basic blocks that we have - ICorJitInfo::ProfileBuffer ** profileBuffer, - ULONG * numRuns - ); - - void recordCallSite( - ULONG instrOffset, /* IN */ - CORINFO_SIG_INFO * callSig, /* IN */ - CORINFO_METHOD_HANDLE methodHandle /* IN */ - ); - - void recordRelocation( - void *location, - void *target, - WORD fRelocType, - WORD slot, - INT32 addlDelta); - - WORD getRelocTypeHint(void * target); - - void getModuleNativeEntryPointRange( - void** pStart, - void** pEnd); - - DWORD getExpectedTargetArchitecture(); - - CodeHeader* GetCodeHeader() - { - LIMITED_METHOD_CONTRACT; - return m_CodeHeader; - } - - void SetCodeHeader(CodeHeader* pValue) - { - LIMITED_METHOD_CONTRACT; - m_CodeHeader = pValue; - } - - void ResetForJitRetry() - { - CONTRACTL { - SO_TOLERANT; - NOTHROW; - GC_NOTRIGGER; - } CONTRACTL_END; - - m_CodeHeader = NULL; - - if (m_pOffsetMapping != NULL) - delete [] ((BYTE*) m_pOffsetMapping); - - if (m_pNativeVarInfo != NULL) - delete [] ((BYTE*) m_pNativeVarInfo); - - m_iOffsetMapping = 0; - m_pOffsetMapping = NULL; - m_iNativeVarInfo = 0; - m_pNativeVarInfo = NULL; - -#ifdef WIN64EXCEPTIONS - m_moduleBase = NULL; - m_totalUnwindSize = 0; - m_usedUnwindSize = 0; - m_theUnwindBlock = NULL; - m_totalUnwindInfos = 0; - m_usedUnwindInfos = 0; -#endif // WIN64EXCEPTIONS - } - -#ifdef _TARGET_AMD64_ - void SetAllowRel32(BOOL fAllowRel32) - { - LIMITED_METHOD_CONTRACT; - m_fAllowRel32 = fAllowRel32; - } - - void SetRel32Overflow(BOOL fRel32Overflow) - { - LIMITED_METHOD_CONTRACT; - m_fRel32Overflow = fRel32Overflow; - } - - BOOL IsRel32Overflow() - { - LIMITED_METHOD_CONTRACT; - return m_fRel32Overflow; - } - - BOOL JitAgain() - { - LIMITED_METHOD_CONTRACT; - return m_fRel32Overflow; - } -#else - BOOL JitAgain() - { - LIMITED_METHOD_CONTRACT; - return FALSE; - } -#endif - - CEEJitInfo(MethodDesc* fd, COR_ILMETHOD_DECODER* header, - EEJitManager* jm, bool fVerifyOnly) - : CEEInfo(fd, fVerifyOnly), - m_jitManager(jm), - m_CodeHeader(NULL), - m_ILHeader(header), -#ifdef WIN64EXCEPTIONS - m_moduleBase(NULL), - m_totalUnwindSize(0), - m_usedUnwindSize(0), - m_theUnwindBlock(NULL), - m_totalUnwindInfos(0), - m_usedUnwindInfos(0), -#endif -#ifdef _TARGET_AMD64_ - m_fAllowRel32(FALSE), - m_fRel32Overflow(FALSE), -#endif - m_GCinfo_len(0), - m_EHinfo_len(0), - m_iOffsetMapping(0), - m_pOffsetMapping(NULL), - m_iNativeVarInfo(0), - m_pNativeVarInfo(NULL), - m_gphCache() - { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } CONTRACTL_END; - - m_pOverride = this; - } - - ~CEEJitInfo() - { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } CONTRACTL_END; - - if (m_pOffsetMapping != NULL) - delete [] ((BYTE*) m_pOffsetMapping); - - if (m_pNativeVarInfo != NULL) - delete [] ((BYTE*) m_pNativeVarInfo); - } - - // ICorDebugInfo stuff. - void setBoundaries(CORINFO_METHOD_HANDLE ftn, - ULONG32 cMap, ICorDebugInfo::OffsetMapping *pMap); - void setVars(CORINFO_METHOD_HANDLE ftn, ULONG32 cVars, - ICorDebugInfo::NativeVarInfo *vars); - void CompressDebugInfo(); - - void* getHelperFtn(CorInfoHelpFunc ftnNum, /* IN */ - void ** ppIndirection); /* OUT */ - static PCODE getHelperFtnStatic(CorInfoHelpFunc ftnNum); - - // Override active dependency to talk to loader - void addActiveDependency(CORINFO_MODULE_HANDLE moduleFrom, CORINFO_MODULE_HANDLE moduleTo); - - // Override of CEEInfo::GetProfilingHandle. The first time this is called for a - // method desc, it calls through to CEEInfo::GetProfilingHandle and caches the - // result in CEEJitInfo::GetProfilingHandleCache. Thereafter, this wrapper regurgitates the cached values - // rather than calling into CEEInfo::GetProfilingHandle each time. This avoids - // making duplicate calls into the profiler's FunctionIDMapper callback. - void GetProfilingHandle( - BOOL *pbHookFunction, - void **pProfilerHandle, - BOOL *pbIndirectedHandles - ); - - InfoAccessType constructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok, void **ppValue); - InfoAccessType emptyStringLiteral(void ** ppValue); - void* getFieldAddress(CORINFO_FIELD_HANDLE field, void **ppIndirection); - void* getMethodSync(CORINFO_METHOD_HANDLE ftnHnd, void **ppIndirection); - - void BackoutJitData(EEJitManager * jitMgr); - -protected : - EEJitManager* m_jitManager; // responsible for allocating memory - CodeHeader* m_CodeHeader; // descriptor for JITTED code - COR_ILMETHOD_DECODER * m_ILHeader; // the code header as exist in the file -#ifdef WIN64EXCEPTIONS - TADDR m_moduleBase; // Base for unwind Infos - ULONG m_totalUnwindSize; // Total reserved unwind space - ULONG m_usedUnwindSize; // used space in m_theUnwindBlock - BYTE * m_theUnwindBlock; // start of the unwind memory block - ULONG m_totalUnwindInfos; // Number of RUNTIME_FUNCTION needed - ULONG m_usedUnwindInfos; -#endif - -#ifdef _TARGET_AMD64_ - BOOL m_fAllowRel32; // Use 32-bit PC relative address modes - BOOL m_fRel32Overflow; // Overflow while trying to use encode 32-bit PC relative address. - // The code will need to be regenerated with m_fRel32Allowed == FALSE. -#endif - -#if defined(_DEBUG) - ULONG m_codeSize; // Code size requested via allocMem -#endif - - size_t m_GCinfo_len; // Cached copy of GCinfo_len so we can backout in BackoutJitData() - size_t m_EHinfo_len; // Cached copy of EHinfo_len so we can backout in BackoutJitData() - - ULONG32 m_iOffsetMapping; - ICorDebugInfo::OffsetMapping * m_pOffsetMapping; - - ULONG32 m_iNativeVarInfo; - ICorDebugInfo::NativeVarInfo * m_pNativeVarInfo; - - // The first time a call is made to CEEJitInfo::GetProfilingHandle() from this thread - // for this method, these values are filled in. Thereafter, these values are used - // in lieu of calling into the base CEEInfo::GetProfilingHandle() again. This protects the - // profiler from duplicate calls to its FunctionIDMapper() callback. - struct GetProfilingHandleCache - { - GetProfilingHandleCache() : - m_bGphIsCacheValid(false), - m_bGphHookFunction(false), - m_pvGphProfilerHandle(NULL) - { - LIMITED_METHOD_CONTRACT; - } - - bool m_bGphIsCacheValid : 1; // Tells us whether below values are valid - bool m_bGphHookFunction : 1; - void* m_pvGphProfilerHandle; - } m_gphCache; - - -}; -#endif // CROSSGEN_COMPILE - -/*********************************************************************/ -/*********************************************************************/ - -typedef struct { - void * pfnHelper; -#ifdef _DEBUG - const char* name; -#endif -} VMHELPDEF; - -#if defined(DACCESS_COMPILE) - -GARY_DECL(VMHELPDEF, hlpFuncTable, CORINFO_HELP_COUNT); - -#else - -extern "C" const VMHELPDEF hlpFuncTable[CORINFO_HELP_COUNT]; - -#endif - -#if defined(_DEBUG) && (defined(_TARGET_AMD64_) || defined(_TARGET_X86_)) && !defined(FEATURE_PAL) -typedef struct { - void* pfnRealHelper; - const char* helperName; - LONG count; - LONG helperSize; -} VMHELPCOUNTDEF; - -extern "C" VMHELPCOUNTDEF hlpFuncCountTable[CORINFO_HELP_COUNT+1]; - -void InitJitHelperLogging(); -void WriteJitHelperCountToSTRESSLOG(); -#else -inline void InitJitHelperLogging() { } -inline void WriteJitHelperCountToSTRESSLOG() { } -#endif - -// enum for dynamically assigned helper calls -enum DynamicCorInfoHelpFunc { -#define JITHELPER(code, pfnHelper, sig) -#define DYNAMICJITHELPER(code, pfnHelper, sig) DYNAMIC_##code, -#include "jithelpers.h" - DYNAMIC_CORINFO_HELP_COUNT -}; - -#ifdef _MSC_VER -// GCC complains about duplicate "extern". And it is not needed for the GCC build -extern "C" -#endif -GARY_DECL(VMHELPDEF, hlpDynamicFuncTable, DYNAMIC_CORINFO_HELP_COUNT); - -#define SetJitHelperFunction(ftnNum, pFunc) _SetJitHelperFunction(DYNAMIC_##ftnNum, (void*)(pFunc)) -void _SetJitHelperFunction(DynamicCorInfoHelpFunc ftnNum, void * pFunc); -#ifdef ENABLE_FAST_GCPOLL_HELPER -//These should only be called from ThreadStore::TrapReturningThreads! - -//Called when the VM wants to suspend one or more threads. -void EnableJitGCPoll(); -//Called when there are no threads to suspend. -void DisableJitGCPoll(); -#endif - -// Helper for RtlVirtualUnwind-based tail calls -#if defined(_TARGET_AMD64_) || defined(_TARGET_ARM_) - -// The Stub-linker generated assembly routine to copy arguments from the va_list -// into the CONTEXT and the stack. -// -typedef size_t (*pfnCopyArgs)(va_list, _CONTEXT *, DWORD_PTR *, size_t); - -// Forward declaration from Frames.h -class TailCallFrame; - -// The shared stub return location -EXTERN_C void JIT_TailCallHelperStub_ReturnAddress(); - -#endif // _TARGET_AMD64_ || _TARGET_ARM_ - - -#ifdef _TARGET_X86_ - -class JIT_TrialAlloc -{ -public: - enum Flags - { - NORMAL = 0x0, - MP_ALLOCATOR = 0x1, - SIZE_IN_EAX = 0x2, - OBJ_ARRAY = 0x4, - ALIGN8 = 0x8, // insert a dummy object to insure 8 byte alignment (until the next GC) - ALIGN8OBJ = 0x10, - NO_FRAME = 0x20, // call is from unmanaged code - don't try to put up a frame - }; - - static void *GenAllocSFast(Flags flags); - static void *GenBox(Flags flags); - static void *GenAllocArray(Flags flags); - static void *GenAllocString(Flags flags); - -private: - static void EmitAlignmentRoundup(CPUSTUBLINKER *psl,X86Reg regTestAlign, X86Reg regToAdj, Flags flags); - static void EmitDummyObject(CPUSTUBLINKER *psl, X86Reg regTestAlign, Flags flags); - static void EmitCore(CPUSTUBLINKER *psl, CodeLabel *noLock, CodeLabel *noAlloc, Flags flags); - static void EmitNoAllocCode(CPUSTUBLINKER *psl, Flags flags); - -#if CHECK_APP_DOMAIN_LEAKS - static void EmitSetAppDomain(CPUSTUBLINKER *psl); - static void EmitCheckRestore(CPUSTUBLINKER *psl); -#endif -}; -#endif // _TARGET_X86_ - -void *GenFastGetSharedStaticBase(bool bCheckCCtor); - -#ifdef HAVE_GCCOVER -void SetupGcCoverage(MethodDesc* pMD, BYTE* nativeCode); -void SetupGcCoverageForNativeImage(Module* module); -bool IsGcCoverageInterrupt(LPVOID ip); -BOOL OnGcCoverageInterrupt(PT_CONTEXT regs); -void DoGcStress (PT_CONTEXT regs, MethodDesc *pMD); -#endif //HAVE_GCCOVER - -EXTERN_C FCDECL2(LPVOID, ArrayStoreCheck, Object** pElement, PtrArray** pArray); - -OBJECTHANDLE ConstructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok); - -FCDECL2(Object*, JIT_Box, CORINFO_CLASS_HANDLE type, void* data); -FCDECL0(VOID, JIT_PollGC); -#ifdef ENABLE_FAST_GCPOLL_HELPER -EXTERN_C FCDECL0(VOID, JIT_PollGC_Nop); -#endif - -BOOL ObjIsInstanceOf(Object *pObject, TypeHandle toTypeHnd, BOOL throwCastException = FALSE); -EXTERN_C TypeHandle::CastResult STDCALL ObjIsInstanceOfNoGC(Object *pObject, TypeHandle toTypeHnd); - -#ifdef _WIN64 -class InlinedCallFrame; -Thread * __stdcall JIT_InitPInvokeFrame(InlinedCallFrame *pFrame, PTR_VOID StubSecretArg); -#endif - -#ifdef _DEBUG -extern LONG g_JitCount; -#endif - -struct VirtualFunctionPointerArgs -{ - CORINFO_CLASS_HANDLE classHnd; - CORINFO_METHOD_HANDLE methodHnd; -}; - -FCDECL2(CORINFO_MethodPtr, JIT_VirtualFunctionPointer_Dynamic, Object * objectUNSAFE, VirtualFunctionPointerArgs * pArgs); - -typedef TADDR (F_CALL_CONV * FnStaticBaseHelper)(TADDR arg0, TADDR arg1); - -struct StaticFieldAddressArgs -{ - FnStaticBaseHelper staticBaseHelper; - TADDR arg0; - TADDR arg1; - SIZE_T offset; -}; - -FCDECL1(TADDR, JIT_StaticFieldAddress_Dynamic, StaticFieldAddressArgs * pArgs); -FCDECL1(TADDR, JIT_StaticFieldAddressUnbox_Dynamic, StaticFieldAddressArgs * pArgs); - -CORINFO_GENERIC_HANDLE JIT_GenericHandleWorker(MethodDesc *pMD, - MethodTable *pMT, - LPVOID signature); - -void ClearJitGenericHandleCache(AppDomain *pDomain); - -class JitHelpers { -public: - static FCDECL3(void, UnsafeSetArrayElement, PtrArray* pPtrArray, INT32 index, Object* object); -}; - -DWORD GetDebuggerCompileFlags(Module* pModule, DWORD flags); - -bool TrackAllocationsEnabled(); - -#endif // JITINTERFACE_H +// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+// ===========================================================================
+// File: JITinterface.H
+//
+
+// ===========================================================================
+
+
+#ifndef JITINTERFACE_H
+#define JITINTERFACE_H
+
+#include "corjit.h"
+#ifdef FEATURE_PREJIT
+#include "corcompile.h"
+#endif // FEATURE_PREJIT
+
+#ifndef FEATURE_PAL
+#define MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT ((32*1024)-1) // when generating JIT code
+#else // !FEATURE_PAL
+#define MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT ((OS_PAGE_SIZE / 2) - 1)
+#endif // !FEATURE_PAL
+
+class Stub;
+class MethodDesc;
+class FieldDesc;
+enum RuntimeExceptionKind;
+class AwareLock;
+class PtrArray;
+
+#include "genericdict.h"
+
+inline FieldDesc* GetField(CORINFO_FIELD_HANDLE fieldHandle)
+{
+ LIMITED_METHOD_CONTRACT;
+ return (FieldDesc*) fieldHandle;
+}
+
+inline
+bool SigInfoFlagsAreValid (CORINFO_SIG_INFO *sig)
+{
+ LIMITED_METHOD_CONTRACT;
+ return !(sig->flags & ~( CORINFO_SIGFLAG_IS_LOCAL_SIG
+ | CORINFO_SIGFLAG_IL_STUB
+ ));
+}
+
+
+void InitJITHelpers1();
+void InitJITHelpers2();
+
+PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* header,
+ DWORD flags, DWORD flags2, ULONG* sizeOfCode = NULL);
+
+void getMethodInfoHelper(MethodDesc * ftn,
+ CORINFO_METHOD_HANDLE ftnHnd,
+ COR_ILMETHOD_DECODER * header,
+ CORINFO_METHOD_INFO * methInfo);
+
+void getMethodInfoILMethodHeaderHelper(
+ COR_ILMETHOD_DECODER* header,
+ CORINFO_METHOD_INFO* methInfo
+ );
+
+
+#ifdef FEATURE_PREJIT
+BOOL LoadDynamicInfoEntry(Module *currentModule,
+ RVA fixupRva,
+ SIZE_T *entry);
+#endif // FEATURE_PREJIT
+
+//
+// The legacy x86 monitor helpers do not need a state argument
+//
+#if !defined(_TARGET_X86_)
+
+#define FCDECL_MONHELPER(funcname, arg) FCDECL2(void, funcname, arg, BYTE* pbLockTaken)
+#define HCIMPL_MONHELPER(funcname, arg) HCIMPL2(void, funcname, arg, BYTE* pbLockTaken)
+#define MONHELPER_STATE(x) x
+#define MONHELPER_ARG pbLockTaken
+
+#else
+
+#define FCDECL_MONHELPER(funcname, arg) FCDECL1(void, funcname, arg)
+#define HCIMPL_MONHELPER(funcname, arg) HCIMPL1(void, funcname, arg)
+#define MONHELPER_STATE(x)
+#define MONHELPER_ARG NULL
+
+#endif // _TARGET_X86_
+
+
+//
+// JIT HELPER ALIASING FOR PORTABILITY.
+//
+// The portable helper is used if the platform does not provide optimized implementation.
+//
+
+#ifndef JIT_MonEnter
+#define JIT_MonEnter JIT_MonEnter_Portable
+#endif
+EXTERN_C FCDECL1(void, JIT_MonEnter, Object *obj);
+EXTERN_C FCDECL1(void, JIT_MonEnter_Portable, Object *obj);
+
+#ifndef JIT_MonEnterWorker
+#define JIT_MonEnterWorker JIT_MonEnterWorker_Portable
+#endif
+EXTERN_C FCDECL_MONHELPER(JIT_MonEnterWorker, Object *obj);
+EXTERN_C FCDECL_MONHELPER(JIT_MonEnterWorker_Portable, Object *obj);
+
+#ifndef JIT_MonReliableEnter
+#define JIT_MonReliableEnter JIT_MonReliableEnter_Portable
+#endif
+EXTERN_C FCDECL2(void, JIT_MonReliableEnter, Object* obj, BYTE *tookLock);
+EXTERN_C FCDECL2(void, JIT_MonReliableEnter_Portable, Object* obj, BYTE *tookLock);
+
+#ifndef JIT_MonTryEnter
+#define JIT_MonTryEnter JIT_MonTryEnter_Portable
+#endif
+EXTERN_C FCDECL3(void, JIT_MonTryEnter, Object *obj, INT32 timeout, BYTE* pbLockTaken);
+EXTERN_C FCDECL3(void, JIT_MonTryEnter_Portable, Object *obj, INT32 timeout, BYTE* pbLockTaken);
+
+#ifndef JIT_MonExit
+#define JIT_MonExit JIT_MonExit_Portable
+#endif
+EXTERN_C FCDECL1(void, JIT_MonExit, Object *obj);
+EXTERN_C FCDECL1(void, JIT_MonExit_Portable, Object *obj);
+
+#ifndef JIT_MonExitWorker
+#define JIT_MonExitWorker JIT_MonExitWorker_Portable
+#endif
+EXTERN_C FCDECL_MONHELPER(JIT_MonExitWorker, Object *obj);
+EXTERN_C FCDECL_MONHELPER(JIT_MonExitWorker_Portable, Object *obj);
+
+#ifndef JIT_MonEnterStatic
+#define JIT_MonEnterStatic JIT_MonEnterStatic_Portable
+#endif
+EXTERN_C FCDECL_MONHELPER(JIT_MonEnterStatic, AwareLock *lock);
+EXTERN_C FCDECL_MONHELPER(JIT_MonEnterStatic_Portable, AwareLock *lock);
+
+#ifndef JIT_MonExitStatic
+#define JIT_MonExitStatic JIT_MonExitStatic_Portable
+#endif
+EXTERN_C FCDECL_MONHELPER(JIT_MonExitStatic, AwareLock *lock);
+EXTERN_C FCDECL_MONHELPER(JIT_MonExitStatic_Portable, AwareLock *lock);
+
+
+#ifndef JIT_GetSharedGCStaticBase
+#define JIT_GetSharedGCStaticBase JIT_GetSharedGCStaticBase_Portable
+#endif
+EXTERN_C FCDECL2(void*, JIT_GetSharedGCStaticBase, SIZE_T moduleDomainID, DWORD dwModuleClassID);
+EXTERN_C FCDECL2(void*, JIT_GetSharedGCStaticBase_Portable, SIZE_T moduleDomainID, DWORD dwModuleClassID);
+
+#ifndef JIT_GetSharedNonGCStaticBase
+#define JIT_GetSharedNonGCStaticBase JIT_GetSharedNonGCStaticBase_Portable
+#endif
+EXTERN_C FCDECL2(void*, JIT_GetSharedNonGCStaticBase, SIZE_T moduleDomainID, DWORD dwModuleClassID);
+EXTERN_C FCDECL2(void*, JIT_GetSharedNonGCStaticBase_Portable, SIZE_T moduleDomainID, DWORD dwModuleClassID);
+
+#ifndef JIT_GetSharedGCStaticBaseNoCtor
+#define JIT_GetSharedGCStaticBaseNoCtor JIT_GetSharedGCStaticBaseNoCtor_Portable
+#endif
+EXTERN_C FCDECL1(void*, JIT_GetSharedGCStaticBaseNoCtor, SIZE_T moduleDomainID);
+EXTERN_C FCDECL1(void*, JIT_GetSharedGCStaticBaseNoCtor_Portable, SIZE_T moduleDomainID);
+
+#ifndef JIT_GetSharedNonGCStaticBaseNoCtor
+#define JIT_GetSharedNonGCStaticBaseNoCtor JIT_GetSharedNonGCStaticBaseNoCtor_Portable
+#endif
+EXTERN_C FCDECL1(void*, JIT_GetSharedNonGCStaticBaseNoCtor, SIZE_T moduleDomainID);
+EXTERN_C FCDECL1(void*, JIT_GetSharedNonGCStaticBaseNoCtor_Portable, SIZE_T moduleDomainID);
+
+#ifndef JIT_ChkCastClass
+#define JIT_ChkCastClass JIT_ChkCastClass_Portable
+#endif
+EXTERN_C FCDECL2(Object*, JIT_ChkCastClass, MethodTable* pMT, Object* pObject);
+EXTERN_C FCDECL2(Object*, JIT_ChkCastClass_Portable, MethodTable* pMT, Object* pObject);
+
+#ifndef JIT_ChkCastClassSpecial
+#define JIT_ChkCastClassSpecial JIT_ChkCastClassSpecial_Portable
+#endif
+EXTERN_C FCDECL2(Object*, JIT_ChkCastClassSpecial, MethodTable* pMT, Object* pObject);
+EXTERN_C FCDECL2(Object*, JIT_ChkCastClassSpecial_Portable, MethodTable* pMT, Object* pObject);
+
+#ifndef JIT_IsInstanceOfClass
+#define JIT_IsInstanceOfClass JIT_IsInstanceOfClass_Portable
+#endif
+EXTERN_C FCDECL2(Object*, JIT_IsInstanceOfClass, MethodTable* pMT, Object* pObject);
+EXTERN_C FCDECL2(Object*, JIT_IsInstanceOfClass_Portable, MethodTable* pMT, Object* pObject);
+
+#ifndef JIT_ChkCastInterface
+#define JIT_ChkCastInterface JIT_ChkCastInterface_Portable
+#endif
+EXTERN_C FCDECL2(Object*, JIT_ChkCastInterface, MethodTable* pMT, Object* pObject);
+EXTERN_C FCDECL2(Object*, JIT_ChkCastInterface_Portable, MethodTable* pMT, Object* pObject);
+
+#ifndef JIT_IsInstanceOfInterface
+#define JIT_IsInstanceOfInterface JIT_IsInstanceOfInterface_Portable
+#endif
+EXTERN_C FCDECL2(Object*, JIT_IsInstanceOfInterface, MethodTable* pMT, Object* pObject);
+EXTERN_C FCDECL2(Object*, JIT_IsInstanceOfInterface_Portable, MethodTable* pMT, Object* pObject);
+
+extern FCDECL1(Object*, JIT_NewS_MP_FastPortable, CORINFO_CLASS_HANDLE typeHnd_);
+extern FCDECL1(Object*, JIT_New, CORINFO_CLASS_HANDLE typeHnd_);
+
+#ifndef JIT_NewCrossContext
+#define JIT_NewCrossContext JIT_NewCrossContext_Portable
+#endif
+EXTERN_C FCDECL1(Object*, JIT_NewCrossContext, CORINFO_CLASS_HANDLE typeHnd_);
+EXTERN_C FCDECL1(Object*, JIT_NewCrossContext_Portable, CORINFO_CLASS_HANDLE typeHnd_);
+
+extern FCDECL1(StringObject*, AllocateString_MP_FastPortable, DWORD stringLength);
+extern FCDECL1(StringObject*, UnframedAllocateString, DWORD stringLength);
+extern FCDECL1(StringObject*, FramedAllocateString, DWORD stringLength);
+
+extern FCDECL2(Object*, JIT_NewArr1VC_MP_FastPortable, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size);
+extern FCDECL2(Object*, JIT_NewArr1OBJ_MP_FastPortable, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size);
+extern FCDECL2(Object*, JIT_NewArr1, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size);
+
+#ifndef JIT_Stelem_Ref
+#define JIT_Stelem_Ref JIT_Stelem_Ref_Portable
+#endif
+EXTERN_C FCDECL3(void, JIT_Stelem_Ref, PtrArray* array, unsigned idx, Object* val);
+EXTERN_C FCDECL3(void, JIT_Stelem_Ref_Portable, PtrArray* array, unsigned idx, Object* val);
+
+EXTERN_C FCDECL_MONHELPER(JITutil_MonEnterWorker, Object* obj);
+EXTERN_C FCDECL2(void, JITutil_MonReliableEnter, Object* obj, BYTE* pbLockTaken);
+EXTERN_C FCDECL3(void, JITutil_MonTryEnter, Object* obj, INT32 timeOut, BYTE* pbLockTaken);
+EXTERN_C FCDECL_MONHELPER(JITutil_MonExitWorker, Object* obj);
+EXTERN_C FCDECL_MONHELPER(JITutil_MonSignal, AwareLock* lock);
+EXTERN_C FCDECL_MONHELPER(JITutil_MonContention, AwareLock* awarelock);
+EXTERN_C FCDECL2(void, JITutil_MonReliableContention, AwareLock* awarelock, BYTE* pbLockTaken);
+
+// Slow versions to tail call if the fast version fails
+EXTERN_C FCDECL2(void*, JIT_GetSharedNonGCStaticBase_Helper, DomainLocalModule *pLocalModule, DWORD dwClassDomainID);
+EXTERN_C FCDECL2(void*, JIT_GetSharedGCStaticBase_Helper, DomainLocalModule *pLocalModule, DWORD dwClassDomainID);
+
+EXTERN_C void DoJITFailFast ();
+EXTERN_C FCDECL0(void, JIT_FailFast);
+extern FCDECL3(void, JIT_ThrowAccessException, RuntimeExceptionKind, CORINFO_METHOD_HANDLE caller, void * callee);
+
+FCDECL1(void*, JIT_SafeReturnableByref, void* byref);
+
+#if !defined(FEATURE_USE_ASM_GC_WRITE_BARRIERS) && defined(FEATURE_COUNT_GC_WRITE_BARRIERS)
+// Extra argument for the classification of the checked barriers.
+extern "C" FCDECL3(VOID, JIT_CheckedWriteBarrier, Object **dst, Object *ref, CheckedWriteBarrierKinds kind);
+#else
+// Regular checked write barrier.
+extern "C" FCDECL2(VOID, JIT_CheckedWriteBarrier, Object **dst, Object *ref);
+#endif
+
+extern "C" FCDECL2(VOID, JIT_WriteBarrier, Object **dst, Object *ref);
+
+extern "C" FCDECL2(VOID, JIT_WriteBarrierEnsureNonHeapTarget, Object **dst, Object *ref);
+
+extern "C" FCDECL2(Object*, JIT_ChkCastAny, CORINFO_CLASS_HANDLE type, Object *pObject); // JITInterfaceX86.cpp, etc.
+extern "C" FCDECL2(Object*, JIT_IsInstanceOfAny, CORINFO_CLASS_HANDLE type, Object *pObject);
+
+extern "C" FCDECL2(Object*, JITutil_ChkCastInterface, MethodTable *pInterfaceMT, Object *obj);
+extern "C" FCDECL2(Object*, JITutil_IsInstanceOfInterface, MethodTable *pInterfaceMT, Object *obj);
+extern "C" FCDECL2(Object*, JITutil_ChkCastAny, CORINFO_CLASS_HANDLE type, Object *obj);
+extern "C" FCDECL2(Object*, JITutil_IsInstanceOfAny, CORINFO_CLASS_HANDLE type, Object *obj);
+
+extern "C" FCDECL1(void, JIT_InternalThrow, unsigned exceptNum);
+extern "C" FCDECL1(void*, JIT_InternalThrowFromHelper, unsigned exceptNum);
+
+#ifdef _TARGET_AMD64_
+
+
+class WriteBarrierManager
+{
+public:
+ enum WriteBarrierType
+ {
+ WRITE_BARRIER_UNINITIALIZED,
+ WRITE_BARRIER_PREGROW64,
+ WRITE_BARRIER_POSTGROW64,
+#ifdef FEATURE_SVR_GC
+ WRITE_BARRIER_SVR64,
+#endif // FEATURE_SVR_GC
+#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
+ WRITE_BARRIER_WRITE_WATCH_PREGROW64,
+ WRITE_BARRIER_WRITE_WATCH_POSTGROW64,
+#ifdef FEATURE_SVR_GC
+ WRITE_BARRIER_WRITE_WATCH_SVR64,
+#endif // FEATURE_SVR_GC
+#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
+ WRITE_BARRIER_BUFFER
+ };
+
+ WriteBarrierManager();
+ void Initialize();
+
+ void UpdateEphemeralBounds(bool isRuntimeSuspended);
+ void UpdateWriteWatchAndCardTableLocations(bool isRuntimeSuspended, bool bReqUpperBoundsCheck);
+
+#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
+ void SwitchToWriteWatchBarrier(bool isRuntimeSuspended);
+ void SwitchToNonWriteWatchBarrier(bool isRuntimeSuspended);
+#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
+
+protected:
+ size_t GetCurrentWriteBarrierSize();
+ size_t GetSpecificWriteBarrierSize(WriteBarrierType writeBarrier);
+ PBYTE CalculatePatchLocation(LPVOID base, LPVOID label, int offset);
+ PCODE GetCurrentWriteBarrierCode();
+ void ChangeWriteBarrierTo(WriteBarrierType newWriteBarrier, bool isRuntimeSuspended);
+ bool NeedDifferentWriteBarrier(bool bReqUpperBoundsCheck, WriteBarrierType* pNewWriteBarrierType);
+
+private:
+ void Validate();
+
+ WriteBarrierType m_currentWriteBarrier;
+
+ PBYTE m_pWriteWatchTableImmediate; // PREGROW | POSTGROW | SVR | WRITE_WATCH |
+ PBYTE m_pLowerBoundImmediate; // PREGROW | POSTGROW | | WRITE_WATCH |
+ PBYTE m_pCardTableImmediate; // PREGROW | POSTGROW | SVR | WRITE_WATCH |
+ PBYTE m_pUpperBoundImmediate; // | POSTGROW | | WRITE_WATCH |
+};
+
+#endif // _TARGET_AMD64_
+
+#ifdef _WIN64
+EXTERN_C FCDECL1(Object*, JIT_TrialAllocSFastMP_InlineGetThread, CORINFO_CLASS_HANDLE typeHnd_);
+EXTERN_C FCDECL2(Object*, JIT_BoxFastMP_InlineGetThread, CORINFO_CLASS_HANDLE type, void* data);
+EXTERN_C FCDECL2(Object*, JIT_NewArr1VC_MP_InlineGetThread, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size);
+EXTERN_C FCDECL2(Object*, JIT_NewArr1OBJ_MP_InlineGetThread, CORINFO_CLASS_HANDLE typeHnd_, INT_PTR size);
+
+#endif // _WIN64
+
+EXTERN_C FCDECL2_VV(INT64, JIT_LMul, INT64 val1, INT64 val2);
+
+EXTERN_C FCDECL1_V(INT64, JIT_Dbl2Lng, double val);
+EXTERN_C FCDECL1_V(INT64, JIT_Dbl2IntSSE2, double val);
+EXTERN_C FCDECL1_V(INT64, JIT_Dbl2LngP4x87, double val);
+EXTERN_C FCDECL1_V(INT64, JIT_Dbl2LngSSE3, double val);
+EXTERN_C FCDECL1_V(INT64, JIT_Dbl2LngOvf, double val);
+
+EXTERN_C FCDECL1_V(INT32, JIT_Dbl2IntOvf, double val);
+
+EXTERN_C FCDECL2_VV(float, JIT_FltRem, float dividend, float divisor);
+EXTERN_C FCDECL2_VV(double, JIT_DblRem, double dividend, double divisor);
+
+#if !defined(_WIN64) && !defined(_TARGET_X86_)
+EXTERN_C FCDECL2_VV(UINT64, JIT_LLsh, UINT64 num, int shift);
+EXTERN_C FCDECL2_VV(INT64, JIT_LRsh, INT64 num, int shift);
+EXTERN_C FCDECL2_VV(UINT64, JIT_LRsz, UINT64 num, int shift);
+#endif
+
+#ifdef _TARGET_X86_
+
+extern "C"
+{
+ void STDCALL JIT_LLsh(); // JIThelp.asm
+ void STDCALL JIT_LRsh(); // JIThelp.asm
+ void STDCALL JIT_LRsz(); // JIThelp.asm
+
+ void STDCALL JIT_CheckedWriteBarrierEAX(); // JIThelp.asm/JIThelp.s
+ void STDCALL JIT_CheckedWriteBarrierEBX(); // JIThelp.asm/JIThelp.s
+ void STDCALL JIT_CheckedWriteBarrierECX(); // JIThelp.asm/JIThelp.s
+ void STDCALL JIT_CheckedWriteBarrierESI(); // JIThelp.asm/JIThelp.s
+ void STDCALL JIT_CheckedWriteBarrierEDI(); // JIThelp.asm/JIThelp.s
+ void STDCALL JIT_CheckedWriteBarrierEBP(); // JIThelp.asm/JIThelp.s
+
+ void STDCALL JIT_DebugWriteBarrierEAX(); // JIThelp.asm/JIThelp.s
+ void STDCALL JIT_DebugWriteBarrierEBX(); // JIThelp.asm/JIThelp.s
+ void STDCALL JIT_DebugWriteBarrierECX(); // JIThelp.asm/JIThelp.s
+ void STDCALL JIT_DebugWriteBarrierESI(); // JIThelp.asm/JIThelp.s
+ void STDCALL JIT_DebugWriteBarrierEDI(); // JIThelp.asm/JIThelp.s
+ void STDCALL JIT_DebugWriteBarrierEBP(); // JIThelp.asm/JIThelp.s
+
+ void STDCALL JIT_WriteBarrierEAX(); // JIThelp.asm/JIThelp.s
+ void STDCALL JIT_WriteBarrierEBX(); // JIThelp.asm/JIThelp.s
+ void STDCALL JIT_WriteBarrierECX(); // JIThelp.asm/JIThelp.s
+ void STDCALL JIT_WriteBarrierESI(); // JIThelp.asm/JIThelp.s
+ void STDCALL JIT_WriteBarrierEDI(); // JIThelp.asm/JIThelp.s
+ void STDCALL JIT_WriteBarrierEBP(); // JIThelp.asm/JIThelp.s
+
+ void STDCALL JIT_WriteBarrierStart();
+ void STDCALL JIT_WriteBarrierLast();
+
+ void STDCALL JIT_PatchedWriteBarrierStart();
+ void STDCALL JIT_PatchedWriteBarrierLast();
+}
+
+void ValidateWriteBarrierHelpers();
+
+#endif //_TARGET_X86_
+
+extern "C"
+{
+ void STDCALL JIT_EndCatch(); // JIThelp.asm/JIThelp.s
+
+ void STDCALL JIT_ByRefWriteBarrier(); // JIThelp.asm/JIThelp.s
+
+#if defined(_TARGET_AMD64_) || defined(_TARGET_ARM_)
+
+ FCDECL2VA(void, JIT_TailCall, PCODE copyArgs, PCODE target);
+
+#else // _TARGET_AMD64_ || _TARGET_ARM_
+
+ void STDCALL JIT_TailCall(); // JIThelp.asm
+
+#endif // _TARGET_AMD64_ || _TARGET_ARM_
+
+ void STDCALL JIT_MemSet(void *dest, int c, SIZE_T count);
+ void STDCALL JIT_MemCpy(void *dest, const void *src, SIZE_T count);
+
+ void STDCALL JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle);
+};
+
+#ifndef FEATURE_CORECLR
+//
+// Obfluscators that are hacking into the JIT expect certain methods to exist in certain places of CEEInfo vtable. Add artifical slots
+// to the vtable to avoid breaking apps by .NET 4.5 in-place update.
+//
+
+class ICorMethodInfo_Hack
+{
+public:
+ virtual const char* __stdcall ICorMethodInfo_Hack_getMethodName (CORINFO_METHOD_HANDLE ftnHnd, const char** scopeName) = 0;
+};
+
+class ICorModuleInfo_Hack
+{
+public:
+ virtual void ICorModuleInfo_Hack_dummy() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
+};
+
+class ICorClassInfo_Hack
+{
+public:
+ virtual void ICorClassInfo_Hack_dummy1() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
+ virtual void ICorClassInfo_Hack_dummy2() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
+ virtual void ICorClassInfo_Hack_dummy3() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
+ virtual void ICorClassInfo_Hack_dummy4() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
+ virtual void ICorClassInfo_Hack_dummy5() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
+ virtual void ICorClassInfo_Hack_dummy6() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
+ virtual void ICorClassInfo_Hack_dummy7() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
+ virtual void ICorClassInfo_Hack_dummy8() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
+ virtual void ICorClassInfo_Hack_dummy9() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
+ virtual void ICorClassInfo_Hack_dummy10() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
+ virtual void ICorClassInfo_Hack_dummy11() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
+ virtual void ICorClassInfo_Hack_dummy12() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
+ virtual void ICorClassInfo_Hack_dummy13() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
+ virtual void ICorClassInfo_Hack_dummy14() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
+
+ virtual mdMethodDef __stdcall ICorClassInfo_Hack_getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod) = 0;
+};
+
+class ICorStaticInfo_Hack : public virtual ICorMethodInfo_Hack, public virtual ICorModuleInfo_Hack, public virtual ICorClassInfo_Hack
+{
+ virtual void ICorStaticInfo_Hack_dummy() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
+};
+
+#endif // FEATURE_CORECLR
+
+
+/*********************************************************************/
+/*********************************************************************/
+class CEEInfo : public ICorJitInfo
+#ifndef FEATURE_CORECLR
+ , public virtual ICorStaticInfo_Hack
+#endif
+{
+ friend class CEEDynamicCodeInfo;
+
+ const char * __stdcall ICorMethodInfo_Hack_getMethodName(CORINFO_METHOD_HANDLE ftnHnd, const char** scopeName)
+ {
+ WRAPPER_NO_CONTRACT;
+ return getMethodName(ftnHnd, scopeName);
+ }
+
+ mdMethodDef __stdcall ICorClassInfo_Hack_getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod)
+ {
+ WRAPPER_NO_CONTRACT;
+ return getMethodDefFromMethod(hMethod);
+ }
+
+public:
+ // ICorClassInfo stuff
+ CorInfoType asCorInfoType (CORINFO_CLASS_HANDLE cls);
+ // This normalizes EE type information into the form expected by the JIT.
+ //
+ // If typeHnd contains exact type information, then *clsRet will contain
+ // the normalized CORINFO_CLASS_HANDLE information on return.
+ static CorInfoType asCorInfoType (CorElementType cet,
+ TypeHandle typeHnd = TypeHandle() /* optional in */,
+ CORINFO_CLASS_HANDLE *clsRet = NULL /* optional out */ );
+
+ CORINFO_MODULE_HANDLE getClassModule(CORINFO_CLASS_HANDLE clsHnd);
+ CORINFO_ASSEMBLY_HANDLE getModuleAssembly(CORINFO_MODULE_HANDLE mod);
+ const char* getAssemblyName(CORINFO_ASSEMBLY_HANDLE assem);
+ void* LongLifetimeMalloc(size_t sz);
+ void LongLifetimeFree(void* obj);
+ size_t getClassModuleIdForStatics(CORINFO_CLASS_HANDLE clsHnd, CORINFO_MODULE_HANDLE *pModuleHandle, void **ppIndirection);
+ const char* getClassName (CORINFO_CLASS_HANDLE cls);
+ const char* getHelperName(CorInfoHelpFunc ftnNum);
+ int appendClassName(__deref_inout_ecount(*pnBufLen) WCHAR** ppBuf,
+ int* pnBufLen,
+ CORINFO_CLASS_HANDLE cls,
+ BOOL fNamespace,
+ BOOL fFullInst,
+ BOOL fAssembly);
+ BOOL isValueClass (CORINFO_CLASS_HANDLE cls);
+ BOOL canInlineTypeCheckWithObjectVTable (CORINFO_CLASS_HANDLE cls);
+
+ DWORD getClassAttribs (CORINFO_CLASS_HANDLE cls);
+
+ // Internal version without JIT-EE transition
+ DWORD getClassAttribsInternal (CORINFO_CLASS_HANDLE cls);
+
+ BOOL isStructRequiringStackAllocRetBuf(CORINFO_CLASS_HANDLE cls);
+
+ unsigned getClassSize (CORINFO_CLASS_HANDLE cls);
+ unsigned getClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint);
+ static unsigned getClassAlignmentRequirementStatic(TypeHandle clsHnd);
+
+ // Used for HFA's on IA64...and later for type based disambiguation
+ CORINFO_FIELD_HANDLE getFieldInClass(CORINFO_CLASS_HANDLE clsHnd, INT num);
+
+ mdMethodDef getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod);
+ BOOL checkMethodModifier(CORINFO_METHOD_HANDLE hMethod, LPCSTR modifier, BOOL fOptional);
+
+ unsigned getClassGClayout (CORINFO_CLASS_HANDLE cls, BYTE* gcPtrs); /* really GCType* gcPtrs */
+ unsigned getClassNumInstanceFields(CORINFO_CLASS_HANDLE cls);
+
+ // returns the enregister info for a struct based on type of fields, alignment, etc.
+ bool getSystemVAmd64PassStructInRegisterDescriptor(
+ /*IN*/ CORINFO_CLASS_HANDLE _structHnd,
+ /*OUT*/ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr);
+
+ // Check Visibility rules.
+ // For Protected (family access) members, type of the instance is also
+ // considered when checking visibility rules.
+
+
+ CorInfoHelpFunc getNewHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_METHOD_HANDLE callerHandle);
+ static CorInfoHelpFunc getNewHelperStatic(MethodTable * pMT);
+
+ CorInfoHelpFunc getNewArrHelper(CORINFO_CLASS_HANDLE arrayCls);
+ static CorInfoHelpFunc getNewArrHelperStatic(TypeHandle clsHnd);
+
+ CorInfoHelpFunc getCastingHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fThrowing);
+ static CorInfoHelpFunc getCastingHelperStatic(TypeHandle clsHnd, bool fThrowing, bool * pfClassMustBeRestored);
+
+ CorInfoHelpFunc getSharedCCtorHelper(CORINFO_CLASS_HANDLE clsHnd);
+ CorInfoHelpFunc getSecurityPrologHelper(CORINFO_METHOD_HANDLE ftn);
+ CORINFO_CLASS_HANDLE getTypeForBox(CORINFO_CLASS_HANDLE cls);
+ CorInfoHelpFunc getBoxHelper(CORINFO_CLASS_HANDLE cls);
+ CorInfoHelpFunc getUnBoxHelper(CORINFO_CLASS_HANDLE cls);
+
+ bool getReadyToRunHelper(
+ CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ CORINFO_LOOKUP_KIND * pGenericLookupKind,
+ CorInfoHelpFunc id,
+ CORINFO_CONST_LOOKUP * pLookup
+ );
+
+ void getReadyToRunDelegateCtorHelper(
+ CORINFO_RESOLVED_TOKEN * pTargetMethod,
+ CORINFO_CLASS_HANDLE delegateType,
+ CORINFO_CONST_LOOKUP * pLookup
+ );
+
+ CorInfoInitClassResult initClass(
+ CORINFO_FIELD_HANDLE field,
+ CORINFO_METHOD_HANDLE method,
+ CORINFO_CONTEXT_HANDLE context,
+ BOOL speculative = FALSE);
+
+ void classMustBeLoadedBeforeCodeIsRun (CORINFO_CLASS_HANDLE cls);
+ void methodMustBeLoadedBeforeCodeIsRun (CORINFO_METHOD_HANDLE meth);
+ CORINFO_METHOD_HANDLE mapMethodDeclToMethodImpl(CORINFO_METHOD_HANDLE methHnd);
+ CORINFO_CLASS_HANDLE getBuiltinClass(CorInfoClassId classId);
+ void getGSCookie(GSCookie * pCookieVal, GSCookie ** ppCookieVal);
+
+ // "System.Int32" ==> CORINFO_TYPE_INT..
+ CorInfoType getTypeForPrimitiveValueClass(
+ CORINFO_CLASS_HANDLE cls
+ );
+
+ // TRUE if child is a subtype of parent
+ // if parent is an interface, then does child implement / extend parent
+ BOOL canCast(
+ CORINFO_CLASS_HANDLE child,
+ CORINFO_CLASS_HANDLE parent
+ );
+
+ // TRUE if cls1 and cls2 are considered equivalent types.
+ BOOL areTypesEquivalent(
+ CORINFO_CLASS_HANDLE cls1,
+ CORINFO_CLASS_HANDLE cls2
+ );
+
+ // returns is the intersection of cls1 and cls2.
+ CORINFO_CLASS_HANDLE mergeClasses(
+ CORINFO_CLASS_HANDLE cls1,
+ CORINFO_CLASS_HANDLE cls2
+ );
+
+ // Given a class handle, returns the Parent type.
+ // For COMObjectType, it returns Class Handle of System.Object.
+ // Returns 0 if System.Object is passed in.
+ CORINFO_CLASS_HANDLE getParentType (
+ CORINFO_CLASS_HANDLE cls
+ );
+
+ // Returns the CorInfoType of the "child type". If the child type is
+ // not a primitive type, *clsRet will be set.
+ // Given an Array of Type Foo, returns Foo.
+ // Given BYREF Foo, returns Foo
+ CorInfoType getChildType (
+ CORINFO_CLASS_HANDLE clsHnd,
+ CORINFO_CLASS_HANDLE *clsRet
+ );
+
+ // Check constraints on type arguments of this class and parent classes
+ BOOL satisfiesClassConstraints(
+ CORINFO_CLASS_HANDLE cls
+ );
+
+ // Check if this is a single dimensional array type
+ BOOL isSDArray(
+ CORINFO_CLASS_HANDLE cls
+ );
+
+ // Get the number of dimensions in an array
+ unsigned getArrayRank(
+ CORINFO_CLASS_HANDLE cls
+ );
+
+ // Get static field data for an array
+ void * getArrayInitializationData(
+ CORINFO_FIELD_HANDLE field,
+ DWORD size
+ );
+
+ // Check Visibility rules.
+ CorInfoIsAccessAllowedResult canAccessClass(
+ CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ CORINFO_METHOD_HANDLE callerHandle,
+ CORINFO_HELPER_DESC *pAccessHelper /* If canAccessClass returns something other
+ than ALLOWED, then this is filled in. */
+ );
+
+ // Returns that compilation flags that are shared between JIT and NGen
+ static DWORD GetBaseCompileFlags(MethodDesc * ftn);
+
+ // Resolve metadata token into runtime method handles.
+ void resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken);
+
+ // Attempt to resolve a metadata token into a runtime method handle. Returns true
+ // if resolution succeeded and false otherwise.
+ bool tryResolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken);
+
+ void getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ CORINFO_METHOD_HANDLE callerHandle,
+ CORINFO_ACCESS_FLAGS flags,
+ CORINFO_FIELD_INFO *pResult
+ );
+ static CorInfoHelpFunc getSharedStaticsHelper(FieldDesc * pField, MethodTable * pFieldMT);
+
+ bool isFieldStatic(CORINFO_FIELD_HANDLE fldHnd);
+
+ // Given a signature token sigTOK, use class/method instantiation in context to instantiate any type variables in the signature and return a new signature
+ void findSig(CORINFO_MODULE_HANDLE scopeHnd, unsigned sigTOK, CORINFO_CONTEXT_HANDLE context, CORINFO_SIG_INFO* sig);
+ void findCallSiteSig(CORINFO_MODULE_HANDLE scopeHnd, unsigned methTOK, CORINFO_CONTEXT_HANDLE context, CORINFO_SIG_INFO* sig);
+ CORINFO_CLASS_HANDLE getTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken);
+
+ size_t findNameOfToken (CORINFO_MODULE_HANDLE module, mdToken metaTOK,
+ __out_ecount (FQNameCapacity) char * szFQName, size_t FQNameCapacity);
+
+ CorInfoCanSkipVerificationResult canSkipVerification(CORINFO_MODULE_HANDLE moduleHnd);
+
+ // Checks if the given metadata token is valid
+ BOOL isValidToken (
+ CORINFO_MODULE_HANDLE module,
+ mdToken metaTOK);
+
+ // Checks if the given metadata token is valid StringRef
+ BOOL isValidStringRef (
+ CORINFO_MODULE_HANDLE module,
+ mdToken metaTOK);
+
+ static size_t findNameOfToken (Module* module, mdToken metaTOK,
+ __out_ecount (FQNameCapacity) char * szFQName, size_t FQNameCapacity);
+
+ // ICorMethodInfo stuff
+ const char* getMethodName (CORINFO_METHOD_HANDLE ftnHnd, const char** scopeName);
+ unsigned getMethodHash (CORINFO_METHOD_HANDLE ftnHnd);
+
+ DWORD getMethodAttribs (CORINFO_METHOD_HANDLE ftnHnd);
+ // Internal version without JIT-EE transition
+ DWORD getMethodAttribsInternal (CORINFO_METHOD_HANDLE ftnHnd);
+
+ void setMethodAttribs (CORINFO_METHOD_HANDLE ftnHnd, CorInfoMethodRuntimeFlags attribs);
+
+ bool getMethodInfo (
+ CORINFO_METHOD_HANDLE ftnHnd,
+ CORINFO_METHOD_INFO* methInfo);
+
+ CorInfoInline canInline (
+ CORINFO_METHOD_HANDLE callerHnd,
+ CORINFO_METHOD_HANDLE calleeHnd,
+ DWORD* pRestrictions);
+
+ void reportInliningDecision (CORINFO_METHOD_HANDLE inlinerHnd,
+ CORINFO_METHOD_HANDLE inlineeHnd,
+ CorInfoInline inlineResult,
+ const char * reason);
+
+ // Used by ngen
+ CORINFO_METHOD_HANDLE instantiateMethodAtObject(CORINFO_METHOD_HANDLE method);
+
+ // Loads the constraints on a typical method definition, detecting cycles;
+ // used by verifiers.
+ void initConstraintsForVerification(
+ CORINFO_METHOD_HANDLE method,
+ BOOL *pfHasCircularClassConstraints,
+ BOOL *pfHasCircularMethodConstraints
+ );
+
+ CorInfoInstantiationVerification isInstantiationOfVerifiedGeneric (
+ CORINFO_METHOD_HANDLE methodHnd);
+
+
+ bool canTailCall (
+ CORINFO_METHOD_HANDLE callerHnd,
+ CORINFO_METHOD_HANDLE declaredCalleeHnd,
+ CORINFO_METHOD_HANDLE exactCalleeHnd,
+ bool fIsTailPrefix);
+
+ void reportTailCallDecision (CORINFO_METHOD_HANDLE callerHnd,
+ CORINFO_METHOD_HANDLE calleeHnd,
+ bool fIsTailPrefix,
+ CorInfoTailCall tailCallResult,
+ const char * reason);
+
+ CorInfoCanSkipVerificationResult canSkipMethodVerification(
+ CORINFO_METHOD_HANDLE ftnHnd);
+
+ // Given a method descriptor ftnHnd, extract signature information into sigInfo
+ // Obtain (representative) instantiation information from ftnHnd's owner class
+ //@GENERICSVER: added explicit owner parameter
+ void getMethodSig (
+ CORINFO_METHOD_HANDLE ftnHnd,
+ CORINFO_SIG_INFO* sigInfo,
+ CORINFO_CLASS_HANDLE owner = NULL
+ );
+ // Internal version without JIT-EE transition
+ void getMethodSigInternal (
+ CORINFO_METHOD_HANDLE ftnHnd,
+ CORINFO_SIG_INFO* sigInfo,
+ CORINFO_CLASS_HANDLE owner = NULL
+ );
+
+ void getEHinfo(
+ CORINFO_METHOD_HANDLE ftn,
+ unsigned EHnumber,
+ CORINFO_EH_CLAUSE* clause);
+
+ CORINFO_CLASS_HANDLE getMethodClass (CORINFO_METHOD_HANDLE methodHnd);
+ CORINFO_MODULE_HANDLE getMethodModule (CORINFO_METHOD_HANDLE methodHnd);
+
+ void getMethodVTableOffset (
+ CORINFO_METHOD_HANDLE methodHnd,
+ unsigned * pOffsetOfIndirection,
+ unsigned * pOffsetAfterIndirection
+ );
+
+ CorInfoIntrinsics getIntrinsicID(CORINFO_METHOD_HANDLE method,
+ bool * pMustExpand = NULL);
+
+ bool isInSIMDModule(CORINFO_CLASS_HANDLE classHnd);
+
+ CorInfoUnmanagedCallConv getUnmanagedCallConv(CORINFO_METHOD_HANDLE method);
+ BOOL pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig);
+
+ // Generate a cookie based on the signature that would needs to be passed
+ // to the above generic stub
+ LPVOID GetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void ** ppIndirection);
+ bool canGetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig);
+
+ // Check Visibility rules.
+
+ // should we enforce the new (for whidbey) restrictions on calling virtual methods?
+ BOOL shouldEnforceCallvirtRestriction(
+ CORINFO_MODULE_HANDLE scope);
+
+ // Check constraints on method type arguments (only).
+ // The parent class should be checked separately using satisfiesClassConstraints(parent).
+ BOOL satisfiesMethodConstraints(
+ CORINFO_CLASS_HANDLE parent, // the exact parent of the method
+ CORINFO_METHOD_HANDLE method
+ );
+
+ // Given a Delegate type and a method, check if the method signature
+ // is Compatible with the Invoke method of the delegate.
+ //@GENERICSVER: new (suitable for generics)
+ BOOL isCompatibleDelegate(
+ CORINFO_CLASS_HANDLE objCls,
+ CORINFO_CLASS_HANDLE methodParentCls,
+ CORINFO_METHOD_HANDLE method,
+ CORINFO_CLASS_HANDLE delegateCls,
+ BOOL* pfIsOpenDelegate);
+
+ // Determines whether the delegate creation obeys security transparency rules
+ BOOL isDelegateCreationAllowed (
+ CORINFO_CLASS_HANDLE delegateHnd,
+ CORINFO_METHOD_HANDLE calleeHnd);
+
+ // ICorFieldInfo stuff
+ const char* getFieldName (CORINFO_FIELD_HANDLE field,
+ const char** scopeName);
+
+ CORINFO_CLASS_HANDLE getFieldClass (CORINFO_FIELD_HANDLE field);
+
+ //@GENERICSVER: added owner parameter
+ CorInfoType getFieldType (CORINFO_FIELD_HANDLE field, CORINFO_CLASS_HANDLE* structType,CORINFO_CLASS_HANDLE owner = NULL);
+ // Internal version without JIT-EE transition
+ CorInfoType getFieldTypeInternal (CORINFO_FIELD_HANDLE field, CORINFO_CLASS_HANDLE* structType,CORINFO_CLASS_HANDLE owner = NULL);
+
+ unsigned getFieldOffset (CORINFO_FIELD_HANDLE field);
+
+ bool isWriteBarrierHelperRequired(CORINFO_FIELD_HANDLE field);
+
+ void* getFieldAddress(CORINFO_FIELD_HANDLE field, void **ppIndirection);
+
+ // ICorDebugInfo stuff
+ void * allocateArray(ULONG cBytes);
+ void freeArray(void *array);
+ void getBoundaries(CORINFO_METHOD_HANDLE ftn,
+ unsigned int *cILOffsets, DWORD **pILOffsets,
+ ICorDebugInfo::BoundaryTypes *implictBoundaries);
+ void setBoundaries(CORINFO_METHOD_HANDLE ftn,
+ ULONG32 cMap, ICorDebugInfo::OffsetMapping *pMap);
+ void getVars(CORINFO_METHOD_HANDLE ftn, ULONG32 *cVars,
+ ICorDebugInfo::ILVarInfo **vars, bool *extendOthers);
+ void setVars(CORINFO_METHOD_HANDLE ftn, ULONG32 cVars,
+ ICorDebugInfo::NativeVarInfo *vars);
+
+ // ICorArgInfo stuff
+
+ CorInfoTypeWithMod getArgType (
+ CORINFO_SIG_INFO* sig,
+ CORINFO_ARG_LIST_HANDLE args,
+ CORINFO_CLASS_HANDLE *vcTypeRet
+ );
+
+ CORINFO_CLASS_HANDLE getArgClass (
+ CORINFO_SIG_INFO* sig,
+ CORINFO_ARG_LIST_HANDLE args
+ );
+
+ CorInfoType getHFAType (
+ CORINFO_CLASS_HANDLE hClass
+ );
+
+ CORINFO_ARG_LIST_HANDLE getArgNext (
+ CORINFO_ARG_LIST_HANDLE args
+ );
+
+ // ICorErrorInfo stuff
+
+ HRESULT GetErrorHRESULT(struct _EXCEPTION_POINTERS *pExceptionPointers);
+ ULONG GetErrorMessage(__out_ecount(bufferLength) LPWSTR buffer,
+ ULONG bufferLength);
+ int FilterException(struct _EXCEPTION_POINTERS *pExceptionPointers);
+ void HandleException(struct _EXCEPTION_POINTERS *pExceptionPointers);
+ void ThrowExceptionForJitResult(HRESULT result);
+ void ThrowExceptionForHelper(const CORINFO_HELPER_DESC * throwHelper);
+
+ // ICorStaticInfo stuff
+ void getEEInfo(CORINFO_EE_INFO *pEEInfoOut);
+
+ LPCWSTR getJitTimeLogFilename();
+
+ //ICorDynamicInfo stuff
+ DWORD getFieldThreadLocalStoreID (CORINFO_FIELD_HANDLE field, void **ppIndirection);
+
+ // Stub dispatch stuff
+ void getCallInfo(
+ CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken,
+ CORINFO_METHOD_HANDLE callerHandle,
+ CORINFO_CALLINFO_FLAGS flags,
+ CORINFO_CALL_INFO *pResult /*out */);
+ BOOL canAccessFamily(CORINFO_METHOD_HANDLE hCaller,
+ CORINFO_CLASS_HANDLE hInstanceType);
+
+protected:
+
+ static void getEHinfoHelper(
+ CORINFO_METHOD_HANDLE ftnHnd,
+ unsigned EHnumber,
+ CORINFO_EH_CLAUSE* clause,
+ COR_ILMETHOD_DECODER* pILHeader);
+
+ bool isVerifyOnly()
+ {
+ return m_fVerifyOnly;
+ }
+
+public:
+
+ BOOL isRIDClassDomainID(CORINFO_CLASS_HANDLE cls);
+ unsigned getClassDomainID (CORINFO_CLASS_HANDLE cls, void **ppIndirection);
+ CORINFO_VARARGS_HANDLE getVarArgsHandle(CORINFO_SIG_INFO *sig, void **ppIndirection);
+ bool canGetVarArgsHandle(CORINFO_SIG_INFO *sig);
+ void* getPInvokeUnmanagedTarget(CORINFO_METHOD_HANDLE method, void **ppIndirection);
+ void* getAddressOfPInvokeFixup(CORINFO_METHOD_HANDLE method, void **ppIndirection);
+ void getAddressOfPInvokeTarget(CORINFO_METHOD_HANDLE method, CORINFO_CONST_LOOKUP *pLookup);
+ CORINFO_JUST_MY_CODE_HANDLE getJustMyCodeHandle(CORINFO_METHOD_HANDLE method, CORINFO_JUST_MY_CODE_HANDLE **ppIndirection);
+
+ void GetProfilingHandle(
+ BOOL *pbHookFunction,
+ void **pProfilerHandle,
+ BOOL *pbIndirectedHandles
+ );
+
+ InfoAccessType constructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok, void **ppValue);
+ InfoAccessType emptyStringLiteral(void ** ppValue);
+ void* getMethodSync(CORINFO_METHOD_HANDLE ftnHnd, void **ppIndirection);
+
+ DWORD getThreadTLSIndex(void **ppIndirection);
+ const void * getInlinedCallFrameVptr(void **ppIndirection);
+
+ // Returns the address of the domain neutral module id. This only makes sense for domain neutral (shared)
+ // modules
+ SIZE_T* getAddrModuleDomainID(CORINFO_MODULE_HANDLE module);
+
+ LONG * getAddrOfCaptureThreadGlobal(void **ppIndirection);
+ void* getHelperFtn(CorInfoHelpFunc ftnNum, /* IN */
+ void ** ppIndirection); /* OUT */
+
+ void* getTailCallCopyArgsThunk(CORINFO_SIG_INFO *pSig,
+ CorInfoHelperTailCallSpecialHandling flags);
+
+ void getFunctionEntryPoint(CORINFO_METHOD_HANDLE ftn, /* IN */
+ CORINFO_CONST_LOOKUP * pResult, /* OUT */
+ CORINFO_ACCESS_FLAGS accessFlags = CORINFO_ACCESS_ANY);
+
+ void getFunctionFixedEntryPoint(CORINFO_METHOD_HANDLE ftn,
+ CORINFO_CONST_LOOKUP * pResult);
+
+ // get slow lazy string literal helper to use (CORINFO_HELP_STRCNS*).
+ // Returns CORINFO_HELP_UNDEF if lazy string literal helper cannot be used.
+ CorInfoHelpFunc getLazyStringLiteralHelper(CORINFO_MODULE_HANDLE handle);
+
+ CORINFO_MODULE_HANDLE embedModuleHandle(CORINFO_MODULE_HANDLE handle,
+ void **ppIndirection);
+ CORINFO_CLASS_HANDLE embedClassHandle(CORINFO_CLASS_HANDLE handle,
+ void **ppIndirection);
+ CORINFO_FIELD_HANDLE embedFieldHandle(CORINFO_FIELD_HANDLE handle,
+ void **ppIndirection);
+ CORINFO_METHOD_HANDLE embedMethodHandle(CORINFO_METHOD_HANDLE handle,
+ void **ppIndirection);
+
+ void embedGenericHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ BOOL fEmbedParent,
+ CORINFO_GENERICHANDLE_RESULT *pResult);
+
+ CORINFO_LOOKUP_KIND getLocationOfThisType(CORINFO_METHOD_HANDLE context);
+
+
+ void setOverride(ICorDynamicInfo *pOverride, CORINFO_METHOD_HANDLE currentMethod)
+ {
+ LIMITED_METHOD_CONTRACT;
+ m_pOverride = pOverride;
+ m_pMethodBeingCompiled = (MethodDesc *)currentMethod; // method being compiled
+
+ m_hMethodForSecurity_Key = NULL;
+ m_pMethodForSecurity_Value = NULL;
+ }
+
+ // Returns whether we are generating code for NGen image.
+ BOOL IsCompilingForNGen()
+ {
+ LIMITED_METHOD_CONTRACT;
+ // NGen is the only place where we set the override
+ return this != m_pOverride;
+ }
+
+ void addActiveDependency(CORINFO_MODULE_HANDLE moduleFrom, CORINFO_MODULE_HANDLE moduleTo);
+ CORINFO_METHOD_HANDLE GetDelegateCtor(
+ CORINFO_METHOD_HANDLE methHnd,
+ CORINFO_CLASS_HANDLE clsHnd,
+ CORINFO_METHOD_HANDLE targetMethodHnd,
+ DelegateCtorArgs * pCtorData);
+
+ void MethodCompileComplete(
+ CORINFO_METHOD_HANDLE methHnd);
+
+ //
+ // ICorJitInfo stuff - none of this should be called on this class
+ //
+
+ IEEMemoryManager* getMemoryManager();
+
+ void allocMem (
+ ULONG hotCodeSize, /* IN */
+ ULONG coldCodeSize, /* IN */
+ ULONG roDataSize, /* IN */
+ ULONG xcptnsCount, /* IN */
+ CorJitAllocMemFlag flag, /* IN */
+ void ** hotCodeBlock, /* OUT */
+ void ** coldCodeBlock, /* OUT */
+ void ** roDataBlock /* OUT */
+ );
+
+ void reserveUnwindInfo (
+ BOOL isFunclet, /* IN */
+ BOOL isColdCode, /* IN */
+ ULONG unwindSize /* IN */
+ );
+
+ void allocUnwindInfo (
+ BYTE * pHotCode, /* IN */
+ BYTE * pColdCode, /* IN */
+ ULONG startOffset, /* IN */
+ ULONG endOffset, /* IN */
+ ULONG unwindSize, /* IN */
+ BYTE * pUnwindBlock, /* IN */
+ CorJitFuncKind funcKind /* IN */
+ );
+
+ void * allocGCInfo (
+ size_t size /* IN */
+ );
+
+ void yieldExecution();
+
+ void setEHcount (
+ unsigned cEH /* IN */
+ );
+
+ void setEHinfo (
+ unsigned EHnumber, /* IN */
+ const CORINFO_EH_CLAUSE *clause /* IN */
+ );
+
+ BOOL logMsg(unsigned level, const char* fmt, va_list args);
+
+ int doAssert(const char* szFile, int iLine, const char* szExpr);
+
+ void reportFatalError(CorJitResult result);
+
+ void logSQMLongJitEvent(unsigned mcycles, unsigned msec, unsigned ilSize, unsigned numBasicBlocks, bool minOpts,
+ CORINFO_METHOD_HANDLE methodHnd);
+
+ HRESULT allocBBProfileBuffer (
+ ULONG count, // The number of basic blocks that we have
+ ProfileBuffer ** profileBuffer
+ );
+
+ HRESULT getBBProfileData(
+ CORINFO_METHOD_HANDLE ftnHnd,
+ ULONG * count, // The number of basic blocks that we have
+ ProfileBuffer ** profileBuffer,
+ ULONG * numRuns
+ );
+
+ void recordCallSite(
+ ULONG instrOffset, /* IN */
+ CORINFO_SIG_INFO * callSig, /* IN */
+ CORINFO_METHOD_HANDLE methodHandle /* IN */
+ );
+
+ void recordRelocation(
+ void * location, /* IN */
+ void * target, /* IN */
+ WORD fRelocType, /* IN */
+ WORD slotNum = 0, /* IN */
+ INT32 addlDelta = 0 /* IN */
+ );
+
+ WORD getRelocTypeHint(void * target);
+
+ void getModuleNativeEntryPointRange(
+ void ** pStart, /* OUT */
+ void ** pEnd /* OUT */
+ );
+
+ DWORD getExpectedTargetArchitecture();
+
+ CEEInfo(MethodDesc * fd = NULL, bool fVerifyOnly = false) :
+ m_pOverride(NULL),
+ m_pMethodBeingCompiled(fd),
+ m_fVerifyOnly(fVerifyOnly),
+ m_pThread(GetThread()),
+ m_hMethodForSecurity_Key(NULL),
+ m_pMethodForSecurity_Value(NULL)
+ {
+ LIMITED_METHOD_CONTRACT;
+ }
+
+ virtual ~CEEInfo()
+ {
+ LIMITED_METHOD_CONTRACT;
+ }
+
+ // Performs any work JIT-related work that should be performed at process shutdown.
+ void JitProcessShutdownWork();
+
+ void setJitFlags(const CORJIT_FLAGS& jitFlags);
+
+ DWORD getJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes);
+
+ bool runWithErrorTrap(void (*function)(void*), void* param);
+
+private:
+ // Shrinking these buffers drastically reduces the amount of stack space
+ // required for each instance of the interpreter, and thereby reduces SOs.
+#ifdef FEATURE_INTERPRETER
+#define CLS_STRING_SIZE 8 // force heap allocation
+#define CLS_BUFFER_SIZE SBUFFER_PADDED_SIZE(8)
+#else
+#define CLS_STRING_SIZE MAX_CLASSNAME_LENGTH
+#define CLS_BUFFER_SIZE MAX_CLASSNAME_LENGTH
+#endif
+
+#ifdef _DEBUG
+ InlineSString<MAX_CLASSNAME_LENGTH> ssClsNameBuff;
+ ScratchBuffer<MAX_CLASSNAME_LENGTH> ssClsNameBuffScratch;
+#endif
+
+public:
+
+ //@GENERICS:
+ // The method handle is used to instantiate method and class type parameters
+ // It's also used to determine whether an extra dictionary parameter is required
+ static
+ void
+ ConvToJitSig(
+ PCCOR_SIGNATURE pSig,
+ DWORD cbSig,
+ CORINFO_MODULE_HANDLE scopeHnd,
+ mdToken token,
+ CORINFO_SIG_INFO * sigRet,
+ MethodDesc * context,
+ bool localSig,
+ TypeHandle owner = TypeHandle());
+
+ MethodDesc * GetMethodForSecurity(CORINFO_METHOD_HANDLE callerHandle);
+
+ // Prepare the information about how to do a runtime lookup of the handle with shared
+ // generic variables.
+ void ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entryKind,
+ CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken /* for ConstrainedMethodEntrySlot */,
+ MethodDesc * pTemplateMD /* for method-based slots */,
+ CORINFO_LOOKUP *pResultLookup);
+
+ static void ComputeRuntimeLookupForSharedGenericTokenStatic(DictionaryEntryKind entryKind,
+ CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken /* for ConstrainedMethodEntrySlot */,
+ MethodDesc * pTemplateMD /* for method-based slots */,
+ LoaderAllocator* pAllocator,
+ DWORD numGenericArgs,
+ DictionaryLayout* pDictionaryLayout,
+ DWORD typeDictionaryIndex,
+ CORINFO_LOOKUP *pResultLookup,
+ BOOL fEnableTypeHandleLookupOptimization,
+ BOOL fInstrument);
+
+protected:
+ // NGen provides its own modifications to EE-JIT interface. From technical reason it cannot simply inherit
+ // from code:CEEInfo class (because it has dependencies on VM that NGen does not want).
+ // Therefore the "normal" EE-JIT interface has code:m_pOverride hook that is set either to
+ // * 'this' (code:CEEInfo) at runtime, or to
+ // * code:ZapInfo - the NGen specific implementation of the interface.
+ ICorDynamicInfo * m_pOverride;
+
+ MethodDesc* m_pMethodBeingCompiled; // Top-level method being compiled
+ bool m_fVerifyOnly;
+ Thread * m_pThread; // Cached current thread for faster JIT-EE transitions
+ CORJIT_FLAGS m_jitFlags;
+
+ CORINFO_METHOD_HANDLE getMethodBeingCompiled()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return (CORINFO_METHOD_HANDLE)m_pMethodBeingCompiled;
+ }
+
+ // Cache of last GetMethodForSecurity() lookup
+ CORINFO_METHOD_HANDLE m_hMethodForSecurity_Key;
+ MethodDesc * m_pMethodForSecurity_Value;
+
+ // Tracking of module activation dependencies. We have two flavors:
+ // - Fast one that gathers generic arguments from EE handles, but does not work inside generic context.
+ // - Slow one that operates on typespec and methodspecs from metadata.
+ void ScanForModuleDependencies(Module* pModule, SigPointer psig);
+ void ScanMethodSpec(Module * pModule, PCCOR_SIGNATURE pMethodSpec, ULONG cbMethodSpec);
+ // Returns true if it is ok to proceed with scan of parent chain
+ BOOL ScanTypeSpec(Module * pModule, PCCOR_SIGNATURE pTypeSpec, ULONG cbTypeSpec);
+ void ScanInstantiation(Module * pModule, Instantiation inst);
+
+ // The main entrypoints for module activation tracking
+ void ScanToken(Module * pModule, CORINFO_RESOLVED_TOKEN * pResolvedToken, TypeHandle th, MethodDesc * pMD = NULL);
+ void ScanTokenForDynamicScope(CORINFO_RESOLVED_TOKEN * pResolvedToken, TypeHandle th, MethodDesc * pMD = NULL);
+};
+
+
+/*********************************************************************/
+
+class EEJitManager;
+struct _hpCodeHdr;
+typedef struct _hpCodeHdr CodeHeader;
+
+#ifndef CROSSGEN_COMPILE
+// CEEJitInfo is the concrete implementation of callbacks that the EE must provide for the JIT to do its
+// work. See code:ICorJitInfo#JitToEEInterface for more on this interface.
+class CEEJitInfo : public CEEInfo
+{
+public:
+ // ICorJitInfo stuff
+
+ void allocMem (
+ ULONG hotCodeSize, /* IN */
+ ULONG coldCodeSize, /* IN */
+ ULONG roDataSize, /* IN */
+ ULONG xcptnsCount, /* IN */
+ CorJitAllocMemFlag flag, /* IN */
+ void ** hotCodeBlock, /* OUT */
+ void ** coldCodeBlock, /* OUT */
+ void ** roDataBlock /* OUT */
+ );
+
+ void reserveUnwindInfo(BOOL isFunclet, BOOL isColdCode, ULONG unwindSize);
+
+ void allocUnwindInfo (
+ BYTE * pHotCode, /* IN */
+ BYTE * pColdCode, /* IN */
+ ULONG startOffset, /* IN */
+ ULONG endOffset, /* IN */
+ ULONG unwindSize, /* IN */
+ BYTE * pUnwindBlock, /* IN */
+ CorJitFuncKind funcKind /* IN */
+ );
+
+ void * allocGCInfo (size_t size);
+
+ void setEHcount (unsigned cEH);
+
+ void setEHinfo (
+ unsigned EHnumber,
+ const CORINFO_EH_CLAUSE* clause);
+
+ void getEHinfo(
+ CORINFO_METHOD_HANDLE ftn, /* IN */
+ unsigned EHnumber, /* IN */
+ CORINFO_EH_CLAUSE* clause /* OUT */
+ );
+
+
+ HRESULT allocBBProfileBuffer (
+ ULONG count, // The number of basic blocks that we have
+ ICorJitInfo::ProfileBuffer ** profileBuffer
+ );
+
+ HRESULT getBBProfileData (
+ CORINFO_METHOD_HANDLE ftnHnd,
+ ULONG * count, // The number of basic blocks that we have
+ ICorJitInfo::ProfileBuffer ** profileBuffer,
+ ULONG * numRuns
+ );
+
+ void recordCallSite(
+ ULONG instrOffset, /* IN */
+ CORINFO_SIG_INFO * callSig, /* IN */
+ CORINFO_METHOD_HANDLE methodHandle /* IN */
+ );
+
+ void recordRelocation(
+ void *location,
+ void *target,
+ WORD fRelocType,
+ WORD slot,
+ INT32 addlDelta);
+
+ WORD getRelocTypeHint(void * target);
+
+ void getModuleNativeEntryPointRange(
+ void** pStart,
+ void** pEnd);
+
+ DWORD getExpectedTargetArchitecture();
+
+ CodeHeader* GetCodeHeader()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_CodeHeader;
+ }
+
+ void SetCodeHeader(CodeHeader* pValue)
+ {
+ LIMITED_METHOD_CONTRACT;
+ m_CodeHeader = pValue;
+ }
+
+ void ResetForJitRetry()
+ {
+ CONTRACTL {
+ SO_TOLERANT;
+ NOTHROW;
+ GC_NOTRIGGER;
+ } CONTRACTL_END;
+
+ m_CodeHeader = NULL;
+
+ if (m_pOffsetMapping != NULL)
+ delete [] ((BYTE*) m_pOffsetMapping);
+
+ if (m_pNativeVarInfo != NULL)
+ delete [] ((BYTE*) m_pNativeVarInfo);
+
+ m_iOffsetMapping = 0;
+ m_pOffsetMapping = NULL;
+ m_iNativeVarInfo = 0;
+ m_pNativeVarInfo = NULL;
+
+#ifdef WIN64EXCEPTIONS
+ m_moduleBase = NULL;
+ m_totalUnwindSize = 0;
+ m_usedUnwindSize = 0;
+ m_theUnwindBlock = NULL;
+ m_totalUnwindInfos = 0;
+ m_usedUnwindInfos = 0;
+#endif // WIN64EXCEPTIONS
+ }
+
+#ifdef _TARGET_AMD64_
+ void SetAllowRel32(BOOL fAllowRel32)
+ {
+ LIMITED_METHOD_CONTRACT;
+ m_fAllowRel32 = fAllowRel32;
+ }
+
+ void SetRel32Overflow(BOOL fRel32Overflow)
+ {
+ LIMITED_METHOD_CONTRACT;
+ m_fRel32Overflow = fRel32Overflow;
+ }
+
+ BOOL IsRel32Overflow()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_fRel32Overflow;
+ }
+
+ BOOL JitAgain()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_fRel32Overflow;
+ }
+#else
+ BOOL JitAgain()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return FALSE;
+ }
+#endif
+
+ CEEJitInfo(MethodDesc* fd, COR_ILMETHOD_DECODER* header,
+ EEJitManager* jm, bool fVerifyOnly)
+ : CEEInfo(fd, fVerifyOnly),
+ m_jitManager(jm),
+ m_CodeHeader(NULL),
+ m_ILHeader(header),
+#ifdef WIN64EXCEPTIONS
+ m_moduleBase(NULL),
+ m_totalUnwindSize(0),
+ m_usedUnwindSize(0),
+ m_theUnwindBlock(NULL),
+ m_totalUnwindInfos(0),
+ m_usedUnwindInfos(0),
+#endif
+#ifdef _TARGET_AMD64_
+ m_fAllowRel32(FALSE),
+ m_fRel32Overflow(FALSE),
+#endif
+ m_GCinfo_len(0),
+ m_EHinfo_len(0),
+ m_iOffsetMapping(0),
+ m_pOffsetMapping(NULL),
+ m_iNativeVarInfo(0),
+ m_pNativeVarInfo(NULL),
+ m_gphCache()
+ {
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ } CONTRACTL_END;
+
+ m_pOverride = this;
+ }
+
+ ~CEEJitInfo()
+ {
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ } CONTRACTL_END;
+
+ if (m_pOffsetMapping != NULL)
+ delete [] ((BYTE*) m_pOffsetMapping);
+
+ if (m_pNativeVarInfo != NULL)
+ delete [] ((BYTE*) m_pNativeVarInfo);
+ }
+
+ // ICorDebugInfo stuff.
+ void setBoundaries(CORINFO_METHOD_HANDLE ftn,
+ ULONG32 cMap, ICorDebugInfo::OffsetMapping *pMap);
+ void setVars(CORINFO_METHOD_HANDLE ftn, ULONG32 cVars,
+ ICorDebugInfo::NativeVarInfo *vars);
+ void CompressDebugInfo();
+
+ void* getHelperFtn(CorInfoHelpFunc ftnNum, /* IN */
+ void ** ppIndirection); /* OUT */
+ static PCODE getHelperFtnStatic(CorInfoHelpFunc ftnNum);
+
+ // Override active dependency to talk to loader
+ void addActiveDependency(CORINFO_MODULE_HANDLE moduleFrom, CORINFO_MODULE_HANDLE moduleTo);
+
+ // Override of CEEInfo::GetProfilingHandle. The first time this is called for a
+ // method desc, it calls through to CEEInfo::GetProfilingHandle and caches the
+ // result in CEEJitInfo::GetProfilingHandleCache. Thereafter, this wrapper regurgitates the cached values
+ // rather than calling into CEEInfo::GetProfilingHandle each time. This avoids
+ // making duplicate calls into the profiler's FunctionIDMapper callback.
+ void GetProfilingHandle(
+ BOOL *pbHookFunction,
+ void **pProfilerHandle,
+ BOOL *pbIndirectedHandles
+ );
+
+ InfoAccessType constructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok, void **ppValue);
+ InfoAccessType emptyStringLiteral(void ** ppValue);
+ void* getFieldAddress(CORINFO_FIELD_HANDLE field, void **ppIndirection);
+ void* getMethodSync(CORINFO_METHOD_HANDLE ftnHnd, void **ppIndirection);
+
+ void BackoutJitData(EEJitManager * jitMgr);
+
+protected :
+ EEJitManager* m_jitManager; // responsible for allocating memory
+ CodeHeader* m_CodeHeader; // descriptor for JITTED code
+ COR_ILMETHOD_DECODER * m_ILHeader; // the code header as exist in the file
+#ifdef WIN64EXCEPTIONS
+ TADDR m_moduleBase; // Base for unwind Infos
+ ULONG m_totalUnwindSize; // Total reserved unwind space
+ ULONG m_usedUnwindSize; // used space in m_theUnwindBlock
+ BYTE * m_theUnwindBlock; // start of the unwind memory block
+ ULONG m_totalUnwindInfos; // Number of RUNTIME_FUNCTION needed
+ ULONG m_usedUnwindInfos;
+#endif
+
+#ifdef _TARGET_AMD64_
+ BOOL m_fAllowRel32; // Use 32-bit PC relative address modes
+ BOOL m_fRel32Overflow; // Overflow while trying to use encode 32-bit PC relative address.
+ // The code will need to be regenerated with m_fRel32Allowed == FALSE.
+#endif
+
+#if defined(_DEBUG)
+ ULONG m_codeSize; // Code size requested via allocMem
+#endif
+
+ size_t m_GCinfo_len; // Cached copy of GCinfo_len so we can backout in BackoutJitData()
+ size_t m_EHinfo_len; // Cached copy of EHinfo_len so we can backout in BackoutJitData()
+
+ ULONG32 m_iOffsetMapping;
+ ICorDebugInfo::OffsetMapping * m_pOffsetMapping;
+
+ ULONG32 m_iNativeVarInfo;
+ ICorDebugInfo::NativeVarInfo * m_pNativeVarInfo;
+
+ // The first time a call is made to CEEJitInfo::GetProfilingHandle() from this thread
+ // for this method, these values are filled in. Thereafter, these values are used
+ // in lieu of calling into the base CEEInfo::GetProfilingHandle() again. This protects the
+ // profiler from duplicate calls to its FunctionIDMapper() callback.
+ struct GetProfilingHandleCache
+ {
+ GetProfilingHandleCache() :
+ m_bGphIsCacheValid(false),
+ m_bGphHookFunction(false),
+ m_pvGphProfilerHandle(NULL)
+ {
+ LIMITED_METHOD_CONTRACT;
+ }
+
+ bool m_bGphIsCacheValid : 1; // Tells us whether below values are valid
+ bool m_bGphHookFunction : 1;
+ void* m_pvGphProfilerHandle;
+ } m_gphCache;
+
+
+};
+#endif // CROSSGEN_COMPILE
+
+/*********************************************************************/
+/*********************************************************************/
+
+typedef struct {
+ void * pfnHelper;
+#ifdef _DEBUG
+ const char* name;
+#endif
+} VMHELPDEF;
+
+#if defined(DACCESS_COMPILE)
+
+GARY_DECL(VMHELPDEF, hlpFuncTable, CORINFO_HELP_COUNT);
+
+#else
+
+extern "C" const VMHELPDEF hlpFuncTable[CORINFO_HELP_COUNT];
+
+#endif
+
+#if defined(_DEBUG) && (defined(_TARGET_AMD64_) || defined(_TARGET_X86_)) && !defined(FEATURE_PAL)
+typedef struct {
+ void* pfnRealHelper;
+ const char* helperName;
+ LONG count;
+ LONG helperSize;
+} VMHELPCOUNTDEF;
+
+extern "C" VMHELPCOUNTDEF hlpFuncCountTable[CORINFO_HELP_COUNT+1];
+
+void InitJitHelperLogging();
+void WriteJitHelperCountToSTRESSLOG();
+#else
+inline void InitJitHelperLogging() { }
+inline void WriteJitHelperCountToSTRESSLOG() { }
+#endif
+
+// enum for dynamically assigned helper calls
+enum DynamicCorInfoHelpFunc {
+#define JITHELPER(code, pfnHelper, sig)
+#define DYNAMICJITHELPER(code, pfnHelper, sig) DYNAMIC_##code,
+#include "jithelpers.h"
+ DYNAMIC_CORINFO_HELP_COUNT
+};
+
+#ifdef _MSC_VER
+// GCC complains about duplicate "extern". And it is not needed for the GCC build
+extern "C"
+#endif
+GARY_DECL(VMHELPDEF, hlpDynamicFuncTable, DYNAMIC_CORINFO_HELP_COUNT);
+
+#define SetJitHelperFunction(ftnNum, pFunc) _SetJitHelperFunction(DYNAMIC_##ftnNum, (void*)(pFunc))
+void _SetJitHelperFunction(DynamicCorInfoHelpFunc ftnNum, void * pFunc);
+#ifdef ENABLE_FAST_GCPOLL_HELPER
+//These should only be called from ThreadStore::TrapReturningThreads!
+
+//Called when the VM wants to suspend one or more threads.
+void EnableJitGCPoll();
+//Called when there are no threads to suspend.
+void DisableJitGCPoll();
+#endif
+
+// Helper for RtlVirtualUnwind-based tail calls
+#if defined(_TARGET_AMD64_) || defined(_TARGET_ARM_)
+
+// The Stub-linker generated assembly routine to copy arguments from the va_list
+// into the CONTEXT and the stack.
+//
+typedef size_t (*pfnCopyArgs)(va_list, _CONTEXT *, DWORD_PTR *, size_t);
+
+// Forward declaration from Frames.h
+class TailCallFrame;
+
+// The shared stub return location
+EXTERN_C void JIT_TailCallHelperStub_ReturnAddress();
+
+#endif // _TARGET_AMD64_ || _TARGET_ARM_
+
+
+#ifdef _TARGET_X86_
+
+class JIT_TrialAlloc
+{
+public:
+ enum Flags
+ {
+ NORMAL = 0x0,
+ MP_ALLOCATOR = 0x1,
+ SIZE_IN_EAX = 0x2,
+ OBJ_ARRAY = 0x4,
+ ALIGN8 = 0x8, // insert a dummy object to insure 8 byte alignment (until the next GC)
+ ALIGN8OBJ = 0x10,
+ NO_FRAME = 0x20, // call is from unmanaged code - don't try to put up a frame
+ };
+
+ static void *GenAllocSFast(Flags flags);
+ static void *GenBox(Flags flags);
+ static void *GenAllocArray(Flags flags);
+ static void *GenAllocString(Flags flags);
+
+private:
+ static void EmitAlignmentRoundup(CPUSTUBLINKER *psl,X86Reg regTestAlign, X86Reg regToAdj, Flags flags);
+ static void EmitDummyObject(CPUSTUBLINKER *psl, X86Reg regTestAlign, Flags flags);
+ static void EmitCore(CPUSTUBLINKER *psl, CodeLabel *noLock, CodeLabel *noAlloc, Flags flags);
+ static void EmitNoAllocCode(CPUSTUBLINKER *psl, Flags flags);
+
+#if CHECK_APP_DOMAIN_LEAKS
+ static void EmitSetAppDomain(CPUSTUBLINKER *psl);
+ static void EmitCheckRestore(CPUSTUBLINKER *psl);
+#endif
+};
+#endif // _TARGET_X86_
+
+void *GenFastGetSharedStaticBase(bool bCheckCCtor);
+
+#ifdef HAVE_GCCOVER
+void SetupGcCoverage(MethodDesc* pMD, BYTE* nativeCode);
+void SetupGcCoverageForNativeImage(Module* module);
+bool IsGcCoverageInterrupt(LPVOID ip);
+BOOL OnGcCoverageInterrupt(PT_CONTEXT regs);
+void DoGcStress (PT_CONTEXT regs, MethodDesc *pMD);
+#endif //HAVE_GCCOVER
+
+EXTERN_C FCDECL2(LPVOID, ArrayStoreCheck, Object** pElement, PtrArray** pArray);
+
+OBJECTHANDLE ConstructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok);
+
+FCDECL2(Object*, JIT_Box, CORINFO_CLASS_HANDLE type, void* data);
+FCDECL0(VOID, JIT_PollGC);
+#ifdef ENABLE_FAST_GCPOLL_HELPER
+EXTERN_C FCDECL0(VOID, JIT_PollGC_Nop);
+#endif
+
+BOOL ObjIsInstanceOf(Object *pObject, TypeHandle toTypeHnd, BOOL throwCastException = FALSE);
+EXTERN_C TypeHandle::CastResult STDCALL ObjIsInstanceOfNoGC(Object *pObject, TypeHandle toTypeHnd);
+
+#ifdef _WIN64
+class InlinedCallFrame;
+Thread * __stdcall JIT_InitPInvokeFrame(InlinedCallFrame *pFrame, PTR_VOID StubSecretArg);
+#endif
+
+#ifdef _DEBUG
+extern LONG g_JitCount;
+#endif
+
+struct VirtualFunctionPointerArgs
+{
+ CORINFO_CLASS_HANDLE classHnd;
+ CORINFO_METHOD_HANDLE methodHnd;
+};
+
+FCDECL2(CORINFO_MethodPtr, JIT_VirtualFunctionPointer_Dynamic, Object * objectUNSAFE, VirtualFunctionPointerArgs * pArgs);
+
+typedef TADDR (F_CALL_CONV * FnStaticBaseHelper)(TADDR arg0, TADDR arg1);
+
+struct StaticFieldAddressArgs
+{
+ FnStaticBaseHelper staticBaseHelper;
+ TADDR arg0;
+ TADDR arg1;
+ SIZE_T offset;
+};
+
+FCDECL1(TADDR, JIT_StaticFieldAddress_Dynamic, StaticFieldAddressArgs * pArgs);
+FCDECL1(TADDR, JIT_StaticFieldAddressUnbox_Dynamic, StaticFieldAddressArgs * pArgs);
+
+CORINFO_GENERIC_HANDLE JIT_GenericHandleWorker(MethodDesc *pMD,
+ MethodTable *pMT,
+ LPVOID signature);
+
+void ClearJitGenericHandleCache(AppDomain *pDomain);
+
+class JitHelpers {
+public:
+ static FCDECL3(void, UnsafeSetArrayElement, PtrArray* pPtrArray, INT32 index, Object* object);
+};
+
+DWORD GetDebuggerCompileFlags(Module* pModule, DWORD flags);
+
+bool TrackAllocationsEnabled();
+
+#endif // JITINTERFACE_H
diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp index 20b532fd07..c918fcb02d 100644 --- a/src/zap/zapinfo.cpp +++ b/src/zap/zapinfo.cpp @@ -427,13 +427,14 @@ void ZapInfo::CompileMethod() // this they can add the hint and reduce the perf cost at runtime. m_pImage->m_pPreloader->PrePrepareMethodIfNecessary(m_currentMethodHandle); - int jitFlags = ComputeJitFlags(m_currentMethodHandle); + m_jitFlags = { 0 }; + m_jitFlags.corJitFlags = ComputeJitFlags(m_currentMethodHandle); #ifdef FEATURE_READYTORUN_COMPILER if (IsReadyToRunCompilation()) { // READYTORUN: FUTURE: Producedure spliting - jitFlags &= ~CORJIT_FLG_PROCSPLIT; + m_jitFlags.corJitFlags &= ~CORJIT_FLG_PROCSPLIT; DWORD methodAttribs = getMethodAttribs(m_currentMethodHandle); if (!(methodAttribs & CORINFO_FLG_NOSECURITYWRAP) || (methodAttribs & CORINFO_FLG_SECURITYCHECK)) @@ -444,13 +445,13 @@ void ZapInfo::CompileMethod() } #endif - if ((jitFlags & CORJIT_FLG_SKIP_VERIFICATION) == 0) + if ((m_jitFlags.corJitFlags & CORJIT_FLG_SKIP_VERIFICATION) == 0) { BOOL raiseVerificationException, unverifiableGenericCode; - jitFlags = GetCompileFlagsIfGenericInstantiation( + m_jitFlags.corJitFlags = GetCompileFlagsIfGenericInstantiation( m_currentMethodHandle, - (CorJitFlag)jitFlags, + (CorJitFlag)m_jitFlags.corJitFlags, this, &raiseVerificationException, &unverifiableGenericCode); @@ -462,6 +463,11 @@ void ZapInfo::CompileMethod() return; } +#if !defined(FEATURE_CORECLR) + // Ask the JIT to generate desktop-quirk-compatible code. + m_jitFlags.corJitFlags2 |= CORJIT_FLG2_DESKTOP_QUIRKS; +#endif + if (m_pImage->m_stats) { m_pImage->m_stats->m_methods++; @@ -480,7 +486,7 @@ void ZapInfo::CompileMethod() res = m_zapper->m_alternateJit->compileMethod( this, &m_currentMethodInfo, - jitFlags, + CORJIT_FLG_CALL_GETJITFLAGS, &pCode, &cCode ); if (FAILED(res)) @@ -498,7 +504,7 @@ void ZapInfo::CompileMethod() ICorJitCompiler * pCompiler = m_zapper->m_pJitCompiler; res = pCompiler->compileMethod(this, &m_currentMethodInfo, - jitFlags, + CORJIT_FLG_CALL_GETJITFLAGS, &pCode, &cCode); @@ -859,8 +865,10 @@ void ZapInfo::getGSCookie(GSCookie * pCookieVal, GSCookie ** ppCookieVal) DWORD ZapInfo::getJitFlags(CORJIT_FLAGS* jitFlags, DWORD sizeInBytes) { _ASSERTE(jitFlags != NULL); + _ASSERTE(sizeInBytes >= sizeof(m_jitFlags)); - return 0; + *jitFlags = m_jitFlags; + return sizeof(m_jitFlags); } IEEMemoryManager* ZapInfo::getMemoryManager() @@ -1682,7 +1690,7 @@ void ZapInfo::embedGenericSignature(CORINFO_LOOKUP * pLookup) if (IsReadyToRunCompilation()) { - UNREACHABLE_MSG("We should never get here for the ReadyToRun compilation."); + UNREACHABLE_MSG("We should never get here for the ReadyToRun compilation."); ThrowHR(E_NOTIMPL); } @@ -2139,8 +2147,8 @@ void ZapInfo::getCallInfo(CORINFO_RESOLVED_TOKEN * pResolvedToken, { if (pResult->stubLookup.lookupKind.needsRuntimeLookup) { - if (!IsReadyToRunCompilation()) - embedGenericSignature(&pResult->stubLookup); + if (!IsReadyToRunCompilation()) + embedGenericSignature(&pResult->stubLookup); return; } @@ -2173,8 +2181,8 @@ void ZapInfo::getCallInfo(CORINFO_RESOLVED_TOKEN * pResolvedToken, case CORINFO_CALL_CODE_POINTER: _ASSERTE(pResult->codePointerLookup.lookupKind.needsRuntimeLookup); - if (!IsReadyToRunCompilation()) - embedGenericSignature(&pResult->codePointerLookup); + if (!IsReadyToRunCompilation()) + embedGenericSignature(&pResult->codePointerLookup); // There is no easy way to detect method referenced via generic lookups in generated code. // Report this method reference unconditionally. @@ -2215,18 +2223,18 @@ void ZapInfo::getCallInfo(CORINFO_RESOLVED_TOKEN * pResolvedToken, case CORINFO_VIRTUALCALL_LDVIRTFTN: #ifdef FEATURE_READYTORUN_COMPILER - if (IsReadyToRunCompilation() && !pResult->exactContextNeedsRuntimeLookup) - { - DWORD fAtypicalCallsite = (flags & CORINFO_CALLINFO_ATYPICAL_CALLSITE) ? CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE : 0; + if (IsReadyToRunCompilation() && !pResult->exactContextNeedsRuntimeLookup) + { + DWORD fAtypicalCallsite = (flags & CORINFO_CALLINFO_ATYPICAL_CALLSITE) ? CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE : 0; - ZapImport * pImport = m_pImage->GetImportTable()->GetDynamicHelperCell( - (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_VIRTUAL_ENTRY | fAtypicalCallsite), pResult->hMethod, pResolvedToken); + ZapImport * pImport = m_pImage->GetImportTable()->GetDynamicHelperCell( + (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_VIRTUAL_ENTRY | fAtypicalCallsite), pResult->hMethod, pResolvedToken); - pResult->codePointerLookup.constLookup.accessType = IAT_PVALUE; - pResult->codePointerLookup.constLookup.addr = pImport; + pResult->codePointerLookup.constLookup.accessType = IAT_PVALUE; + pResult->codePointerLookup.constLookup.addr = pImport; - _ASSERTE(!pResult->sig.hasTypeArg()); - } + _ASSERTE(!pResult->sig.hasTypeArg()); + } #endif // Include the declaring instantiation of virtual generic methods in the NGen image. @@ -2243,10 +2251,10 @@ void ZapInfo::getCallInfo(CORINFO_RESOLVED_TOKEN * pResolvedToken, { if (pResult->exactContextNeedsRuntimeLookup) { - // Nothing to do... The generic handle lookup gets embedded in to the codegen - // during the jitting of the call. - // (Note: The generic lookup in R2R is performed by a call to a helper at runtime, not by - // codegen emitted at crossgen time) + // Nothing to do... The generic handle lookup gets embedded in to the codegen + // during the jitting of the call. + // (Note: The generic lookup in R2R is performed by a call to a helper at runtime, not by + // codegen emitted at crossgen time) } else { @@ -2863,6 +2871,9 @@ void ZapInfo::getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken, m_pEEJitInfo->getFieldInfo(pResolvedToken, callerHandle, flags, pResult); #ifdef FEATURE_READYTORUN_COMPILER + CORINFO_EE_INFO eeInfo; + m_pEEJitInfo->getEEInfo(&eeInfo); + if (IsReadyToRunCompilation()) { if (pResult->accessAllowed != CORINFO_ACCESS_ALLOWED) @@ -2886,7 +2897,7 @@ void ZapInfo::getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken, { ZapImport * pImport = m_pImage->GetImportTable()->GetFieldImport(ENCODE_FIELD_OFFSET, pResolvedToken->hField, pResolvedToken); - if (pResult->offset > MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT / 2) + if (pResult->offset > eeInfo.maxUncheckedOffsetForNullObject / 2) { m_zapper->Warning(W("ReadyToRun: Cross-module instance fields with large offsets not supported\n")); ThrowHR(E_NOTIMPL); @@ -2913,7 +2924,7 @@ void ZapInfo::getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken, { ZapImport * pImport = m_pImage->GetImportTable()->GetClassImport(ENCODE_FIELD_BASE_OFFSET, pResolvedToken); - if (pResult->offset > MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT / 2) + if (pResult->offset > eeInfo.maxUncheckedOffsetForNullObject / 2) { m_zapper->Warning(W("ReadyToRun: Large objects crossing module boundaries not supported\n")); ThrowHR(E_NOTIMPL); @@ -3002,18 +3013,18 @@ void ZapInfo::getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken, break; case CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER: - { - // Nothing to do... The generic handle lookup gets embedded in to the codegen - // during the jitting of the field lookup. - // (Note: The generic lookup in R2R is performed by a call to a helper at runtime, not by - // codegen emitted at crossgen time) - // TODO: replace the call to the generic lookup helper and the call to the static helper function - // with a single call to a R2R cell that performs: - // 1) Generic handle lookup - // 2) Computes the statics base address - // 3) Generates a stub for subsequent lookups that includes dictionary access - // (For perf reasons) - } + { + // Nothing to do... The generic handle lookup gets embedded in to the codegen + // during the jitting of the field lookup. + // (Note: The generic lookup in R2R is performed by a call to a helper at runtime, not by + // codegen emitted at crossgen time) + // TODO: replace the call to the generic lookup helper and the call to the static helper function + // with a single call to a R2R cell that performs: + // 1) Generic handle lookup + // 2) Computes the statics base address + // 3) Generates a stub for subsequent lookups that includes dictionary access + // (For perf reasons) + } break; case CORINFO_FIELD_STATIC_ADDRESS: // field at given address @@ -3359,141 +3370,141 @@ unsigned ZapInfo::getClassNumInstanceFields(CORINFO_CLASS_HANDLE cls) CorInfoHelpFunc ZapInfo::getNewHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_METHOD_HANDLE callerHandle) { - if (IsReadyToRunCompilation()) - return CORINFO_HELP_NEWFAST; + if (IsReadyToRunCompilation()) + return CORINFO_HELP_NEWFAST; - classMustBeLoadedBeforeCodeIsRun(pResolvedToken->hClass); - return m_pEEJitInfo->getNewHelper(pResolvedToken, callerHandle); + classMustBeLoadedBeforeCodeIsRun(pResolvedToken->hClass); + return m_pEEJitInfo->getNewHelper(pResolvedToken, callerHandle); } CorInfoHelpFunc ZapInfo::getSharedCCtorHelper(CORINFO_CLASS_HANDLE clsHnd) { - return m_pEEJitInfo->getSharedCCtorHelper(clsHnd); + return m_pEEJitInfo->getSharedCCtorHelper(clsHnd); } CorInfoHelpFunc ZapInfo::getSecurityPrologHelper(CORINFO_METHOD_HANDLE ftn) { - return m_pEEJitInfo->getSecurityPrologHelper(ftn); + return m_pEEJitInfo->getSecurityPrologHelper(ftn); } CORINFO_CLASS_HANDLE ZapInfo::getTypeForBox(CORINFO_CLASS_HANDLE cls) { - return m_pEEJitInfo->getTypeForBox(cls); + return m_pEEJitInfo->getTypeForBox(cls); } CorInfoHelpFunc ZapInfo::getBoxHelper(CORINFO_CLASS_HANDLE cls) { - return m_pEEJitInfo->getBoxHelper(cls); + return m_pEEJitInfo->getBoxHelper(cls); } CorInfoHelpFunc ZapInfo::getUnBoxHelper(CORINFO_CLASS_HANDLE cls) { - return m_pEEJitInfo->getUnBoxHelper(cls); + return m_pEEJitInfo->getUnBoxHelper(cls); } CorInfoHelpFunc ZapInfo::getCastingHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fThrowing) { - if (IsReadyToRunCompilation()) - return (fThrowing ? CORINFO_HELP_CHKCASTANY : CORINFO_HELP_ISINSTANCEOFANY); + if (IsReadyToRunCompilation()) + return (fThrowing ? CORINFO_HELP_CHKCASTANY : CORINFO_HELP_ISINSTANCEOFANY); - return m_pEEJitInfo->getCastingHelper(pResolvedToken, fThrowing); + return m_pEEJitInfo->getCastingHelper(pResolvedToken, fThrowing); } CorInfoHelpFunc ZapInfo::getNewArrHelper(CORINFO_CLASS_HANDLE arrayCls) { - if (IsReadyToRunCompilation()) - return CORINFO_HELP_NEWARR_1_DIRECT; + if (IsReadyToRunCompilation()) + return CORINFO_HELP_NEWARR_1_DIRECT; - return m_pEEJitInfo->getNewArrHelper(arrayCls); + return m_pEEJitInfo->getNewArrHelper(arrayCls); } -bool ZapInfo::getReadyToRunHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, - CORINFO_LOOKUP_KIND * pGenericLookupKind, - CorInfoHelpFunc id, - CORINFO_CONST_LOOKUP * pLookup) +bool ZapInfo::getReadyToRunHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken, + CORINFO_LOOKUP_KIND * pGenericLookupKind, + CorInfoHelpFunc id, + CORINFO_CONST_LOOKUP * pLookup) { #ifdef FEATURE_READYTORUN_COMPILER - _ASSERTE(IsReadyToRunCompilation()); - - ZapImport * pImport = NULL; - - DWORD fAtypicalCallsite = (id & CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE); - id = (CorInfoHelpFunc)(id & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE); - - switch (id) - { - case CORINFO_HELP_READYTORUN_NEW: - if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0) - return false; // Requires runtime lookup. - pImport = m_pImage->GetImportTable()->GetDynamicHelperCell( - (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_NEW_HELPER | fAtypicalCallsite), pResolvedToken->hClass); - break; - - case CORINFO_HELP_READYTORUN_NEWARR_1: - if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0) - return false; // Requires runtime lookup. - pImport = m_pImage->GetImportTable()->GetDynamicHelperCell( - (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_NEW_ARRAY_HELPER | fAtypicalCallsite), pResolvedToken->hClass); - break; - - case CORINFO_HELP_READYTORUN_ISINSTANCEOF: - if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0) - return false; // Requires runtime lookup. - pImport = m_pImage->GetImportTable()->GetDynamicHelperCell( - (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_ISINSTANCEOF_HELPER | fAtypicalCallsite), pResolvedToken->hClass); - break; - - case CORINFO_HELP_READYTORUN_CHKCAST: - if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0) - return false; // Requires runtime lookup. - pImport = m_pImage->GetImportTable()->GetDynamicHelperCell( - (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_CHKCAST_HELPER | fAtypicalCallsite), pResolvedToken->hClass); - break; - - case CORINFO_HELP_READYTORUN_STATIC_BASE: - if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0) - return false; // Requires runtime lookup. - if (m_pImage->GetCompileInfo()->IsInCurrentVersionBubble(m_pEEJitInfo->getClassModule(pResolvedToken->hClass))) - { - pImport = m_pImage->GetImportTable()->GetDynamicHelperCell( - (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_CCTOR_TRIGGER | fAtypicalCallsite), pResolvedToken->hClass); - } - else - { - // READYTORUN: FUTURE: Cross-module static cctor triggers - m_zapper->Warning(W("ReadyToRun: Cross-module static cctor triggers not supported\n")); - ThrowHR(E_NOTIMPL); - } - break; - - case CORINFO_HELP_READYTORUN_GENERIC_HANDLE: - _ASSERTE(pGenericLookupKind != NULL && pGenericLookupKind->needsRuntimeLookup); - if (pGenericLookupKind->runtimeLookupKind == CORINFO_LOOKUP_METHODPARAM) - { - pImport = m_pImage->GetImportTable()->GetDictionaryLookupCell( - (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_DICTIONARY_LOOKUP_METHOD | fAtypicalCallsite), pResolvedToken, pGenericLookupKind); - } - else if (pGenericLookupKind->runtimeLookupKind == CORINFO_LOOKUP_THISOBJ) - { - pImport = m_pImage->GetImportTable()->GetDictionaryLookupCell( - (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_DICTIONARY_LOOKUP_THISOBJ | fAtypicalCallsite), pResolvedToken, pGenericLookupKind); - } - else - { - _ASSERTE(pGenericLookupKind->runtimeLookupKind == CORINFO_LOOKUP_CLASSPARAM); - pImport = m_pImage->GetImportTable()->GetDictionaryLookupCell( - (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_DICTIONARY_LOOKUP_TYPE | fAtypicalCallsite), pResolvedToken, pGenericLookupKind); - } - break; - - default: - _ASSERTE(false); - ThrowHR(E_NOTIMPL); - } - - pLookup->accessType = IAT_PVALUE; - pLookup->addr = pImport; - return true; + _ASSERTE(IsReadyToRunCompilation()); + + ZapImport * pImport = NULL; + + DWORD fAtypicalCallsite = (id & CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE); + id = (CorInfoHelpFunc)(id & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE); + + switch (id) + { + case CORINFO_HELP_READYTORUN_NEW: + if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0) + return false; // Requires runtime lookup. + pImport = m_pImage->GetImportTable()->GetDynamicHelperCell( + (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_NEW_HELPER | fAtypicalCallsite), pResolvedToken->hClass); + break; + + case CORINFO_HELP_READYTORUN_NEWARR_1: + if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0) + return false; // Requires runtime lookup. + pImport = m_pImage->GetImportTable()->GetDynamicHelperCell( + (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_NEW_ARRAY_HELPER | fAtypicalCallsite), pResolvedToken->hClass); + break; + + case CORINFO_HELP_READYTORUN_ISINSTANCEOF: + if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0) + return false; // Requires runtime lookup. + pImport = m_pImage->GetImportTable()->GetDynamicHelperCell( + (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_ISINSTANCEOF_HELPER | fAtypicalCallsite), pResolvedToken->hClass); + break; + + case CORINFO_HELP_READYTORUN_CHKCAST: + if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0) + return false; // Requires runtime lookup. + pImport = m_pImage->GetImportTable()->GetDynamicHelperCell( + (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_CHKCAST_HELPER | fAtypicalCallsite), pResolvedToken->hClass); + break; + + case CORINFO_HELP_READYTORUN_STATIC_BASE: + if ((getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) != 0) + return false; // Requires runtime lookup. + if (m_pImage->GetCompileInfo()->IsInCurrentVersionBubble(m_pEEJitInfo->getClassModule(pResolvedToken->hClass))) + { + pImport = m_pImage->GetImportTable()->GetDynamicHelperCell( + (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_CCTOR_TRIGGER | fAtypicalCallsite), pResolvedToken->hClass); + } + else + { + // READYTORUN: FUTURE: Cross-module static cctor triggers + m_zapper->Warning(W("ReadyToRun: Cross-module static cctor triggers not supported\n")); + ThrowHR(E_NOTIMPL); + } + break; + + case CORINFO_HELP_READYTORUN_GENERIC_HANDLE: + _ASSERTE(pGenericLookupKind != NULL && pGenericLookupKind->needsRuntimeLookup); + if (pGenericLookupKind->runtimeLookupKind == CORINFO_LOOKUP_METHODPARAM) + { + pImport = m_pImage->GetImportTable()->GetDictionaryLookupCell( + (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_DICTIONARY_LOOKUP_METHOD | fAtypicalCallsite), pResolvedToken, pGenericLookupKind); + } + else if (pGenericLookupKind->runtimeLookupKind == CORINFO_LOOKUP_THISOBJ) + { + pImport = m_pImage->GetImportTable()->GetDictionaryLookupCell( + (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_DICTIONARY_LOOKUP_THISOBJ | fAtypicalCallsite), pResolvedToken, pGenericLookupKind); +} + else + { + _ASSERTE(pGenericLookupKind->runtimeLookupKind == CORINFO_LOOKUP_CLASSPARAM); + pImport = m_pImage->GetImportTable()->GetDictionaryLookupCell( + (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_DICTIONARY_LOOKUP_TYPE | fAtypicalCallsite), pResolvedToken, pGenericLookupKind); + } + break; + + default: + _ASSERTE(false); + ThrowHR(E_NOTIMPL); + } + + pLookup->accessType = IAT_PVALUE; + pLookup->addr = pImport; + return true; #else return false; #endif @@ -3921,3 +3932,4 @@ BOOL ZapInfo::CurrentMethodHasProfileData() ICorJitInfo::ProfileBuffer * profileBuffer; return SUCCEEDED(getBBProfileData(m_currentMethodHandle, &size, &profileBuffer, NULL)); } + diff --git a/src/zap/zapinfo.h b/src/zap/zapinfo.h index d2a29b7a59..3d8736f067 100644 --- a/src/zap/zapinfo.h +++ b/src/zap/zapinfo.h @@ -227,6 +227,8 @@ class ZapInfo LoadTable<CORINFO_CLASS_HANDLE> m_ClassLoadTable; LoadTable<CORINFO_METHOD_HANDLE> m_MethodLoadTable; + CORJIT_FLAGS m_jitFlags; + void InitMethodName(); int ComputeJitFlags(CORINFO_METHOD_HANDLE handle); |