diff options
Diffstat (limited to 'src/vm/jitinterface.cpp')
-rw-r--r-- | src/vm/jitinterface.cpp | 505 |
1 files changed, 135 insertions, 370 deletions
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp index ecabc89ba7..d960394e12 100644 --- a/src/vm/jitinterface.cpp +++ b/src/vm/jitinterface.cpp @@ -24,7 +24,6 @@ #include "excep.h" #include "float.h" // for isnan #include "dbginterface.h" -#include "security.h" #include "dllimport.h" #include "gcheaputilities.h" #include "comdelegate.h" @@ -47,7 +46,6 @@ #include "genericdict.h" #include "array.h" #include "debuginfostore.h" -#include "security.h" #include "safemath.h" #include "runtimehandles.h" #include "sigbuilder.h" @@ -68,6 +66,10 @@ #include "interpreter.h" #endif // FEATURE_INTERPRETER +#ifdef FEATURE_PERFMAP +#include "perfmap.h" +#endif + // The Stack Overflow probe takes place in the COOPERATIVE_TRANSITION_BEGIN() macro // @@ -1783,9 +1785,7 @@ void CEEInfo::getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken, fieldAttribs, NULL, (flags & CORINFO_ACCESS_INIT_ARRAY) ? NULL : pField, // For InitializeArray, we don't need tocheck the type of the field. - accessCheckOptions, - FALSE /*checkTargetMethodTransparency*/, - TRUE /*checkTargetTypeTransparency*/); + accessCheckOptions); if (!canAccess) { @@ -1924,14 +1924,6 @@ CEEInfo::findCallSiteSig( if (TypeFromToken(sigMethTok) == mdtMemberRef) { IfFailThrow(module->GetMDImport()->GetNameAndSigOfMemberRef(sigMethTok, &pSig, &cbSig, &szName)); - - // Defs have already been checked by the loader for validity - // However refs need to be checked. - if (!Security::CanSkipVerification(module->GetDomainAssembly())) - { - // Can pass 0 for the flags, since it is only used for defs. - IfFailThrow(validateTokenSig(sigMethTok, pSig, cbSig, 0, module->GetMDImport())); - } } else if (TypeFromToken(sigMethTok) == mdtMethodDef) { @@ -3093,6 +3085,7 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr pResult->signature = NULL; pResult->indirectFirstOffset = 0; + pResult->indirectSecondOffset = 0; // Unless we decide otherwise, just do the lookup via a helper function pResult->indirections = CORINFO_USEHELPER; @@ -3139,9 +3132,6 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr #ifdef FEATURE_READYTORUN_COMPILER if (IsReadyToRunCompilation()) { -#if defined(_TARGET_ARM_) - ThrowHR(E_NOTIMPL); /* TODO - NYI */ -#endif pResultLookup->lookupKind.runtimeLookupArgs = NULL; switch (entryKind) @@ -3307,6 +3297,12 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr IfFailThrow(sigptr.GetData(&data)); pResult->offsets[2] = sizeof(TypeHandle) * data; + if (MethodTable::IsPerInstInfoRelative()) + { + pResult->indirectFirstOffset = 1; + pResult->indirectSecondOffset = 1; + } + return; } else if (type == ELEMENT_TYPE_GENERICINST && @@ -3554,6 +3550,12 @@ NoSpecialCase: // Next indirect through the dictionary appropriate to this instantiated type pResult->offsets[1] = sizeof(TypeHandle*) * (pContextMT->GetNumDicts() - 1); + + if (MethodTable::IsPerInstInfoRelative()) + { + pResult->indirectFirstOffset = 1; + pResult->indirectSecondOffset = 1; + } } } } @@ -5554,9 +5556,7 @@ void CEEInfo::getCallInfo( pCalleeForSecurity->GetAttrs(), pCalleeForSecurity, NULL, - accessCheckOptions, - FALSE, - TRUE + accessCheckOptions ); // If we were allowed access to the exact method, but it is on a type that has a type parameter @@ -5576,11 +5576,10 @@ void CEEInfo::getCallInfo( // No accees check is need for Var, MVar, or FnPtr. if (pTypeParamMT != NULL) - canAccessMethod = ClassLoader::CanAccessClassForExtraChecks(&accessContext, - pTypeParamMT, - typeParam.GetAssembly(), - accessCheckOptions, - TRUE); + canAccessMethod = ClassLoader::CanAccessClass(&accessContext, + pTypeParamMT, + typeParam.GetAssembly(), + accessCheckOptions); } pResult->accessAllowed = canAccessMethod ? CORINFO_ACCESS_ALLOWED : CORINFO_ACCESS_ILLEGAL; @@ -6457,6 +6456,48 @@ const char* CEEInfo::getMethodName (CORINFO_METHOD_HANDLE ftnHnd, const char** s return result; } +const char* CEEInfo::getMethodNameFromMetadata(CORINFO_METHOD_HANDLE ftnHnd, const char** className, const char** namespaceName) +{ + CONTRACTL { + SO_TOLERANT; + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } CONTRACTL_END; + + const char* result = NULL; + const char* classResult = NULL; + const char* namespaceResult = NULL; + + JIT_TO_EE_TRANSITION(); + + MethodDesc *ftn = GetMethod(ftnHnd); + mdMethodDef token = ftn->GetMemberDef(); + + if (!IsNilToken(token)) + { + if (!FAILED(ftn->GetMDImport()->GetNameOfMethodDef(token, &result))) + { + MethodTable* pMT = ftn->GetMethodTable(); + classResult = pMT->GetFullyQualifiedNameInfo(&namespaceResult); + } + } + + if (className != NULL) + { + *className = classResult; + } + + if (namespaceName != NULL) + { + *namespaceName = namespaceResult; + } + + EE_TO_JIT_TRANSITION(); + + return result; +} + /*********************************************************************/ DWORD CEEInfo::getMethodAttribs (CORINFO_METHOD_HANDLE ftn) { @@ -6494,13 +6535,10 @@ DWORD CEEInfo::getMethodAttribsInternal (CORINFO_METHOD_HANDLE ftn) if (pMD->IsLCGMethod()) { -#ifndef CROSSGEN_COMPILE -#endif // !CROSSGEN_COMPILE - return CORINFO_FLG_STATIC | CORINFO_FLG_DONT_INLINE | CORINFO_FLG_NOSECURITYWRAP; } - DWORD result = 0; + DWORD result = CORINFO_FLG_NOSECURITYWRAP; // <REVISIT_TODO>@todo: can we git rid of CORINFO_FLG_ stuff and just include cor.h?</REVISIT_TODO> @@ -6514,6 +6552,8 @@ DWORD CEEInfo::getMethodAttribsInternal (CORINFO_METHOD_HANDLE ftn) result |= CORINFO_FLG_SYNCH; if (pMD->IsFCallOrIntrinsic()) result |= CORINFO_FLG_NOGCCHECK | CORINFO_FLG_INTRINSIC; + if (pMD->IsJitIntrinsic()) + result |= CORINFO_FLG_JIT_INTRINSIC; if (IsMdVirtual(attribs)) result |= CORINFO_FLG_VIRTUAL; if (IsMdAbstract(attribs)) @@ -6554,11 +6594,6 @@ DWORD CEEInfo::getMethodAttribsInternal (CORINFO_METHOD_HANDLE ftn) result |= CORINFO_FLG_PINVOKE; } - if (!pMD->IsInterceptedForDeclSecurity()) - { - result |= CORINFO_FLG_NOSECURITYWRAP; - } - if (IsMdRequireSecObject(attribs)) { // Assume all methods marked as DynamicSecurity are @@ -6640,15 +6675,6 @@ void CEEInfo::setMethodAttribs ( } } - // Both CORINFO_FLG_UNVERIFIABLE and CORINFO_FLG_VERIFIABLE cannot be set - _ASSERTE(!(attribs & CORINFO_FLG_UNVERIFIABLE) || - !(attribs & CORINFO_FLG_VERIFIABLE )); - - if (attribs & CORINFO_FLG_VERIFIABLE) - ftn->SetIsVerified(TRUE); - else if (attribs & CORINFO_FLG_UNVERIFIABLE) - ftn->SetIsVerified(FALSE); - EE_TO_JIT_TRANSITION(); } @@ -6870,7 +6896,8 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } - else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_AS)->GetMemberDef()) + else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_AS)->GetMemberDef() || + tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__OBJECT_AS)->GetMemberDef()) { // Return the argument that was passed in. static const BYTE ilcode[] = { CEE_LDARG_0, CEE_RET }; @@ -6881,7 +6908,8 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn, methInfo->options = (CorInfoOptions)0; return true; } - else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_ADD)->GetMemberDef()) + else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_ADD)->GetMemberDef() || + tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__PTR_ADD)->GetMemberDef()) { mdToken tokGenericArg = FindGenericMethodArgTypeSpec(MscorlibBinder::GetModule()->GetMDImport()); @@ -7204,31 +7232,41 @@ getMethodInfoHelper( bool fILIntrinsic = false; MethodTable * pMT = ftn->GetMethodTable(); - - if (MscorlibBinder::IsClass(pMT, CLASS__JIT_HELPERS)) - { - fILIntrinsic = getILIntrinsicImplementation(ftn, methInfo); - } - else if (MscorlibBinder::IsClass(pMT, CLASS__UNSAFE)) - { - fILIntrinsic = getILIntrinsicImplementationForUnsafe(ftn, methInfo); - } - else if (MscorlibBinder::IsClass(pMT, CLASS__INTERLOCKED)) - { - fILIntrinsic = getILIntrinsicImplementationForInterlocked(ftn, methInfo); - } - else if (MscorlibBinder::IsClass(pMT, CLASS__VOLATILE)) - { - fILIntrinsic = getILIntrinsicImplementationForVolatile(ftn, methInfo); - } - else if (MscorlibBinder::IsClass(pMT, CLASS__RUNTIME_HELPERS)) + + if (pMT->GetModule()->IsSystem()) { - fILIntrinsic = getILIntrinsicImplementationForRuntimeHelpers(ftn, methInfo); + if (MscorlibBinder::IsClass(pMT, CLASS__JIT_HELPERS)) + { + fILIntrinsic = getILIntrinsicImplementation(ftn, methInfo); + } + else if (MscorlibBinder::IsClass(pMT, CLASS__UNSAFE)) + { + fILIntrinsic = getILIntrinsicImplementationForUnsafe(ftn, methInfo); + } + else if (MscorlibBinder::IsClass(pMT, CLASS__INTERLOCKED)) + { + fILIntrinsic = getILIntrinsicImplementationForInterlocked(ftn, methInfo); + } + else if (MscorlibBinder::IsClass(pMT, CLASS__VOLATILE)) + { + fILIntrinsic = getILIntrinsicImplementationForVolatile(ftn, methInfo); + } + else if (MscorlibBinder::IsClass(pMT, CLASS__RUNTIME_HELPERS)) + { + fILIntrinsic = getILIntrinsicImplementationForRuntimeHelpers(ftn, methInfo); + } } if (!fILIntrinsic) { getMethodInfoILMethodHeaderHelper(header, methInfo); + + // Workaround for https://github.com/dotnet/coreclr/issues/1279 + // Set init locals bit to zero for system module unless profiler may have overrided it. Remove once we have + // better solution for this issue. + if (pMT->GetModule()->IsSystem() && !(CORProfilerDisableAllNGenImages() || CORProfilerUseProfileImages())) + methInfo->options = (CorInfoOptions)0; + pLocalSig = header->LocalVarSig; cbLocalSig = header->cbLocalVarSig; } @@ -7384,12 +7422,6 @@ CEEInfo::getMethodInfo( else { /* Get the IL header */ - /* <REVISIT_TODO>TODO: canInline already did validation, however, we do it again - here because NGEN uses this function without calling canInline - It would be nice to avoid this redundancy </REVISIT_TODO>*/ - Module* pModule = ftn->GetModule(); - - bool verify = !Security::CanSkipVerification(ftn); if (ftn->IsDynamicMethod()) { @@ -7397,28 +7429,7 @@ CEEInfo::getMethodInfo( } else { - COR_ILMETHOD_DECODER::DecoderStatus status = COR_ILMETHOD_DECODER::SUCCESS; - COR_ILMETHOD_DECODER header(ftn->GetILHeader(TRUE), ftn->GetMDImport(), verify ? &status : NULL); - - // If we get a verification error then we try to demand SkipVerification for the module - if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR && - Security::CanSkipVerification(pModule->GetDomainAssembly())) - { - status = COR_ILMETHOD_DECODER::SUCCESS; - } - - if (status != COR_ILMETHOD_DECODER::SUCCESS) - { - if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR) - { - // Throw a verification HR - COMPlusThrowHR(COR_E_VERIFICATION); - } - else - { - COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_BAD_IL); - } - } + COR_ILMETHOD_DECODER header(ftn->GetILHeader(TRUE), ftn->GetMDImport(), NULL); getMethodInfoHelper(ftn, ftnHnd, &header, methInfo); } @@ -7545,25 +7556,6 @@ CorInfoInline CEEInfo::canInline (CORINFO_METHOD_HANDLE hCaller, Module * pOrigCallerModule; pOrigCallerModule = pOrigCaller->GetLoaderModule(); - // Prevent recursive compiling/inlining/verifying - if (pOrigCaller != pCallee) - { - // The Inliner may not do code verification. - // So never inline anything that is unverifiable / bad code. - if (!Security::CanSkipVerification(pCallee)) - { - // Inlinee needs to be verifiable - if (!pCallee->IsVerifiable()) - { - result = INLINE_NEVER; - szFailReason = "Inlinee is not verifiable"; - goto exit; - } - } - } - - // We check this here as the call to MethodDesc::IsVerifiable() - // may set CORINFO_FLG_DONT_INLINE. if (pCallee->IsNotInline()) { result = INLINE_NEVER; @@ -7672,64 +7664,10 @@ CorInfoInline CEEInfo::canInline (CORINFO_METHOD_HANDLE hCaller, { // #rejit // - // See if rejit-specific flags for the caller disable inlining - if ((ReJitManager::GetCurrentReJitFlags(pCaller) & - COR_PRF_CODEGEN_DISABLE_INLINING) != 0) - { - result = INLINE_FAIL; - szFailReason = "ReJIT request disabled inlining from caller"; - goto exit; - } - - // If the profiler has set a mask preventing inlining, always return - // false to the jit. - if (CORProfilerDisableInlining()) - { - result = INLINE_FAIL; - szFailReason = "Profiler disabled inlining globally"; - goto exit; - } - - // If the profiler wishes to be notified of JIT events and the result from - // the above tests will cause a function to be inlined, we need to tell the - // profiler that this inlining is going to take place, and give them a - // chance to prevent it. - { - BEGIN_PIN_PROFILER(CORProfilerTrackJITInfo()); - if (pCaller->IsILStub() || pCallee->IsILStub()) - { - // do nothing - } - else - { - BOOL fShouldInline; - - HRESULT hr = g_profControlBlock.pProfInterface->JITInlining( - (FunctionID)pCaller, - (FunctionID)pCallee, - &fShouldInline); - - if (SUCCEEDED(hr) && !fShouldInline) - { - result = INLINE_FAIL; - szFailReason = "Profiler disabled inlining locally"; - goto exit; - } - } - END_PIN_PROFILER(); - } - } -#endif // PROFILING_SUPPORTED - - -#ifdef PROFILING_SUPPORTED - if (CORProfilerPresent()) - { - // #rejit - // - // See if rejit-specific flags for the caller disable inlining - if ((ReJitManager::GetCurrentReJitFlags(pCaller) & - COR_PRF_CODEGEN_DISABLE_INLINING) != 0) + // Currently the rejit path is the only path which sets this. + // If we get more reasons to set this then we may need to change + // the failure reason message or disambiguate them. + if (!m_allowInlining) { result = INLINE_FAIL; szFailReason = "ReJIT request disabled inlining from caller"; @@ -8018,8 +7956,7 @@ CorInfoInstantiationVerification goto exit; } - result = pMethod->IsVerifiable() ? INSTVER_GENERIC_PASSED_VERIFICATION - : INSTVER_GENERIC_FAILED_VERIFICATION; + result = INSTVER_GENERIC_PASSED_VERIFICATION; exit: ; @@ -8074,16 +8011,6 @@ bool CEEInfo::canTailCall (CORINFO_METHOD_HANDLE hCaller, goto exit; } - // TailCalls will throw off security stackwalking logic when there is a declarative Assert - // Note that this check will also include declarative demands. It's OK to do a tailcall in - // those cases, but we currently don't have a way to check only for declarative Asserts. - if (pCaller->IsInterceptedForDeclSecurity()) - { - result = false; - szFailReason = "Caller has declarative security"; - goto exit; - } - if (!fIsTailPrefix) { mdMethodDef callerToken = pCaller->GetMemberDef(); @@ -8581,7 +8508,8 @@ CONTRACTL { /*********************************************************************/ void CEEInfo::getMethodVTableOffset (CORINFO_METHOD_HANDLE methodHnd, unsigned * pOffsetOfIndirection, - unsigned * pOffsetAfterIndirection) + unsigned * pOffsetAfterIndirection, + bool * isRelative) { CONTRACTL { SO_TOLERANT; @@ -8602,8 +8530,9 @@ void CEEInfo::getMethodVTableOffset (CORINFO_METHOD_HANDLE methodHnd, // better be in the vtable _ASSERTE(method->GetSlot() < method->GetMethodTable()->GetNumVirtuals()); - *pOffsetOfIndirection = MethodTable::GetVtableOffset() + MethodTable::GetIndexOfVtableIndirection(method->GetSlot()) * sizeof(PTR_PCODE); + *pOffsetOfIndirection = MethodTable::GetVtableOffset() + MethodTable::GetIndexOfVtableIndirection(method->GetSlot()) * sizeof(MethodTable::VTableIndir_t); *pOffsetAfterIndirection = MethodTable::GetIndexAfterVtableIndirection(method->GetSlot()) * sizeof(PCODE); + *isRelative = MethodTable::VTableIndir_t::isRelative ? 1 : 0; EE_TO_JIT_TRANSITION_LEAF(); } @@ -9391,7 +9320,6 @@ CorInfoType CEEInfo::getHFAType(CORINFO_CLASS_HANDLE hClass) CorInfoType result = CORINFO_TYPE_UNDEF; -#ifdef FEATURE_HFA JIT_TO_EE_TRANSITION(); TypeHandle VMClsHnd(hClass); @@ -9399,7 +9327,6 @@ CorInfoType CEEInfo::getHFAType(CORINFO_CLASS_HANDLE hClass) result = asCorInfoType(VMClsHnd.GetHFAType()); EE_TO_JIT_TRANSITION(); -#endif return result; } @@ -11819,6 +11746,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, #ifdef FEATURE_INTERPRETER static ConfigDWORD s_InterpreterFallback; + bool isInterpreterStub = false; bool interpreterFallback = (s_InterpreterFallback.val(CLRConfig::INTERNAL_InterpreterFallback) != 0); if (interpreterFallback == false) @@ -11827,7 +11755,10 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, // (We assume that importation is completely architecture-independent, or at least nearly so.) if (FAILED(ret) && !jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) && !jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MAKEFINALCODE)) { - ret = Interpreter::GenerateInterpreterStub(comp, info, nativeEntry, nativeSizeOfCode); + if (SUCCEEDED(ret = Interpreter::GenerateInterpreterStub(comp, info, nativeEntry, nativeSizeOfCode))) + { + isInterpreterStub = true; + } } } @@ -11847,7 +11778,10 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, // (We assume that importation is completely architecture-independent, or at least nearly so.) if (FAILED(ret) && !jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) && !jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MAKEFINALCODE)) { - ret = Interpreter::GenerateInterpreterStub(comp, info, nativeEntry, nativeSizeOfCode); + if (SUCCEEDED(ret = Interpreter::GenerateInterpreterStub(comp, info, nativeEntry, nativeSizeOfCode))) + { + isInterpreterStub = true; + } } } #else @@ -11882,7 +11816,13 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr, #if defined(FEATURE_GDBJIT) - if (SUCCEEDED(ret) && *nativeEntry != NULL) + bool isJittedEntry = SUCCEEDED(ret) && *nativeEntry != NULL; + +#ifdef FEATURE_INTERPRETER + isJittedEntry &= !isInterpreterStub; +#endif // FEATURE_INTERPRETER + + if (isJittedEntry) { CodeHeader* pCH = ((CodeHeader*)((PCODE)*nativeEntry & ~1)) - 1; pCH->SetCalledMethods((PTR_VOID)comp->GetCalledMethods()); @@ -11926,13 +11866,6 @@ CorJitResult invokeCompileMethod(EEJitManager *jitMgr, return ret; } -CORJIT_FLAGS GetCompileFlagsIfGenericInstantiation( - CORINFO_METHOD_HANDLE method, - CORJIT_FLAGS compileFlags, - ICorJitInfo * pCorJitInfo, - BOOL * raiseVerificationException, - BOOL * unverifiableGenericCode); - CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr, CEEInfo *comp, struct CORINFO_METHOD_INFO *info, @@ -12182,22 +12115,10 @@ CORJIT_FLAGS GetCompileFlags(MethodDesc * ftn, CORJIT_FLAGS flags, CORINFO_METHO } } - // - // Verification flags - // - -#ifdef _DEBUG - if (g_pConfig->IsJitVerificationDisabled()) - flags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); -#endif // _DEBUG - - if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) && Security::CanSkipVerification(ftn)) - flags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); + flags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); if (ftn->IsILStub()) { - flags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); - // no debug info available for IL stubs flags.Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO); } @@ -12205,148 +12126,6 @@ CORJIT_FLAGS GetCompileFlags(MethodDesc * ftn, CORJIT_FLAGS flags, CORINFO_METHO return flags; } -#if defined(_WIN64) -//The implementation of Jit64 prevents it from both inlining and verifying at the same time. This causes a -//perf problem for code that adopts Transparency. This code attempts to enable inlining in spite of that -//limitation in that scenario. -// -//This only works for real methods. If the method isn't IsIL, then IsVerifiable will AV. That would be a -//bad thing (TM). -BOOL IsTransparentMethodSafeToSkipVerification(CORJIT_FLAGS flags, MethodDesc * ftn) -{ - STANDARD_VM_CONTRACT; - - BOOL ret = FALSE; - if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) && !flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION) - && Security::IsMethodTransparent(ftn) && - ((ftn->IsIL() && !ftn->IsUnboxingStub()) || - (ftn->IsDynamicMethod() && !ftn->IsILStub()))) - { - EX_TRY - { - //Verify the method - ret = ftn->IsVerifiable(); - } - EX_CATCH - { - //If the jit throws an exception, do not let it leak out of here. For example, we can sometimes - //get an IPE that we could recover from in the Jit (i.e. invalid local in a method with skip - //verification). - } - EX_END_CATCH(RethrowTerminalExceptions) - } - return ret; -} -#else -#define IsTransparentMethodSafeToSkipVerification(flags,ftn) (FALSE) -#endif //_WIN64 - -/*********************************************************************/ -// We verify generic code once and for all using the typical open type, -// and then no instantiations need to be verified. If verification -// failed, then we need to throw an exception whenever we try -// to compile a real instantiation - -CORJIT_FLAGS GetCompileFlagsIfGenericInstantiation( - CORINFO_METHOD_HANDLE method, - CORJIT_FLAGS compileFlags, - ICorJitInfo * pCorJitInfo, - BOOL * raiseVerificationException, - BOOL * unverifiableGenericCode) -{ - STANDARD_VM_CONTRACT; - - *raiseVerificationException = FALSE; - *unverifiableGenericCode = FALSE; - - // If we have already decided to skip verification, keep on going. - if (compileFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION)) - return compileFlags; - - CorInfoInstantiationVerification ver = pCorJitInfo->isInstantiationOfVerifiedGeneric(method); - - switch(ver) - { - case INSTVER_NOT_INSTANTIATION: - // Non-generic, or open instantiation of a generic type/method - if (IsTransparentMethodSafeToSkipVerification(compileFlags, (MethodDesc*)method)) - compileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); - return compileFlags; - - case INSTVER_GENERIC_PASSED_VERIFICATION: - // If the typical instantiation is verifiable, there is no need - // to verify the concrete instantiations - compileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); - return compileFlags; - - case INSTVER_GENERIC_FAILED_VERIFICATION: - - *unverifiableGenericCode = TRUE; - - // The generic method is not verifiable. - // Check if it has SkipVerification permission - MethodDesc * pGenMethod = GetMethod(method)->LoadTypicalMethodDefinition(); - - CORINFO_METHOD_HANDLE genMethodHandle = CORINFO_METHOD_HANDLE(pGenMethod); - - CorInfoCanSkipVerificationResult canSkipVer; - canSkipVer = pCorJitInfo->canSkipMethodVerification(genMethodHandle); - - switch(canSkipVer) - { - -#ifdef FEATURE_PREJIT - case CORINFO_VERIFICATION_DONT_JIT: - { - // Transparent code could be partial trust, but we don't know at NGEN time. - // This is the flag that NGEN passes to the JIT to tell it to give-up if it - // hits unverifiable code. Since we've already hit unverifiable code, - // there's no point in starting the JIT, just to have it give up, so we - // give up here. - _ASSERTE(compileFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_PREJIT)); - *raiseVerificationException = TRUE; - return CORJIT_FLAGS(); // This value will not be used - } -#else // FEATURE_PREJIT - // Need to have this case here to keep the MAC build happy - case CORINFO_VERIFICATION_DONT_JIT: - { - _ASSERTE(!"We should never get here"); - return compileFlags; - } -#endif // FEATURE_PREJIT - - case CORINFO_VERIFICATION_CANNOT_SKIP: - { - // For unverifiable generic code without SkipVerification permission, - // we cannot ask the compiler to emit CORINFO_HELP_VERIFICATION in - // unverifiable branches as the compiler cannot determine the unverifiable - // branches while compiling the concrete instantiation. Instead, - // just throw a VerificationException right away. - *raiseVerificationException = TRUE; - return CORJIT_FLAGS(); // This value will not be used - } - - case CORINFO_VERIFICATION_CAN_SKIP: - { - compileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION); - return compileFlags; - } - - case CORINFO_VERIFICATION_RUNTIME_CHECK: - { - // Compile the method without CORJIT_FLAG_SKIP_VERIFICATION. - // The compiler will know to add a call to - // CORINFO_HELP_VERIFICATION_RUNTIME_CHECK, and then to skip verification. - return compileFlags; - } - } - } - - _ASSERTE(!"We should never get here"); - return compileFlags; -} - // ******************************************************************** // Throw the right type of exception for the given JIT result @@ -12554,7 +12333,8 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader, CORJIT_ for (;;) { #ifndef CROSSGEN_COMPILE - CEEJitInfo jitInfo(ftn, ILHeader, jitMgr, flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY)); + CEEJitInfo jitInfo(ftn, ILHeader, jitMgr, flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY), + !flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_NO_INLINING)); #else // This path should be only ever used for verification in crossgen and so we should not need EEJitManager _ASSERTE(flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY)); @@ -12604,26 +12384,12 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader, CORJIT_ pMethodForSecurity->GetAttrs(), pMethodForSecurity, NULL, - accessCheckOptions, - TRUE /*Check method transparency*/, - TRUE /*Check type transparency*/)) + accessCheckOptions)) { EX_THROW(EEMethodException, (pMethodForSecurity)); } } - BOOL raiseVerificationException, unverifiableGenericCode; - - flags = GetCompileFlagsIfGenericInstantiation( - ftnHnd, - flags, - &jitInfo, - &raiseVerificationException, - &unverifiableGenericCode); - - if (raiseVerificationException) - COMPlusThrow(kVerificationException); - CorJitResult res; PBYTE nativeEntry; ULONG sizeOfCode; @@ -12720,11 +12486,6 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader, CORJIT_ if (flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY)) { - // The method must been processed by the verifier. Note that it may - // either have been marked as verifiable or unverifiable. - // ie. IsVerified() does not imply IsVerifiable() - _ASSERTE(ftn->IsVerified()); - // We are done break; } @@ -12829,6 +12590,10 @@ void Module::LoadHelperTable() BYTE * curEntry = table; BYTE * tableEnd = table + tableSize; +#ifdef FEATURE_PERFMAP + PerfMap::LogStubs(__FUNCTION__, GetSimpleName(), (PCODE)table, tableSize); +#endif + #ifdef LOGGING int iEntryNumber = 0; #endif // LOGGING |