diff --git a/src/coreclr/inc/corcompile.h b/src/coreclr/inc/corcompile.h index c98c2eb18a2c57..839ab3e87d58fc 100644 --- a/src/coreclr/inc/corcompile.h +++ b/src/coreclr/inc/corcompile.h @@ -1164,26 +1164,4 @@ extern "C" unsigned __stdcall PartialNGenStressPercentage(); extern "C" HRESULT __stdcall CreatePdb(CORINFO_ASSEMBLY_HANDLE hAssembly, BSTR pNativeImagePath, BSTR pPdbPath, BOOL pdbLines, BSTR pManagedPdbSearchPath, LPCWSTR pDiasymreaderPath); extern bool g_fNGenMissingDependenciesOk; - -#ifdef FEATURE_READYTORUN_COMPILER -extern bool g_fReadyToRunCompilation; -extern bool g_fLargeVersionBubble; -#endif - -inline bool IsReadyToRunCompilation() -{ -#ifdef FEATURE_READYTORUN_COMPILER - return g_fReadyToRunCompilation; -#else - return false; -#endif -} - -#ifdef FEATURE_READYTORUN_COMPILER -inline bool IsLargeVersionBubbleEnabled() -{ - return g_fLargeVersionBubble; -} -#endif - #endif /* COR_COMPILE_H_ */ diff --git a/src/coreclr/vm/ceeload.cpp b/src/coreclr/vm/ceeload.cpp index d418fee532d039..8af16d073d7a0e 100644 --- a/src/coreclr/vm/ceeload.cpp +++ b/src/coreclr/vm/ceeload.cpp @@ -3089,7 +3089,7 @@ BOOL Module::IsInCurrentVersionBubble() return TRUE; } -#if defined(FEATURE_READYTORUN) && !defined(FEATURE_READYTORUN_COMPILER) +#if defined(FEATURE_READYTORUN) //--------------------------------------------------------------------------------------- // Check if the target module is in the same version bubble as this one // The current implementation uses the presence of an AssemblyRef for the target module's assembly in @@ -3156,7 +3156,7 @@ BOOL Module::IsInSameVersionBubble(Module *target) return FALSE; } -#endif // FEATURE_READYTORUN && !FEATURE_READYTORUN_COMPILER +#endif // FEATURE_READYTORUN //--------------------------------------------------------------------------------------- // diff --git a/src/coreclr/vm/ceeload.h b/src/coreclr/vm/ceeload.h index bebb24ebbe8d60..8127e369d1d342 100644 --- a/src/coreclr/vm/ceeload.h +++ b/src/coreclr/vm/ceeload.h @@ -1779,9 +1779,9 @@ class Module BOOL IsInCurrentVersionBubble(); -#if defined(FEATURE_READYTORUN) && !defined(FEATURE_READYTORUN_COMPILER) +#if defined(FEATURE_READYTORUN) BOOL IsInSameVersionBubble(Module *target); -#endif // FEATURE_READYTORUN && !FEATURE_READYTORUN_COMPILER +#endif // FEATURE_READYTORUN LPCWSTR GetPathForErrorMessages(); diff --git a/src/coreclr/vm/classcompat.cpp b/src/coreclr/vm/classcompat.cpp index 1d9e9025c48230..6b577f954302eb 100644 --- a/src/coreclr/vm/classcompat.cpp +++ b/src/coreclr/vm/classcompat.cpp @@ -1243,7 +1243,7 @@ VOID MethodTableBuilder::BuildInteropVTable_ExpandInterface(InterfaceInfo_t *pIn MethodTable *pItf = it.GetInterfaceApprox(); if (pItf->HasInstantiation() || pItf->IsSpecialMarkerTypeForGenericCasting()) continue; - + BuildInteropVTable_ExpandInterface(pInterfaceMap, pItf, pwInterfaceListSize, pdwMaxInterfaceMethods, FALSE); } @@ -2594,7 +2594,7 @@ VOID MethodTableBuilder::EnumerateClassMethods() if (fIsClassInterface #if defined(FEATURE_DEFAULT_INTERFACES) // Only fragile crossgen wasn't upgraded to deal with default interface methods. - && !IsReadyToRunCompilation() && !IsNgenPDBCompilationProcess() + && !IsNgenPDBCompilationProcess() #endif ) { diff --git a/src/coreclr/vm/dllimport.cpp b/src/coreclr/vm/dllimport.cpp index 7070769edfa6d8..aefb674d37e24a 100644 --- a/src/coreclr/vm/dllimport.cpp +++ b/src/coreclr/vm/dllimport.cpp @@ -651,7 +651,7 @@ class ILStubState : public StubState DWORD dwMethodDescLocalNum = (DWORD)-1; // Notify the profiler of call out of the runtime - if (!SF_IsReverseCOMStub(m_dwStubFlags) && !SF_IsStructMarshalStub(m_dwStubFlags) && (CORProfilerTrackTransitions() || (!IsReadyToRunCompilation() && SF_IsNGENedStubForProfiling(m_dwStubFlags)))) + if (!SF_IsReverseCOMStub(m_dwStubFlags) && !SF_IsStructMarshalStub(m_dwStubFlags) && (CORProfilerTrackTransitions() || SF_IsNGENedStubForProfiling(m_dwStubFlags))) { dwMethodDescLocalNum = m_slIL.EmitProfilerBeginTransitionCallback(pcsDispatch, m_dwStubFlags); _ASSERTE(dwMethodDescLocalNum != (DWORD)-1); @@ -3399,13 +3399,6 @@ BOOL NDirect::MarshalingRequired( return TRUE; } -#ifdef FEATURE_READYTORUN_COMPILER - if (IsReadyToRunCompilation()) - { - if (!hndArgType.AsMethodTable()->IsLayoutInCurrentVersionBubble()) - return TRUE; - } -#endif if (i > 0) { const bool isValueType = true; @@ -5321,12 +5314,6 @@ MethodDesc* NDirect::CreateStructMarshalILStub(MethodTable* pMT) } CONTRACT_END; - if (IsReadyToRunCompilation()) - { - // We don't support emitting struct marshalling IL stubs into R2R images. - ThrowHR(E_FAIL); - } - DWORD dwStubFlags = NDIRECTSTUB_FL_STRUCT_MARSHAL; BOOL bestFit, throwOnUnmappableChar; diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 7b0cf9a9604d6e..883eb1ceb1883d 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -656,80 +656,6 @@ size_t CEEInfo::findNameOfToken ( return NameLen; } -#ifdef FEATURE_READYTORUN_COMPILER - -// Returns true if assemblies are in the same version bubble -// Right now each assembly is in its own version bubble. -// If the need arises (i.e. performance issues) we will define sets of assemblies (e.g. all app assemblies) -// The main point is that all this logic is concentrated in one place. - -// NOTICE: If you change this logic to allow multi-assembly version bubbles you -// need to consider the impact on diagnostic tools. Currently there is an inlining -// table which tracks inliner/inlinee relationships in R2R images but it is not -// yet capable of encoding cross-assembly inlines. The scenario where this -// may show are instrumenting profilers that want to instrument a given method A -// using the ReJit APIs. If method A happens to inlined within method B in another -// assembly then the profiler needs to know that so it can rejit B too. -// The recommended approach is to upgrade the inlining table (vm\inlinetracking.h\.cpp) -// now that presumably R2R images have some way to refer to methods in other -// assemblies in their version bubble. Chat with the diagnostics team if you need more -// details. -// -// There already is a case where cross-assembly inlining occurs in an -// unreported fashion for methods marked NonVersionable. There is a specific -// exemption called out for this on ICorProfilerInfo6::EnumNgenModuleMethodsInliningThisMethod -// and the impact of the cut was vetted with partners. It would not be appropriate -// to increase that unreported set without additional review. - - -bool IsInSameVersionBubble(Assembly * current, Assembly * target) -{ - LIMITED_METHOD_CONTRACT; - - // trivial case: current and target are identical - // DO NOT change this without reading the notice above - if (current == target) - return true; - - return IsLargeVersionBubbleEnabled(); -} - -// Returns true if the assemblies defining current and target are in the same version bubble -static bool IsInSameVersionBubble(MethodDesc* pCurMD, MethodDesc *pTargetMD) -{ - LIMITED_METHOD_CONTRACT; - // DO NOT change this without reading the notice above - if (IsInSameVersionBubble(pCurMD->GetModule()->GetAssembly(), - pTargetMD->GetModule()->GetAssembly())) - { - return true; - } - if (IsReadyToRunCompilation()) - { - if (pTargetMD->GetModule()->GetMDImport()->GetCustomAttributeByName(pTargetMD->GetMemberDef(), - NONVERSIONABLE_TYPE, NULL, NULL) == S_OK) - { - return true; - } - } - return false; - -} - -#endif // FEATURE_READYTORUN_COMPILER - -static bool CallerAndCalleeInSystemVersionBubble(MethodDesc* pCaller, MethodDesc* pCallee) -{ - LIMITED_METHOD_CONTRACT; - -#ifdef FEATURE_READYTORUN_COMPILER - if (IsReadyToRunCompilation()) - return pCallee->GetModule()->IsSystem() && IsInSameVersionBubble(pCaller, pCallee); -#endif - - return false; -} - /*********************************************************************/ // Checks if the given metadata token is valid bool CEEInfo::isValidToken ( @@ -1976,9 +1902,6 @@ CEEInfo::getHeapClassSize( _ASSERTE(pMT); _ASSERTE(!pMT->IsValueType()); _ASSERTE(!pMT->HasComponentSize()); -#ifdef FEATURE_READYTORUN_COMPILER - _ASSERTE(!IsReadyToRunCompilation() || pMT->IsInheritanceChainLayoutFixedInCurrentVersionBubble()); -#endif // Add OBJECT_SIZE to account for method table pointer. result = pMT->GetNumInstanceFieldBytes() + OBJECT_SIZE; @@ -2009,13 +1932,6 @@ bool CEEInfo::canAllocateOnStack(CORINFO_CLASS_HANDLE clsHnd) result = !pMT->HasFinalizer(); -#ifdef FEATURE_READYTORUN_COMPILER - if (IsReadyToRunCompilation() && !pMT->IsInheritanceChainLayoutFixedInCurrentVersionBubble()) - { - result = false; - } -#endif - EE_TO_JIT_TRANSITION_LEAF(); return result; } @@ -2282,11 +2198,6 @@ unsigned CEEInfo::getClassGClayoutStatic(TypeHandle VMClsHnd, BYTE* gcPtrs) _ASSERTE(sizeof(BYTE) == 1); BOOL isValueClass = pMT->IsValueType(); - -#ifdef FEATURE_READYTORUN_COMPILER - _ASSERTE(isValueClass || !IsReadyToRunCompilation() || pMT->IsInheritanceChainLayoutFixedInCurrentVersionBubble()); -#endif - unsigned int size = isValueClass ? VMClsHnd.GetSize() : pMT->GetNumInstanceFieldBytes() + OBJECT_SIZE; // assume no GC pointers at first @@ -3092,57 +3003,6 @@ void CEEInfo::ComputeRuntimeLookupForSharedGenericToken(DictionaryEntryKind entr pResultLookup->lookupKind.runtimeLookupKind = CORINFO_LOOKUP_THISOBJ; } -#ifdef FEATURE_READYTORUN_COMPILER - if (IsReadyToRunCompilation()) - { - pResultLookup->lookupKind.runtimeLookupArgs = NULL; - - switch (entryKind) - { - case DeclaringTypeHandleSlot: - _ASSERTE(pTemplateMD != NULL); - pResultLookup->lookupKind.runtimeLookupArgs = pTemplateMD->GetMethodTable(); - pResultLookup->lookupKind.runtimeLookupFlags = READYTORUN_FIXUP_DeclaringTypeHandle; - break; - - case TypeHandleSlot: - pResultLookup->lookupKind.runtimeLookupFlags = READYTORUN_FIXUP_TypeHandle; - break; - - case MethodDescSlot: - case MethodEntrySlot: - case ConstrainedMethodEntrySlot: - case DispatchStubAddrSlot: - { - if (pTemplateMD != (MethodDesc*)pResolvedToken->hMethod) - ThrowHR(E_NOTIMPL); - - if (entryKind == MethodDescSlot) - pResultLookup->lookupKind.runtimeLookupFlags = READYTORUN_FIXUP_MethodHandle; - else if (entryKind == MethodEntrySlot || entryKind == ConstrainedMethodEntrySlot) - pResultLookup->lookupKind.runtimeLookupFlags = READYTORUN_FIXUP_MethodEntry; - else - pResultLookup->lookupKind.runtimeLookupFlags = READYTORUN_FIXUP_VirtualEntry; - - pResultLookup->lookupKind.runtimeLookupArgs = pConstrainedResolvedToken; - - break; - } - - case FieldDescSlot: - pResultLookup->lookupKind.runtimeLookupFlags = READYTORUN_FIXUP_FieldHandle; - break; - - default: - _ASSERTE(!"Unknown dictionary entry kind!"); - IfFailThrow(E_FAIL); - } - - // For R2R compilations, we don't generate the dictionary lookup signatures (dictionary lookups are done in a - // different way that is more version resilient... plus we can't have pointers to existing MTs/MDs in the sigs) - return; - } -#endif // If we've got a method type parameter of any kind then we must look in the method desc arg if (pContextMD->RequiresInstMethodDescArg()) { @@ -3924,14 +3784,7 @@ uint32_t CEEInfo::getClassAttribsInternal (CORINFO_CLASS_HANDLE clsHnd) if (pClass->IsBeforeFieldInit()) { - if (IsReadyToRunCompilation() && !pMT->GetModule()->IsInCurrentVersionBubble()) - { - // For version resiliency do not allow hoisting static constructors out of loops - } - else - { - ret |= CORINFO_FLG_BEFOREFIELDINIT; - } + ret |= CORINFO_FLG_BEFOREFIELDINIT; } if (pClass->IsAbstract()) @@ -4568,19 +4421,6 @@ TypeCompareState CEEInfo::compareTypesForCast( } } -#ifdef FEATURE_READYTORUN_COMPILER - // In R2R it is a breaking change for a previously positive - // cast to become negative, but not for a previously negative - // cast to become positive. So in R2R a negative result is - // always reported back as May, except for CoreLib version bubble. - if (IsReadyToRunCompilation() && (result == TypeCompareState::MustNot) - && !GetAppDomain()->ToCompilationDomain()->GetTargetModule()->IsSystem() - && !IsLargeVersionBubbleEnabled()) - { - result = TypeCompareState::May; - } -#endif // FEATURE_READYTORUN_COMPILER - EE_TO_JIT_TRANSITION(); return result; @@ -5236,21 +5076,8 @@ void CEEInfo::getCallInfo( // Because of .NET's notion of base calls, exactType may point to a sub-class // of the actual class that defines pTargetMD. If the JIT decides to inline, it is // important that they 'match', so we fix exactType here. -#ifdef FEATURE_READYTORUN_COMPILER - if (IsReadyToRunCompilation() && - !isVerifyOnly() && - !IsInSameVersionBubble((MethodDesc*)callerHandle, pTargetMD)) - { - // For version resilient code we can only inline within the same version bubble; - // we "repair" the precise types only for those callees. - // The above condition needs to stay in sync with CEEInfo::canInline - } - else -#endif - { - exactType = pTargetMD->GetExactDeclaringType(exactType.AsMethodTable()); - _ASSERTE(!exactType.IsNull()); - } + exactType = pTargetMD->GetExactDeclaringType(exactType.AsMethodTable()); + _ASSERTE(!exactType.IsNull()); } pResult->contextHandle = MAKE_CLASSCONTEXT(exactType.AsPtr()); @@ -5299,36 +5126,6 @@ void CEEInfo::getCallInfo( else { bool devirt; - -#ifdef FEATURE_READYTORUN_COMPILER - - // if we are generating version resilient code - // AND - // caller/callee are in different version bubbles - // we have to apply more restrictive rules - // These rules are related to the "inlining rules" as far as the - // boundaries of a version bubble are concerned. - - if (IsReadyToRunCompilation() && - !isVerifyOnly() && - !IsInSameVersionBubble((MethodDesc*)callerHandle, pTargetMD) - ) - { - // For version resiliency we won't de-virtualize all final/sealed method calls. Because during a - // servicing event it is legal to unseal a method or type. - // - // Note that it is safe to devirtualize in the following cases, since a servicing event cannot later modify it - // 1) Callvirt on a virtual final method of a value type - since value types are sealed types as per ECMA spec - // 2) Delegate.Invoke() - since a Delegate is a sealed class as per ECMA spec - // 3) JIT intrinsics - since they have pre-defined behavior - devirt = pTargetMD->GetMethodTable()->IsValueType() || - (pTargetMD->GetMethodTable()->IsDelegate() && ((DelegateEEClass*)(pTargetMD->GetMethodTable()->GetClass()))->GetInvokeMethod() == pMD) || - (pTargetMD->IsFCall() && ECall::GetIntrinsicID(pTargetMD) != CORINFO_INTRINSIC_Illegal); - - callVirtCrossingVersionBubble = true; - } - else -#endif if (pTargetMD->GetMethodTable()->IsInterface()) { // Handle interface methods specially because the Sealed bit has no meaning on interfaces. @@ -5414,36 +5211,27 @@ void CEEInfo::getCallInfo( { _ASSERTE(!m_pMethodBeingCompiled->IsDynamicMethod()); - if (IsReadyToRunCompilation() && unresolvedLdVirtFtn) + pResult->kind = CORINFO_CALL_CODE_POINTER; + + DictionaryEntryKind entryKind; + if (constrainedType.IsNull() || ((flags & CORINFO_CALLINFO_CALLVIRT) && !constrainedType.IsValueType())) { - // Compensate for always treating delegates as direct calls above. - // Dictionary lookup is computed in embedGenericHandle as part of the LDVIRTFTN code sequence - pResult->kind = CORINFO_VIRTUALCALL_LDVIRTFTN; + // For reference types, the constrained type does not affect method resolution on a callvirt, and if there is no + // constraint, it doesn't effect it either + entryKind = MethodEntrySlot; } else { - pResult->kind = CORINFO_CALL_CODE_POINTER; - - DictionaryEntryKind entryKind; - if (constrainedType.IsNull() || ((flags & CORINFO_CALLINFO_CALLVIRT) && !constrainedType.IsValueType())) - { - // For reference types, the constrained type does not affect method resolution on a callvirt, and if there is no - // constraint, it doesn't effect it either - entryKind = MethodEntrySlot; - } - else - { - // constrained. callvirt case where the constraint type is a valuetype - // OR - // constrained. call or constrained. ldftn case - entryKind = ConstrainedMethodEntrySlot; - } - ComputeRuntimeLookupForSharedGenericToken(entryKind, - pResolvedToken, - pConstrainedResolvedToken, - pMD, - &pResult->codePointerLookup); + // constrained. callvirt case where the constraint type is a valuetype + // OR + // constrained. call or constrained. ldftn case + entryKind = ConstrainedMethodEntrySlot; } + ComputeRuntimeLookupForSharedGenericToken(entryKind, + pResolvedToken, + pConstrainedResolvedToken, + pMD, + &pResult->codePointerLookup); } else { @@ -5453,12 +5241,6 @@ void CEEInfo::getCallInfo( } pResult->kind = CORINFO_CALL; - - if (IsReadyToRunCompilation() && unresolvedLdVirtFtn) - { - // Compensate for always treating delegates as direct calls above - pResult->kind = CORINFO_VIRTUALCALL_LDVIRTFTN; - } } pResult->nullInstanceCheck = resolvedCallVirt; } @@ -5475,28 +5257,11 @@ void CEEInfo::getCallInfo( { pResult->kind = CORINFO_VIRTUALCALL_VTABLE; pResult->nullInstanceCheck = TRUE; - - // We'll special virtual calls to target methods in the corelib assembly when compiling in R2R mode, and generate fragile-NI-like callsites for improved performance. We - // can do that because today we'll always service the corelib assembly and the runtime in one bundle. Any caller in the corelib version bubble can benefit from this - // performance optimization. - if (IsReadyToRunCompilation() && !CallerAndCalleeInSystemVersionBubble((MethodDesc*)callerHandle, pTargetMD)) - { - pResult->kind = CORINFO_VIRTUALCALL_STUB; - } } else { - if (IsReadyToRunCompilation()) - { - // Insert explicit null checks for cross-version bubble non-interface calls. - // It is required to handle null checks properly for non-virtual <-> virtual change between versions - pResult->nullInstanceCheck = !!(callVirtCrossingVersionBubble && !pTargetMD->IsInterface()); - } - else - { - // No need to null check - the dispatch code will deal with null this. - pResult->nullInstanceCheck = FALSE; - } + // No need to null check - the dispatch code will deal with null this. + pResult->nullInstanceCheck = FALSE; #ifdef STUB_DISPATCH_PORTABLE pResult->kind = CORINFO_VIRTUALCALL_LDVIRTFTN; #else // STUB_DISPATCH_PORTABLE @@ -6018,13 +5783,6 @@ CorInfoHelpFunc CEEInfo::getNewHelperStatic(MethodTable * pMT, bool * pHasSideEf *pHasSideEffects = true; } else -#ifdef FEATURE_READYTORUN_COMPILER - if (IsReadyToRunCompilation()) - { - *pHasSideEffects = hasFinalizer || !pMT->IsInheritanceChainFixedInCurrentVersionBubble(); - } - else -#endif { *pHasSideEffects = !!hasFinalizer; } @@ -7999,54 +7757,6 @@ CorInfoInline CEEInfo::canInline (CORINFO_METHOD_HANDLE hCaller, { Module * pCalleeModule = pCallee->GetModule(); -#ifdef FEATURE_PREJIT - Assembly * pCalleeAssembly = pCalleeModule->GetAssembly(); - -#ifdef _DEBUG - // - // Make sure that all methods with StackCrawlMark are marked as IsMdRequireSecObject - // - if (pCalleeAssembly->IsSystem()) - { - _ASSERTE(!containsStackCrawlMarkLocal(pCallee)); - } -#endif - - // To allow for servicing of Ngen images we want to disable most - // Cross-Assembly inlining except for the cases that we explicitly allow. - // - if (IsCompilingForNGen()) - { - // This is an canInline call at Ngen time - // - // - Assembly * pOrigCallerAssembly = pOrigCallerModule->GetAssembly(); - - if (pCalleeAssembly == pOrigCallerAssembly) - { - // Within the same assembly - // we can freely inline with no restrictions - } - else - { -#ifdef FEATURE_READYTORUN_COMPILER - // No inlinining for version resilient code except if in the same version bubble - // If this condition changes, please make the corresponding change - // in getCallInfo, too. - if (IsReadyToRunCompilation() && - !isVerifyOnly() && - !IsInSameVersionBubble(pCaller, pCallee) - ) - { - result = INLINE_NEVER; - szFailReason = "Cross-module inlining in version resilient code"; - goto exit; - } -#endif - } - } -#endif // FEATURE_PREJIT - // TODO: We can probably be smarter here if the caller is jitted, as we will // know for sure if the inlinee has really no string interning active (currently // it's only on in the ngen case (besides requiring the attribute)), but this is getting @@ -9046,25 +8756,6 @@ bool CEEInfo::resolveVirtualMethodHelper(CORINFO_DEVIRTUALIZATION_INFO * info) pExactMT = pDevirtMD->GetExactDeclaringType(pObjMT); } -#ifdef FEATURE_READYTORUN_COMPILER - // Check if devirtualization is dependent upon cross-version - // bubble information and if so, disallow it. - if (IsReadyToRunCompilation()) - { - MethodDesc* callerMethod = m_pMethodBeingCompiled; - Assembly* pCallerAssembly = callerMethod->GetModule()->GetAssembly(); - bool allowDevirt = - IsInSameVersionBubble(pCallerAssembly , pDevirtMD->GetModule()->GetAssembly()) - && IsInSameVersionBubble(pCallerAssembly, pObjMT->GetAssembly()); - - if (!allowDevirt) - { - info->detail = CORINFO_DEVIRTUALIZATION_FAILED_BUBBLE; - return false; - } - } -#endif - // Success! Pass back the results. // info->devirtualizedMethod = (CORINFO_METHOD_HANDLE) pDevirtMD; @@ -10330,38 +10021,11 @@ void CEEInfo::getEEInfo(CORINFO_EE_INFO *pEEInfoOut) JIT_TO_EE_TRANSITION(); - if (!IsReadyToRunCompilation()) - { - InlinedCallFrame::GetEEInfo(&pEEInfoOut->inlinedCallFrameInfo); - - // Offsets into the Thread structure - pEEInfoOut->offsetOfThreadFrame = Thread::GetOffsetOfCurrentFrame(); - pEEInfoOut->offsetOfGCState = Thread::GetOffsetOfGCFlag(); - } - else - { - // We'll declare a fixed size to use for the inlined call frame for R2R here. The size we declare - // is currently slightly larger that the actual size of the struct, just in case we decide to add - // more fields to the struct in the future, in an effort to not completely invalidate existing R2R images. - // The assert below ensures that this fixed size is at least large enough to hold the data structures - // used at runtime. - // ** IMPORTANT ** If you ever need to change the value of this fixed size, make sure to change the R2R - // version number, otherwise older R2R images will probably crash when used. - - const int r2rInlinedCallFrameSize = TARGET_POINTER_SIZE * READYTORUN_PInvokeTransitionFrameSizeInPointerUnits; - -#if defined(_DEBUG) && !defined(CROSSBITNESS_COMPILE) - InlinedCallFrame::GetEEInfo(&pEEInfoOut->inlinedCallFrameInfo); - _ASSERTE(pEEInfoOut->inlinedCallFrameInfo.size <= r2rInlinedCallFrameSize); -#endif - - // inlinedCallFrameInfo is mostly not used for R2R compilation (only the size field is used) - ZeroMemory(&pEEInfoOut->inlinedCallFrameInfo, sizeof(pEEInfoOut->inlinedCallFrameInfo)); + InlinedCallFrame::GetEEInfo(&pEEInfoOut->inlinedCallFrameInfo); - pEEInfoOut->offsetOfThreadFrame = (DWORD)-1; - pEEInfoOut->offsetOfGCState = (DWORD)-1; - pEEInfoOut->inlinedCallFrameInfo.size = r2rInlinedCallFrameSize; - } + // Offsets into the Thread structure + pEEInfoOut->offsetOfThreadFrame = Thread::GetOffsetOfCurrentFrame(); + pEEInfoOut->offsetOfGCState = Thread::GetOffsetOfGCFlag(); #ifndef CROSSBITNESS_COMPILE // The assertions must hold in every non-crossbitness scenario @@ -10385,16 +10049,7 @@ void CEEInfo::getEEInfo(CORINFO_EE_INFO *pEEInfoOut) _ASSERTE(sizeof(ReversePInvokeFrame) <= pEEInfoOut->sizeOfReversePInvokeFrame); #endif - if (!IsReadyToRunCompilation()) - { - pEEInfoOut->osPageSize = GetOsPageSize(); - } - else - { - // In AOT scenarios the VM reports to the JIT the minimal supported page size. - pEEInfoOut->osPageSize = 0x1000; - } - + pEEInfoOut->osPageSize = GetOsPageSize(); pEEInfoOut->maxUncheckedOffsetForNullObject = MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT; pEEInfoOut->targetAbi = CORINFO_CORECLR_ABI; @@ -11522,7 +11177,7 @@ void CEEJitInfo::allocUnwindInfo ( } PT_RUNTIME_FUNCTION pRuntimeFunction = m_CodeHeaderRW->GetUnwindInfo(m_usedUnwindInfos); - + m_usedUnwindInfos++; // Make sure that the RUNTIME_FUNCTION is aligned on a DWORD sized boundary @@ -12027,7 +11682,7 @@ CORINFO_CLASS_HANDLE CEEJitInfo::getStaticFieldCurrentClass(CORINFO_FIELD_HANDLE } // Only examine the field's value if we are producing jitted code. - if (isVerifyOnly() || IsCompilingForNGen() || IsReadyToRunCompilation()) + if (isVerifyOnly()) { return result; } @@ -12227,7 +11882,7 @@ HRESULT CEEJitInfo::getPgoInstrumentationResults( m_foundPgoData = newPgoData; newPgoData.SuppressRelease(); - newPgoData->m_hr = PgoManager::getPgoInstrumentationResults(pMD, &newPgoData->m_allocatedData, &newPgoData->m_schema, + newPgoData->m_hr = PgoManager::getPgoInstrumentationResults(pMD, &newPgoData->m_allocatedData, &newPgoData->m_schema, &newPgoData->m_cSchemaElems, &newPgoData->m_pInstrumentationData, &newPgoData->m_pgoSource); pDataCur = m_foundPgoData; } @@ -14293,7 +13948,7 @@ BOOL LoadDynamicInfoEntry(Module *currentModule, TypeHandle thImpl = ZapSig::DecodeType(currentModule, pInfoModule, updatedSignature, CLASS_LOADED, &updatedSignature); MethodDesc *pImplMethodCompiler = NULL; - + if ((flags & READYTORUN_VIRTUAL_OVERRIDE_VirtualFunctionOverriden) != 0) { pImplMethodCompiler = ZapSig::DecodeMethod(currentModule, pInfoModule, updatedSignature); diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 1ba51e6b94d0be..6a5a670f26b8f0 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -4553,7 +4553,7 @@ void MethodTable::DoFullyLoad(Generics::RecursionGraph * const pVisited, const } // Validate implementation of virtual static methods on all implemented interfaces unless: - // 1) The type resides in a module where sanity checks are disabled (such as System.Private.CoreLib, or an + // 1) The type resides in a module where sanity checks are disabled (such as System.Private.CoreLib, or an // R2R module with type checks disabled) // 2) There are no virtual static methods defined on any of the interfaces implemented by this type; // 3) The type is abstract in which case it's allowed to leave some virtual static methods unimplemented @@ -8167,7 +8167,7 @@ MethodTable::ResolveVirtualStaticMethod(MethodTable* pInterfaceType, MethodDesc* } else { - // When performing override checking to ensure that a concrete type is valid, require the implementation + // When performing override checking to ensure that a concrete type is valid, require the implementation // actually implement the exact or equivalent interface. equivalentOrVariantCompatible = pItfInMap->IsEquivalentTo(pInterfaceType); } @@ -8251,7 +8251,7 @@ MethodTable::TryResolveVirtualStaticMethodOnThisType(MethodTable* pInterfaceType continue; } MethodDesc *pMethodDecl; - + if ((TypeFromToken(methodDecl) == mdtMethodDef) || pInterfaceMT->IsFullyLoaded()) { pMethodDecl = MemberLoader::GetMethodDescFromMemberDefOrRefOrSpec( @@ -8297,7 +8297,7 @@ MethodTable::TryResolveVirtualStaticMethodOnThisType(MethodTable* pInterfaceType { COMPlusThrow(kTypeLoadException, E_FAIL); } - + MethodDesc *pMethodImpl = MemberLoader::GetMethodDescFromMethodDef( GetModule(), methodBody, @@ -8308,7 +8308,7 @@ MethodTable::TryResolveVirtualStaticMethodOnThisType(MethodTable* pInterfaceType COMPlusThrow(kTypeLoadException, E_FAIL); } - // Spec requires that all body token for MethodImpls that refer to static virtual implementation methods must to methods + // Spec requires that all body token for MethodImpls that refer to static virtual implementation methods must to methods // defined on the same type that defines the MethodImpl if (!HasSameTypeDefAs(pMethodImpl->GetMethodTable())) { @@ -8710,165 +8710,3 @@ PTR_MethodTable MethodTable::InterfaceMapIterator::GetInterface(MethodTable* pMT RETURN (pResult); } #endif // DACCESS_COMPILE - -#ifdef FEATURE_READYTORUN_COMPILER - -static BOOL ComputeIsLayoutFixedInCurrentVersionBubble(MethodTable * pMT) -{ - STANDARD_VM_CONTRACT; - - // Primitive types and enums have fixed layout - if (pMT->IsTruePrimitive() || pMT->IsEnum()) - return TRUE; - - if (!pMT->GetModule()->IsInCurrentVersionBubble()) - { - if (!pMT->IsValueType()) - { - // Eventually, we may respect the non-versionable attribute for reference types too. For now, we are going - // to play is safe and ignore it. - return FALSE; - } - - // Valuetypes with non-versionable attribute are candidates for fixed layout. Reject the rest. - if (pMT->GetModule()->GetMDImport()->GetCustomAttributeByName(pMT->GetCl(), - NONVERSIONABLE_TYPE, NULL, NULL) != S_OK) - { - return FALSE; - } - } - - // If the above condition passed, check that all instance fields have fixed layout as well. In particular, - // it is important for generic types with non-versionable layout (e.g. Nullable) - ApproxFieldDescIterator fieldIterator(pMT, ApproxFieldDescIterator::INSTANCE_FIELDS); - for (FieldDesc *pFD = fieldIterator.Next(); pFD != NULL; pFD = fieldIterator.Next()) - { - if (pFD->GetFieldType() != ELEMENT_TYPE_VALUETYPE) - continue; - - MethodTable * pFieldMT = pFD->GetApproxFieldTypeHandleThrowing().AsMethodTable(); - if (!pFieldMT->IsLayoutFixedInCurrentVersionBubble()) - return FALSE; - } - - return TRUE; -} - -static BOOL ComputeIsLayoutInCurrentVersionBubble(MethodTable* pMT) -{ - if (pMT->IsTruePrimitive() || pMT->IsEnum()) - return TRUE; - - if (!pMT->GetModule()->IsInCurrentVersionBubble()) - return FALSE; - - ApproxFieldDescIterator fieldIterator(pMT, ApproxFieldDescIterator::INSTANCE_FIELDS); - for (FieldDesc *pFD = fieldIterator.Next(); pFD != NULL; pFD = fieldIterator.Next()) - { - MethodTable * pFieldMT = pFD->GetApproxFieldTypeHandleThrowing().GetMethodTable(); - - if (!pFieldMT->IsLayoutInCurrentVersionBubble()) - return FALSE; - } - - if (!pMT->IsValueType()) - { - pMT = pMT->GetParentMethodTable(); - - while ((pMT != g_pObjectClass) && (pMT != NULL)) - { - if (!pMT->IsLayoutInCurrentVersionBubble()) - return FALSE; - - pMT = pMT->GetParentMethodTable(); - } - } - - return TRUE; -} - -BOOL MethodTable::IsLayoutInCurrentVersionBubble() -{ - STANDARD_VM_CONTRACT; - - const MethodTableWriteableData * pWriteableData = GetWriteableData(); - if (!(pWriteableData->m_dwFlags & MethodTableWriteableData::enum_flag_NGEN_IsLayoutInCurrentVersionBubbleComputed)) - { - MethodTableWriteableData * pWriteableDataForWrite = GetWriteableDataForWrite(); - if (ComputeIsLayoutInCurrentVersionBubble(this)) - pWriteableDataForWrite->m_dwFlags |= MethodTableWriteableData::enum_flag_NGEN_IsLayoutInCurrentVersionBubble; - pWriteableDataForWrite->m_dwFlags |= MethodTableWriteableData::enum_flag_NGEN_IsLayoutInCurrentVersionBubbleComputed; - } - - return (pWriteableData->m_dwFlags & MethodTableWriteableData::enum_flag_NGEN_IsLayoutInCurrentVersionBubble) != 0; -} - -// -// Is field layout in this type fixed within the current version bubble? -// This check does not take the inheritance chain into account. -// -BOOL MethodTable::IsLayoutFixedInCurrentVersionBubble() -{ - STANDARD_VM_CONTRACT; - - const MethodTableWriteableData * pWriteableData = GetWriteableData(); - if (!(pWriteableData->m_dwFlags & MethodTableWriteableData::enum_flag_NGEN_IsLayoutFixedComputed)) - { - MethodTableWriteableData * pWriteableDataForWrite = GetWriteableDataForWrite(); - if (ComputeIsLayoutFixedInCurrentVersionBubble(this)) - pWriteableDataForWrite->m_dwFlags |= MethodTableWriteableData::enum_flag_NGEN_IsLayoutFixed; - pWriteableDataForWrite->m_dwFlags |= MethodTableWriteableData::enum_flag_NGEN_IsLayoutFixedComputed; - } - - return (pWriteableData->m_dwFlags & MethodTableWriteableData::enum_flag_NGEN_IsLayoutFixed) != 0; -} - -// -// Is field layout of the inheritance chain fixed within the current version bubble? -// -BOOL MethodTable::IsInheritanceChainLayoutFixedInCurrentVersionBubble() -{ - STANDARD_VM_CONTRACT; - - // This method is not expected to be called for value types - _ASSERTE(!IsValueType()); - - MethodTable * pMT = this; - - while ((pMT != g_pObjectClass) && (pMT != NULL)) - { - if (!pMT->IsLayoutFixedInCurrentVersionBubble()) - return FALSE; - - pMT = pMT->GetParentMethodTable(); - } - - return TRUE; -} - -// -// Is the inheritance chain fixed within the current version bubble? -// -BOOL MethodTable::IsInheritanceChainFixedInCurrentVersionBubble() -{ - STANDARD_VM_CONTRACT; - - MethodTable * pMT = this; - - if (pMT->IsValueType()) - { - return pMT->GetModule()->IsInCurrentVersionBubble(); - } - - while ((pMT != g_pObjectClass) && (pMT != NULL)) - { - if (!pMT->GetModule()->IsInCurrentVersionBubble()) - return FALSE; - - pMT = pMT->GetParentMethodTable(); - } - - return TRUE; -} - -#endif // FEATURE_READYTORUN_COMPILER diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index cc9a3f5b579268..36069a2ca32991 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -337,12 +337,10 @@ struct MethodTableWriteableData enum_flag_NGEN_CachedNeedsRestore = 0x00040000, // The result of the needs restore computation // enum_unused = 0x00080000, -#ifdef FEATURE_READYTORUN_COMPILER - enum_flag_NGEN_IsLayoutFixedComputed = 0x0010000, // Set if we have cached the result of IsLayoutFixed computation - enum_flag_NGEN_IsLayoutFixed = 0x0020000, // The result of the IsLayoutFixed computation - enum_flag_NGEN_IsLayoutInCurrentVersionBubbleComputed = 0x0040000, // Set if we have cached the result of IsLayoutInCurrentVersionBubble computation - enum_flag_NGEN_IsLayoutInCurrentVersionBubble = 0x0080000, // The result of the IsLayoutInCurrentVersionBubble computation -#endif + // enum_unused = 0x0010000, + // enum_unused = 0x0020000, + // enum_unused = 0x0040000, + // enum_unused = 0x0080000, #endif // FEATURE_PREJIT @@ -1225,7 +1223,7 @@ class MethodTable // The current rule is that these interfaces can only appear // on valuetypes that are not shared generic, and that the special // marker type is the open generic type. - // + // inline bool IsSpecialMarkerTypeForGenericCasting() { return IsGenericTypeDefinition(); @@ -2203,8 +2201,8 @@ class MethodTable bool exactMatch = pCurrentMethodTable == pMT; if (!exactMatch) { - if (pCurrentMethodTable->HasSameTypeDefAs(pMT) && - pMT->HasInstantiation() && + if (pCurrentMethodTable->HasSameTypeDefAs(pMT) && + pMT->HasInstantiation() && pCurrentMethodTable->IsSpecialMarkerTypeForGenericCasting() && !pMTOwner->ContainsGenericVariables() && pMT->GetInstantiation().ContainsAllOneType(pMTOwner)) @@ -4050,29 +4048,6 @@ public : public: BOOL Validate (); - -#ifdef FEATURE_READYTORUN_COMPILER - // - // Is field layout in this type within the current version bubble? - // - BOOL IsLayoutInCurrentVersionBubble(); - // - // Is field layout in this type fixed within the current version bubble? - // This check does not take the inheritance chain into account. - // - BOOL IsLayoutFixedInCurrentVersionBubble(); - - // - // Is field layout of the inheritance chain fixed within the current version bubble? - // - BOOL IsInheritanceChainLayoutFixedInCurrentVersionBubble(); - - // - // Is the inheritance chain fixed within the current version bubble? - // - BOOL IsInheritanceChainFixedInCurrentVersionBubble(); -#endif - }; // class MethodTable #ifndef CROSSBITNESS_COMPILE diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index 5fdba35480ddd7..40b037e6a6b25f 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -3024,7 +3024,7 @@ MethodTableBuilder::EnumerateClassMethods() if (fIsClassInterface #if defined(FEATURE_DEFAULT_INTERFACES) // Only fragile crossgen wasn't upgraded to deal with default interface methods. - && !IsReadyToRunCompilation() && !IsNgenPDBCompilationProcess() + && !IsNgenPDBCompilationProcess() #endif ) { @@ -6783,7 +6783,7 @@ VOID MethodTableBuilder::ValidateStaticMethodImpl( bmtMethodHandle hDecl, bmtMethodHandle hImpl) { - // While we don't want to place the static method impl declarations on the class/interface, we do + // While we don't want to place the static method impl declarations on the class/interface, we do // need to validate the method constraints and signature are compatible if (!bmtProp->fNoSanityChecks) { @@ -9104,7 +9104,7 @@ MethodTableBuilder::LoadExactInterfaceMap(MethodTable *pMT) // to represent a type instantiated over its own generic variables, and the special marker type is currently the open type // and we make this case distinguishable by simply disallowing the optimization in those cases. bool retryWithExactInterfaces = !pMT->IsValueType() || pMT->IsSharedByGenericInstantiations() || pMT->ContainsGenericVariables(); - + DWORD nAssigned = 0; do { @@ -9147,7 +9147,7 @@ MethodTableBuilder::LoadExactInterfaceMap(MethodTable *pMT) MethodTable *pItfPossiblyApprox = intIt.GetInterfaceApprox(); if (uninstGenericCase && pItfPossiblyApprox->HasInstantiation() && pItfPossiblyApprox->ContainsGenericVariables()) { - // We allow a limited set of interface generic shapes with type variables. In particular, we require the + // We allow a limited set of interface generic shapes with type variables. In particular, we require the // instantiations to be exactly simple type variables, and to have a relatively small number of generic arguments // so that the fallback instantiating logic works efficiently if (InstantiationIsAllTypeVariables(pItfPossiblyApprox->GetInstantiation()) && pItfPossiblyApprox->GetInstantiation().GetNumArgs() <= MethodTable::MaxGenericParametersForSpecialMarkerType) @@ -9193,7 +9193,7 @@ MethodTableBuilder::LoadExactInterfaceMap(MethodTable *pMT) #endif // We have a special algorithm for interface maps in CoreLib, which doesn't expand interfaces, and assumes no ambiguous // duplicates. Code related to this is marked with #SpecialCorelibInterfaceExpansionAlgorithm - _ASSERTE(!duplicates || !(pMT->GetModule()->IsSystem() && pMT->IsValueType())); + _ASSERTE(!duplicates || !(pMT->GetModule()->IsSystem() && pMT->IsValueType())); CONSISTENCY_CHECK(duplicates || (nAssigned == pMT->GetNumInterfaces())); if (duplicates) @@ -11303,8 +11303,7 @@ BOOL MethodTableBuilder::NeedsAlignedBaseOffset() if (!GetModule()->GetFile()->IsILImageReadyToRun()) { // Always use ReadyToRun field layout algorithm to produce ReadyToRun images - if (!IsReadyToRunCompilation()) - return FALSE; + return FALSE; } if (!ModulesAreDistributedAsAnIndivisibleUnit(GetModule(), pParentMT->GetModule()) || diff --git a/src/coreclr/vm/pefile.cpp b/src/coreclr/vm/pefile.cpp index 96354bfa5b199d..31af194be166dc 100644 --- a/src/coreclr/vm/pefile.cpp +++ b/src/coreclr/vm/pefile.cpp @@ -1360,12 +1360,6 @@ BOOL PEFile::ShouldTreatNIAsMSIL() { LIMITED_METHOD_CONTRACT; - // Never use fragile native image content during ReadyToRun compilation. It would - // produces non-version resilient images because of wrong cached values for - // MethodTable::IsLayoutFixedInCurrentVersionBubble, etc. - if (IsReadyToRunCompilation()) - return TRUE; - // Ask profiling API & config vars whether NGENd images should be avoided // completely. if (!NGENImagesAllowed()) diff --git a/src/coreclr/vm/vars.hpp b/src/coreclr/vm/vars.hpp index 7746407ebca25b..2cc4536727fc6a 100644 --- a/src/coreclr/vm/vars.hpp +++ b/src/coreclr/vm/vars.hpp @@ -702,11 +702,6 @@ PTR_GSCookie GetProcessGSCookiePtr() { return PTR_GSCookie(&s_gsCookie); } inline GSCookie GetProcessGSCookie() { return *(RAW_KEYWORD(volatile) GSCookie *)(&s_gsCookie); } -#ifdef FEATURE_READYTORUN_COMPILER -extern bool g_fReadyToRunCompilation; -extern bool g_fLargeVersionBubble; -#endif - // Returns true if this is NGen compilation process. // This is a superset of CompilationDomain::IsCompilationDomain() as there is more // than one AppDomain in ngen (the DefaultDomain) diff --git a/src/coreclr/vm/zapsig.cpp b/src/coreclr/vm/zapsig.cpp index 3d9eeaa466e8d4..744acbeec56975 100644 --- a/src/coreclr/vm/zapsig.cpp +++ b/src/coreclr/vm/zapsig.cpp @@ -1229,38 +1229,7 @@ BOOL ZapSig::EncodeMethod( } CONTRACTL_END; - TypeHandle ownerType; - -#ifdef FEATURE_READYTORUN_COMPILER - - // For methods encoded outside of the version bubble, we use pResolvedToken which describes the metadata token from which the method originated - // For tokens inside the version bubble we are not constrained by the contents of pResolvedToken and as such we skip this codepath - // Generic interfaces in canonical form are an exception, we need to get the real type from the pResolvedToken so that the lookup at runtime - // can find the type in interface map. - // FUTURE: This condition should likely be changed or reevaluated once support for smaller version bubbles is implemented. - if (IsReadyToRunCompilation() && (!IsLargeVersionBubbleEnabled() || !pMethod->GetModule()->IsInCurrentVersionBubble() || (pMethod->IsSharedByGenericInstantiations() && pMethod->IsInterface()))) - { - if (pMethod->IsNDirect()) - { - ownerType = pMethod->GetMethodTable_NoLogging(); - } - else - { - if (pResolvedToken == NULL) - { - _ASSERTE(!"CORINFO_RESOLVED_TOKEN required to encode method!"); - ThrowHR(E_FAIL); - } - - // Encode the referencing method type - ownerType = TypeHandle(pResolvedToken->hClass); - } - } - else -#endif - { - ownerType = pMethod->GetMethodTable_NoLogging(); - } + TypeHandle ownerType = pMethod->GetMethodTable_NoLogging(); ZapSig::ExternalTokens externalTokens = ZapSig::NormalTokens; if (pInfoModule == NULL) @@ -1308,116 +1277,6 @@ BOOL ZapSig::EncodeMethod( methodFlags |= ENCODE_METHOD_SIG_OwnerType; } -#ifdef FEATURE_READYTORUN_COMPILER - if (IsReadyToRunCompilation() && (pConstrainedResolvedToken != NULL)) - { - methodFlags |= ENCODE_METHOD_SIG_Constrained; - } - - // FUTURE: This condition should likely be changed or reevaluated once support for smaller version bubbles is implemented. - if (IsReadyToRunCompilation() && (!IsLargeVersionBubbleEnabled() || !pMethod->GetModule()->IsInCurrentVersionBubble())) - { - Module * pReferencingModule = pMethod->IsNDirect() ? - pMethod->GetModule() : - IsDynamicScope(pResolvedToken->tokenScope) ? NULL: GetModule(pResolvedToken->tokenScope); - - // pReferencingModule may be NULL if the method is a dynamic method. - - if (pReferencingModule != NULL && !pReferencingModule->IsInCurrentVersionBubble()) - { - // FUTURE: Encoding of new cross-module references for ReadyToRun - // This warning is hit for recursive cross-module inlining. It is commented out to avoid noise. - // GetSvcLogger()->Printf(W("ReadyToRun: Method reference outside of current version bubble cannot be encoded\n")); - ThrowHR(E_FAIL); - } - - if (pMethod->IsNDirect()) - { - methodToken = pMethod->GetMemberDef_NoLogging(); - } - else if (!IsDynamicScope(pResolvedToken->tokenScope)) - { - // Normal case for IL code - methodToken = pResolvedToken->token; - } - else - { - // Dynamic scope case. IL Stubs only - if (!pMethod->GetModule()->IsSystem()) - { - _ASSERTE(FALSE); // IL stubs are expected to only have references to System. - ThrowHR(E_FAIL); - } - - if (pInfoModule == pMethod->GetModule()) - { - // This is assuming that the current module being compiled is the same as the module - // associated with the method being called. If so, we can identify the method by a MethodDef - // token. Otherwise, a more complex operation would be necessary. - methodToken = pMethod->GetMemberDef_NoLogging(); - } - else - { - // Attempt to compile IL stub with use of helper function outside of CoreLib - _ASSERTE(FALSE); - ThrowHR(E_FAIL); - } - - if (!ownerType.IsTypicalTypeDefinition() || pMethod->HasMethodInstantiation()) - { - _ASSERTE(FALSE); // IL Stubs are not expected to have use of generic functions - ThrowHR(E_FAIL); // Attempt to compile IL stub with use of generic function. This encoding does not support that. - } - } - - if (TypeFromToken(methodToken) != mdtMethodDef) - { - if (pReferencingModule == NULL) - { - // Invalid situation. Null pReferencingModule can only happen with a dynamic scope, - // and in that case the reference can only be a methoddef. - ThrowHR(E_FAIL); - } - } - - if (TypeFromToken(methodToken) == mdtMethodSpec) - { - IfFailThrow(pReferencingModule->GetMDImport()->GetMethodSpecProps(methodToken, &methodToken, NULL, NULL)); - } - - switch (TypeFromToken(methodToken)) - { - case mdtMethodDef: - _ASSERTE(pMethod->IsNDirect() || pResolvedToken->pTypeSpec == NULL); - if (!ownerType.HasInstantiation() || ownerType.IsTypicalTypeDefinition()) - { - methodFlags &= ~ENCODE_METHOD_SIG_OwnerType; - } - break; - - case mdtMemberRef: - _ASSERTE(pResolvedToken != NULL); - methodFlags |= ENCODE_METHOD_SIG_MemberRefToken; - - if (pResolvedToken->pTypeSpec == NULL) - { - methodFlags &= ~ENCODE_METHOD_SIG_OwnerType; - } - else - if (!(methodFlags & ENCODE_METHOD_SIG_InstantiatingStub)) - { - if (SigPointer(pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec).IsPolyType(NULL) == hasNoVars) - methodFlags &= ~ENCODE_METHOD_SIG_OwnerType; - } - break; - - default: - _ASSERTE(!"Unexpected method token type!"); - ThrowHR(E_NOTIMPL); - } - } - else -#endif if (IsNilToken(methodToken)) { methodFlags |= ENCODE_METHOD_SIG_SlotInsteadOfToken; @@ -1489,15 +1348,6 @@ BOOL ZapSig::EncodeMethod( _ASSERTE(pResolvedToken->cbTypeSpec > 0); DWORD moduleIndex = MODULE_INDEX_NONE; - if ((IsReadyToRunCompilation() && pMethod->GetModule()->IsInCurrentVersionBubble() && pInfoModule != GetModule(pResolvedToken->tokenScope))) - { - if (IsDynamicScope(pResolvedToken->tokenScope)) - { - _ASSERTE(FALSE); // IL stubs aren't expected to call methods which need this - ThrowHR(E_FAIL); - } - moduleIndex = (*((EncodeModuleCallback)pfnEncodeModule))(pEncodeModuleContext, (Module *) GetModule(pResolvedToken->tokenScope)); - } SigParser sigParser(pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec); CopyTypeSignature(&sigParser, pSigBuilder, moduleIndex); @@ -1546,10 +1396,6 @@ BOOL ZapSig::EncodeMethod( } DWORD moduleIndex = MODULE_INDEX_NONE; - if (IsReadyToRunCompilation() && pMethod->GetModule()->IsInCurrentVersionBubble() && pInfoModule != GetModule(pResolvedToken->tokenScope)) - { - moduleIndex = (*((EncodeModuleCallback)pfnEncodeModule))(pEncodeModuleContext, GetModule(pResolvedToken->tokenScope)); - } while (numGenArgs != 0) { @@ -1576,35 +1422,6 @@ BOOL ZapSig::EncodeMethod( } } -#ifdef FEATURE_READYTORUN_COMPILER - if ((methodFlags & ENCODE_METHOD_SIG_Constrained) != 0) - { - if (fEncodeUsingResolvedTokenSpecStreams && pConstrainedResolvedToken->pTypeSpec != NULL) - { - _ASSERTE(pConstrainedResolvedToken->cbTypeSpec > 0); - - DWORD moduleIndex = MODULE_INDEX_NONE; - if (IsReadyToRunCompilation() && pMethod->GetModule()->IsInCurrentVersionBubble() && pInfoModule != GetModule(pConstrainedResolvedToken->tokenScope)) - { - if (IsDynamicScope(pConstrainedResolvedToken->tokenScope)) - { - _ASSERTE(FALSE); // IL stubs aren't expected to call methods which need this - ThrowHR(E_FAIL); - } - moduleIndex = (*((EncodeModuleCallback)pfnEncodeModule))(pEncodeModuleContext, GetModule(pConstrainedResolvedToken->tokenScope)); - } - - SigParser sigParser(pConstrainedResolvedToken->pTypeSpec, pConstrainedResolvedToken->cbTypeSpec); - CopyTypeSignature(&sigParser, pSigBuilder, moduleIndex); - } - else - { - if (!zapSig.GetSignatureForTypeHandle(TypeHandle(pConstrainedResolvedToken->hClass), pSigBuilder)) - return FALSE; - } - } -#endif - return TRUE; } @@ -1625,75 +1442,10 @@ void ZapSig::EncodeField( } CONTRACTL_END; - MethodTable * pMT; + MethodTable * pMT = pField->GetApproxEnclosingMethodTable(); mdMethodDef fieldToken = pField->GetMemberDef(); - DWORD fieldFlags = ENCODE_FIELD_SIG_OwnerType; - -#ifdef FEATURE_READYTORUN_COMPILER - if (IsReadyToRunCompilation() && (!IsLargeVersionBubbleEnabled() || !pField->GetModule()->IsInCurrentVersionBubble())) - { - if (pResolvedToken == NULL) - { - _ASSERTE(!"CORINFO_RESOLVED_TOKEN required to encode field!"); - ThrowHR(E_FAIL); - } - - // Encode the referencing field type - pMT = (MethodTable *)(pResolvedToken->hClass); - - if (IsDynamicScope(pResolvedToken->tokenScope)) - { - _ASSERTE(FALSE); // IL stubs aren't expected to need to access this sort of field - ThrowHR(E_FAIL); - } - - Module * pReferencingModule = GetModule(pResolvedToken->tokenScope); - - if (!pReferencingModule->IsInCurrentVersionBubble()) - { - // FUTURE: Encoding of new cross-module references for ReadyToRun - // This warning is hit for recursive cross-module inlining. It is commented out to avoid noise. - // GetSvcLogger()->Printf(W("ReadyToRun: Field reference outside of current version bubble cannot be encoded\n")); - ThrowHR(E_FAIL); - } - _ASSERTE(pReferencingModule == GetAppDomain()->ToCompilationDomain()->GetTargetModule()); - - fieldToken = pResolvedToken->token; - - switch (TypeFromToken(fieldToken)) - { - case mdtFieldDef: - _ASSERTE(pResolvedToken->pTypeSpec == NULL); - fieldFlags &= ~ENCODE_FIELD_SIG_OwnerType; - break; - - case mdtMemberRef: - fieldFlags |= ENCODE_FIELD_SIG_MemberRefToken; - - if (pResolvedToken->pTypeSpec == NULL) - { - fieldFlags &= ~ENCODE_METHOD_SIG_OwnerType; - } - else - { - if (SigPointer(pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec).IsPolyType(NULL) == hasNoVars) - fieldFlags &= ~ENCODE_METHOD_SIG_OwnerType; - } - break; - - default: - _ASSERTE(!"Unexpected field token type!"); - ThrowHR(E_NOTIMPL); - } - } - else -#endif - { - pMT = pField->GetApproxEnclosingMethodTable(); - - fieldFlags |= ENCODE_FIELD_SIG_IndexInsteadOfToken; - } + DWORD fieldFlags = ENCODE_FIELD_SIG_OwnerType | ENCODE_FIELD_SIG_IndexInsteadOfToken; // // output the flags @@ -1707,10 +1459,6 @@ void ZapSig::EncodeField( _ASSERTE(pResolvedToken->cbTypeSpec > 0); DWORD moduleIndex = MODULE_INDEX_NONE; - if ((IsReadyToRunCompilation() && pField->GetModule()->IsInCurrentVersionBubble() && pInfoModule != (Module *) pResolvedToken->tokenScope)) - { - moduleIndex = (*((EncodeModuleCallback)pfnEncodeModule))(pEncodeModuleContext, (Module *) pResolvedToken->tokenScope); - } SigParser sigParser(pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec); CopyTypeSignature(&sigParser, pSigBuilder, moduleIndex);