From c1a182c3e5ffb402c17d4047550ee97f0d7af041 Mon Sep 17 00:00:00 2001 From: Brian Sullivan Date: Wed, 12 Jul 2017 15:38:15 -0700 Subject: [PATCH] Improvements in the Zapper to VM interface, no longer throw exceptions across the interface. Catch the exception on the VM side of the interface call and report the error to the zapper using an Error() function call rather than letting the exception go across tyhe interface call. The interface methods LoadIBCTypeHelper and LoadIBCMethodHelper no longer need a ThrowsViolation in their contracts. Instead oif using BAD_FORMAT exceptions for a failures to load IBC data type and methods, we now throw TypeLoad exception. --- src/dlls/mscorrc/mscorrc.rc | 7 +- src/dlls/mscorrc/resource.h | 7 +- src/inc/corcompile.h | 6 +- src/vm/ceeload.cpp | 166 ++++++++++---------------------------------- src/vm/ceeload.h | 10 +-- src/vm/compile.cpp | 70 ++++++++++--------- src/vm/compile.h | 2 +- src/vm/siginfo.cpp | 12 ++-- src/vm/typehash.cpp | 2 +- src/zap/zapimage.cpp | 139 ++++++++++++++++++------------------- src/zap/zapinfo.cpp | 2 +- 11 files changed, 161 insertions(+), 262 deletions(-) diff --git a/src/dlls/mscorrc/mscorrc.rc b/src/dlls/mscorrc/mscorrc.rc index bb2a9ee..8dd29ae 100644 --- a/src/dlls/mscorrc/mscorrc.rc +++ b/src/dlls/mscorrc/mscorrc.rc @@ -851,6 +851,8 @@ BEGIN IDS_EE_PROC_NOT_FOUND "A procedure imported by '%1' could not be loaded." IDS_EE_SIMD_NGEN_DISALLOWED "Target-dependent SIMD vector types may not be used with ngen." IDS_EE_SIMD_PARTIAL_TRUST_DISALLOWED "SIMD intrinsics may not be used by partial trust applications." + IDS_IBC_MISSING_EXTERNAL_TYPE "The generic type specified by the IBC data is not available to this assembly" + IDS_IBC_MISSING_EXTERNAL_METHOD "The generic method specified by the IBC data is not available to this assembly" IDS_INET_E_CANNOT_CONNECT "Cannot connect to URL for '%1'." IDS_INET_E_RESOURCE_NOT_FOUND "The server or proxy was not found for '%1'." @@ -2038,11 +2040,6 @@ BEGIN BFA_TYPEDBYREFCANNOTHAVEBYREF "An ELEMENT_TYPE_TYPEDBYREF cannot have a ELEMENT_TYPE_BYREF modifier." BFA_REFERENCE_ASSEMBLY "Cannot load a reference assembly for execution." -#ifdef FEATURE_PREJIT - BFA_MISSING_IBC_EXTERNAL_TYPE "The type specified by the IBC data is no longer present in the assembly's metadata" - BFA_MISSING_IBC_EXTERNAL_METHOD "The method specified by the IBC data is no longer present in the assembly's metadata" -#endif - #ifdef FEATURE_COMINTEROP BFA_WINRT_INVALID_NAMESPACE_FOR_TYPE "Windows Runtime type '%1' has invalid namespace that does not begin with the file name in assembly '%2'." #endif diff --git a/src/dlls/mscorrc/resource.h b/src/dlls/mscorrc/resource.h index 6153246..205445a 100644 --- a/src/dlls/mscorrc/resource.h +++ b/src/dlls/mscorrc/resource.h @@ -611,6 +611,8 @@ #define IDS_EE_SIMD_NGEN_DISALLOWED 0x1ac3 #define IDS_EE_SIMD_PARTIAL_TRUST_DISALLOWED 0x1ac4 +#define IDS_IBC_MISSING_EXTERNAL_TYPE 0x1ac5 +#define IDS_IBC_MISSING_EXTERNAL_METHOD 0x1ac6 #define BFA_INVALID_FILE_TOKEN 0x2000 #define BFA_INVALID_TOKEN_TYPE 0x2001 @@ -826,11 +828,6 @@ #define IDS_E_LOADFROM_REMOTE_SOURCE_MOTW 0x2204 -#ifdef FEATURE_PREJIT -#define BFA_MISSING_IBC_EXTERNAL_TYPE 0x2400 -#define BFA_MISSING_IBC_EXTERNAL_METHOD 0x2401 -#endif - // Profiler error messages for event log #define IDS_E_PROF_NO_CLSID 0x2500 #define IDS_E_PROF_INTERNAL_INIT 0x2501 diff --git a/src/inc/corcompile.h b/src/inc/corcompile.h index d7ac28d..31bf213 100644 --- a/src/inc/corcompile.h +++ b/src/inc/corcompile.h @@ -1156,12 +1156,12 @@ class ICorCompilePreloader // If the class or method is generic, instantiate all parameters with virtual CORINFO_METHOD_HANDLE LookupMethodDef(mdMethodDef token) = 0; + // For the given ftnHnd fill in the methInfo structure and return true if successful. + virtual bool GetMethodInfo(mdMethodDef token, CORINFO_METHOD_HANDLE ftnHnd, CORINFO_METHOD_INFO * methInfo) = 0; + // Returns region that the IL should be emitted in virtual CorCompileILRegion GetILRegion(mdMethodDef token) = 0; - // Find the (parameterized) type for the given blob from the profile data - virtual CORINFO_CLASS_HANDLE FindTypeForProfileEntry(CORBBTPROF_BLOB_PARAM_SIG_ENTRY * profileBlobEntry) = 0; - // Find the (parameterized) method for the given blob from the profile data virtual CORINFO_METHOD_HANDLE FindMethodForProfileEntry(CORBBTPROF_BLOB_PARAM_SIG_ENTRY * profileBlobEntry) = 0; diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp index 5049475..68af979 100644 --- a/src/vm/ceeload.cpp +++ b/src/vm/ceeload.cpp @@ -7374,7 +7374,9 @@ mdMethodDef Module::LookupIbcMethodToken(TypeHandle enclosingType, mdToken ibcTo ibcName.tkEnclosingClass = LookupIbcTypeToken(pExternalModule, ibcName.tkIbcNestedClass, optionalFullNameOut); if (IsNilToken(ibcName.tkEnclosingClass)) - THROW_BAD_FORMAT(BFA_MISSING_IBC_EXTERNAL_TYPE, this); + { + COMPlusThrow(kTypeLoadException, IDS_IBC_MISSING_EXTERNAL_TYPE); + } if (optionalFullNameOut != NULL) { @@ -7434,100 +7436,7 @@ mdMethodDef Module::LookupIbcMethodToken(TypeHandle enclosingType, mdToken ibcTo return mdResult; } -void Module::IBCTypeLoadFailed(CORBBTPROF_BLOB_PARAM_SIG_ENTRY *pBlobSigEntry, - SString& exceptionMessage, SString* typeNameError) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - PRECONDITION(CheckPointer(pBlobSigEntry)); - } - CONTRACTL_END - - // - // Print an error message for the type load failure - // - StackSString msg(W("Failed to load type token ")); - SString typeName; - - char buff[16]; - sprintf_s(buff, COUNTOF(buff), "%08x", pBlobSigEntry->blob.token); - StackSString szToken(SString::Ascii, &buff[0]); - msg += szToken; - - if (!exceptionMessage.IsEmpty()) - { - if ((typeNameError != NULL) && !typeNameError->IsEmpty()) - { - msg += W(" for the profile data in "); - msg.Append(exceptionMessage); - msg += W("."); - - msg += W(" The type was "); - msg.Append(*typeNameError); - msg += W("."); - } - else - { - msg += W(" from profile data. The error is "); - msg.Append(exceptionMessage); - } - } - msg += W("\n"); - - GetSvcLogger()->Log(msg, LogLevel_Info); -} - -void Module::IBCMethodLoadFailed(CORBBTPROF_BLOB_PARAM_SIG_ENTRY *pBlobSigEntry, - SString& exceptionMessage, SString* methodNameError) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM()); - PRECONDITION(CheckPointer(pBlobSigEntry)); - } - CONTRACTL_END - - // - // Print an error message for the type load failure - // - StackSString msg(W("Failed to load method token ")); - - char buff[16]; - sprintf_s(buff, COUNTOF(buff), "%08x", pBlobSigEntry->blob.token); - StackSString szToken(SString::Ascii, &buff[0]); - msg += szToken; - - if (!exceptionMessage.IsEmpty()) - { - if ((methodNameError != NULL) && !methodNameError->IsEmpty()) - { - msg += W(" for the profile data in "); - msg.Append(exceptionMessage); - msg += W("."); - - msg += W(" The method was "); - msg.Append(*methodNameError); - msg += W(".\n"); - } - else - { - msg += W(" from profile data. The error is "); - msg.Append(exceptionMessage); - } - } - msg += W("\n"); - - GetSvcLogger()->Log(msg, LogLevel_Info); -} - -TypeHandle Module::LoadIBCTypeHelper(CORBBTPROF_BLOB_PARAM_SIG_ENTRY *pBlobSigEntry) +TypeHandle Module::LoadIBCTypeHelper(DataImage *image, CORBBTPROF_BLOB_PARAM_SIG_ENTRY *pBlobSigEntry) { CONTRACT(TypeHandle) { @@ -7568,11 +7477,7 @@ TypeHandle Module::LoadIBCTypeHelper(CORBBTPROF_BLOB_PARAM_SIG_ENTRY *pBlobSigEn } EX_CATCH { - CONTRACT_VIOLATION(ThrowsViolation); - - StackSString exceptionMessage; - GET_EXCEPTION()->GetMessage(exceptionMessage); - IBCTypeLoadFailed(pBlobSigEntry, exceptionMessage, nullptr); + image->GetPreloader()->Error(pBlobSigEntry->blob.token, GET_EXCEPTION()); loadedType = TypeHandle(); } EX_END_CATCH(SwallowAllExceptions) @@ -7582,7 +7487,7 @@ TypeHandle Module::LoadIBCTypeHelper(CORBBTPROF_BLOB_PARAM_SIG_ENTRY *pBlobSigEn //--------------------------------------------------------------------------------------- // -MethodDesc* Module::LoadIBCMethodHelper(CORBBTPROF_BLOB_PARAM_SIG_ENTRY * pBlobSigEntry) +MethodDesc* Module::LoadIBCMethodHelper(DataImage *image, CORBBTPROF_BLOB_PARAM_SIG_ENTRY * pBlobSigEntry) { CONTRACT(MethodDesc*) { @@ -7629,11 +7534,7 @@ MethodDesc* Module::LoadIBCMethodHelper(CORBBTPROF_BLOB_PARAM_SIG_ENTRY * pBlobS } EX_CATCH { - CONTRACT_VIOLATION(ThrowsViolation); - - StackSString exceptionMessage; - GET_EXCEPTION()->GetMessage(exceptionMessage); - IBCTypeLoadFailed(pBlobSigEntry, exceptionMessage, nullptr); + image->GetPreloader()->Error(pBlobSigEntry->blob.token, GET_EXCEPTION()); enclosingType = TypeHandle(); } EX_END_CATCH(SwallowAllExceptions) @@ -7697,11 +7598,10 @@ MethodDesc* Module::LoadIBCMethodHelper(CORBBTPROF_BLOB_PARAM_SIG_ENTRY * pBlobS if (IsNilToken(methodToken)) { - THROW_BAD_FORMAT(BFA_MISSING_IBC_EXTERNAL_METHOD, this); + COMPlusThrow(kTypeLoadException, IDS_IBC_MISSING_EXTERNAL_METHOD); } } - SigTypeContext methodTypeContext( enclosingType ); pMethod = MemberLoader::GetMethodDescFromMemberDefOrRefOrSpec( pOwnerMT->GetModule(), @@ -7727,13 +7627,23 @@ MethodDesc* Module::LoadIBCMethodHelper(CORBBTPROF_BLOB_PARAM_SIG_ENTRY * pBlobS for (DWORD i = 0; i < nargs; i++) { - pInst[i] = p.GetTypeHandleThrowing( this, + TypeHandle curInst; + + curInst = p.GetTypeHandleThrowing( this, &typeContext, ClassLoader::LoadTypes, CLASS_LOADED, FALSE, NULL, pZapSigContext); + + // curInst will be nullptr when the type fails the versioning bubble check + if (curInst.IsNull() && IsReadyToRunCompilation()) + { + COMPlusThrow(kTypeLoadException, IDS_IBC_MISSING_EXTERNAL_TYPE); + } + + pInst[i] = curInst; IfFailThrow(p.SkipExactlyOne()); } @@ -7744,26 +7654,26 @@ MethodDesc* Module::LoadIBCMethodHelper(CORBBTPROF_BLOB_PARAM_SIG_ENTRY * pBlobS inst = pMethod->LoadMethodInstantiation(); } + // We should now be able to create an instantiation for this generic method + // This must be called even if nargs == 0, in order to create an instantiating // stub for static methods in generic classees if needed, also for BoxedEntryPointStubs // in non-generic structs. + const bool allowInstParam = !(isInstantiatingStub || isUnboxingStub); + pMethod = MethodDesc::FindOrCreateAssociatedMethodDesc(pMethod, pOwnerMT, - isUnboxingStub, - inst, - !(isInstantiatingStub || isUnboxingStub)); + isUnboxingStub, + inst, allowInstParam); #if defined(_DEBUG) && !defined(DACCESS_COMPILE) g_pConfig->DebugCheckAndForceIBCFailure(EEConfig::CallSite_3); #endif - } EX_CATCH { - CONTRACT_VIOLATION(ThrowsViolation); - - StackSString exceptionMessage; - GET_EXCEPTION()->GetMessage(exceptionMessage); - IBCMethodLoadFailed(pBlobSigEntry, exceptionMessage, nullptr); + // Catch any kTypeLoadException that we may have thrown above + // + image->GetPreloader()->Error(pBlobSigEntry->blob.token, GET_EXCEPTION()); pMethod = NULL; } EX_END_CATCH(SwallowAllExceptions) @@ -8066,7 +7976,8 @@ void Module::ExpandAll(DataImage *image) // // Load all the reported parameterized types and methods // - CORBBTPROF_BLOB_ENTRY *pBlobEntry = GetProfileData()->GetBlobStream(); + CorProfileData * profileData = this->GetProfileData(); + CORBBTPROF_BLOB_ENTRY *pBlobEntry = profileData->GetBlobStream(); if (pBlobEntry != NULL) { @@ -8077,7 +7988,8 @@ void Module::ExpandAll(DataImage *image) _ASSERTE(pBlobEntry->type == ParamTypeSpec); CORBBTPROF_BLOB_PARAM_SIG_ENTRY *pBlobSigEntry = (CORBBTPROF_BLOB_PARAM_SIG_ENTRY *) pBlobEntry; - TypeHandle th = LoadIBCTypeHelper(pBlobSigEntry); + TypeHandle th = LoadIBCTypeHelper(image, pBlobSigEntry); + if (!th.IsNull()) { image->GetPreloader()->TriageTypeForZap(th, TRUE); @@ -8088,17 +8000,13 @@ void Module::ExpandAll(DataImage *image) _ASSERTE(pBlobEntry->type == ParamMethodSpec); CORBBTPROF_BLOB_PARAM_SIG_ENTRY *pBlobSigEntry = (CORBBTPROF_BLOB_PARAM_SIG_ENTRY *) pBlobEntry; - MethodDesc *pMD = LoadIBCMethodHelper(pBlobSigEntry); - if (pMD != NULL) - { - image->GetPreloader()->TriageMethodForZap(pMD, TRUE); - } + MethodDesc *pMD = LoadIBCMethodHelper(image, pBlobSigEntry); } pBlobEntry = pBlobEntry->GetNextEntry(); } _ASSERTE(pBlobEntry->type == EndOfBlobStream); } - + { // // Fill out MemberRef RID map and va sig cookies for @@ -8715,7 +8623,7 @@ void Module::Save(DataImage *image) if (pBlobEntry->token == token) { CORBBTPROF_BLOB_PARAM_SIG_ENTRY *pBlobSigEntry = (CORBBTPROF_BLOB_PARAM_SIG_ENTRY *) pBlobEntry; - TypeHandle th = LoadIBCTypeHelper(pBlobSigEntry); + TypeHandle th = LoadIBCTypeHelper(image, pBlobSigEntry); if (!th.IsNull()) { @@ -9474,7 +9382,7 @@ void Module::Arrange(DataImage *image) // // decode generic type signature // - TypeHandle th = LoadIBCTypeHelper(pBlobSigEntry); + TypeHandle th = LoadIBCTypeHelper(image, pBlobSigEntry); // // Place a hot instantiated type and it's data @@ -9542,7 +9450,7 @@ void Module::Arrange(DataImage *image) else // (pBlobSigEntry != NULL) { _ASSERTE(pBlobSigEntry->blob.token == token); - MethodDesc * pMD = LoadIBCMethodHelper(pBlobSigEntry); + MethodDesc * pMD = LoadIBCMethodHelper(image, pBlobSigEntry); if (pMD != NULL) { diff --git a/src/vm/ceeload.h b/src/vm/ceeload.h index 5aeebb8..bc9937a 100644 --- a/src/vm/ceeload.h +++ b/src/vm/ceeload.h @@ -2936,17 +2936,11 @@ public: void SetProfileData(CorProfileData * profileData); CorProfileData *GetProfileData(); - mdTypeDef LookupIbcTypeToken( Module * pExternalModule, mdToken ibcToken, SString* optionalFullNameOut = NULL); mdMethodDef LookupIbcMethodToken(TypeHandle enclosingType, mdToken ibcToken, SString* optionalFullNameOut = NULL); - void IBCTypeLoadFailed( CORBBTPROF_BLOB_PARAM_SIG_ENTRY *pBlobSigEntry, - SString& exceptionMessage, SString* typeNameError); - void IBCMethodLoadFailed(CORBBTPROF_BLOB_PARAM_SIG_ENTRY *pBlobSigEntry, - SString& exceptionMessage, SString* typeNameError); - - TypeHandle LoadIBCTypeHelper( CORBBTPROF_BLOB_PARAM_SIG_ENTRY *pBlobSigEntry); - MethodDesc * LoadIBCMethodHelper(CORBBTPROF_BLOB_PARAM_SIG_ENTRY *pBlobSigEntry); + TypeHandle LoadIBCTypeHelper(DataImage *image, CORBBTPROF_BLOB_PARAM_SIG_ENTRY *pBlobSigEntry); + MethodDesc * LoadIBCMethodHelper(DataImage *image, CORBBTPROF_BLOB_PARAM_SIG_ENTRY *pBlobSigEntry); void ExpandAll(DataImage *image); diff --git a/src/vm/compile.cpp b/src/vm/compile.cpp index 5782a0b..abfe07e 100644 --- a/src/vm/compile.cpp +++ b/src/vm/compile.cpp @@ -5912,14 +5912,6 @@ void CEEPreloader::TriageMethodForZap(MethodDesc* pMD, BOOL fAcceptIfNotSure, BO goto Done; } - // Filter out other weird cases we do not care about. - if (!m_image->GetModule()->GetInstMethodHashTable()->ContainsMethodDesc(pMD)) - { - triage = Rejected; - rejectReason = "method is not in the current module"; - goto Done; - } - // Always store items in their preferred zap module even if we are not sure if (Module::GetPreferredZapModuleForMethodDesc(pMD) == m_image->GetModule()) { @@ -6601,20 +6593,45 @@ bool CEEPreloader::CanSkipMethodPreparation ( CORINFO_METHOD_HANDLE CEEPreloader::LookupMethodDef(mdMethodDef token) { STANDARD_VM_CONTRACT; + MethodDesc *resultMD = nullptr; - MethodDesc *pMD = MemberLoader::GetMethodDescFromMethodDef( - m_image->GetModule(), - token, - FALSE); + EX_TRY + { + MethodDesc *pMD = MemberLoader::GetMethodDescFromMethodDef(m_image->GetModule(), token, FALSE); + + if (IsReadyToRunCompilation() && pMD->HasClassOrMethodInstantiation()) + { + _ASSERTE(IsCompilationProcess() && pMD->GetModule_NoLogging() == GetAppDomain()->ToCompilationDomain()->GetTargetModule()); + } - if (IsReadyToRunCompilation() && pMD->HasClassOrMethodInstantiation()) + resultMD = pMD->FindOrCreateTypicalSharedInstantiation(); + } + EX_CATCH { - _ASSERTE(IsCompilationProcess() && pMD->GetModule_NoLogging() == GetAppDomain()->ToCompilationDomain()->GetTargetModule()); + this->Error(token, GET_EXCEPTION()); } + EX_END_CATCH(SwallowAllExceptions) + + return CORINFO_METHOD_HANDLE(resultMD); +} + +bool CEEPreloader::GetMethodInfo(mdMethodDef token, CORINFO_METHOD_HANDLE ftnHnd, CORINFO_METHOD_INFO * methInfo) +{ + STANDARD_VM_CONTRACT; + bool result = false; - pMD = pMD->FindOrCreateTypicalSharedInstantiation(); + EX_TRY + { + result = GetZapJitInfo()->getMethodInfo(ftnHnd, methInfo); + } + EX_CATCH + { + result = false; + this->Error(token, GET_EXCEPTION()); + } + EX_END_CATCH(SwallowAllExceptions) - return CORINFO_METHOD_HANDLE(pMD); + return result; } static BOOL MethodIsVisibleOutsideItsAssembly(DWORD dwMethodAttr) @@ -6710,33 +6727,20 @@ CorCompileILRegion CEEPreloader::GetILRegion(mdMethodDef token) return region; } -CORINFO_CLASS_HANDLE CEEPreloader::FindTypeForProfileEntry(CORBBTPROF_BLOB_PARAM_SIG_ENTRY * profileBlobEntry) -{ - STANDARD_VM_CONTRACT; - - _ASSERTE(profileBlobEntry->blob.type == ParamTypeSpec); - - if (PartialNGenStressPercentage() != 0) - return CORINFO_CLASS_HANDLE( NULL ); - - Module * pModule = GetAppDomain()->ToCompilationDomain()->GetTargetModule(); - TypeHandle th = pModule->LoadIBCTypeHelper(profileBlobEntry); - - return CORINFO_CLASS_HANDLE(th.AsPtr()); -} CORINFO_METHOD_HANDLE CEEPreloader::FindMethodForProfileEntry(CORBBTPROF_BLOB_PARAM_SIG_ENTRY * profileBlobEntry) { STANDARD_VM_CONTRACT; + MethodDesc * pMethod = nullptr; _ASSERTE(profileBlobEntry->blob.type == ParamMethodSpec); if (PartialNGenStressPercentage() != 0) return CORINFO_METHOD_HANDLE( NULL ); - - Module * pModule = GetAppDomain()->ToCompilationDomain()->GetTargetModule(); - MethodDesc * pMethod = pModule->LoadIBCMethodHelper(profileBlobEntry); + Module * pModule = GetAppDomain()->ToCompilationDomain()->GetTargetModule(); + pMethod = pModule->LoadIBCMethodHelper(m_image, profileBlobEntry); + return CORINFO_METHOD_HANDLE( pMethod ); } diff --git a/src/vm/compile.h b/src/vm/compile.h index 8618b01..5b932d5 100644 --- a/src/vm/compile.h +++ b/src/vm/compile.h @@ -637,10 +637,10 @@ public: void NoteDeduplicatedCode(CORINFO_METHOD_HANDLE method, CORINFO_METHOD_HANDLE duplicateMethod); CORINFO_METHOD_HANDLE LookupMethodDef(mdMethodDef token); + bool GetMethodInfo(mdMethodDef token, CORINFO_METHOD_HANDLE ftnHnd, CORINFO_METHOD_INFO * methInfo); CorCompileILRegion GetILRegion(mdMethodDef token); - CORINFO_CLASS_HANDLE FindTypeForProfileEntry(CORBBTPROF_BLOB_PARAM_SIG_ENTRY * profileBlobEntry); CORINFO_METHOD_HANDLE FindMethodForProfileEntry(CORBBTPROF_BLOB_PARAM_SIG_ENTRY * profileBlobEntry); void ReportInlining(CORINFO_METHOD_HANDLE inliner, CORINFO_METHOD_HANDLE inlinee); diff --git a/src/vm/siginfo.cpp b/src/vm/siginfo.cpp index 9f809b6..30dcf0f 100644 --- a/src/vm/siginfo.cpp +++ b/src/vm/siginfo.cpp @@ -1200,8 +1200,6 @@ TypeHandle SigPointer::GetTypeHandleThrowing( PREFIX_ASSUME(pZapSigContext != NULL); pModule = pZapSigContext->GetZapSigModule()->GetModuleFromIndex(ix); - // For ReadyToRunCompilation we return a null TypeHandle when we reference a non-local module - // if ((pModule != NULL) && pModule->IsInCurrentVersionBubble()) { thRet = psig.GetTypeHandleThrowing(pModule, @@ -1212,6 +1210,12 @@ TypeHandle SigPointer::GetTypeHandleThrowing( pSubst, pZapSigContext); } + else + { + // For ReadyToRunCompilation we return a null TypeHandle when we reference a non-local module + // + thRet = TypeHandle(); + } #else DacNotImpl(); thRet = TypeHandle(); @@ -1466,7 +1470,7 @@ TypeHandle SigPointer::GetTypeHandleThrowing( if (IsNilToken(typeToken)) { - THROW_BAD_FORMAT(BFA_MISSING_IBC_EXTERNAL_TYPE, pOrigModule); + COMPlusThrow(kTypeLoadException, IDS_IBC_MISSING_EXTERNAL_TYPE); } } #endif @@ -1768,7 +1772,7 @@ TypeHandle SigPointer::GetGenericInstType(Module * pModule, if (IsNilToken(typeToken)) { - THROW_BAD_FORMAT(BFA_MISSING_IBC_EXTERNAL_TYPE, pOrigModule); + COMPlusThrow(kTypeLoadException, IDS_IBC_MISSING_EXTERNAL_TYPE); } } #endif diff --git a/src/vm/typehash.cpp b/src/vm/typehash.cpp index 0d53a15..a1d6d77 100644 --- a/src/vm/typehash.cpp +++ b/src/vm/typehash.cpp @@ -716,7 +716,7 @@ void EETypeHashTable::Save(DataImage *image, Module *module, CorProfileData *pro { if (flags & (1<LoadIBCTypeHelper(pBlobSigEntry); + TypeHandle th = GetModule()->LoadIBCTypeHelper(image, pBlobSigEntry); #if defined(_DEBUG) && !defined(DACCESS_COMPILE) g_pConfig->DebugCheckAndForceIBCFailure(EEConfig::CallSite_8); #endif diff --git a/src/zap/zapimage.cpp b/src/zap/zapimage.cpp index 469b841..2b38eaf 100644 --- a/src/zap/zapimage.cpp +++ b/src/zap/zapimage.cpp @@ -1682,6 +1682,15 @@ void ZapImage::CompileHotRegion() compileResult = TryCompileInstantiatedMethod(pMethod, methodProfilingDataFlags); } + else + { + // This generic/parameterized method is not part of the native image + // Either the IBC type specified no longer exists or it is a SIMD types + // or the type can't be loaded in a ReadyToRun native image because of + // a cross-module type dependencies. + // + compileResult = COMPILE_EXCLUDED; + } } } @@ -1925,65 +1934,18 @@ ZapImage::CompileStatus ZapImage::TryCompileMethodDef(mdMethodDef md, unsigned m CORINFO_METHOD_HANDLE handle = NULL; CompileStatus result = NOT_COMPILED; - EX_TRY + if (ShouldCompileMethodDef(md)) { - if (ShouldCompileMethodDef(md)) - handle = m_pPreloader->LookupMethodDef(md); - else - result = COMPILE_EXCLUDED; - } - EX_CATCH - { - // Continue unwinding if fatal error was hit. - if (FAILED(g_hrFatalError)) - ThrowHR(g_hrFatalError); - - // COM introduces the notion of a vtable gap method, which is not a real method at all but instead - // aids in the explicit layout of COM interop vtables. These methods have no implementation and no - // direct runtime state tracking them. Trying to lookup a method handle for a vtable gap method will - // throw an exception but we choose to let that happen and filter out the warning here in the - // handler because (a) vtable gap methods are rare and (b) it's not all that cheap to identify them - // beforehand. - if (IsVTableGapMethod(md)) - { - handle = NULL; - } - else + handle = m_pPreloader->LookupMethodDef(md); + if (handle == nullptr) { - Exception *ex = GET_EXCEPTION(); - HRESULT hrException = ex->GetHR(); - - StackSString message; - ex->GetMessage(message); - - CorZapLogLevel level; - -#ifdef CROSSGEN_COMPILE - // Warnings should not go to stderr during crossgen - level = CORZAP_LOGLEVEL_WARNING; -#else - level = CORZAP_LOGLEVEL_ERROR; -#endif - - // FileNotFound errors here can be converted into a single error string per ngen compile, and the detailed error is available with verbose logging - if (hrException == COR_E_FILENOTFOUND) - { - StackSString logMessage(W("System.IO.FileNotFoundException: ")); - logMessage.Append(message); - FileNotFoundError(logMessage.GetUnicode()); - level = CORZAP_LOGLEVEL_INFO; - } - - m_zapper->Print(level, W("%s while compiling method token 0x%x\n"), message.GetUnicode(), md); - result = LOOKUP_FAILED; - - m_zapper->m_failed = TRUE; - if (m_stats) - m_stats->m_failedMethods++; } } - EX_END_CATCH(SwallowAllExceptions); + else + { + result = COMPILE_EXCLUDED; + } if (handle == NULL) return result; @@ -2187,28 +2149,44 @@ ZapImage::CompileStatus ZapImage::TryCompileMethodWorker(CORINFO_METHOD_HANDLE h Exception *ex = GET_EXCEPTION(); HRESULT hrException = ex->GetHR(); + CorZapLogLevel level; + +#ifdef CROSSGEN_COMPILE + // Warnings should not go to stderr during crossgen + level = CORZAP_LOGLEVEL_WARNING; +#else + level = CORZAP_LOGLEVEL_ERROR; + + m_zapper->m_failed = TRUE; +#endif + + result = COMPILE_FAILED; + #ifdef FEATURE_READYTORUN_COMPILER - // NYI features in R2R - Stop crossgen from spitting unnecessary messages to the console - if (IsReadyToRunCompilation() && hrException == E_NOTIMPL) + // NYI features in R2R - Stop crossgen from spitting unnecessary + // messages to the console + if (IsReadyToRunCompilation()) { - result = NOT_COMPILED; + // When compiling the method we may recieve an exeception when the + // method uses a feature that is Not Implemented for ReadyToRun + // or a Type Load exception if the method uses for a SIMD type. + // + // We skip the compilation of such methods and we don't want to + // issue a warning or error + // + if ((hrException == E_NOTIMPL) || (hrException == IDS_CLASSLOAD_GENERAL)) + { + result = NOT_COMPILED; + level = CORZAP_LOGLEVEL_INFO; + } } - else #endif { StackSString message; ex->GetMessage(message); - CorZapLogLevel level; - - #ifdef CROSSGEN_COMPILE - // Warnings should not go to stderr during crossgen - level = CORZAP_LOGLEVEL_WARNING; - #else - level = CORZAP_LOGLEVEL_ERROR; - #endif - - // FileNotFound errors here can be converted into a single error string per ngen compile, and the detailed error is available with verbose logging + // FileNotFound errors here can be converted into a single error string per ngen compile, + // and the detailed error is available with verbose logging if (hrException == COR_E_FILENOTFOUND) { StackSString logMessage(W("System.IO.FileNotFoundException: ")); @@ -2219,10 +2197,7 @@ ZapImage::CompileStatus ZapImage::TryCompileMethodWorker(CORINFO_METHOD_HANDLE h m_zapper->Print(level, W("%s while compiling method %s\n"), message.GetUnicode(), zapInfo.m_currentMethodName.GetUnicode()); - result = COMPILE_FAILED; - m_zapper->m_failed = TRUE; - - if (m_stats != NULL) + if ((result == COMPILE_FAILED) && (m_stats != NULL)) { if (!m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB)) m_stats->m_failedMethods++; @@ -3560,6 +3535,17 @@ void ZapImage::Error(mdToken token, HRESULT hr, UINT resID, LPCWSTR message) if (FAILED(g_hrFatalError)) ThrowHR(g_hrFatalError); + // COM introduces the notion of a vtable gap method, which is not a real method at all but instead + // aids in the explicit layout of COM interop vtables. These methods have no implementation and no + // direct runtime state tracking them. Trying to lookup a method handle for a vtable gap method will + // throw an exception but we choose to let that happen and filter out the warning here in the + // handler because (a) vtable gap methods are rare and (b) it's not all that cheap to identify them + // beforehand. + if ((TypeFromToken(token) == mdtMethodDef) && IsVTableGapMethod(token)) + { + return; + } + CorZapLogLevel level = CORZAP_LOGLEVEL_ERROR; // Some warnings are demoted to informational level @@ -3569,6 +3555,15 @@ void ZapImage::Error(mdToken token, HRESULT hr, UINT resID, LPCWSTR message) level = CORZAP_LOGLEVEL_INFO; } +#ifdef CROSSGEN_COMPILE + if ((resID == IDS_IBC_MISSING_EXTERNAL_TYPE) || + (resID == IDS_IBC_MISSING_EXTERNAL_METHOD)) + { + // Supress printing of "The generic type/method specified by the IBC data is not available to this assembly" + level = CORZAP_LOGLEVEL_INFO; + } +#endif + if (m_zapper->m_pOpt->m_ignoreErrors) { #ifdef CROSSGEN_COMPILE diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp index 5616212..f1399b3 100644 --- a/src/zap/zapinfo.cpp +++ b/src/zap/zapinfo.cpp @@ -3586,7 +3586,7 @@ void ZapInfo::getMethodSig(CORINFO_METHOD_HANDLE ftn, CORINFO_SIG_INFO *sig,CORI bool ZapInfo::getMethodInfo(CORINFO_METHOD_HANDLE ftn,CORINFO_METHOD_INFO* info) { - bool result = m_pEEJitInfo->getMethodInfo(ftn, info); + bool result = m_pImage->m_pPreloader->GetMethodInfo(m_currentMethodToken, ftn, info); info->regionKind = m_pImage->GetCurrentRegionKind(); return result; } -- 2.7.4