diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index e5278d53388834..707359a3b9a0db 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -60,7 +60,6 @@ if(CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_AMD64) add_compile_definitions(OUT_OF_PROCESS_SETTHREADCONTEXT) endif(CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_AMD64) -add_compile_definitions(FEATURE_CODE_VERSIONING) add_definitions(-DFEATURE_COLLECTIBLE_TYPES) if(CLR_CMAKE_TARGET_WIN32) @@ -176,6 +175,7 @@ endif(NOT CLR_CMAKE_HOST_ANDROID) add_definitions(-DFEATURE_SYMDIFF) if (FEATURE_TIERED_COMPILATION) + add_compile_definitions(FEATURE_CODE_VERSIONING) add_compile_definitions(FEATURE_TIERED_COMPILATION) endif(FEATURE_TIERED_COMPILATION) diff --git a/src/coreclr/vm/appdomain.cpp b/src/coreclr/vm/appdomain.cpp index 23d205e26c1717..862f1c8ff64a70 100644 --- a/src/coreclr/vm/appdomain.cpp +++ b/src/coreclr/vm/appdomain.cpp @@ -719,7 +719,9 @@ void SystemDomain::Attach() CONTRACTL_END; // Initialize stub managers +#ifndef FEATURE_PORTABLE_ENTRYPOINTS PrecodeStubManager::Init(); +#endif // !FEATURE_PORTABLE_ENTRYPOINTS JumpStubStubManager::Init(); RangeSectionStubManager::Init(); ILStubManager::Init(); diff --git a/src/coreclr/vm/assembly.cpp b/src/coreclr/vm/assembly.cpp index 7ec8d6b0db16e0..90f7b35c1aeafd 100644 --- a/src/coreclr/vm/assembly.cpp +++ b/src/coreclr/vm/assembly.cpp @@ -2127,9 +2127,11 @@ BOOL Assembly::DoIncrementalLoad(FileLoadLevel level) DeliverSyncEvents(); break; +#ifdef FEATURE_IJW case FILE_LOAD_VTABLE_FIXUPS: VtableFixups(); break; +#endif // FEATURE_IJW case FILE_LOADED: FinishLoad(); @@ -2206,12 +2208,14 @@ void Assembly::EagerFixups() #endif // FEATURE_READYTORUN } +#ifdef FEATURE_IJW void Assembly::VtableFixups() { WRAPPER_NO_CONTRACT; GetModule()->FixupVTables(); } +#endif // FEATURE_IJW void Assembly::FinishLoad() { diff --git a/src/coreclr/vm/assembly.hpp b/src/coreclr/vm/assembly.hpp index 9d6bf377e0c523..3edb4c0b3e1570 100644 --- a/src/coreclr/vm/assembly.hpp +++ b/src/coreclr/vm/assembly.hpp @@ -126,7 +126,9 @@ class Assembly void Begin(); void BeforeTypeLoad(); void EagerFixups(); +#ifdef FEATURE_IJW void VtableFixups(); +#endif // FEATURE_IJW void DeliverSyncEvents(); void DeliverAsyncEvents(); void FinishLoad(); diff --git a/src/coreclr/vm/assemblyspec.hpp b/src/coreclr/vm/assemblyspec.hpp index 49446800fe7be2..8f21f9e010ed32 100644 --- a/src/coreclr/vm/assemblyspec.hpp +++ b/src/coreclr/vm/assemblyspec.hpp @@ -33,7 +33,9 @@ enum FileLoadLevel FILE_LOAD_BEFORE_TYPE_LOAD, FILE_LOAD_EAGER_FIXUPS, FILE_LOAD_DELIVER_EVENTS, +#ifdef FEATURE_IJW FILE_LOAD_VTABLE_FIXUPS, +#endif // FEATURE_IJW FILE_LOADED, // Loaded by not yet active FILE_ACTIVE // Fully active (constructors run & security checked) }; diff --git a/src/coreclr/vm/ceeload.cpp b/src/coreclr/vm/ceeload.cpp index bb0f2037816852..b0b0b61cee54f5 100644 --- a/src/coreclr/vm/ceeload.cpp +++ b/src/coreclr/vm/ceeload.cpp @@ -1319,10 +1319,12 @@ void Module::AllocateMaps() m_TypeRefToMethodTableMap.dwCount = TYPEREF_MAP_INITIAL_SIZE; m_MemberRefMap.dwCount = MEMBERREF_MAP_INITIAL_SIZE; m_MethodDefToDescMap.dwCount = MEMBERDEF_MAP_INITIAL_SIZE; - m_ILCodeVersioningStateMap.dwCount = MEMBERDEF_MAP_INITIAL_SIZE; m_FieldDefToDescMap.dwCount = MEMBERDEF_MAP_INITIAL_SIZE; m_GenericParamToDescMap.dwCount = GENERICPARAM_MAP_INITIAL_SIZE; m_ManifestModuleReferencesMap.dwCount = ASSEMBLYREFERENCES_MAP_INITIAL_SIZE; +#ifdef FEATURE_CODE_VERSIONING + m_ILCodeVersioningStateMap.dwCount = MEMBERDEF_MAP_INITIAL_SIZE; +#endif // FEATURE_CODE_VERSIONING } else { @@ -1340,9 +1342,6 @@ void Module::AllocateMaps() // Get # MethodDefs m_MethodDefToDescMap.dwCount = pImport->GetCountWithTokenKind(mdtMethodDef)+1; - // IL code versions are relatively rare so keep small. - m_ILCodeVersioningStateMap.dwCount = 1; - // Get # FieldDefs m_FieldDefToDescMap.dwCount = pImport->GetCountWithTokenKind(mdtFieldDef)+1; @@ -1351,6 +1350,11 @@ void Module::AllocateMaps() // Get the number of AssemblyReferences in the map m_ManifestModuleReferencesMap.dwCount = pImport->GetCountWithTokenKind(mdtAssemblyRef)+1; + +#ifdef FEATURE_CODE_VERSIONING + // IL code versions are relatively rare so keep small. + m_ILCodeVersioningStateMap.dwCount = 1; +#endif // FEATURE_CODE_VERSIONING } S_SIZE_T nTotal; @@ -1359,10 +1363,12 @@ void Module::AllocateMaps() nTotal += m_TypeRefToMethodTableMap.dwCount; nTotal += m_MemberRefMap.dwCount; nTotal += m_MethodDefToDescMap.dwCount; - nTotal += m_ILCodeVersioningStateMap.dwCount; nTotal += m_FieldDefToDescMap.dwCount; nTotal += m_GenericParamToDescMap.dwCount; nTotal += m_ManifestModuleReferencesMap.dwCount; +#ifdef FEATURE_CODE_VERSIONING + nTotal += m_ILCodeVersioningStateMap.dwCount; +#endif // FEATURE_CODE_VERSIONING _ASSERTE (m_pAssembly && m_pAssembly->GetLowFrequencyHeap()); pTable = (PTR_TADDR)(void*)m_pAssembly->GetLowFrequencyHeap()->AllocMem(nTotal * S_SIZE_T(sizeof(TADDR))); @@ -1376,7 +1382,7 @@ void Module::AllocateMaps() m_TypeRefToMethodTableMap.pNext = NULL; m_TypeRefToMethodTableMap.supportedFlags = TYPE_REF_MAP_ALL_FLAGS; - m_TypeRefToMethodTableMap.pTable = &pTable[m_TypeDefToMethodTableMap.dwCount]; + m_TypeRefToMethodTableMap.pTable = &m_TypeDefToMethodTableMap.pTable[m_TypeDefToMethodTableMap.dwCount]; m_MemberRefMap.pNext = NULL; m_MemberRefMap.supportedFlags = MEMBER_REF_MAP_ALL_FLAGS; @@ -1386,13 +1392,9 @@ void Module::AllocateMaps() m_MethodDefToDescMap.supportedFlags = METHOD_DEF_MAP_ALL_FLAGS; m_MethodDefToDescMap.pTable = &m_MemberRefMap.pTable[m_MemberRefMap.dwCount]; - m_ILCodeVersioningStateMap.pNext = NULL; - m_ILCodeVersioningStateMap.supportedFlags = METHOD_DEF_MAP_ALL_FLAGS; - m_ILCodeVersioningStateMap.pTable = &m_MethodDefToDescMap.pTable[m_MethodDefToDescMap.dwCount]; - m_FieldDefToDescMap.pNext = NULL; m_FieldDefToDescMap.supportedFlags = FIELD_DEF_MAP_ALL_FLAGS; - m_FieldDefToDescMap.pTable = &m_ILCodeVersioningStateMap.pTable[m_ILCodeVersioningStateMap.dwCount]; + m_FieldDefToDescMap.pTable = &m_MethodDefToDescMap.pTable[m_MethodDefToDescMap.dwCount]; m_GenericParamToDescMap.pNext = NULL; m_GenericParamToDescMap.supportedFlags = GENERIC_PARAM_MAP_ALL_FLAGS; @@ -1401,6 +1403,12 @@ void Module::AllocateMaps() m_ManifestModuleReferencesMap.pNext = NULL; m_ManifestModuleReferencesMap.supportedFlags = MANIFEST_MODULE_MAP_ALL_FLAGS; m_ManifestModuleReferencesMap.pTable = &m_GenericParamToDescMap.pTable[m_GenericParamToDescMap.dwCount]; + +#ifdef FEATURE_CODE_VERSIONING + m_ILCodeVersioningStateMap.pNext = NULL; + m_ILCodeVersioningStateMap.supportedFlags = METHOD_DEF_MAP_ALL_FLAGS; + m_ILCodeVersioningStateMap.pTable = &m_ManifestModuleReferencesMap.pTable[m_ManifestModuleReferencesMap.dwCount]; +#endif // FEATURE_CODE_VERSIONING } @@ -3137,16 +3145,18 @@ BYTE * GetTargetForVTableEntry(HINSTANCE hInst, BYTE **ppVTEntry) return *ppVTEntry; } +#ifdef FEATURE_IJW //====================================================================================== // Fixup vtables stored in the header to contain pointers to method desc // prestubs rather than metadata method tokens. void Module::FixupVTables() { - CONTRACTL{ + CONTRACTL + { INSTANCE_CHECK; STANDARD_VM_CHECK; - } CONTRACTL_END; - + } + CONTRACTL_END; // If we've already fixed up, or this is not an IJW module, just return. // NOTE: This relies on ILOnly files not having fixups. If this changes, @@ -3406,6 +3416,7 @@ void Module::FixupVTables() SetIsIJWFixedUp(); // On the module } // End of Stage 3 } +#endif // FEATURE_IJW ModuleBase *Module::GetModuleFromIndex(DWORD ix) { diff --git a/src/coreclr/vm/ceeload.h b/src/coreclr/vm/ceeload.h index c4d02b6e02dbb6..f3db489f9e52dc 100644 --- a/src/coreclr/vm/ceeload.h +++ b/src/coreclr/vm/ceeload.h @@ -740,16 +740,18 @@ class Module : public ModuleBase // For generic methods, IsGenericTypeDefinition() is true i.e. instantiation at formals LookupMap m_MethodDefToDescMap; - // Linear mapping from MethodDef token to ILCodeVersioningState * - // This is used for Code Versioning logic - LookupMap m_ILCodeVersioningStateMap; - // Linear mapping from FieldDef token to FieldDesc* LookupMap m_FieldDefToDescMap; // Linear mapping from GenericParam token to TypeVarTypeDesc* LookupMap m_GenericParamToDescMap; +#ifdef FEATURE_CODE_VERSIONING + // Linear mapping from MethodDef token to ILCodeVersioningState * + // This is used for Code Versioning logic + LookupMap m_ILCodeVersioningStateMap; +#endif // FEATURE_CODE_VERSIONING + // IL stub cache with fabricated MethodTable parented by this module. ILStubCache *m_pILStubCache; @@ -871,7 +873,9 @@ class Module : public ModuleBase void ApplyMetaData(); +#ifdef FEATURE_IJW void FixupVTables(); +#endif // FEATURE_IJW void FreeClassTables(); @@ -1252,6 +1256,7 @@ class Module : public ModuleBase } #endif // !DACCESS_COMPILE +#ifdef FEATURE_CODE_VERSIONING PTR_ILCodeVersioningState LookupILCodeVersioningState(mdMethodDef token); #ifndef DACCESS_COMPILE @@ -1270,6 +1275,7 @@ class Module : public ModuleBase m_ILCodeVersioningStateMap.SetElement(RidFromToken(token), value); } #endif // !DACCESS_COMPILE +#endif // FEATURE_CODE_VERSIONING #ifndef DACCESS_COMPILE FieldDesc *LookupFieldDef(mdFieldDef token) @@ -1714,7 +1720,9 @@ struct cdac_data static constexpr size_t MethodDefToDescMap = offsetof(Module, m_MethodDefToDescMap); static constexpr size_t TypeDefToMethodTableMap = offsetof(Module, m_TypeDefToMethodTableMap); static constexpr size_t TypeRefToMethodTableMap = offsetof(Module, m_TypeRefToMethodTableMap); +#ifdef FEATURE_CODE_VERSIONING static constexpr size_t MethodDefToILCodeVersioningStateMap = offsetof(Module, m_ILCodeVersioningStateMap); +#endif // FEATURE_CODE_VERSIONING static constexpr size_t DynamicILBlobTable = offsetof(Module, m_debuggerSpecificData.m_pDynamicILBlobTable); }; diff --git a/src/coreclr/vm/ceeload.inl b/src/coreclr/vm/ceeload.inl index 2067de38088fd9..fe7ad7c7a9a09f 100644 --- a/src/coreclr/vm/ceeload.inl +++ b/src/coreclr/vm/ceeload.inl @@ -274,6 +274,7 @@ inline PTR_MethodDesc Module::LookupMethodDef(mdMethodDef token) return m_MethodDefToDescMap.GetElement(RidFromToken(token)); } +#ifdef FEATURE_CODE_VERSIONING inline PTR_ILCodeVersioningState Module::LookupILCodeVersioningState(mdMethodDef token) { CONTRACTL @@ -288,6 +289,7 @@ inline PTR_ILCodeVersioningState Module::LookupILCodeVersioningState(mdMethodDef _ASSERTE(TypeFromToken(token) == mdtMethodDef); return m_ILCodeVersioningStateMap.GetElement(RidFromToken(token)); } +#endif // FEATURE_CODE_VERSIONING inline MethodDesc *Module::LookupMemberRefAsMethod(mdMemberRef token) { diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index fb59a8eb5903f6..8a7315add3bdcb 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -669,11 +669,16 @@ void EEStartupHelper() JITInlineTrackingMap::StaticInitialize(); MethodDescBackpatchInfoTracker::StaticInitialize(); + +#ifdef FEATURE_CODE_VERSIONING CodeVersionManager::StaticInitialize(); +#endif // FEATURE_CODE_VERSIONING + #ifdef FEATURE_TIERED_COMPILATION TieredCompilationManager::StaticInitialize(); CallCountingManager::StaticInitialize(); #endif // FEATURE_TIERED_COMPILATION + OnStackReplacementManager::StaticInitialize(); MethodTable::InitMethodDataCache(); diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index fae188a904282d..643b2f41d12017 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -3407,7 +3407,7 @@ TypeHandle InterpreterJitManager::ResolveEHClause(EE_ILEXCEPTION_CLAUSE* pEHClau _ASSERTE(!declaringType.IsNull()); SigTypeContext typeContext(pMD, declaringType); - + Module* pModule = pMD->GetModule(); thResolved = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, pEHClause->ClassToken, &typeContext, @@ -5127,7 +5127,7 @@ MethodDesc * ExecutionManager::GetCodeMethodDesc(PCODE currentPC) CONTRACTL_END ExecutionManager::ScanFlag scanFlag = ExecutionManager::GetScanFlags(); -#ifdef FEATURE_INTERPRETER +#if defined(FEATURE_INTERPRETER) && !defined(FEATURE_PORTABLE_ENTRYPOINTS) RangeSection * pRS = ExecutionManager::FindCodeRange(currentPC, scanFlag); if (pRS == NULL) return NULL; @@ -5143,7 +5143,7 @@ MethodDesc * ExecutionManager::GetCodeMethodDesc(PCODE currentPC) } } } -#endif // FEATURE_INTERPRETER +#endif // FEATURE_INTERPRETER && !FEATURE_PORTABLE_ENTRYPOINTS EECodeInfo codeInfo(currentPC, scanFlag); if (!codeInfo.IsValid()) diff --git a/src/coreclr/vm/codeversion.cpp b/src/coreclr/vm/codeversion.cpp index d1afe575a70c93..1fdfa6f952f44e 100644 --- a/src/coreclr/vm/codeversion.cpp +++ b/src/coreclr/vm/codeversion.cpp @@ -320,7 +320,7 @@ MethodDescVersioningState* NativeCodeVersion::GetMethodDescVersioningState() CodeVersionManager* pCodeVersionManager = pMethodDesc->GetCodeVersionManager(); return pCodeVersionManager->GetMethodDescVersioningState(pMethodDesc); } -#endif +#endif // !DACCESS_COMPILE bool NativeCodeVersion::IsFinalTier() const { @@ -1737,7 +1737,7 @@ PCODE CodeVersionManager::PublishVersionableCodeIfNecessary( break; } - if (!pMethodDesc->IsPointingToPrestub()) + if (!pMethodDesc->ShouldCallPrestub()) { *doFullBackpatchRef = true; return (PCODE)NULL; diff --git a/src/coreclr/vm/codeversion.h b/src/coreclr/vm/codeversion.h index 33700718aad612..0e55b7fc3d7e89 100644 --- a/src/coreclr/vm/codeversion.h +++ b/src/coreclr/vm/codeversion.h @@ -29,7 +29,7 @@ typedef DPTR(class ILCodeVersioningState) PTR_ILCodeVersioningState; class CodeVersionManager; typedef DPTR(class CodeVersionManager) PTR_CodeVersionManager; -#endif +#endif // FEATURE_CODE_VERSIONING #ifdef HAVE_GCCOVER class GCCoverageInfo; @@ -46,14 +46,14 @@ class NativeCodeVersion #ifdef FEATURE_CODE_VERSIONING friend class MethodDescVersioningState; friend class ILCodeVersion; -#endif +#endif // FEATURE_CODE_VERSIONING public: NativeCodeVersion(); NativeCodeVersion(const NativeCodeVersion & rhs); #ifdef FEATURE_CODE_VERSIONING NativeCodeVersion(PTR_NativeCodeVersionNode pVersionNode); -#endif +#endif // FEATURE_CODE_VERSIONING explicit NativeCodeVersion(PTR_MethodDesc pMethod); BOOL IsNull() const; @@ -65,7 +65,7 @@ class NativeCodeVersion #ifdef FEATURE_CODE_VERSIONING ILCodeVersion GetILCodeVersion() const; ReJITID GetILCodeVersionId() const; -#endif +#endif // FEATURE_CODE_VERSIONING #ifndef DACCESS_COMPILE BOOL SetNativeCodeInterlocked(PCODE pCode, PCODE pExpected = 0); diff --git a/src/coreclr/vm/comdelegate.cpp b/src/coreclr/vm/comdelegate.cpp index 5d59f3298e9a18..2d624e5beb0059 100644 --- a/src/coreclr/vm/comdelegate.cpp +++ b/src/coreclr/vm/comdelegate.cpp @@ -1344,6 +1344,10 @@ LPVOID COMDelegate::ConvertToCallback(OBJECTREF pDelegateObj) } else { +#ifdef FEATURE_PORTABLE_ENTRYPOINTS + COMPlusThrow(kPlatformNotSupportedException, W("PlatformNotSupported_DynamicEntrypoint")); + +#else // !FEATURE_PORTABLE_ENTRYPOINTS UMEntryThunkData* pUMEntryThunk = NULL; SyncBlock* pSyncBlock = pDelegate->GetSyncBlock(); @@ -1407,6 +1411,7 @@ LPVOID COMDelegate::ConvertToCallback(OBJECTREF pDelegateObj) } pCode = (PCODE)pUMEntryThunk->GetCode(); +#endif // FEATURE_PORTABLE_ENTRYPOINTS } GCPROTECT_END(); @@ -1431,6 +1436,7 @@ OBJECTREF COMDelegate::ConvertToDelegate(LPVOID pCallback, MethodTable* pMT) // Check if this callback was originally a managed method passed out to unmanaged code. // +#ifndef FEATURE_PORTABLE_ENTRYPOINTS UMEntryThunk* pUMEntryThunk = NULL; auto stubKind = RangeSectionStubManager::GetStubKind((PCODE)pCallback); @@ -1443,19 +1449,19 @@ OBJECTREF COMDelegate::ConvertToDelegate(LPVOID pCallback, MethodTable* pMT) } } - // Lookup the callsite in the hash, if found, we can map this call back to its managed function. // Otherwise, we'll treat this as an unmanaged callsite. // Make sure that the pointer doesn't have the value of 1 which is our hash table deleted item marker. - OBJECTHANDLE DelegateHnd = (pUMEntryThunk != NULL) + OBJECTHANDLE delegateHnd = (pUMEntryThunk != NULL) ? pUMEntryThunk->GetData()->GetObjectHandle() : (OBJECTHANDLE)NULL; - if (DelegateHnd != (OBJECTHANDLE)NULL) + if (delegateHnd != (OBJECTHANDLE)NULL) { // Found a managed callsite - return ObjectFromHandle(DelegateHnd); + return ObjectFromHandle(delegateHnd); } +#endif // !FEATURE_PORTABLE_ENTRYPOINTS // Validate the MethodTable is a delegate type // See Marshal.GetDelegateForFunctionPointer() for exception details. diff --git a/src/coreclr/vm/corelib.cpp b/src/coreclr/vm/corelib.cpp index 75f5dd62da82ea..9e89019b200780 100644 --- a/src/coreclr/vm/corelib.cpp +++ b/src/coreclr/vm/corelib.cpp @@ -14,6 +14,7 @@ // #include "arraynative.h" #include "objectnative.h" +#include "dllimport.h" #include "comdelegate.h" #include "customattribute.h" #include "comdynamic.h" diff --git a/src/coreclr/vm/corhost.cpp b/src/coreclr/vm/corhost.cpp index a2369f89695cfe..4f1c5afdd4bc1b 100644 --- a/src/coreclr/vm/corhost.cpp +++ b/src/coreclr/vm/corhost.cpp @@ -682,7 +682,6 @@ HRESULT CorHost2::CreateDelegate( LPCWSTR wszMethodName, INT_PTR* fnPtr) { - CONTRACTL { NOTHROW; @@ -691,8 +690,6 @@ HRESULT CorHost2::CreateDelegate( } CONTRACTL_END; - HRESULT hr=S_OK; - EMPTY_STRING_TO_NULL(wszAssemblyName); EMPTY_STRING_TO_NULL(wszClassName); EMPTY_STRING_TO_NULL(wszMethodName); @@ -714,7 +711,13 @@ HRESULT CorHost2::CreateDelegate( if (appDomainID != DefaultADID) return HOST_E_INVALIDOPERATION; + HRESULT hr = S_OK; BEGIN_EXTERNAL_ENTRYPOINT(&hr); + +#ifdef FEATURE_PORTABLE_ENTRYPOINTS + hr = E_NOTIMPL; + +#else // !FEATURE_PORTABLE_ENTRYPOINTS GCX_COOP_THREAD_EXISTS(GET_THREAD()); MAKE_UTF8PTR_FROMWIDE(szClassName, wszClassName); @@ -759,6 +762,7 @@ HRESULT CorHost2::CreateDelegate( *fnPtr = (INT_PTR)pUMEntryThunk->GetCode(); } } +#endif // FEATURE_PORTABLE_ENTRYPOINTS END_EXTERNAL_ENTRYPOINT; diff --git a/src/coreclr/vm/datadescriptor/datadescriptor.inc b/src/coreclr/vm/datadescriptor/datadescriptor.inc index e54560e22ee228..e84411a6fc338b 100644 --- a/src/coreclr/vm/datadescriptor/datadescriptor.inc +++ b/src/coreclr/vm/datadescriptor/datadescriptor.inc @@ -183,7 +183,9 @@ CDAC_TYPE_FIELD(Module, /*pointer*/, MemberRefToDescMap, cdac_data::Memb CDAC_TYPE_FIELD(Module, /*pointer*/, MethodDefToDescMap, cdac_data::MethodDefToDescMap) CDAC_TYPE_FIELD(Module, /*pointer*/, TypeDefToMethodTableMap, cdac_data::TypeDefToMethodTableMap) CDAC_TYPE_FIELD(Module, /*pointer*/, TypeRefToMethodTableMap, cdac_data::TypeRefToMethodTableMap) +#ifdef FEATURE_CODE_VERSIONING CDAC_TYPE_FIELD(Module, /*pointer*/, MethodDefToILCodeVersioningStateMap, cdac_data::MethodDefToILCodeVersioningStateMap) +#endif // FEATURE_CODE_VERSIONING CDAC_TYPE_FIELD(Module, /*pointer*/, DynamicILBlobTable, cdac_data::DynamicILBlobTable) CDAC_TYPE_END(Module) @@ -499,14 +501,18 @@ CDAC_TYPE_END(CodePointer) CDAC_TYPE_BEGIN(MethodDescCodeData) CDAC_TYPE_INDETERMINATE(MethodDescCodeData) CDAC_TYPE_FIELD(MethodDescCodeData, /*CodePointer*/, TemporaryEntryPoint, offsetof(MethodDescCodeData,TemporaryEntryPoint)) +#ifdef FEATURE_CODE_VERSIONING CDAC_TYPE_FIELD(MethodDescCodeData, /*pointer*/, VersioningState, offsetof(MethodDescCodeData,VersioningState)) +#endif // FEATURE_CODE_VERSIONING CDAC_TYPE_END(MethodDescCodeData) +#ifdef FEATURE_CODE_VERSIONING CDAC_TYPE_BEGIN(MethodDescVersioningState) CDAC_TYPE_INDETERMINATE(MethodDescVersioningState) CDAC_TYPE_FIELD(MethodDescVersioningState, /*pointer*/, NativeCodeVersionNode, cdac_data::NativeCodeVersionNode) CDAC_TYPE_FIELD(MethodDescVersioningState, /*uint8*/, Flags, cdac_data::Flags) CDAC_TYPE_END(MethodDescVersioningState) +#endif // FEATURE_CODE_VERSIONING #ifndef FEATURE_PORTABLE_ENTRYPOINTS CDAC_TYPE_BEGIN(PrecodeMachineDescriptor) @@ -677,6 +683,7 @@ CDAC_TYPE_FIELD(CodeHeapListNode, /*pointer*/, MapBase, offsetof(HeapList, mapBa CDAC_TYPE_FIELD(CodeHeapListNode, /*pointer*/, HeaderMap, offsetof(HeapList, pHdrMap)) CDAC_TYPE_END(CodeHeapListNode) +#ifdef FEATURE_CODE_VERSIONING CDAC_TYPE_BEGIN(ILCodeVersioningState) CDAC_TYPE_INDETERMINATE(ILCodeVersioningState) CDAC_TYPE_FIELD(ILCodeVersioningState, /*pointer*/, FirstVersionNode, cdac_data::FirstVersionNode) @@ -705,6 +712,7 @@ CDAC_TYPE_FIELD(ILCodeVersionNode, /*pointer*/, Next, cdac_data::RejitState) CDAC_TYPE_FIELD(ILCodeVersionNode, /*pointer*/, ILAddress, cdac_data::ILAddress) CDAC_TYPE_END(ILCodeVersionNode) +#endif // FEATURE_CODE_VERSIONING CDAC_TYPE_BEGIN(ProfControlBlock) CDAC_TYPE_FIELD(ProfControlBlock, /*uint64*/, GlobalEventMask, offsetof(ProfControlBlock, globalEventMask)) diff --git a/src/coreclr/vm/dllimport.cpp b/src/coreclr/vm/dllimport.cpp index 9bf757b3ba0750..14d504199be7c1 100644 --- a/src/coreclr/vm/dllimport.cpp +++ b/src/coreclr/vm/dllimport.cpp @@ -572,7 +572,6 @@ class ILStubState : public StubState { default: UNREACHABLE_MSG("Unexpected element type found on native return type."); - break; case ELEMENT_TYPE_VOID: _ASSERTE(retvalLocalNum == (DWORD)-1); pcsExceptionHandler->EmitPOP(); @@ -2014,6 +2013,10 @@ void PInvokeStubLinker::Begin(DWORD dwStubFlags) { if (SF_IsDelegateStub(dwStubFlags)) { +#ifdef FEATURE_PORTABLE_ENTRYPOINTS + _ASSERTE(!"Delegate reverse pinvoke stubs not supported with FEATURE_PORTABLE_ENTRYPOINTS"); + +#else // !FEATURE_PORTABLE_ENTRYPOINTS // // recover delegate object from UMEntryThunk @@ -2024,6 +2027,7 @@ void PInvokeStubLinker::Begin(DWORD dwStubFlags) m_pcsDispatch->EmitLDIND_I(); // get OBJECTHANDLE m_pcsDispatch->EmitLDIND_REF(); // get Delegate object m_pcsDispatch->EmitLDFLD(GetToken(CoreLibBinder::GetField(FIELD__DELEGATE__TARGET))); +#endif // FEATURE_PORTABLE_ENTRYPOINTS } } @@ -2186,6 +2190,10 @@ void PInvokeStubLinker::DoPInvoke(ILCodeStream *pcsEmit, DWORD dwStubFlags, Meth } else // native-to-managed { +#ifdef FEATURE_PORTABLE_ENTRYPOINTS + _ASSERTE(!"Delegate reverse pinvoke stubs not supported with FEATURE_PORTABLE_ENTRYPOINTS"); + +#else // !FEATURE_PORTABLE_ENTRYPOINTS if (SF_IsDelegateStub(dwStubFlags)) // reverse P/Invoke via delegate { int tokDelegate_methodPtr = pcsEmit->GetToken(CoreLibBinder::GetField(FIELD__DELEGATE__METHOD_PTR)); @@ -2212,6 +2220,7 @@ void PInvokeStubLinker::DoPInvoke(ILCodeStream *pcsEmit, DWORD dwStubFlags, Meth // pcsEmit->EmitADD(); pcsEmit->EmitLDIND_I(); // Get UMEntryThunk::m_pManagedTarget } +#endif // FEATURE_PORTABLE_ENTRYPOINTS } // For managed-to-native calls, the rest of the work is done by the JIT. It will @@ -5650,6 +5659,9 @@ PCODE PInvoke::GetStubForILStub(PInvokeMethodDesc* pNMD, MethodDesc** ppStubMD, { CONSISTENCY_CHECK(pNMD->IsVarArgs()); +#ifdef FEATURE_PORTABLE_ENTRYPOINTS + COMPlusThrow(kInvalidProgramException, IDS_EE_VARARG_NOT_SUPPORTED); +#else // !FEATURE_PORTABLE_ENTRYPOINTS // // varargs goes through vararg PInvoke stub // @@ -5657,6 +5669,7 @@ PCODE PInvoke::GetStubForILStub(PInvokeMethodDesc* pNMD, MethodDesc** ppStubMD, // Only vararg P/Invoke use shared stubs, they need a precode to push the hidden argument. (void)pNMD->GetOrCreatePrecode(); +#endif // FEATURE_PORTABLE_ENTRYPOINTS } if (pNMD->IsEarlyBound()) diff --git a/src/coreclr/vm/dllimportcallback.cpp b/src/coreclr/vm/dllimportcallback.cpp index 341a538e9fd185..29409f8c1b63dc 100644 --- a/src/coreclr/vm/dllimportcallback.cpp +++ b/src/coreclr/vm/dllimportcallback.cpp @@ -4,8 +4,7 @@ // File: DllImportCallback.cpp // -// - +#ifndef FEATURE_PORTABLE_ENTRYPOINTS #include "common.h" @@ -164,20 +163,6 @@ UMEntryThunkData *UMEntryThunkCache::GetUMEntryThunk(MethodDesc *pMD) RETURN pThunk; } -// FailFast if a method marked UnmanagedCallersOnlyAttribute is -// invoked directly from managed code. UMThunkStub.asm check the -// mode and call this function to failfast. -extern "C" VOID STDCALL ReversePInvokeBadTransition() -{ - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_TRIGGERS; - // Fail - EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE( - COR_E_EXECUTIONENGINE, - W("Invalid Program: attempted to call a UnmanagedCallersOnly method from managed code.") - ); -} - //------------------------------------------------------------------------- // This function is used to report error when we call collected delegate. // But memory that was allocated for thunk can be reused, due to it this @@ -210,20 +195,20 @@ VOID CallbackOnCollectedDelegate(UMEntryThunkData* pEntryThunkData) EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_FAILFAST, message.GetUnicode()); } -#ifdef FEATURE_INTERPRETER +#if defined(FEATURE_INTERPRETER) PLATFORM_THREAD_LOCAL UMEntryThunkData * t_MostRecentUMEntryThunkData; -UMEntryThunkData * GetMostRecentUMEntryThunkData() +UMEntryThunkData* GetMostRecentUMEntryThunkData() { LIMITED_METHOD_CONTRACT; - UMEntryThunkData * result = t_MostRecentUMEntryThunkData; + UMEntryThunkData* result = t_MostRecentUMEntryThunkData; t_MostRecentUMEntryThunkData = nullptr; return result; } -#endif +#endif // FEATURE_INTERPRETER -PCODE TheUMEntryPrestubWorker(UMEntryThunkData * pUMEntryThunkData) +PCODE TheUMEntryPrestubWorker(UMEntryThunkData* pUMEntryThunkData) { STATIC_CONTRACT_THROWS; STATIC_CONTRACT_GC_TRIGGERS; @@ -449,3 +434,4 @@ VOID UMThunkMarshInfo::RunTimeInit() // Must be the last thing we set! InterlockedCompareExchangeT(&m_pILStub, pFinalILStub, (PCODE)1); } +#endif // !FEATURE_PORTABLE_ENTRYPOINTS diff --git a/src/coreclr/vm/dllimportcallback.h b/src/coreclr/vm/dllimportcallback.h index eedf953b0ff394..ad34a04db45765 100644 --- a/src/coreclr/vm/dllimportcallback.h +++ b/src/coreclr/vm/dllimportcallback.h @@ -4,12 +4,11 @@ // File: DllImportCallback.h // -// - - #ifndef __dllimportcallback_h__ #define __dllimportcallback_h__ +#ifndef FEATURE_PORTABLE_ENTRYPOINTS + #include "object.h" #include "stublink.h" #include "ceeload.h" @@ -247,7 +246,8 @@ class UMEntryThunkData PCODE entryPoint = m_pUMThunkMarshInfo->GetExecStubEntryPoint(); -#ifdef FEATURE_INTERPRETER + bool setTarget = true; +#if defined(FEATURE_INTERPRETER) // For interpreted stubs we need to ensure that TheUMEntryPrestubWorker runs for every // unmanaged-to-managed invocation in order to populate the TLS variable every time. auto stubKind = RangeSectionStubManager::GetStubKind(entryPoint); @@ -257,12 +257,12 @@ class UMEntryThunkData if (pPrecode->GetType() == PRECODE_INTERPRETER) { m_pInterpretedTarget = entryPoint; - entryPoint = (PCODE)0; + setTarget = false; } } - - if (entryPoint != (PCODE)0) #endif // FEATURE_INTERPRETER + + if (setTarget) { m_pUMEntryThunk->SetTargetUnconditional(entryPoint); } @@ -423,4 +423,9 @@ EXCEPTION_HANDLER_DECL(FastNExportExceptHandler); extern "C" void TheUMEntryPrestub(void); extern "C" PCODE TheUMEntryPrestubWorker(UMEntryThunkData * pUMEntryThunk); +#if defined(FEATURE_INTERPRETER) +UMEntryThunkData* GetMostRecentUMEntryThunkData(); +#endif // FEATURE_INTERPRETER +#endif // !FEATURE_PORTABLE_ENTRYPOINTS + #endif //__dllimportcallback_h__ diff --git a/src/coreclr/vm/encee.cpp b/src/coreclr/vm/encee.cpp index 4959fde39cd43e..025df8ac2aa77f 100644 --- a/src/coreclr/vm/encee.cpp +++ b/src/coreclr/vm/encee.cpp @@ -606,7 +606,7 @@ PCODE EditAndContinueModule::JitUpdatedFunction( MethodDesc *pMD, // get the code address (may jit the fcn if not already jitted) EX_TRY { - if (pMD->IsPointingToNativeCode()) + if (!pMD->ShouldCallPrestub()) { LOG((LF_ENC, LL_INFO100, "EACM::ResumeInUpdatedFunction %p already JITed\n", pMD)); } diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index d6cc958f06341e..8d6b8abed82e98 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -679,9 +679,7 @@ static void CallPreStub(MethodDesc *pMD) STATIC_STANDARD_VM_CONTRACT; _ASSERTE(pMD != NULL); - if (!pMD->IsPointingToPrestub() && - pMD->GetTemporaryEntryPoint() && // The prestub may not yet be ready to be used, so force temporary entry point creation, and check again. - !pMD->IsPointingToPrestub()) + if (!pMD->ShouldCallPrestub()) return; struct Param @@ -709,8 +707,6 @@ static void CallPreStub(MethodDesc *pMD) PAL_ENDTRY } -UMEntryThunkData * GetMostRecentUMEntryThunkData(); - void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFrame *pFrame, InterpThreadContext *pThreadContext, ExceptionClauseArgs *pExceptionClauseArgs) { CONTRACTL @@ -794,14 +790,16 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr MemoryBarrier(); ip++; break; +#ifndef FEATURE_PORTABLE_ENTRYPOINTS case INTOP_STORESTUBCONTEXT: { - void *thunkData = GetMostRecentUMEntryThunkData(); + UMEntryThunkData* thunkData = GetMostRecentUMEntryThunkData(); assert(thunkData); LOCAL_VAR(ip[1], void*) = thunkData; ip += 2; break; } +#endif // !FEATURE_PORTABLE_ENTRYPOINTS case INTOP_LDC_I4: LOCAL_VAR(ip[1], int32_t) = ip[2]; ip += 3; @@ -2594,10 +2592,10 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr break; } } - + OBJECTREF targetMethodObj = (*delegateObj)->GetTarget(); LOCAL_VAR(callArgsOffset, OBJECTREF) = targetMethodObj; - + if ((targetMethod = NonVirtualEntry2MethodDesc(targetAddress)) != NULL) { // In this case targetMethod holds a pointer to the MethodDesc that will be called by using targetMethodObj as diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index 58b418fe5fb309..fef3e6877b7000 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -1035,6 +1035,20 @@ HCIMPL0(void, JIT_FailFast) } HCIMPLEND +// FailFast if a method marked UnmanagedCallersOnlyAttribute is +// invoked directly from managed code. UMThunkStub.asm check the +// mode and call this function to failfast. +void ReversePInvokeBadTransition() +{ + STATIC_CONTRACT_THROWS; + STATIC_CONTRACT_GC_TRIGGERS; + // Fail + EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE( + COR_E_EXECUTIONENGINE, + W("Invalid Program: attempted to call a UnmanagedCallersOnly method from managed code.") + ); +} + //======================================================================== // // DEBUGGER/PROFILER HELPERS @@ -2295,15 +2309,35 @@ Thread * JIT_InitPInvokeFrame(InlinedCallFrame *pFrame) EXTERN_C void JIT_PInvokeBegin(InlinedCallFrame* pFrame); EXTERN_C void JIT_PInvokeEnd(InlinedCallFrame* pFrame); -// Forward declaration -EXTERN_C void STDCALL ReversePInvokeBadTransition(); - #ifndef FEATURE_EH_FUNCLETS EXCEPTION_HANDLER_DECL(FastNExportExceptHandler); #endif +#ifdef DEBUGGING_SUPPORTED +static void DebuggerTraceCall(void* returnAddr, void* thunkDataMaybe) +{ + _ASSERTE(CORDebuggerTraceCall()); + _ASSERTE(returnAddr != NULL); + + const BYTE* addr; +#ifdef FEATURE_PORTABLE_ENTRYPOINTS + addr = (const BYTE*)returnAddr; + _ASSERTE(thunkDataMaybe == NULL); // Should not be used with portable entrypoints +#else // !FEATURE_PORTABLE_ENTRYPOINTS + addr = (thunkDataMaybe != NULL) ? (const BYTE*)((UMEntryThunkData*)thunkDataMaybe)->GetManagedTarget() : (const BYTE*)returnAddr; +#endif // FEATURE_PORTABLE_ENTRYPOINTS + + // If the debugger is attached, we use this opportunity to see if + // we're disabling preemptive GC on the way into the runtime from + // unmanaged code. We end up here because + // Increment/DecrementTraceCallCount() will bump + // g_TrapReturningThreads for us. + g_pDebugInterface->TraceCall(addr); +} +#endif // DEBUGGING_SUPPORTED + // This is a slower version of the reverse PInvoke enter function. -NOINLINE static void JIT_ReversePInvokeEnterRare(ReversePInvokeFrame* frame, void* returnAddr, UMEntryThunkData* pUMEntryThunkData = NULL) +NOINLINE static void JIT_ReversePInvokeEnterRare(ReversePInvokeFrame* frame, void* returnAddr, void* thunkDataMaybe = NULL) { _ASSERTE(frame != NULL); @@ -2326,27 +2360,17 @@ NOINLINE static void JIT_ReversePInvokeEnterRare(ReversePInvokeFrame* frame, voi thread->DisablePreemptiveGC(); #ifdef DEBUGGING_SUPPORTED - // If the debugger is attached, we use this opportunity to see if - // we're disabling preemptive GC on the way into the runtime from - // unmanaged code. We end up here because - // Increment/DecrementTraceCallCount() will bump - // g_TrapReturningThreads for us. if (CORDebuggerTraceCall()) - g_pDebugInterface->TraceCall(pUMEntryThunkData ? (const BYTE*)pUMEntryThunkData->GetManagedTarget() : (const BYTE*)returnAddr); + DebuggerTraceCall(returnAddr, thunkDataMaybe); #endif // DEBUGGING_SUPPORTED } -NOINLINE static void JIT_ReversePInvokeEnterRare2(ReversePInvokeFrame* frame, void* returnAddr, UMEntryThunkData* pUMEntryThunkData = NULL) +NOINLINE static void JIT_ReversePInvokeEnterRare2(ReversePInvokeFrame* frame, void* returnAddr, void* thunkDataMaybe = NULL) { frame->currentThread->RareDisablePreemptiveGC(); #ifdef DEBUGGING_SUPPORTED - // If the debugger is attached, we use this opportunity to see if - // we're disabling preemptive GC on the way into the runtime from - // unmanaged code. We end up here because - // Increment/DecrementTraceCallCount() will bump - // g_TrapReturningThreads for us. if (CORDebuggerTraceCall()) - g_pDebugInterface->TraceCall(pUMEntryThunkData ? (const BYTE*)pUMEntryThunkData->GetManagedTarget() : (const BYTE*)returnAddr); + DebuggerTraceCall(returnAddr, thunkDataMaybe); #endif // DEBUGGING_SUPPORTED } @@ -2355,15 +2379,14 @@ NOINLINE static void JIT_ReversePInvokeEnterRare2(ReversePInvokeFrame* frame, vo // We may not have a managed thread set up in JIT_ReversePInvokeEnter, and the GC mode may be incorrect. // On x86, SEH handlers are set up and torn down explicitly, so we avoid using dynamic contracts. // This method uses the correct calling convention and argument layout manually, without relying on standard macros or contracts. -HCIMPL3_RAW(void, JIT_ReversePInvokeEnterTrackTransitions, ReversePInvokeFrame* frame, MethodDesc* pMD, UMEntryThunkData* pUMEntryThunkData) +HCIMPL3_RAW(void, JIT_ReversePInvokeEnterTrackTransitions, ReversePInvokeFrame* frame, MethodDesc* pMD, void* thunkDataMaybe) { _ASSERTE(frame != NULL && pMD != NULL); - _ASSERTE(!pMD->IsILStub() || pUMEntryThunkData != NULL); + _ASSERTE(!pMD->IsILStub() || thunkDataMaybe != NULL); - if (pUMEntryThunkData != NULL) - { - pMD = pUMEntryThunkData->GetMethod(); - } +#ifndef FEATURE_PORTABLE_ENTRYPOINTS + pMD = (thunkDataMaybe != NULL) ? ((UMEntryThunkData*)thunkDataMaybe)->GetMethod() : pMD; +#endif // !FEATURE_PORTABLE_ENTRYPOINTS frame->pMD = pMD; Thread* thread = GetThreadNULLOk(); @@ -2388,14 +2411,14 @@ HCIMPL3_RAW(void, JIT_ReversePInvokeEnterTrackTransitions, ReversePInvokeFrame* { // If we're in an IL stub, we want to trace the address of the target method, // not the next instruction in the stub. - JIT_ReversePInvokeEnterRare2(frame, _ReturnAddress(), pUMEntryThunkData); + JIT_ReversePInvokeEnterRare2(frame, _ReturnAddress(), thunkDataMaybe); } } else { // If we're in an IL stub, we want to trace the address of the target method, // not the next instruction in the stub. - JIT_ReversePInvokeEnterRare(frame, _ReturnAddress(), pUMEntryThunkData); + JIT_ReversePInvokeEnterRare(frame, _ReturnAddress(), thunkDataMaybe); } #if defined(TARGET_X86) && defined(TARGET_WINDOWS) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index f0e6abfd342a03..4dca52fe12eca4 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9112,6 +9112,11 @@ void CEEInfo::getFunctionEntryPoint(CORINFO_METHOD_HANDLE ftnHnd, JIT_TO_EE_TRANSITION(); +#ifdef FEATURE_PORTABLE_ENTRYPOINTS + PORTABILITY_ASSERT("NYI: getFunctionEntryPoint for FEATURE_PORTABLE_ENTRYPOINTS"); + +#else // !FEATURE_PORTABLE_ENTRYPOINTS + MethodDesc * ftn = GetMethod(ftnHnd); #if defined(FEATURE_GDBJIT) MethodDesc * orig_ftn = ftn; @@ -9155,6 +9160,7 @@ void CEEInfo::getFunctionEntryPoint(CORINFO_METHOD_HANDLE ftnHnd, CalledMethod * pCM = new CalledMethod(orig_ftn, ret, m_pCalledMethods); m_pCalledMethods = pCM; #endif +#endif // FEATURE_PORTABLE_ENTRYPOINTS EE_TO_JIT_TRANSITION(); diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 460c7e7f3fdd5a..c5011bcee2c46a 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -176,11 +176,13 @@ EXTERN_C FCDECL2(void, JITutil_MonReliableContention, AwareLock* awarelock, BYTE EXTERN_C FCDECL1(void*, JIT_GetNonGCStaticBase_Helper, MethodTable *pMT); EXTERN_C FCDECL1(void*, JIT_GetGCStaticBase_Helper, MethodTable *pMT); -EXTERN_C void DoJITFailFast (); +EXTERN_C void DoJITFailFast(); EXTERN_C FCDECL0(void, JIT_FailFast); FCDECL0(int, JIT_GetCurrentManagedThreadId); +EXTERN_C void ReversePInvokeBadTransition(); + #if !defined(FEATURE_USE_ASM_GC_WRITE_BARRIERS) && defined(FEATURE_COUNT_GC_WRITE_BARRIERS) // Extra argument for the classification of the checked barriers. extern "C" FCDECL3(VOID, JIT_CheckedWriteBarrier, Object **dst, Object *ref, CheckedWriteBarrierKinds kind); diff --git a/src/coreclr/vm/loaderallocator.cpp b/src/coreclr/vm/loaderallocator.cpp index f33bd9de06e62e..14fbb00a8d744f 100644 --- a/src/coreclr/vm/loaderallocator.cpp +++ b/src/coreclr/vm/loaderallocator.cpp @@ -83,15 +83,17 @@ LoaderAllocator::LoaderAllocator(bool collectible) : #ifdef FEATURE_COMINTEROP m_pComCallWrapperCache = NULL; -#endif +#endif // FEATURE_COMINTEROP +#ifndef FEATURE_PORTABLE_ENTRYPOINTS m_pUMEntryThunkCache = NULL; +#endif // !FEATURE_PORTABLE_ENTRYPOINTS m_nLoaderAllocator = InterlockedIncrement64((LONGLONG *)&LoaderAllocator::cLoaderAllocatorsCreated); #ifdef FEATURE_PGO m_pgoManager = NULL; -#endif +#endif // FEATURE_PGO } LoaderAllocator::~LoaderAllocator() @@ -1384,14 +1386,16 @@ void LoaderAllocator::Terminate() m_fGCPressure = false; } +#ifndef FEATURE_PORTABLE_ENTRYPOINTS delete m_pUMEntryThunkCache; m_pUMEntryThunkCache = NULL; +#endif // !FEATURE_PORTABLE_ENTRYPOINTS m_crstLoaderAllocator.Destroy(); #ifdef FEATURE_COMINTEROP m_ComCallWrapperCrst.Destroy(); m_InteropDataCrst.Destroy(); -#endif +#endif // FEATURE_COMINTEROP m_LoaderAllocatorReferences.RemoveAll(); #ifdef FEATURE_TIERED_COMPILATION @@ -1400,7 +1404,7 @@ void LoaderAllocator::Terminate() delete m_callCountingManager; m_callCountingManager = NULL; } -#endif +#endif // FEATURE_TIERED_COMPILATION #ifdef FEATURE_ON_STACK_REPLACEMENT if (m_onStackReplacementManager != NULL) @@ -1408,7 +1412,7 @@ void LoaderAllocator::Terminate() delete m_onStackReplacementManager; m_onStackReplacementManager = NULL; } -#endif +#endif // FEATURE_ON_STACK_REPLACEMENT // In collectible types we merge the low frequency and high frequency heaps // So don't destroy them twice. @@ -2153,6 +2157,7 @@ ComCallWrapperCache * LoaderAllocator::GetComCallWrapperCache() } #endif // FEATURE_COMINTEROP +#ifndef FEATURE_PORTABLE_ENTRYPOINTS // U->M thunks created in this LoaderAllocator and not associated with a delegate. UMEntryThunkCache *LoaderAllocator::GetUMEntryThunkCache() { @@ -2178,6 +2183,7 @@ UMEntryThunkCache *LoaderAllocator::GetUMEntryThunkCache() _ASSERTE(m_pUMEntryThunkCache); return m_pUMEntryThunkCache; } +#endif // !FEATURE_PORTABLE_ENTRYPOINTS /* static */ void LoaderAllocator::RemoveMemoryToLoaderAllocatorAssociation(LoaderAllocator* pLoaderAllocator) diff --git a/src/coreclr/vm/loaderallocator.hpp b/src/coreclr/vm/loaderallocator.hpp index eaf327588f9a99..41ca855f87e186 100644 --- a/src/coreclr/vm/loaderallocator.hpp +++ b/src/coreclr/vm/loaderallocator.hpp @@ -364,9 +364,11 @@ class LoaderAllocator BYTE * m_pVSDHeapInitialAlloc; BYTE * m_pCodeHeapInitialAlloc; +#ifndef FEATURE_PORTABLE_ENTRYPOINTS // U->M thunks that are not associated with a delegate. // The cache is keyed by MethodDesc pointers. UMEntryThunkCache * m_pUMEntryThunkCache; +#endif // !FEATURE_PORTABLE_ENTRYPOINTS // IL stub cache with fabricated MethodTable parented by a random module in this LoaderAllocator. ILStubCache m_ILStubCache; diff --git a/src/coreclr/vm/marshalnative.cpp b/src/coreclr/vm/marshalnative.cpp index f0e5d17c81963e..bd290844478af4 100644 --- a/src/coreclr/vm/marshalnative.cpp +++ b/src/coreclr/vm/marshalnative.cpp @@ -59,7 +59,7 @@ extern "C" VOID QCALLTYPE MarshalNative_Prelink(MethodDesc * pMD) // If the code is already ready, we are done. Else, we need to execute the prestub // This is a perf thing since it's always safe to execute the prestub twice. - if (!pMD->IsPointingToPrestub()) + if (!pMD->ShouldCallPrestub()) return; // Silently ignore if not PInvoke and not runtime generated. diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index 6eb4204c1630f0..9a4ed1c3837b31 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -239,6 +239,7 @@ HRESULT MethodDesc::EnsureCodeDataExists(AllocMemTracker *pamTracker) return S_OK; } +#ifdef FEATURE_CODE_VERSIONING HRESULT MethodDesc::SetMethodDescVersionState(PTR_MethodDescVersioningState state) { WRAPPER_NO_CONTRACT; @@ -252,6 +253,7 @@ HRESULT MethodDesc::SetMethodDescVersionState(PTR_MethodDescVersioningState stat return S_OK; } +#endif // FEATURE_CODE_VERSIONING #ifdef FEATURE_INTERPRETER // Set the call stub for the interpreter to JIT/AOT calls @@ -279,6 +281,7 @@ CallStubHeader *MethodDesc::GetCallStub() #endif //!DACCESS_COMPILE +#ifdef FEATURE_CODE_VERSIONING PTR_MethodDescVersioningState MethodDesc::GetMethodDescVersionState() { WRAPPER_NO_CONTRACT; @@ -287,6 +290,7 @@ PTR_MethodDescVersioningState MethodDesc::GetMethodDescVersionState() return NULL; return VolatileLoadWithoutBarrier(&codeData->VersioningState); } +#endif // FEATURE_CODE_VERSIONING //******************************************************************************* LPCUTF8 MethodDesc::GetNameThrowing() @@ -1057,7 +1061,7 @@ PCODE MethodDesc::GetNativeCodeAnyVersion() { return pDefaultCode; } - +#ifdef FEATURE_CODE_VERSIONING else { CodeVersionManager *pCodeVersionManager = GetCodeVersionManager(); @@ -1075,8 +1079,10 @@ PCODE MethodDesc::GetNativeCodeAnyVersion() } } } - return (PCODE)NULL; } +#endif // FEATURE_CODE_VERSIONING + + return (PCODE)NULL; } //******************************************************************************* @@ -2366,7 +2372,7 @@ MethodReturnKind ClassifyMethodReturnKind(SigPointer sig, Module* pModule, ULONG } //******************************************************************************* -BOOL MethodDesc::IsPointingToPrestub() +BOOL MethodDesc::ShouldCallPrestub() { CONTRACTL { @@ -2376,20 +2382,30 @@ BOOL MethodDesc::IsPointingToPrestub() } CONTRACTL_END; + PCODE methodEntryPoint; if (!HasStableEntryPoint()) { if (IsVersionableWithVtableSlotBackpatch()) { - PCODE methodEntrypoint = GetMethodEntryPointIfExists(); - return methodEntrypoint == GetTemporaryEntryPointIfExists() && methodEntrypoint != (PCODE)NULL; + methodEntryPoint = GetMethodEntryPointIfExists(); + return methodEntryPoint == (PCODE)NULL + || methodEntryPoint == GetTemporaryEntryPointIfExists(); } return TRUE; } +#ifdef FEATURE_PORTABLE_ENTRYPOINTS + methodEntryPoint = GetStableEntryPoint(); + return methodEntryPoint == (PCODE)NULL + || (!PortableEntryPoint::HasInterpreterData(methodEntryPoint) + && !PortableEntryPoint::HasNativeEntryPoint(methodEntryPoint)); + +#else // !FEATURE_PORTABLE_ENTRYPOINTS if (!HasPrecode()) return FALSE; return GetPrecode()->IsPointingToPrestub(); +#endif // FEATURE_PORTABLE_ENTRYPOINTS } //******************************************************************************* @@ -2408,16 +2424,23 @@ void MethodDesc::Reset() // Reset any flags relevant to the old code ClearFlagsOnUpdate(); +#ifndef FEATURE_PORTABLE_ENTRYPOINTS if (HasPrecode()) { GetPrecode()->Reset(); } else +#endif // !FEATURE_PORTABLE_ENTRYPOINTS { // We should go here only for the rental methods _ASSERTE(GetLoaderModule()->IsReflectionEmit()); - InterlockedUpdateFlags3(enum_flag3_HasStableEntryPoint | enum_flag3_HasPrecode, FALSE); + WORD flagsToSet = enum_flag3_HasStableEntryPoint; +#ifndef FEATURE_PORTABLE_ENTRYPOINTS + flagsToSet |= enum_flag3_HasPrecode; +#endif // !FEATURE_PORTABLE_ENTRYPOINTS + + InterlockedUpdateFlags3(flagsToSet, FALSE); *GetAddrOfSlot() = GetTemporaryEntryPoint(); } @@ -2715,7 +2738,7 @@ void MethodDesc::SetTemporaryEntryPoint(AllocMemTracker *pamTracker) { // The rest of the system assumes that certain methods always have stable entrypoints. // Mark the precode as such - MarkPrecodeAsStableEntrypoint(); + MarkStableEntryPoint(); } } @@ -2861,8 +2884,7 @@ void MethodDescChunk::DetermineAndSetIsEligibleForTieredCompilation() } } - -//******************************************************************************* +#ifndef FEATURE_PORTABLE_ENTRYPOINTS Precode* MethodDesc::GetOrCreatePrecode() { WRAPPER_NO_CONTRACT; @@ -2883,11 +2905,9 @@ Precode* MethodDesc::GetOrCreatePrecode() PTR_PCODE pSlot = GetAddrOfSlot(); _ASSERTE(*pSlot != (PCODE)NULL); _ASSERTE(*pSlot == tempEntry); -#ifndef FEATURE_PORTABLE_ENTRYPOINTS PrecodeType requiredType = GetPrecodeType(); PrecodeType availableType = Precode::GetPrecodeFromEntryPoint(tempEntry)->GetType(); _ASSERTE(requiredType == availableType); -#endif // !FEATURE_PORTABLE_ENTRYPOINTS #endif // _DEBUG // Set the flags atomically @@ -2895,8 +2915,9 @@ Precode* MethodDesc::GetOrCreatePrecode() return Precode::GetPrecodeFromEntryPoint(tempEntry); } +#endif // !FEATURE_PORTABLE_ENTRYPOINTS -void MethodDesc::MarkPrecodeAsStableEntrypoint() +void MethodDesc::MarkStableEntryPoint() { #if _DEBUG PCODE tempEntry = GetTemporaryEntryPointIfExists(); @@ -2907,12 +2928,17 @@ void MethodDesc::MarkPrecodeAsStableEntrypoint() PrecodeType requiredType = GetPrecodeType(); PrecodeType availableType = Precode::GetPrecodeFromEntryPoint(tempEntry)->GetType(); _ASSERTE(requiredType == availableType); + _ASSERTE(!HasPrecode()); #endif // FEATURE_PORTABLE_ENTRYPOINTS #endif // _DEBUG - _ASSERTE(!HasPrecode()); _ASSERTE(RequiresStableEntryPoint()); - InterlockedUpdateFlags3(enum_flag3_HasStableEntryPoint | enum_flag3_HasPrecode, TRUE); + WORD flagsToSet = enum_flag3_HasStableEntryPoint; +#ifndef FEATURE_PORTABLE_ENTRYPOINTS + flagsToSet |= enum_flag3_HasPrecode; +#endif // !FEATURE_PORTABLE_ENTRYPOINTS + + InterlockedUpdateFlags3(flagsToSet, TRUE); } bool MethodDesc::DetermineIsEligibleForTieredCompilationInvariantForAllMethodsInChunk() @@ -3125,6 +3151,7 @@ FORCEINLINE bool MethodDesc::TryBackpatchEntryPointSlots( return true; } +#ifdef FEATURE_CODE_VERSIONING void MethodDesc::TrySetInitialCodeEntryPointForVersionableMethod( PCODE entryPoint, bool mayHaveEntryPointSlotsToBackpatch) @@ -3144,13 +3171,17 @@ void MethodDesc::TrySetInitialCodeEntryPointForVersionableMethod( GetOrCreatePrecode()->SetTargetInterlocked(entryPoint, TRUE /* fOnlyRedirectFromPrestub */); } } +#endif // FEATURE_CODE_VERSIONING void MethodDesc::SetCodeEntryPoint(PCODE entryPoint) { WRAPPER_NO_CONTRACT; _ASSERTE(entryPoint != (PCODE)NULL); -#ifndef FEATURE_PORTABLE_ENTRYPOINTS +#ifdef FEATURE_PORTABLE_ENTRYPOINTS + SetStableEntryPointInterlocked(entryPoint); + +#else // !FEATURE_PORTABLE_ENTRYPOINTS if (MayHaveEntryPointSlotsToBackpatch()) { BackpatchEntryPointSlots(entryPoint); @@ -3176,15 +3207,16 @@ void MethodDesc::SetCodeEntryPoint(PCODE entryPoint) GetOrCreatePrecode()->SetTargetInterlocked(entryPoint); return; } -#endif // !FEATURE_PORTABLE_ENTRYPOINTS if (!HasStableEntryPoint()) { SetStableEntryPointInterlocked(entryPoint); return; } +#endif // FEATURE_PORTABLE_ENTRYPOINTS } +#ifdef FEATURE_TIERED_COMPILATION void MethodDesc::ResetCodeEntryPoint() { WRAPPER_NO_CONTRACT; @@ -3202,6 +3234,7 @@ void MethodDesc::ResetCodeEntryPoint() GetPrecode()->ResetTargetInterlocked(); } } +#endif // FEATURE_TIERED_COMPILATION void MethodDesc::ResetCodeEntryPointForEnC() { @@ -3221,12 +3254,15 @@ void MethodDesc::ResetCodeEntryPointForEnC() return; } - LOG((LF_ENC, LL_INFO100000, "MD::RCEPFENC: this:%p - %s::%s - HasPrecode():%s, HasNativeCodeSlot():%s\n", - this, m_pszDebugClassName, m_pszDebugMethodName, (HasPrecode() ? "true" : "false"), (HasNativeCodeSlot() ? "true" : "false"))); + LOG((LF_ENC, LL_INFO100000, "MD::RCEPFENC: this:%p - %s::%s\n", this, m_pszDebugClassName, m_pszDebugMethodName)); +#ifndef FEATURE_PORTABLE_ENTRYPOINTS + LOG((LF_ENC, LL_INFO100000, "MD::RCEPFENC: HasPrecode():%s, HasNativeCodeSlot():%s\n", + (HasPrecode() ? "true" : "false"), (HasNativeCodeSlot() ? "true" : "false"))); if (HasPrecode()) { GetPrecode()->ResetTargetInterlocked(); } +#endif // !FEATURE_PORTABLE_ENTRYPOINTS if (HasNativeCodeSlot()) { diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index f56eddccf9012d..c4566bd5e92422 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -234,7 +234,9 @@ enum MethodDescFlags // Used for storing additional items related to native code struct MethodDescCodeData final { +#ifdef FEATURE_CODE_VERSIONING PTR_MethodDescVersioningState VersioningState; +#endif // FEATURE_CODE_VERSIONING PCODE TemporaryEntryPoint; #ifdef FEATURE_INTERPRETER CallStubHeader *CallStub; @@ -376,9 +378,14 @@ class MethodDesc { LIMITED_METHOD_DAC_CONTRACT; +#ifdef FEATURE_PORTABLE_ENTRYPOINTS + return FALSE; +#else // !FEATURE_PORTABLE_ENTRYPOINTS return (m_wFlags3AndTokenRemainder & enum_flag3_HasPrecode) != 0; +#endif // FEATURE_PORTABLE_ENTRYPOINTS } +#ifndef FEATURE_PORTABLE_ENTRYPOINTS inline Precode* GetPrecode() { LIMITED_METHOD_DAC_CONTRACT; @@ -388,6 +395,7 @@ class MethodDesc _ASSERTE(pPrecode != NULL); return pPrecode; } +#endif // !FEATURE_PORTABLE_ENTRYPOINTS inline bool MayHavePrecode() { @@ -412,8 +420,10 @@ class MethodDesc return result; } +#ifndef FEATURE_PORTABLE_ENTRYPOINTS Precode* GetOrCreatePrecode(); - void MarkPrecodeAsStableEntrypoint(); +#endif // !FEATURE_PORTABLE_ENTRYPOINTS + void MarkStableEntryPoint(); static MethodDesc * GetMethodDescFromPrecode(PCODE addr, BOOL fSpeculative = FALSE); @@ -1164,7 +1174,7 @@ class MethodDesc // the table. void SetChunkIndex(MethodDescChunk *pChunk); - BOOL IsPointingToPrestub(); + BOOL ShouldCallPrestub(); public: @@ -1412,9 +1422,13 @@ class MethodDesc bool TryBackpatchEntryPointSlots(PCODE entryPoint, bool isPrestubEntryPoint, bool onlyFromPrestubEntryPoint); public: +#ifdef FEATURE_CODE_VERSIONING void TrySetInitialCodeEntryPointForVersionableMethod(PCODE entryPoint, bool mayHaveEntryPointSlotsToBackpatch); +#endif // FEATURE_CODE_VERSIONING void SetCodeEntryPoint(PCODE entryPoint); +#ifdef FEATURE_TIERED_COMPILATION void ResetCodeEntryPoint(); +#endif // FEATURE_TIERED_COMPILATION void ResetCodeEntryPointForEnC(); @@ -1443,32 +1457,31 @@ class MethodDesc return !IsVersionable() && !InEnCEnabledModule(); } - //Is this method currently pointing to native code that will never change? - BOOL IsPointingToStableNativeCode() +#ifndef FEATURE_PORTABLE_ENTRYPOINTS + BOOL IsPointingToNativeCode() { LIMITED_METHOD_DAC_CONTRACT; - if (!IsNativeCodeStableAfterInit()) + if (!HasStableEntryPoint()) return FALSE; - return IsPointingToNativeCode(); + if (!HasPrecode()) + return TRUE; + + return GetPrecode()->IsPointingToNativeCode(GetNativeCode()); } - // Note: We are skipping the prestub based on addition information from the JIT. - // (e.g. that the call is on same this ptr or that the this ptr is not null). - // Thus we can end up with a running NGENed method for which IsPointingToNativeCode is false! - BOOL IsPointingToNativeCode() + //Is this method currently pointing to native code that will never change? + BOOL IsPointingToStableNativeCode() { LIMITED_METHOD_DAC_CONTRACT; - if (!HasStableEntryPoint()) + if (!IsNativeCodeStableAfterInit()) return FALSE; - if (!HasPrecode()) - return TRUE; - - return GetPrecode()->IsPointingToNativeCode(GetNativeCode()); + return IsPointingToNativeCode(); } +#endif // !FEATURE_PORTABLE_ENTRYPOINTS // Be careful about races with profiler when using this method. The profiler can // replace preimplemented code of the method with jitted code. @@ -1746,7 +1759,7 @@ class MethodDesc // Return value: // stable entry point (code:MethodDesc::GetStableEntryPoint()) // - PCODE DoBackpatch(MethodTable * pMT, MethodTable * pDispatchingMT, BOOL fFullBackPatch); + PCODE DoBackpatch(MethodTable * pMT, MethodTable * pDispatchingMT, bool fFullBackPatch); PCODE DoPrestub(MethodTable *pDispatchingMT, CallerGCMode callerGCMode = CallerGCMode::Unknown); @@ -1775,15 +1788,17 @@ class MethodDesc // The actual data stored in a MethodDesc follows. protected: - enum { + enum + { // There are flags available for use here (currently 4 flags bits are available); however, new bits are hard to come by, so any new flags bits should // have a fairly strong justification for existence. enum_flag3_TokenRemainderMask = 0x0FFF, // This must equal METHOD_TOKEN_REMAINDER_MASK calculated higher in this file. // for this method. - // enum_flag3_HasPrecode implies that enum_flag3_HasStableEntryPoint is set. + // enum_flag3_HasPrecode implies that enum_flag3_HasStableEntryPoint is set in non-portable entrypoint scenarios. enum_flag3_HasStableEntryPoint = 0x1000, // The method entrypoint is stable (either precode or actual code) +#ifndef FEATURE_PORTABLE_ENTRYPOINTS enum_flag3_HasPrecode = 0x2000, // Precode has been allocated for this method - +#endif // !FEATURE_PORTABLE_ENTRYPOINTS enum_flag3_IsUnboxingStub = 0x4000, enum_flag3_IsEligibleForTieredCompilation = 0x8000, }; @@ -1866,16 +1881,19 @@ class MethodDesc // pamTracker must be NULL for a MethodDesc which cannot be freed by an external AllocMemTracker // OR must be set to point to the same AllocMemTracker that controls allocation of the MethodDesc HRESULT EnsureCodeDataExists(AllocMemTracker *pamTracker); +#endif //!DACCESS_COMPILE - HRESULT SetMethodDescVersionState(PTR_MethodDescVersioningState state); -#ifdef FEATURE_INTERPRETER +#if defined(FEATURE_INTERPRETER) && !defined(DACCESS_COMPILE) bool SetCallStub(CallStubHeader *pHeader); CallStubHeader *GetCallStub(); -#endif // FEATURE_INTERPRETER - -#endif //!DACCESS_COMPILE +#endif // FEATURE_INTERPRETER && !DACCESS_COMPILE +#ifdef FEATURE_CODE_VERSIONING +#ifndef DACCESS_COMPILE + HRESULT SetMethodDescVersionState(PTR_MethodDescVersioningState state); +#endif // !DACCESS_COMPILE PTR_MethodDescVersioningState GetMethodDescVersionState(); +#endif // FEATURE_CODE_VERSIONING public: inline DWORD GetClassification() const @@ -2867,12 +2885,12 @@ class DynamicMethodDesc : public StoredSigMethodDesc m_dwExtendedFlags = (m_dwExtendedFlags & ~StackArgSizeMask) | ((DWORD)cbArgSize << 16); } - bool IsReverseStub() const + bool IsReversePInvokeStub() const { LIMITED_METHOD_DAC_CONTRACT; _ASSERTE(IsILStub()); ILStubType type = GetILStubType(); - return type == StubCOMToCLRInterop || type == StubReversePInvoke; + return type == StubReversePInvoke; } bool IsStepThroughStub() const diff --git a/src/coreclr/vm/methodtablebuilder.cpp b/src/coreclr/vm/methodtablebuilder.cpp index 7070a5a3054a2c..7726e70541c98e 100644 --- a/src/coreclr/vm/methodtablebuilder.cpp +++ b/src/coreclr/vm/methodtablebuilder.cpp @@ -1365,7 +1365,6 @@ MethodTableBuilder::BuildMethodTableThrowing( if (g_pConfig->ShouldBreakOnClassBuild(className)) { - CONSISTENCY_CHECK_MSGF(false, ("BreakOnClassBuild: typename '%s' ", className)); GetHalfBakedClass()->m_fDebuggingClass = TRUE; } @@ -11216,7 +11215,7 @@ MethodTableBuilder::SetupMethodTable2( { // The rest of the system assumes that certain methods always have stable entrypoints. // Create them now. - pMD->MarkPrecodeAsStableEntrypoint(); + pMD->MarkStableEntryPoint(); } } } diff --git a/src/coreclr/vm/precode.cpp b/src/coreclr/vm/precode.cpp index 74f8082c1246a2..c063464443450b 100644 --- a/src/coreclr/vm/precode.cpp +++ b/src/coreclr/vm/precode.cpp @@ -215,6 +215,12 @@ BOOL Precode::IsPointingToPrestub(PCODE target) return FALSE; } +BOOL Precode::IsPointingToPrestub() +{ + WRAPPER_NO_CONTRACT; + return IsPointingToPrestub(GetTarget()); +} + #ifndef DACCESS_COMPILE void FlushCacheForDynamicMappedStub(void* code, SIZE_T size) @@ -380,12 +386,11 @@ BOOL Precode::SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub) WRAPPER_NO_CONTRACT; _ASSERTE(!IsPointingToPrestub(target)); - PCODE expected = GetTarget(); BOOL ret = FALSE; - - if (fOnlyRedirectFromPrestub && !IsPointingToPrestub(expected)) + if (fOnlyRedirectFromPrestub && !IsPointingToPrestub()) return FALSE; + PCODE expected = GetTarget(); PrecodeType precodeType = GetType(); switch (precodeType) { diff --git a/src/coreclr/vm/precode.h b/src/coreclr/vm/precode.h index 75ba4094bd3570..b4a50b56afc023 100644 --- a/src/coreclr/vm/precode.h +++ b/src/coreclr/vm/precode.h @@ -633,6 +633,8 @@ class Precode { #endif } + BOOL IsPointingToPrestub(PCODE target); + public: PrecodeType GetType() { @@ -684,7 +686,7 @@ class Precode { // Note: This is immediate target of the precode. It does not follow jump stub if there is one. PCODE GetTarget(); - BOOL IsPointingTo(PCODE target, PCODE addr) + static BOOL IsPointingTo(PCODE target, PCODE addr) { WRAPPER_NO_CONTRACT; SUPPORTS_DAC; @@ -712,13 +714,7 @@ class Precode { return IsPointingTo(GetTarget(), pNativeCode); } - BOOL IsPointingToPrestub(PCODE target); - - BOOL IsPointingToPrestub() - { - WRAPPER_NO_CONTRACT; - return IsPointingToPrestub(GetTarget()); - } + BOOL IsPointingToPrestub(); PCODE GetEntryPoint() { diff --git a/src/coreclr/vm/precode_portable.cpp b/src/coreclr/vm/precode_portable.cpp index b5ef68ecb105fe..5b2b96c83271d4 100644 --- a/src/coreclr/vm/precode_portable.cpp +++ b/src/coreclr/vm/precode_portable.cpp @@ -20,6 +20,13 @@ bool PortableEntryPoint::HasNativeEntryPoint(PCODE addr) return portableEntryPoint->HasNativeCode(); } +bool PortableEntryPoint::HasInterpreterData(PCODE addr) +{ + LIMITED_METHOD_CONTRACT; + PortableEntryPoint* portableEntryPoint = ToPortableEntryPoint(addr); + return portableEntryPoint->HasInterpreterCode(); +} + void* PortableEntryPoint::GetActualCode(PCODE addr) { STANDARD_VM_CONTRACT; @@ -109,53 +116,6 @@ void PortableEntryPoint::Init(void* nativeEntryPoint) InterleavedLoaderHeapConfig s_stubPrecodeHeapConfig; -void StubPrecode::Init(StubPrecode* pPrecodeRX, TADDR secretParam, LoaderAllocator *pLoaderAllocator, TADDR type, TADDR target) -{ - LIMITED_METHOD_CONTRACT; - _ASSERTE(!"StubPrecode::Init is not supported with Portable EntryPoints"); -} - -BYTE StubPrecode::GetType() -{ - LIMITED_METHOD_CONTRACT; - _ASSERTE(!"StubPrecode::GetType is not supported with Portable EntryPoints"); - return 0; -} - -void StubPrecode::SetTargetUnconditional(TADDR target) -{ - LIMITED_METHOD_CONTRACT; - _ASSERTE(!"StubPrecode::SetTargetUnconditional is not supported with Portable EntryPoints"); -} - -TADDR StubPrecode::GetSecretParam() const -{ - LIMITED_METHOD_CONTRACT; - _ASSERTE(!"StubPrecode::GetSecretParam is not supported with Portable EntryPoints"); - return (TADDR)NULL; -} - -MethodDesc* StubPrecode::GetMethodDesc() -{ - LIMITED_METHOD_CONTRACT; - _ASSERTE(!"StubPrecode::GetMethodDesc is not supported with Portable EntryPoints"); - return NULL; -} - -PCODE* FixupPrecode::GetTargetSlot() -{ - LIMITED_METHOD_CONTRACT; - _ASSERTE(!"FixupPrecode::GetTargetSlot is not supported with Portable EntryPoints"); - return NULL; -} - -MethodDesc* FixupPrecode::GetMethodDesc() -{ - LIMITED_METHOD_CONTRACT; - _ASSERTE(!"FixupPrecode::GetMethodDesc is not supported with Portable EntryPoints"); - return NULL; -} - Precode* Precode::Allocate(PrecodeType t, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator, AllocMemTracker *pamTracker) { @@ -164,13 +124,6 @@ Precode* Precode::Allocate(PrecodeType t, MethodDesc* pMD, return NULL; } -Precode* Precode::GetPrecodeFromEntryPoint(PCODE addr, BOOL fSpeculative) -{ - LIMITED_METHOD_CONTRACT; - _ASSERTE(!"Precode::GetPrecodeFromEntryPoint is not supported with Portable EntryPoints"); - return NULL; -} - PrecodeType Precode::GetType() { LIMITED_METHOD_CONTRACT; @@ -178,20 +131,6 @@ PrecodeType Precode::GetType() return (PrecodeType)0; } -UMEntryThunk* Precode::AsUMEntryThunk() -{ - LIMITED_METHOD_CONTRACT; - _ASSERTE(!"Precode::AsUMEntryThunk is not supported with Portable EntryPoints"); - return NULL; -} - -StubPrecode* Precode::AsStubPrecode() -{ - LIMITED_METHOD_CONTRACT; - _ASSERTE(!"Precode::AsStubPrecode is not supported with Portable EntryPoints"); - return NULL; -} - MethodDesc* Precode::GetMethodDesc(BOOL fSpeculative) { LIMITED_METHOD_CONTRACT; @@ -206,26 +145,6 @@ PCODE Precode::GetEntryPoint() return (PCODE)NULL; } -BOOL Precode::IsPointingToNativeCode(PCODE pNativeCode) -{ - LIMITED_METHOD_CONTRACT; - _ASSERTE(!"Precode::IsPointingToNativeCode is not supported with Portable EntryPoints"); - return FALSE; -} - -void Precode::Reset() -{ - LIMITED_METHOD_CONTRACT; - _ASSERTE(!"Precode::Reset is not supported with Portable EntryPoints"); -} - -PCODE Precode::GetTarget() -{ - LIMITED_METHOD_CONTRACT; - _ASSERTE(!"Precode::GetTarget is not supported with Portable EntryPoints"); - return (PCODE)NULL; -} - void Precode::ResetTargetInterlocked() { LIMITED_METHOD_CONTRACT; @@ -239,20 +158,6 @@ BOOL Precode::SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub) return FALSE; } -BOOL Precode::IsPointingToPrestub() -{ - LIMITED_METHOD_CONTRACT; - _ASSERTE(!"Precode::IsPointingToPrestub is not supported with Portable EntryPoints"); - return FALSE; -} - -BOOL Precode::IsPointingToPrestub(PCODE target) -{ - LIMITED_METHOD_CONTRACT; - _ASSERTE(!"Precode::IsPointingToPrestub is not supported with Portable EntryPoints"); - return FALSE; -} - void FlushCacheForDynamicMappedStub(void* code, SIZE_T size) { LIMITED_METHOD_CONTRACT; diff --git a/src/coreclr/vm/precode_portable.hpp b/src/coreclr/vm/precode_portable.hpp index 57cf812e7186ae..cae51ba32225b1 100644 --- a/src/coreclr/vm/precode_portable.hpp +++ b/src/coreclr/vm/precode_portable.hpp @@ -13,6 +13,7 @@ class PortableEntryPoint final { public: // static static bool HasNativeEntryPoint(PCODE addr); + static bool HasInterpreterData(PCODE addr); static void* GetActualCode(PCODE addr); static void SetActualCode(PCODE addr, PCODE actualCode); @@ -78,68 +79,24 @@ enum PrecodeType class StubPrecode { -public: // static - static const BYTE Type = PRECODE_STUB; - -public: - void Init(StubPrecode* pPrecodeRX, TADDR secretParam, LoaderAllocator *pLoaderAllocator = NULL, TADDR type = StubPrecode::Type, TADDR target = 0); - - BYTE GetType(); - - void SetTargetUnconditional(TADDR target); - - TADDR GetSecretParam() const; - - MethodDesc* GetMethodDesc(); -}; - -typedef DPTR(StubPrecode) PTR_StubPrecode; - -class FixupPrecode final -{ -public: // static - static const int FixupCodeOffset = 0; - -public: - PCODE* GetTargetSlot(); - - MethodDesc* GetMethodDesc(); }; -class UMEntryThunk; - class Precode { public: // static static Precode* Allocate(PrecodeType t, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator, AllocMemTracker *pamTracker); - static Precode* GetPrecodeFromEntryPoint(PCODE addr, BOOL fSpeculative = FALSE); - public: PrecodeType GetType(); - UMEntryThunk* AsUMEntryThunk(); - - StubPrecode* AsStubPrecode(); - MethodDesc* GetMethodDesc(BOOL fSpeculative = FALSE); PCODE GetEntryPoint(); - BOOL IsPointingToNativeCode(PCODE pNativeCode); - - void Reset(); - - PCODE GetTarget(); - void ResetTargetInterlocked(); BOOL SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub = TRUE); - - BOOL IsPointingToPrestub(); - - BOOL IsPointingToPrestub(PCODE target); }; void FlushCacheForDynamicMappedStub(void* code, SIZE_T size); diff --git a/src/coreclr/vm/prestub.cpp b/src/coreclr/vm/prestub.cpp index dab4dc040f892b..fa63cb58f5da53 100644 --- a/src/coreclr/vm/prestub.cpp +++ b/src/coreclr/vm/prestub.cpp @@ -66,7 +66,7 @@ void MethodDesc::Init() //========================================================================== -PCODE MethodDesc::DoBackpatch(MethodTable * pMT, MethodTable *pDispatchingMT, BOOL fFullBackPatch) +PCODE MethodDesc::DoBackpatch(MethodTable * pMT, MethodTable *pDispatchingMT, bool fFullBackPatch) { CONTRACTL { @@ -138,8 +138,10 @@ PCODE MethodDesc::DoBackpatch(MethodTable * pMT, MethodTable *pDispatchingMT, BO } } +#ifndef FEATURE_PORTABLE_ENTRYPOINTS // Patch the fake entrypoint if necessary Precode::GetPrecodeFromEntryPoint(pExpected)->SetTargetInterlocked(pTarget); +#endif // !FEATURE_PORTABLE_ENTRYPOINTS } if (HasNonVtableSlot()) @@ -363,6 +365,8 @@ PCODE MethodDesc::PrepareILBasedCode(PrepareCodeConfig* pConfig) shouldTier = false; } #endif // FEATURE_TIERED_COMPILATION + +#ifdef FEATURE_CODE_VERSIONING NativeCodeVersion nativeCodeVersion = pConfig->GetCodeVersion(); if (shouldTier && !nativeCodeVersion.IsDefaultVersion()) { @@ -372,6 +376,7 @@ PCODE MethodDesc::PrepareILBasedCode(PrepareCodeConfig* pConfig) shouldTier = false; } } +#endif // FEATURE_CODE_VERSIONING if (pConfig->MayUsePrecompiledCode()) { @@ -743,6 +748,7 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J // JITCompilationStarted. It isn't clear if this is the ideal policy for these // notifications yet. NativeCodeVersion nativeCodeVersion = pConfig->GetCodeVersion(); +#ifdef FEATURE_CODE_VERSIONING ReJITID rejitId = nativeCodeVersion.GetILCodeVersionId(); if (rejitId != 0) { @@ -752,14 +758,14 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J TRUE); } else +#endif // FEATURE_CODE_VERSIONING + { // If profiling, need to give a chance for a tool to examine and modify // the IL before it gets to the JIT. This allows one to add probe calls for // things like code coverage, performance, or whatever. - { if (!IsNoMetadata()) { (&g_profControlBlock)->JITCompilationStarted((FunctionID)this, TRUE); - } else { @@ -770,10 +776,12 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J (&g_profControlBlock)->DynamicMethodJITCompilationStarted((FunctionID)this, TRUE, ilHeaderPointer, ilSize); } +#ifdef FEATURE_CODE_VERSIONING if (nativeCodeVersion.IsDefaultVersion()) { pConfig->SetProfilerMayHaveActivatedNonDefaultCodeVersion(); } +#endif // FEATURE_CODE_VERSIONING } END_PROFILER_CALLBACK(); } @@ -833,6 +841,7 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J // JITCompilationFinished. It isn't clear if this is the ideal policy for these // notifications yet. NativeCodeVersion nativeCodeVersion = pConfig->GetCodeVersion(); +#ifdef FEATURE_CODE_VERSIONING ReJITID rejitId = nativeCodeVersion.GetILCodeVersionId(); if (rejitId != 0) { @@ -843,10 +852,11 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J TRUE); } else +#endif // FEATURE_CODE_VERSIONING + { // Notify the profiler that JIT completed. // Must do this after the address has been set. // @ToDo: Why must we set the address before notifying the profiler ?? - { if (!IsNoMetadata()) { (&g_profControlBlock)-> @@ -859,10 +869,12 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J (&g_profControlBlock)->DynamicMethodJITCompilationFinished((FunctionID)this, pEntry->m_hrResultCode, TRUE); } +#ifdef FEATURE_CODE_VERSIONING if (nativeCodeVersion.IsDefaultVersion()) { pConfig->SetProfilerMayHaveActivatedNonDefaultCodeVersion(); } +#endif // FEATURE_CODE_VERSIONING } END_PROFILER_CALLBACK(); } @@ -2027,8 +2039,6 @@ static InterpThreadContext* GetInterpThreadContext() return threadContext; } -EXTERN_C void STDCALL ReversePInvokeBadTransition(); - extern "C" void* STDCALL ExecuteInterpretedMethod(TransitionBlock* pTransitionBlock, TADDR byteCodeAddr, void* retBuff) { // Argument registers are in the TransitionBlock @@ -2253,14 +2263,14 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT, CallerGCMode callerGCMo _ASSERTE(pCode != (PCODE)NULL); goto Return; } -#endif +#endif // FEATURE_CODE_VERSIONING - if (!IsPointingToPrestub()) + if (!ShouldCallPrestub()) { LOG((LF_CLASSLOADER, LL_INFO10000, " In PreStubWorker, method already jitted, backpatching call point\n")); - pCode = DoBackpatch(pMT, pDispatchingMT, TRUE); + pCode = DoBackpatch(pMT, pDispatchingMT, true /* doFullBackpatch */); goto Return; } @@ -2277,10 +2287,12 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT, CallerGCMode callerGCMo #endif // defined(FEATURE_SHARE_GENERIC_CODE) else if (IsIL() || IsNoMetadata()) { +#ifndef FEATURE_PORTABLE_ENTRYPOINTS if (!IsNativeCodeStableAfterInit()) { GetOrCreatePrecode(); } +#endif // !FEATURE_PORTABLE_ENTRYPOINTS pCode = PrepareInitialCode(callerGCMode); } // end else if (IsIL() || IsNoMetadata()) else if (IsPInvoke()) @@ -2331,7 +2343,7 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT, CallerGCMode callerGCMo MethodDesc* helperMD = PortableEntryPoint::GetMethodDesc(pCode); // If the FCall implementation is managed, then we need to potentially set up the interpreter code for it as well. // This is because the FCall may have been compiled to an IL stub that needs to be interpreted. - if (helperMD->IsPointingToPrestub()) + if (helperMD->ShouldCallPrestub()) (void)helperMD->DoPrestub(NULL /* MethodTable */, CallerGCMode::Coop); void* ilStubInterpData = helperMD->GetInterpreterCode(); SetInterpreterCode((InterpByteCodeStart*)ilStubInterpData); @@ -2392,7 +2404,7 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT, CallerGCMode callerGCMo _ASSERTE(ilStubInterpData != NULL); SetInterpreterCode((InterpByteCodeStart*)ilStubInterpData); SetCodeEntryPoint(pCode); -#else +#else // !FEATURE_PORTABLE_ENTRYPOINTS if (!GetOrCreatePrecode()->SetTargetInterlocked(pStub->GetEntryPoint())) { if (pStub->HasExternalEntryPoint()) @@ -2412,13 +2424,13 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT, CallerGCMode callerGCMo // need to free the Stub allocation now. pStub->DecRef(); } -#endif // !FEATURE_PORTABLE_ENTRYPOINTS +#endif // FEATURE_PORTABLE_ENTRYPOINTS } - _ASSERTE(!IsPointingToPrestub()); + _ASSERTE(!ShouldCallPrestub()); _ASSERTE(HasStableEntryPoint()); - pCode = DoBackpatch(pMT, pDispatchingMT, FALSE); + pCode = DoBackpatch(pMT, pDispatchingMT, false /* doFullBackpatch */); Return: // Interpreter-FIXME: Call stubs are not yet supported on WASM @@ -2467,7 +2479,11 @@ PCODE TheUMThunkPreStub() { LIMITED_METHOD_CONTRACT; +#ifdef FEATURE_PORTABLE_ENTRYPOINTS + UNREACHABLE_MSG("TheUMThunkPreStub not supported with FEATURE_PORTABLE_ENTRYPOINTS"); +#else // !FEATURE_PORTABLE_ENTRYPOINTS return GetEEFuncEntryPoint(TheUMEntryPrestub); +#endif // FEATURE_PORTABLE_ENTRYPOINTS } PCODE TheVarargPInvokeStub(BOOL hasRetBuffArg) @@ -2835,7 +2851,7 @@ EXTERN_C PCODE STDCALL ExternalMethodFixupWorker(TransitionBlock * pTransitionBl #endif // _DEBUG // - // Note that we do not want to call code:MethodDesc::IsPointingToPrestub() here. It does not take remoting + // Note that we do not want to call code:MethodDesc::ShouldCallPrestub() here. It does not take remoting // interception into account and so it would cause otherwise intercepted methods to be JITed. It is a compat // issue if the JITing fails. // diff --git a/src/coreclr/vm/proftoeeinterfaceimpl.cpp b/src/coreclr/vm/proftoeeinterfaceimpl.cpp index c1ad32fdb03401..e9b57d15af94af 100644 --- a/src/coreclr/vm/proftoeeinterfaceimpl.cpp +++ b/src/coreclr/vm/proftoeeinterfaceimpl.cpp @@ -2535,6 +2535,7 @@ HRESULT ProfToEEInterfaceImpl::GetCodeInfo3(FunctionID functionId, if (SUCCEEDED(hr)) { PCODE pCodeStart = (PCODE)NULL; +#ifdef FEATURE_CODE_VERSIONING CodeVersionManager* pCodeVersionManager = pMethodDesc->GetCodeVersionManager(); { ILCodeVersion ilCodeVersion = pCodeVersionManager->GetILCodeVersion(pMethodDesc, reJitId); @@ -2549,6 +2550,7 @@ HRESULT ProfToEEInterfaceImpl::GetCodeInfo3(FunctionID functionId, break; } } +#endif // FEATURE_CODE_VERSIONING hr = GetCodeInfoFromCodeStart(pCodeStart, cCodeInfos, @@ -4919,6 +4921,7 @@ HRESULT ProfToEEInterfaceImpl::GetILToNativeMapping2(FunctionID functionId, else { PCODE pCodeStart = (PCODE)NULL; +#ifdef FEATURE_CODE_VERSIONING CodeVersionManager *pCodeVersionManager = pMD->GetCodeVersionManager(); ILCodeVersion ilCodeVersion = NULL; { @@ -4934,6 +4937,7 @@ HRESULT ProfToEEInterfaceImpl::GetILToNativeMapping2(FunctionID functionId, break; } } +#endif // FEATURE_CODE_VERSIONING hr = GetILToNativeMapping3(pCodeStart, cMap, pcMap, map); } @@ -6439,6 +6443,7 @@ HRESULT ProfToEEInterfaceImpl::GetNativeCodeStartAddresses(FunctionID functionID ULONG32 trueLen = 0; StackSArray addresses; +#ifdef FEATURE_CODE_VERSIONING CodeVersionManager *pCodeVersionManager = pMD->GetCodeVersionManager(); ILCodeVersion ilCodeVersion = NULL; @@ -6459,6 +6464,7 @@ HRESULT ProfToEEInterfaceImpl::GetNativeCodeStartAddresses(FunctionID functionID } } } +#endif // FEATURE_CODE_VERSIONING if (pcCodeStartAddresses != NULL) { diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 256182b0c1aac6..11e57f6663e15c 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -9,6 +9,7 @@ // #include "arraynative.h" #include "objectnative.h" +#include "dllimport.h" #include "comdelegate.h" #include "customattribute.h" #include "comdynamic.h" diff --git a/src/coreclr/vm/reflectioninvocation.cpp b/src/coreclr/vm/reflectioninvocation.cpp index 7477de9a20ecc9..a01c9820479469 100644 --- a/src/coreclr/vm/reflectioninvocation.cpp +++ b/src/coreclr/vm/reflectioninvocation.cpp @@ -1221,7 +1221,7 @@ extern "C" void QCALLTYPE ReflectionInvocation_CompileMethod(MethodDesc * pMD) // Argument is checked on the managed side PRECONDITION(pMD != NULL); - if (!pMD->IsPointingToPrestub()) + if (!pMD->ShouldCallPrestub()) return; BEGIN_QCALL; @@ -1270,13 +1270,13 @@ static void PrepareMethodHelper(MethodDesc * pMD) pMD->EnsureActive(); - if (pMD->IsPointingToPrestub()) + if (pMD->ShouldCallPrestub()) pMD->DoPrestub(NULL); if (pMD->IsWrapperStub()) { pMD = pMD->GetWrappedMethodDesc(); - if (pMD->IsPointingToPrestub()) + if (pMD->ShouldCallPrestub()) pMD->DoPrestub(NULL); } } diff --git a/src/coreclr/vm/stubmgr.cpp b/src/coreclr/vm/stubmgr.cpp index f225baea1cba9f..0d87bd838e9d41 100644 --- a/src/coreclr/vm/stubmgr.cpp +++ b/src/coreclr/vm/stubmgr.cpp @@ -971,6 +971,7 @@ BOOL ThePreStubManager::CheckIsStub_Internal(PCODE stubStartAddress) // Stub manager functions & globals // ------------------------------------------------------- +#ifndef FEATURE_PORTABLE_ENTRYPOINTS SPTR_IMPL(PrecodeStubManager, PrecodeStubManager, g_pManager); #ifndef DACCESS_COMPILE @@ -1105,12 +1106,10 @@ BOOL PrecodeStubManager::DoTraceStub(PCODE stubStartAddress, break; } - PCODE target = pPrecode->GetTarget(); - // check if the method has been jitted - if (!pPrecode->IsPointingToPrestub(target)) + if (!pPrecode->IsPointingToPrestub()) { - trace->InitForStub(target); + trace->InitForStub(pPrecode->GetTarget()); LOG_TRACE_DESTINATION(trace, stubStartAddress, "PrecodeStubManager::DoTraceStub - code"); return TRUE; } @@ -1159,6 +1158,7 @@ BOOL PrecodeStubManager::TraceManager(Thread *thread, return FALSE; } #endif +#endif // !FEATURE_PORTABLE_ENTRYPOINTS // ------------------------------------------------------- // StubLinkStubManager @@ -1735,21 +1735,23 @@ BOOL ILStubManager::TraceManager(Thread *thread, _ASSERTE(!"We should never get here. Multicast Delegates should not invoke TraceManager."); return FALSE; } - else if (pStubMD->IsReverseStub()) + else if (pStubMD->IsReversePInvokeStub()) { - if (pStubMD->IsStatic()) - { - // This is reverse P/Invoke stub, the argument is UMEntryThunkData - UMEntryThunkData *pEntryThunk = (UMEntryThunkData*)arg; - target = pEntryThunk->GetManagedTarget(); - LOG((LF_CORDB, LL_INFO10000, "ILSM::TraceManager: Reverse P/Invoke case %p\n", target)); - } - else - { - // This is COM-to-CLR stub, the argument is the target - target = (PCODE)arg; - LOG((LF_CORDB, LL_INFO10000, "ILSM::TraceManager: COM-to-CLR case %p\n", target)); - } +#ifdef FEATURE_PORTABLE_ENTRYPOINTS + UNREACHABLE_MSG("Reverse P/Invoke stubs not supported with FEATURE_PORTABLE_ENTRYPOINTS."); +#else // !FEATURE_PORTABLE_ENTRYPOINTS + // This is reverse P/Invoke stub, the argument is UMEntryThunkData + UMEntryThunkData *pEntryThunk = (UMEntryThunkData*)arg; + target = pEntryThunk->GetManagedTarget(); + LOG((LF_CORDB, LL_INFO10000, "ILSM::TraceManager: Reverse P/Invoke case %p\n", target)); + trace->InitForManaged(target); +#endif // FEATURE_PORTABLE_ENTRYPOINTS + } + else if (pStubMD->IsCOMToCLRStub()) + { + // This is COM-to-CLR stub, the argument is the target + target = (PCODE)arg; + LOG((LF_CORDB, LL_INFO10000, "ILSM::TraceManager: COM-to-CLR case %p\n", target)); trace->InitForManaged(target); } else if (pStubMD->IsPInvokeDelegateStub()) @@ -2146,6 +2148,7 @@ BOOL TailCallStubManager::DoTraceStub(PCODE stubStartAddress, TraceDestination * #ifdef DACCESS_COMPILE +#ifndef FEATURE_PORTABLE_ENTRYPOINTS void PrecodeStubManager::DoEnumMemoryRegions(CLRDataEnumMemoryFlags flags) { @@ -2154,6 +2157,7 @@ PrecodeStubManager::DoEnumMemoryRegions(CLRDataEnumMemoryFlags flags) DAC_ENUM_VTHIS(); EMEM_OUT(("MEM: %p PrecodeStubManager\n", dac_cast(this))); } +#endif // !FEATURE_PORTABLE_ENTRYPOINTS void StubLinkStubManager::DoEnumMemoryRegions(CLRDataEnumMemoryFlags flags) diff --git a/src/coreclr/vm/stubmgr.h b/src/coreclr/vm/stubmgr.h index d1a71ca46f83db..c5d9495dff5bcd 100644 --- a/src/coreclr/vm/stubmgr.h +++ b/src/coreclr/vm/stubmgr.h @@ -392,6 +392,7 @@ class ThePreStubManager : public StubManager // frame-pushing, StubLinker created stubs // ------------------------------------------------------- +#ifndef FEATURE_PORTABLE_ENTRYPOINTS typedef VPTR(class PrecodeStubManager) PTR_PrecodeStubManager; class PrecodeStubManager : public StubManager @@ -434,6 +435,7 @@ class PrecodeStubManager : public StubManager { LIMITED_METHOD_CONTRACT; return W("MethodDescPrestub"); } #endif }; +#endif // !FEATURE_PORTABLE_ENTRYPOINTS // Note that this stub was written by a debugger guy, and thus when he refers to 'multicast' // stub, he really means multi or single cast stub. This was done b/c the same stub diff --git a/src/coreclr/vm/syncblk.cpp b/src/coreclr/vm/syncblk.cpp index 55c7f39fe48904..c47011789f3e29 100644 --- a/src/coreclr/vm/syncblk.cpp +++ b/src/coreclr/vm/syncblk.cpp @@ -64,9 +64,12 @@ InteropSyncBlockInfo::~InteropSyncBlockInfo() } CONTRACTL_END; +#ifndef FEATURE_PORTABLE_ENTRYPOINTS FreeUMEntryThunk(); +#endif // !FEATURE_PORTABLE_ENTRYPOINTS } +#ifndef FEATURE_PORTABLE_ENTRYPOINTS void InteropSyncBlockInfo::FreeUMEntryThunk() { CONTRACTL @@ -85,6 +88,7 @@ void InteropSyncBlockInfo::FreeUMEntryThunk() m_pUMEntryThunk = NULL; } } +#endif // !FEATURE_PORTABLE_ENTRYPOINTS #ifdef FEATURE_COMINTEROP // Returns either NULL or an RCW on which AcquireLock has been called. diff --git a/src/coreclr/vm/syncblk.h b/src/coreclr/vm/syncblk.h index 0e24261dd5be7b..45676d0e30266e 100644 --- a/src/coreclr/vm/syncblk.h +++ b/src/coreclr/vm/syncblk.h @@ -602,7 +602,10 @@ class AwareLock } }; +#ifndef FEATURE_PORTABLE_ENTRYPOINTS class UMEntryThunkData; +#endif // !FEATURE_PORTABLE_ENTRYPOINTS + #ifdef FEATURE_COMINTEROP class ComCallWrapper; class ComClassFactory; @@ -733,7 +736,7 @@ class InteropSyncBlockInfo #endif // FEATURE_COMINTEROP_UNMANAGED_ACTIVATION #endif // FEATURE_COMINTEROP -#if !defined(DACCESS_COMPILE) +#if !defined(DACCESS_COMPILE) && !defined(FEATURE_PORTABLE_ENTRYPOINTS) // set m_pUMEntryThunk if not already set - return true if not already set bool SetUMEntryThunk(UMEntryThunkData* pUMEntryThunk) { @@ -744,19 +747,24 @@ class InteropSyncBlockInfo } void FreeUMEntryThunk(); +#endif // !DACCESS_COMPILE && !FEATURE_PORTABLE_ENTRYPOINTS -#endif // DACCESS_COMPILE - +#ifndef FEATURE_PORTABLE_ENTRYPOINTS UMEntryThunkData* GetUMEntryThunk() { LIMITED_METHOD_CONTRACT; return m_pUMEntryThunk; } +#endif // !FEATURE_PORTABLE_ENTRYPOINTS private: +#ifdef FEATURE_PORTABLE_ENTRYPOINTS + void* m_pUMEntryThunk; // Dummy field to make using the C++ initializer list syntax easier to use. +#else // !FEATURE_PORTABLE_ENTRYPOINTS // If this is a delegate marshalled out to unmanaged code, this points // to the thunk generated for unmanaged code to call back on. UMEntryThunkData* m_pUMEntryThunk; +#endif // FEATURE_PORTABLE_ENTRYPOINTS #ifdef FEATURE_COMINTEROP // If this object is being exposed to COM, it will have an associated CCW object