From 0302e184749c98a18f18c2fe3fb660c47ed0c5e5 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 3 Dec 2020 14:00:11 -0800 Subject: [PATCH 01/38] Allow non-primitive struct returns to not require a stub. Fixes #35928. --- src/coreclr/src/vm/dllimport.cpp | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/coreclr/src/vm/dllimport.cpp b/src/coreclr/src/vm/dllimport.cpp index d9a003f9ee712..714d8196c3948 100644 --- a/src/coreclr/src/vm/dllimport.cpp +++ b/src/coreclr/src/vm/dllimport.cpp @@ -3227,21 +3227,7 @@ BOOL NDirect::MarshalingRequired( return TRUE; } #endif - - // return value is fine as long as it can be normalized to an integer - if (i == 0) - { - CorElementType normalizedType = hndArgType.GetInternalCorElementType(); - if (normalizedType == ELEMENT_TYPE_VALUETYPE) - { - // it is a structure even after normalization - return TRUE; - } - } - else - { - dwStackSize += StackElemSize(hndArgType.GetSize()); - } + dwStackSize += StackElemSize(hndArgType.GetSize()); break; } From ee5264f6e6e7ee364114a2c543e0bc12c9d144f9 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 4 Dec 2020 15:18:25 -0800 Subject: [PATCH 02/38] Support propagating the UnmanagedCallersOnly calling convention to the JIT. Block UnmanagedCallersOnly in crossgen1 since the attribute parsing code isn't included. --- src/coreclr/src/vm/dllimportcallback.cpp | 248 +++++++++--------- src/coreclr/src/vm/dllimportcallback.h | 4 +- src/coreclr/src/vm/jitinterface.cpp | 52 +++- src/coreclr/src/vm/jitinterface.h | 3 +- src/coreclr/src/zap/zapinfo.cpp | 16 +- .../Miscellaneous/ThisCall/ThisCallTest.cs | 100 +++++++ 6 files changed, 280 insertions(+), 143 deletions(-) diff --git a/src/coreclr/src/vm/dllimportcallback.cpp b/src/coreclr/src/vm/dllimportcallback.cpp index e33e08849f979..364fbca1a935f 100644 --- a/src/coreclr/src/vm/dllimportcallback.cpp +++ b/src/coreclr/src/vm/dllimportcallback.cpp @@ -655,128 +655,6 @@ VOID UMEntryThunk::CompileUMThunkWorker(UMThunkStubInfo *pInfo, pcpusl->X86EmitNearJump(pEnableRejoin); } -namespace -{ - // Templated function to compute if a char string begins with a constant string. - template - bool BeginsWith(ULONG s1Len, const char* s1, const char (&s2)[S2LEN]) - { - WRAPPER_NO_CONTRACT; - - ULONG s2Len = (ULONG)S2LEN - 1; // Remove null - if (s1Len < s2Len) - return false; - - return (0 == strncmp(s1, s2, s2Len)); - } -} - -VOID UMThunkMarshInfo::SetUpForUnmanagedCallersOnly() -{ - STANDARD_VM_CONTRACT; - - MethodDesc* pMD = GetMethod(); - _ASSERTE(pMD != NULL && pMD->HasUnmanagedCallersOnlyAttribute()); - - // Validate usage - COMDelegate::ThrowIfInvalidUnmanagedCallersOnlyUsage(pMD); - - BYTE* pData = NULL; - LONG cData = 0; - - bool nativeCallableInternalData = false; - HRESULT hr = pMD->GetCustomAttribute(WellKnownAttribute::UnmanagedCallersOnly, (const VOID **)(&pData), (ULONG *)&cData); - if (hr == S_FALSE) - { - hr = pMD->GetCustomAttribute(WellKnownAttribute::NativeCallableInternal, (const VOID **)(&pData), (ULONG *)&cData); - nativeCallableInternalData = SUCCEEDED(hr); - } - - IfFailThrow(hr); - - _ASSERTE(cData > 0); - - CustomAttributeParser ca(pData, cData); - - // UnmanagedCallersOnly and NativeCallableInternal each - // have optional named arguments. - CaNamedArg namedArgs[2]; - - // For the UnmanagedCallersOnly scenario. - CaType caCallConvs; - - // Define attribute specific optional named properties - if (nativeCallableInternalData) - { - namedArgs[0].InitI4FieldEnum("CallingConvention", "System.Runtime.InteropServices.CallingConvention", (ULONG)(CorPinvokeMap)0); - } - else - { - caCallConvs.Init(SERIALIZATION_TYPE_SZARRAY, SERIALIZATION_TYPE_TYPE, SERIALIZATION_TYPE_UNDEFINED, NULL, 0); - namedArgs[0].Init("CallConvs", SERIALIZATION_TYPE_SZARRAY, caCallConvs); - } - - // Define common optional named properties - CaTypeCtor caEntryPoint(SERIALIZATION_TYPE_STRING); - namedArgs[1].Init("EntryPoint", SERIALIZATION_TYPE_STRING, caEntryPoint); - - InlineFactory, 4> caValueArrayFactory; - DomainAssembly* domainAssembly = pMD->GetLoaderModule()->GetDomainAssembly(); - IfFailThrow(Attribute::ParseAttributeArgumentValues( - pData, - cData, - &caValueArrayFactory, - NULL, - 0, - namedArgs, - lengthof(namedArgs), - domainAssembly)); - - // If the value isn't defined, then return without setting anything. - if (namedArgs[0].val.type.tag == SERIALIZATION_TYPE_UNDEFINED) - return; - - CorPinvokeMap callConvLocal = (CorPinvokeMap)0; - if (nativeCallableInternalData) - { - callConvLocal = (CorPinvokeMap)(namedArgs[0].val.u4 << 8); - } - else - { - // Set WinAPI as the default - callConvLocal = CorPinvokeMap::pmCallConvWinapi; - - CaValue* arrayOfTypes = &namedArgs[0].val; - for (ULONG i = 0; i < arrayOfTypes->arr.length; i++) - { - CaValue& typeNameValue = arrayOfTypes->arr[i]; - - // According to ECMA-335, type name strings are UTF-8. Since we are - // looking for type names that are equivalent in ASCII and UTF-8, - // using a const char constant is acceptable. Type name strings are - // in Fully Qualified form, so we include the ',' delimiter. - if (BeginsWith(typeNameValue.str.cbStr, typeNameValue.str.pStr, "System.Runtime.CompilerServices.CallConvCdecl,")) - { - callConvLocal = CorPinvokeMap::pmCallConvCdecl; - } - else if (BeginsWith(typeNameValue.str.cbStr, typeNameValue.str.pStr, "System.Runtime.CompilerServices.CallConvStdcall,")) - { - callConvLocal = CorPinvokeMap::pmCallConvStdcall; - } - else if (BeginsWith(typeNameValue.str.cbStr, typeNameValue.str.pStr, "System.Runtime.CompilerServices.CallConvFastcall,")) - { - callConvLocal = CorPinvokeMap::pmCallConvFastcall; - } - else if (BeginsWith(typeNameValue.str.cbStr, typeNameValue.str.pStr, "System.Runtime.CompilerServices.CallConvThiscall,")) - { - callConvLocal = CorPinvokeMap::pmCallConvThiscall; - } - } - } - - m_callConv = (UINT16)callConvLocal; -} - // Compiles an unmanaged to managed thunk for the given signature. Stub *UMThunkMarshInfo::CompileNExportThunk(LoaderHeap *pLoaderHeap, PInvokeStaticSigInfo* pSigInfo, MetaSig *pMetaSig, BOOL fNoStub) { @@ -1341,7 +1219,11 @@ VOID UMThunkMarshInfo::RunTimeInit() if (pMD != NULL && pMD->HasUnmanagedCallersOnlyAttribute()) { - SetUpForUnmanagedCallersOnly(); + CorPinvokeMap callConv; + if (TryGetCallingConventionFromUnmanagedCallersOnly(pMD, &callConv)) + { + m_callConv = (UINT16)callConv; + } } #endif // TARGET_X86 && !FEATURE_STUBS_AS_IL @@ -1605,4 +1487,124 @@ void STDCALL LogUMTransition(UMEntryThunk* thunk) } #endif +namespace +{ + // Templated function to compute if a char string begins with a constant string. + template + bool BeginsWith(ULONG s1Len, const char* s1, const char (&s2)[S2LEN]) + { + WRAPPER_NO_CONTRACT; + + ULONG s2Len = (ULONG)S2LEN - 1; // Remove null + if (s1Len < s2Len) + return false; + + return (0 == strncmp(s1, s2, s2Len)); + } +} + +bool TryGetCallingConventionFromUnmanagedCallersOnly(MethodDesc* pMD, CorPinvokeMap* pCallConv) +{ + STANDARD_VM_CONTRACT; + _ASSERTE(pMD != NULL && pMD->HasUnmanagedCallersOnlyAttribute()); + + // Validate usage + COMDelegate::ThrowIfInvalidUnmanagedCallersOnlyUsage(pMD); + + BYTE* pData = NULL; + LONG cData = 0; + + bool nativeCallableInternalData = false; + HRESULT hr = pMD->GetCustomAttribute(WellKnownAttribute::UnmanagedCallersOnly, (const VOID **)(&pData), (ULONG *)&cData); + if (hr == S_FALSE) + { + hr = pMD->GetCustomAttribute(WellKnownAttribute::NativeCallableInternal, (const VOID **)(&pData), (ULONG *)&cData); + nativeCallableInternalData = SUCCEEDED(hr); + } + + IfFailThrow(hr); + + _ASSERTE(cData > 0); + + CustomAttributeParser ca(pData, cData); + + // UnmanagedCallersOnly and NativeCallableInternal each + // have optional named arguments. + CaNamedArg namedArgs[2]; + + // For the UnmanagedCallersOnly scenario. + CaType caCallConvs; + + // Define attribute specific optional named properties + if (nativeCallableInternalData) + { + namedArgs[0].InitI4FieldEnum("CallingConvention", "System.Runtime.InteropServices.CallingConvention", (ULONG)(CorPinvokeMap)0); + namedArgs[0].InitI4FieldEnum("CallingConvention", "System.Runtime.InteropServices.CallingConvention", (ULONG)(CorPinvokeMap)0); + } + else + { + caCallConvs.Init(SERIALIZATION_TYPE_SZARRAY, SERIALIZATION_TYPE_TYPE, SERIALIZATION_TYPE_UNDEFINED, NULL, 0); + namedArgs[0].Init("CallConvs", SERIALIZATION_TYPE_SZARRAY, caCallConvs); + } + + // Define common optional named properties + CaTypeCtor caEntryPoint(SERIALIZATION_TYPE_STRING); + namedArgs[1].Init("EntryPoint", SERIALIZATION_TYPE_STRING, caEntryPoint); + + InlineFactory, 4> caValueArrayFactory; + DomainAssembly* domainAssembly = pMD->GetLoaderModule()->GetDomainAssembly(); + IfFailThrow(Attribute::ParseAttributeArgumentValues( + pData, + cData, + &caValueArrayFactory, + NULL, + 0, + namedArgs, + lengthof(namedArgs), + domainAssembly)); + + // If the value isn't defined, then return without setting anything. + if (namedArgs[0].val.type.tag == SERIALIZATION_TYPE_UNDEFINED) + return false; + + CorPinvokeMap callConvLocal = (CorPinvokeMap)0; + if (nativeCallableInternalData) + { + callConvLocal = (CorPinvokeMap)(namedArgs[0].val.u4 << 8); + } + else + { + // Set WinAPI as the default + callConvLocal = CorPinvokeMap::pmCallConvWinapi; + + CaValue* arrayOfTypes = &namedArgs[0].val; + for (ULONG i = 0; i < arrayOfTypes->arr.length; i++) + { + CaValue& typeNameValue = arrayOfTypes->arr[i]; + + // According to ECMA-335, type name strings are UTF-8. Since we are + // looking for type names that are equivalent in ASCII and UTF-8, + // using a const char constant is acceptable. Type name strings are + // in Fully Qualified form, so we include the ',' delimiter. + if (BeginsWith(typeNameValue.str.cbStr, typeNameValue.str.pStr, "System.Runtime.CompilerServices.CallConvCdecl,")) + { + callConvLocal = CorPinvokeMap::pmCallConvCdecl; + } + else if (BeginsWith(typeNameValue.str.cbStr, typeNameValue.str.pStr, "System.Runtime.CompilerServices.CallConvStdcall,")) + { + callConvLocal = CorPinvokeMap::pmCallConvStdcall; + } + else if (BeginsWith(typeNameValue.str.cbStr, typeNameValue.str.pStr, "System.Runtime.CompilerServices.CallConvFastcall,")) + { + callConvLocal = CorPinvokeMap::pmCallConvFastcall; + } + else if (BeginsWith(typeNameValue.str.cbStr, typeNameValue.str.pStr, "System.Runtime.CompilerServices.CallConvThiscall,")) + { + callConvLocal = CorPinvokeMap::pmCallConvThiscall; + } + } + } + *pCallConv = callConvLocal; + return true; +} #endif // CROSSGEN_COMPILE diff --git a/src/coreclr/src/vm/dllimportcallback.h b/src/coreclr/src/vm/dllimportcallback.h index 1bdb5d5cbebd3..f0628da5b4fd0 100644 --- a/src/coreclr/src/vm/dllimportcallback.h +++ b/src/coreclr/src/vm/dllimportcallback.h @@ -177,8 +177,6 @@ class UMThunkMarshInfo VOID SetupArguments(char *pSrc, ArgumentRegisters *pArgRegs, char *pDst); #else private: - VOID SetUpForUnmanagedCallersOnly(); - // Compiles an unmanaged to managed thunk for the given signature. The thunk // will call the stub or, if fNoStub == TRUE, directly the managed target. Stub *CompileNExportThunk(LoaderHeap *pLoaderHeap, PInvokeStaticSigInfo* pSigInfo, MetaSig *pMetaSig, BOOL fNoStub); @@ -529,6 +527,8 @@ EXCEPTION_HANDLER_DECL(UMThunkPrestubHandler); #endif // TARGET_X86 && !FEATURE_STUBS_AS_IL +bool TryGetCallingConventionFromUnmanagedCallersOnly(MethodDesc* pMD, CorPinvokeMap* pCallConv); + extern "C" void TheUMEntryPrestub(void); extern "C" PCODE TheUMEntryPrestubWorker(UMEntryThunk * pUMEntryThunk); diff --git a/src/coreclr/src/vm/jitinterface.cpp b/src/coreclr/src/vm/jitinterface.cpp index 6515a798ba588..8cda68fb8257e 100644 --- a/src/coreclr/src/vm/jitinterface.cpp +++ b/src/coreclr/src/vm/jitinterface.cpp @@ -24,6 +24,7 @@ #include "float.h" // for isnan #include "dbginterface.h" #include "dllimport.h" +#include "dllimportcallback.h" #include "gcheaputilities.h" #include "comdelegate.h" #include "corprof.h" @@ -444,7 +445,8 @@ CEEInfo::ConvToJitSig( CORINFO_SIG_INFO * sigRet, MethodDesc * pContextMD, bool localSig, - TypeHandle contextType) + TypeHandle contextType, + bool checkUnmanagedCallersOnly) { CONTRACTL { THROWS; @@ -529,6 +531,38 @@ CEEInfo::ConvToJitSig( sigRet->callConv = (CorInfoCallConv)MetaSig::GetDefaultUnmanagedCallingConvention(); } } +#if !defined(TARGET_X86) + else if (checkUnmanagedCallersOnly && sigRet->callConv == IMAGE_CEE_CS_CALLCONV_DEFAULT && + pContextMD && pContextMD->HasUnmanagedCallersOnlyAttribute()) + { +#ifdef CROSSGEN_COMPILE + _ASSERTE_MSG(false, "UnmanagedCallersOnly methods are not supported in crossgen and should be rejected before getting here."); +#else + CorPinvokeMap unmanagedCallConv; + if (TryGetCallingConventionFromUnmanagedCallersOnly(pContextMD, &unmanagedCallConv)) + { + switch (unmanagedCallConv) + { + case pmCallConvWinapi: + sigRet->callConv = (CorInfoCallConv)MetaSig::GetDefaultUnmanagedCallingConvention(); + break; + case pmCallConvCdecl: + sigRet->callConv = CORINFO_CALLCONV_C; + break; + case pmCallConvStdcall: + sigRet->callConv = CORINFO_CALLCONV_STDCALL; + break; + case pmCallConvThiscall: + sigRet->callConv = CORINFO_CALLCONV_THISCALL; + break; + case pmCallConvFastcall: + sigRet->callConv = CORINFO_CALLCONV_FASTCALL; + break; + } + } +#endif + } +#endif // Skip number of type arguments if (sigRet->callConv & IMAGE_CEE_CS_CALLCONV_GENERIC) @@ -7763,7 +7797,9 @@ getMethodInfoHelper( mdTokenNil, &methInfo->args, ftn, - false); + false, + TypeHandle(), + true); // Shared generic or static per-inst methods and shared methods on generic structs // take an extra argument representing their instantiation @@ -11920,7 +11956,7 @@ HRESULT CEEJitInfo::getMethodBlockCounts ( #endif EE_TO_JIT_TRANSITION(); - + return hr; } @@ -12709,7 +12745,7 @@ CORJIT_FLAGS GetCompileFlags(MethodDesc * ftn, CORJIT_FLAGS flags, CORINFO_METHO #ifdef FEATURE_PGO // Instrument, if - // + // // * We're writing pgo data and we're jitting at Tier0. // * Tiered PGO is enabled and we're jitting at Tier0. // @@ -12733,7 +12769,7 @@ CORJIT_FLAGS GetCompileFlags(MethodDesc * ftn, CORJIT_FLAGS flags, CORINFO_METHO { flags.Set(CORJIT_FLAGS::CORJIT_FLAG_BBOPT); } - + #endif return flags; @@ -13856,7 +13892,7 @@ BOOL LoadDynamicInfoEntry(Module *currentModule, // Verification failures are failfast events DefineFullyQualifiedNameForClassW(); SString fatalErrorString; - fatalErrorString.Printf(W("Verify_TypeLayout '%s' failed to verify type layout"), + fatalErrorString.Printf(W("Verify_TypeLayout '%s' failed to verify type layout"), GetFullyQualifiedNameForClassW(pMT)); #ifdef _DEBUG @@ -13909,7 +13945,7 @@ BOOL LoadDynamicInfoEntry(Module *currentModule, } DWORD actualBaseOffset = 0; - if (!pField->IsStatic() && + if (!pField->IsStatic() && pEnclosingMT->GetParentMethodTable() != NULL && !pEnclosingMT->IsValueType()) { @@ -13923,7 +13959,7 @@ BOOL LoadDynamicInfoEntry(Module *currentModule, SString ssFieldName(SString::Utf8, pField->GetName()); SString fatalErrorString; - fatalErrorString.Printf(W("Verify_FieldOffset '%s.%s' Field offset %d!=%d(actual) || baseOffset %d!=%d(actual)"), + fatalErrorString.Printf(W("Verify_FieldOffset '%s.%s' Field offset %d!=%d(actual) || baseOffset %d!=%d(actual)"), GetFullyQualifiedNameForClassW(pEnclosingMT), ssFieldName.GetUnicode(), fieldOffset, diff --git a/src/coreclr/src/vm/jitinterface.h b/src/coreclr/src/vm/jitinterface.h index 7518004464e7d..e1c7a0ee9e903 100644 --- a/src/coreclr/src/vm/jitinterface.h +++ b/src/coreclr/src/vm/jitinterface.h @@ -1131,7 +1131,8 @@ class CEEInfo : public ICorJitInfo CORINFO_SIG_INFO * sigRet, MethodDesc * context, bool localSig, - TypeHandle owner = TypeHandle()); + TypeHandle owner = TypeHandle(), + bool checkUnmanagedCallersOnly = false); MethodDesc * GetMethodForSecurity(CORINFO_METHOD_HANDLE callerHandle); diff --git a/src/coreclr/src/zap/zapinfo.cpp b/src/coreclr/src/zap/zapinfo.cpp index 036457ab673d8..177a158156172 100644 --- a/src/coreclr/src/zap/zapinfo.cpp +++ b/src/coreclr/src/zap/zapinfo.cpp @@ -399,6 +399,13 @@ void ZapInfo::CompileMethod() // only do it when we are truely logging m_zapper->Info(W("Compiling method %s\n"), m_currentMethodName.GetUnicode()); } + + if (GetCompileInfo()->IsUnmanagedCallersOnlyMethod(m_currentMethodHandle)) + { + if (m_zapper->m_pOpt->m_verbose) + m_zapper->Warning(W("ReadyToRun: Methods with UnmanagedCallersOnlyAttribute not implemented\n")); + ThrowHR(E_NOTIMPL); + } m_currentMethodInfo = CORINFO_METHOD_INFO(); if (!getMethodInfo(m_currentMethodHandle, &m_currentMethodInfo)) @@ -474,15 +481,6 @@ void ZapInfo::CompileMethod() } #endif -#ifdef TARGET_X86 - if (GetCompileInfo()->IsUnmanagedCallersOnlyMethod(m_currentMethodHandle)) - { - if (m_zapper->m_pOpt->m_verbose) - m_zapper->Warning(W("ReadyToRun: Methods with UnmanagedCallersOnlyAttribute not implemented\n")); - ThrowHR(E_NOTIMPL); - } -#endif // TARGET_X86 - if (m_pImage->m_stats) { m_pImage->m_stats->m_methods++; diff --git a/src/tests/Interop/PInvoke/Miscellaneous/ThisCall/ThisCallTest.cs b/src/tests/Interop/PInvoke/Miscellaneous/ThisCall/ThisCallTest.cs index 66d40546e91b3..31719e8d7aed8 100644 --- a/src/tests/Interop/PInvoke/Miscellaneous/ThisCall/ThisCallTest.cs +++ b/src/tests/Interop/PInvoke/Miscellaneous/ThisCall/ThisCallTest.cs @@ -6,6 +6,7 @@ using System.Reflection; using System.Text; using TestLibrary; +using System.Runtime.CompilerServices; unsafe class ThisCallNative { @@ -86,6 +87,10 @@ public static int Main(string[] args) Test4ByteHFAReverse(); Test4ByteNonHFAReverse(); TestEnumReverse(); + Test8ByteHFAUnmanagedCallersOnly(); + Test4ByteHFAUnmanagedCallersOnly(); + Test4ByteNonHFAUnmanagedCallersOnly(); + TestEnumUnmanagedCallersOnly(); } catch (System.Exception ex) { @@ -164,6 +169,38 @@ private static void TestEnumReverse() Assert.AreEqual(c.dummy, result); } + private static void Test8ByteHFAUnmanagedCallersOnly() + { + ThisCallNative.C c = CreateCWithUnmanagedCallersOnlyVTable(2.0f, 3.0f); + ThisCallNative.SizeF result = ThisCallNative.GetSizeFromManaged(&c); + + Assert.AreEqual(c.width, result.width); + Assert.AreEqual(c.height, result.height); + } + + private static void Test4ByteHFAUnmanagedCallersOnly() + { + ThisCallNative.C c = CreateCWithUnmanagedCallersOnlyVTable(2.0f, 3.0f); + ThisCallNative.Width result = ThisCallNative.GetWidthFromManaged(&c); + + Assert.AreEqual(c.width, result.width); + } + + private static void Test4ByteNonHFAUnmanagedCallersOnly() + { + ThisCallNative.C c = CreateCWithUnmanagedCallersOnlyVTable(2.0f, 3.0f); + ThisCallNative.IntWrapper result = ThisCallNative.GetHeightAsIntFromManaged(&c); + + Assert.AreEqual((int)c.height, result.i); + } + + private static void TestEnumUnmanagedCallersOnly() + { + ThisCallNative.C c = CreateCWithUnmanagedCallersOnlyVTable(2.0f, 3.0f); + ThisCallNative.E result = ThisCallNative.GetEFromManaged(&c); + + Assert.AreEqual(c.dummy, result); + } private static ThisCallNative.C CreateCWithManagedVTable(float width, float height) { @@ -176,6 +213,17 @@ private static ThisCallNative.C CreateCWithManagedVTable(float width, float heig }; } + private static ThisCallNative.C CreateCWithUnmanagedCallersOnlyVTable(float width, float height) + { + return new ThisCallNative.C + { + vtable = UnmanagedCallersOnlyVtable, + dummy = ThisCallNative.E.Value, + width = width, + height = height + }; + } + private static ThisCallNative.C.VtableLayout* managedVtable; private static ThisCallNative.C.VtableLayout* ManagedVtable @@ -197,4 +245,56 @@ private static ThisCallNative.C.VtableLayout* ManagedVtable return managedVtable; } } + + private static ThisCallNative.C.VtableLayout* unmanagedCallersOnlyVtable; + + private static ThisCallNative.C.VtableLayout* UnmanagedCallersOnlyVtable + { + get + { + if (unmanagedCallersOnlyVtable == null) + { + unmanagedCallersOnlyVtable = (ThisCallNative.C.VtableLayout*)Marshal.AllocHGlobal(sizeof(ThisCallNative.C.VtableLayout)); + unmanagedCallersOnlyVtable->getSize = (IntPtr)(delegate* unmanaged[Thiscall])&GetSize; + unmanagedCallersOnlyVtable->getWidth = (IntPtr)(delegate* unmanaged[Thiscall])&GetWidth; + unmanagedCallersOnlyVtable->getHeightAsInt = (IntPtr)(delegate* unmanaged[Thiscall])&GetHeightAsInt; + unmanagedCallersOnlyVtable->getE = (IntPtr)(delegate* unmanaged[Thiscall])&GetE; + } + return unmanagedCallersOnlyVtable; + } + } + + [UnmanagedCallersOnly(CallConvs = new [] {typeof(CallConvThiscall)})] + private static ThisCallNative.SizeF GetSize(ThisCallNative.C* c) + { + return new ThisCallNative.SizeF + { + width = c->width, + height = c->height + }; + } + + [UnmanagedCallersOnly(CallConvs = new [] {typeof(CallConvThiscall)})] + private static ThisCallNative.Width GetWidth(ThisCallNative.C* c) + { + return new ThisCallNative.Width + { + width = c->width + }; + } + + [UnmanagedCallersOnly(CallConvs = new [] {typeof(CallConvThiscall)})] + private static ThisCallNative.IntWrapper GetHeightAsInt(ThisCallNative.C* c) + { + return new ThisCallNative.IntWrapper + { + i = (int)c->height + }; + } + + [UnmanagedCallersOnly(CallConvs = new [] {typeof(CallConvThiscall)})] + private static ThisCallNative.E GetE(ThisCallNative.C* c) + { + return c->dummy; + } } From 96e5e0f973bba4af36546eacad5bd00f17d7bc38 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 4 Dec 2020 16:10:18 -0800 Subject: [PATCH 03/38] Support passing through the calling convention for UnmanagedCallersOnly in crossgen2 --- .../tools/Common/JitInterface/CorInfoImpl.cs | 77 ++++++++++++++++--- 1 file changed, 65 insertions(+), 12 deletions(-) diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs index b73d9d13f15bf..884b1dafa79f3 100644 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs @@ -27,6 +27,8 @@ #if READYTORUN using System.Reflection.Metadata.Ecma335; using ILCompiler.DependencyAnalysis.ReadyToRun; +using System.Reflection.Metadata; +using System.Collections.Immutable; #endif namespace Internal.JitInterface @@ -474,13 +476,13 @@ private bool Get_CORINFO_METHOD_INFO(MethodDesc method, MethodIL methodIL, CORIN methodInfo->options |= CorInfoOptions.CORINFO_GENERICS_CTXT_FROM_METHODTABLE; } methodInfo->regionKind = CorInfoRegionKind.CORINFO_REGION_NONE; - Get_CORINFO_SIG_INFO(method, &methodInfo->args); + Get_CORINFO_SIG_INFO(method, &methodInfo->args, checkUnmanagedCallersOnly: true); Get_CORINFO_SIG_INFO(methodIL.GetLocals(), &methodInfo->locals); return true; } - private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, bool suppressHiddenArgument = false) + private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, bool suppressHiddenArgument = false, bool checkUnmanagedCallersOnly = false) { Get_CORINFO_SIG_INFO(method.Signature, sig); @@ -520,6 +522,54 @@ private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, bool { sig->callConv |= CorInfoCallConv.CORINFO_CALLCONV_PARAMTYPE; } + else if (checkUnmanagedCallersOnly && method.IsUnmanagedCallersOnly) + { + CustomAttributeValue unmanagedCallersOnlyAttribute = ((EcmaMethod)method).GetDecodedCustomAttribute("System.Runtime.InteropServices", "UnmanagedCallersOnlyAttribute").Value; + sig->callConv = GetUnmanagedCallingConventionFromAttribute(unmanagedCallersOnlyAttribute); + } + } + + private CorInfoCallConv GetUnmanagedCallingConventionFromAttribute(CustomAttributeValue unmanagedCallersOnlyAttribute) + { + CorInfoCallConv callConv = (CorInfoCallConv)PlatformDefaultUnmanagedCallingConvention(); + + ImmutableArray> callConvArray = default; + foreach (var arg in unmanagedCallersOnlyAttribute.NamedArguments) + { + if (arg.Name == "CallConvs") + { + callConvArray = (ImmutableArray>)arg.Value; + } + } + + // No calling convention was specified in the attribute, so return the default. + if (callConvArray.IsDefault) + { + return callConv; + } + + bool found = false; + foreach (CustomAttributeTypedArgument type in callConvArray) + { + if (!(type.Value is DefType defType)) + continue; + + if (defType.Namespace != "System.Runtime.CompilerServices") + continue; + + CorInfoCallConv? callConvLocal = GetCallingConventionForCallConvType(defType); + + if (callConvLocal.HasValue) + { + // Error if there are multiple recognized calling conventions + if (found) + ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramMultipleCallConv, MethodBeingCompiled); + + callConv = callConvLocal.Value; + found = true; + } + } + return callConv; } private bool TryGetUnmanagedCallingConventionFromModOpt(MethodSignature signature, out CorInfoCallConv callConv) @@ -545,22 +595,14 @@ private bool TryGetUnmanagedCallingConventionFromModOpt(MethodSignature signatur if (defType.Namespace != "System.Runtime.CompilerServices") continue; - // Look for a recognized calling convention in metadata. - CorInfoCallConv? callConvLocal = defType.Name switch - { - "CallConvCdecl" => CorInfoCallConv.CORINFO_CALLCONV_C, - "CallConvStdcall" => CorInfoCallConv.CORINFO_CALLCONV_STDCALL, - "CallConvFastcall" => CorInfoCallConv.CORINFO_CALLCONV_FASTCALL, - "CallConvThiscall" => CorInfoCallConv.CORINFO_CALLCONV_THISCALL, - _ => null - }; + CorInfoCallConv? callConvLocal = GetCallingConventionForCallConvType(defType); if (callConvLocal.HasValue) { // Error if there are multiple recognized calling conventions if (found) ThrowHelper.ThrowInvalidProgramException(ExceptionStringID.InvalidProgramMultipleCallConv, MethodBeingCompiled); - + callConv = callConvLocal.Value; found = true; } @@ -569,6 +611,17 @@ private bool TryGetUnmanagedCallingConventionFromModOpt(MethodSignature signatur return found; } + private static CorInfoCallConv? GetCallingConventionForCallConvType(DefType defType) => + // Look for a recognized calling convention in metadata. + defType.Name switch + { + "CallConvCdecl" => CorInfoCallConv.CORINFO_CALLCONV_C, + "CallConvStdcall" => CorInfoCallConv.CORINFO_CALLCONV_STDCALL, + "CallConvFastcall" => CorInfoCallConv.CORINFO_CALLCONV_FASTCALL, + "CallConvThiscall" => CorInfoCallConv.CORINFO_CALLCONV_THISCALL, + _ => null + }; + private void Get_CORINFO_SIG_INFO(MethodSignature signature, CORINFO_SIG_INFO* sig) { sig->callConv = (CorInfoCallConv)(signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask); From 1b3ed1a0ee26b4bc0cd4e22e77d97cd66141b7ff Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 4 Dec 2020 16:49:40 -0800 Subject: [PATCH 04/38] Fix clang errors. --- src/coreclr/src/vm/jitinterface.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/vm/jitinterface.cpp b/src/coreclr/src/vm/jitinterface.cpp index 8cda68fb8257e..d925c75fe1d97 100644 --- a/src/coreclr/src/vm/jitinterface.cpp +++ b/src/coreclr/src/vm/jitinterface.cpp @@ -532,7 +532,7 @@ CEEInfo::ConvToJitSig( } } #if !defined(TARGET_X86) - else if (checkUnmanagedCallersOnly && sigRet->callConv == IMAGE_CEE_CS_CALLCONV_DEFAULT && + else if (checkUnmanagedCallersOnly && sigRet->callConv == CORINFO_CALLCONV_DEFAULT && pContextMD && pContextMD->HasUnmanagedCallersOnlyAttribute()) { #ifdef CROSSGEN_COMPILE @@ -558,6 +558,8 @@ CEEInfo::ConvToJitSig( case pmCallConvFastcall: sigRet->callConv = CORINFO_CALLCONV_FASTCALL; break; + default: + break; } } #endif From 79b5916277444d544a79c3577915dedff6e67f64 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 7 Dec 2020 10:50:33 -0800 Subject: [PATCH 05/38] Fix stack calculation. --- src/coreclr/src/vm/dllimport.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/vm/dllimport.cpp b/src/coreclr/src/vm/dllimport.cpp index 714d8196c3948..11c6b8cded6c2 100644 --- a/src/coreclr/src/vm/dllimport.cpp +++ b/src/coreclr/src/vm/dllimport.cpp @@ -3227,7 +3227,10 @@ BOOL NDirect::MarshalingRequired( return TRUE; } #endif - dwStackSize += StackElemSize(hndArgType.GetSize()); + if (i > 0) + { + dwStackSize += StackElemSize(hndArgType.GetSize()); + } break; } From 2723dc66c27e44b91b717a577c8c402f4d2f9919 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 7 Dec 2020 12:48:10 -0800 Subject: [PATCH 06/38] Fix usings --- src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs index 884b1dafa79f3..044d3a31e505b 100644 --- a/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/src/tools/Common/JitInterface/CorInfoImpl.cs @@ -3,9 +3,11 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Diagnostics; using System.IO; using System.Text; +using System.Reflection.Metadata; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; @@ -27,8 +29,6 @@ #if READYTORUN using System.Reflection.Metadata.Ecma335; using ILCompiler.DependencyAnalysis.ReadyToRun; -using System.Reflection.Metadata; -using System.Collections.Immutable; #endif namespace Internal.JitInterface From d0e811bba2b32c1c0e9317107b3118fc4a85cb52 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 7 Dec 2020 15:42:34 -0800 Subject: [PATCH 07/38] Clean up jitinterface. --- src/coreclr/src/vm/jitinterface.cpp | 60 +++++++++++++---------------- src/coreclr/src/vm/jitinterface.h | 40 ++++++++++++++++--- 2 files changed, 62 insertions(+), 38 deletions(-) diff --git a/src/coreclr/src/vm/jitinterface.cpp b/src/coreclr/src/vm/jitinterface.cpp index d925c75fe1d97..a082798a94c8d 100644 --- a/src/coreclr/src/vm/jitinterface.cpp +++ b/src/coreclr/src/vm/jitinterface.cpp @@ -442,11 +442,9 @@ CEEInfo::ConvToJitSig( DWORD cbSig, CORINFO_MODULE_HANDLE scopeHnd, mdToken token, - CORINFO_SIG_INFO * sigRet, - MethodDesc * pContextMD, - bool localSig, - TypeHandle contextType, - bool checkUnmanagedCallersOnly) + SignatureContext context, + ConvToJitSigFlags flags, + CORINFO_SIG_INFO * sigRet) { CONTRACTL { THROWS; @@ -456,15 +454,15 @@ CEEInfo::ConvToJitSig( SigTypeContext typeContext; uint32_t sigRetFlags = 0; - if (pContextMD) + if (context.methodContext) { - SigTypeContext::InitTypeContext(pContextMD, contextType, &typeContext); - if (pContextMD->ShouldSuppressGCTransition()) + SigTypeContext::InitTypeContext(context.methodContext, context.typeContext, &typeContext); + if (context.methodContext->ShouldSuppressGCTransition()) sigRetFlags |= CORINFO_SIGFLAG_SUPPRESS_GC_TRANSITION; } else { - SigTypeContext::InitTypeContext(contextType, &typeContext); + SigTypeContext::InitTypeContext(context.typeContext, &typeContext); } static_assert_no_msg(CORINFO_CALLCONV_DEFAULT == (CorInfoCallConv) IMAGE_CEE_CS_CALLCONV_DEFAULT); @@ -487,7 +485,7 @@ CEEInfo::ConvToJitSig( SigPointer sig(pSig, cbSig); - if (!localSig) + if ((flags & CONV_TO_JITSIG_FLAGS_LOCALSIG) == 0) { // This is a method signature which includes calling convention, return type, // arguments, etc @@ -532,14 +530,15 @@ CEEInfo::ConvToJitSig( } } #if !defined(TARGET_X86) - else if (checkUnmanagedCallersOnly && sigRet->callConv == CORINFO_CALLCONV_DEFAULT && - pContextMD && pContextMD->HasUnmanagedCallersOnlyAttribute()) + else if ((flags & CONV_TO_JITSIG_FLAGS_CHECK_UNMANAGEDCALLERSONLY) == 0 + && sigRet->callConv == CORINFO_CALLCONV_DEFAULT + && context.methodContext && context.methodContext->HasUnmanagedCallersOnlyAttribute()) { #ifdef CROSSGEN_COMPILE _ASSERTE_MSG(false, "UnmanagedCallersOnly methods are not supported in crossgen and should be rejected before getting here."); #else CorPinvokeMap unmanagedCallConv; - if (TryGetCallingConventionFromUnmanagedCallersOnly(pContextMD, &unmanagedCallConv)) + if (TryGetCallingConventionFromUnmanagedCallersOnly(context.methodContext, &unmanagedCallConv)) { switch (unmanagedCallConv) { @@ -1913,10 +1912,9 @@ CEEInfo::findCallSiteSig( cbSig, scopeHnd, sigMethTok, - sigRet, - GetMethodFromContext(context), - false, - GetTypeFromContext(context)); + CEEInfo::SignatureContext(this, context), + CONV_TO_JITSIG_FLAGS_NONE, + sigRet); EE_TO_JIT_TRANSITION(); } // CEEInfo::findCallSiteSig @@ -1962,10 +1960,9 @@ CEEInfo::findSig( cbSig, scopeHnd, sigTok, - sigRet, - GetMethodFromContext(context), - false, - GetTypeFromContext(context)); + CEEInfo::SignatureContext(this, context), + CONV_TO_JITSIG_FLAGS_NONE, + sigRet); EE_TO_JIT_TRANSITION(); } // CEEInfo::findSig @@ -7797,11 +7794,9 @@ getMethodInfoHelper( cbSig, GetScopeHandle(ftn), mdTokenNil, - &methInfo->args, - ftn, - false, - TypeHandle(), - true); + CEEInfo::SignatureContext(ftn), + CEEInfo::CONV_TO_JITSIG_FLAGS_CHECK_UNMANAGEDCALLERSONLY, + &methInfo->args); // Shared generic or static per-inst methods and shared methods on generic structs // take an extra argument representing their instantiation @@ -7818,9 +7813,9 @@ getMethodInfoHelper( cbLocalSig, GetScopeHandle(ftn), mdTokenNil, - &methInfo->locals, - ftn, - true); + CEEInfo::SignatureContext(ftn), + CEEInfo::CONV_TO_JITSIG_FLAGS_LOCALSIG, + &methInfo->locals); } // getMethodInfoHelper @@ -8660,10 +8655,9 @@ CEEInfo::getMethodSigInternal( cbSig, GetScopeHandle(ftn), mdTokenNil, - sigRet, - ftn, - false, - (TypeHandle)owner); + CEEInfo::SignatureContext(ftn, (TypeHandle)owner), + CONV_TO_JITSIG_FLAGS_NONE, + sigRet); //@GENERICS: // Shared generic methods and shared methods on generic structs take an extra argument representing their instantiation diff --git a/src/coreclr/src/vm/jitinterface.h b/src/coreclr/src/vm/jitinterface.h index e1c7a0ee9e903..1fbdec99bc2ef 100644 --- a/src/coreclr/src/vm/jitinterface.h +++ b/src/coreclr/src/vm/jitinterface.h @@ -1118,6 +1118,38 @@ class CEEInfo : public ICorJitInfo public: + struct SignatureContext + { + MethodDesc* methodContext = NULL; + TypeHandle typeContext = TypeHandle(); + + SignatureContext() = default; + + SignatureContext(MethodDesc* pMD) + { + methodContext = pMD; + } + + SignatureContext(MethodDesc* pMD, TypeHandle type) + { + methodContext = pMD; + typeContext = type; + } + + SignatureContext(CEEInfo* pEEInfo, CORINFO_CONTEXT_HANDLE jitContext) + { + methodContext = pEEInfo->GetMethodFromContext(jitContext); + typeContext = pEEInfo->GetTypeFromContext(jitContext); + } + }; + + enum ConvToJitSigFlags : int + { + CONV_TO_JITSIG_FLAGS_NONE = 0x0, + CONV_TO_JITSIG_FLAGS_LOCALSIG = 0x1, + CONV_TO_JITSIG_FLAGS_CHECK_UNMANAGEDCALLERSONLY = 0x2, + }; + //@GENERICS: // The method handle is used to instantiate method and class type parameters // It's also used to determine whether an extra dictionary parameter is required @@ -1128,11 +1160,9 @@ class CEEInfo : public ICorJitInfo DWORD cbSig, CORINFO_MODULE_HANDLE scopeHnd, mdToken token, - CORINFO_SIG_INFO * sigRet, - MethodDesc * context, - bool localSig, - TypeHandle owner = TypeHandle(), - bool checkUnmanagedCallersOnly = false); + SignatureContext context, + ConvToJitSigFlags flags, + CORINFO_SIG_INFO * sigRet); MethodDesc * GetMethodForSecurity(CORINFO_METHOD_HANDLE callerHandle); From 5d839538195432761fab423c6c3b0e7410abedf1 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 7 Dec 2020 15:42:52 -0800 Subject: [PATCH 08/38] Remove invalid assert. --- src/coreclr/src/jit/importer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index 88e60351aaae6..e91c2c5431929 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -1319,7 +1319,6 @@ GenTree* Compiler::impAssignStructPtr(GenTree* destAddr, // The argument list has already been reversed. // Insert the return buffer as the last node so it will be pushed on to the stack last // as required by the native ABI. - assert(srcCall->gtCallType == CT_INDIRECT); GenTreeCall::Use* lastArg = srcCall->gtCallArgs; if (lastArg == nullptr) { From 6fe0f4eb7e72c2627798baa126d824f6cdd8d411 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 7 Dec 2020 15:46:43 -0800 Subject: [PATCH 09/38] Fix up stdcall name mangling lookup. --- src/coreclr/src/debug/daccess/nidump.cpp | 1 - src/coreclr/src/vm/amd64/cgencpu.h | 14 ------- src/coreclr/src/vm/arm/cgencpu.h | 11 ------ src/coreclr/src/vm/arm64/cgencpu.h | 9 ----- src/coreclr/src/vm/dllimport.cpp | 50 ------------------------ src/coreclr/src/vm/i386/cgencpu.h | 15 ------- src/coreclr/src/vm/method.cpp | 6 --- src/coreclr/src/vm/method.hpp | 12 ------ 8 files changed, 118 deletions(-) diff --git a/src/coreclr/src/debug/daccess/nidump.cpp b/src/coreclr/src/debug/daccess/nidump.cpp index e59fc9195954f..0cfa3951ba5ee 100644 --- a/src/coreclr/src/debug/daccess/nidump.cpp +++ b/src/coreclr/src/debug/daccess/nidump.cpp @@ -7350,7 +7350,6 @@ static NativeImageDumper::EnumMnemonics g_NDirectFlags[] = NDF_ENTRY(kStdCall), NDF_ENTRY(kThisCall), NDF_ENTRY(kIsQCall), - NDF_ENTRY(kStdCallWithRetBuf), #undef NDF_ENTRY }; NativeImageDumper::EnumMnemonics NativeImageDumper::s_IMDFlags[] = diff --git a/src/coreclr/src/vm/amd64/cgencpu.h b/src/coreclr/src/vm/amd64/cgencpu.h index 0115cf7acb668..c7ecc88d2c4d2 100644 --- a/src/coreclr/src/vm/amd64/cgencpu.h +++ b/src/coreclr/src/vm/amd64/cgencpu.h @@ -419,20 +419,6 @@ extern "C" void getFPReturn(int fpSize, INT64 *retval); struct ComToManagedExRecord; // defined in cgencpu.cpp -inline BOOL IsUnmanagedValueTypeReturnedByRef(UINT sizeofvaluetype) -{ - LIMITED_METHOD_CONTRACT; - - if (sizeofvaluetype > ENREGISTERED_RETURNTYPE_MAXSIZE) - { - return TRUE; - } - else - { - return FALSE; - } -} - #include struct DECLSPEC_ALIGN(8) UMEntryThunkCode { diff --git a/src/coreclr/src/vm/arm/cgencpu.h b/src/coreclr/src/vm/arm/cgencpu.h index 51cb67acba0de..3739f4ce5dc66 100644 --- a/src/coreclr/src/vm/arm/cgencpu.h +++ b/src/coreclr/src/vm/arm/cgencpu.h @@ -929,17 +929,6 @@ class StubLinkerCPU : public StubLinker extern "C" void SinglecastDelegateInvokeStub(); -// SEH info forward declarations - -inline BOOL IsUnmanagedValueTypeReturnedByRef(UINT sizeofvaluetype) -{ - LIMITED_METHOD_CONTRACT; - - // structure that dont fit in the machine-word size are returned - // by reference. - return (sizeofvaluetype > 4); -} - #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4359) // Prevent "warning C4359: 'UMEntryThunkCode': Alignment specifier is less than actual alignment (8), and will be ignored." in crossbitness scenario diff --git a/src/coreclr/src/vm/arm64/cgencpu.h b/src/coreclr/src/vm/arm64/cgencpu.h index d8b4281073afb..b28ac4d99c9fe 100644 --- a/src/coreclr/src/vm/arm64/cgencpu.h +++ b/src/coreclr/src/vm/arm64/cgencpu.h @@ -338,15 +338,6 @@ inline PCODE decodeBackToBackJump(PCODE pBuffer) return decodeJump(pBuffer); } -// SEH info forward declarations - -inline BOOL IsUnmanagedValueTypeReturnedByRef(UINT sizeofvaluetype) -{ - // ARM64TODO: Does this need to care about HFA. It does not for ARM32 - return (sizeofvaluetype > ENREGISTERED_RETURNTYPE_INTEGER_MAXSIZE); -} - - //---------------------------------------------------------------------- struct IntReg diff --git a/src/coreclr/src/vm/dllimport.cpp b/src/coreclr/src/vm/dllimport.cpp index 11c6b8cded6c2..45801c5c2019b 100644 --- a/src/coreclr/src/vm/dllimport.cpp +++ b/src/coreclr/src/vm/dllimport.cpp @@ -3665,35 +3665,6 @@ static void CreateNDirectStubWorker(StubState* pss, } } - if (marshalType == MarshalInfo::MARSHAL_TYPE_DATE || - marshalType == MarshalInfo::MARSHAL_TYPE_CURRENCY || - marshalType == MarshalInfo::MARSHAL_TYPE_ARRAYWITHOFFSET || - marshalType == MarshalInfo::MARSHAL_TYPE_HANDLEREF || - marshalType == MarshalInfo::MARSHAL_TYPE_ARGITERATOR -#ifdef FEATURE_COMINTEROP - || marshalType == MarshalInfo::MARSHAL_TYPE_OLECOLOR -#endif // FEATURE_COMINTEROP - ) - { - // These are special non-blittable types returned by-ref in managed, - // but marshaled as primitive values returned by-value in unmanaged. - } - else - { - // This is an ordinary value type - see if it is returned by-ref. - TypeHandle retType = msig.GetRetTypeHandleThrowing(); - if (retType.IsValueType() && !retType.IsEnum() && IsUnmanagedValueTypeReturnedByRef(retType.MakeNativeValueType().GetSize())) - { - nativeStackSize += sizeof(LPVOID); - } -#if defined(TARGET_WINDOWS) && !defined(TARGET_ARM) - else if (fThisCall && !retType.IsEnum()) - { - nativeStackSize += sizeof(LPVOID); - } -#endif - } - if (SF_IsHRESULTSwapping(dwStubFlags)) { if (msig.GetReturnType() != ELEMENT_TYPE_VOID) @@ -4229,27 +4200,6 @@ void NDirect::PopulateNDirectMethodDesc(NDirectMethodDesc* pNMD, PInvokeStaticSi pNMD->ndirect.m_pszEntrypointName.SetValueMaybeNull(szEntryPointName); } -#ifdef TARGET_X86 - if (ndirectflags & NDirectMethodDesc::kStdCall) - { - // Compute the kStdCallWithRetBuf flag which is needed at link time for entry point mangling. - MetaSig msig(pNMD); - ArgIterator argit(&msig); - if (argit.HasRetBuffArg()) - { - MethodTable *pRetMT = msig.GetRetTypeHandleThrowing().AsMethodTable(); - // The System.DateTime type itself technically doesn't have a native representation, - // so we have to special-case it here. - // If a type doesn't have a native representation, we won't set this flag. - // We'll throw an exception later when setting up the marshalling. - if (pRetMT != CoreLibBinder::GetClass(CLASS__DATE_TIME) && pRetMT->HasLayout() && IsUnmanagedValueTypeReturnedByRef(pRetMT->GetNativeSize())) - { - ndirectflags |= NDirectMethodDesc::kStdCallWithRetBuf; - } - } - } -#endif // TARGET_X86 - // Call this exactly ONCE per thread. Do not publish incomplete prestub flags // or you will introduce a race condition. pNMD->InterlockedSetNDirectFlags(ndirectflags); diff --git a/src/coreclr/src/vm/i386/cgencpu.h b/src/coreclr/src/vm/i386/cgencpu.h index 0fb8b70deb22f..7a0ef55aec80a 100644 --- a/src/coreclr/src/vm/i386/cgencpu.h +++ b/src/coreclr/src/vm/i386/cgencpu.h @@ -453,21 +453,6 @@ EXTERN_C void __stdcall getFPReturn(int fpSize, INT64 *pretval); // SEH info forward declarations -inline BOOL IsUnmanagedValueTypeReturnedByRef(UINT sizeofvaluetype) -{ - LIMITED_METHOD_CONTRACT; - -#ifndef UNIX_X86_ABI - // odd-sized small structures are not - // enregistered e.g. struct { char a,b,c; } - return (sizeofvaluetype > 8) || - (sizeofvaluetype & (sizeofvaluetype - 1)); // check that the size is power of two -#else - // For UNIX_X86_ABI, we always return the value type by reference regardless of its size - return true; -#endif -} - #include struct DECLSPEC_ALIGN(4) UMEntryThunkCode { diff --git a/src/coreclr/src/vm/method.cpp b/src/coreclr/src/vm/method.cpp index ed6f44e7426ce..1daa37156640c 100644 --- a/src/coreclr/src/vm/method.cpp +++ b/src/coreclr/src/vm/method.cpp @@ -5314,12 +5314,6 @@ FARPROC NDirectMethodDesc::FindEntryPointWithMangling(NATIVE_LIBRARY_HANDLE hMod UINT16 numParamBytesMangle = GetStackArgumentSize(); - if (IsStdCallWithRetBuf()) - { - _ASSERTE(numParamBytesMangle >= sizeof(LPVOID)); - numParamBytesMangle -= (UINT16)sizeof(LPVOID); - } - sprintf_s(szProbedEntrypointName + probedEntrypointNameLength, dstbufsize - probedEntrypointNameLength + 1, "@%lu", (ULONG)numParamBytesMangle); pFunc = GetProcAddress(hMod, szProbedEntrypointName); } diff --git a/src/coreclr/src/vm/method.hpp b/src/coreclr/src/vm/method.hpp index 28c6935212df7..ee1e68567f6ef 100644 --- a/src/coreclr/src/vm/method.hpp +++ b/src/coreclr/src/vm/method.hpp @@ -2963,8 +2963,6 @@ class NDirectMethodDesc : public MethodDesc #if defined(TARGET_X86) // Size of outgoing arguments (on stack). Note that in order to get the @n stdcall name decoration, - // it may be necessary to subtract 4 as the hidden large structure pointer parameter does not count. - // See code:kStdCallWithRetBuf WORD m_cbStackArgumentSize; #endif // defined(TARGET_X86) @@ -3014,9 +3012,6 @@ class NDirectMethodDesc : public MethodDesc kIsQCall = 0x1000, kDefaultDllImportSearchPathsStatus = 0x2000, // either method has custom attribute or not. - - kStdCallWithRetBuf = 0x8000, // Call returns large structure, only valid if kStdCall is also set - }; // Resolve the import to the NDirect target and set it on the NDirectMethodDesc. @@ -3161,13 +3156,6 @@ class NDirectMethodDesc : public MethodDesc return (ndirect.m_DefaultDllImportSearchPathsAttributeValue & 0x2) != 0; } - BOOL IsStdCallWithRetBuf() const - { - LIMITED_METHOD_DAC_CONTRACT; - - return (ndirect.m_wFlags & kStdCallWithRetBuf) != 0; - } - PTR_NDirectWriteableData GetWriteableData() const { LIMITED_METHOD_DAC_CONTRACT; From 2e3fecc83dabcb533fd91eaed6d52720bf2d18f7 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 7 Dec 2020 16:54:12 -0800 Subject: [PATCH 10/38] Fix flag condition. --- src/coreclr/src/vm/jitinterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/vm/jitinterface.cpp b/src/coreclr/src/vm/jitinterface.cpp index a082798a94c8d..dd890e2f27c82 100644 --- a/src/coreclr/src/vm/jitinterface.cpp +++ b/src/coreclr/src/vm/jitinterface.cpp @@ -530,7 +530,7 @@ CEEInfo::ConvToJitSig( } } #if !defined(TARGET_X86) - else if ((flags & CONV_TO_JITSIG_FLAGS_CHECK_UNMANAGEDCALLERSONLY) == 0 + else if ((flags & CONV_TO_JITSIG_FLAGS_CHECK_UNMANAGEDCALLERSONLY) != 0 && sigRet->callConv == CORINFO_CALLCONV_DEFAULT && context.methodContext && context.methodContext->HasUnmanagedCallersOnlyAttribute()) { From e2a9d406b7b65ccea4b23098f9b1e02d2df92076 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 8 Dec 2020 12:14:35 -0800 Subject: [PATCH 11/38] Use the register var type when copying from the register to the stack. --- src/coreclr/jit/codegencommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 3613312f75fcb..d7c0e4313a394 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -11839,9 +11839,9 @@ void CodeGen::genMultiRegStoreToLocal(GenTreeLclVar* lclNode) regNumber varReg = lclNode->GetRegByIndex(i); unsigned fieldLclNum = varDsc->lvFieldLclStart + i; LclVarDsc* fieldVarDsc = compiler->lvaGetDesc(fieldLclNum); - var_types type = fieldVarDsc->TypeGet(); if (varReg != REG_NA) { + var_types type = fieldVarDsc->TypeGet(); hasRegs = true; if (varReg != reg) { From 74a69e5f3f3d794a11a7ffd7ddb191478fb361f6 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 8 Dec 2020 12:15:39 -0800 Subject: [PATCH 12/38] Change flag check for readability. --- src/coreclr/vm/jitinterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 74ffff63dd284..f59d072d697d9 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -530,7 +530,7 @@ CEEInfo::ConvToJitSig( } } #if !defined(TARGET_X86) - else if ((flags & CONV_TO_JITSIG_FLAGS_CHECK_UNMANAGEDCALLERSONLY) != 0 + else if ((flags & CONV_TO_JITSIG_FLAGS_CHECK_UNMANAGEDCALLERSONLY) == CONV_TO_JITSIG_FLAGS_CHECK_UNMANAGEDCALLERSONLY && sigRet->callConv == CORINFO_CALLCONV_DEFAULT && context.methodContext && context.methodContext->HasUnmanagedCallersOnlyAttribute()) { From c12cc51c5c1d64ff1a4f2a65acb7d3d3d019ced4 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 8 Dec 2020 12:19:49 -0800 Subject: [PATCH 13/38] Rename variables to remove shadowing. --- src/coreclr/jit/codegencommon.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index d7c0e4313a394..c78b5a8fcce3c 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -11828,8 +11828,8 @@ void CodeGen::genMultiRegStoreToLocal(GenTreeLclVar* lclNode) } for (unsigned i = 0; i < regCount; ++i) { - regNumber reg = genConsumeReg(op1, i); - var_types type = actualOp1->GetRegTypeByIndex(i); + regNumber reg = genConsumeReg(op1, i); + var_types srcType = actualOp1->GetRegTypeByIndex(i); // genConsumeReg will return the valid register, either from the COPY // or from the original source. assert(reg != REG_NA); @@ -11841,12 +11841,12 @@ void CodeGen::genMultiRegStoreToLocal(GenTreeLclVar* lclNode) LclVarDsc* fieldVarDsc = compiler->lvaGetDesc(fieldLclNum); if (varReg != REG_NA) { - var_types type = fieldVarDsc->TypeGet(); + var_types destType = fieldVarDsc->TypeGet(); hasRegs = true; if (varReg != reg) { // We may need a cross register-file copy here. - inst_RV_RV(ins_Copy(reg, type), varReg, reg, type); + inst_RV_RV(ins_Copy(reg, destType), varReg, reg, destType); } fieldVarDsc->SetRegNum(varReg); } @@ -11858,15 +11858,15 @@ void CodeGen::genMultiRegStoreToLocal(GenTreeLclVar* lclNode) { if (!lclNode->AsLclVar()->IsLastUse(i)) { - GetEmitter()->emitIns_S_R(ins_Store(type), emitTypeSize(type), reg, fieldLclNum, 0); + GetEmitter()->emitIns_S_R(ins_Store(srcType), emitTypeSize(srcType), reg, fieldLclNum, 0); } } fieldVarDsc->SetRegNum(varReg); } else { - GetEmitter()->emitIns_S_R(ins_Store(type), emitTypeSize(type), reg, lclNum, offset); - offset += genTypeSize(type); + GetEmitter()->emitIns_S_R(ins_Store(srcType), emitTypeSize(srcType), reg, lclNum, offset); + offset += genTypeSize(srcType); } } From 6345e3e190c930bff6dde3362a994fd698820bf1 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 8 Dec 2020 14:24:06 -0800 Subject: [PATCH 14/38] Fix formatting. --- src/coreclr/jit/codegencommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index c78b5a8fcce3c..49c24fde21669 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -11842,7 +11842,7 @@ void CodeGen::genMultiRegStoreToLocal(GenTreeLclVar* lclNode) if (varReg != REG_NA) { var_types destType = fieldVarDsc->TypeGet(); - hasRegs = true; + hasRegs = true; if (varReg != reg) { // We may need a cross register-file copy here. From f08c166c1d9c96817daf28bbc242449d42c05016 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 9 Dec 2020 12:57:39 -0800 Subject: [PATCH 15/38] Create new getEntryPointCallConv method on the EE-JIT interface to handle all calling convention resolution and support extensible calling conventions. --- .../superpmi-shared/icorjitinfoimpl.h | 4 + .../superpmi/superpmi-shared/lwmlist.h | 3 +- .../superpmi-shared/methodcontext.cpp | 66 +++- .../superpmi/superpmi-shared/methodcontext.h | 9 +- .../superpmi-shim-collector/icorjitinfo.cpp | 12 + .../superpmi-shim-counter/icorjitinfo.cpp | 8 + .../superpmi-shim-simple/icorjitinfo.cpp | 7 + .../ToolBox/superpmi/superpmi/icorjitinfo.cpp | 10 + src/coreclr/inc/corinfo.h | 28 +- src/coreclr/inc/jiteeversionguid.h | 10 +- src/coreclr/jit/ICorJitInfo_API_names.h | 1 + src/coreclr/jit/ICorJitInfo_API_wrapper.hpp | 10 + src/coreclr/jit/codegencommon.cpp | 6 +- src/coreclr/jit/codegenxarch.cpp | 3 +- src/coreclr/jit/compiler.cpp | 42 ++- src/coreclr/jit/compiler.h | 4 +- src/coreclr/jit/gcencode.cpp | 3 +- src/coreclr/jit/importer.cpp | 43 +-- src/coreclr/jit/lclvars.cpp | 6 +- src/coreclr/jit/lower.cpp | 3 +- src/coreclr/jit/lsrabuild.cpp | 3 +- src/coreclr/jit/morph.cpp | 2 +- src/coreclr/jit/target.h | 18 - .../tools/Common/JitInterface/CorInfoBase.cs | 322 +++++++++--------- .../tools/Common/JitInterface/CorInfoImpl.cs | 101 ++++-- .../tools/Common/JitInterface/CorInfoTypes.cs | 12 + .../ThunkGenerator/ThunkInput.txt | 2 + .../tools/aot/jitinterface/jitinterface.h | 11 + src/coreclr/vm/jitinterface.cpp | 156 +++++++-- src/coreclr/vm/jitinterface.h | 4 +- src/coreclr/zap/zapinfo.cpp | 5 + src/coreclr/zap/zapinfo.h | 1 + 32 files changed, 598 insertions(+), 317 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h index 3089d361e20a4..be9a2238882a9 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h @@ -104,6 +104,10 @@ bool isIntrinsicType( CorInfoUnmanagedCallConv getUnmanagedCallConv( CORINFO_METHOD_HANDLE method); +CorInfoCallConvExtension getEntryPointCallConv( + CORINFO_METHOD_HANDLE method, + CORINFO_SIG_INFO* callSiteSig); + bool pInvokeMarshalingRequired( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h index 8aca1b1634b83..73e9eb3384849 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h @@ -149,12 +149,13 @@ LWM(IsValidToken, DLD, DWORD) LWM(IsValueClass, DWORDLONG, DWORD) LWM(MergeClasses, DLDL, DWORDLONG) LWM(IsMoreSpecificType, DLDL, DWORD) -LWM(PInvokeMarshalingRequired, PInvokeMarshalingRequiredValue, DWORD) +LWM(PInvokeMarshalingRequired, MethodSigInfoPairValue, DWORD) LWM(ResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, ResolveTokenValue) LWM(ResolveVirtualMethod, Agnostic_ResolveVirtualMethodKey, Agnostic_ResolveVirtualMethodResult) LWM(TryResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, TryResolveTokenValue) LWM(SatisfiesClassConstraints, DWORDLONG, DWORD) LWM(SatisfiesMethodConstraints, DLDL, DWORD) +LWM(GetEntryPointCallConv, MethodSigInfoPairValue, DWORD) #undef LWM diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index 00d88a6b10a66..52fa0d8c67f53 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -3771,10 +3771,10 @@ void MethodContext::recPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, bool result) { if (PInvokeMarshalingRequired == nullptr) - PInvokeMarshalingRequired = new LightWeightMap(); + PInvokeMarshalingRequired = new LightWeightMap(); - PInvokeMarshalingRequiredValue key; - ZeroMemory(&key, sizeof(PInvokeMarshalingRequiredValue)); // We use the input structs as a key and use memcmp to + MethodSigInfoPairValue key; + ZeroMemory(&key, sizeof(MethodSigInfoPairValue)); // We use the input structs as a key and use memcmp to // compare.. so we need to zero out padding too key.method = (DWORDLONG)method; @@ -3785,7 +3785,7 @@ void MethodContext::recPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, PInvokeMarshalingRequired->Add(key, (DWORD)result); DEBUG_REC(dmpPInvokeMarshalingRequired(key, (DWORD)result)); } -void MethodContext::dmpPInvokeMarshalingRequired(const PInvokeMarshalingRequiredValue& key, DWORD value) +void MethodContext::dmpPInvokeMarshalingRequired(const MethodSigInfoPairValue& key, DWORD value) { printf("PInvokeMarshalingRequired key mth-%016llX scp-%016llX sig-%u, value res-%u", key.method, key.scope, key.pSig_Index, value); @@ -3796,9 +3796,9 @@ bool MethodContext::repPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, C if (PInvokeMarshalingRequired == nullptr) // so when we replay checked on free, we throw from lwm return TRUE; // TODO-Cleanup: hackish... - PInvokeMarshalingRequiredValue key; - ZeroMemory(&key, sizeof(PInvokeMarshalingRequiredValue)); // We use the input structs as a key and use memcmp to - // compare.. so we need to zero out padding too + MethodSigInfoPairValue key; + ZeroMemory(&key, sizeof(MethodSigInfoPairValue)); // We use the input structs as a key and use memcmp to + // compare.. so we need to zero out padding too key.method = (DWORDLONG)method; key.pSig_Index = (DWORD)PInvokeMarshalingRequired->Contains((unsigned char*)callSiteSig->pSig, callSiteSig->cbSig); @@ -3810,6 +3810,58 @@ bool MethodContext::repPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, C return value; } +void MethodContext::recGetEntryPointCallConv(CORINFO_METHOD_HANDLE method, + CORINFO_SIG_INFO* callSiteSig, + CorInfoCallConvExtension result) +{ + if (GetEntryPointCallConv == nullptr) + GetEntryPointCallConv = new LightWeightMap(); + + MethodSigInfoPairValue key; + ZeroMemory(&key, sizeof(MethodSigInfoPairValue)); // We use the input structs as a key and use memcmp to + // compare.. so we need to zero out padding too + + key.method = (DWORDLONG)method; + key.pSig_Index = (DWORD)PInvokeMarshalingRequired->AddBuffer((unsigned char*)callSiteSig->pSig, callSiteSig->cbSig); + key.cbSig = (DWORD)callSiteSig->cbSig; + key.scope = (DWORDLONG)callSiteSig->scope; + + GetEntryPointCallConv->Add(key, (DWORD)result); + DEBUG_REC(dmpGetEntryPointCallConv(key, (DWORD)result)); +} +void MethodContext::dmpGetEntryPointCallConv(const MethodSigInfoPairValue& key, DWORD value) +{ + printf("GetEntryPointCallConv key mth-%016llX scp-%016llX sig-%u, value res-%u", key.method, key.scope, + key.pSig_Index, value); +} +// Note the jit interface implementation seems to only care about scope and pSig from callSiteSig +CorInfoCallConvExtension MethodContext::repGetEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) +{ + if (GetEntryPointCallConv == nullptr) + { +#ifdef sparseMC + LogDebug("Sparse - repGetEntryPointCallConv returning CorInfoCallConvExtension::Managed"); + return CorInfoCallConvExtension::Managed; +#else + LogException(EXCEPTIONCODE_MC, "Found a null GetUnmGetEntryPointCallConvanagedCallConv. Probably missing a fatTrigger for %016llX.", + (DWORDLONG)method); +#endif + } + + MethodSigInfoPairValue key; + ZeroMemory(&key, sizeof(MethodSigInfoPairValue)); // We use the input structs as a key and use memcmp to + // compare.. so we need to zero out padding too + + key.method = (DWORDLONG)method; + key.pSig_Index = (DWORD)GetEntryPointCallConv->Contains((unsigned char*)callSiteSig->pSig, callSiteSig->cbSig); + key.cbSig = (DWORD)callSiteSig->cbSig; + key.scope = (DWORDLONG)callSiteSig->scope; + + DWORD value = GetEntryPointCallConv->Get(key); + DEBUG_REP(dmpGetEntryPointCallConv(key, value)); + return (CorInfoCallConvExtension)value; +} + void MethodContext::recFindSig(CORINFO_MODULE_HANDLE module, unsigned sigTOK, CORINFO_CONTEXT_HANDLE context, diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h index 1678a1069447a..6ee6392504d30 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h @@ -318,7 +318,7 @@ class MethodContext DWORD sigTOK; DWORDLONG context; }; - struct PInvokeMarshalingRequiredValue + struct MethodSigInfoPairValue { DWORDLONG method; DWORD pSig_Index; @@ -1003,8 +1003,12 @@ class MethodContext CORINFO_CLASS_HANDLE repEmbedClassHandle(CORINFO_CLASS_HANDLE handle, void** ppIndirection); void recPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool result); - void dmpPInvokeMarshalingRequired(const PInvokeMarshalingRequiredValue& key, DWORD value); + void dmpPInvokeMarshalingRequired(const MethodSigInfoPairValue& key, DWORD value); bool repPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); + + void recGetEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, CorInfoCallConvExtension result); + void dmpGetEntryPointCallConv(const MethodSigInfoPairValue& key, DWORD value); + CorInfoCallConvExtension repGetEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); void recFindSig(CORINFO_MODULE_HANDLE module, unsigned sigTOK, @@ -1514,6 +1518,7 @@ enum mcPackets Packet_GetReadyToRunHelper = 150, // Added 10/10/2014 Packet_GetReadyToRunDelegateCtorHelper = 157, // Added 3/30/2016 Packet_GetUnmanagedCallConv = 94, + Packet_GetEntryPointCallConv = 183, // Added 12/8/2020 Packet_GetVarArgsHandle = 95, Packet_GetVars = 96, Packet_HandleException = 135, diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 90462003479c5..50d24b1c695a2 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -298,6 +298,18 @@ CorInfoUnmanagedCallConv interceptor_ICJI::getUnmanagedCallConv(CORINFO_METHOD_H return temp; } +// return the entry point calling convention for any of the following +// - a P/Invoke +// - a method marked with UnmanagedCallersOnly +// - a function pointer with the CORINFO_CALLCONV_UNMANAGED calling convention. +CorInfoCallConvExtension interceptor_ICJI::getEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) +{ + mc->cr->AddCall("getUnmanagedCallConv"); + CorInfoCallConvExtension temp = original_ICorJitInfo->getEntryPointCallConv(method, callSiteSig); + mc->recGetEntryPointCallConv(method, callSiteSig, temp); + return temp; +} + // return if any marshaling is required for PInvoke methods. Note that // method == 0 => calli. The call site sig is only needed for the varargs or calli case bool interceptor_ICJI::pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp index 36a7e280cfa7b..8a2535a52544e 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp @@ -169,6 +169,14 @@ CorInfoUnmanagedCallConv interceptor_ICJI::getUnmanagedCallConv( return original_ICorJitInfo->getUnmanagedCallConv(method); } +CorInfoCallConvExtension interceptor_ICJI::getEntryPointCallConv( + CORINFO_METHOD_HANDLE method, + CORINFO_SIG_INFO* callSiteSig) +{ + mcs->AddCall("getEntryPointCallConv"); + return original_ICorJitInfo->getEntryPointCallConv(method, callSiteSig); +} + bool interceptor_ICJI::pInvokeMarshalingRequired( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp index de8ca59c54813..48e4158d5a88b 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp @@ -150,6 +150,13 @@ CorInfoUnmanagedCallConv interceptor_ICJI::getUnmanagedCallConv( return original_ICorJitInfo->getUnmanagedCallConv(method); } +CorInfoCallConvExtension interceptor_ICJI::getEntryPointCallConv( + CORINFO_METHOD_HANDLE method, + CORINFO_SIG_INFO* callSiteSig) +{ + return original_ICorJitInfo->getEntryPointCallConv(method, callSiteSig); +} + bool interceptor_ICJI::pInvokeMarshalingRequired( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) diff --git a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp index 0bbbd1f0e2532..569e9bbd9e385 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp @@ -225,6 +225,16 @@ CorInfoUnmanagedCallConv MyICJI::getUnmanagedCallConv(CORINFO_METHOD_HANDLE meth return jitInstance->mc->repGetUnmanagedCallConv(method); } +// return the entry point calling convention for any of the following +// - a P/Invoke +// - a method marked with UnmanagedCallersOnly +// - a function pointer with the CORINFO_CALLCONV_UNMANAGED calling convention. +CorInfoCallConvExtension MyICJI::getEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) +{ + jitInstance->mc->cr->AddCall("getEntryPointCallConv"); + return jitInstance->mc->repGetEntryPointCallConv(method, callSiteSig); +} + // return if any marshaling is required for PInvoke methods. Note that // method == 0 => calli. The call site sig is only needed for the varargs or calli case bool MyICJI::pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index b1207b32d25a5..06ef1bdf54145 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -700,8 +700,7 @@ inline bool IsCallerPop(CorInfoCallConv callConv) } #endif // UNIX_X86_ABI -// Represents the calling conventions supported with the extensible calling convention syntax -// as well as the original metadata-encoded calling conventions. +// Represents the original metadata-encoded calling conventions. enum CorInfoUnmanagedCallConv { // These correspond to CorUnmanagedCallingConvention @@ -713,10 +712,22 @@ enum CorInfoUnmanagedCallConv // New calling conventions supported with the extensible calling convention encoding go here. }; +// Represents the calling conventions supported with the extensible calling convention syntax +// as well as the original metadata-encoded calling conventions. +enum class CorInfoCallConvExtension +{ + Managed, + C, + Stdcall, + Thiscall, + Fastcall + // New calling conventions supported with the extensible calling convention encoding go here. +}; + // Determines whether or not this calling convention is an instance method calling convention. -inline bool callConvIsInstanceMethodCallConv(CorInfoUnmanagedCallConv callConv) +inline bool callConvIsInstanceMethodCallConv(CorInfoCallConvExtension callConv) { - return callConv == CORINFO_UNMANAGED_CALLCONV_THISCALL; + return callConv == CorInfoCallConvExtension::Thiscall; } // These are returned from getMethodOptions @@ -2087,6 +2098,15 @@ class ICorStaticInfo CORINFO_METHOD_HANDLE method ) = 0; + // return the entry point calling convention for any of the following + // - a P/Invoke + // - a method marked with UnmanagedCallersOnly + // - a function pointer with the CORINFO_CALLCONV_UNMANAGED calling convention. + virtual CorInfoCallConvExtension getEntryPointCallConv( + CORINFO_METHOD_HANDLE method, + CORINFO_SIG_INFO* callSiteSig + ) = 0; + // return if any marshaling is required for PInvoke methods. Note that // method == 0 => calli. The call site sig is only needed for the varargs or calli case virtual bool pInvokeMarshalingRequired( diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index 88eb44da50c80..1ed1452b15379 100644 --- a/src/coreclr/inc/jiteeversionguid.h +++ b/src/coreclr/inc/jiteeversionguid.h @@ -25,11 +25,11 @@ // ////////////////////////////////////////////////////////////////////////////////////////////////////////// -constexpr GUID JITEEVersionIdentifier = { /* 790de1e5-1426-4ecf-939c-2cd60445c219 */ - 0x790de1e5, - 0x1426, - 0x4ecf, - { 0x93, 0x9c, 0x2c, 0xd6, 0x4, 0x45, 0xc2, 0x19 } +constexpr GUID JITEEVersionIdentifier = { /* {a7bb194e-4e7c-4850-af12-ea9f30ea5a13} */ + 0xa7bb194e, + 0x4e7c, + 0x4850, + {0xaf, 0x12, 0xea, 0x9f, 0x30, 0xea, 0x5a, 0x13} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/jit/ICorJitInfo_API_names.h b/src/coreclr/jit/ICorJitInfo_API_names.h index d9a6719efcd9c..d5968c0daeceb 100644 --- a/src/coreclr/jit/ICorJitInfo_API_names.h +++ b/src/coreclr/jit/ICorJitInfo_API_names.h @@ -23,6 +23,7 @@ DEF_CLR_API(expandRawHandleIntrinsic) DEF_CLR_API(getIntrinsicID) DEF_CLR_API(isIntrinsicType) DEF_CLR_API(getUnmanagedCallConv) +DEF_CLR_API(getEntryPointCallConv) DEF_CLR_API(pInvokeMarshalingRequired) DEF_CLR_API(satisfiesMethodConstraints) DEF_CLR_API(isCompatibleDelegate) diff --git a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp index 9a9723a0c4b54..64dee20a188b4 100644 --- a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp +++ b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp @@ -200,6 +200,16 @@ CorInfoUnmanagedCallConv WrapICorJitInfo::getUnmanagedCallConv( return temp; } +CorInfoCallConvExtension WrapICorJitInfo::getEntryPointCallConv( + CORINFO_METHOD_HANDLE method, + CORINFO_SIG_INFO* callSiteSig) +{ + API_ENTER(getEntryPointCallConv); + CorInfoCallConvExtension temp = wrapHnd->getEntryPointCallConv(method, callSiteSig); + API_LEAVE(getEntryPointCallConv); + return temp; +} + bool WrapICorJitInfo::pInvokeMarshalingRequired( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 49c24fde21669..0ce762c2ed511 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -11534,8 +11534,7 @@ void CodeGen::genReturn(GenTree* treeNode) } else // we must have a struct return type { - CorInfoCallConvExtension callConv = - compiler->compMethodInfoGetEntrypointCallConv(compiler->info.compMethodInfo); + CorInfoCallConvExtension callConv = compiler->info.compCallConv; retTypeDesc.InitializeStructReturnType(compiler, compiler->info.compMethodInfo->args.retTypeClass, callConv); @@ -11664,8 +11663,7 @@ void CodeGen::genStructReturn(GenTree* treeNode) { varDsc = compiler->lvaGetDesc(actualOp1->AsLclVar()->GetLclNum()); retTypeDesc.InitializeStructReturnType(compiler, varDsc->GetStructHnd(), - compiler->compMethodInfoGetEntrypointCallConv( - compiler->info.compMethodInfo)); + compiler->info.compCallConv); assert(varDsc->lvIsMultiRegRet); } else diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 6f1ba9ab9bb8b..648a11223c2e8 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -141,8 +141,7 @@ void CodeGen::genEmitGSCookieCheck(bool pushReg) else // we must have a struct return type { retTypeDesc.InitializeStructReturnType(compiler, compiler->info.compMethodInfo->args.retTypeClass, - compiler->compMethodInfoGetEntrypointCallConv( - compiler->info.compMethodInfo)); + compiler->info.compCallConv); } const unsigned regCount = retTypeDesc.GetReturnRegCount(); diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 4642388b574e4..0683ccbe74bef 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -2057,18 +2057,34 @@ unsigned Compiler::compGetTypeSize(CorInfoType cit, CORINFO_CLASS_HANDLE clsHnd) CorInfoCallConvExtension Compiler::compMethodInfoGetEntrypointCallConv(CORINFO_METHOD_INFO* mthInfo) { - CorInfoCallConv callConv = mthInfo->args.getCallConv(); - if (callConv == CORINFO_CALLCONV_DEFAULT || callConv == CORINFO_CALLCONV_VARARG) + switch (mthInfo->args.getCallConv()) { - // Both the default and the varargs calling conventions represent a managed callconv. - return CorInfoCallConvExtension::Managed; + case CORINFO_CALLCONV_NATIVEVARARG: + return CorInfoCallConvExtension::C; + break; + case CORINFO_CALLCONV_VARARG: + { + CorInfoCallConvExtension callConv = info.compCompHnd->getEntryPointCallConv(mthInfo->ftn, nullptr); + if (callConv != CorInfoCallConvExtension::Managed) + { + callConv = CorInfoCallConvExtension::C; + } + return callConv; + break; + } + case CORINFO_CALLCONV_C: + return CorInfoCallConvExtension::C; + case CORINFO_CALLCONV_STDCALL: + return CorInfoCallConvExtension::Stdcall; + case CORINFO_CALLCONV_THISCALL: + return CorInfoCallConvExtension::Thiscall; + case CORINFO_CALLCONV_UNMANAGED: + case CORINFO_CALLCONV_DEFAULT: + return info.compCompHnd->getEntryPointCallConv(mthInfo->ftn, nullptr); + default: + BADCODE("bad calling convention"); } - - static_assert_no_msg((unsigned)CorInfoCallConvExtension::C == (unsigned)CORINFO_CALLCONV_C); - static_assert_no_msg((unsigned)CorInfoCallConvExtension::Stdcall == (unsigned)CORINFO_CALLCONV_STDCALL); - static_assert_no_msg((unsigned)CorInfoCallConvExtension::Thiscall == (unsigned)CORINFO_CALLCONV_THISCALL); - - return (CorInfoCallConvExtension)callConv; + return CorInfoCallConvExtension::Managed; } #ifdef DEBUG @@ -6108,21 +6124,25 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr, info.compHasNextCallRetAddr = false; + info.compCallConv = compMethodInfoGetEntrypointCallConv(methodInfo); + switch (methodInfo->args.getCallConv()) { - case CORINFO_CALLCONV_VARARG: case CORINFO_CALLCONV_NATIVEVARARG: + case CORINFO_CALLCONV_VARARG: info.compIsVarArgs = true; break; case CORINFO_CALLCONV_C: case CORINFO_CALLCONV_STDCALL: case CORINFO_CALLCONV_THISCALL: + case CORINFO_CALLCONV_UNMANAGED: case CORINFO_CALLCONV_DEFAULT: info.compIsVarArgs = false; break; default: BADCODE("bad calling convention"); } + info.compRetNativeType = info.compRetType = JITtype2varType(methodInfo->args.retType); info.compUnmanagedCallCountWithGCTransition = 0; diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 9306d20631921..8ab703e8d72dc 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -9313,6 +9313,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX UNATIVE_OFFSET compTotalColdCodeSize; // Total number of bytes of Cold Code in the method unsigned compUnmanagedCallCountWithGCTransition; // count of unmanaged calls with GC transition. + + CorInfoCallConvExtension compCallConv; // The entry-point calling convention for this method. unsigned compLvFrameListRoot; // lclNum for the Frame root unsigned compXcptnsCount; // Number of exception-handling clauses read in the method's IL. @@ -9393,7 +9395,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // to be returned in x0. CLANG_FORMAT_COMMENT_ANCHOR; #if defined(TARGET_WINDOWS) && defined(TARGET_ARM64) - auto callConv = compMethodInfoGetEntrypointCallConv(info.compMethodInfo); + auto callConv = info.compCallConv; if (callConvIsInstanceMethodCallConv(callConv)) { return (info.compRetBuffArg != BAD_VAR_NUM); diff --git a/src/coreclr/jit/gcencode.cpp b/src/coreclr/jit/gcencode.cpp index 0147932eb1712..7956525650486 100644 --- a/src/coreclr/jit/gcencode.cpp +++ b/src/coreclr/jit/gcencode.cpp @@ -51,8 +51,7 @@ ReturnKind GCInfo::getReturnKind() { CORINFO_CLASS_HANDLE structType = compiler->info.compMethodInfo->args.retTypeClass; var_types retType = - compiler->getReturnTypeForStruct(structType, compiler->compMethodInfoGetEntrypointCallConv( - compiler->info.compMethodInfo)); + compiler->getReturnTypeForStruct(structType, compiler->info.compCallConv); switch (retType) { diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 57fbb98e5ee9c..fbb570462260a 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -7025,7 +7025,7 @@ bool Compiler::impCanPInvokeInlineCallSite(BasicBlock* block) void Compiler::impCheckForPInvokeCall( GenTreeCall* call, CORINFO_METHOD_HANDLE methHnd, CORINFO_SIG_INFO* sig, unsigned mflags, BasicBlock* block) { - CorInfoUnmanagedCallConv unmanagedCallConv; + CorInfoCallConvExtension unmanagedCallConv; // If VM flagged it as Pinvoke, flag the call node accordingly if ((mflags & CORINFO_FLG_PINVOKE) != 0) @@ -7045,26 +7045,17 @@ void Compiler::impCheckForPInvokeCall( return; } - unmanagedCallConv = info.compCompHnd->getUnmanagedCallConv(methHnd); + unmanagedCallConv = info.compCompHnd->getEntryPointCallConv(methHnd, nullptr); } else { - CorInfoCallConv callConv = CorInfoCallConv(sig->callConv & CORINFO_CALLCONV_MASK); - if (callConv == CORINFO_CALLCONV_NATIVEVARARG) - { - // Used by the IL Stubs. - callConv = CORINFO_CALLCONV_C; - } - static_assert_no_msg((unsigned)CORINFO_CALLCONV_C == (unsigned)CORINFO_UNMANAGED_CALLCONV_C); - static_assert_no_msg((unsigned)CORINFO_CALLCONV_STDCALL == (unsigned)CORINFO_UNMANAGED_CALLCONV_STDCALL); - static_assert_no_msg((unsigned)CORINFO_CALLCONV_THISCALL == (unsigned)CORINFO_UNMANAGED_CALLCONV_THISCALL); - unmanagedCallConv = CorInfoUnmanagedCallConv(callConv); + unmanagedCallConv = info.compCompHnd->getEntryPointCallConv(nullptr, sig); assert(!call->gtCallCookie); } - if (unmanagedCallConv != CORINFO_UNMANAGED_CALLCONV_C && unmanagedCallConv != CORINFO_UNMANAGED_CALLCONV_STDCALL && - unmanagedCallConv != CORINFO_UNMANAGED_CALLCONV_THISCALL) + if (unmanagedCallConv != CorInfoCallConvExtension::C && unmanagedCallConv != CorInfoCallConvExtension::Stdcall && + unmanagedCallConv != CorInfoCallConvExtension::Thiscall) { return; } @@ -7120,24 +7111,20 @@ void Compiler::impCheckForPInvokeCall( JITLOG((LL_INFO1000000, "\nInline a CALLI PINVOKE call from method %s", info.compFullName)); - static_assert_no_msg((unsigned)CorInfoCallConvExtension::C == (unsigned)CORINFO_UNMANAGED_CALLCONV_C); - static_assert_no_msg((unsigned)CorInfoCallConvExtension::Stdcall == (unsigned)CORINFO_UNMANAGED_CALLCONV_STDCALL); - static_assert_no_msg((unsigned)CorInfoCallConvExtension::Thiscall == (unsigned)CORINFO_UNMANAGED_CALLCONV_THISCALL); - call->gtFlags |= GTF_CALL_UNMANAGED; - call->unmgdCallConv = CorInfoCallConvExtension(unmanagedCallConv); + call->unmgdCallConv = unmanagedCallConv; if (!call->IsSuppressGCTransition()) { info.compUnmanagedCallCountWithGCTransition++; } // AMD64 convention is same for native and managed - if (unmanagedCallConv == CORINFO_UNMANAGED_CALLCONV_C) + if (unmanagedCallConv == CorInfoCallConvExtension::C) { call->gtFlags |= GTF_CALL_POP_ARGS; } - if (unmanagedCallConv == CORINFO_UNMANAGED_CALLCONV_THISCALL) + if (unmanagedCallConv == CorInfoCallConvExtension::Thiscall) { call->gtCallMoreFlags |= GTF_CALL_M_UNMGD_THISCALL; } @@ -8913,7 +8900,7 @@ var_types Compiler::impImportCall(OPCODE opcode, if (canTailCall && !impTailCallRetTypeCompatible(info.compRetType, info.compMethodInfo->args.retTypeClass, - compMethodInfoGetEntrypointCallConv(info.compMethodInfo), callRetTyp, + info.compCallConv, callRetTyp, sig->retTypeClass, call->AsCall()->GetUnmanagedCallConv())) { canTailCall = false; @@ -16985,7 +16972,7 @@ bool Compiler::impReturnInstruction(int prefixFlags, OPCODE& opcode) // adjust the type away from struct to integral // and no normalizing op2 = impFixupStructReturnType(op2, retClsHnd, - compMethodInfoGetEntrypointCallConv(info.compMethodInfo)); + info.compCallConv); } else { @@ -17186,7 +17173,7 @@ bool Compiler::impReturnInstruction(int prefixFlags, OPCODE& opcode) #else // defined(UNIX_AMD64_ABI) ReturnTypeDesc retTypeDesc; retTypeDesc.InitializeStructReturnType(this, retClsHnd, - compMethodInfoGetEntrypointCallConv(info.compMethodInfo)); + info.compCallConv); unsigned retRegCount = retTypeDesc.GetReturnRegCount(); if (retRegCount != 0) @@ -17221,7 +17208,7 @@ bool Compiler::impReturnInstruction(int prefixFlags, OPCODE& opcode) #elif defined(TARGET_ARM64) ReturnTypeDesc retTypeDesc; retTypeDesc.InitializeStructReturnType(this, retClsHnd, - compMethodInfoGetEntrypointCallConv(info.compMethodInfo)); + info.compCallConv); unsigned retRegCount = retTypeDesc.GetReturnRegCount(); if (retRegCount != 0) @@ -17246,7 +17233,7 @@ bool Compiler::impReturnInstruction(int prefixFlags, OPCODE& opcode) #elif defined(TARGET_X86) ReturnTypeDesc retTypeDesc; retTypeDesc.InitializeStructReturnType(this, retClsHnd, - compMethodInfoGetEntrypointCallConv(info.compMethodInfo)); + info.compCallConv); unsigned retRegCount = retTypeDesc.GetReturnRegCount(); if (retRegCount != 0) @@ -17335,7 +17322,7 @@ bool Compiler::impReturnInstruction(int prefixFlags, OPCODE& opcode) #if defined(TARGET_WINDOWS) && defined(TARGET_ARM64) // On ARM64, the native instance calling convention variant // requires the implicit ByRef to be explicitly returned. - else if (callConvIsInstanceMethodCallConv(compMethodInfoGetEntrypointCallConv(info.compMethodInfo))) + else if (callConvIsInstanceMethodCallConv(info.compCallConv)) { op1 = gtNewOperNode(GT_RETURN, TYP_BYREF, gtNewLclvNode(info.compRetBuffArg, TYP_BYREF)); } @@ -17354,7 +17341,7 @@ bool Compiler::impReturnInstruction(int prefixFlags, OPCODE& opcode) // Also on System V AMD64 the multireg structs returns are also left as structs. noway_assert(info.compRetNativeType != TYP_STRUCT); #endif - op2 = impFixupStructReturnType(op2, retClsHnd, compMethodInfoGetEntrypointCallConv(info.compMethodInfo)); + op2 = impFixupStructReturnType(op2, retClsHnd, info.compCallConv); // return op2 var_types returnType; if (compDoOldStructRetyping()) diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index 4d8230187e284..b606203595117 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -146,7 +146,7 @@ void Compiler::lvaInitTypeRef() Compiler::structPassingKind howToReturnStruct; var_types returnType = - getReturnTypeForStruct(retClsHnd, compMethodInfoGetEntrypointCallConv(info.compMethodInfo), + getReturnTypeForStruct(retClsHnd, info.compCallConv, &howToReturnStruct); // We can safely widen the return type for enclosed structs. @@ -353,7 +353,7 @@ void Compiler::lvaInitArgs(InitVarDscInfo* varDscInfo) unsigned numUserArgsToSkip = 0; unsigned numUserArgs = info.compMethodInfo->args.numArgs; #if defined(TARGET_WINDOWS) && !defined(TARGET_ARM) - if (callConvIsInstanceMethodCallConv(compMethodInfoGetEntrypointCallConv(info.compMethodInfo))) + if (callConvIsInstanceMethodCallConv(info.compCallConv)) { // If we are a native instance method, handle the first user arg // (the unmanaged this parameter) and then handle the hidden @@ -5349,7 +5349,7 @@ void Compiler::lvaAssignVirtualFrameOffsetsToArgs() // the this parameter comes before the hidden return buffer parameter. // So, we want to process the native "this" parameter before we process // the native return buffer parameter. - if (callConvIsInstanceMethodCallConv(compMethodInfoGetEntrypointCallConv(info.compMethodInfo))) + if (callConvIsInstanceMethodCallConv(info.compCallConv)) { noway_assert(lvaTable[lclNum].lvIsRegArg); #ifndef TARGET_X86 diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 176eac0d15a99..d064c5c817afc 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -3017,8 +3017,7 @@ void Lowering::LowerRet(GenTreeUnOp* ret) LclVarDsc* varDsc = nullptr; varDsc = comp->lvaGetDesc(retVal->AsLclVar()->GetLclNum()); retTypeDesc.InitializeStructReturnType(comp, varDsc->GetStructHnd(), - comp->compMethodInfoGetEntrypointCallConv( - comp->info.compMethodInfo)); + comp->info.compCallConv); if (retTypeDesc.GetReturnRegCount() > 1) { CheckMultiRegLclVar(retVal->AsLclVar(), &retTypeDesc); diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index a0cbf2d5f24a9..ac383e5123185 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -3507,8 +3507,7 @@ int LinearScan::BuildReturn(GenTree* tree) LclVarDsc* varDsc = compiler->lvaGetDesc(op1->AsLclVar()->GetLclNum()); ReturnTypeDesc retTypeDesc; retTypeDesc.InitializeStructReturnType(compiler, varDsc->GetStructHnd(), - compiler->compMethodInfoGetEntrypointCallConv( - compiler->info.compMethodInfo)); + compiler->info.compCallConv); pRetTypeDesc = &retTypeDesc; assert(compiler->lvaGetDesc(op1->AsLclVar()->GetLclNum())->lvFieldCnt == retTypeDesc.GetReturnRegCount()); diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index b00e370c166f5..c01d29f1b328c 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -6829,7 +6829,7 @@ bool Compiler::fgCanFastTailCall(GenTreeCall* callee, const char** failReason) { var_types retType = (compDoOldStructRetyping() ? info.compRetNativeType : info.compRetType); assert(impTailCallRetTypeCompatible(retType, info.compMethodInfo->args.retTypeClass, - compMethodInfoGetEntrypointCallConv(info.compMethodInfo), + info.compCallConv, (var_types)callee->gtReturnType, callee->gtRetClsHnd, callee->GetUnmanagedCallConv())); } diff --git a/src/coreclr/jit/target.h b/src/coreclr/jit/target.h index 5d3e7ad96d14c..633f5dc34d22b 100644 --- a/src/coreclr/jit/target.h +++ b/src/coreclr/jit/target.h @@ -2027,24 +2027,6 @@ typedef target_ssize_t cnsval_ssize_t; typedef target_size_t cnsval_size_t; #endif -// Represents the calling conventions supported with the extensible calling convention syntax -// as well as the original metadata-encoded calling conventions. -enum class CorInfoCallConvExtension -{ - Managed, - C, - Stdcall, - Thiscall, - Fastcall - // New calling conventions supported with the extensible calling convention encoding go here. -}; - -// Determines whether or not this calling convention is an instance method calling convention. -inline bool callConvIsInstanceMethodCallConv(CorInfoCallConvExtension callConv) -{ - return callConv == CorInfoCallConvExtension::Thiscall; -} - /*****************************************************************************/ #endif // TARGET_H_ /*****************************************************************************/ diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs index 1e87eb90e9be3..4ad3dee296069 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs @@ -290,6 +290,21 @@ static CorInfoUnmanagedCallConv _getUnmanagedCallConv(IntPtr thisHandle, IntPtr* } } + [UnmanagedCallersOnly] + static CorInfoCallConvExtension _getEntryPointCallConv(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method, CORINFO_SIG_INFO* callSiteSig) + { + var _this = GetThis(thisHandle); + try + { + return _this.getEntryPointCallConv(method, callSiteSig); + } + catch (Exception ex) + { + *ppException = _this.AllocException(ex); + return default; + } + } + [UnmanagedCallersOnly] static byte _pInvokeMarshalingRequired(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method, CORINFO_SIG_INFO* callSiteSig) { @@ -2536,7 +2551,7 @@ static uint _getJitFlags(IntPtr thisHandle, IntPtr* ppException, CORJIT_FLAGS* f static IntPtr GetUnmanagedCallbacks() { - void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 171); + void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 172); callbacks[0] = (delegate* unmanaged)&_getMethodAttribs; callbacks[1] = (delegate* unmanaged)&_setMethodAttribs; @@ -2557,158 +2572,159 @@ static IntPtr GetUnmanagedCallbacks() callbacks[16] = (delegate* unmanaged)&_getIntrinsicID; callbacks[17] = (delegate* unmanaged)&_isIntrinsicType; callbacks[18] = (delegate* unmanaged)&_getUnmanagedCallConv; - callbacks[19] = (delegate* unmanaged)&_pInvokeMarshalingRequired; - callbacks[20] = (delegate* unmanaged)&_satisfiesMethodConstraints; - callbacks[21] = (delegate* unmanaged)&_isCompatibleDelegate; - callbacks[22] = (delegate* unmanaged)&_methodMustBeLoadedBeforeCodeIsRun; - callbacks[23] = (delegate* unmanaged)&_mapMethodDeclToMethodImpl; - callbacks[24] = (delegate* unmanaged)&_getGSCookie; - callbacks[25] = (delegate* unmanaged)&_setPatchpointInfo; - callbacks[26] = (delegate* unmanaged)&_getOSRInfo; - callbacks[27] = (delegate* unmanaged)&_resolveToken; - callbacks[28] = (delegate* unmanaged)&_tryResolveToken; - callbacks[29] = (delegate* unmanaged)&_findSig; - callbacks[30] = (delegate* unmanaged)&_findCallSiteSig; - callbacks[31] = (delegate* unmanaged)&_getTokenTypeAsHandle; - callbacks[32] = (delegate* unmanaged)&_isValidToken; - callbacks[33] = (delegate* unmanaged)&_isValidStringRef; - callbacks[34] = (delegate* unmanaged)&_getStringLiteral; - callbacks[35] = (delegate* unmanaged)&_asCorInfoType; - callbacks[36] = (delegate* unmanaged)&_getClassName; - callbacks[37] = (delegate* unmanaged)&_getClassNameFromMetadata; - callbacks[38] = (delegate* unmanaged)&_getTypeInstantiationArgument; - callbacks[39] = (delegate* unmanaged)&_appendClassName; - callbacks[40] = (delegate* unmanaged)&_isValueClass; - callbacks[41] = (delegate* unmanaged)&_canInlineTypeCheck; - callbacks[42] = (delegate* unmanaged)&_getClassAttribs; - callbacks[43] = (delegate* unmanaged)&_isStructRequiringStackAllocRetBuf; - callbacks[44] = (delegate* unmanaged)&_getClassModule; - callbacks[45] = (delegate* unmanaged)&_getModuleAssembly; - callbacks[46] = (delegate* unmanaged)&_getAssemblyName; - callbacks[47] = (delegate* unmanaged)&_LongLifetimeMalloc; - callbacks[48] = (delegate* unmanaged)&_LongLifetimeFree; - callbacks[49] = (delegate* unmanaged)&_getClassModuleIdForStatics; - callbacks[50] = (delegate* unmanaged)&_getClassSize; - callbacks[51] = (delegate* unmanaged)&_getHeapClassSize; - callbacks[52] = (delegate* unmanaged)&_canAllocateOnStack; - callbacks[53] = (delegate* unmanaged)&_getClassAlignmentRequirement; - callbacks[54] = (delegate* unmanaged)&_getClassGClayout; - callbacks[55] = (delegate* unmanaged)&_getClassNumInstanceFields; - callbacks[56] = (delegate* unmanaged)&_getFieldInClass; - callbacks[57] = (delegate* unmanaged)&_checkMethodModifier; - callbacks[58] = (delegate* unmanaged)&_getNewHelper; - callbacks[59] = (delegate* unmanaged)&_getNewArrHelper; - callbacks[60] = (delegate* unmanaged)&_getCastingHelper; - callbacks[61] = (delegate* unmanaged)&_getSharedCCtorHelper; - callbacks[62] = (delegate* unmanaged)&_getTypeForBox; - callbacks[63] = (delegate* unmanaged)&_getBoxHelper; - callbacks[64] = (delegate* unmanaged)&_getUnBoxHelper; - callbacks[65] = (delegate* unmanaged)&_getReadyToRunHelper; - callbacks[66] = (delegate* unmanaged)&_getReadyToRunDelegateCtorHelper; - callbacks[67] = (delegate* unmanaged)&_getHelperName; - callbacks[68] = (delegate* unmanaged)&_initClass; - callbacks[69] = (delegate* unmanaged)&_classMustBeLoadedBeforeCodeIsRun; - callbacks[70] = (delegate* unmanaged)&_getBuiltinClass; - callbacks[71] = (delegate* unmanaged)&_getTypeForPrimitiveValueClass; - callbacks[72] = (delegate* unmanaged)&_getTypeForPrimitiveNumericClass; - callbacks[73] = (delegate* unmanaged)&_canCast; - callbacks[74] = (delegate* unmanaged)&_areTypesEquivalent; - callbacks[75] = (delegate* unmanaged)&_compareTypesForCast; - callbacks[76] = (delegate* unmanaged)&_compareTypesForEquality; - callbacks[77] = (delegate* unmanaged)&_mergeClasses; - callbacks[78] = (delegate* unmanaged)&_isMoreSpecificType; - callbacks[79] = (delegate* unmanaged)&_getParentType; - callbacks[80] = (delegate* unmanaged)&_getChildType; - callbacks[81] = (delegate* unmanaged)&_satisfiesClassConstraints; - callbacks[82] = (delegate* unmanaged)&_isSDArray; - callbacks[83] = (delegate* unmanaged)&_getArrayRank; - callbacks[84] = (delegate* unmanaged)&_getArrayInitializationData; - callbacks[85] = (delegate* unmanaged)&_canAccessClass; - callbacks[86] = (delegate* unmanaged)&_getFieldName; - callbacks[87] = (delegate* unmanaged)&_getFieldClass; - callbacks[88] = (delegate* unmanaged)&_getFieldType; - callbacks[89] = (delegate* unmanaged)&_getFieldOffset; - callbacks[90] = (delegate* unmanaged)&_getFieldInfo; - callbacks[91] = (delegate* unmanaged)&_isFieldStatic; - callbacks[92] = (delegate* unmanaged)&_getBoundaries; - callbacks[93] = (delegate* unmanaged)&_setBoundaries; - callbacks[94] = (delegate* unmanaged)&_getVars; - callbacks[95] = (delegate* unmanaged)&_setVars; - callbacks[96] = (delegate* unmanaged)&_allocateArray; - callbacks[97] = (delegate* unmanaged)&_freeArray; - callbacks[98] = (delegate* unmanaged)&_getArgNext; - callbacks[99] = (delegate* unmanaged)&_getArgType; - callbacks[100] = (delegate* unmanaged)&_getArgClass; - callbacks[101] = (delegate* unmanaged)&_getHFAType; - callbacks[102] = (delegate* unmanaged)&_GetErrorHRESULT; - callbacks[103] = (delegate* unmanaged)&_GetErrorMessage; - callbacks[104] = (delegate* unmanaged)&_FilterException; - callbacks[105] = (delegate* unmanaged)&_HandleException; - callbacks[106] = (delegate* unmanaged)&_ThrowExceptionForJitResult; - callbacks[107] = (delegate* unmanaged)&_ThrowExceptionForHelper; - callbacks[108] = (delegate* unmanaged)&_runWithErrorTrap; - callbacks[109] = (delegate* unmanaged)&_getEEInfo; - callbacks[110] = (delegate* unmanaged)&_getJitTimeLogFilename; - callbacks[111] = (delegate* unmanaged)&_getMethodDefFromMethod; - callbacks[112] = (delegate* unmanaged)&_getMethodName; - callbacks[113] = (delegate* unmanaged)&_getMethodNameFromMetadata; - callbacks[114] = (delegate* unmanaged)&_getMethodHash; - callbacks[115] = (delegate* unmanaged)&_findNameOfToken; - callbacks[116] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; - callbacks[117] = (delegate* unmanaged)&_getThreadTLSIndex; - callbacks[118] = (delegate* unmanaged)&_getInlinedCallFrameVptr; - callbacks[119] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; - callbacks[120] = (delegate* unmanaged)&_getHelperFtn; - callbacks[121] = (delegate* unmanaged)&_getFunctionEntryPoint; - callbacks[122] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; - callbacks[123] = (delegate* unmanaged)&_getMethodSync; - callbacks[124] = (delegate* unmanaged)&_getLazyStringLiteralHelper; - callbacks[125] = (delegate* unmanaged)&_embedModuleHandle; - callbacks[126] = (delegate* unmanaged)&_embedClassHandle; - callbacks[127] = (delegate* unmanaged)&_embedMethodHandle; - callbacks[128] = (delegate* unmanaged)&_embedFieldHandle; - callbacks[129] = (delegate* unmanaged)&_embedGenericHandle; - callbacks[130] = (delegate* unmanaged)&_getLocationOfThisType; - callbacks[131] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; - callbacks[132] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; - callbacks[133] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; - callbacks[134] = (delegate* unmanaged)&_getJustMyCodeHandle; - callbacks[135] = (delegate* unmanaged)&_GetProfilingHandle; - callbacks[136] = (delegate* unmanaged)&_getCallInfo; - callbacks[137] = (delegate* unmanaged)&_canAccessFamily; - callbacks[138] = (delegate* unmanaged)&_isRIDClassDomainID; - callbacks[139] = (delegate* unmanaged)&_getClassDomainID; - callbacks[140] = (delegate* unmanaged)&_getFieldAddress; - callbacks[141] = (delegate* unmanaged)&_getStaticFieldCurrentClass; - callbacks[142] = (delegate* unmanaged)&_getVarArgsHandle; - callbacks[143] = (delegate* unmanaged)&_canGetVarArgsHandle; - callbacks[144] = (delegate* unmanaged)&_constructStringLiteral; - callbacks[145] = (delegate* unmanaged)&_emptyStringLiteral; - callbacks[146] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; - callbacks[147] = (delegate* unmanaged)&_setOverride; - callbacks[148] = (delegate* unmanaged)&_addActiveDependency; - callbacks[149] = (delegate* unmanaged)&_GetDelegateCtor; - callbacks[150] = (delegate* unmanaged)&_MethodCompileComplete; - callbacks[151] = (delegate* unmanaged)&_getTailCallHelpers; - callbacks[152] = (delegate* unmanaged)&_convertPInvokeCalliToCall; - callbacks[153] = (delegate* unmanaged)&_notifyInstructionSetUsage; - callbacks[154] = (delegate* unmanaged)&_allocMem; - callbacks[155] = (delegate* unmanaged)&_reserveUnwindInfo; - callbacks[156] = (delegate* unmanaged)&_allocUnwindInfo; - callbacks[157] = (delegate* unmanaged)&_allocGCInfo; - callbacks[158] = (delegate* unmanaged)&_setEHcount; - callbacks[159] = (delegate* unmanaged)&_setEHinfo; - callbacks[160] = (delegate* unmanaged)&_logMsg; - callbacks[161] = (delegate* unmanaged)&_doAssert; - callbacks[162] = (delegate* unmanaged)&_reportFatalError; - callbacks[163] = (delegate* unmanaged)&_allocMethodBlockCounts; - callbacks[164] = (delegate* unmanaged)&_getMethodBlockCounts; - callbacks[165] = (delegate* unmanaged)&_getLikelyClass; - callbacks[166] = (delegate* unmanaged)&_recordCallSite; - callbacks[167] = (delegate* unmanaged)&_recordRelocation; - callbacks[168] = (delegate* unmanaged)&_getRelocTypeHint; - callbacks[169] = (delegate* unmanaged)&_getExpectedTargetArchitecture; - callbacks[170] = (delegate* unmanaged)&_getJitFlags; + callbacks[19] = (delegate* unmanaged)&_getEntryPointCallConv; + callbacks[20] = (delegate* unmanaged)&_pInvokeMarshalingRequired; + callbacks[21] = (delegate* unmanaged)&_satisfiesMethodConstraints; + callbacks[22] = (delegate* unmanaged)&_isCompatibleDelegate; + callbacks[23] = (delegate* unmanaged)&_methodMustBeLoadedBeforeCodeIsRun; + callbacks[24] = (delegate* unmanaged)&_mapMethodDeclToMethodImpl; + callbacks[25] = (delegate* unmanaged)&_getGSCookie; + callbacks[26] = (delegate* unmanaged)&_setPatchpointInfo; + callbacks[27] = (delegate* unmanaged)&_getOSRInfo; + callbacks[28] = (delegate* unmanaged)&_resolveToken; + callbacks[29] = (delegate* unmanaged)&_tryResolveToken; + callbacks[30] = (delegate* unmanaged)&_findSig; + callbacks[31] = (delegate* unmanaged)&_findCallSiteSig; + callbacks[32] = (delegate* unmanaged)&_getTokenTypeAsHandle; + callbacks[33] = (delegate* unmanaged)&_isValidToken; + callbacks[34] = (delegate* unmanaged)&_isValidStringRef; + callbacks[35] = (delegate* unmanaged)&_getStringLiteral; + callbacks[36] = (delegate* unmanaged)&_asCorInfoType; + callbacks[37] = (delegate* unmanaged)&_getClassName; + callbacks[38] = (delegate* unmanaged)&_getClassNameFromMetadata; + callbacks[39] = (delegate* unmanaged)&_getTypeInstantiationArgument; + callbacks[40] = (delegate* unmanaged)&_appendClassName; + callbacks[41] = (delegate* unmanaged)&_isValueClass; + callbacks[42] = (delegate* unmanaged)&_canInlineTypeCheck; + callbacks[43] = (delegate* unmanaged)&_getClassAttribs; + callbacks[44] = (delegate* unmanaged)&_isStructRequiringStackAllocRetBuf; + callbacks[45] = (delegate* unmanaged)&_getClassModule; + callbacks[46] = (delegate* unmanaged)&_getModuleAssembly; + callbacks[47] = (delegate* unmanaged)&_getAssemblyName; + callbacks[48] = (delegate* unmanaged)&_LongLifetimeMalloc; + callbacks[49] = (delegate* unmanaged)&_LongLifetimeFree; + callbacks[50] = (delegate* unmanaged)&_getClassModuleIdForStatics; + callbacks[51] = (delegate* unmanaged)&_getClassSize; + callbacks[52] = (delegate* unmanaged)&_getHeapClassSize; + callbacks[53] = (delegate* unmanaged)&_canAllocateOnStack; + callbacks[54] = (delegate* unmanaged)&_getClassAlignmentRequirement; + callbacks[55] = (delegate* unmanaged)&_getClassGClayout; + callbacks[56] = (delegate* unmanaged)&_getClassNumInstanceFields; + callbacks[57] = (delegate* unmanaged)&_getFieldInClass; + callbacks[58] = (delegate* unmanaged)&_checkMethodModifier; + callbacks[59] = (delegate* unmanaged)&_getNewHelper; + callbacks[60] = (delegate* unmanaged)&_getNewArrHelper; + callbacks[61] = (delegate* unmanaged)&_getCastingHelper; + callbacks[62] = (delegate* unmanaged)&_getSharedCCtorHelper; + callbacks[63] = (delegate* unmanaged)&_getTypeForBox; + callbacks[64] = (delegate* unmanaged)&_getBoxHelper; + callbacks[65] = (delegate* unmanaged)&_getUnBoxHelper; + callbacks[66] = (delegate* unmanaged)&_getReadyToRunHelper; + callbacks[67] = (delegate* unmanaged)&_getReadyToRunDelegateCtorHelper; + callbacks[68] = (delegate* unmanaged)&_getHelperName; + callbacks[69] = (delegate* unmanaged)&_initClass; + callbacks[70] = (delegate* unmanaged)&_classMustBeLoadedBeforeCodeIsRun; + callbacks[71] = (delegate* unmanaged)&_getBuiltinClass; + callbacks[72] = (delegate* unmanaged)&_getTypeForPrimitiveValueClass; + callbacks[73] = (delegate* unmanaged)&_getTypeForPrimitiveNumericClass; + callbacks[74] = (delegate* unmanaged)&_canCast; + callbacks[75] = (delegate* unmanaged)&_areTypesEquivalent; + callbacks[76] = (delegate* unmanaged)&_compareTypesForCast; + callbacks[77] = (delegate* unmanaged)&_compareTypesForEquality; + callbacks[78] = (delegate* unmanaged)&_mergeClasses; + callbacks[79] = (delegate* unmanaged)&_isMoreSpecificType; + callbacks[80] = (delegate* unmanaged)&_getParentType; + callbacks[81] = (delegate* unmanaged)&_getChildType; + callbacks[82] = (delegate* unmanaged)&_satisfiesClassConstraints; + callbacks[83] = (delegate* unmanaged)&_isSDArray; + callbacks[84] = (delegate* unmanaged)&_getArrayRank; + callbacks[85] = (delegate* unmanaged)&_getArrayInitializationData; + callbacks[86] = (delegate* unmanaged)&_canAccessClass; + callbacks[87] = (delegate* unmanaged)&_getFieldName; + callbacks[88] = (delegate* unmanaged)&_getFieldClass; + callbacks[89] = (delegate* unmanaged)&_getFieldType; + callbacks[90] = (delegate* unmanaged)&_getFieldOffset; + callbacks[91] = (delegate* unmanaged)&_getFieldInfo; + callbacks[92] = (delegate* unmanaged)&_isFieldStatic; + callbacks[93] = (delegate* unmanaged)&_getBoundaries; + callbacks[94] = (delegate* unmanaged)&_setBoundaries; + callbacks[95] = (delegate* unmanaged)&_getVars; + callbacks[96] = (delegate* unmanaged)&_setVars; + callbacks[97] = (delegate* unmanaged)&_allocateArray; + callbacks[98] = (delegate* unmanaged)&_freeArray; + callbacks[99] = (delegate* unmanaged)&_getArgNext; + callbacks[100] = (delegate* unmanaged)&_getArgType; + callbacks[101] = (delegate* unmanaged)&_getArgClass; + callbacks[102] = (delegate* unmanaged)&_getHFAType; + callbacks[103] = (delegate* unmanaged)&_GetErrorHRESULT; + callbacks[104] = (delegate* unmanaged)&_GetErrorMessage; + callbacks[105] = (delegate* unmanaged)&_FilterException; + callbacks[106] = (delegate* unmanaged)&_HandleException; + callbacks[107] = (delegate* unmanaged)&_ThrowExceptionForJitResult; + callbacks[108] = (delegate* unmanaged)&_ThrowExceptionForHelper; + callbacks[109] = (delegate* unmanaged)&_runWithErrorTrap; + callbacks[110] = (delegate* unmanaged)&_getEEInfo; + callbacks[111] = (delegate* unmanaged)&_getJitTimeLogFilename; + callbacks[112] = (delegate* unmanaged)&_getMethodDefFromMethod; + callbacks[113] = (delegate* unmanaged)&_getMethodName; + callbacks[114] = (delegate* unmanaged)&_getMethodNameFromMetadata; + callbacks[115] = (delegate* unmanaged)&_getMethodHash; + callbacks[116] = (delegate* unmanaged)&_findNameOfToken; + callbacks[117] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; + callbacks[118] = (delegate* unmanaged)&_getThreadTLSIndex; + callbacks[119] = (delegate* unmanaged)&_getInlinedCallFrameVptr; + callbacks[120] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; + callbacks[121] = (delegate* unmanaged)&_getHelperFtn; + callbacks[122] = (delegate* unmanaged)&_getFunctionEntryPoint; + callbacks[123] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; + callbacks[124] = (delegate* unmanaged)&_getMethodSync; + callbacks[125] = (delegate* unmanaged)&_getLazyStringLiteralHelper; + callbacks[126] = (delegate* unmanaged)&_embedModuleHandle; + callbacks[127] = (delegate* unmanaged)&_embedClassHandle; + callbacks[128] = (delegate* unmanaged)&_embedMethodHandle; + callbacks[129] = (delegate* unmanaged)&_embedFieldHandle; + callbacks[130] = (delegate* unmanaged)&_embedGenericHandle; + callbacks[131] = (delegate* unmanaged)&_getLocationOfThisType; + callbacks[132] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; + callbacks[133] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; + callbacks[134] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; + callbacks[135] = (delegate* unmanaged)&_getJustMyCodeHandle; + callbacks[136] = (delegate* unmanaged)&_GetProfilingHandle; + callbacks[137] = (delegate* unmanaged)&_getCallInfo; + callbacks[138] = (delegate* unmanaged)&_canAccessFamily; + callbacks[139] = (delegate* unmanaged)&_isRIDClassDomainID; + callbacks[140] = (delegate* unmanaged)&_getClassDomainID; + callbacks[141] = (delegate* unmanaged)&_getFieldAddress; + callbacks[142] = (delegate* unmanaged)&_getStaticFieldCurrentClass; + callbacks[143] = (delegate* unmanaged)&_getVarArgsHandle; + callbacks[144] = (delegate* unmanaged)&_canGetVarArgsHandle; + callbacks[145] = (delegate* unmanaged)&_constructStringLiteral; + callbacks[146] = (delegate* unmanaged)&_emptyStringLiteral; + callbacks[147] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; + callbacks[148] = (delegate* unmanaged)&_setOverride; + callbacks[149] = (delegate* unmanaged)&_addActiveDependency; + callbacks[150] = (delegate* unmanaged)&_GetDelegateCtor; + callbacks[151] = (delegate* unmanaged)&_MethodCompileComplete; + callbacks[152] = (delegate* unmanaged)&_getTailCallHelpers; + callbacks[153] = (delegate* unmanaged)&_convertPInvokeCalliToCall; + callbacks[154] = (delegate* unmanaged)&_notifyInstructionSetUsage; + callbacks[155] = (delegate* unmanaged)&_allocMem; + callbacks[156] = (delegate* unmanaged)&_reserveUnwindInfo; + callbacks[157] = (delegate* unmanaged)&_allocUnwindInfo; + callbacks[158] = (delegate* unmanaged)&_allocGCInfo; + callbacks[159] = (delegate* unmanaged)&_setEHcount; + callbacks[160] = (delegate* unmanaged)&_setEHinfo; + callbacks[161] = (delegate* unmanaged)&_logMsg; + callbacks[162] = (delegate* unmanaged)&_doAssert; + callbacks[163] = (delegate* unmanaged)&_reportFatalError; + callbacks[164] = (delegate* unmanaged)&_allocMethodBlockCounts; + callbacks[165] = (delegate* unmanaged)&_getMethodBlockCounts; + callbacks[166] = (delegate* unmanaged)&_getLikelyClass; + callbacks[167] = (delegate* unmanaged)&_recordCallSite; + callbacks[168] = (delegate* unmanaged)&_recordRelocation; + callbacks[169] = (delegate* unmanaged)&_getRelocTypeHint; + callbacks[170] = (delegate* unmanaged)&_getExpectedTargetArchitecture; + callbacks[171] = (delegate* unmanaged)&_getJitFlags; return (IntPtr)callbacks; } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 4df942bb98ee2..6ab916b96838a 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -476,13 +476,13 @@ private bool Get_CORINFO_METHOD_INFO(MethodDesc method, MethodIL methodIL, CORIN methodInfo->options |= CorInfoOptions.CORINFO_GENERICS_CTXT_FROM_METHODTABLE; } methodInfo->regionKind = CorInfoRegionKind.CORINFO_REGION_NONE; - Get_CORINFO_SIG_INFO(method, &methodInfo->args, checkUnmanagedCallersOnly: true); + Get_CORINFO_SIG_INFO(method, &methodInfo->args); Get_CORINFO_SIG_INFO(methodIL.GetLocals(), &methodInfo->locals); return true; } - private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, bool suppressHiddenArgument = false, bool checkUnmanagedCallersOnly = false) + private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, bool suppressHiddenArgument = false) { Get_CORINFO_SIG_INFO(method.Signature, sig); @@ -522,16 +522,11 @@ private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, bool { sig->callConv |= CorInfoCallConv.CORINFO_CALLCONV_PARAMTYPE; } - else if (checkUnmanagedCallersOnly && method.IsUnmanagedCallersOnly) - { - CustomAttributeValue unmanagedCallersOnlyAttribute = ((EcmaMethod)method).GetDecodedCustomAttribute("System.Runtime.InteropServices", "UnmanagedCallersOnlyAttribute").Value; - sig->callConv = GetUnmanagedCallingConventionFromAttribute(unmanagedCallersOnlyAttribute); - } } - private CorInfoCallConv GetUnmanagedCallingConventionFromAttribute(CustomAttributeValue unmanagedCallersOnlyAttribute) + private CorInfoCallConvExtension GetUnmanagedCallingConventionFromAttribute(CustomAttributeValue unmanagedCallersOnlyAttribute) { - CorInfoCallConv callConv = (CorInfoCallConv)PlatformDefaultUnmanagedCallingConvention(); + CorInfoCallConvExtension callConv = (CorInfoCallConvExtension)PlatformDefaultUnmanagedCallingConvention(); ImmutableArray> callConvArray = default; foreach (var arg in unmanagedCallersOnlyAttribute.NamedArguments) @@ -557,7 +552,7 @@ private CorInfoCallConv GetUnmanagedCallingConventionFromAttribute(CustomAttribu if (defType.Namespace != "System.Runtime.CompilerServices") continue; - CorInfoCallConv? callConvLocal = GetCallingConventionForCallConvType(defType); + CorInfoCallConvExtension? callConvLocal = GetCallingConventionForCallConvType(defType); if (callConvLocal.HasValue) { @@ -572,9 +567,9 @@ private CorInfoCallConv GetUnmanagedCallingConventionFromAttribute(CustomAttribu return callConv; } - private bool TryGetUnmanagedCallingConventionFromModOpt(MethodSignature signature, out CorInfoCallConv callConv) + private bool TryGetUnmanagedCallingConventionFromModOpt(MethodSignature signature, out CorInfoCallConvExtension callConv) { - callConv = CorInfoCallConv.CORINFO_CALLCONV_UNMANAGED; + callConv = CorInfoCallConvExtension.Managed; if (!signature.HasEmbeddedSignatureData || signature.GetEmbeddedSignatureData() == null) return false; @@ -595,7 +590,7 @@ private bool TryGetUnmanagedCallingConventionFromModOpt(MethodSignature signatur if (defType.Namespace != "System.Runtime.CompilerServices") continue; - CorInfoCallConv? callConvLocal = GetCallingConventionForCallConvType(defType); + CorInfoCallConvExtension? callConvLocal = GetCallingConventionForCallConvType(defType); if (callConvLocal.HasValue) { @@ -611,14 +606,14 @@ private bool TryGetUnmanagedCallingConventionFromModOpt(MethodSignature signatur return found; } - private static CorInfoCallConv? GetCallingConventionForCallConvType(DefType defType) => + private static CorInfoCallConvExtension? GetCallingConventionForCallConvType(DefType defType) => // Look for a recognized calling convention in metadata. defType.Name switch { - "CallConvCdecl" => CorInfoCallConv.CORINFO_CALLCONV_C, - "CallConvStdcall" => CorInfoCallConv.CORINFO_CALLCONV_STDCALL, - "CallConvFastcall" => CorInfoCallConv.CORINFO_CALLCONV_FASTCALL, - "CallConvThiscall" => CorInfoCallConv.CORINFO_CALLCONV_THISCALL, + "CallConvCdecl" => CorInfoCallConvExtension.C, + "CallConvStdcall" => CorInfoCallConvExtension.Stdcall, + "CallConvFastcall" => CorInfoCallConvExtension.Fastcall, + "CallConvThiscall" => CorInfoCallConvExtension.Thiscall, _ => null }; @@ -632,19 +627,6 @@ private void Get_CORINFO_SIG_INFO(MethodSignature signature, CORINFO_SIG_INFO* s if (!signature.IsStatic) sig->callConv |= CorInfoCallConv.CORINFO_CALLCONV_HASTHIS; - // Unmanaged calling convention indicates modopt should be read - if (sig->callConv == CorInfoCallConv.CORINFO_CALLCONV_UNMANAGED) - { - if (TryGetUnmanagedCallingConventionFromModOpt(signature, out CorInfoCallConv callConvMaybe)) - { - sig->callConv = callConvMaybe; - } - else - { - sig->callConv = (CorInfoCallConv)PlatformDefaultUnmanagedCallingConvention(); - } - } - TypeDesc returnType = signature.ReturnType; CorInfoType corInfoRetType = asCorInfoType(signature.ReturnType, &sig->retTypeClass); @@ -1095,6 +1077,60 @@ private CorInfoUnmanagedCallConv getUnmanagedCallConv(CORINFO_METHOD_STRUCT_* me return (CorInfoUnmanagedCallConv)unmanagedCallConv; } + private CorInfoCallConvExtension getEntryPointCallConv(CORINFO_METHOD_STRUCT_* method, CORINFO_SIG_INFO* sig) + { + Debug.Assert(method != null || sig != null); + if (method != null) + { + MethodDesc methodDesc = HandleToObject(method); + if (methodDesc.IsPInvoke) + { + MethodSignatureFlags unmanagedCallConv = HandleToObject(method).GetPInvokeMethodMetadata().Flags.UnmanagedCallingConvention; + + if (unmanagedCallConv == MethodSignatureFlags.None) + unmanagedCallConv = PlatformDefaultUnmanagedCallingConvention(); + + // Verify that it is safe to convert MethodSignatureFlags.UnmanagedCallingConvention to CorInfoCallConvExtension via a simple cast + Debug.Assert((int)CorInfoCallConvExtension.C == (int)MethodSignatureFlags.UnmanagedCallingConventionCdecl); + Debug.Assert((int)CorInfoCallConvExtension.Stdcall == (int)MethodSignatureFlags.UnmanagedCallingConventionStdCall); + Debug.Assert((int)CorInfoCallConvExtension.Thiscall == (int)MethodSignatureFlags.UnmanagedCallingConventionThisCall); + + return (CorInfoCallConvExtension)unmanagedCallConv; + } + else if (methodDesc.IsUnmanagedCallersOnly) + { + CustomAttributeValue unmanagedCallersOnlyAttribute = ((EcmaMethod)methodDesc).GetDecodedCustomAttribute("System.Runtime.InteropServices", "UnmanagedCallersOnlyAttribute").Value; + return GetUnmanagedCallingConventionFromAttribute(unmanagedCallersOnlyAttribute); + } + return CorInfoCallConvExtension.Managed; + } // Unmanaged calling convention indicates modopt should be read + else if (sig->callConv == CorInfoCallConv.CORINFO_CALLCONV_UNMANAGED) + { + if (TryGetUnmanagedCallingConventionFromModOpt((MethodSignature)HandleToObject((IntPtr)sig->pSig), out CorInfoCallConvExtension callConvMaybe)) + { + return callConvMaybe; + } + else + { + return (CorInfoCallConvExtension)PlatformDefaultUnmanagedCallingConvention(); + } + } + else if ((sig->callConv & CorInfoCallConv.CORINFO_CALLCONV_MASK) == CorInfoCallConv.CORINFO_CALLCONV_NATIVEVARARG) + { + return CorInfoCallConvExtension.C; + } + else if ((sig->callConv & CorInfoCallConv.CORINFO_CALLCONV_MASK) == CorInfoCallConv.CORINFO_CALLCONV_VARARG) + { + return CorInfoCallConvExtension.Managed; + } + + // Verify that it is safe to convert CORINFO_CALLCONV_* for unmanaged calling conventions to CorInfoCallConvExtension via a simple cast + Debug.Assert((int)CorInfoCallConvExtension.C == (int)CorInfoCallConv.CORINFO_CALLCONV_C); + Debug.Assert((int)CorInfoCallConvExtension.Stdcall == (int)CorInfoCallConv.CORINFO_CALLCONV_STDCALL); + Debug.Assert((int)CorInfoCallConvExtension.Thiscall == (int)CorInfoCallConv.CORINFO_CALLCONV_THISCALL); + return (CorInfoCallConvExtension)(sig->callConv & CorInfoCallConv.CORINFO_CALLCONV_MASK); + } + private bool satisfiesMethodConstraints(CORINFO_CLASS_STRUCT_* parent, CORINFO_METHOD_STRUCT_* method) { throw new NotImplementedException("satisfiesMethodConstraints"); } private bool isCompatibleDelegate(CORINFO_CLASS_STRUCT_* objCls, CORINFO_CLASS_STRUCT_* methodParentCls, CORINFO_METHOD_STRUCT_* method, CORINFO_CLASS_STRUCT_* delegateCls, ref bool pfIsOpenDelegate) @@ -1342,9 +1378,6 @@ private void findSig(CORINFO_MODULE_STRUCT_* module, uint sigTOK, CORINFO_CONTEX Get_CORINFO_SIG_INFO(methodSig, sig); - // CORINFO_CALLCONV_UNMANAGED is handled by Get_CORINFO_SIG_INFO - Debug.Assert(sig->callConv != CorInfoCallConv.CORINFO_CALLCONV_UNMANAGED); - // TODO: Replace this with a public mechanism to mark calli with SuppressGCTransition once it becomes available. if (methodIL is PInvokeILStubMethodIL stubIL) { diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index d3a627cf1535c..2848c0aa596e7 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -342,6 +342,18 @@ public enum CorInfoUnmanagedCallConv CORINFO_UNMANAGED_CALLCONV_THISCALL, CORINFO_UNMANAGED_CALLCONV_FASTCALL } + + // Represents the calling conventions supported with the extensible calling convention syntax + // as well as the original metadata-encoded calling conventions. + enum CorInfoCallConvExtension + { + Managed, + C, + Stdcall, + Thiscall, + Fastcall + // New calling conventions supported with the extensible calling convention encoding go here. + } public enum CORINFO_CALLINFO_FLAGS { diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index f83c4924ca240..9b3c3b018869d 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -124,6 +124,7 @@ CorInfoType,,int CorInfoHFAElemType,,int CorInfoTypeWithMod,,int CorInfoUnmanagedCallConv,,int +CorInfoCallConvExtension,,int InfoAccessType,,int CORINFO_LOOKUP_KIND CORINFO_ACCESS_FLAGS,,int @@ -177,6 +178,7 @@ FUNCTIONS CorInfoIntrinsics getIntrinsicID( CORINFO_METHOD_HANDLE method , BoolStar pMustExpand); bool isIntrinsicType( CORINFO_CLASS_HANDLE classHnd ); CorInfoUnmanagedCallConv getUnmanagedCallConv( CORINFO_METHOD_HANDLE method ); + CorInfoCallConvExtension getEntryPointCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); bool pInvokeMarshalingRequired( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig ); bool satisfiesMethodConstraints( CORINFO_CLASS_HANDLE parent, CORINFO_METHOD_HANDLE method ); bool isCompatibleDelegate( CORINFO_CLASS_HANDLE objCls, CORINFO_CLASS_HANDLE methodParentCls, CORINFO_METHOD_HANDLE method, CORINFO_CLASS_HANDLE delegateCls, bool *pfIsOpenDelegate ); diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface.h b/src/coreclr/tools/aot/jitinterface/jitinterface.h index fa2c9e7169998..0619019d9dcf0 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface.h @@ -29,6 +29,7 @@ struct JitInterfaceCallbacks int (* getIntrinsicID)(void * thisHandle, CorInfoExceptionClass** ppException, void* method, bool* pMustExpand); bool (* isIntrinsicType)(void * thisHandle, CorInfoExceptionClass** ppException, void* classHnd); int (* getUnmanagedCallConv)(void * thisHandle, CorInfoExceptionClass** ppException, void* method); + int (* getEntryPointCallConv)(void * thisHandle, CorInfoExceptionClass** ppException, void* method, void* callSiteSig); bool (* pInvokeMarshalingRequired)(void * thisHandle, CorInfoExceptionClass** ppException, void* method, void* callSiteSig); bool (* satisfiesMethodConstraints)(void * thisHandle, CorInfoExceptionClass** ppException, void* parent, void* method); bool (* isCompatibleDelegate)(void * thisHandle, CorInfoExceptionClass** ppException, void* objCls, void* methodParentCls, void* method, void* delegateCls, bool* pfIsOpenDelegate); @@ -384,6 +385,16 @@ class JitInterfaceWrapper return temp; } + virtual int getEntryPointCallConv( + void* method, + void* callSiteSig) +{ + CorInfoExceptionClass* pException = nullptr; + int temp = _callbacks->getEntryPointCallConv(_thisHandle, &pException, method, callSiteSig); + if (pException != nullptr) throw pException; + return temp; +} + virtual bool pInvokeMarshalingRequired( void* method, void* callSiteSig) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index f59d072d697d9..64221988456a4 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -529,41 +529,6 @@ CEEInfo::ConvToJitSig( sigRet->callConv = (CorInfoCallConv)MetaSig::GetDefaultUnmanagedCallingConvention(); } } -#if !defined(TARGET_X86) - else if ((flags & CONV_TO_JITSIG_FLAGS_CHECK_UNMANAGEDCALLERSONLY) == CONV_TO_JITSIG_FLAGS_CHECK_UNMANAGEDCALLERSONLY - && sigRet->callConv == CORINFO_CALLCONV_DEFAULT - && context.methodContext && context.methodContext->HasUnmanagedCallersOnlyAttribute()) - { -#ifdef CROSSGEN_COMPILE - _ASSERTE_MSG(false, "UnmanagedCallersOnly methods are not supported in crossgen and should be rejected before getting here."); -#else - CorPinvokeMap unmanagedCallConv; - if (TryGetCallingConventionFromUnmanagedCallersOnly(context.methodContext, &unmanagedCallConv)) - { - switch (unmanagedCallConv) - { - case pmCallConvWinapi: - sigRet->callConv = (CorInfoCallConv)MetaSig::GetDefaultUnmanagedCallingConvention(); - break; - case pmCallConvCdecl: - sigRet->callConv = CORINFO_CALLCONV_C; - break; - case pmCallConvStdcall: - sigRet->callConv = CORINFO_CALLCONV_STDCALL; - break; - case pmCallConvThiscall: - sigRet->callConv = CORINFO_CALLCONV_THISCALL; - break; - case pmCallConvFastcall: - sigRet->callConv = CORINFO_CALLCONV_FASTCALL; - break; - default: - break; - } - } -#endif - } -#endif // Skip number of type arguments if (sigRet->callConv & IMAGE_CEE_CS_CALLCONV_GENERIC) @@ -7792,7 +7757,7 @@ getMethodInfoHelper( GetScopeHandle(ftn), mdTokenNil, CEEInfo::SignatureContext(ftn), - CEEInfo::CONV_TO_JITSIG_FLAGS_CHECK_UNMANAGEDCALLERSONLY, + CEEInfo::CONV_TO_JITSIG_FLAGS_NONE, &methInfo->args); // Shared generic or static per-inst methods and shared methods on generic structs @@ -9881,6 +9846,125 @@ CorInfoUnmanagedCallConv CEEInfo::getUnmanagedCallConv(CORINFO_METHOD_HANDLE met return result; } +/*********************************************************************/ + + // return the entry point calling convention for any of the following + // - a P/Invoke + // - a method marked with UnmanagedCallersOnly + // - a function pointer with the CORINFO_CALLCONV_UNMANAGED calling convention. +CorInfoCallConvExtension CEEInfo::getEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) +{ + CONTRACTL { + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } CONTRACTL_END; + + CorInfoCallConvExtension callConv = CorInfoCallConvExtension::Managed; + + JIT_TO_EE_TRANSITION(); + + _ASSERTE(method != nullptr || callSiteSig != nullptr); + + if (method) + { + MethodDesc* pMD = GetMethod(method); + if(pMD->IsNDirect()) + { + EX_TRY + { + PInvokeStaticSigInfo sigInfo(pMD, PInvokeStaticSigInfo::NO_THROW_ON_ERROR); + + switch (sigInfo.GetCallConv()) { + case pmCallConvCdecl: + callConv = CorInfoCallConvExtension::C; + break; + case pmCallConvStdcall: + callConv = CorInfoCallConvExtension::Stdcall; + break; + case pmCallConvThiscall: + callConv = CorInfoCallConvExtension::Thiscall; + break; + default: + callConv = CorInfoCallConvExtension::Managed; + break; + } + } + EX_CATCH + { + callConv = CorInfoCallConvExtension::Managed; + } + EX_END_CATCH(SwallowAllExceptions) + } +#if !defined(TARGET_X86) + else if (pMD->HasUnmanagedCallersOnlyAttribute()) + { +#ifdef CROSSGEN_COMPILE + _ASSERTE_MSG(false, "UnmanagedCallersOnly methods are not supported in crossgen and should be rejected before getting here."); +#else + CorPinvokeMap unmanagedCallConv; + if (TryGetCallingConventionFromUnmanagedCallersOnly(pMD, &unmanagedCallConv)) + { + switch (unmanagedCallConv) + { + case pmCallConvWinapi: + callConv = (CorInfoCallConvExtension)MetaSig::GetDefaultUnmanagedCallingConvention(); + break; + case pmCallConvCdecl: + callConv = CorInfoCallConvExtension::C; + break; + case pmCallConvStdcall: + callConv = CorInfoCallConvExtension::Stdcall; + break; + case pmCallConvThiscall: + callConv = CorInfoCallConvExtension::Thiscall; + break; + case pmCallConvFastcall: + callConv = CorInfoCallConvExtension::Fastcall; + break; + default: + break; + } + } +#endif // CROSSGEN_COMPILE + } +#endif // !defined(TARGET_X86) + } + else if (callSiteSig->callConv == CORINFO_CALLCONV_UNMANAGED) + { + CorUnmanagedCallingConvention callConvMaybe; + UINT errorResID; + HRESULT hr = MetaSig::TryGetUnmanagedCallingConventionFromModOpt(GetModule(callSiteSig->scope), callSiteSig->pSig, callSiteSig->cbSig, &callConvMaybe, &errorResID); + if (FAILED(hr)) + COMPlusThrowHR(hr, errorResID); + + if (hr == S_OK) + { + callConv = (CorInfoCallConvExtension)callConvMaybe; + } + else + { + callConv = (CorInfoCallConvExtension)MetaSig::GetDefaultUnmanagedCallingConvention(); + } + } + else if ((callSiteSig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_NATIVEVARARG) + { + callConv = CorInfoCallConvExtension::C; + } + else if ((callSiteSig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_VARARG) + { + callConv = CorInfoCallConvExtension::Managed; + } + else + { + callConv = (CorInfoCallConvExtension)(callSiteSig->callConv & CORINFO_CALLCONV_MASK); + } + + EE_TO_JIT_TRANSITION(); + + return callConv; +} + /*********************************************************************/ bool CEEInfo::pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) { diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index bd12bbf50d66d..eafd33ddee98e 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -758,6 +758,9 @@ class CEEInfo : public ICorJitInfo bool isIntrinsicType(CORINFO_CLASS_HANDLE classHnd); CorInfoUnmanagedCallConv getUnmanagedCallConv(CORINFO_METHOD_HANDLE method); + + CorInfoCallConvExtension getEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); + bool pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); // Generate a cookie based on the signature that would needs to be passed @@ -1138,7 +1141,6 @@ class CEEInfo : public ICorJitInfo { CONV_TO_JITSIG_FLAGS_NONE = 0x0, CONV_TO_JITSIG_FLAGS_LOCALSIG = 0x1, - CONV_TO_JITSIG_FLAGS_CHECK_UNMANAGEDCALLERSONLY = 0x2, }; //@GENERICS: diff --git a/src/coreclr/zap/zapinfo.cpp b/src/coreclr/zap/zapinfo.cpp index da2ef94649e64..355b9277ba0bc 100644 --- a/src/coreclr/zap/zapinfo.cpp +++ b/src/coreclr/zap/zapinfo.cpp @@ -4050,6 +4050,11 @@ CorInfoUnmanagedCallConv ZapInfo::getUnmanagedCallConv(CORINFO_METHOD_HANDLE met return m_pEEJitInfo->getUnmanagedCallConv(method); } +CorInfoCallConvExtension ZapInfo::getEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) +{ + return m_pEEJitInfo->getEntryPointCallConv(method, sig); +} + bool ZapInfo::pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { diff --git a/src/coreclr/zap/zapinfo.h b/src/coreclr/zap/zapinfo.h index 8514cce6ccb29..e8fb8d1976a0a 100644 --- a/src/coreclr/zap/zapinfo.h +++ b/src/coreclr/zap/zapinfo.h @@ -692,6 +692,7 @@ class ZapInfo bool * pMustExpand = NULL); bool isIntrinsicType(CORINFO_CLASS_HANDLE classHnd); CorInfoUnmanagedCallConv getUnmanagedCallConv(CORINFO_METHOD_HANDLE method); + CorInfoCallConvExtension getEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); bool pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); LPVOID GetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void ** ppIndirecton); From e598176b55129be62d96e8222235f3ad91dcc5d1 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 9 Dec 2020 14:48:11 -0800 Subject: [PATCH 16/38] Remove unreachable code. --- src/coreclr/jit/compiler.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 0683ccbe74bef..04587a902bd8d 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -2084,7 +2084,6 @@ CorInfoCallConvExtension Compiler::compMethodInfoGetEntrypointCallConv(CORINFO_M default: BADCODE("bad calling convention"); } - return CorInfoCallConvExtension::Managed; } #ifdef DEBUG From 8ea0869a2c5c8cd4a8564404f623b8dca39e6c24 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 9 Dec 2020 15:13:55 -0800 Subject: [PATCH 17/38] Remove now unused getUnmanagedCallConv jitinterface method (replaced by getEntryPointCallConv). --- .../superpmi-shared/icorjitinfoimpl.h | 3 - .../superpmi/superpmi-shared/lwmlist.h | 1 - .../superpmi-shared/methodcontext.cpp | 29 -- .../superpmi/superpmi-shared/methodcontext.h | 6 +- .../superpmi-shim-collector/icorjitinfo.cpp | 11 +- .../superpmi-shim-counter/icorjitinfo.cpp | 7 - .../superpmi-shim-simple/icorjitinfo.cpp | 6 - .../ToolBox/superpmi/superpmi/icorjitinfo.cpp | 7 - src/coreclr/inc/corinfo.h | 17 - src/coreclr/jit/ICorJitInfo_API_names.h | 1 - src/coreclr/jit/ICorJitInfo_API_wrapper.hpp | 9 - .../tools/Common/JitInterface/CorInfoBase.cs | 324 +++++++++--------- .../tools/Common/JitInterface/CorInfoImpl.cs | 15 - .../tools/Common/JitInterface/CorInfoTypes.cs | 11 - .../ThunkGenerator/ThunkInput.txt | 2 - .../tools/aot/jitinterface/jitinterface.h | 10 - src/coreclr/vm/jitinterface.cpp | 55 --- src/coreclr/vm/jitinterface.h | 2 - src/coreclr/zap/zapinfo.cpp | 5 - src/coreclr/zap/zapinfo.h | 1 - 20 files changed, 156 insertions(+), 366 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h index be9a2238882a9..86890421711ed 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h @@ -101,9 +101,6 @@ CorInfoIntrinsics getIntrinsicID( bool isIntrinsicType( CORINFO_CLASS_HANDLE classHnd); -CorInfoUnmanagedCallConv getUnmanagedCallConv( - CORINFO_METHOD_HANDLE method); - CorInfoCallConvExtension getEntryPointCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h index 73e9eb3384849..5a40bddc997bf 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h @@ -132,7 +132,6 @@ LWM(GetTypeForPrimitiveValueClass, DWORDLONG, DWORD) LWM(GetTypeForPrimitiveNumericClass, DWORDLONG, DWORD) LWM(GetUnboxedEntry, DWORDLONG, DLD); LWM(GetUnBoxHelper, DWORDLONG, DWORD) -LWM(GetUnmanagedCallConv, DWORDLONG, DWORD) LWM(GetVarArgsHandle, GetVarArgsHandleValue, DLDL) LWM(GetVars, DWORDLONG, Agnostic_GetVars) DENSELWM(HandleException, DWORD) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index 52fa0d8c67f53..27cdcf5adf3cc 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -1624,35 +1624,6 @@ bool MethodContext::repIsIntrinsicType(CORINFO_CLASS_HANDLE cls) return result; } -void MethodContext::recGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CorInfoUnmanagedCallConv result) -{ - if (GetUnmanagedCallConv == nullptr) - GetUnmanagedCallConv = new LightWeightMap(); - - GetUnmanagedCallConv->Add((DWORDLONG)method, result); - DEBUG_REC(dmpGetUnmanagedCallConv((DWORDLONG)method, (DWORD)result)); -} -void MethodContext::dmpGetUnmanagedCallConv(DWORDLONG key, DWORD result) -{ - printf("GetUnmanagedCallConv key ftn-%016llX, value res-%u", key, result); -} -CorInfoUnmanagedCallConv MethodContext::repGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method) -{ - if ((GetUnmanagedCallConv == nullptr) || (GetUnmanagedCallConv->GetIndex((DWORDLONG)method) == -1)) - { -#ifdef sparseMC - LogDebug("Sparse - repGetUnmanagedCallConv returning CORINFO_UNMANAGED_CALLCONV_STDCALL"); - return CORINFO_UNMANAGED_CALLCONV_STDCALL; -#else - LogException(EXCEPTIONCODE_MC, "Found a null GetUnmanagedCallConv. Probably missing a fatTrigger for %016llX.", - (DWORDLONG)method); -#endif - } - CorInfoUnmanagedCallConv result = (CorInfoUnmanagedCallConv)GetUnmanagedCallConv->Get((DWORDLONG)method); - DEBUG_REP(dmpGetUnmanagedCallConv((DWORDLONG)method, (DWORD)result)); - return result; -} - void MethodContext::recAsCorInfoType(CORINFO_CLASS_HANDLE cls, CorInfoType result) { if (AsCorInfoType == nullptr) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h index 6ee6392504d30..94bc32579ef0d 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h @@ -730,10 +730,6 @@ class MethodContext void dmpGetIntrinsicID(DWORDLONG key, DD value); CorInfoIntrinsics repGetIntrinsicID(CORINFO_METHOD_HANDLE method, bool* pMustExpand); - void recGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CorInfoUnmanagedCallConv result); - void dmpGetUnmanagedCallConv(DWORDLONG key, DWORD result); - CorInfoUnmanagedCallConv repGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method); - void recAsCorInfoType(CORINFO_CLASS_HANDLE cls, CorInfoType result); void dmpAsCorInfoType(DWORDLONG key, DWORD value); CorInfoType repAsCorInfoType(CORINFO_CLASS_HANDLE cls); @@ -1517,7 +1513,7 @@ enum mcPackets Packet_GetUnBoxHelper = 92, Packet_GetReadyToRunHelper = 150, // Added 10/10/2014 Packet_GetReadyToRunDelegateCtorHelper = 157, // Added 3/30/2016 - Packet_GetUnmanagedCallConv = 94, + Packet_GetUnmanagedCallConv = 94, // Retired 12/9/2020 Packet_GetEntryPointCallConv = 183, // Added 12/8/2020 Packet_GetVarArgsHandle = 95, Packet_GetVars = 96, diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 50d24b1c695a2..f890502a71b3a 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -289,22 +289,13 @@ bool interceptor_ICJI::isIntrinsicType(CORINFO_CLASS_HANDLE classHnd) return temp; } -// return the unmanaged calling convention for a PInvoke -CorInfoUnmanagedCallConv interceptor_ICJI::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method) -{ - mc->cr->AddCall("getUnmanagedCallConv"); - CorInfoUnmanagedCallConv temp = original_ICorJitInfo->getUnmanagedCallConv(method); - mc->recGetUnmanagedCallConv(method, temp); - return temp; -} - // return the entry point calling convention for any of the following // - a P/Invoke // - a method marked with UnmanagedCallersOnly // - a function pointer with the CORINFO_CALLCONV_UNMANAGED calling convention. CorInfoCallConvExtension interceptor_ICJI::getEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) { - mc->cr->AddCall("getUnmanagedCallConv"); + mc->cr->AddCall("getEntryPointCallConv"); CorInfoCallConvExtension temp = original_ICorJitInfo->getEntryPointCallConv(method, callSiteSig); mc->recGetEntryPointCallConv(method, callSiteSig, temp); return temp; diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp index 8a2535a52544e..74fa0f8798850 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp @@ -162,13 +162,6 @@ bool interceptor_ICJI::isIntrinsicType( return original_ICorJitInfo->isIntrinsicType(classHnd); } -CorInfoUnmanagedCallConv interceptor_ICJI::getUnmanagedCallConv( - CORINFO_METHOD_HANDLE method) -{ - mcs->AddCall("getUnmanagedCallConv"); - return original_ICorJitInfo->getUnmanagedCallConv(method); -} - CorInfoCallConvExtension interceptor_ICJI::getEntryPointCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp index 48e4158d5a88b..266484b7c7d29 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp @@ -144,12 +144,6 @@ bool interceptor_ICJI::isIntrinsicType( return original_ICorJitInfo->isIntrinsicType(classHnd); } -CorInfoUnmanagedCallConv interceptor_ICJI::getUnmanagedCallConv( - CORINFO_METHOD_HANDLE method) -{ - return original_ICorJitInfo->getUnmanagedCallConv(method); -} - CorInfoCallConvExtension interceptor_ICJI::getEntryPointCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) diff --git a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp index 569e9bbd9e385..71a5ef40696ef 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp @@ -218,13 +218,6 @@ bool MyICJI::isIntrinsicType(CORINFO_CLASS_HANDLE classHnd) return jitInstance->mc->repIsIntrinsicType(classHnd) ? true : false; } -// return the unmanaged calling convention for a PInvoke -CorInfoUnmanagedCallConv MyICJI::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method) -{ - jitInstance->mc->cr->AddCall("getUnmanagedCallConv"); - return jitInstance->mc->repGetUnmanagedCallConv(method); -} - // return the entry point calling convention for any of the following // - a P/Invoke // - a method marked with UnmanagedCallersOnly diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 06ef1bdf54145..25a0c9db702b5 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -700,18 +700,6 @@ inline bool IsCallerPop(CorInfoCallConv callConv) } #endif // UNIX_X86_ABI -// Represents the original metadata-encoded calling conventions. -enum CorInfoUnmanagedCallConv -{ - // These correspond to CorUnmanagedCallingConvention - CORINFO_UNMANAGED_CALLCONV_UNKNOWN, - CORINFO_UNMANAGED_CALLCONV_C, - CORINFO_UNMANAGED_CALLCONV_STDCALL, - CORINFO_UNMANAGED_CALLCONV_THISCALL, - CORINFO_UNMANAGED_CALLCONV_FASTCALL - // New calling conventions supported with the extensible calling convention encoding go here. -}; - // Represents the calling conventions supported with the extensible calling convention syntax // as well as the original metadata-encoded calling conventions. enum class CorInfoCallConvExtension @@ -2093,11 +2081,6 @@ class ICorStaticInfo CORINFO_CLASS_HANDLE classHnd ) { return false; } - // return the unmanaged calling convention for a PInvoke - virtual CorInfoUnmanagedCallConv getUnmanagedCallConv( - CORINFO_METHOD_HANDLE method - ) = 0; - // return the entry point calling convention for any of the following // - a P/Invoke // - a method marked with UnmanagedCallersOnly diff --git a/src/coreclr/jit/ICorJitInfo_API_names.h b/src/coreclr/jit/ICorJitInfo_API_names.h index d5968c0daeceb..4192ac8432cd2 100644 --- a/src/coreclr/jit/ICorJitInfo_API_names.h +++ b/src/coreclr/jit/ICorJitInfo_API_names.h @@ -22,7 +22,6 @@ DEF_CLR_API(getDefaultEqualityComparerClass) DEF_CLR_API(expandRawHandleIntrinsic) DEF_CLR_API(getIntrinsicID) DEF_CLR_API(isIntrinsicType) -DEF_CLR_API(getUnmanagedCallConv) DEF_CLR_API(getEntryPointCallConv) DEF_CLR_API(pInvokeMarshalingRequired) DEF_CLR_API(satisfiesMethodConstraints) diff --git a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp index 64dee20a188b4..416ac460077e6 100644 --- a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp +++ b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp @@ -191,15 +191,6 @@ bool WrapICorJitInfo::isIntrinsicType( return temp; } -CorInfoUnmanagedCallConv WrapICorJitInfo::getUnmanagedCallConv( - CORINFO_METHOD_HANDLE method) -{ - API_ENTER(getUnmanagedCallConv); - CorInfoUnmanagedCallConv temp = wrapHnd->getUnmanagedCallConv(method); - API_LEAVE(getUnmanagedCallConv); - return temp; -} - CorInfoCallConvExtension WrapICorJitInfo::getEntryPointCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs index 4ad3dee296069..609a904d85dd7 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs @@ -275,21 +275,6 @@ static byte _isIntrinsicType(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLA } } - [UnmanagedCallersOnly] - static CorInfoUnmanagedCallConv _getUnmanagedCallConv(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method) - { - var _this = GetThis(thisHandle); - try - { - return _this.getUnmanagedCallConv(method); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - [UnmanagedCallersOnly] static CorInfoCallConvExtension _getEntryPointCallConv(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method, CORINFO_SIG_INFO* callSiteSig) { @@ -2551,7 +2536,7 @@ static uint _getJitFlags(IntPtr thisHandle, IntPtr* ppException, CORJIT_FLAGS* f static IntPtr GetUnmanagedCallbacks() { - void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 172); + void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 171); callbacks[0] = (delegate* unmanaged)&_getMethodAttribs; callbacks[1] = (delegate* unmanaged)&_setMethodAttribs; @@ -2571,160 +2556,159 @@ static IntPtr GetUnmanagedCallbacks() callbacks[15] = (delegate* unmanaged)&_expandRawHandleIntrinsic; callbacks[16] = (delegate* unmanaged)&_getIntrinsicID; callbacks[17] = (delegate* unmanaged)&_isIntrinsicType; - callbacks[18] = (delegate* unmanaged)&_getUnmanagedCallConv; - callbacks[19] = (delegate* unmanaged)&_getEntryPointCallConv; - callbacks[20] = (delegate* unmanaged)&_pInvokeMarshalingRequired; - callbacks[21] = (delegate* unmanaged)&_satisfiesMethodConstraints; - callbacks[22] = (delegate* unmanaged)&_isCompatibleDelegate; - callbacks[23] = (delegate* unmanaged)&_methodMustBeLoadedBeforeCodeIsRun; - callbacks[24] = (delegate* unmanaged)&_mapMethodDeclToMethodImpl; - callbacks[25] = (delegate* unmanaged)&_getGSCookie; - callbacks[26] = (delegate* unmanaged)&_setPatchpointInfo; - callbacks[27] = (delegate* unmanaged)&_getOSRInfo; - callbacks[28] = (delegate* unmanaged)&_resolveToken; - callbacks[29] = (delegate* unmanaged)&_tryResolveToken; - callbacks[30] = (delegate* unmanaged)&_findSig; - callbacks[31] = (delegate* unmanaged)&_findCallSiteSig; - callbacks[32] = (delegate* unmanaged)&_getTokenTypeAsHandle; - callbacks[33] = (delegate* unmanaged)&_isValidToken; - callbacks[34] = (delegate* unmanaged)&_isValidStringRef; - callbacks[35] = (delegate* unmanaged)&_getStringLiteral; - callbacks[36] = (delegate* unmanaged)&_asCorInfoType; - callbacks[37] = (delegate* unmanaged)&_getClassName; - callbacks[38] = (delegate* unmanaged)&_getClassNameFromMetadata; - callbacks[39] = (delegate* unmanaged)&_getTypeInstantiationArgument; - callbacks[40] = (delegate* unmanaged)&_appendClassName; - callbacks[41] = (delegate* unmanaged)&_isValueClass; - callbacks[42] = (delegate* unmanaged)&_canInlineTypeCheck; - callbacks[43] = (delegate* unmanaged)&_getClassAttribs; - callbacks[44] = (delegate* unmanaged)&_isStructRequiringStackAllocRetBuf; - callbacks[45] = (delegate* unmanaged)&_getClassModule; - callbacks[46] = (delegate* unmanaged)&_getModuleAssembly; - callbacks[47] = (delegate* unmanaged)&_getAssemblyName; - callbacks[48] = (delegate* unmanaged)&_LongLifetimeMalloc; - callbacks[49] = (delegate* unmanaged)&_LongLifetimeFree; - callbacks[50] = (delegate* unmanaged)&_getClassModuleIdForStatics; - callbacks[51] = (delegate* unmanaged)&_getClassSize; - callbacks[52] = (delegate* unmanaged)&_getHeapClassSize; - callbacks[53] = (delegate* unmanaged)&_canAllocateOnStack; - callbacks[54] = (delegate* unmanaged)&_getClassAlignmentRequirement; - callbacks[55] = (delegate* unmanaged)&_getClassGClayout; - callbacks[56] = (delegate* unmanaged)&_getClassNumInstanceFields; - callbacks[57] = (delegate* unmanaged)&_getFieldInClass; - callbacks[58] = (delegate* unmanaged)&_checkMethodModifier; - callbacks[59] = (delegate* unmanaged)&_getNewHelper; - callbacks[60] = (delegate* unmanaged)&_getNewArrHelper; - callbacks[61] = (delegate* unmanaged)&_getCastingHelper; - callbacks[62] = (delegate* unmanaged)&_getSharedCCtorHelper; - callbacks[63] = (delegate* unmanaged)&_getTypeForBox; - callbacks[64] = (delegate* unmanaged)&_getBoxHelper; - callbacks[65] = (delegate* unmanaged)&_getUnBoxHelper; - callbacks[66] = (delegate* unmanaged)&_getReadyToRunHelper; - callbacks[67] = (delegate* unmanaged)&_getReadyToRunDelegateCtorHelper; - callbacks[68] = (delegate* unmanaged)&_getHelperName; - callbacks[69] = (delegate* unmanaged)&_initClass; - callbacks[70] = (delegate* unmanaged)&_classMustBeLoadedBeforeCodeIsRun; - callbacks[71] = (delegate* unmanaged)&_getBuiltinClass; - callbacks[72] = (delegate* unmanaged)&_getTypeForPrimitiveValueClass; - callbacks[73] = (delegate* unmanaged)&_getTypeForPrimitiveNumericClass; - callbacks[74] = (delegate* unmanaged)&_canCast; - callbacks[75] = (delegate* unmanaged)&_areTypesEquivalent; - callbacks[76] = (delegate* unmanaged)&_compareTypesForCast; - callbacks[77] = (delegate* unmanaged)&_compareTypesForEquality; - callbacks[78] = (delegate* unmanaged)&_mergeClasses; - callbacks[79] = (delegate* unmanaged)&_isMoreSpecificType; - callbacks[80] = (delegate* unmanaged)&_getParentType; - callbacks[81] = (delegate* unmanaged)&_getChildType; - callbacks[82] = (delegate* unmanaged)&_satisfiesClassConstraints; - callbacks[83] = (delegate* unmanaged)&_isSDArray; - callbacks[84] = (delegate* unmanaged)&_getArrayRank; - callbacks[85] = (delegate* unmanaged)&_getArrayInitializationData; - callbacks[86] = (delegate* unmanaged)&_canAccessClass; - callbacks[87] = (delegate* unmanaged)&_getFieldName; - callbacks[88] = (delegate* unmanaged)&_getFieldClass; - callbacks[89] = (delegate* unmanaged)&_getFieldType; - callbacks[90] = (delegate* unmanaged)&_getFieldOffset; - callbacks[91] = (delegate* unmanaged)&_getFieldInfo; - callbacks[92] = (delegate* unmanaged)&_isFieldStatic; - callbacks[93] = (delegate* unmanaged)&_getBoundaries; - callbacks[94] = (delegate* unmanaged)&_setBoundaries; - callbacks[95] = (delegate* unmanaged)&_getVars; - callbacks[96] = (delegate* unmanaged)&_setVars; - callbacks[97] = (delegate* unmanaged)&_allocateArray; - callbacks[98] = (delegate* unmanaged)&_freeArray; - callbacks[99] = (delegate* unmanaged)&_getArgNext; - callbacks[100] = (delegate* unmanaged)&_getArgType; - callbacks[101] = (delegate* unmanaged)&_getArgClass; - callbacks[102] = (delegate* unmanaged)&_getHFAType; - callbacks[103] = (delegate* unmanaged)&_GetErrorHRESULT; - callbacks[104] = (delegate* unmanaged)&_GetErrorMessage; - callbacks[105] = (delegate* unmanaged)&_FilterException; - callbacks[106] = (delegate* unmanaged)&_HandleException; - callbacks[107] = (delegate* unmanaged)&_ThrowExceptionForJitResult; - callbacks[108] = (delegate* unmanaged)&_ThrowExceptionForHelper; - callbacks[109] = (delegate* unmanaged)&_runWithErrorTrap; - callbacks[110] = (delegate* unmanaged)&_getEEInfo; - callbacks[111] = (delegate* unmanaged)&_getJitTimeLogFilename; - callbacks[112] = (delegate* unmanaged)&_getMethodDefFromMethod; - callbacks[113] = (delegate* unmanaged)&_getMethodName; - callbacks[114] = (delegate* unmanaged)&_getMethodNameFromMetadata; - callbacks[115] = (delegate* unmanaged)&_getMethodHash; - callbacks[116] = (delegate* unmanaged)&_findNameOfToken; - callbacks[117] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; - callbacks[118] = (delegate* unmanaged)&_getThreadTLSIndex; - callbacks[119] = (delegate* unmanaged)&_getInlinedCallFrameVptr; - callbacks[120] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; - callbacks[121] = (delegate* unmanaged)&_getHelperFtn; - callbacks[122] = (delegate* unmanaged)&_getFunctionEntryPoint; - callbacks[123] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; - callbacks[124] = (delegate* unmanaged)&_getMethodSync; - callbacks[125] = (delegate* unmanaged)&_getLazyStringLiteralHelper; - callbacks[126] = (delegate* unmanaged)&_embedModuleHandle; - callbacks[127] = (delegate* unmanaged)&_embedClassHandle; - callbacks[128] = (delegate* unmanaged)&_embedMethodHandle; - callbacks[129] = (delegate* unmanaged)&_embedFieldHandle; - callbacks[130] = (delegate* unmanaged)&_embedGenericHandle; - callbacks[131] = (delegate* unmanaged)&_getLocationOfThisType; - callbacks[132] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; - callbacks[133] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; - callbacks[134] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; - callbacks[135] = (delegate* unmanaged)&_getJustMyCodeHandle; - callbacks[136] = (delegate* unmanaged)&_GetProfilingHandle; - callbacks[137] = (delegate* unmanaged)&_getCallInfo; - callbacks[138] = (delegate* unmanaged)&_canAccessFamily; - callbacks[139] = (delegate* unmanaged)&_isRIDClassDomainID; - callbacks[140] = (delegate* unmanaged)&_getClassDomainID; - callbacks[141] = (delegate* unmanaged)&_getFieldAddress; - callbacks[142] = (delegate* unmanaged)&_getStaticFieldCurrentClass; - callbacks[143] = (delegate* unmanaged)&_getVarArgsHandle; - callbacks[144] = (delegate* unmanaged)&_canGetVarArgsHandle; - callbacks[145] = (delegate* unmanaged)&_constructStringLiteral; - callbacks[146] = (delegate* unmanaged)&_emptyStringLiteral; - callbacks[147] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; - callbacks[148] = (delegate* unmanaged)&_setOverride; - callbacks[149] = (delegate* unmanaged)&_addActiveDependency; - callbacks[150] = (delegate* unmanaged)&_GetDelegateCtor; - callbacks[151] = (delegate* unmanaged)&_MethodCompileComplete; - callbacks[152] = (delegate* unmanaged)&_getTailCallHelpers; - callbacks[153] = (delegate* unmanaged)&_convertPInvokeCalliToCall; - callbacks[154] = (delegate* unmanaged)&_notifyInstructionSetUsage; - callbacks[155] = (delegate* unmanaged)&_allocMem; - callbacks[156] = (delegate* unmanaged)&_reserveUnwindInfo; - callbacks[157] = (delegate* unmanaged)&_allocUnwindInfo; - callbacks[158] = (delegate* unmanaged)&_allocGCInfo; - callbacks[159] = (delegate* unmanaged)&_setEHcount; - callbacks[160] = (delegate* unmanaged)&_setEHinfo; - callbacks[161] = (delegate* unmanaged)&_logMsg; - callbacks[162] = (delegate* unmanaged)&_doAssert; - callbacks[163] = (delegate* unmanaged)&_reportFatalError; - callbacks[164] = (delegate* unmanaged)&_allocMethodBlockCounts; - callbacks[165] = (delegate* unmanaged)&_getMethodBlockCounts; - callbacks[166] = (delegate* unmanaged)&_getLikelyClass; - callbacks[167] = (delegate* unmanaged)&_recordCallSite; - callbacks[168] = (delegate* unmanaged)&_recordRelocation; - callbacks[169] = (delegate* unmanaged)&_getRelocTypeHint; - callbacks[170] = (delegate* unmanaged)&_getExpectedTargetArchitecture; - callbacks[171] = (delegate* unmanaged)&_getJitFlags; + callbacks[18] = (delegate* unmanaged)&_getEntryPointCallConv; + callbacks[19] = (delegate* unmanaged)&_pInvokeMarshalingRequired; + callbacks[20] = (delegate* unmanaged)&_satisfiesMethodConstraints; + callbacks[21] = (delegate* unmanaged)&_isCompatibleDelegate; + callbacks[22] = (delegate* unmanaged)&_methodMustBeLoadedBeforeCodeIsRun; + callbacks[23] = (delegate* unmanaged)&_mapMethodDeclToMethodImpl; + callbacks[24] = (delegate* unmanaged)&_getGSCookie; + callbacks[25] = (delegate* unmanaged)&_setPatchpointInfo; + callbacks[26] = (delegate* unmanaged)&_getOSRInfo; + callbacks[27] = (delegate* unmanaged)&_resolveToken; + callbacks[28] = (delegate* unmanaged)&_tryResolveToken; + callbacks[29] = (delegate* unmanaged)&_findSig; + callbacks[30] = (delegate* unmanaged)&_findCallSiteSig; + callbacks[31] = (delegate* unmanaged)&_getTokenTypeAsHandle; + callbacks[32] = (delegate* unmanaged)&_isValidToken; + callbacks[33] = (delegate* unmanaged)&_isValidStringRef; + callbacks[34] = (delegate* unmanaged)&_getStringLiteral; + callbacks[35] = (delegate* unmanaged)&_asCorInfoType; + callbacks[36] = (delegate* unmanaged)&_getClassName; + callbacks[37] = (delegate* unmanaged)&_getClassNameFromMetadata; + callbacks[38] = (delegate* unmanaged)&_getTypeInstantiationArgument; + callbacks[39] = (delegate* unmanaged)&_appendClassName; + callbacks[40] = (delegate* unmanaged)&_isValueClass; + callbacks[41] = (delegate* unmanaged)&_canInlineTypeCheck; + callbacks[42] = (delegate* unmanaged)&_getClassAttribs; + callbacks[43] = (delegate* unmanaged)&_isStructRequiringStackAllocRetBuf; + callbacks[44] = (delegate* unmanaged)&_getClassModule; + callbacks[45] = (delegate* unmanaged)&_getModuleAssembly; + callbacks[46] = (delegate* unmanaged)&_getAssemblyName; + callbacks[47] = (delegate* unmanaged)&_LongLifetimeMalloc; + callbacks[48] = (delegate* unmanaged)&_LongLifetimeFree; + callbacks[49] = (delegate* unmanaged)&_getClassModuleIdForStatics; + callbacks[50] = (delegate* unmanaged)&_getClassSize; + callbacks[51] = (delegate* unmanaged)&_getHeapClassSize; + callbacks[52] = (delegate* unmanaged)&_canAllocateOnStack; + callbacks[53] = (delegate* unmanaged)&_getClassAlignmentRequirement; + callbacks[54] = (delegate* unmanaged)&_getClassGClayout; + callbacks[55] = (delegate* unmanaged)&_getClassNumInstanceFields; + callbacks[56] = (delegate* unmanaged)&_getFieldInClass; + callbacks[57] = (delegate* unmanaged)&_checkMethodModifier; + callbacks[58] = (delegate* unmanaged)&_getNewHelper; + callbacks[59] = (delegate* unmanaged)&_getNewArrHelper; + callbacks[60] = (delegate* unmanaged)&_getCastingHelper; + callbacks[61] = (delegate* unmanaged)&_getSharedCCtorHelper; + callbacks[62] = (delegate* unmanaged)&_getTypeForBox; + callbacks[63] = (delegate* unmanaged)&_getBoxHelper; + callbacks[64] = (delegate* unmanaged)&_getUnBoxHelper; + callbacks[65] = (delegate* unmanaged)&_getReadyToRunHelper; + callbacks[66] = (delegate* unmanaged)&_getReadyToRunDelegateCtorHelper; + callbacks[67] = (delegate* unmanaged)&_getHelperName; + callbacks[68] = (delegate* unmanaged)&_initClass; + callbacks[69] = (delegate* unmanaged)&_classMustBeLoadedBeforeCodeIsRun; + callbacks[70] = (delegate* unmanaged)&_getBuiltinClass; + callbacks[71] = (delegate* unmanaged)&_getTypeForPrimitiveValueClass; + callbacks[72] = (delegate* unmanaged)&_getTypeForPrimitiveNumericClass; + callbacks[73] = (delegate* unmanaged)&_canCast; + callbacks[74] = (delegate* unmanaged)&_areTypesEquivalent; + callbacks[75] = (delegate* unmanaged)&_compareTypesForCast; + callbacks[76] = (delegate* unmanaged)&_compareTypesForEquality; + callbacks[77] = (delegate* unmanaged)&_mergeClasses; + callbacks[78] = (delegate* unmanaged)&_isMoreSpecificType; + callbacks[79] = (delegate* unmanaged)&_getParentType; + callbacks[80] = (delegate* unmanaged)&_getChildType; + callbacks[81] = (delegate* unmanaged)&_satisfiesClassConstraints; + callbacks[82] = (delegate* unmanaged)&_isSDArray; + callbacks[83] = (delegate* unmanaged)&_getArrayRank; + callbacks[84] = (delegate* unmanaged)&_getArrayInitializationData; + callbacks[85] = (delegate* unmanaged)&_canAccessClass; + callbacks[86] = (delegate* unmanaged)&_getFieldName; + callbacks[87] = (delegate* unmanaged)&_getFieldClass; + callbacks[88] = (delegate* unmanaged)&_getFieldType; + callbacks[89] = (delegate* unmanaged)&_getFieldOffset; + callbacks[90] = (delegate* unmanaged)&_getFieldInfo; + callbacks[91] = (delegate* unmanaged)&_isFieldStatic; + callbacks[92] = (delegate* unmanaged)&_getBoundaries; + callbacks[93] = (delegate* unmanaged)&_setBoundaries; + callbacks[94] = (delegate* unmanaged)&_getVars; + callbacks[95] = (delegate* unmanaged)&_setVars; + callbacks[96] = (delegate* unmanaged)&_allocateArray; + callbacks[97] = (delegate* unmanaged)&_freeArray; + callbacks[98] = (delegate* unmanaged)&_getArgNext; + callbacks[99] = (delegate* unmanaged)&_getArgType; + callbacks[100] = (delegate* unmanaged)&_getArgClass; + callbacks[101] = (delegate* unmanaged)&_getHFAType; + callbacks[102] = (delegate* unmanaged)&_GetErrorHRESULT; + callbacks[103] = (delegate* unmanaged)&_GetErrorMessage; + callbacks[104] = (delegate* unmanaged)&_FilterException; + callbacks[105] = (delegate* unmanaged)&_HandleException; + callbacks[106] = (delegate* unmanaged)&_ThrowExceptionForJitResult; + callbacks[107] = (delegate* unmanaged)&_ThrowExceptionForHelper; + callbacks[108] = (delegate* unmanaged)&_runWithErrorTrap; + callbacks[109] = (delegate* unmanaged)&_getEEInfo; + callbacks[110] = (delegate* unmanaged)&_getJitTimeLogFilename; + callbacks[111] = (delegate* unmanaged)&_getMethodDefFromMethod; + callbacks[112] = (delegate* unmanaged)&_getMethodName; + callbacks[113] = (delegate* unmanaged)&_getMethodNameFromMetadata; + callbacks[114] = (delegate* unmanaged)&_getMethodHash; + callbacks[115] = (delegate* unmanaged)&_findNameOfToken; + callbacks[116] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; + callbacks[117] = (delegate* unmanaged)&_getThreadTLSIndex; + callbacks[118] = (delegate* unmanaged)&_getInlinedCallFrameVptr; + callbacks[119] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; + callbacks[120] = (delegate* unmanaged)&_getHelperFtn; + callbacks[121] = (delegate* unmanaged)&_getFunctionEntryPoint; + callbacks[122] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; + callbacks[123] = (delegate* unmanaged)&_getMethodSync; + callbacks[124] = (delegate* unmanaged)&_getLazyStringLiteralHelper; + callbacks[125] = (delegate* unmanaged)&_embedModuleHandle; + callbacks[126] = (delegate* unmanaged)&_embedClassHandle; + callbacks[127] = (delegate* unmanaged)&_embedMethodHandle; + callbacks[128] = (delegate* unmanaged)&_embedFieldHandle; + callbacks[129] = (delegate* unmanaged)&_embedGenericHandle; + callbacks[130] = (delegate* unmanaged)&_getLocationOfThisType; + callbacks[131] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; + callbacks[132] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; + callbacks[133] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; + callbacks[134] = (delegate* unmanaged)&_getJustMyCodeHandle; + callbacks[135] = (delegate* unmanaged)&_GetProfilingHandle; + callbacks[136] = (delegate* unmanaged)&_getCallInfo; + callbacks[137] = (delegate* unmanaged)&_canAccessFamily; + callbacks[138] = (delegate* unmanaged)&_isRIDClassDomainID; + callbacks[139] = (delegate* unmanaged)&_getClassDomainID; + callbacks[140] = (delegate* unmanaged)&_getFieldAddress; + callbacks[141] = (delegate* unmanaged)&_getStaticFieldCurrentClass; + callbacks[142] = (delegate* unmanaged)&_getVarArgsHandle; + callbacks[143] = (delegate* unmanaged)&_canGetVarArgsHandle; + callbacks[144] = (delegate* unmanaged)&_constructStringLiteral; + callbacks[145] = (delegate* unmanaged)&_emptyStringLiteral; + callbacks[146] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; + callbacks[147] = (delegate* unmanaged)&_setOverride; + callbacks[148] = (delegate* unmanaged)&_addActiveDependency; + callbacks[149] = (delegate* unmanaged)&_GetDelegateCtor; + callbacks[150] = (delegate* unmanaged)&_MethodCompileComplete; + callbacks[151] = (delegate* unmanaged)&_getTailCallHelpers; + callbacks[152] = (delegate* unmanaged)&_convertPInvokeCalliToCall; + callbacks[153] = (delegate* unmanaged)&_notifyInstructionSetUsage; + callbacks[154] = (delegate* unmanaged)&_allocMem; + callbacks[155] = (delegate* unmanaged)&_reserveUnwindInfo; + callbacks[156] = (delegate* unmanaged)&_allocUnwindInfo; + callbacks[157] = (delegate* unmanaged)&_allocGCInfo; + callbacks[158] = (delegate* unmanaged)&_setEHcount; + callbacks[159] = (delegate* unmanaged)&_setEHinfo; + callbacks[160] = (delegate* unmanaged)&_logMsg; + callbacks[161] = (delegate* unmanaged)&_doAssert; + callbacks[162] = (delegate* unmanaged)&_reportFatalError; + callbacks[163] = (delegate* unmanaged)&_allocMethodBlockCounts; + callbacks[164] = (delegate* unmanaged)&_getMethodBlockCounts; + callbacks[165] = (delegate* unmanaged)&_getLikelyClass; + callbacks[166] = (delegate* unmanaged)&_recordCallSite; + callbacks[167] = (delegate* unmanaged)&_recordRelocation; + callbacks[168] = (delegate* unmanaged)&_getRelocTypeHint; + callbacks[169] = (delegate* unmanaged)&_getExpectedTargetArchitecture; + callbacks[170] = (delegate* unmanaged)&_getJitFlags; return (IntPtr)callbacks; } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 6ab916b96838a..7447543096022 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -1062,21 +1062,6 @@ private MethodSignatureFlags PlatformDefaultUnmanagedCallingConvention() MethodSignatureFlags.UnmanagedCallingConventionStdCall : MethodSignatureFlags.UnmanagedCallingConventionCdecl; } - private CorInfoUnmanagedCallConv getUnmanagedCallConv(CORINFO_METHOD_STRUCT_* method) - { - MethodSignatureFlags unmanagedCallConv = HandleToObject(method).GetPInvokeMethodMetadata().Flags.UnmanagedCallingConvention; - - if (unmanagedCallConv == MethodSignatureFlags.None) - unmanagedCallConv = PlatformDefaultUnmanagedCallingConvention(); - - // Verify that it is safe to convert MethodSignatureFlags.UnmanagedCallingConvention to CorInfoUnmanagedCallConv via a simple cast - Debug.Assert((int)CorInfoUnmanagedCallConv.CORINFO_UNMANAGED_CALLCONV_C == (int)MethodSignatureFlags.UnmanagedCallingConventionCdecl); - Debug.Assert((int)CorInfoUnmanagedCallConv.CORINFO_UNMANAGED_CALLCONV_STDCALL == (int)MethodSignatureFlags.UnmanagedCallingConventionStdCall); - Debug.Assert((int)CorInfoUnmanagedCallConv.CORINFO_UNMANAGED_CALLCONV_THISCALL == (int)MethodSignatureFlags.UnmanagedCallingConventionThisCall); - - return (CorInfoUnmanagedCallConv)unmanagedCallConv; - } - private CorInfoCallConvExtension getEntryPointCallConv(CORINFO_METHOD_STRUCT_* method, CORINFO_SIG_INFO* sig) { Debug.Assert(method != null || sig != null); diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index 2848c0aa596e7..b6e41e9fa3fe1 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -331,17 +331,6 @@ public enum CorInfoCallConv CORINFO_CALLCONV_EXPLICITTHIS = 0x40, CORINFO_CALLCONV_PARAMTYPE = 0x80, // Passed last. Same as CORINFO_GENERICS_CTXT_FROM_PARAMTYPEARG } - - public enum CorInfoUnmanagedCallConv - { - // These correspond to CorUnmanagedCallingConvention - - CORINFO_UNMANAGED_CALLCONV_UNKNOWN, - CORINFO_UNMANAGED_CALLCONV_C, - CORINFO_UNMANAGED_CALLCONV_STDCALL, - CORINFO_UNMANAGED_CALLCONV_THISCALL, - CORINFO_UNMANAGED_CALLCONV_FASTCALL - } // Represents the calling conventions supported with the extensible calling convention syntax // as well as the original metadata-encoded calling conventions. diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 9b3c3b018869d..72d93b5b03c8f 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -123,7 +123,6 @@ CorInfoTailCall,,int CorInfoType,,int CorInfoHFAElemType,,int CorInfoTypeWithMod,,int -CorInfoUnmanagedCallConv,,int CorInfoCallConvExtension,,int InfoAccessType,,int CORINFO_LOOKUP_KIND @@ -177,7 +176,6 @@ FUNCTIONS void expandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_GENERICHANDLE_RESULT * pResult); CorInfoIntrinsics getIntrinsicID( CORINFO_METHOD_HANDLE method , BoolStar pMustExpand); bool isIntrinsicType( CORINFO_CLASS_HANDLE classHnd ); - CorInfoUnmanagedCallConv getUnmanagedCallConv( CORINFO_METHOD_HANDLE method ); CorInfoCallConvExtension getEntryPointCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); bool pInvokeMarshalingRequired( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig ); bool satisfiesMethodConstraints( CORINFO_CLASS_HANDLE parent, CORINFO_METHOD_HANDLE method ); diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface.h b/src/coreclr/tools/aot/jitinterface/jitinterface.h index 0619019d9dcf0..5a11d55cb3b71 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface.h @@ -28,7 +28,6 @@ struct JitInterfaceCallbacks void (* expandRawHandleIntrinsic)(void * thisHandle, CorInfoExceptionClass** ppException, void* pResolvedToken, void* pResult); int (* getIntrinsicID)(void * thisHandle, CorInfoExceptionClass** ppException, void* method, bool* pMustExpand); bool (* isIntrinsicType)(void * thisHandle, CorInfoExceptionClass** ppException, void* classHnd); - int (* getUnmanagedCallConv)(void * thisHandle, CorInfoExceptionClass** ppException, void* method); int (* getEntryPointCallConv)(void * thisHandle, CorInfoExceptionClass** ppException, void* method, void* callSiteSig); bool (* pInvokeMarshalingRequired)(void * thisHandle, CorInfoExceptionClass** ppException, void* method, void* callSiteSig); bool (* satisfiesMethodConstraints)(void * thisHandle, CorInfoExceptionClass** ppException, void* parent, void* method); @@ -376,15 +375,6 @@ class JitInterfaceWrapper return temp; } - virtual int getUnmanagedCallConv( - void* method) -{ - CorInfoExceptionClass* pException = nullptr; - int temp = _callbacks->getUnmanagedCallConv(_thisHandle, &pException, method); - if (pException != nullptr) throw pException; - return temp; -} - virtual int getEntryPointCallConv( void* method, void* callSiteSig) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 64221988456a4..815daa0f7c62a 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9791,61 +9791,6 @@ CorInfoHFAElemType CEEInfo::getHFAType(CORINFO_CLASS_HANDLE hClass) return result; } -/*********************************************************************/ - - // return the unmanaged calling convention for a PInvoke -CorInfoUnmanagedCallConv CEEInfo::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_PREEMPTIVE; - } CONTRACTL_END; - - CorInfoUnmanagedCallConv result = CORINFO_UNMANAGED_CALLCONV_UNKNOWN; - - JIT_TO_EE_TRANSITION(); - - MethodDesc* pMD = NULL; - pMD = GetMethod(method); - _ASSERTE(pMD->IsNDirect()); - -#ifdef TARGET_X86 - EX_TRY - { - PInvokeStaticSigInfo sigInfo(pMD, PInvokeStaticSigInfo::NO_THROW_ON_ERROR); - - switch (sigInfo.GetCallConv()) { - case pmCallConvCdecl: - result = CORINFO_UNMANAGED_CALLCONV_C; - break; - case pmCallConvStdcall: - result = CORINFO_UNMANAGED_CALLCONV_STDCALL; - break; - case pmCallConvThiscall: - result = CORINFO_UNMANAGED_CALLCONV_THISCALL; - break; - default: - result = CORINFO_UNMANAGED_CALLCONV_UNKNOWN; - } - } - EX_CATCH - { - result = CORINFO_UNMANAGED_CALLCONV_UNKNOWN; - } - EX_END_CATCH(SwallowAllExceptions) -#else // !TARGET_X86 - // - // we have only one calling convention - // - result = CORINFO_UNMANAGED_CALLCONV_STDCALL; -#endif // !TARGET_X86 - - EE_TO_JIT_TRANSITION(); - - return result; -} - /*********************************************************************/ // return the entry point calling convention for any of the following diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index eafd33ddee98e..372f71ad08a1b 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -756,8 +756,6 @@ class CEEInfo : public ICorJitInfo bool * pMustExpand = NULL); bool isIntrinsicType(CORINFO_CLASS_HANDLE classHnd); - - CorInfoUnmanagedCallConv getUnmanagedCallConv(CORINFO_METHOD_HANDLE method); CorInfoCallConvExtension getEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); diff --git a/src/coreclr/zap/zapinfo.cpp b/src/coreclr/zap/zapinfo.cpp index 355b9277ba0bc..29196db050e6c 100644 --- a/src/coreclr/zap/zapinfo.cpp +++ b/src/coreclr/zap/zapinfo.cpp @@ -4045,11 +4045,6 @@ bool ZapInfo::isIntrinsicType(CORINFO_CLASS_HANDLE classHnd) return m_pEEJitInfo->isIntrinsicType(classHnd); } -CorInfoUnmanagedCallConv ZapInfo::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method) -{ - return m_pEEJitInfo->getUnmanagedCallConv(method); -} - CorInfoCallConvExtension ZapInfo::getEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { return m_pEEJitInfo->getEntryPointCallConv(method, sig); diff --git a/src/coreclr/zap/zapinfo.h b/src/coreclr/zap/zapinfo.h index e8fb8d1976a0a..b47e80bc8e200 100644 --- a/src/coreclr/zap/zapinfo.h +++ b/src/coreclr/zap/zapinfo.h @@ -691,7 +691,6 @@ class ZapInfo CorInfoIntrinsics getIntrinsicID(CORINFO_METHOD_HANDLE method, bool * pMustExpand = NULL); bool isIntrinsicType(CORINFO_CLASS_HANDLE classHnd); - CorInfoUnmanagedCallConv getUnmanagedCallConv(CORINFO_METHOD_HANDLE method); CorInfoCallConvExtension getEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); bool pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); LPVOID GetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, From bcf270d5d7107716de02d965674b027c7dbab283 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 9 Dec 2020 15:51:24 -0800 Subject: [PATCH 18/38] Fix formatting. --- src/coreclr/jit/codegencommon.cpp | 3 +-- src/coreclr/jit/compiler.h | 2 +- src/coreclr/jit/gcencode.cpp | 3 +-- src/coreclr/jit/importer.cpp | 17 ++++++----------- src/coreclr/jit/lclvars.cpp | 4 +--- src/coreclr/jit/lower.cpp | 3 +-- src/coreclr/jit/morph.cpp | 3 +-- 7 files changed, 12 insertions(+), 23 deletions(-) diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 0ce762c2ed511..ae8d439a7aa78 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -11662,8 +11662,7 @@ void CodeGen::genStructReturn(GenTree* treeNode) if (actualOp1->OperIs(GT_LCL_VAR)) { varDsc = compiler->lvaGetDesc(actualOp1->AsLclVar()->GetLclNum()); - retTypeDesc.InitializeStructReturnType(compiler, varDsc->GetStructHnd(), - compiler->info.compCallConv); + retTypeDesc.InitializeStructReturnType(compiler, varDsc->GetStructHnd(), compiler->info.compCallConv); assert(varDsc->lvIsMultiRegRet); } else diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 0410ae89b74f4..8187f3169d13b 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -9311,7 +9311,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX UNATIVE_OFFSET compTotalColdCodeSize; // Total number of bytes of Cold Code in the method unsigned compUnmanagedCallCountWithGCTransition; // count of unmanaged calls with GC transition. - + CorInfoCallConvExtension compCallConv; // The entry-point calling convention for this method. unsigned compLvFrameListRoot; // lclNum for the Frame root diff --git a/src/coreclr/jit/gcencode.cpp b/src/coreclr/jit/gcencode.cpp index 7956525650486..6e4bcff08de73 100644 --- a/src/coreclr/jit/gcencode.cpp +++ b/src/coreclr/jit/gcencode.cpp @@ -50,8 +50,7 @@ ReturnKind GCInfo::getReturnKind() case TYP_STRUCT: { CORINFO_CLASS_HANDLE structType = compiler->info.compMethodInfo->args.retTypeClass; - var_types retType = - compiler->getReturnTypeForStruct(structType, compiler->info.compCallConv); + var_types retType = compiler->getReturnTypeForStruct(structType, compiler->info.compCallConv); switch (retType) { diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index fbb570462260a..edf68269b36f3 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -8899,9 +8899,8 @@ var_types Compiler::impImportCall(OPCODE opcode, // a small-typed return value is responsible for normalizing the return val if (canTailCall && - !impTailCallRetTypeCompatible(info.compRetType, info.compMethodInfo->args.retTypeClass, - info.compCallConv, callRetTyp, - sig->retTypeClass, call->AsCall()->GetUnmanagedCallConv())) + !impTailCallRetTypeCompatible(info.compRetType, info.compMethodInfo->args.retTypeClass, info.compCallConv, + callRetTyp, sig->retTypeClass, call->AsCall()->GetUnmanagedCallConv())) { canTailCall = false; szCanTailCallFailReason = "Return types are not tail call compatible"; @@ -16971,8 +16970,7 @@ bool Compiler::impReturnInstruction(int prefixFlags, OPCODE& opcode) noway_assert(info.compRetBuffArg == BAD_VAR_NUM); // adjust the type away from struct to integral // and no normalizing - op2 = impFixupStructReturnType(op2, retClsHnd, - info.compCallConv); + op2 = impFixupStructReturnType(op2, retClsHnd, info.compCallConv); } else { @@ -17172,8 +17170,7 @@ bool Compiler::impReturnInstruction(int prefixFlags, OPCODE& opcode) // Same as !IsHfa but just don't bother with impAssignStructPtr. #else // defined(UNIX_AMD64_ABI) ReturnTypeDesc retTypeDesc; - retTypeDesc.InitializeStructReturnType(this, retClsHnd, - info.compCallConv); + retTypeDesc.InitializeStructReturnType(this, retClsHnd, info.compCallConv); unsigned retRegCount = retTypeDesc.GetReturnRegCount(); if (retRegCount != 0) @@ -17207,8 +17204,7 @@ bool Compiler::impReturnInstruction(int prefixFlags, OPCODE& opcode) else #elif defined(TARGET_ARM64) ReturnTypeDesc retTypeDesc; - retTypeDesc.InitializeStructReturnType(this, retClsHnd, - info.compCallConv); + retTypeDesc.InitializeStructReturnType(this, retClsHnd, info.compCallConv); unsigned retRegCount = retTypeDesc.GetReturnRegCount(); if (retRegCount != 0) @@ -17232,8 +17228,7 @@ bool Compiler::impReturnInstruction(int prefixFlags, OPCODE& opcode) else #elif defined(TARGET_X86) ReturnTypeDesc retTypeDesc; - retTypeDesc.InitializeStructReturnType(this, retClsHnd, - info.compCallConv); + retTypeDesc.InitializeStructReturnType(this, retClsHnd, info.compCallConv); unsigned retRegCount = retTypeDesc.GetReturnRegCount(); if (retRegCount != 0) diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index b606203595117..a81f70a2e5cd1 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -145,9 +145,7 @@ void Compiler::lvaInitTypeRef() CORINFO_CLASS_HANDLE retClsHnd = info.compMethodInfo->args.retTypeClass; Compiler::structPassingKind howToReturnStruct; - var_types returnType = - getReturnTypeForStruct(retClsHnd, info.compCallConv, - &howToReturnStruct); + var_types returnType = getReturnTypeForStruct(retClsHnd, info.compCallConv, &howToReturnStruct); // We can safely widen the return type for enclosed structs. if ((howToReturnStruct == SPK_PrimitiveType) || (howToReturnStruct == SPK_EnclosingType)) diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index d064c5c817afc..d7488c8522875 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -3016,8 +3016,7 @@ void Lowering::LowerRet(GenTreeUnOp* ret) ReturnTypeDesc retTypeDesc; LclVarDsc* varDsc = nullptr; varDsc = comp->lvaGetDesc(retVal->AsLclVar()->GetLclNum()); - retTypeDesc.InitializeStructReturnType(comp, varDsc->GetStructHnd(), - comp->info.compCallConv); + retTypeDesc.InitializeStructReturnType(comp, varDsc->GetStructHnd(), comp->info.compCallConv); if (retTypeDesc.GetReturnRegCount() > 1) { CheckMultiRegLclVar(retVal->AsLclVar(), &retTypeDesc); diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index c01d29f1b328c..a1627472d22ca 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -6828,8 +6828,7 @@ bool Compiler::fgCanFastTailCall(GenTreeCall* callee, const char** failReason) if (callee->IsTailPrefixedCall()) { var_types retType = (compDoOldStructRetyping() ? info.compRetNativeType : info.compRetType); - assert(impTailCallRetTypeCompatible(retType, info.compMethodInfo->args.retTypeClass, - info.compCallConv, + assert(impTailCallRetTypeCompatible(retType, info.compMethodInfo->args.retTypeClass, info.compCallConv, (var_types)callee->gtReturnType, callee->gtRetClsHnd, callee->GetUnmanagedCallConv())); } From d2e016c93b67752ab749a9ab5b6bbd23b764751a Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 10 Dec 2020 15:56:08 -0800 Subject: [PATCH 19/38] Rename getEntryPointCallConv and only call it with a method when it's a P/Invoke or Reverse P/Invoke. --- .../superpmi-shared/icorjitinfoimpl.h | 2 +- .../superpmi-shim-collector/icorjitinfo.cpp | 10 ++-- .../superpmi-shim-counter/icorjitinfo.cpp | 6 +-- .../superpmi-shim-simple/icorjitinfo.cpp | 4 +- .../ToolBox/superpmi/superpmi/icorjitinfo.cpp | 8 ++-- src/coreclr/inc/corinfo.h | 6 ++- src/coreclr/jit/ICorJitInfo_API_names.h | 2 +- src/coreclr/jit/ICorJitInfo_API_wrapper.hpp | 8 ++-- src/coreclr/jit/compiler.cpp | 16 +++++-- src/coreclr/jit/compiler.h | 5 +- src/coreclr/jit/importer.cpp | 11 +++-- src/coreclr/jit/lclvars.cpp | 4 +- .../tools/Common/JitInterface/CorInfoBase.cs | 2 +- .../tools/Common/JitInterface/CorInfoImpl.cs | 11 +++-- .../ThunkGenerator/ThunkInput.txt | 16 +++---- .../tools/aot/jitinterface/jitinterface.h | 6 +-- src/coreclr/vm/jitinterface.cpp | 47 ++++++++----------- src/coreclr/vm/jitinterface.h | 10 ++-- src/coreclr/zap/zapinfo.cpp | 8 ++-- src/coreclr/zap/zapinfo.h | 2 +- 20 files changed, 96 insertions(+), 88 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h index a7263fdbf9fdc..1d0c4c63578af 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h @@ -101,7 +101,7 @@ CorInfoIntrinsics getIntrinsicID( bool isIntrinsicType( CORINFO_CLASS_HANDLE classHnd); -CorInfoCallConvExtension getEntryPointCallConv( +CorInfoCallConvExtension getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp index f890502a71b3a..a7378fc663dfc 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -291,12 +291,12 @@ bool interceptor_ICJI::isIntrinsicType(CORINFO_CLASS_HANDLE classHnd) // return the entry point calling convention for any of the following // - a P/Invoke -// - a method marked with UnmanagedCallersOnly +// - a method marked with UnmanagedCallersOnly // - a function pointer with the CORINFO_CALLCONV_UNMANAGED calling convention. -CorInfoCallConvExtension interceptor_ICJI::getEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) +CorInfoCallConvExtension interceptor_ICJI::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) { - mc->cr->AddCall("getEntryPointCallConv"); - CorInfoCallConvExtension temp = original_ICorJitInfo->getEntryPointCallConv(method, callSiteSig); + mc->cr->AddCall("getUnmanagedCallConv"); + CorInfoCallConvExtension temp = original_ICorJitInfo->getUnmanagedCallConv(method, callSiteSig); mc->recGetEntryPointCallConv(method, callSiteSig, temp); return temp; } @@ -2049,7 +2049,7 @@ HRESULT interceptor_ICJI::getMethodBlockCounts(CORINFO_METHOD_HANDLE ftnHnd, // Get the likely implementing class for a virtual call or interface call made by ftnHnd // at the indicated IL offset. baseHnd is the interface class or base class for the method -// being called. +// being called. CORINFO_CLASS_HANDLE interceptor_ICJI::getLikelyClass(CORINFO_METHOD_HANDLE ftnHnd, CORINFO_CLASS_HANDLE baseHnd, UINT32 ilOffset, diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp index 28b2a0a1bbe25..f59015994f7d5 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp @@ -162,12 +162,12 @@ bool interceptor_ICJI::isIntrinsicType( return original_ICorJitInfo->isIntrinsicType(classHnd); } -CorInfoCallConvExtension interceptor_ICJI::getEntryPointCallConv( +CorInfoCallConvExtension interceptor_ICJI::getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) { - mcs->AddCall("getEntryPointCallConv"); - return original_ICorJitInfo->getEntryPointCallConv(method, callSiteSig); + mcs->AddCall("getUnmanagedCallConv"); + return original_ICorJitInfo->getUnmanagedCallConv(method, callSiteSig); } bool interceptor_ICJI::pInvokeMarshalingRequired( diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp index c1b08e5e26fc1..10aff10d027cc 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp @@ -144,11 +144,11 @@ bool interceptor_ICJI::isIntrinsicType( return original_ICorJitInfo->isIntrinsicType(classHnd); } -CorInfoCallConvExtension interceptor_ICJI::getEntryPointCallConv( +CorInfoCallConvExtension interceptor_ICJI::getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) { - return original_ICorJitInfo->getEntryPointCallConv(method, callSiteSig); + return original_ICorJitInfo->getUnmanagedCallConv(method, callSiteSig); } bool interceptor_ICJI::pInvokeMarshalingRequired( diff --git a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp index 71a5ef40696ef..d850cefd056cc 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp @@ -220,11 +220,11 @@ bool MyICJI::isIntrinsicType(CORINFO_CLASS_HANDLE classHnd) // return the entry point calling convention for any of the following // - a P/Invoke -// - a method marked with UnmanagedCallersOnly +// - a method marked with UnmanagedCallersOnly // - a function pointer with the CORINFO_CALLCONV_UNMANAGED calling convention. -CorInfoCallConvExtension MyICJI::getEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) +CorInfoCallConvExtension MyICJI::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) { - jitInstance->mc->cr->AddCall("getEntryPointCallConv"); + jitInstance->mc->cr->AddCall("getUnmanagedCallConv"); return jitInstance->mc->repGetEntryPointCallConv(method, callSiteSig); } @@ -1806,7 +1806,7 @@ HRESULT MyICJI::getMethodBlockCounts(CORINFO_METHOD_HANDLE ftnHnd, // Get the likely implementing class for a virtual call or interface call made by ftnHnd // at the indicated IL offset. baseHnd is the interface class or base class for the method -// being called. +// being called. CORINFO_CLASS_HANDLE MyICJI::getLikelyClass(CORINFO_METHOD_HANDLE ftnHnd, CORINFO_CLASS_HANDLE baseHnd, UINT32 ilOffset, diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 25a0c9db702b5..575bc3c7f2f56 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2083,9 +2083,11 @@ class ICorStaticInfo // return the entry point calling convention for any of the following // - a P/Invoke - // - a method marked with UnmanagedCallersOnly + // - a method marked with UnmanagedCallersOnly // - a function pointer with the CORINFO_CALLCONV_UNMANAGED calling convention. - virtual CorInfoCallConvExtension getEntryPointCallConv( + // May return CorInfoCallConvExtension::Managed when the method or call site doesn't + // use an unmanaged calling convention as an entry point. + virtual CorInfoCallConvExtension getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig ) = 0; diff --git a/src/coreclr/jit/ICorJitInfo_API_names.h b/src/coreclr/jit/ICorJitInfo_API_names.h index 6f16a1de5f47a..d5a683a12176b 100644 --- a/src/coreclr/jit/ICorJitInfo_API_names.h +++ b/src/coreclr/jit/ICorJitInfo_API_names.h @@ -22,7 +22,7 @@ DEF_CLR_API(getDefaultEqualityComparerClass) DEF_CLR_API(expandRawHandleIntrinsic) DEF_CLR_API(getIntrinsicID) DEF_CLR_API(isIntrinsicType) -DEF_CLR_API(getEntryPointCallConv) +DEF_CLR_API(getUnmanagedCallConv) DEF_CLR_API(pInvokeMarshalingRequired) DEF_CLR_API(satisfiesMethodConstraints) DEF_CLR_API(isCompatibleDelegate) diff --git a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp index 2c4b6a4bcd41d..0ca68bb1ac52b 100644 --- a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp +++ b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp @@ -191,13 +191,13 @@ bool WrapICorJitInfo::isIntrinsicType( return temp; } -CorInfoCallConvExtension WrapICorJitInfo::getEntryPointCallConv( +CorInfoCallConvExtension WrapICorJitInfo::getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) { - API_ENTER(getEntryPointCallConv); - CorInfoCallConvExtension temp = wrapHnd->getEntryPointCallConv(method, callSiteSig); - API_LEAVE(getEntryPointCallConv); + API_ENTER(getUnmanagedCallConv); + CorInfoCallConvExtension temp = wrapHnd->getUnmanagedCallConv(method, callSiteSig); + API_LEAVE(getUnmanagedCallConv); return temp; } diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 04587a902bd8d..99fabfc9c8cc1 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -2064,7 +2064,7 @@ CorInfoCallConvExtension Compiler::compMethodInfoGetEntrypointCallConv(CORINFO_M break; case CORINFO_CALLCONV_VARARG: { - CorInfoCallConvExtension callConv = info.compCompHnd->getEntryPointCallConv(mthInfo->ftn, nullptr); + CorInfoCallConvExtension callConv = info.compCompHnd->getUnmanagedCallConv(mthInfo->ftn, nullptr); if (callConv != CorInfoCallConvExtension::Managed) { callConv = CorInfoCallConvExtension::C; @@ -2078,9 +2078,12 @@ CorInfoCallConvExtension Compiler::compMethodInfoGetEntrypointCallConv(CORINFO_M return CorInfoCallConvExtension::Stdcall; case CORINFO_CALLCONV_THISCALL: return CorInfoCallConvExtension::Thiscall; + // UNMANAGED calling convention means we need to read the calling convention + // from the signature, not from the method's metadata. case CORINFO_CALLCONV_UNMANAGED: + return info.compCompHnd->getUnmanagedCallConv(nullptr, &mthInfo->args); case CORINFO_CALLCONV_DEFAULT: - return info.compCompHnd->getEntryPointCallConv(mthInfo->ftn, nullptr); + return info.compCompHnd->getUnmanagedCallConv(mthInfo->ftn, nullptr); default: BADCODE("bad calling convention"); } @@ -6123,7 +6126,14 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr, info.compHasNextCallRetAddr = false; - info.compCallConv = compMethodInfoGetEntrypointCallConv(methodInfo); + if (opts.IsReversePInvoke()) + { + info.compCallConv = compMethodInfoGetEntrypointCallConv(methodInfo); + } + else + { + info.compCallConv = CorInfoCallConvExtension::Managed; + } switch (methodInfo->args.getCallConv()) { diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 8187f3169d13b..d2d634e21b426 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -3847,7 +3847,7 @@ class Compiler CORINFO_CLASS_HANDLE impGetSpecialIntrinsicExactReturnType(CORINFO_METHOD_HANDLE specialIntrinsicHandle); - bool impMethodInfo_hasRetBuffArg(CORINFO_METHOD_INFO* methInfo); + bool impMethodInfo_hasRetBuffArg(CORINFO_METHOD_INFO* methInfo, CorInfoCallConvExtension callConv); GenTree* impFixupCallStructReturn(GenTreeCall* call, CORINFO_CLASS_HANDLE retClsHnd); @@ -9602,6 +9602,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // Gets the calling convention the method's entry point should have. CorInfoCallConvExtension compMethodInfoGetEntrypointCallConv(CORINFO_METHOD_INFO* mthInfo); + // Returns true if the method being compiled has a return buffer. + bool compHasRetBuffArg(); + #ifdef DEBUG // Components used by the compiler may write unit test suites, and // have them run within this method. They will be run only once per process, and only diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index edf68269b36f3..dd87f7e9805d9 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -7045,11 +7045,11 @@ void Compiler::impCheckForPInvokeCall( return; } - unmanagedCallConv = info.compCompHnd->getEntryPointCallConv(methHnd, nullptr); + unmanagedCallConv = info.compCompHnd->getUnmanagedCallConv(methHnd, nullptr); } else { - unmanagedCallConv = info.compCompHnd->getEntryPointCallConv(nullptr, sig); + unmanagedCallConv = info.compCompHnd->getUnmanagedCallConv(nullptr, sig); assert(!call->gtCallCookie); } @@ -9243,7 +9243,7 @@ var_types Compiler::impImportCall(OPCODE opcode, #pragma warning(pop) #endif -bool Compiler::impMethodInfo_hasRetBuffArg(CORINFO_METHOD_INFO* methInfo) +bool Compiler::impMethodInfo_hasRetBuffArg(CORINFO_METHOD_INFO* methInfo, CorInfoCallConvExtension callConv) { CorInfoType corType = methInfo->args.retType; @@ -9253,7 +9253,7 @@ bool Compiler::impMethodInfo_hasRetBuffArg(CORINFO_METHOD_INFO* methInfo) structPassingKind howToReturnStruct = SPK_Unknown; var_types returnType = - getReturnTypeForStruct(methInfo->args.retTypeClass, compMethodInfoGetEntrypointCallConv(methInfo), + getReturnTypeForStruct(methInfo->args.retTypeClass, callConv, &howToReturnStruct); if (howToReturnStruct == SPK_ByReference) @@ -19455,7 +19455,8 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo) InlLclVarInfo* lclVarInfo = pInlineInfo->lclVarInfo; InlineResult* inlineResult = pInlineInfo->inlineResult; - const bool hasRetBuffArg = impMethodInfo_hasRetBuffArg(methInfo); + // Inlined methods always use the managed calling convention + const bool hasRetBuffArg = impMethodInfo_hasRetBuffArg(methInfo, CorInfoCallConvExtension::Managed); /* init the argument stuct */ diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index a81f70a2e5cd1..49a2879a4a2bd 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -135,7 +135,7 @@ void Compiler::lvaInitTypeRef() // Are we returning a struct using a return buffer argument? // - const bool hasRetBuffArg = impMethodInfo_hasRetBuffArg(info.compMethodInfo); + const bool hasRetBuffArg = impMethodInfo_hasRetBuffArg(info.compMethodInfo, info.compCallConv); // Possibly change the compRetNativeType from TYP_STRUCT to a "primitive" type // when we are returning a struct by value and it fits in one register @@ -503,7 +503,7 @@ void Compiler::lvaInitThisPtr(InitVarDscInfo* varDscInfo) void Compiler::lvaInitRetBuffArg(InitVarDscInfo* varDscInfo, bool useFixedRetBufReg) { LclVarDsc* varDsc = varDscInfo->varDsc; - bool hasRetBuffArg = impMethodInfo_hasRetBuffArg(info.compMethodInfo); + bool hasRetBuffArg = impMethodInfo_hasRetBuffArg(info.compMethodInfo, info.compCallConv); // These two should always match noway_assert(hasRetBuffArg == varDscInfo->hasRetBufArg); diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs index 61fe944d2608f..4d3e03e6f0436 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs @@ -281,7 +281,7 @@ static CorInfoCallConvExtension _getEntryPointCallConv(IntPtr thisHandle, IntPtr var _this = GetThis(thisHandle); try { - return _this.getEntryPointCallConv(method, callSiteSig); + return _this.getUnmanagedCallConv(method, callSiteSig); } catch (Exception ex) { diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index a79356e9feb49..186f0a5d7b10a 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -699,7 +699,7 @@ private CorInfoType asCorInfoType(TypeDesc type, out TypeDesc typeIfNotPrimitive typeIfNotPrimitive = null; return CorInfoType.CORINFO_TYPE_PTR; } - + typeIfNotPrimitive = type; if (type.IsByRef) @@ -1060,7 +1060,7 @@ private MethodSignatureFlags PlatformDefaultUnmanagedCallingConvention() MethodSignatureFlags.UnmanagedCallingConventionStdCall : MethodSignatureFlags.UnmanagedCallingConventionCdecl; } - private CorInfoCallConvExtension getEntryPointCallConv(CORINFO_METHOD_STRUCT_* method, CORINFO_SIG_INFO* sig) + private CorInfoCallConvExtension getUnmanagedCallConv(CORINFO_METHOD_STRUCT_* method, CORINFO_SIG_INFO* sig) { Debug.Assert(method != null || sig != null); if (method != null) @@ -1086,7 +1086,8 @@ private CorInfoCallConvExtension getEntryPointCallConv(CORINFO_METHOD_STRUCT_* m return GetUnmanagedCallingConventionFromAttribute(unmanagedCallersOnlyAttribute); } return CorInfoCallConvExtension.Managed; - } // Unmanaged calling convention indicates modopt should be read + } + // Unmanaged calling convention indicates modopt should be read else if (sig->callConv == CorInfoCallConv.CORINFO_CALLCONV_UNMANAGED) { if (TryGetUnmanagedCallingConventionFromModOpt((MethodSignature)HandleToObject((IntPtr)sig->pSig), out CorInfoCallConvExtension callConvMaybe)) @@ -1716,7 +1717,7 @@ static bool ShouldAlign8(DefType type) { if (field.IsStatic) continue; - + instanceFields++; if (field.FieldType == doubleType) @@ -3069,7 +3070,7 @@ private ref ArrayBuilder findRelocBlock(BlockType blockType, out int length = _roData.Length; return ref _roDataRelocs; default: - throw new NotImplementedException("Arbitrary relocs"); + throw new NotImplementedException("Arbitrary relocs"); } } diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 72d93b5b03c8f..0be42e4dbfaa6 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -1,18 +1,18 @@ ; Licensed to the .NET Foundation under one or more agreements. ; The .NET Foundation licenses this file to you under the MIT license. ; -; Thunk generator input file for generating the thunks from the C++ version of the -; jit interface to COM, into managed, and from COM to C++. +; Thunk generator input file for generating the thunks from the C++ version of the +; jit interface to COM, into managed, and from COM to C++. ; -; The format of this file is as follows. +; The format of this file is as follows. ; There are NORMALTYPES, RETURNTYPES, and FUNCTIONS regions -; In the NORMALTYPES/RETURNTYPES region, each type is described. If a type is +; In the NORMALTYPES/RETURNTYPES region, each type is described. If a type is ; described in the NORMALTYPES section, but isn't described in the RETURNTYPES section ; then the NORMALTYPES description can be used for a return value. ; ; TYPES have three fields ; ThunkDescriptionType,ManagedType,NativeType,NativeType2 -; If either ManagedType, NativeType, or NativeType2 are missing, then that form is replaced with ThunkDescriptionType. +; If either ManagedType, NativeType, or NativeType2 are missing, then that form is replaced with ThunkDescriptionType. ; NativeType is used for representing the type in headers which do not include the PAL and corinfo.h ; NativeType2 is used for representing the type in headers that are fully integrated with the PAL ; This feature allows reduction in type for enums and other types where the same type can be used in managed an native @@ -24,12 +24,12 @@ ; PointerToIntPointer,int**,int** ; ; Following the TYPES sections, there is the FUNCTIONS section -; Each function that is to be part of the interface is written here. The format is basically the C++ format +; Each function that is to be part of the interface is written here. The format is basically the C++ format ; without support for inline comments or sal annotations. ; ; Also, note that an empty line is ignored, and a line that begins with a ; is ignored. ; -; If the boilerplate around the individual functions needs adjustment, edit the thunk generator source code, and +; If the boilerplate around the individual functions needs adjustment, edit the thunk generator source code, and ; rebuild with rebuildthunkgen.cmd in the the ThunkGenerator subdir, then rebuildthunks.cmd ; If this file is editted, rebuild with gen.cmd -- DO NOT RUN from within a razzle window. ; @@ -176,7 +176,7 @@ FUNCTIONS void expandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_GENERICHANDLE_RESULT * pResult); CorInfoIntrinsics getIntrinsicID( CORINFO_METHOD_HANDLE method , BoolStar pMustExpand); bool isIntrinsicType( CORINFO_CLASS_HANDLE classHnd ); - CorInfoCallConvExtension getEntryPointCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); + CorInfoCallConvExtension getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); bool pInvokeMarshalingRequired( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig ); bool satisfiesMethodConstraints( CORINFO_CLASS_HANDLE parent, CORINFO_METHOD_HANDLE method ); bool isCompatibleDelegate( CORINFO_CLASS_HANDLE objCls, CORINFO_CLASS_HANDLE methodParentCls, CORINFO_METHOD_HANDLE method, CORINFO_CLASS_HANDLE delegateCls, bool *pfIsOpenDelegate ); diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface.h b/src/coreclr/tools/aot/jitinterface/jitinterface.h index b8b523bda6663..0d9cdf57d1582 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface.h @@ -28,7 +28,7 @@ struct JitInterfaceCallbacks void (* expandRawHandleIntrinsic)(void * thisHandle, CorInfoExceptionClass** ppException, void* pResolvedToken, void* pResult); int (* getIntrinsicID)(void * thisHandle, CorInfoExceptionClass** ppException, void* method, bool* pMustExpand); bool (* isIntrinsicType)(void * thisHandle, CorInfoExceptionClass** ppException, void* classHnd); - int (* getEntryPointCallConv)(void * thisHandle, CorInfoExceptionClass** ppException, void* method, void* callSiteSig); + int (* getUnmanagedCallConv)(void * thisHandle, CorInfoExceptionClass** ppException, void* method, void* callSiteSig); bool (* pInvokeMarshalingRequired)(void * thisHandle, CorInfoExceptionClass** ppException, void* method, void* callSiteSig); bool (* satisfiesMethodConstraints)(void * thisHandle, CorInfoExceptionClass** ppException, void* parent, void* method); bool (* isCompatibleDelegate)(void * thisHandle, CorInfoExceptionClass** ppException, void* objCls, void* methodParentCls, void* method, void* delegateCls, bool* pfIsOpenDelegate); @@ -375,12 +375,12 @@ class JitInterfaceWrapper return temp; } - virtual int getEntryPointCallConv( + virtual int getUnmanagedCallConv( void* method, void* callSiteSig) { CorInfoExceptionClass* pException = nullptr; - int temp = _callbacks->getEntryPointCallConv(_thisHandle, &pException, method, callSiteSig); + int temp = _callbacks->getUnmanagedCallConv(_thisHandle, &pException, method, callSiteSig); if (pException != nullptr) throw pException; return temp; } diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 815daa0f7c62a..b769d714b90df 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -8908,7 +8908,7 @@ bool CEEInfo::resolveVirtualMethodHelper(CORINFO_DEVIRTUALIZATION_INFO * info) return false; } - // For generic interface methods we must have context to + // For generic interface methods we must have context to // safely devirtualize. if (info->context != nullptr) { @@ -9795,9 +9795,9 @@ CorInfoHFAElemType CEEInfo::getHFAType(CORINFO_CLASS_HANDLE hClass) // return the entry point calling convention for any of the following // - a P/Invoke - // - a method marked with UnmanagedCallersOnly + // - a method marked with UnmanagedCallersOnly // - a function pointer with the CORINFO_CALLCONV_UNMANAGED calling convention. -CorInfoCallConvExtension CEEInfo::getEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) +CorInfoCallConvExtension CEEInfo::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) { CONTRACTL { THROWS; @@ -9814,35 +9814,27 @@ CorInfoCallConvExtension CEEInfo::getEntryPointCallConv(CORINFO_METHOD_HANDLE me if (method) { MethodDesc* pMD = GetMethod(method); + _ASSERTE(pMD->IsNDirect() || pMD->HasUnmanagedCallersOnlyAttribute()); if(pMD->IsNDirect()) { - EX_TRY + PInvokeStaticSigInfo sigInfo(pMD, PInvokeStaticSigInfo::NO_THROW_ON_ERROR); + switch (sigInfo.GetCallConv()) { - PInvokeStaticSigInfo sigInfo(pMD, PInvokeStaticSigInfo::NO_THROW_ON_ERROR); - - switch (sigInfo.GetCallConv()) { - case pmCallConvCdecl: - callConv = CorInfoCallConvExtension::C; - break; - case pmCallConvStdcall: - callConv = CorInfoCallConvExtension::Stdcall; - break; - case pmCallConvThiscall: - callConv = CorInfoCallConvExtension::Thiscall; - break; - default: - callConv = CorInfoCallConvExtension::Managed; - break; - } - } - EX_CATCH - { - callConv = CorInfoCallConvExtension::Managed; + case pmCallConvCdecl: + callConv = CorInfoCallConvExtension::C; + break; + case pmCallConvStdcall: + callConv = CorInfoCallConvExtension::Stdcall; + break; + case pmCallConvThiscall: + callConv = CorInfoCallConvExtension::Thiscall; + break; + default: + callConv = CorInfoCallConvExtension::Managed; + break; } - EX_END_CATCH(SwallowAllExceptions) } -#if !defined(TARGET_X86) - else if (pMD->HasUnmanagedCallersOnlyAttribute()) + else { #ifdef CROSSGEN_COMPILE _ASSERTE_MSG(false, "UnmanagedCallersOnly methods are not supported in crossgen and should be rejected before getting here."); @@ -9873,7 +9865,6 @@ CorInfoCallConvExtension CEEInfo::getEntryPointCallConv(CORINFO_METHOD_HANDLE me } #endif // CROSSGEN_COMPILE } -#endif // !defined(TARGET_X86) } else if (callSiteSig->callConv == CORINFO_CALLCONV_UNMANAGED) { diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 372f71ad08a1b..fb83f60600270 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -756,9 +756,9 @@ class CEEInfo : public ICorJitInfo bool * pMustExpand = NULL); bool isIntrinsicType(CORINFO_CLASS_HANDLE classHnd); - - CorInfoCallConvExtension getEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); - + + CorInfoCallConvExtension getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); + bool pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); // Generate a cookie based on the signature that would needs to be passed @@ -917,7 +917,7 @@ class CEEInfo : public ICorJitInfo bool convertPInvokeCalliToCall(CORINFO_RESOLVED_TOKEN * pResolvedToken, bool fMustConvert); - bool notifyInstructionSetUsage(CORINFO_InstructionSet instructionSet, + bool notifyInstructionSetUsage(CORINFO_InstructionSet instructionSet, bool supportEnabled); void getFunctionEntryPoint(CORINFO_METHOD_HANDLE ftn, /* IN */ @@ -1040,7 +1040,7 @@ class CEEInfo : public ICorJitInfo CORINFO_CLASS_HANDLE getLikelyClass( CORINFO_METHOD_HANDLE ftnHnd, CORINFO_CLASS_HANDLE baseHnd, - UINT32 ilOffset, + UINT32 ilOffset, UINT32 * pLikelihood, UINT32 * pNumberOfClasses ); diff --git a/src/coreclr/zap/zapinfo.cpp b/src/coreclr/zap/zapinfo.cpp index 29196db050e6c..04def45a28524 100644 --- a/src/coreclr/zap/zapinfo.cpp +++ b/src/coreclr/zap/zapinfo.cpp @@ -399,7 +399,7 @@ void ZapInfo::CompileMethod() // only do it when we are truely logging m_zapper->Info(W("Compiling method %s\n"), m_currentMethodName.GetUnicode()); } - + if (GetCompileInfo()->IsUnmanagedCallersOnlyMethod(m_currentMethodHandle)) { if (m_zapper->m_pOpt->m_verbose) @@ -2206,7 +2206,7 @@ DWORD FilterNamedIntrinsicMethodAttribs(ZapInfo* pZapInfo, DWORD attribs, CORINF } #else fTreatAsRegularMethodCall |= !fIsPlatformHWIntrinsic && fIsHWIntrinsic; -#endif +#endif if (fIsPlatformHWIntrinsic) { @@ -4045,9 +4045,9 @@ bool ZapInfo::isIntrinsicType(CORINFO_CLASS_HANDLE classHnd) return m_pEEJitInfo->isIntrinsicType(classHnd); } -CorInfoCallConvExtension ZapInfo::getEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) +CorInfoCallConvExtension ZapInfo::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) { - return m_pEEJitInfo->getEntryPointCallConv(method, sig); + return m_pEEJitInfo->getUnmanagedCallConv(method, sig); } bool ZapInfo::pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, diff --git a/src/coreclr/zap/zapinfo.h b/src/coreclr/zap/zapinfo.h index b47e80bc8e200..91378d81ee3a1 100644 --- a/src/coreclr/zap/zapinfo.h +++ b/src/coreclr/zap/zapinfo.h @@ -691,7 +691,7 @@ class ZapInfo CorInfoIntrinsics getIntrinsicID(CORINFO_METHOD_HANDLE method, bool * pMustExpand = NULL); bool isIntrinsicType(CORINFO_CLASS_HANDLE classHnd); - CorInfoCallConvExtension getEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + CorInfoCallConvExtension getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); bool pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); LPVOID GetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void ** ppIndirecton); From b809ff82198511f07a2454583d79c4468426ed79 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 10 Dec 2020 16:53:39 -0800 Subject: [PATCH 20/38] Pass SuppressGCTransition through the getUnmanagedCallConv JIT-EE interface API. --- .../superpmi-shared/icorjitinfoimpl.h | 3 +- .../superpmi/superpmi-shared/lwmlist.h | 2 +- .../superpmi-shared/methodcontext.cpp | 40 ++++++++++--------- .../superpmi/superpmi-shared/methodcontext.h | 11 +++-- .../superpmi-shim-collector/icorjitinfo.cpp | 6 +-- .../superpmi-shim-counter/icorjitinfo.cpp | 5 ++- .../superpmi-shim-simple/icorjitinfo.cpp | 5 ++- .../ToolBox/superpmi/superpmi/icorjitinfo.cpp | 4 +- src/coreclr/inc/corinfo.h | 5 ++- src/coreclr/jit/ICorJitInfo_API_wrapper.hpp | 5 ++- src/coreclr/jit/importer.cpp | 12 +++--- .../tools/Common/JitInterface/CorInfoBase.cs | 6 +-- .../tools/Common/JitInterface/CorInfoImpl.cs | 26 +++++------- .../tools/Common/JitInterface/CorInfoTypes.cs | 7 ++-- .../ThunkGenerator/ThunkInput.txt | 2 +- .../tools/aot/jitinterface/jitinterface.h | 7 ++-- src/coreclr/vm/jitinterface.cpp | 14 +++++-- src/coreclr/vm/jitinterface.h | 3 +- src/coreclr/zap/zapinfo.cpp | 4 +- src/coreclr/zap/zapinfo.h | 2 +- 20 files changed, 89 insertions(+), 80 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h index 1d0c4c63578af..d8fee51378161 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h @@ -103,7 +103,8 @@ bool isIntrinsicType( CorInfoCallConvExtension getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* callSiteSig); + CORINFO_SIG_INFO* callSiteSig, + bool* pSuppressGCTransition); bool pInvokeMarshalingRequired( CORINFO_METHOD_HANDLE method, diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h index 5a40bddc997bf..b1c4a4047478f 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h @@ -154,7 +154,7 @@ LWM(ResolveVirtualMethod, Agnostic_ResolveVirtualMethodKey, Agnostic_ResolveVirt LWM(TryResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, TryResolveTokenValue) LWM(SatisfiesClassConstraints, DWORDLONG, DWORD) LWM(SatisfiesMethodConstraints, DLDL, DWORD) -LWM(GetEntryPointCallConv, MethodSigInfoPairValue, DWORD) +LWM(GetUnmanagedCallConv, MethodSigInfoPairValue, DD) #undef LWM diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index 27cdcf5adf3cc..d781f4d15c4df 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -3057,7 +3057,7 @@ void MethodContext::recResolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO * info key.context = (DWORDLONG)info->context; Agnostic_ResolveVirtualMethodResult result; result.returnValue = returnValue; - result.devirtualizedMethod = (DWORDLONG)info->devirtualizedMethod; + result.devirtualizedMethod = (DWORDLONG)info->devirtualizedMethod; result.requiresInstMethodTableArg = info->requiresInstMethodTableArg; result.exactContext = (DWORDLONG)info->exactContext; ResolveVirtualMethod->Add(key, result); @@ -3781,12 +3781,13 @@ bool MethodContext::repPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, C return value; } -void MethodContext::recGetEntryPointCallConv(CORINFO_METHOD_HANDLE method, +void MethodContext::recGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, - CorInfoCallConvExtension result) + CorInfoCallConvExtension result, + bool suppressGCTransitionResult) { - if (GetEntryPointCallConv == nullptr) - GetEntryPointCallConv = new LightWeightMap(); + if (GetUnmanagedCallConv == nullptr) + GetUnmanagedCallConv = new LightWeightMap(); MethodSigInfoPairValue key; ZeroMemory(&key, sizeof(MethodSigInfoPairValue)); // We use the input structs as a key and use memcmp to @@ -3797,24 +3798,24 @@ void MethodContext::recGetEntryPointCallConv(CORINFO_METHOD_HANDLE method, key.cbSig = (DWORD)callSiteSig->cbSig; key.scope = (DWORDLONG)callSiteSig->scope; - GetEntryPointCallConv->Add(key, (DWORD)result); - DEBUG_REC(dmpGetEntryPointCallConv(key, (DWORD)result)); + GetUnmanagedCallConv->Add(key, { (DWORD)result, (DWORD)suppressGCTransitionResult }); + DEBUG_REC(dmpGetUnmanagedCallConv(key, { (DWORD)result, (DWORD)suppressGCTransitionResult })); } -void MethodContext::dmpGetEntryPointCallConv(const MethodSigInfoPairValue& key, DWORD value) +void MethodContext::dmpGetUnmanagedCallConv(const MethodSigInfoPairValue& key, DD value) { - printf("GetEntryPointCallConv key mth-%016llX scp-%016llX sig-%u, value res-%u", key.method, key.scope, - key.pSig_Index, value); + printf("GetUnmanagedCallConv key mth-%016llX scp-%016llX sig-%u, value res-%u,%u", key.method, key.scope, + key.pSig_Index, value.A, value.B); } // Note the jit interface implementation seems to only care about scope and pSig from callSiteSig -CorInfoCallConvExtension MethodContext::repGetEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) +CorInfoCallConvExtension MethodContext::repGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition) { - if (GetEntryPointCallConv == nullptr) + if (GetUnmanagedCallConv == nullptr) { #ifdef sparseMC - LogDebug("Sparse - repGetEntryPointCallConv returning CorInfoCallConvExtension::Managed"); + LogDebug("Sparse - repGetUnmanagedCallConv returning CorInfoCallConvExtension::Managed"); return CorInfoCallConvExtension::Managed; #else - LogException(EXCEPTIONCODE_MC, "Found a null GetUnmGetEntryPointCallConvanagedCallConv. Probably missing a fatTrigger for %016llX.", + LogException(EXCEPTIONCODE_MC, "Found a null GetUnmGetUnmanagedCallConvanagedCallConv. Probably missing a fatTrigger for %016llX.", (DWORDLONG)method); #endif } @@ -3824,13 +3825,14 @@ CorInfoCallConvExtension MethodContext::repGetEntryPointCallConv(CORINFO_METHOD_ // compare.. so we need to zero out padding too key.method = (DWORDLONG)method; - key.pSig_Index = (DWORD)GetEntryPointCallConv->Contains((unsigned char*)callSiteSig->pSig, callSiteSig->cbSig); + key.pSig_Index = (DWORD)GetUnmanagedCallConv->Contains((unsigned char*)callSiteSig->pSig, callSiteSig->cbSig); key.cbSig = (DWORD)callSiteSig->cbSig; key.scope = (DWORDLONG)callSiteSig->scope; - DWORD value = GetEntryPointCallConv->Get(key); - DEBUG_REP(dmpGetEntryPointCallConv(key, value)); - return (CorInfoCallConvExtension)value; + DD value = GetUnmanagedCallConv->Get(key); + DEBUG_REP(dmpGetUnmanagedCallConv(key, value)); + *pSuppressGCTransition = value.B != 0; + return (CorInfoCallConvExtension)value.A; } void MethodContext::recFindSig(CORINFO_MODULE_HANDLE module, @@ -5313,7 +5315,7 @@ void MethodContext::recGetLikelyClass(CORINFO_METHOD_HANDLE ftnHnd, CORINFO_CLAS } void MethodContext::dmpGetLikelyClass(const Agnostic_GetLikelyClass& key, const Agnostic_GetLikelyClassResult& value) { - printf("GetLikelyClass key ftn-%016llX base-%016llX il-%u, class-%016llX likelihood-%u numberOfClasses-%u", + printf("GetLikelyClass key ftn-%016llX base-%016llX il-%u, class-%016llX likelihood-%u numberOfClasses-%u", key.ftnHnd, key.baseHnd, key.ilOffset, value.classHnd, value.likelihood, value.numberOfClasses); } CORINFO_CLASS_HANDLE MethodContext::repGetLikelyClass(CORINFO_METHOD_HANDLE ftnHnd, CORINFO_CLASS_HANDLE baseHnd, UINT32 ilOffset, UINT32* pLikelihood, UINT32* pNumberOfClasses) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h index 94bc32579ef0d..edd10e484c975 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h @@ -1001,10 +1001,10 @@ class MethodContext void recPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool result); void dmpPInvokeMarshalingRequired(const MethodSigInfoPairValue& key, DWORD value); bool repPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); - - void recGetEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, CorInfoCallConvExtension result); - void dmpGetEntryPointCallConv(const MethodSigInfoPairValue& key, DWORD value); - CorInfoCallConvExtension repGetEntryPointCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); + + void recGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, CorInfoCallConvExtension result, bool suppressGCTransitionResult); + void dmpGetUnmanagedCallConv(const MethodSigInfoPairValue& key, DD value); + CorInfoCallConvExtension repGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition); void recFindSig(CORINFO_MODULE_HANDLE module, unsigned sigTOK, @@ -1513,8 +1513,7 @@ enum mcPackets Packet_GetUnBoxHelper = 92, Packet_GetReadyToRunHelper = 150, // Added 10/10/2014 Packet_GetReadyToRunDelegateCtorHelper = 157, // Added 3/30/2016 - Packet_GetUnmanagedCallConv = 94, // Retired 12/9/2020 - Packet_GetEntryPointCallConv = 183, // Added 12/8/2020 + Packet_GetUnmanagedCallConv = 94, Packet_GetVarArgsHandle = 95, Packet_GetVars = 96, Packet_HandleException = 135, diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp index a7378fc663dfc..b001578311c6c 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -293,11 +293,11 @@ bool interceptor_ICJI::isIntrinsicType(CORINFO_CLASS_HANDLE classHnd) // - a P/Invoke // - a method marked with UnmanagedCallersOnly // - a function pointer with the CORINFO_CALLCONV_UNMANAGED calling convention. -CorInfoCallConvExtension interceptor_ICJI::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) +CorInfoCallConvExtension interceptor_ICJI::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition) { mc->cr->AddCall("getUnmanagedCallConv"); - CorInfoCallConvExtension temp = original_ICorJitInfo->getUnmanagedCallConv(method, callSiteSig); - mc->recGetEntryPointCallConv(method, callSiteSig, temp); + CorInfoCallConvExtension temp = original_ICorJitInfo->getUnmanagedCallConv(method, callSiteSig, pSuppressGCTransition); + mc->recGetUnmanagedCallConv(method, callSiteSig, temp, *pSuppressGCTransition); return temp; } diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp index f59015994f7d5..359a4bf55523c 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp @@ -164,10 +164,11 @@ bool interceptor_ICJI::isIntrinsicType( CorInfoCallConvExtension interceptor_ICJI::getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* callSiteSig) + CORINFO_SIG_INFO* callSiteSig, + bool* pSuppressGCTransition) { mcs->AddCall("getUnmanagedCallConv"); - return original_ICorJitInfo->getUnmanagedCallConv(method, callSiteSig); + return original_ICorJitInfo->getUnmanagedCallConv(method, callSiteSig, pSuppressGCTransition); } bool interceptor_ICJI::pInvokeMarshalingRequired( diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp index 10aff10d027cc..22c019ab80c4e 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp @@ -146,9 +146,10 @@ bool interceptor_ICJI::isIntrinsicType( CorInfoCallConvExtension interceptor_ICJI::getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* callSiteSig) + CORINFO_SIG_INFO* callSiteSig, + bool* pSuppressGCTransition) { - return original_ICorJitInfo->getUnmanagedCallConv(method, callSiteSig); + return original_ICorJitInfo->getUnmanagedCallConv(method, callSiteSig, pSuppressGCTransition); } bool interceptor_ICJI::pInvokeMarshalingRequired( diff --git a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp index d850cefd056cc..c210e18798516 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/icorjitinfo.cpp @@ -222,10 +222,10 @@ bool MyICJI::isIntrinsicType(CORINFO_CLASS_HANDLE classHnd) // - a P/Invoke // - a method marked with UnmanagedCallersOnly // - a function pointer with the CORINFO_CALLCONV_UNMANAGED calling convention. -CorInfoCallConvExtension MyICJI::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) +CorInfoCallConvExtension MyICJI::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition) { jitInstance->mc->cr->AddCall("getUnmanagedCallConv"); - return jitInstance->mc->repGetEntryPointCallConv(method, callSiteSig); + return jitInstance->mc->repGetUnmanagedCallConv(method, callSiteSig, pSuppressGCTransition); } // return if any marshaling is required for PInvoke methods. Note that diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 575bc3c7f2f56..75bf47e540e78 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -1070,7 +1070,7 @@ enum CorInfoSigInfoFlags { CORINFO_SIGFLAG_IS_LOCAL_SIG = 0x01, CORINFO_SIGFLAG_IL_STUB = 0x02, - CORINFO_SIGFLAG_SUPPRESS_GC_TRANSITION = 0x04, + // unused = 0x04, CORINFO_SIGFLAG_FAT_CALL = 0x08, }; @@ -2089,7 +2089,8 @@ class ICorStaticInfo // use an unmanaged calling convention as an entry point. virtual CorInfoCallConvExtension getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* callSiteSig + CORINFO_SIG_INFO* callSiteSig, + bool* pSuppressGCTransition = NULL /* OUT */ ) = 0; // return if any marshaling is required for PInvoke methods. Note that diff --git a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp index 0ca68bb1ac52b..0788bc6af4e3c 100644 --- a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp +++ b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp @@ -193,10 +193,11 @@ bool WrapICorJitInfo::isIntrinsicType( CorInfoCallConvExtension WrapICorJitInfo::getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, - CORINFO_SIG_INFO* callSiteSig) + CORINFO_SIG_INFO* callSiteSig, + bool* pSuppressGCTransition) { API_ENTER(getUnmanagedCallConv); - CorInfoCallConvExtension temp = wrapHnd->getUnmanagedCallConv(method, callSiteSig); + CorInfoCallConvExtension temp = wrapHnd->getUnmanagedCallConv(method, callSiteSig, pSuppressGCTransition); API_LEAVE(getUnmanagedCallConv); return temp; } diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index dd87f7e9805d9..6af32e07f1718 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -7033,11 +7033,6 @@ void Compiler::impCheckForPInvokeCall( call->gtCallMoreFlags |= GTF_CALL_M_PINVOKE; } - if ((sig->flags & CORINFO_SIGFLAG_SUPPRESS_GC_TRANSITION) != 0) - { - call->gtCallMoreFlags |= GTF_CALL_M_SUPPRESS_GC_TRANSITION; - } - if (methHnd) { if ((mflags & CORINFO_FLG_PINVOKE) == 0) @@ -7045,7 +7040,12 @@ void Compiler::impCheckForPInvokeCall( return; } - unmanagedCallConv = info.compCompHnd->getUnmanagedCallConv(methHnd, nullptr); + bool suppressGCTransition = false; + unmanagedCallConv = info.compCompHnd->getUnmanagedCallConv(methHnd, nullptr, &suppressGCTransition); + if (suppressGCTransition) + { + call->gtCallMoreFlags |= GTF_CALL_M_SUPPRESS_GC_TRANSITION; + } } else { diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs index 4d3e03e6f0436..48fdb2e7c6785 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs @@ -276,12 +276,12 @@ static byte _isIntrinsicType(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLA } [UnmanagedCallersOnly] - static CorInfoCallConvExtension _getEntryPointCallConv(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method, CORINFO_SIG_INFO* callSiteSig) + static CorInfoCallConvExtension _getUnmanagedCallConv(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method, CORINFO_SIG_INFO* callSiteSig, byte* pSuppressGCTransition) { var _this = GetThis(thisHandle); try { - return _this.getUnmanagedCallConv(method, callSiteSig); + return _this.getUnmanagedCallConv(method, callSiteSig, pSuppressGCTransition); } catch (Exception ex) { @@ -2556,7 +2556,7 @@ static IntPtr GetUnmanagedCallbacks() callbacks[15] = (delegate* unmanaged)&_expandRawHandleIntrinsic; callbacks[16] = (delegate* unmanaged)&_getIntrinsicID; callbacks[17] = (delegate* unmanaged)&_isIntrinsicType; - callbacks[18] = (delegate* unmanaged)&_getEntryPointCallConv; + callbacks[18] = (delegate* unmanaged)&_getUnmanagedCallConv; callbacks[19] = (delegate* unmanaged)&_pInvokeMarshalingRequired; callbacks[20] = (delegate* unmanaged)&_satisfiesMethodConstraints; callbacks[21] = (delegate* unmanaged)&_isCompatibleDelegate; diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 186f0a5d7b10a..2f40c9faa3cfa 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -486,11 +486,6 @@ private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, bool { Get_CORINFO_SIG_INFO(method.Signature, sig); - if (method.IsPInvoke && method.IsSuppressGCTransition()) - { - sig->flags |= CorInfoSigInfoFlags.CORINFO_SIGFLAG_SUPPRESS_GC_TRANSITION; - } - // Does the method have a hidden parameter? bool hasHiddenParameter = !suppressHiddenArgument && method.RequiresInstArg(); @@ -1060,14 +1055,23 @@ private MethodSignatureFlags PlatformDefaultUnmanagedCallingConvention() MethodSignatureFlags.UnmanagedCallingConventionStdCall : MethodSignatureFlags.UnmanagedCallingConventionCdecl; } - private CorInfoCallConvExtension getUnmanagedCallConv(CORINFO_METHOD_STRUCT_* method, CORINFO_SIG_INFO* sig) + private CorInfoCallConvExtension getUnmanagedCallConv(CORINFO_METHOD_STRUCT_* method, CORINFO_SIG_INFO* sig, byte* pSuppressGCTransition) { + if (pSuppressGCTransition != null) + { + *pSuppressGCTransition = 0; + } + Debug.Assert(method != null || sig != null); if (method != null) { MethodDesc methodDesc = HandleToObject(method); if (methodDesc.IsPInvoke) { + if (pSuppressGCTransition != null) + { + *pSuppressGCTransition = methodDesc.IsSuppressGCTransition() ? 1 : 0; + } MethodSignatureFlags unmanagedCallConv = HandleToObject(method).GetPInvokeMethodMetadata().Flags.UnmanagedCallingConvention; if (unmanagedCallConv == MethodSignatureFlags.None) @@ -1362,16 +1366,6 @@ private void findSig(CORINFO_MODULE_STRUCT_* module, uint sigTOK, CORINFO_CONTEX Get_CORINFO_SIG_INFO(methodSig, sig); - // TODO: Replace this with a public mechanism to mark calli with SuppressGCTransition once it becomes available. - if (methodIL is PInvokeILStubMethodIL stubIL) - { - var method = stubIL.OwningMethod; - if (method.IsPInvoke && method.IsSuppressGCTransition()) - { - sig->flags |= CorInfoSigInfoFlags.CORINFO_SIGFLAG_SUPPRESS_GC_TRANSITION; - } - } - #if !READYTORUN // Check whether we need to report this as a fat pointer call if (_compilation.IsFatPointerCandidate(methodIL.OwningMethod, methodSig)) diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index b6e41e9fa3fe1..5b09442379700 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -63,7 +63,7 @@ public struct CORINFO_JUST_MY_CODE_HANDLE_ public struct CORINFO_VarArgInfo { } - + public struct PatchpointInfo { } @@ -331,7 +331,7 @@ public enum CorInfoCallConv CORINFO_CALLCONV_EXPLICITTHIS = 0x40, CORINFO_CALLCONV_PARAMTYPE = 0x80, // Passed last. Same as CORINFO_GENERICS_CTXT_FROM_PARAMTYPEARG } - + // Represents the calling conventions supported with the extensible calling convention syntax // as well as the original metadata-encoded calling conventions. enum CorInfoCallConvExtension @@ -369,7 +369,8 @@ public enum CorInfoSigInfoFlags : byte { CORINFO_SIGFLAG_IS_LOCAL_SIG = 0x01, CORINFO_SIGFLAG_IL_STUB = 0x02, - CORINFO_SIGFLAG_SUPPRESS_GC_TRANSITION = 0x04, + + // unused = 0x04, CORINFO_SIGFLAG_FAT_CALL = 0x08, }; diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 0be42e4dbfaa6..4c185f4c7d316 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -176,7 +176,7 @@ FUNCTIONS void expandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_GENERICHANDLE_RESULT * pResult); CorInfoIntrinsics getIntrinsicID( CORINFO_METHOD_HANDLE method , BoolStar pMustExpand); bool isIntrinsicType( CORINFO_CLASS_HANDLE classHnd ); - CorInfoCallConvExtension getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); + CorInfoCallConvExtension getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, BoolStar pSuppressGCTransition); bool pInvokeMarshalingRequired( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig ); bool satisfiesMethodConstraints( CORINFO_CLASS_HANDLE parent, CORINFO_METHOD_HANDLE method ); bool isCompatibleDelegate( CORINFO_CLASS_HANDLE objCls, CORINFO_CLASS_HANDLE methodParentCls, CORINFO_METHOD_HANDLE method, CORINFO_CLASS_HANDLE delegateCls, bool *pfIsOpenDelegate ); diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface.h b/src/coreclr/tools/aot/jitinterface/jitinterface.h index 0d9cdf57d1582..1d94c382277e5 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface.h @@ -28,7 +28,7 @@ struct JitInterfaceCallbacks void (* expandRawHandleIntrinsic)(void * thisHandle, CorInfoExceptionClass** ppException, void* pResolvedToken, void* pResult); int (* getIntrinsicID)(void * thisHandle, CorInfoExceptionClass** ppException, void* method, bool* pMustExpand); bool (* isIntrinsicType)(void * thisHandle, CorInfoExceptionClass** ppException, void* classHnd); - int (* getUnmanagedCallConv)(void * thisHandle, CorInfoExceptionClass** ppException, void* method, void* callSiteSig); + int (* getUnmanagedCallConv)(void * thisHandle, CorInfoExceptionClass** ppException, void* method, void* callSiteSig, bool* pSuppressGCTransition); bool (* pInvokeMarshalingRequired)(void * thisHandle, CorInfoExceptionClass** ppException, void* method, void* callSiteSig); bool (* satisfiesMethodConstraints)(void * thisHandle, CorInfoExceptionClass** ppException, void* parent, void* method); bool (* isCompatibleDelegate)(void * thisHandle, CorInfoExceptionClass** ppException, void* objCls, void* methodParentCls, void* method, void* delegateCls, bool* pfIsOpenDelegate); @@ -377,10 +377,11 @@ class JitInterfaceWrapper virtual int getUnmanagedCallConv( void* method, - void* callSiteSig) + void* callSiteSig, + bool* pSuppressGCTransition) { CorInfoExceptionClass* pException = nullptr; - int temp = _callbacks->getUnmanagedCallConv(_thisHandle, &pException, method, callSiteSig); + int temp = _callbacks->getUnmanagedCallConv(_thisHandle, &pException, method, callSiteSig, pSuppressGCTransition); if (pException != nullptr) throw pException; return temp; } diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index b769d714b90df..16b7410152d4e 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -457,8 +457,6 @@ CEEInfo::ConvToJitSig( if (context.methodContext) { SigTypeContext::InitTypeContext(context.methodContext, context.typeContext, &typeContext); - if (context.methodContext->ShouldSuppressGCTransition()) - sigRetFlags |= CORINFO_SIGFLAG_SUPPRESS_GC_TRANSITION; } else { @@ -9797,7 +9795,7 @@ CorInfoHFAElemType CEEInfo::getHFAType(CORINFO_CLASS_HANDLE hClass) // - a P/Invoke // - a method marked with UnmanagedCallersOnly // - a function pointer with the CORINFO_CALLCONV_UNMANAGED calling convention. -CorInfoCallConvExtension CEEInfo::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig) +CorInfoCallConvExtension CEEInfo::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition) { CONTRACTL { THROWS; @@ -9809,6 +9807,11 @@ CorInfoCallConvExtension CEEInfo::getUnmanagedCallConv(CORINFO_METHOD_HANDLE met JIT_TO_EE_TRANSITION(); + if (pSuppressGCTransition) + { + *pSuppressGCTransition = false; + } + _ASSERTE(method != nullptr || callSiteSig != nullptr); if (method) @@ -9817,6 +9820,11 @@ CorInfoCallConvExtension CEEInfo::getUnmanagedCallConv(CORINFO_METHOD_HANDLE met _ASSERTE(pMD->IsNDirect() || pMD->HasUnmanagedCallersOnlyAttribute()); if(pMD->IsNDirect()) { + if (pSuppressGCTransition) + { + *pSuppressGCTransition = pMD->ShouldSuppressGCTransition(); + } + PInvokeStaticSigInfo sigInfo(pMD, PInvokeStaticSigInfo::NO_THROW_ON_ERROR); switch (sigInfo.GetCallConv()) { diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index fb83f60600270..1fa2e4fdd222b 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -61,7 +61,6 @@ bool SigInfoFlagsAreValid (CORINFO_SIG_INFO *sig) LIMITED_METHOD_CONTRACT; return !(sig->flags & ~( CORINFO_SIGFLAG_IS_LOCAL_SIG | CORINFO_SIGFLAG_IL_STUB - | CORINFO_SIGFLAG_SUPPRESS_GC_TRANSITION )); } @@ -757,7 +756,7 @@ class CEEInfo : public ICorJitInfo bool isIntrinsicType(CORINFO_CLASS_HANDLE classHnd); - CorInfoCallConvExtension getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); + CorInfoCallConvExtension getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition); bool pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); diff --git a/src/coreclr/zap/zapinfo.cpp b/src/coreclr/zap/zapinfo.cpp index 04def45a28524..4ff3c584d47a9 100644 --- a/src/coreclr/zap/zapinfo.cpp +++ b/src/coreclr/zap/zapinfo.cpp @@ -4045,9 +4045,9 @@ bool ZapInfo::isIntrinsicType(CORINFO_CLASS_HANDLE classHnd) return m_pEEJitInfo->isIntrinsicType(classHnd); } -CorInfoCallConvExtension ZapInfo::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig) +CorInfoCallConvExtension ZapInfo::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig, bool* pSuppressGCTransition) { - return m_pEEJitInfo->getUnmanagedCallConv(method, sig); + return m_pEEJitInfo->getUnmanagedCallConv(method, sig, pSuppressGCTransition); } bool ZapInfo::pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, diff --git a/src/coreclr/zap/zapinfo.h b/src/coreclr/zap/zapinfo.h index 91378d81ee3a1..d3e8561c3d603 100644 --- a/src/coreclr/zap/zapinfo.h +++ b/src/coreclr/zap/zapinfo.h @@ -691,7 +691,7 @@ class ZapInfo CorInfoIntrinsics getIntrinsicID(CORINFO_METHOD_HANDLE method, bool * pMustExpand = NULL); bool isIntrinsicType(CORINFO_CLASS_HANDLE classHnd); - CorInfoCallConvExtension getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); + CorInfoCallConvExtension getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig, bool* pSuppressGCTransition); bool pInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig); LPVOID GetCookieForPInvokeCalliSig(CORINFO_SIG_INFO* szMetaSig, void ** ppIndirecton); From ddb885f8b6f4ae2709d0542a445f69190d5ff569 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 11 Dec 2020 11:38:03 -0800 Subject: [PATCH 21/38] Refactor callconv handling so we can handle reverse P/Invokes with the callconv in the signature (and not in an UnmanagedCallersOnly attribute). --- src/coreclr/jit/compiler.cpp | 47 +--- src/coreclr/jit/compiler.h | 3 - src/coreclr/jit/importer.cpp | 6 +- .../tools/Common/JitInterface/CorInfoImpl.cs | 90 +++--- src/coreclr/vm/jitinterface.cpp | 256 ++++++++++-------- src/coreclr/vm/jitinterface.h | 27 +- 6 files changed, 201 insertions(+), 228 deletions(-) diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 99fabfc9c8cc1..c5747dea04c9c 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -2055,40 +2055,6 @@ unsigned Compiler::compGetTypeSize(CorInfoType cit, CORINFO_CLASS_HANDLE clsHnd) return sigSize; } -CorInfoCallConvExtension Compiler::compMethodInfoGetEntrypointCallConv(CORINFO_METHOD_INFO* mthInfo) -{ - switch (mthInfo->args.getCallConv()) - { - case CORINFO_CALLCONV_NATIVEVARARG: - return CorInfoCallConvExtension::C; - break; - case CORINFO_CALLCONV_VARARG: - { - CorInfoCallConvExtension callConv = info.compCompHnd->getUnmanagedCallConv(mthInfo->ftn, nullptr); - if (callConv != CorInfoCallConvExtension::Managed) - { - callConv = CorInfoCallConvExtension::C; - } - return callConv; - break; - } - case CORINFO_CALLCONV_C: - return CorInfoCallConvExtension::C; - case CORINFO_CALLCONV_STDCALL: - return CorInfoCallConvExtension::Stdcall; - case CORINFO_CALLCONV_THISCALL: - return CorInfoCallConvExtension::Thiscall; - // UNMANAGED calling convention means we need to read the calling convention - // from the signature, not from the method's metadata. - case CORINFO_CALLCONV_UNMANAGED: - return info.compCompHnd->getUnmanagedCallConv(nullptr, &mthInfo->args); - case CORINFO_CALLCONV_DEFAULT: - return info.compCompHnd->getUnmanagedCallConv(mthInfo->ftn, nullptr); - default: - BADCODE("bad calling convention"); - } -} - #ifdef DEBUG static bool DidComponentUnitTests = false; @@ -6128,28 +6094,21 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr, if (opts.IsReversePInvoke()) { - info.compCallConv = compMethodInfoGetEntrypointCallConv(methodInfo); + info.compCallConv = info.compCompHnd->getUnmanagedCallConv(methodInfo->ftn, nullptr); } else { info.compCallConv = CorInfoCallConvExtension::Managed; } + info.compIsVarArgs = false; + switch (methodInfo->args.getCallConv()) { case CORINFO_CALLCONV_NATIVEVARARG: case CORINFO_CALLCONV_VARARG: info.compIsVarArgs = true; break; - case CORINFO_CALLCONV_C: - case CORINFO_CALLCONV_STDCALL: - case CORINFO_CALLCONV_THISCALL: - case CORINFO_CALLCONV_UNMANAGED: - case CORINFO_CALLCONV_DEFAULT: - info.compIsVarArgs = false; - break; - default: - BADCODE("bad calling convention"); } info.compRetNativeType = info.compRetType = JITtype2varType(methodInfo->args.retType); diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index d2d634e21b426..935a699dda705 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -9599,9 +9599,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // size of the type these describe. unsigned compGetTypeSize(CorInfoType cit, CORINFO_CLASS_HANDLE clsHnd); - // Gets the calling convention the method's entry point should have. - CorInfoCallConvExtension compMethodInfoGetEntrypointCallConv(CORINFO_METHOD_INFO* mthInfo); - // Returns true if the method being compiled has a return buffer. bool compHasRetBuffArg(); diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 6af32e07f1718..20e2f99c5f173 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -8494,10 +8494,8 @@ var_types Compiler::impImportCall(OPCODE opcode, goto DONE; } - else if ((opcode == CEE_CALLI) && (((sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_STDCALL) || - ((sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_C) || - ((sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_THISCALL) || - ((sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_FASTCALL))) + else if ((opcode == CEE_CALLI) && ((sig->callConv & CORINFO_CALLCONV_MASK) != CORINFO_CALLCONV_DEFAULT) && + ((sig->callConv & CORINFO_CALLCONV_MASK) != CORINFO_CALLCONV_VARARG)) { if (!info.compCompHnd->canGetCookieForPInvokeCalliSig(sig)) { diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 2f40c9faa3cfa..9ec88b2c149ab 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -1062,17 +1062,37 @@ private CorInfoCallConvExtension getUnmanagedCallConv(CORINFO_METHOD_STRUCT_* me *pSuppressGCTransition = 0; } - Debug.Assert(method != null || sig != null); if (method != null) { - MethodDesc methodDesc = HandleToObject(method); + CorInfoCallConvExtension callConv = GetUnmanagedCallConv(HandleToObject(method), out bool suppressGCTransition); + if (pSuppressGCTransition != null) + { + *pSuppressGCTransition = suppressGCTransition ? 1 : 0; + } + return callConv; + } + else + { + Debug.Assert(sig != null); + + CorInfoCallConvExtension callConv = GetUnmanagedCallConv((MethodSignature)HandleToObject((IntPtr)sig->pSig), out bool suppressGCTransition); + if (pSuppressGCTransition != null) + { + *pSuppressGCTransition = suppressGCTransition ? 1 : 0; + } + return callConv; + } + } + private CorInfoCallConvExtension GetUnmanagedCallConv(MethodDesc methodDesc, out bool suppressGCTransition) + { + suppressGCTransition = false; + MethodSignatureFlags callConv = methodDesc.Signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask; + if (callConv == MethodSignatureFlags.None) + { if (methodDesc.IsPInvoke) { - if (pSuppressGCTransition != null) - { - *pSuppressGCTransition = methodDesc.IsSuppressGCTransition() ? 1 : 0; - } - MethodSignatureFlags unmanagedCallConv = HandleToObject(method).GetPInvokeMethodMetadata().Flags.UnmanagedCallingConvention; + suppressGCTransition = methodDesc.IsSuppressGCTransition(); + MethodSignatureFlags unmanagedCallConv = methodDesc.GetPInvokeMethodMetadata().Flags.UnmanagedCallingConvention; if (unmanagedCallConv == MethodSignatureFlags.None) unmanagedCallConv = PlatformDefaultUnmanagedCallingConvention(); @@ -1084,39 +1104,43 @@ private CorInfoCallConvExtension getUnmanagedCallConv(CORINFO_METHOD_STRUCT_* me return (CorInfoCallConvExtension)unmanagedCallConv; } - else if (methodDesc.IsUnmanagedCallersOnly) + else { + Debug.Assert(methodDesc.IsUnmanagedCallersOnly); CustomAttributeValue unmanagedCallersOnlyAttribute = ((EcmaMethod)methodDesc).GetDecodedCustomAttribute("System.Runtime.InteropServices", "UnmanagedCallersOnlyAttribute").Value; return GetUnmanagedCallingConventionFromAttribute(unmanagedCallersOnlyAttribute); } - return CorInfoCallConvExtension.Managed; - } - // Unmanaged calling convention indicates modopt should be read - else if (sig->callConv == CorInfoCallConv.CORINFO_CALLCONV_UNMANAGED) - { - if (TryGetUnmanagedCallingConventionFromModOpt((MethodSignature)HandleToObject((IntPtr)sig->pSig), out CorInfoCallConvExtension callConvMaybe)) - { - return callConvMaybe; - } - else - { - return (CorInfoCallConvExtension)PlatformDefaultUnmanagedCallingConvention(); - } - } - else if ((sig->callConv & CorInfoCallConv.CORINFO_CALLCONV_MASK) == CorInfoCallConv.CORINFO_CALLCONV_NATIVEVARARG) - { - return CorInfoCallConvExtension.C; } - else if ((sig->callConv & CorInfoCallConv.CORINFO_CALLCONV_MASK) == CorInfoCallConv.CORINFO_CALLCONV_VARARG) + return GetUnmanagedCallConv(methodDesc.Signature, out suppressGCTransition); + } + + private CorInfoCallConvExtension GetUnmanagedCallConv(MethodSignature signature, out bool suppressGCTransition) + { + suppressGCTransition = false; + switch (signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) { - return CorInfoCallConvExtension.Managed; + case MethodSignatureFlags.None: + ThrowHelper.ThrowInvalidProgramException(); + return CorInfoCallConvExtension.Managed; + case MethodSignatureFlags.UnmanagedCallingConventionCdecl: + return CorInfoCallConvExtension.C; + case MethodSignatureFlags.UnmanagedCallingConventionStdCall: + return CorInfoCallConvExtension.Stdcall; + case MethodSignatureFlags.UnmanagedCallingConventionThisCall: + return CorInfoCallConvExtension.Thiscall; + case MethodSignatureFlags.UnmanagedCallingConvention: + if (TryGetUnmanagedCallingConventionFromModOpt(signature, out CorInfoCallConvExtension callConvMaybe)) + { + return callConvMaybe; + } + else + { + return (CorInfoCallConvExtension)PlatformDefaultUnmanagedCallingConvention(); + } + default: + ThrowHelper.ThrowInvalidProgramException(); + return CorInfoCallConvExtension.Managed; } - - // Verify that it is safe to convert CORINFO_CALLCONV_* for unmanaged calling conventions to CorInfoCallConvExtension via a simple cast - Debug.Assert((int)CorInfoCallConvExtension.C == (int)CorInfoCallConv.CORINFO_CALLCONV_C); - Debug.Assert((int)CorInfoCallConvExtension.Stdcall == (int)CorInfoCallConv.CORINFO_CALLCONV_STDCALL); - Debug.Assert((int)CorInfoCallConvExtension.Thiscall == (int)CorInfoCallConv.CORINFO_CALLCONV_THISCALL); - return (CorInfoCallConvExtension)(sig->callConv & CorInfoCallConv.CORINFO_CALLCONV_MASK); } private bool satisfiesMethodConstraints(CORINFO_CLASS_STRUCT_* parent, CORINFO_METHOD_STRUCT_* method) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 16b7410152d4e..55546a7637781 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -442,7 +442,7 @@ CEEInfo::ConvToJitSig( DWORD cbSig, CORINFO_MODULE_HANDLE scopeHnd, mdToken token, - SignatureContext context, + SigTypeContext typeContext, ConvToJitSigFlags flags, CORINFO_SIG_INFO * sigRet) { @@ -451,17 +451,7 @@ CEEInfo::ConvToJitSig( GC_TRIGGERS; } CONTRACTL_END; - SigTypeContext typeContext; - uint32_t sigRetFlags = 0; - if (context.methodContext) - { - SigTypeContext::InitTypeContext(context.methodContext, context.typeContext, &typeContext); - } - else - { - SigTypeContext::InitTypeContext(context.typeContext, &typeContext); - } static_assert_no_msg(CORINFO_CALLCONV_DEFAULT == (CorInfoCallConv) IMAGE_CEE_CS_CALLCONV_DEFAULT); static_assert_no_msg(CORINFO_CALLCONV_VARARG == (CorInfoCallConv) IMAGE_CEE_CS_CALLCONV_VARARG); @@ -504,30 +494,6 @@ CEEInfo::ConvToJitSig( } #endif // defined(TARGET_UNIX) || defined(TARGET_ARM) - // Unmanaged calling convention indicates modopt should be read - if (sigRet->callConv == CORINFO_CALLCONV_UNMANAGED) - { - static_assert_no_msg(CORINFO_CALLCONV_C == (CorInfoCallConv)IMAGE_CEE_UNMANAGED_CALLCONV_C); - static_assert_no_msg(CORINFO_CALLCONV_STDCALL == (CorInfoCallConv)IMAGE_CEE_UNMANAGED_CALLCONV_STDCALL); - static_assert_no_msg(CORINFO_CALLCONV_THISCALL == (CorInfoCallConv)IMAGE_CEE_UNMANAGED_CALLCONV_THISCALL); - static_assert_no_msg(CORINFO_CALLCONV_FASTCALL == (CorInfoCallConv)IMAGE_CEE_UNMANAGED_CALLCONV_FASTCALL); - - CorUnmanagedCallingConvention callConvMaybe; - UINT errorResID; - HRESULT hr = MetaSig::TryGetUnmanagedCallingConventionFromModOpt(module, pSig, cbSig, &callConvMaybe, &errorResID); - if (FAILED(hr)) - COMPlusThrowHR(hr, errorResID); - - if (hr == S_OK) - { - sigRet->callConv = (CorInfoCallConv)callConvMaybe; - } - else - { - sigRet->callConv = (CorInfoCallConv)MetaSig::GetDefaultUnmanagedCallingConvention(); - } - } - // Skip number of type arguments if (sigRet->callConv & IMAGE_CEE_CS_CALLCONV_GENERIC) IfFailThrow(sig.GetData(NULL)); @@ -1875,7 +1841,7 @@ CEEInfo::findCallSiteSig( cbSig, scopeHnd, sigMethTok, - CEEInfo::SignatureContext(this, context), + SigTypeContext(GetMethodFromContext(context), GetTypeFromContext(context)), CONV_TO_JITSIG_FLAGS_NONE, sigRet); EE_TO_JIT_TRANSITION(); @@ -1923,7 +1889,7 @@ CEEInfo::findSig( cbSig, scopeHnd, sigTok, - CEEInfo::SignatureContext(this, context), + SigTypeContext(GetMethodFromContext(context), GetTypeFromContext(context)), CONV_TO_JITSIG_FLAGS_NONE, sigRet); @@ -7754,7 +7720,7 @@ getMethodInfoHelper( cbSig, GetScopeHandle(ftn), mdTokenNil, - CEEInfo::SignatureContext(ftn), + SigTypeContext(ftn), CEEInfo::CONV_TO_JITSIG_FLAGS_NONE, &methInfo->args); @@ -7773,7 +7739,7 @@ getMethodInfoHelper( cbLocalSig, GetScopeHandle(ftn), mdTokenNil, - CEEInfo::SignatureContext(ftn), + SigTypeContext(ftn), CEEInfo::CONV_TO_JITSIG_FLAGS_LOCALSIG, &methInfo->locals); @@ -8615,7 +8581,7 @@ CEEInfo::getMethodSigInternal( cbSig, GetScopeHandle(ftn), mdTokenNil, - CEEInfo::SignatureContext(ftn, (TypeHandle)owner), + SigTypeContext(ftn, (TypeHandle)owner), CONV_TO_JITSIG_FLAGS_NONE, sigRet); @@ -9789,119 +9755,173 @@ CorInfoHFAElemType CEEInfo::getHFAType(CORINFO_CLASS_HANDLE hClass) return result; } -/*********************************************************************/ - - // return the entry point calling convention for any of the following - // - a P/Invoke - // - a method marked with UnmanagedCallersOnly - // - a function pointer with the CORINFO_CALLCONV_UNMANAGED calling convention. -CorInfoCallConvExtension CEEInfo::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition) +namespace { - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_PREEMPTIVE; - } CONTRACTL_END; - - CorInfoCallConvExtension callConv = CorInfoCallConvExtension::Managed; - - JIT_TO_EE_TRANSITION(); - - if (pSuppressGCTransition) - { - *pSuppressGCTransition = false; - } - - _ASSERTE(method != nullptr || callSiteSig != nullptr); - - if (method) + CorInfoCallConvExtension getUnmanagedCallConvForSig(Module* mod, PCCOR_SIGNATURE pSig, DWORD cbSig, bool* pSuppressGCTransition) { - MethodDesc* pMD = GetMethod(method); - _ASSERTE(pMD->IsNDirect() || pMD->HasUnmanagedCallersOnlyAttribute()); - if(pMD->IsNDirect()) + SigParser parser(pSig, cbSig); + ULONG rawCallConv; + if (FAILED(parser.GetCallingConv(&rawCallConv))) + { + COMPlusThrowHR(COR_E_BADIMAGEFORMAT); + } + switch ((CorInfoCallConv)rawCallConv) + { + case CORINFO_CALLCONV_DEFAULT: + _ASSERTE_MSG(false, "bad callconv"); + return CorInfoCallConvExtension::Managed; + case CORINFO_CALLCONV_C: + return CorInfoCallConvExtension::C; + case CORINFO_CALLCONV_STDCALL: + return CorInfoCallConvExtension::Stdcall; + case CORINFO_CALLCONV_THISCALL: + return CorInfoCallConvExtension::Thiscall; + case CORINFO_CALLCONV_FASTCALL: + return CorInfoCallConvExtension::Fastcall; + case CORINFO_CALLCONV_UNMANAGED: { - if (pSuppressGCTransition) + CorUnmanagedCallingConvention callConvMaybe; + UINT errorResID; + HRESULT hr = MetaSig::TryGetUnmanagedCallingConventionFromModOpt(mod, pSig, cbSig, &callConvMaybe, &errorResID); + if (FAILED(hr)) + COMPlusThrowHR(hr, errorResID); + + if (hr == S_OK) { - *pSuppressGCTransition = pMD->ShouldSuppressGCTransition(); + return (CorInfoCallConvExtension)callConvMaybe; } - - PInvokeStaticSigInfo sigInfo(pMD, PInvokeStaticSigInfo::NO_THROW_ON_ERROR); - switch (sigInfo.GetCallConv()) + else { - case pmCallConvCdecl: - callConv = CorInfoCallConvExtension::C; - break; - case pmCallConvStdcall: - callConv = CorInfoCallConvExtension::Stdcall; - break; - case pmCallConvThiscall: - callConv = CorInfoCallConvExtension::Thiscall; - break; - default: - callConv = CorInfoCallConvExtension::Managed; - break; + return (CorInfoCallConvExtension)MetaSig::GetDefaultUnmanagedCallingConvention(); } } - else + case CORINFO_CALLCONV_NATIVEVARARG: + return CorInfoCallConvExtension::C; + default: + _ASSERTE_MSG(false, "bad callconv"); + return CorInfoCallConvExtension::Managed; + } + } + + CorInfoCallConvExtension getUnmanagedCallConvForMethod(MethodDesc* pMD, bool* pSuppressGCTransition) + { + ULONG methodCallConv; + PCCOR_SIGNATURE pSig; + DWORD cbSig; + pMD->GetSig(&pSig, &cbSig); + if (FAILED(SigParser(pSig, cbSig).GetCallingConv(&methodCallConv))) { -#ifdef CROSSGEN_COMPILE - _ASSERTE_MSG(false, "UnmanagedCallersOnly methods are not supported in crossgen and should be rejected before getting here."); -#else - CorPinvokeMap unmanagedCallConv; - if (TryGetCallingConventionFromUnmanagedCallersOnly(pMD, &unmanagedCallConv)) + COMPlusThrowHR(COR_E_BADIMAGEFORMAT); + } + + if (methodCallConv == CORINFO_CALLCONV_DEFAULT || methodCallConv == CORINFO_CALLCONV_VARARG) + { + _ASSERTE(pMD->IsNDirect() || pMD->HasUnmanagedCallersOnlyAttribute()); + if (pMD->IsNDirect()) { - switch (unmanagedCallConv) + if (pSuppressGCTransition) + { + *pSuppressGCTransition = pMD->ShouldSuppressGCTransition(); + } + + PInvokeStaticSigInfo sigInfo(pMD, PInvokeStaticSigInfo::NO_THROW_ON_ERROR); + switch (sigInfo.GetCallConv()) { - case pmCallConvWinapi: - callConv = (CorInfoCallConvExtension)MetaSig::GetDefaultUnmanagedCallingConvention(); - break; case pmCallConvCdecl: - callConv = CorInfoCallConvExtension::C; + return CorInfoCallConvExtension::C; break; case pmCallConvStdcall: - callConv = CorInfoCallConvExtension::Stdcall; + return CorInfoCallConvExtension::Stdcall; break; case pmCallConvThiscall: - callConv = CorInfoCallConvExtension::Thiscall; + return CorInfoCallConvExtension::Thiscall; break; case pmCallConvFastcall: - callConv = CorInfoCallConvExtension::Fastcall; + return CorInfoCallConvExtension::Fastcall; break; default: + _ASSERTE_MSG(false, "bad callconv"); + return CorInfoCallConvExtension::Managed; break; } } + else + { +#ifdef CROSSGEN_COMPILE + _ASSERTE_MSG(false, "UnmanagedCallersOnly methods are not supported in crossgen and should be rejected before getting here."); + return CorInfoCallConvExtension::Managed; +#else + CorPinvokeMap unmanagedCallConv; + if (TryGetCallingConventionFromUnmanagedCallersOnly(pMD, &unmanagedCallConv)) + { + if (methodCallConv == CORINFO_CALLCONV_VARARG) + { + return CorInfoCallConvExtension::C; + } + switch (unmanagedCallConv) + { + case pmCallConvWinapi: + return (CorInfoCallConvExtension)MetaSig::GetDefaultUnmanagedCallingConvention(); + break; + case pmCallConvCdecl: + return CorInfoCallConvExtension::C; + break; + case pmCallConvStdcall: + return CorInfoCallConvExtension::Stdcall; + break; + case pmCallConvThiscall: + return CorInfoCallConvExtension::Thiscall; + break; + case pmCallConvFastcall: + return CorInfoCallConvExtension::Fastcall; + break; + default: + _ASSERTE_MSG(false, "bad callconv"); + break; + } + } + return (CorInfoCallConvExtension)MetaSig::GetDefaultUnmanagedCallingConvention(); #endif // CROSSGEN_COMPILE - } - } - else if (callSiteSig->callConv == CORINFO_CALLCONV_UNMANAGED) - { - CorUnmanagedCallingConvention callConvMaybe; - UINT errorResID; - HRESULT hr = MetaSig::TryGetUnmanagedCallingConventionFromModOpt(GetModule(callSiteSig->scope), callSiteSig->pSig, callSiteSig->cbSig, &callConvMaybe, &errorResID); - if (FAILED(hr)) - COMPlusThrowHR(hr, errorResID); - - if (hr == S_OK) - { - callConv = (CorInfoCallConvExtension)callConvMaybe; + } } else { - callConv = (CorInfoCallConvExtension)MetaSig::GetDefaultUnmanagedCallingConvention(); + return getUnmanagedCallConvForSig(pMD->GetModule(), pSig, cbSig, pSuppressGCTransition); } } - else if ((callSiteSig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_NATIVEVARARG) +} + +/*********************************************************************/ + + // return the entry point calling convention for any of the following + // - a P/Invoke + // - a method marked with UnmanagedCallersOnly + // - a function pointer with the CORINFO_CALLCONV_UNMANAGED calling convention. +CorInfoCallConvExtension CEEInfo::getUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition) +{ + CONTRACTL { + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + } CONTRACTL_END; + + CorInfoCallConvExtension callConv = CorInfoCallConvExtension::Managed; + + JIT_TO_EE_TRANSITION(); + + if (pSuppressGCTransition) { - callConv = CorInfoCallConvExtension::C; + *pSuppressGCTransition = false; } - else if ((callSiteSig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_VARARG) + + if (method) { - callConv = CorInfoCallConvExtension::Managed; + callConv = getUnmanagedCallConvForMethod(GetMethod(method), pSuppressGCTransition); } else { - callConv = (CorInfoCallConvExtension)(callSiteSig->callConv & CORINFO_CALLCONV_MASK); + _ASSERTE(callSiteSig != nullptr); + callConv = getUnmanagedCallConvForSig(GetModule(callSiteSig->scope), callSiteSig->pSig, callSiteSig->cbSig, pSuppressGCTransition); } EE_TO_JIT_TRANSITION(); diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 1fa2e4fdd222b..1214bbb07f51d 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -1109,31 +1109,6 @@ class CEEInfo : public ICorJitInfo public: - struct SignatureContext - { - MethodDesc* methodContext = NULL; - TypeHandle typeContext = TypeHandle(); - - SignatureContext() = default; - - SignatureContext(MethodDesc* pMD) - { - methodContext = pMD; - } - - SignatureContext(MethodDesc* pMD, TypeHandle type) - { - methodContext = pMD; - typeContext = type; - } - - SignatureContext(CEEInfo* pEEInfo, CORINFO_CONTEXT_HANDLE jitContext) - { - methodContext = pEEInfo->GetMethodFromContext(jitContext); - typeContext = pEEInfo->GetTypeFromContext(jitContext); - } - }; - enum ConvToJitSigFlags : int { CONV_TO_JITSIG_FLAGS_NONE = 0x0, @@ -1150,7 +1125,7 @@ class CEEInfo : public ICorJitInfo DWORD cbSig, CORINFO_MODULE_HANDLE scopeHnd, mdToken token, - SignatureContext context, + SigTypeContext context, ConvToJitSigFlags flags, CORINFO_SIG_INFO * sigRet); From 0b98994c8b67f28a76018aa7e323e5856a61cd83 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 11 Dec 2020 11:57:12 -0800 Subject: [PATCH 22/38] Clean up whitespace. --- src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index 5b09442379700..893d00f058a20 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -369,7 +369,6 @@ public enum CorInfoSigInfoFlags : byte { CORINFO_SIGFLAG_IS_LOCAL_SIG = 0x01, CORINFO_SIGFLAG_IL_STUB = 0x02, - // unused = 0x04, CORINFO_SIGFLAG_FAT_CALL = 0x08, }; From 3f0c7f97a4c0b4edffa442a4ada315db7c027397 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 11 Dec 2020 14:46:25 -0800 Subject: [PATCH 23/38] Pass MethodIL as the scope for the signature to enable propagating down annotations for calli's in P/Invokes. --- .../tools/Common/JitInterface/CorInfoImpl.cs | 32 ++++++++++++------- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 2 +- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 9ec88b2c149ab..36c68de804bb3 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -476,15 +476,15 @@ private bool Get_CORINFO_METHOD_INFO(MethodDesc method, MethodIL methodIL, CORIN methodInfo->options |= CorInfoOptions.CORINFO_GENERICS_CTXT_FROM_METHODTABLE; } methodInfo->regionKind = CorInfoRegionKind.CORINFO_REGION_NONE; - Get_CORINFO_SIG_INFO(method, &methodInfo->args); + Get_CORINFO_SIG_INFO(method, methodIL, sig: &methodInfo->args); Get_CORINFO_SIG_INFO(methodIL.GetLocals(), &methodInfo->locals); return true; } - private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, bool suppressHiddenArgument = false) + private void Get_CORINFO_SIG_INFO(MethodDesc method, MethodIL methodIL, CORINFO_SIG_INFO* sig, bool suppressHiddenArgument = false) { - Get_CORINFO_SIG_INFO(method.Signature, sig); + Get_CORINFO_SIG_INFO(method.Signature, methodIL, sig); // Does the method have a hidden parameter? bool hasHiddenParameter = !suppressHiddenArgument && method.RequiresInstArg(); @@ -612,7 +612,7 @@ private bool TryGetUnmanagedCallingConventionFromModOpt(MethodSignature signatur _ => null }; - private void Get_CORINFO_SIG_INFO(MethodSignature signature, CORINFO_SIG_INFO* sig) + private void Get_CORINFO_SIG_INFO(MethodSignature signature, MethodIL methodIL, CORINFO_SIG_INFO* sig) { sig->callConv = (CorInfoCallConv)(signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask); @@ -641,7 +641,7 @@ private void Get_CORINFO_SIG_INFO(MethodSignature signature, CORINFO_SIG_INFO* s sig->pSig = (byte*)ObjectToHandle(signature); sig->cbSig = 0; // Not used by the JIT - sig->scope = null; // Not used by the JIT + sig->scope = (CORINFO_MODULE_STRUCT_*)ObjectToHandle(methodIL); sig->token = 0; // Not used by the JIT } @@ -907,7 +907,7 @@ private void getMethodSig(CORINFO_METHOD_STRUCT_* ftn, CORINFO_SIG_INFO* sig, CO } } - Get_CORINFO_SIG_INFO(method, sig); + Get_CORINFO_SIG_INFO(method, _compilation.GetMethodIL(method), sig: sig); } private bool getMethodInfo(CORINFO_METHOD_STRUCT_* ftn, CORINFO_METHOD_INFO* info) @@ -1064,6 +1064,7 @@ private CorInfoCallConvExtension getUnmanagedCallConv(CORINFO_METHOD_STRUCT_* me if (method != null) { + MethodDesc methodDesc = HandleToObject(method); CorInfoCallConvExtension callConv = GetUnmanagedCallConv(HandleToObject(method), out bool suppressGCTransition); if (pSuppressGCTransition != null) { @@ -1075,7 +1076,7 @@ private CorInfoCallConvExtension getUnmanagedCallConv(CORINFO_METHOD_STRUCT_* me { Debug.Assert(sig != null); - CorInfoCallConvExtension callConv = GetUnmanagedCallConv((MethodSignature)HandleToObject((IntPtr)sig->pSig), out bool suppressGCTransition); + CorInfoCallConvExtension callConv = GetUnmanagedCallConv((MethodSignature)HandleToObject((IntPtr)sig->pSig), (MethodIL)HandleToObject((IntPtr)sig->scope), out bool suppressGCTransition); if (pSuppressGCTransition != null) { *pSuppressGCTransition = suppressGCTransition ? 1 : 0; @@ -1111,12 +1112,21 @@ private CorInfoCallConvExtension GetUnmanagedCallConv(MethodDesc methodDesc, out return GetUnmanagedCallingConventionFromAttribute(unmanagedCallersOnlyAttribute); } } - return GetUnmanagedCallConv(methodDesc.Signature, out suppressGCTransition); + // We don't want to do any additional resolution based on what method we're in, + // so don't pass the current method's IL context for when we process the signature. + return GetUnmanagedCallConv(methodDesc.Signature, null, out suppressGCTransition); } - private CorInfoCallConvExtension GetUnmanagedCallConv(MethodSignature signature, out bool suppressGCTransition) + private CorInfoCallConvExtension GetUnmanagedCallConv(MethodSignature signature, MethodIL methodIL, out bool suppressGCTransition) { suppressGCTransition = false; + // TODO: Remove when we have a public way to represent SuppressGCTransition on a calli. + if (methodIL is PInvokeILStubMethodIL stubIL && + stubIL.OwningMethod.IsPInvoke && + stubIL.OwningMethod.IsSuppressGCTransition()) + { + suppressGCTransition = true; + } switch (signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) { case MethodSignatureFlags.None: @@ -1388,7 +1398,7 @@ private void findSig(CORINFO_MODULE_STRUCT_* module, uint sigTOK, CORINFO_CONTEX var methodIL = (MethodIL)HandleToObject((IntPtr)module); var methodSig = (MethodSignature)methodIL.GetObject((int)sigTOK); - Get_CORINFO_SIG_INFO(methodSig, sig); + Get_CORINFO_SIG_INFO(methodSig, methodIL, sig); #if !READYTORUN // Check whether we need to report this as a fat pointer call @@ -1404,7 +1414,7 @@ private void findSig(CORINFO_MODULE_STRUCT_* module, uint sigTOK, CORINFO_CONTEX private void findCallSiteSig(CORINFO_MODULE_STRUCT_* module, uint methTOK, CORINFO_CONTEXT_STRUCT* context, CORINFO_SIG_INFO* sig) { var methodIL = (MethodIL)HandleToObject((IntPtr)module); - Get_CORINFO_SIG_INFO(((MethodDesc)methodIL.GetObject((int)methTOK)), sig); + Get_CORINFO_SIG_INFO(((MethodDesc)methodIL.GetObject((int)methTOK)), methodIL, sig: sig); } private CORINFO_CLASS_STRUCT_* getTokenTypeAsHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken) diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index 61779f5406ab6..cb44df2efbf7d 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -1663,7 +1663,7 @@ private void ceeInfoGetCallInfo( pResult->wrapperDelegateInvoke = false; - Get_CORINFO_SIG_INFO(methodToCall, &pResult->sig, useInstantiatingStub); + Get_CORINFO_SIG_INFO(methodToCall, (MethodIL)HandleToObject((IntPtr)pResolvedToken.tokenScope), &pResult->sig, useInstantiatingStub); } private uint getMethodAttribs(CORINFO_METHOD_STRUCT_* ftn) From af41c1b166001649d6422db196d5ddbaaf94025f Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 11 Dec 2020 16:28:32 -0800 Subject: [PATCH 24/38] Remove usages of CORINFO_CALLCONV_FOO where FOO is an unmanaged callconv. move the definitions of those ones to the interpreter since that's the only place they're used. --- src/coreclr/inc/corinfo.h | 29 ++++++++----------- src/coreclr/jit/codegencommon.cpp | 2 +- src/coreclr/jit/importer.cpp | 12 ++++---- .../tools/Common/JitInterface/CorInfoTypes.cs | 9 +++--- src/coreclr/vm/dllimport.cpp | 14 ++++----- src/coreclr/vm/interpreter.h | 10 +++++++ src/coreclr/vm/jitinterface.cpp | 18 ++++++------ 7 files changed, 50 insertions(+), 44 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 75bf47e540e78..eac7146f531c7 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -671,10 +671,11 @@ enum CorInfoCallConv // These correspond to CorCallingConvention CORINFO_CALLCONV_DEFAULT = 0x0, - CORINFO_CALLCONV_C = 0x1, - CORINFO_CALLCONV_STDCALL = 0x2, - CORINFO_CALLCONV_THISCALL = 0x3, - CORINFO_CALLCONV_FASTCALL = 0x4, + // Instead of using the below values, use the CorInfoCallConvExtension enum for unmanaged calling conventions. + // CORINFO_CALLCONV_C = 0x1, + // CORINFO_CALLCONV_STDCALL = 0x2, + // CORINFO_CALLCONV_THISCALL = 0x3, + // CORINFO_CALLCONV_FASTCALL = 0x4, CORINFO_CALLCONV_VARARG = 0x5, CORINFO_CALLCONV_FIELD = 0x6, CORINFO_CALLCONV_LOCAL_SIG = 0x7, @@ -689,17 +690,6 @@ enum CorInfoCallConv CORINFO_CALLCONV_PARAMTYPE = 0x80, // Passed last. Same as CORINFO_GENERICS_CTXT_FROM_PARAMTYPEARG }; -#ifdef UNIX_X86_ABI -inline bool IsCallerPop(CorInfoCallConv callConv) -{ - unsigned int umask = CORINFO_CALLCONV_STDCALL - | CORINFO_CALLCONV_THISCALL - | CORINFO_CALLCONV_FASTCALL; - - return !(callConv & umask); -} -#endif // UNIX_X86_ABI - // Represents the calling conventions supported with the extensible calling convention syntax // as well as the original metadata-encoded calling conventions. enum class CorInfoCallConvExtension @@ -712,6 +702,13 @@ enum class CorInfoCallConvExtension // New calling conventions supported with the extensible calling convention encoding go here. }; +#ifdef UNIX_X86_ABI +inline bool IsCallerPop(CorInfoCallConvExtension callConv) +{ + return callConv == CorInfoCallConvExtension::Managed || callConv == CorInfoCallConvExtension::C; +} +#endif // UNIX_X86_ABI + // Determines whether or not this calling convention is an instance method calling convention. inline bool callConvIsInstanceMethodCallConv(CorInfoCallConvExtension callConv) { @@ -2085,8 +2082,6 @@ class ICorStaticInfo // - a P/Invoke // - a method marked with UnmanagedCallersOnly // - a function pointer with the CORINFO_CALLCONV_UNMANAGED calling convention. - // May return CorInfoCallConvExtension::Managed when the method or call site doesn't - // use an unmanaged calling convention as an entry point. virtual CorInfoCallConvExtension getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index ae8d439a7aa78..fb3065e24d043 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -8933,7 +8933,7 @@ void CodeGen::genFnEpilog(BasicBlock* block) fCalleePop = false; #ifdef UNIX_X86_ABI - if (IsCallerPop(compiler->info.compMethodInfo->args.callConv)) + if (IsCallerPop(compiler->info.compCallConv)) fCalleePop = false; #endif // UNIX_X86_ABI diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 20e2f99c5f173..1c5567e57e15e 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -8397,12 +8397,6 @@ var_types Compiler::impImportCall(OPCODE opcode, } #endif // !FEATURE_VARARG -#ifdef UNIX_X86_ABI - // On Unix x86 we usually use caller-cleaned convention. - if (!call->AsCall()->IsUnmanaged() && IsCallerPop(sig->callConv)) - call->gtFlags |= GTF_CALL_POP_ARGS; -#endif // UNIX_X86_ABI - if ((sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_VARARG || (sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_NATIVEVARARG) { @@ -8478,6 +8472,12 @@ var_types Compiler::impImportCall(OPCODE opcode, impCheckForPInvokeCall(call->AsCall(), methHnd, sig, mflags, block); } +#ifdef UNIX_X86_ABI + // On Unix x86 we usually use caller-cleaned convention. + if ((call->gtFlags & GTF_CALL_UNMANAGED) == 0) + call->gtFlags |= GTF_CALL_POP_ARGS; +#endif // UNIX_X86_ABI + if (call->gtFlags & GTF_CALL_UNMANAGED) { // We set up the unmanaged call by linking the frame, disabling GC, etc diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index 893d00f058a20..68f41d0cf9038 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -314,10 +314,11 @@ public enum CorInfoCallConv // These correspond to CorCallingConvention CORINFO_CALLCONV_DEFAULT = 0x0, - CORINFO_CALLCONV_C = 0x1, - CORINFO_CALLCONV_STDCALL = 0x2, - CORINFO_CALLCONV_THISCALL = 0x3, - CORINFO_CALLCONV_FASTCALL = 0x4, + // Instead of using the below values, use the CorInfoCallConvExtension enum for unmanaged calling conventions. + // CORINFO_CALLCONV_C = 0x1, + // CORINFO_CALLCONV_STDCALL = 0x2, + // CORINFO_CALLCONV_THISCALL = 0x3, + // CORINFO_CALLCONV_FASTCALL = 0x4, CORINFO_CALLCONV_VARARG = 0x5, CORINFO_CALLCONV_FIELD = 0x6, CORINFO_CALLCONV_LOCAL_SIG = 0x7, diff --git a/src/coreclr/vm/dllimport.cpp b/src/coreclr/vm/dllimport.cpp index aa92422bafebf..187a344b85422 100644 --- a/src/coreclr/vm/dllimport.cpp +++ b/src/coreclr/vm/dllimport.cpp @@ -1598,7 +1598,7 @@ void NDirectStubLinker::SetCallingConvention(CorPinvokeMap unmngCallConv, BOOL f { // The JIT has to use a different calling convention for unmanaged vararg targets on 64-bit and ARM: // any float values must be duplicated in the corresponding general-purpose registers. - uNativeCallingConv = CORINFO_CALLCONV_NATIVEVARARG; + uNativeCallingConv = IMAGE_CEE_CS_CALLCONV_NATIVEVARARG; } else #endif // !TARGET_X86 @@ -1606,17 +1606,17 @@ void NDirectStubLinker::SetCallingConvention(CorPinvokeMap unmngCallConv, BOOL f switch (unmngCallConv) { case pmCallConvCdecl: - uNativeCallingConv = CORINFO_CALLCONV_C; + uNativeCallingConv = IMAGE_CEE_CS_CALLCONV_C; break; case pmCallConvStdcall: - uNativeCallingConv = CORINFO_CALLCONV_STDCALL; + uNativeCallingConv = IMAGE_CEE_CS_CALLCONV_STDCALL; break; case pmCallConvThiscall: - uNativeCallingConv = CORINFO_CALLCONV_THISCALL; + uNativeCallingConv = IMAGE_CEE_CS_CALLCONV_THISCALL; break; default: _ASSERTE(!"Invalid calling convention."); - uNativeCallingConv = CORINFO_CALLCONV_STDCALL; + uNativeCallingConv = IMAGE_CEE_CS_CALLCONV_STDCALL; break; } } @@ -2980,7 +2980,7 @@ namespace HRESULT hr = MetaSig::TryGetUnmanagedCallingConventionFromModOpt(pModule, pSig, cSig, &callConvMaybe, errorResID); if (hr != S_OK) return hr; - + if (!TryConvertCallConvValueToPInvokeCallConv(callConvMaybe, pPinvokeMapOut)) return S_FALSE; @@ -6161,7 +6161,7 @@ namespace #if defined(TARGET_LINUX) if (g_coreclr_embedded) { - // this matches exactly the names in Interop.Libraries.cs + // this matches exactly the names in Interop.Libraries.cs static const LPCWSTR toRedirect[] = { W("libSystem.Native"), W("libSystem.Net.Security.Native"), diff --git a/src/coreclr/vm/interpreter.h b/src/coreclr/vm/interpreter.h index 5b1aea0335aed..a819291043c09 100644 --- a/src/coreclr/vm/interpreter.h +++ b/src/coreclr/vm/interpreter.h @@ -142,6 +142,16 @@ enum CorInfoTypeShifted CORINFO_TYPE_SHIFTED_VAR = unsigned(CORINFO_TYPE_VAR) << 2, //0x16 << 2 = 0x58 }; +enum CorInfoUnmanagedCallConv +{ + // Corresponds to the unmanaged calling conventions specified in metadata. + // Equivalent to the CorUnmanagedCallingConvention enum + CORINFO_CALLCONV_C = 0x1, + CORINFO_CALLCONV_STDCALL = 0x2, + CORINFO_CALLCONV_THISCALL = 0x3, + CORINFO_CALLCONV_FASTCALL = 0x4, +}; + class InterpreterType { // We use this typedef, but the InterpreterType is actually encoded. We assume that the two diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 55546a7637781..e0ca7f482f187 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9765,20 +9765,20 @@ namespace { COMPlusThrowHR(COR_E_BADIMAGEFORMAT); } - switch ((CorInfoCallConv)rawCallConv) + switch ((CorCallingConvention)rawCallConv) { - case CORINFO_CALLCONV_DEFAULT: + case IMAGE_CEE_CS_CALLCONV_DEFAULT: _ASSERTE_MSG(false, "bad callconv"); return CorInfoCallConvExtension::Managed; - case CORINFO_CALLCONV_C: + case IMAGE_CEE_CS_CALLCONV_C: return CorInfoCallConvExtension::C; - case CORINFO_CALLCONV_STDCALL: + case IMAGE_CEE_CS_CALLCONV_STDCALL: return CorInfoCallConvExtension::Stdcall; - case CORINFO_CALLCONV_THISCALL: + case IMAGE_CEE_CS_CALLCONV_THISCALL: return CorInfoCallConvExtension::Thiscall; - case CORINFO_CALLCONV_FASTCALL: + case IMAGE_CEE_CS_CALLCONV_FASTCALL: return CorInfoCallConvExtension::Fastcall; - case CORINFO_CALLCONV_UNMANAGED: + case IMAGE_CEE_CS_CALLCONV_UNMANAGED: { CorUnmanagedCallingConvention callConvMaybe; UINT errorResID; @@ -9795,7 +9795,7 @@ namespace return (CorInfoCallConvExtension)MetaSig::GetDefaultUnmanagedCallingConvention(); } } - case CORINFO_CALLCONV_NATIVEVARARG: + case IMAGE_CEE_CS_CALLCONV_NATIVEVARARG: return CorInfoCallConvExtension::C; default: _ASSERTE_MSG(false, "bad callconv"); @@ -9854,7 +9854,7 @@ namespace CorPinvokeMap unmanagedCallConv; if (TryGetCallingConventionFromUnmanagedCallersOnly(pMD, &unmanagedCallConv)) { - if (methodCallConv == CORINFO_CALLCONV_VARARG) + if (methodCallConv == IMAGE_CEE_CS_CALLCONV_VARARG) { return CorInfoCallConvExtension::C; } From 2db19665ca110d4f1d075be128bd1828563a6287 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 11 Dec 2020 16:35:45 -0800 Subject: [PATCH 25/38] SuppressGC cleanup. --- src/coreclr/inc/corinfo.h | 2 +- src/coreclr/jit/compiler.cpp | 3 ++- src/coreclr/jit/importer.cpp | 13 +++++++------ .../tools/Common/JitInterface/CorInfoBase.cs | 6 +++--- .../tools/Common/JitInterface/CorInfoImpl.cs | 19 ++++--------------- .../ThunkGenerator/ThunkInput.txt | 2 +- 6 files changed, 18 insertions(+), 27 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index eac7146f531c7..aaec3ff51da36 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -2085,7 +2085,7 @@ class ICorStaticInfo virtual CorInfoCallConvExtension getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, - bool* pSuppressGCTransition = NULL /* OUT */ + bool* pSuppressGCTransition /* OUT */ ) = 0; // return if any marshaling is required for PInvoke methods. Note that diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index c5747dea04c9c..a368cb2a18fcd 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -6094,7 +6094,8 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr, if (opts.IsReversePInvoke()) { - info.compCallConv = info.compCompHnd->getUnmanagedCallConv(methodInfo->ftn, nullptr); + bool unused; + info.compCallConv = info.compCompHnd->getUnmanagedCallConv(methodInfo->ftn, nullptr, &unused); } else { diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 1c5567e57e15e..443755bb90a32 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -7033,6 +7033,7 @@ void Compiler::impCheckForPInvokeCall( call->gtCallMoreFlags |= GTF_CALL_M_PINVOKE; } + bool suppressGCTransition = false; if (methHnd) { if ((mflags & CORINFO_FLG_PINVOKE) == 0) @@ -7040,20 +7041,20 @@ void Compiler::impCheckForPInvokeCall( return; } - bool suppressGCTransition = false; unmanagedCallConv = info.compCompHnd->getUnmanagedCallConv(methHnd, nullptr, &suppressGCTransition); - if (suppressGCTransition) - { - call->gtCallMoreFlags |= GTF_CALL_M_SUPPRESS_GC_TRANSITION; - } } else { - unmanagedCallConv = info.compCompHnd->getUnmanagedCallConv(nullptr, sig); + unmanagedCallConv = info.compCompHnd->getUnmanagedCallConv(nullptr, sig, &suppressGCTransition); assert(!call->gtCallCookie); } + if (suppressGCTransition) + { + call->gtCallMoreFlags |= GTF_CALL_M_SUPPRESS_GC_TRANSITION; + } + if (unmanagedCallConv != CorInfoCallConvExtension::C && unmanagedCallConv != CorInfoCallConvExtension::Stdcall && unmanagedCallConv != CorInfoCallConvExtension::Thiscall) { diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs index 48fdb2e7c6785..5808db5f534f7 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs @@ -276,12 +276,12 @@ static byte _isIntrinsicType(IntPtr thisHandle, IntPtr* ppException, CORINFO_CLA } [UnmanagedCallersOnly] - static CorInfoCallConvExtension _getUnmanagedCallConv(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method, CORINFO_SIG_INFO* callSiteSig, byte* pSuppressGCTransition) + static CorInfoCallConvExtension _getUnmanagedCallConv(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition) { var _this = GetThis(thisHandle); try { - return _this.getUnmanagedCallConv(method, callSiteSig, pSuppressGCTransition); + return _this.getUnmanagedCallConv(method, callSiteSig, ref *pSuppressGCTransition); } catch (Exception ex) { @@ -2556,7 +2556,7 @@ static IntPtr GetUnmanagedCallbacks() callbacks[15] = (delegate* unmanaged)&_expandRawHandleIntrinsic; callbacks[16] = (delegate* unmanaged)&_getIntrinsicID; callbacks[17] = (delegate* unmanaged)&_isIntrinsicType; - callbacks[18] = (delegate* unmanaged)&_getUnmanagedCallConv; + callbacks[18] = (delegate* unmanaged)&_getUnmanagedCallConv; callbacks[19] = (delegate* unmanaged)&_pInvokeMarshalingRequired; callbacks[20] = (delegate* unmanaged)&_satisfiesMethodConstraints; callbacks[21] = (delegate* unmanaged)&_isCompatibleDelegate; diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 36c68de804bb3..b8cc74fa0b206 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -1055,32 +1055,21 @@ private MethodSignatureFlags PlatformDefaultUnmanagedCallingConvention() MethodSignatureFlags.UnmanagedCallingConventionStdCall : MethodSignatureFlags.UnmanagedCallingConventionCdecl; } - private CorInfoCallConvExtension getUnmanagedCallConv(CORINFO_METHOD_STRUCT_* method, CORINFO_SIG_INFO* sig, byte* pSuppressGCTransition) + private CorInfoCallConvExtension getUnmanagedCallConv(CORINFO_METHOD_STRUCT_* method, CORINFO_SIG_INFO* sig, ref bool pSuppressGCTransition) { - if (pSuppressGCTransition != null) - { - *pSuppressGCTransition = 0; - } + pSuppressGCTransition = false; if (method != null) { MethodDesc methodDesc = HandleToObject(method); - CorInfoCallConvExtension callConv = GetUnmanagedCallConv(HandleToObject(method), out bool suppressGCTransition); - if (pSuppressGCTransition != null) - { - *pSuppressGCTransition = suppressGCTransition ? 1 : 0; - } + CorInfoCallConvExtension callConv = GetUnmanagedCallConv(HandleToObject(method), out pSuppressGCTransition); return callConv; } else { Debug.Assert(sig != null); - CorInfoCallConvExtension callConv = GetUnmanagedCallConv((MethodSignature)HandleToObject((IntPtr)sig->pSig), (MethodIL)HandleToObject((IntPtr)sig->scope), out bool suppressGCTransition); - if (pSuppressGCTransition != null) - { - *pSuppressGCTransition = suppressGCTransition ? 1 : 0; - } + CorInfoCallConvExtension callConv = GetUnmanagedCallConv((MethodSignature)HandleToObject((IntPtr)sig->pSig), (MethodIL)HandleToObject((IntPtr)sig->scope), out pSuppressGCTransition); return callConv; } } diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 4c185f4c7d316..46a18235a7cc9 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -176,7 +176,7 @@ FUNCTIONS void expandRawHandleIntrinsic(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_GENERICHANDLE_RESULT * pResult); CorInfoIntrinsics getIntrinsicID( CORINFO_METHOD_HANDLE method , BoolStar pMustExpand); bool isIntrinsicType( CORINFO_CLASS_HANDLE classHnd ); - CorInfoCallConvExtension getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, BoolStar pSuppressGCTransition); + CorInfoCallConvExtension getUnmanagedCallConv( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition); bool pInvokeMarshalingRequired( CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig ); bool satisfiesMethodConstraints( CORINFO_CLASS_HANDLE parent, CORINFO_METHOD_HANDLE method ); bool isCompatibleDelegate( CORINFO_CLASS_HANDLE objCls, CORINFO_CLASS_HANDLE methodParentCls, CORINFO_METHOD_HANDLE method, CORINFO_CLASS_HANDLE delegateCls, bool *pfIsOpenDelegate ); From 477ae3c8efb9bb82fa3cd801a0aa8c9b18796ace Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 11 Dec 2020 16:38:09 -0800 Subject: [PATCH 26/38] Rename superpmi struct --- .../superpmi/superpmi-shared/lwmlist.h | 4 ++-- .../superpmi-shared/methodcontext.cpp | 24 +++++++++---------- .../superpmi/superpmi-shared/methodcontext.h | 6 ++--- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h index b1c4a4047478f..b400fbab0b29a 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/lwmlist.h @@ -148,13 +148,13 @@ LWM(IsValidToken, DLD, DWORD) LWM(IsValueClass, DWORDLONG, DWORD) LWM(MergeClasses, DLDL, DWORDLONG) LWM(IsMoreSpecificType, DLDL, DWORD) -LWM(PInvokeMarshalingRequired, MethodSigInfoPairValue, DWORD) +LWM(PInvokeMarshalingRequired, MethodOrSigInfoValue, DWORD) LWM(ResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, ResolveTokenValue) LWM(ResolveVirtualMethod, Agnostic_ResolveVirtualMethodKey, Agnostic_ResolveVirtualMethodResult) LWM(TryResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, TryResolveTokenValue) LWM(SatisfiesClassConstraints, DWORDLONG, DWORD) LWM(SatisfiesMethodConstraints, DLDL, DWORD) -LWM(GetUnmanagedCallConv, MethodSigInfoPairValue, DD) +LWM(GetUnmanagedCallConv, MethodOrSigInfoValue, DD) #undef LWM diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index d781f4d15c4df..cc859f22a8a0f 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -3742,10 +3742,10 @@ void MethodContext::recPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, bool result) { if (PInvokeMarshalingRequired == nullptr) - PInvokeMarshalingRequired = new LightWeightMap(); + PInvokeMarshalingRequired = new LightWeightMap(); - MethodSigInfoPairValue key; - ZeroMemory(&key, sizeof(MethodSigInfoPairValue)); // We use the input structs as a key and use memcmp to + MethodOrSigInfoValue key; + ZeroMemory(&key, sizeof(MethodOrSigInfoValue)); // We use the input structs as a key and use memcmp to // compare.. so we need to zero out padding too key.method = (DWORDLONG)method; @@ -3756,7 +3756,7 @@ void MethodContext::recPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, PInvokeMarshalingRequired->Add(key, (DWORD)result); DEBUG_REC(dmpPInvokeMarshalingRequired(key, (DWORD)result)); } -void MethodContext::dmpPInvokeMarshalingRequired(const MethodSigInfoPairValue& key, DWORD value) +void MethodContext::dmpPInvokeMarshalingRequired(const MethodOrSigInfoValue& key, DWORD value) { printf("PInvokeMarshalingRequired key mth-%016llX scp-%016llX sig-%u, value res-%u", key.method, key.scope, key.pSig_Index, value); @@ -3767,8 +3767,8 @@ bool MethodContext::repPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, C if (PInvokeMarshalingRequired == nullptr) // so when we replay checked on free, we throw from lwm return TRUE; // TODO-Cleanup: hackish... - MethodSigInfoPairValue key; - ZeroMemory(&key, sizeof(MethodSigInfoPairValue)); // We use the input structs as a key and use memcmp to + MethodOrSigInfoValue key; + ZeroMemory(&key, sizeof(MethodOrSigInfoValue)); // We use the input structs as a key and use memcmp to // compare.. so we need to zero out padding too key.method = (DWORDLONG)method; @@ -3787,10 +3787,10 @@ void MethodContext::recGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, bool suppressGCTransitionResult) { if (GetUnmanagedCallConv == nullptr) - GetUnmanagedCallConv = new LightWeightMap(); + GetUnmanagedCallConv = new LightWeightMap(); - MethodSigInfoPairValue key; - ZeroMemory(&key, sizeof(MethodSigInfoPairValue)); // We use the input structs as a key and use memcmp to + MethodOrSigInfoValue key; + ZeroMemory(&key, sizeof(MethodOrSigInfoValue)); // We use the input structs as a key and use memcmp to // compare.. so we need to zero out padding too key.method = (DWORDLONG)method; @@ -3801,7 +3801,7 @@ void MethodContext::recGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, GetUnmanagedCallConv->Add(key, { (DWORD)result, (DWORD)suppressGCTransitionResult }); DEBUG_REC(dmpGetUnmanagedCallConv(key, { (DWORD)result, (DWORD)suppressGCTransitionResult })); } -void MethodContext::dmpGetUnmanagedCallConv(const MethodSigInfoPairValue& key, DD value) +void MethodContext::dmpGetUnmanagedCallConv(const MethodOrSigInfoValue& key, DD value) { printf("GetUnmanagedCallConv key mth-%016llX scp-%016llX sig-%u, value res-%u,%u", key.method, key.scope, key.pSig_Index, value.A, value.B); @@ -3820,8 +3820,8 @@ CorInfoCallConvExtension MethodContext::repGetUnmanagedCallConv(CORINFO_METHOD_H #endif } - MethodSigInfoPairValue key; - ZeroMemory(&key, sizeof(MethodSigInfoPairValue)); // We use the input structs as a key and use memcmp to + MethodOrSigInfoValue key; + ZeroMemory(&key, sizeof(MethodOrSigInfoValue)); // We use the input structs as a key and use memcmp to // compare.. so we need to zero out padding too key.method = (DWORDLONG)method; diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h index edd10e484c975..666c771830adc 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h @@ -318,7 +318,7 @@ class MethodContext DWORD sigTOK; DWORDLONG context; }; - struct MethodSigInfoPairValue + struct MethodOrSigInfoValue { DWORDLONG method; DWORD pSig_Index; @@ -999,11 +999,11 @@ class MethodContext CORINFO_CLASS_HANDLE repEmbedClassHandle(CORINFO_CLASS_HANDLE handle, void** ppIndirection); void recPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool result); - void dmpPInvokeMarshalingRequired(const MethodSigInfoPairValue& key, DWORD value); + void dmpPInvokeMarshalingRequired(const MethodOrSigInfoValue& key, DWORD value); bool repPInvokeMarshalingRequired(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig); void recGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, CorInfoCallConvExtension result, bool suppressGCTransitionResult); - void dmpGetUnmanagedCallConv(const MethodSigInfoPairValue& key, DD value); + void dmpGetUnmanagedCallConv(const MethodOrSigInfoValue& key, DD value); CorInfoCallConvExtension repGetUnmanagedCallConv(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* callSiteSig, bool* pSuppressGCTransition); void recFindSig(CORINFO_MODULE_HANDLE module, From be82f9697b5066b94ac3e70ab3563642122579c9 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 11 Dec 2020 16:38:26 -0800 Subject: [PATCH 27/38] Add default condition to make clang happy. --- src/coreclr/jit/compiler.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index a368cb2a18fcd..d2a91eb98beb4 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -6110,6 +6110,8 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr, case CORINFO_CALLCONV_VARARG: info.compIsVarArgs = true; break; + default: + break; } info.compRetNativeType = info.compRetType = JITtype2varType(methodInfo->args.retType); From dd0c6920d178aab48201a11264d07d4b3a053320 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 11 Dec 2020 17:02:25 -0800 Subject: [PATCH 28/38] change enums to make clang happy. --- src/coreclr/inc/corhdr.h | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/coreclr/inc/corhdr.h b/src/coreclr/inc/corhdr.h index c410f4026de6f..fd3dc4735de5f 100644 --- a/src/coreclr/inc/corhdr.h +++ b/src/coreclr/inc/corhdr.h @@ -954,11 +954,21 @@ typedef enum CorSerializationType // Calling convention flags. // +typedef enum CorUnmanagedCallingConvention +{ + IMAGE_CEE_UNMANAGED_CALLCONV_C = 0x1, + IMAGE_CEE_UNMANAGED_CALLCONV_STDCALL = 0x2, + IMAGE_CEE_UNMANAGED_CALLCONV_THISCALL = 0x3, + IMAGE_CEE_UNMANAGED_CALLCONV_FASTCALL = 0x4, +} CorUnmanagedCallingConvention; typedef enum CorCallingConvention { IMAGE_CEE_CS_CALLCONV_DEFAULT = 0x0, - + IMAGE_CEE_CS_CALLCONV_C = IMAGE_CEE_UNMANAGED_CALLCONV_C, + IMAGE_CEE_CS_CALLCONV_STDCALL = IMAGE_CEE_UNMANAGED_CALLCONV_STDCALL, + IMAGE_CEE_CS_CALLCONV_THISCALL = IMAGE_CEE_UNMANAGED_CALLCONV_THISCALL, + IMAGE_CEE_CS_CALLCONV_FASTCALL = IMAGE_CEE_UNMANAGED_CALLCONV_FASTCALL, IMAGE_CEE_CS_CALLCONV_VARARG = 0x5, IMAGE_CEE_CS_CALLCONV_FIELD = 0x6, IMAGE_CEE_CS_CALLCONV_LOCAL_SIG = 0x7, @@ -979,20 +989,6 @@ typedef enum CorCallingConvention #define IMAGE_CEE_CS_CALLCONV_INSTANTIATION IMAGE_CEE_CS_CALLCONV_GENERICINST -typedef enum CorUnmanagedCallingConvention -{ - IMAGE_CEE_UNMANAGED_CALLCONV_C = 0x1, - IMAGE_CEE_UNMANAGED_CALLCONV_STDCALL = 0x2, - IMAGE_CEE_UNMANAGED_CALLCONV_THISCALL = 0x3, - IMAGE_CEE_UNMANAGED_CALLCONV_FASTCALL = 0x4, - - IMAGE_CEE_CS_CALLCONV_C = IMAGE_CEE_UNMANAGED_CALLCONV_C, - IMAGE_CEE_CS_CALLCONV_STDCALL = IMAGE_CEE_UNMANAGED_CALLCONV_STDCALL, - IMAGE_CEE_CS_CALLCONV_THISCALL = IMAGE_CEE_UNMANAGED_CALLCONV_THISCALL, - IMAGE_CEE_CS_CALLCONV_FASTCALL = IMAGE_CEE_UNMANAGED_CALLCONV_FASTCALL, - -} CorUnmanagedCallingConvention; - typedef enum CorArgType { From 8ba8f9b6b6876c638674827de401ecf52fc735e9 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 11 Dec 2020 17:09:57 -0800 Subject: [PATCH 29/38] Remove CORINFO_CALLCONV_C and family from interpreter. --- src/coreclr/vm/interpreter.cpp | 32 ++++++++++++++++---------------- src/coreclr/vm/interpreter.h | 10 ---------- 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/src/coreclr/vm/interpreter.cpp b/src/coreclr/vm/interpreter.cpp index 5fd9830b00f43..325aaf4590b9e 100644 --- a/src/coreclr/vm/interpreter.cpp +++ b/src/coreclr/vm/interpreter.cpp @@ -384,20 +384,20 @@ void InterpreterMethodInfo::InitArgInfo(CEEInfo* comp, CORINFO_METHOD_INFO* meth } break; - case CORINFO_CALLCONV_C: - NYI_INTERP("InterpreterMethodInfo::InitArgInfo -- CORINFO_CALLCONV_C"); + case IMAGE_CEE_CS_CALLCONV_C: + NYI_INTERP("InterpreterMethodInfo::InitArgInfo -- IMAGE_CEE_CS_CALLCONV_C"); break; - case CORINFO_CALLCONV_STDCALL: - NYI_INTERP("InterpreterMethodInfo::InitArgInfo -- CORINFO_CALLCONV_STDCALL"); + case IMAGE_CEE_CS_CALLCONV_STDCALL: + NYI_INTERP("InterpreterMethodInfo::InitArgInfo -- IMAGE_CEE_CS_CALLCONV_STDCALL"); break; - case CORINFO_CALLCONV_THISCALL: - NYI_INTERP("InterpreterMethodInfo::InitArgInfo -- CORINFO_CALLCONV_THISCALL"); + case IMAGE_CEE_CS_CALLCONV_THISCALL: + NYI_INTERP("InterpreterMethodInfo::InitArgInfo -- IMAGE_CEE_CS_CALLCONV_THISCALL"); break; - case CORINFO_CALLCONV_FASTCALL: - NYI_INTERP("InterpreterMethodInfo::InitArgInfo -- CORINFO_CALLCONV_FASTCALL"); + case IMAGE_CEE_CS_CALLCONV_FASTCALL: + NYI_INTERP("InterpreterMethodInfo::InitArgInfo -- IMAGE_CEE_CS_CALLCONV_FASTCALL"); break; case CORINFO_CALLCONV_FIELD: @@ -1261,20 +1261,20 @@ CorJitResult Interpreter::GenerateInterpreterStub(CEEInfo* comp, } break; - case CORINFO_CALLCONV_C: - NYI_INTERP("GenerateInterpreterStub -- CORINFO_CALLCONV_C"); + case IMAGE_CEE_CS_CALLCONV_C: + NYI_INTERP("GenerateInterpreterStub -- IMAGE_CEE_CS_CALLCONV_C"); break; - case CORINFO_CALLCONV_STDCALL: - NYI_INTERP("GenerateInterpreterStub -- CORINFO_CALLCONV_STDCALL"); + case IMAGE_CEE_CS_CALLCONV_STDCALL: + NYI_INTERP("GenerateInterpreterStub -- IMAGE_CEE_CS_CALLCONV_STDCALL"); break; - case CORINFO_CALLCONV_THISCALL: - NYI_INTERP("GenerateInterpreterStub -- CORINFO_CALLCONV_THISCALL"); + case IMAGE_CEE_CS_CALLCONV_THISCALL: + NYI_INTERP("GenerateInterpreterStub -- IMAGE_CEE_CS_CALLCONV_THISCALL"); break; - case CORINFO_CALLCONV_FASTCALL: - NYI_INTERP("GenerateInterpreterStub -- CORINFO_CALLCONV_FASTCALL"); + case IMAGE_CEE_CS_CALLCONV_FASTCALL: + NYI_INTERP("GenerateInterpreterStub -- IMAGE_CEE_CS_CALLCONV_FASTCALL"); break; case CORINFO_CALLCONV_FIELD: diff --git a/src/coreclr/vm/interpreter.h b/src/coreclr/vm/interpreter.h index a819291043c09..5b1aea0335aed 100644 --- a/src/coreclr/vm/interpreter.h +++ b/src/coreclr/vm/interpreter.h @@ -142,16 +142,6 @@ enum CorInfoTypeShifted CORINFO_TYPE_SHIFTED_VAR = unsigned(CORINFO_TYPE_VAR) << 2, //0x16 << 2 = 0x58 }; -enum CorInfoUnmanagedCallConv -{ - // Corresponds to the unmanaged calling conventions specified in metadata. - // Equivalent to the CorUnmanagedCallingConvention enum - CORINFO_CALLCONV_C = 0x1, - CORINFO_CALLCONV_STDCALL = 0x2, - CORINFO_CALLCONV_THISCALL = 0x3, - CORINFO_CALLCONV_FASTCALL = 0x4, -}; - class InterpreterType { // We use this typedef, but the InterpreterType is actually encoded. We assume that the two From 31eb30a4b3de43cc16ab6ca8b35b67b932864eb6 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 14 Dec 2020 10:44:51 -0800 Subject: [PATCH 30/38] Fix up handling of managed function pointers and remove invalid assert. --- src/coreclr/jit/importer.cpp | 5 +++++ src/coreclr/vm/jitinterface.cpp | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 443755bb90a32..fc92d845a7f88 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -7045,6 +7045,11 @@ void Compiler::impCheckForPInvokeCall( } else { + if (sig->getCallConv() == CORINFO_CALLCONV_DEFAULT || sig->getCallConv() == CORINFO_CALLCONV_VARARG) + { + return; + } + unmanagedCallConv = info.compCompHnd->getUnmanagedCallConv(nullptr, sig, &suppressGCTransition); assert(!call->gtCallCookie); diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index e0ca7f482f187..9e7ac189652d1 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -554,8 +554,6 @@ CEEInfo::ConvToJitSig( sigRet->args = (CORINFO_ARG_LIST_HANDLE)sig.GetPtr(); } - _ASSERTE(sigRet->callConv != CORINFO_CALLCONV_UNMANAGED); - // Set computed flags sigRet->flags = sigRetFlags; From 1be214b96e89e49c2b428050d94ab7418d8dec95 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 14 Dec 2020 10:56:04 -0800 Subject: [PATCH 31/38] Continue to use sigflag for suppressgc workaround. --- src/coreclr/inc/corinfo.h | 2 +- .../tools/Common/JitInterface/CorInfoImpl.cs | 37 +++++++++++-------- .../tools/Common/JitInterface/CorInfoTypes.cs | 2 +- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index aaec3ff51da36..1d4ac4a058668 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -1067,7 +1067,7 @@ enum CorInfoSigInfoFlags { CORINFO_SIGFLAG_IS_LOCAL_SIG = 0x01, CORINFO_SIGFLAG_IL_STUB = 0x02, - // unused = 0x04, + CORINFO_SIGFLAG_SUPPRESS_GC_TRANSITION = 0x04, CORINFO_SIGFLAG_FAT_CALL = 0x08, }; diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index b8cc74fa0b206..ff5745258b0d9 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -484,7 +484,7 @@ private bool Get_CORINFO_METHOD_INFO(MethodDesc method, MethodIL methodIL, CORIN private void Get_CORINFO_SIG_INFO(MethodDesc method, MethodIL methodIL, CORINFO_SIG_INFO* sig, bool suppressHiddenArgument = false) { - Get_CORINFO_SIG_INFO(method.Signature, methodIL, sig); + Get_CORINFO_SIG_INFO(method.Signature, sig); // Does the method have a hidden parameter? bool hasHiddenParameter = !suppressHiddenArgument && method.RequiresInstArg(); @@ -612,7 +612,7 @@ private bool TryGetUnmanagedCallingConventionFromModOpt(MethodSignature signatur _ => null }; - private void Get_CORINFO_SIG_INFO(MethodSignature signature, MethodIL methodIL, CORINFO_SIG_INFO* sig) + private void Get_CORINFO_SIG_INFO(MethodSignature signature, CORINFO_SIG_INFO* sig) { sig->callConv = (CorInfoCallConv)(signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask); @@ -641,7 +641,7 @@ private void Get_CORINFO_SIG_INFO(MethodSignature signature, MethodIL methodIL, sig->pSig = (byte*)ObjectToHandle(signature); sig->cbSig = 0; // Not used by the JIT - sig->scope = (CORINFO_MODULE_STRUCT_*)ObjectToHandle(methodIL); + sig->scope = null; sig->token = 0; // Not used by the JIT } @@ -1069,7 +1069,11 @@ private CorInfoCallConvExtension getUnmanagedCallConv(CORINFO_METHOD_STRUCT_* me { Debug.Assert(sig != null); - CorInfoCallConvExtension callConv = GetUnmanagedCallConv((MethodSignature)HandleToObject((IntPtr)sig->pSig), (MethodIL)HandleToObject((IntPtr)sig->scope), out pSuppressGCTransition); + CorInfoCallConvExtension callConv = GetUnmanagedCallConv((MethodSignature)HandleToObject((IntPtr)sig->pSig), out pSuppressGCTransition); + if (!pSuppressGCTransition && sig->flags.HasFlag(CorInfoSigInfoFlags.CORINFO_SIGFLAG_SUPPRESS_GC_TRANSITION)) + { + pSuppressGCTransition = true; + } return callConv; } } @@ -1101,21 +1105,12 @@ private CorInfoCallConvExtension GetUnmanagedCallConv(MethodDesc methodDesc, out return GetUnmanagedCallingConventionFromAttribute(unmanagedCallersOnlyAttribute); } } - // We don't want to do any additional resolution based on what method we're in, - // so don't pass the current method's IL context for when we process the signature. - return GetUnmanagedCallConv(methodDesc.Signature, null, out suppressGCTransition); + return GetUnmanagedCallConv(methodDesc.Signature, out suppressGCTransition); } - private CorInfoCallConvExtension GetUnmanagedCallConv(MethodSignature signature, MethodIL methodIL, out bool suppressGCTransition) + private CorInfoCallConvExtension GetUnmanagedCallConv(MethodSignature signature, out bool suppressGCTransition) { suppressGCTransition = false; - // TODO: Remove when we have a public way to represent SuppressGCTransition on a calli. - if (methodIL is PInvokeILStubMethodIL stubIL && - stubIL.OwningMethod.IsPInvoke && - stubIL.OwningMethod.IsSuppressGCTransition()) - { - suppressGCTransition = true; - } switch (signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) { case MethodSignatureFlags.None: @@ -1387,7 +1382,17 @@ private void findSig(CORINFO_MODULE_STRUCT_* module, uint sigTOK, CORINFO_CONTEX var methodIL = (MethodIL)HandleToObject((IntPtr)module); var methodSig = (MethodSignature)methodIL.GetObject((int)sigTOK); - Get_CORINFO_SIG_INFO(methodSig, methodIL, sig); + Get_CORINFO_SIG_INFO(methodSig, sig); + + // TODO: Replace this with a public mechanism to mark calli with SuppressGCTransition once it becomes available. + if (methodIL is PInvokeILStubMethodIL stubIL) + { + var method = stubIL.OwningMethod; + if (method.IsPInvoke && method.IsSuppressGCTransition()) + { + sig->flags |= CorInfoSigInfoFlags.CORINFO_SIGFLAG_SUPPRESS_GC_TRANSITION; + } + } #if !READYTORUN // Check whether we need to report this as a fat pointer call diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index 68f41d0cf9038..38a627667f9eb 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -370,7 +370,7 @@ public enum CorInfoSigInfoFlags : byte { CORINFO_SIGFLAG_IS_LOCAL_SIG = 0x01, CORINFO_SIGFLAG_IL_STUB = 0x02, - // unused = 0x04, + CORINFO_SIGFLAG_SUPPRESS_GC_TRANSITION = 0x04, CORINFO_SIGFLAG_FAT_CALL = 0x08, }; From 1440fad0e71c8b401e98ae96c48d9531ecd841f0 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 14 Dec 2020 11:02:49 -0800 Subject: [PATCH 32/38] Clean up comment wording. Signed-off-by: Jeremy Koritzinsky --- src/coreclr/jit/importer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index fc92d845a7f88..4a08e4d3a32b9 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -8479,7 +8479,7 @@ var_types Compiler::impImportCall(OPCODE opcode, } #ifdef UNIX_X86_ABI - // On Unix x86 we usually use caller-cleaned convention. + // On Unix x86 we use caller-cleaned convention. if ((call->gtFlags & GTF_CALL_UNMANAGED) == 0) call->gtFlags |= GTF_CALL_POP_ARGS; #endif // UNIX_X86_ABI From ed5b32e44d22f5bb41f16adef479c0e6b61d18ee Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 14 Dec 2020 11:06:13 -0800 Subject: [PATCH 33/38] Remove more MethodIL passing we don't need any more --- src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs | 8 ++++---- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index ff5745258b0d9..8bc24a468c88c 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -476,13 +476,13 @@ private bool Get_CORINFO_METHOD_INFO(MethodDesc method, MethodIL methodIL, CORIN methodInfo->options |= CorInfoOptions.CORINFO_GENERICS_CTXT_FROM_METHODTABLE; } methodInfo->regionKind = CorInfoRegionKind.CORINFO_REGION_NONE; - Get_CORINFO_SIG_INFO(method, methodIL, sig: &methodInfo->args); + Get_CORINFO_SIG_INFO(method, sig: &methodInfo->args); Get_CORINFO_SIG_INFO(methodIL.GetLocals(), &methodInfo->locals); return true; } - private void Get_CORINFO_SIG_INFO(MethodDesc method, MethodIL methodIL, CORINFO_SIG_INFO* sig, bool suppressHiddenArgument = false) + private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, bool suppressHiddenArgument = false) { Get_CORINFO_SIG_INFO(method.Signature, sig); @@ -907,7 +907,7 @@ private void getMethodSig(CORINFO_METHOD_STRUCT_* ftn, CORINFO_SIG_INFO* sig, CO } } - Get_CORINFO_SIG_INFO(method, _compilation.GetMethodIL(method), sig: sig); + Get_CORINFO_SIG_INFO(method, sig: sig); } private bool getMethodInfo(CORINFO_METHOD_STRUCT_* ftn, CORINFO_METHOD_INFO* info) @@ -1408,7 +1408,7 @@ private void findSig(CORINFO_MODULE_STRUCT_* module, uint sigTOK, CORINFO_CONTEX private void findCallSiteSig(CORINFO_MODULE_STRUCT_* module, uint methTOK, CORINFO_CONTEXT_STRUCT* context, CORINFO_SIG_INFO* sig) { var methodIL = (MethodIL)HandleToObject((IntPtr)module); - Get_CORINFO_SIG_INFO(((MethodDesc)methodIL.GetObject((int)methTOK)), methodIL, sig: sig); + Get_CORINFO_SIG_INFO(((MethodDesc)methodIL.GetObject((int)methTOK)), sig: sig); } private CORINFO_CLASS_STRUCT_* getTokenTypeAsHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken) diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index cb44df2efbf7d..61779f5406ab6 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -1663,7 +1663,7 @@ private void ceeInfoGetCallInfo( pResult->wrapperDelegateInvoke = false; - Get_CORINFO_SIG_INFO(methodToCall, (MethodIL)HandleToObject((IntPtr)pResolvedToken.tokenScope), &pResult->sig, useInstantiatingStub); + Get_CORINFO_SIG_INFO(methodToCall, &pResult->sig, useInstantiatingStub); } private uint getMethodAttribs(CORINFO_METHOD_STRUCT_* ftn) From 3d5c8e267ad9d4e234428a4de38a89ceeb1a0fa6 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 14 Dec 2020 11:21:46 -0800 Subject: [PATCH 34/38] Update src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs Co-authored-by: Jan Kotas --- src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 8bc24a468c88c..c88f858afacfd 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -1070,7 +1070,7 @@ private CorInfoCallConvExtension getUnmanagedCallConv(CORINFO_METHOD_STRUCT_* me Debug.Assert(sig != null); CorInfoCallConvExtension callConv = GetUnmanagedCallConv((MethodSignature)HandleToObject((IntPtr)sig->pSig), out pSuppressGCTransition); - if (!pSuppressGCTransition && sig->flags.HasFlag(CorInfoSigInfoFlags.CORINFO_SIGFLAG_SUPPRESS_GC_TRANSITION)) + if (sig->flags.HasFlag(CorInfoSigInfoFlags.CORINFO_SIGFLAG_SUPPRESS_GC_TRANSITION)) { pSuppressGCTransition = true; } From dead19dced22732a521d144d75cbc0624c7b9140 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 14 Dec 2020 13:58:39 -0800 Subject: [PATCH 35/38] Fix SigTypeContext creation. --- src/coreclr/vm/jitinterface.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 9e7ac189652d1..cd8f46ce32a7c 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -1834,12 +1834,15 @@ CEEInfo::findCallSiteSig( } } + SigTypeContext typeContext; + GetTypeContext(context, &typeContext); + CEEInfo::ConvToJitSig( pSig, cbSig, scopeHnd, sigMethTok, - SigTypeContext(GetMethodFromContext(context), GetTypeFromContext(context)), + typeContext, CONV_TO_JITSIG_FLAGS_NONE, sigRet); EE_TO_JIT_TRANSITION(); @@ -1882,12 +1885,15 @@ CEEInfo::findSig( &pSig)); } + SigTypeContext typeContext; + GetTypeContext(context, &typeContext); + CEEInfo::ConvToJitSig( pSig, cbSig, scopeHnd, sigTok, - SigTypeContext(GetMethodFromContext(context), GetTypeFromContext(context)), + typeContext, CONV_TO_JITSIG_FLAGS_NONE, sigRet); From 6a4cbebf974bdd643a780320a7628c000b9ff2f1 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 14 Dec 2020 14:47:59 -0800 Subject: [PATCH 36/38] Pass context by ptr. --- src/coreclr/vm/jitinterface.cpp | 28 ++++++++++++++++------------ src/coreclr/vm/jitinterface.h | 2 +- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 74379cdf1a760..10a1d5c5b7eab 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -452,7 +452,7 @@ CEEInfo::ConvToJitSig( DWORD cbSig, CORINFO_MODULE_HANDLE scopeHnd, mdToken token, - SigTypeContext typeContext, + SigTypeContext* typeContext, ConvToJitSigFlags flags, CORINFO_SIG_INFO * sigRet) { @@ -476,10 +476,10 @@ CEEInfo::ConvToJitSig( sigRet->retTypeSigClass = 0; sigRet->scope = scopeHnd; sigRet->token = token; - sigRet->sigInst.classInst = (CORINFO_CLASS_HANDLE *) typeContext.m_classInst.GetRawArgs(); - sigRet->sigInst.classInstCount = (unsigned) typeContext.m_classInst.GetNumArgs(); - sigRet->sigInst.methInst = (CORINFO_CLASS_HANDLE *) typeContext.m_methodInst.GetRawArgs(); - sigRet->sigInst.methInstCount = (unsigned) typeContext.m_methodInst.GetNumArgs(); + sigRet->sigInst.classInst = (CORINFO_CLASS_HANDLE *) typeContext->m_classInst.GetRawArgs(); + sigRet->sigInst.classInstCount = (unsigned) typeContext->m_classInst.GetNumArgs(); + sigRet->sigInst.methInst = (CORINFO_CLASS_HANDLE *) typeContext->m_methodInst.GetRawArgs(); + sigRet->sigInst.methInstCount = (unsigned) typeContext->m_methodInst.GetNumArgs(); SigPointer sig(pSig, cbSig); @@ -515,11 +515,11 @@ CEEInfo::ConvToJitSig( sigRet->numArgs = (unsigned short) numArgs; - CorElementType type = sig.PeekElemTypeClosed(module, &typeContext); + CorElementType type = sig.PeekElemTypeClosed(module, typeContext); if (!CorTypeInfo::IsPrimitiveType(type)) { - typeHnd = sig.GetTypeHandleThrowing(module, &typeContext); + typeHnd = sig.GetTypeHandleThrowing(module, typeContext); _ASSERTE(!typeHnd.IsNull()); // I believe it doesn't make any diff. if this is @@ -1852,7 +1852,7 @@ CEEInfo::findCallSiteSig( cbSig, scopeHnd, sigMethTok, - typeContext, + &typeContext, CONV_TO_JITSIG_FLAGS_NONE, sigRet); EE_TO_JIT_TRANSITION(); @@ -1903,7 +1903,7 @@ CEEInfo::findSig( cbSig, scopeHnd, sigTok, - typeContext, + &typeContext, CONV_TO_JITSIG_FLAGS_NONE, sigRet); @@ -7726,6 +7726,8 @@ getMethodInfoHelper( DWORD cbSig = 0; ftn->GetSig(&pSig, &cbSig); + SigTypeContext context(ftn); + /* Fetch the method signature */ // Type parameters in the signature should be instantiated according to the // class/method/array instantiation of ftnHnd @@ -7734,7 +7736,7 @@ getMethodInfoHelper( cbSig, GetScopeHandle(ftn), mdTokenNil, - SigTypeContext(ftn), + &context, CEEInfo::CONV_TO_JITSIG_FLAGS_NONE, &methInfo->args); @@ -7753,7 +7755,7 @@ getMethodInfoHelper( cbLocalSig, GetScopeHandle(ftn), mdTokenNil, - SigTypeContext(ftn), + &context, CEEInfo::CONV_TO_JITSIG_FLAGS_LOCALSIG, &methInfo->locals); @@ -8588,6 +8590,8 @@ CEEInfo::getMethodSigInternal( DWORD cbSig = 0; ftn->GetSig(&pSig, &cbSig); + SigTypeContext context(ftn, (TypeHandle)owner); + // Type parameters in the signature are instantiated // according to the class/method/array instantiation of ftnHnd and owner CEEInfo::ConvToJitSig( @@ -8595,7 +8599,7 @@ CEEInfo::getMethodSigInternal( cbSig, GetScopeHandle(ftn), mdTokenNil, - SigTypeContext(ftn, (TypeHandle)owner), + &context, CONV_TO_JITSIG_FLAGS_NONE, sigRet); diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index a17b59724d899..8b681c4818e57 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -556,7 +556,7 @@ class CEEInfo : public ICorJitInfo DWORD cbSig, CORINFO_MODULE_HANDLE scopeHnd, mdToken token, - SigTypeContext context, + SigTypeContext* context, ConvToJitSigFlags flags, CORINFO_SIG_INFO * sigRet); From 6b870e646f26cf0718e27fe5a66dc9b0850c6a5d Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 14 Dec 2020 15:02:01 -0800 Subject: [PATCH 37/38] Fix formatting. --- src/coreclr/jit/importer.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index f451820211aa9..ff6556dab12b6 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -8499,7 +8499,7 @@ var_types Compiler::impImportCall(OPCODE opcode, goto DONE; } else if ((opcode == CEE_CALLI) && ((sig->callConv & CORINFO_CALLCONV_MASK) != CORINFO_CALLCONV_DEFAULT) && - ((sig->callConv & CORINFO_CALLCONV_MASK) != CORINFO_CALLCONV_VARARG)) + ((sig->callConv & CORINFO_CALLCONV_MASK) != CORINFO_CALLCONV_VARARG)) { if (!info.compCompHnd->canGetCookieForPInvokeCalliSig(sig)) { @@ -9254,9 +9254,7 @@ bool Compiler::impMethodInfo_hasRetBuffArg(CORINFO_METHOD_INFO* methInfo, CorInf // We have some kind of STRUCT being returned structPassingKind howToReturnStruct = SPK_Unknown; - var_types returnType = - getReturnTypeForStruct(methInfo->args.retTypeClass, callConv, - &howToReturnStruct); + var_types returnType = getReturnTypeForStruct(methInfo->args.retTypeClass, callConv, &howToReturnStruct); if (howToReturnStruct == SPK_ByReference) { From 792d56f1800401dce3dcab83b07eaa63542d7d5b Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 14 Dec 2020 16:38:49 -0800 Subject: [PATCH 38/38] Clear the Reverse P/Invoke flag when compiling inlinees. It's only needed on the entry-point functions. --- src/coreclr/jit/compiler.cpp | 1 + src/coreclr/jit/flowgraph.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index d2a91eb98beb4..171bebb45e72b 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -2570,6 +2570,7 @@ void Compiler::compInitOptions(JitFlags* jitFlags) assert(!jitFlags->IsSet(JitFlags::JIT_FLAG_PROF_ENTERLEAVE)); assert(!jitFlags->IsSet(JitFlags::JIT_FLAG_DEBUG_EnC)); assert(!jitFlags->IsSet(JitFlags::JIT_FLAG_DEBUG_INFO)); + assert(!jitFlags->IsSet(JitFlags::JIT_FLAG_REVERSE_PINVOKE)); } opts.jitFlags = jitFlags; diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp index f22c4cde83f81..46c4e75cdfbc1 100644 --- a/src/coreclr/jit/flowgraph.cpp +++ b/src/coreclr/jit/flowgraph.cpp @@ -23497,6 +23497,7 @@ void Compiler::fgInvokeInlineeCompiler(GenTreeCall* call, InlineResult* inlineRe compileFlagsForInlinee.Clear(JitFlags::JIT_FLAG_PROF_ENTERLEAVE); compileFlagsForInlinee.Clear(JitFlags::JIT_FLAG_DEBUG_EnC); compileFlagsForInlinee.Clear(JitFlags::JIT_FLAG_DEBUG_INFO); + compileFlagsForInlinee.Clear(JitFlags::JIT_FLAG_REVERSE_PINVOKE); compileFlagsForInlinee.Set(JitFlags::JIT_FLAG_SKIP_VERIFICATION);