From fbf837886e5c97b5ae5321c47e18313a2e0e6e2c Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Fri, 6 Dec 2024 22:09:22 -0800 Subject: [PATCH 01/21] Convert Signature.GetSignature() to QCall. Rename Signature.GetSignature() to Signature.Init(). --- .../src/System/RuntimeHandles.cs | 96 +++++++---- src/coreclr/vm/ecalllist.h | 1 - src/coreclr/vm/qcallentrypoints.cpp | 1 + src/coreclr/vm/runtimehandles.cpp | 160 +++++++++--------- src/coreclr/vm/runtimehandles.h | 30 ++-- 5 files changed, 158 insertions(+), 130 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index a1907fd90df76..d15bea6028c67 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -1895,68 +1895,94 @@ internal static int GetMDStreamVersion(RuntimeModule module) internal sealed unsafe partial class Signature { - #region FCalls - [MemberNotNull(nameof(m_arguments))] - [MemberNotNull(nameof(m_declaringType))] - [MemberNotNull(nameof(m_returnTypeORfieldType))] - [MethodImpl(MethodImplOptions.InternalCall)] - private extern void GetSignature( - void* pCorSig, int cCorSig, - RuntimeFieldHandleInternal fieldHandle, IRuntimeMethodInfo? methodHandle, RuntimeType? declaringType); - #endregion - #region Private Data Members // // Keep the layout in sync with SignatureNative in the VM // - internal RuntimeType[] m_arguments; - internal RuntimeType m_declaringType; - internal RuntimeType m_returnTypeORfieldType; - internal object? m_keepalive; - internal void* m_sig; - internal int m_managedCallingConventionAndArgIteratorFlags; // lowest byte is CallingConvention, upper 3 bytes are ArgIterator flags - internal int m_nSizeOfArgStack; - internal int m_csig; - internal RuntimeMethodHandleInternal m_pMethod; + private RuntimeType[]? _arguments; + private RuntimeType _declaringType; + private RuntimeType _returnTypeORfieldType; +#pragma warning disable CA1823, 169 + private object? _keepAlive; +#pragma warning restore CA1823, 169 + private void* _sig; + private int _csig; + private int _managedCallingConventionAndArgIteratorFlags; // lowest byte is CallingConvention, upper 3 bytes are ArgIterator flags +#pragma warning disable CA1823, 169 + private int _nSizeOfArgStack; +#pragma warning restore CA1823, 169 + private RuntimeMethodHandleInternal _pMethod; #endregion + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Signature_Init")] + private static partial void Init( + ObjectHandleOnStack _this, + void* pCorSig, int cCorSig, + RuntimeFieldHandleInternal fieldHandle, + RuntimeMethodHandleInternal methodHandle, + IntPtr typeHandle); + + [MemberNotNull(nameof(_declaringType))] + [MemberNotNull(nameof(_returnTypeORfieldType))] + private void Init( + void* pCorSig, int cCorSig, + RuntimeFieldHandleInternal fieldHandle, + RuntimeMethodHandleInternal methodHandle) + { + Signature _this = this; + IntPtr typeHandle = _declaringType?.GetUnderlyingNativeHandle() ?? IntPtr.Zero; + Init(ObjectHandleOnStack.Create(ref _this), + pCorSig, cCorSig, + fieldHandle, + methodHandle, + typeHandle); + Debug.Assert(_declaringType != null); + Debug.Assert(_returnTypeORfieldType != null); + } + #region Constructors public Signature( - IRuntimeMethodInfo method, + IRuntimeMethodInfo methodHandle, RuntimeType[] arguments, RuntimeType returnType, CallingConventions callingConvention) { - m_pMethod = method.Value; - m_arguments = arguments; - m_returnTypeORfieldType = returnType; - m_managedCallingConventionAndArgIteratorFlags = (byte)callingConvention; + _arguments = arguments; + _returnTypeORfieldType = returnType; + _managedCallingConventionAndArgIteratorFlags = (int)callingConvention; + Debug.Assert((_managedCallingConventionAndArgIteratorFlags & 0xffffff00) == 0); + _pMethod = methodHandle.Value; - GetSignature(null, 0, default, method, null); + Init(null, 0, default, methodHandle.Value); + GC.KeepAlive(methodHandle); } public Signature(IRuntimeMethodInfo methodHandle, RuntimeType declaringType) { - GetSignature(null, 0, default, methodHandle, declaringType); + _declaringType = declaringType; + Init(null, 0, default, methodHandle.Value); + GC.KeepAlive(methodHandle); } public Signature(IRuntimeFieldInfo fieldHandle, RuntimeType declaringType) { - GetSignature(null, 0, fieldHandle.Value, null, declaringType); + _declaringType = declaringType; + Init(null, 0, fieldHandle.Value, default); GC.KeepAlive(fieldHandle); } public Signature(void* pCorSig, int cCorSig, RuntimeType declaringType) { - GetSignature(pCorSig, cCorSig, default, null, declaringType); + _declaringType = declaringType; + Init(pCorSig, cCorSig, default, default); } #endregion #region Internal Members - internal CallingConventions CallingConvention => (CallingConventions)(byte)m_managedCallingConventionAndArgIteratorFlags; - internal RuntimeType[] Arguments => m_arguments; - internal RuntimeType ReturnType => m_returnTypeORfieldType; - internal RuntimeType FieldType => m_returnTypeORfieldType; + internal CallingConventions CallingConvention => (CallingConventions)(_managedCallingConventionAndArgIteratorFlags & 0xff); + internal RuntimeType[] Arguments => _arguments ?? []; + internal RuntimeType ReturnType => _returnTypeORfieldType; + internal RuntimeType FieldType => _returnTypeORfieldType; [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Signature_AreEqual")] private static partial Interop.BOOL AreEqual( @@ -1966,8 +1992,8 @@ private static partial Interop.BOOL AreEqual( internal static bool AreEqual(Signature sig1, Signature sig2) { return AreEqual( - sig1.m_sig, sig1.m_csig, new QCallTypeHandle(ref sig1.m_declaringType), - sig2.m_sig, sig2.m_csig, new QCallTypeHandle(ref sig2.m_declaringType)) != Interop.BOOL.FALSE; + sig1._sig, sig1._csig, new QCallTypeHandle(ref sig1._declaringType), + sig2._sig, sig2._csig, new QCallTypeHandle(ref sig2._declaringType)) != Interop.BOOL.FALSE; } internal Type[] GetCustomModifiers(int parameterIndex, bool required) => @@ -1978,7 +2004,7 @@ internal Type[] GetCustomModifiers(int parameterIndex, bool required) => internal int GetParameterOffset(int parameterIndex) { - int offsetMaybe = GetParameterOffsetInternal(m_sig, m_csig, parameterIndex); + int offsetMaybe = GetParameterOffsetInternal(_sig, _csig, parameterIndex); // If the result is negative, it is an error code. if (offsetMaybe < 0) Marshal.ThrowExceptionForHR(offsetMaybe, new IntPtr(-1)); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index e1ba7a2aa4da9..bdd5d8561e2f9 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -132,7 +132,6 @@ FCFuncStart(gMetaDataImport) FCFuncEnd() FCFuncStart(gSignatureNative) - FCFuncElement("GetSignature", SignatureNative::GetSignature) FCFuncElement("GetParameterOffsetInternal", SignatureNative::GetParameterOffsetInternal) FCFuncElement("GetTypeParameterOffset", SignatureNative::GetTypeParameterOffset) FCFuncElement("GetCustomModifiersAtOffset", SignatureNative::GetCustomModifiersAtOffset) diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index f59728794c8ed..6347172021a89 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -188,6 +188,7 @@ static const Entry s_QCall[] = DllImportEntry(ModuleHandle_GetPEKind) DllImportEntry(ModuleHandle_GetDynamicMethod) DllImportEntry(AssemblyHandle_GetManifestModuleSlow) + DllImportEntry(Signature_Init) DllImportEntry(Signature_AreEqual) DllImportEntry(TypeBuilder_DefineGenericParam) DllImportEntry(TypeBuilder_DefineType) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 42f1772e37d8c..a7060f3054100 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -1718,115 +1718,111 @@ FCIMPL1(INT32, RuntimeMethodHandle::GetMethodDef, ReflectMethodObject *pMethodUN } FCIMPLEND -FCIMPL6(void, SignatureNative::GetSignature, - SignatureNative* pSignatureNativeUNSAFE, +extern "C" void QCALLTYPE Signature_Init( + QCall::ObjectHandleOnStack sigNative, PCCOR_SIGNATURE pCorSig, DWORD cCorSig, - FieldDesc *pFieldDesc, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE) { - CONTRACTL { - FCALL_CHECK; - PRECONDITION(pDeclaringTypeUNSAFE || pMethodUNSAFE->GetMethod()->IsDynamicMethod()); - PRECONDITION(CheckPointer(pCorSig, NULL_OK)); - PRECONDITION(CheckPointer(pMethodUNSAFE, NULL_OK)); - PRECONDITION(CheckPointer(pFieldDesc, NULL_OK)); - } - CONTRACTL_END; + FieldDesc* pFieldDesc, + MethodDesc* pMethodDesc, + EnregisteredTypeHandle typeHandleRaw) +{ + QCALL_CONTRACT; + + BEGIN_QCALL; + + GCX_COOP(); struct { - REFLECTCLASSBASEREF refDeclaringType; - REFLECTMETHODREF refMethod; SIGNATURENATIVEREF pSig; } gc; + gc.pSig = (SIGNATURENATIVEREF)sigNative.Get(); + GCPROTECT_BEGIN(gc); - gc.refDeclaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE); - gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE); - gc.pSig = (SIGNATURENATIVEREF)pSignatureNativeUNSAFE; - - MethodDesc *pMethod; - TypeHandle declType; - - if (gc.refDeclaringType == NULL) + TypeHandle declType = TypeHandle::FromPtr(typeHandleRaw); + if (declType.IsNull()) { - // for dynamic method, see precondition - pMethod = gc.refMethod->GetMethod(); - declType = pMethod->GetMethodTable(); - } - else - { - pMethod = gc.refMethod != NULL ? gc.refMethod->GetMethod() : NULL; - declType = gc.refDeclaringType->GetType(); + // Dynamic method case + _ASSERTE(pMethodDesc->IsDynamicMethod()); + declType = pMethodDesc->GetMethodTable(); + + REFLECTCLASSBASEREF refDeclType = (REFLECTCLASSBASEREF)declType.GetManagedClassObject(); + gc.pSig->SetDeclaringType(refDeclType); } + _ASSERTE(!declType.IsNull()); - HELPER_METHOD_FRAME_BEGIN_PROTECT(gc); + if (pMethodDesc != NULL) { - Module* pModule = declType.GetModule(); - - if (pMethod) + pMethodDesc->GetSig(&pCorSig, &cCorSig); + if (pMethodDesc->GetClassification() == mcInstantiated) { - pMethod->GetSig(&pCorSig, &cCorSig); - if (pMethod->GetClassification() == mcInstantiated) - { - LoaderAllocator *pLoaderAllocator = pMethod->GetLoaderAllocator(); - if (pLoaderAllocator->IsCollectible()) - gc.pSig->SetKeepAlive(pLoaderAllocator->GetExposedObject()); - } + LoaderAllocator *pLoaderAllocator = pMethodDesc->GetLoaderAllocator(); + if (pLoaderAllocator->IsCollectible()) + gc.pSig->SetKeepAlive(pLoaderAllocator->GetExposedObject()); } - else if (pFieldDesc) - pFieldDesc->GetSig(&pCorSig, &cCorSig); - - gc.pSig->m_sig = pCorSig; - gc.pSig->m_cSig = cCorSig; - gc.pSig->m_pMethod = pMethod; + } + else if (pFieldDesc != NULL) + { + pFieldDesc->GetSig(&pCorSig, &cCorSig); + } + _ASSERTE(pCorSig != NULL && cCorSig > 0); - REFLECTCLASSBASEREF refDeclType = (REFLECTCLASSBASEREF)declType.GetManagedClassObject(); - gc.pSig->SetDeclaringType(refDeclType); + gc.pSig->m_sig = pCorSig; + gc.pSig->m_cSig = cCorSig; + gc.pSig->m_pMethod = pMethodDesc; - PREFIX_ASSUME(pCorSig!= NULL); - BYTE callConv = *(BYTE*)pCorSig; - SigTypeContext typeContext; - if (pMethod) - SigTypeContext::InitTypeContext( - pMethod, declType.GetClassOrArrayInstantiation(), pMethod->LoadMethodInstantiation(), &typeContext); - else - SigTypeContext::InitTypeContext(declType, &typeContext); + uint32_t callConv; + if (FAILED(CorSigUncompressCallingConv(pCorSig, cCorSig, &callConv))) + COMPlusThrow(kBadImageFormatException); - MetaSig msig(pCorSig, cCorSig, pModule, &typeContext, - (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember); + SigTypeContext typeContext; + if (pMethodDesc != NULL) + { + SigTypeContext::InitTypeContext( + pMethodDesc, declType.GetClassOrArrayInstantiation(), pMethodDesc->LoadMethodInstantiation(), &typeContext); + } + else + { + SigTypeContext::InitTypeContext(declType, &typeContext); + } - if (callConv == IMAGE_CEE_CS_CALLCONV_FIELD) - { - msig.NextArgNormalized(); + Module* pModule = declType.GetModule(); + MetaSig msig(pCorSig, cCorSig, pModule, &typeContext, + (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember); - OBJECTREF refRetType = msig.GetLastTypeHandleThrowing().GetManagedClassObject(); - gc.pSig->SetReturnType(refRetType); - } - else - { - gc.pSig->SetCallingConvention(msig.GetCallingConventionInfo()); + if (callConv == IMAGE_CEE_CS_CALLCONV_FIELD) + { + msig.NextArgNormalized(); - OBJECTREF refRetType = msig.GetRetTypeHandleThrowing().GetManagedClassObject(); - gc.pSig->SetReturnType(refRetType); + OBJECTREF refRetType = msig.GetLastTypeHandleThrowing().GetManagedClassObject(); + gc.pSig->SetReturnType(refRetType); + } + else if (pMethodDesc == NULL || !pMethodDesc->IsDynamicMethod()) + { + gc.pSig->SetCallingConvention(msig.GetCallingConventionInfo()); - INT32 nArgs = msig.NumFixedArgs(); - TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY); + OBJECTREF refRetType = msig.GetRetTypeHandleThrowing().GetManagedClassObject(); + gc.pSig->SetReturnType(refRetType); - PTRARRAYREF ptrArrayarguments = (PTRARRAYREF) AllocateSzArray(arrayHandle, nArgs); - gc.pSig->SetArgumentArray(ptrArrayarguments); + INT32 nArgs = msig.NumFixedArgs(); + TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY); - for (INT32 i = 0; i < nArgs; i++) - { - msig.NextArg(); + PTRARRAYREF ptrArrayarguments = (PTRARRAYREF) AllocateSzArray(arrayHandle, nArgs); + gc.pSig->SetArgumentArray(ptrArrayarguments); - OBJECTREF refArgType = msig.GetLastTypeHandleThrowing().GetManagedClassObject(); - gc.pSig->SetArgument(i, refArgType); - } + for (INT32 i = 0; i < nArgs; i++) + { + msig.NextArg(); - _ASSERTE(gc.pSig->m_returnType != NULL); + OBJECTREF refArgType = msig.GetLastTypeHandleThrowing().GetManagedClassObject(); + gc.pSig->SetArgument(i, refArgType); } } - HELPER_METHOD_FRAME_END(); + + _ASSERTE(gc.pSig->m_declaringType != NULL); + _ASSERTE(gc.pSig->m_returnType != NULL); + GCPROTECT_END(); + END_QCALL; } -FCIMPLEND extern "C" BOOL QCALLTYPE Signature_AreEqual( PCCOR_SIGNATURE sig1, INT32 cSig1, QCall::TypeHandle handle1, diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index 5dd2f5ff5676e..585fc2471dc64 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -315,18 +315,28 @@ typedef REF SIGNATURENATIVEREF; typedef PTR_SignatureNative SIGNATURENATIVEREF; #endif +extern "C" void QCALLTYPE Signature_Init( + QCall::ObjectHandleOnStack sigNative, + PCCOR_SIGNATURE pCorSig, DWORD cCorSig, + FieldDesc* pFieldDesc, + MethodDesc* pMethodDesc, + EnregisteredTypeHandle typeHandleRaw); + +extern "C" BOOL QCALLTYPE Signature_AreEqual( + PCCOR_SIGNATURE sig1, INT32 cSig1, QCall::TypeHandle handle1, + PCCOR_SIGNATURE sig2, INT32 cSig2, QCall::TypeHandle handle2); + class SignatureNative : public Object { - friend class RuntimeMethodHandle; + friend void QCALLTYPE Signature_Init( + QCall::ObjectHandleOnStack sigNative, + PCCOR_SIGNATURE pCorSig, DWORD cCorSig, + FieldDesc* pFieldDesc, + MethodDesc* pMethodDesc, + EnregisteredTypeHandle typeHandleRaw); friend class ArgIteratorForMethodInvoke; public: - static FCDECL6(void, GetSignature, - SignatureNative* pSignatureNative, - PCCOR_SIGNATURE pCorSig, DWORD cCorSig, - FieldDesc *pFieldDesc, ReflectMethodObject *pMethodUNSAFE, - ReflectClassBaseObject *pDeclaringType); - static FCDECL3(INT32, GetParameterOffsetInternal, PCCOR_SIGNATURE sig, DWORD csig, INT32 parameterIndex); static FCDECL3(INT32, GetTypeParameterOffset, SignatureNative* pSig, INT32 offset, INT32 index); @@ -500,16 +510,12 @@ class SignatureNative : public Object OBJECTREF m_returnType; OBJECTREF m_keepalive; PCCOR_SIGNATURE m_sig; + DWORD m_cSig; INT32 m_managedCallingConvention; INT32 m_nSizeOfArgStack; - DWORD m_cSig; MethodDesc* m_pMethod; }; -extern "C" BOOL QCALLTYPE Signature_AreEqual( - PCCOR_SIGNATURE sig1, INT32 cSig1, QCall::TypeHandle handle1, - PCCOR_SIGNATURE sig2, INT32 cSig2, QCall::TypeHandle handle2); - class ReflectionPointer : public Object { public: From 2ddcd693112910318813e7fef876dca46d177a9e Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Fri, 6 Dec 2024 22:27:28 -0800 Subject: [PATCH 02/21] Remove HMF from Signature.GetTypeParameterOffset(). --- .../src/System/RuntimeHandles.cs | 17 +++- src/coreclr/vm/ecalllist.h | 2 +- src/coreclr/vm/runtimehandles.cpp | 98 ++++++++----------- src/coreclr/vm/runtimehandles.h | 2 +- 4 files changed, 57 insertions(+), 62 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index d15bea6028c67..de70f23323b5f 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -2012,7 +2012,22 @@ internal int GetParameterOffset(int parameterIndex) } [MethodImpl(MethodImplOptions.InternalCall)] - internal extern int GetTypeParameterOffset(int offset, int index); + private static extern unsafe int GetTypeParameterOffsetInternal(void* sig, int csig, int offset, int index); + + internal int GetTypeParameterOffset(int offset, int index) + { + if (offset < 0) + { + Debug.Assert(offset == -1); + return offset; + } + + int offsetMaybe = GetTypeParameterOffsetInternal(_sig, _csig, offset, index); + // If the result is negative and not -1, it is an error code. + if (offsetMaybe < 0 && offsetMaybe != -1) + Marshal.ThrowExceptionForHR(offsetMaybe, new IntPtr(-1)); + return offsetMaybe; + } [MethodImpl(MethodImplOptions.InternalCall)] internal extern SignatureCallingConvention GetCallingConventionFromFunctionPointerAtOffset(int offset); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index bdd5d8561e2f9..ae261c19fe362 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -133,7 +133,7 @@ FCFuncEnd() FCFuncStart(gSignatureNative) FCFuncElement("GetParameterOffsetInternal", SignatureNative::GetParameterOffsetInternal) - FCFuncElement("GetTypeParameterOffset", SignatureNative::GetTypeParameterOffset) + FCFuncElement("GetTypeParameterOffsetInternal", SignatureNative::GetTypeParameterOffsetInternal) FCFuncElement("GetCustomModifiersAtOffset", SignatureNative::GetCustomModifiersAtOffset) FCFuncElement("GetCallingConventionFromFunctionPointerAtOffset", SignatureNative::GetCallingConventionFromFunctionPointerAtOffset) FCFuncEnd() diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index a7060f3054100..06b6b717f52cf 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -1471,68 +1471,48 @@ FCIMPL3(INT32, SignatureNative::GetParameterOffsetInternal, PCCOR_SIGNATURE sig, } FCIMPLEND -FCIMPL3(INT32, SignatureNative::GetTypeParameterOffset, SignatureNative* pSignatureUNSAFE, INT32 offset, INT32 index) +FCIMPL4(INT32, SignatureNative::GetTypeParameterOffsetInternal, PCCOR_SIGNATURE sig, DWORD csig, INT32 offset, INT32 index) { FCALL_CONTRACT; + _ASSERTE(offset >= 0); - struct - { - SIGNATURENATIVEREF pSig; - } gc; - - if (offset < 0) - { - _ASSERTE(offset == -1); - return offset; - } - - gc.pSig = (SIGNATURENATIVEREF)pSignatureUNSAFE; - - HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc); - { - SigPointer sp(gc.pSig->GetCorSig() + offset, gc.pSig->GetCorSigSize() - offset); - - CorElementType etype; - IfFailThrow(sp.GetElemType(&etype)); - - uint32_t argCnt; - - switch (etype) - { - case ELEMENT_TYPE_FNPTR: - IfFailThrow(sp.SkipMethodHeaderSignature(&argCnt, /* skipReturnType */ false)); - _ASSERTE((uint32_t)index <= argCnt); - break; - case ELEMENT_TYPE_GENERICINST: - IfFailThrow(sp.SkipExactlyOne()); - - IfFailThrow(sp.GetData(&argCnt)); - _ASSERTE((uint32_t)index < argCnt); - break; - case ELEMENT_TYPE_ARRAY: - case ELEMENT_TYPE_SZARRAY: - case ELEMENT_TYPE_BYREF: - case ELEMENT_TYPE_PTR: - _ASSERTE(index == 0); - break; - case ELEMENT_TYPE_VAR: - case ELEMENT_TYPE_MVAR: - offset = -1; // Use offset -1 to signal method substituted method variable. We do not have full signature for those. - goto Done; - default: - _ASSERTE(false); // Unexpected element type - offset = -1; - goto Done; - } - - for (int i = 0; i < index; i++) - IfFailThrow(sp.SkipExactlyOne()); - - offset = (INT32)(sp.GetPtr() - gc.pSig->GetCorSig()); - Done: ; - } - HELPER_METHOD_FRAME_END(); - + HRESULT hr; + SigPointer sp(sig + offset, csig - offset); + + CorElementType etype; + IfFailRet(sp.GetElemType(&etype)); + + uint32_t argCnt; + switch (etype) + { + case ELEMENT_TYPE_FNPTR: + IfFailRet(sp.SkipMethodHeaderSignature(&argCnt, /* skipReturnType */ false)); + _ASSERTE((uint32_t)index <= argCnt); + break; + case ELEMENT_TYPE_GENERICINST: + IfFailRet(sp.SkipExactlyOne()); + + IfFailRet(sp.GetData(&argCnt)); + _ASSERTE((uint32_t)index < argCnt); + break; + case ELEMENT_TYPE_ARRAY: + case ELEMENT_TYPE_SZARRAY: + case ELEMENT_TYPE_BYREF: + case ELEMENT_TYPE_PTR: + _ASSERTE(index == 0); + break; + case ELEMENT_TYPE_VAR: + case ELEMENT_TYPE_MVAR: + return -1; // Use offset -1 to signal method substituted method variable. We do not have full signature for those. + default: + _ASSERTE(false); // Unexpected element type + return -1; + } + + for (int i = 0; i < index; i++) + IfFailRet(sp.SkipExactlyOne()); + + offset = (INT32)(sp.GetPtr() - sig); return offset; } FCIMPLEND diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index 585fc2471dc64..e1414e89b19c6 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -339,7 +339,7 @@ class SignatureNative : public Object public: static FCDECL3(INT32, GetParameterOffsetInternal, PCCOR_SIGNATURE sig, DWORD csig, INT32 parameterIndex); - static FCDECL3(INT32, GetTypeParameterOffset, SignatureNative* pSig, INT32 offset, INT32 index); + static FCDECL4(INT32, GetTypeParameterOffsetInternal, PCCOR_SIGNATURE sig, DWORD csig, INT32 offset, INT32 index); static FCDECL2(FC_INT8_RET, GetCallingConventionFromFunctionPointerAtOffset, SignatureNative* pSig, INT32 offset); From 5410c4d70b0a8f52891c0d79c4ae5326a02cf3c2 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Fri, 6 Dec 2024 22:48:11 -0800 Subject: [PATCH 03/21] Remove HMF from Signature.GetCallingConventionFromFunctionPointerAtOffset(). --- .../src/System/RuntimeHandles.cs | 17 +++++++++- src/coreclr/vm/ecalllist.h | 2 +- src/coreclr/vm/runtimehandles.cpp | 34 +++++-------------- src/coreclr/vm/runtimehandles.h | 2 +- 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index de70f23323b5f..eef23a360b0ad 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -2030,7 +2030,22 @@ internal int GetTypeParameterOffset(int offset, int index) } [MethodImpl(MethodImplOptions.InternalCall)] - internal extern SignatureCallingConvention GetCallingConventionFromFunctionPointerAtOffset(int offset); + private static extern unsafe int GetCallingConventionFromFunctionPointerAtOffsetInternal(void* sig, int csig, int offset); + + internal SignatureCallingConvention GetCallingConventionFromFunctionPointerAtOffset(int offset) + { + if (offset < 0) + { + Debug.Assert(offset == -1); + return SignatureCallingConvention.Default; + } + + int callConvMaybe = GetCallingConventionFromFunctionPointerAtOffsetInternal(_sig, _csig, offset); + // If the result is negative, it is an error code. + if (callConvMaybe < 0) + Marshal.ThrowExceptionForHR(callConvMaybe, new IntPtr(-1)); + return (SignatureCallingConvention)callConvMaybe; + } [MethodImpl(MethodImplOptions.InternalCall)] internal extern Type[] GetCustomModifiersAtOffset(int offset, bool required); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index ae261c19fe362..7933db66b03cd 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -135,7 +135,7 @@ FCFuncStart(gSignatureNative) FCFuncElement("GetParameterOffsetInternal", SignatureNative::GetParameterOffsetInternal) FCFuncElement("GetTypeParameterOffsetInternal", SignatureNative::GetTypeParameterOffsetInternal) FCFuncElement("GetCustomModifiersAtOffset", SignatureNative::GetCustomModifiersAtOffset) - FCFuncElement("GetCallingConventionFromFunctionPointerAtOffset", SignatureNative::GetCallingConventionFromFunctionPointerAtOffset) + FCFuncElement("GetCallingConventionFromFunctionPointerAtOffsetInternal", SignatureNative::GetCallingConventionFromFunctionPointerAtOffsetInternal) FCFuncEnd() FCFuncStart(gRuntimeMethodHandle) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 06b6b717f52cf..f34765d92270c 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -1517,38 +1517,22 @@ FCIMPL4(INT32, SignatureNative::GetTypeParameterOffsetInternal, PCCOR_SIGNATURE } FCIMPLEND -FCIMPL2(FC_INT8_RET, SignatureNative::GetCallingConventionFromFunctionPointerAtOffset, SignatureNative* pSignatureUNSAFE, INT32 offset) +FCIMPL3(INT32, SignatureNative::GetCallingConventionFromFunctionPointerAtOffsetInternal, PCCOR_SIGNATURE sig, DWORD csig, INT32 offset) { FCALL_CONTRACT; + _ASSERTE(offset >= 0); - struct - { - SIGNATURENATIVEREF pSig; - } gc; - - if (offset < 0) - { - _ASSERTE(offset == -1); - return 0; - } - - gc.pSig = (SIGNATURENATIVEREF)pSignatureUNSAFE; - + HRESULT hr; uint32_t callConv = 0; + SigPointer sp(sig + offset, csig - offset); - HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc); - { - SigPointer sp(gc.pSig->GetCorSig() + offset, gc.pSig->GetCorSigSize() - offset); - - CorElementType etype; - IfFailThrow(sp.GetElemType(&etype)); - _ASSERTE(etype == ELEMENT_TYPE_FNPTR); + CorElementType etype; + IfFailRet(sp.GetElemType(&etype)); + _ASSERTE(etype == ELEMENT_TYPE_FNPTR); - IfFailThrow(sp.GetCallingConv(&callConv)); - } - HELPER_METHOD_FRAME_END(); + IfFailRet(sp.GetCallingConv(&callConv)); - return (FC_INT8_RET)(callConv); + return (INT32)callConv; } FCIMPLEND diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index e1414e89b19c6..a1300a06e2086 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -341,7 +341,7 @@ class SignatureNative : public Object static FCDECL4(INT32, GetTypeParameterOffsetInternal, PCCOR_SIGNATURE sig, DWORD csig, INT32 offset, INT32 index); - static FCDECL2(FC_INT8_RET, GetCallingConventionFromFunctionPointerAtOffset, SignatureNative* pSig, INT32 offset); + static FCDECL3(INT32, GetCallingConventionFromFunctionPointerAtOffsetInternal, PCCOR_SIGNATURE sig, DWORD csig, INT32 offset); static FCDECL3(Object *, GetCustomModifiersAtOffset, SignatureNative* pSig, INT32 offset, FC_BOOL_ARG fRequired); From ec18691ace4d346e63a01918b46dd9de459e8e5f Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Mon, 9 Dec 2024 10:03:50 -0800 Subject: [PATCH 04/21] Convert Signature.GetCustomModifiersAtOffset() to QCall. --- .../src/ILLink/ILLink.Descriptors.Shared.xml | 3 + .../src/System/RuntimeHandles.cs | 26 ++- src/coreclr/vm/ecalllist.h | 1 - src/coreclr/vm/qcallentrypoints.cpp | 1 + src/coreclr/vm/runtimehandles.cpp | 164 +++++++++--------- src/coreclr/vm/runtimehandles.h | 12 +- 6 files changed, 115 insertions(+), 92 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml b/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml index 0c7a6d7e6259f..d338a79c305ad 100644 --- a/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml +++ b/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml @@ -9,6 +9,9 @@ + + + diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index eef23a360b0ad..f728cbd856997 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -1996,9 +1996,6 @@ internal static bool AreEqual(Signature sig1, Signature sig2) sig2._sig, sig2._csig, new QCallTypeHandle(ref sig2._declaringType)) != Interop.BOOL.FALSE; } - internal Type[] GetCustomModifiers(int parameterIndex, bool required) => - GetCustomModifiersAtOffset(GetParameterOffset(parameterIndex), required); - [MethodImpl(MethodImplOptions.InternalCall)] private static extern unsafe int GetParameterOffsetInternal(void* sig, int csig, int parameterIndex); @@ -2047,8 +2044,27 @@ internal SignatureCallingConvention GetCallingConventionFromFunctionPointerAtOff return (SignatureCallingConvention)callConvMaybe; } - [MethodImpl(MethodImplOptions.InternalCall)] - internal extern Type[] GetCustomModifiersAtOffset(int offset, bool required); + internal Type[] GetCustomModifiers(int parameterIndex, bool required) => + GetCustomModifiersAtOffset(GetParameterOffset(parameterIndex), required); + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Signature_GetCustomModifiersAtOffset")] + private static partial void GetCustomModifiersAtOffset( + ObjectHandleOnStack sigObj, + int offset, + Interop.BOOL required, + ObjectHandleOnStack result); + + internal Type[] GetCustomModifiersAtOffset(int offset, bool required) + { + Signature _this = this; + Type[]? result = null; + GetCustomModifiersAtOffset( + ObjectHandleOnStack.Create(ref _this), + offset, + required ? Interop.BOOL.TRUE : Interop.BOOL.FALSE, + ObjectHandleOnStack.Create(ref result)); + return result!; + } #endregion } diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 7933db66b03cd..366e54b58b259 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -134,7 +134,6 @@ FCFuncEnd() FCFuncStart(gSignatureNative) FCFuncElement("GetParameterOffsetInternal", SignatureNative::GetParameterOffsetInternal) FCFuncElement("GetTypeParameterOffsetInternal", SignatureNative::GetTypeParameterOffsetInternal) - FCFuncElement("GetCustomModifiersAtOffset", SignatureNative::GetCustomModifiersAtOffset) FCFuncElement("GetCallingConventionFromFunctionPointerAtOffsetInternal", SignatureNative::GetCallingConventionFromFunctionPointerAtOffsetInternal) FCFuncEnd() diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 6347172021a89..2c0928818ab43 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -190,6 +190,7 @@ static const Entry s_QCall[] = DllImportEntry(AssemblyHandle_GetManifestModuleSlow) DllImportEntry(Signature_Init) DllImportEntry(Signature_AreEqual) + DllImportEntry(Signature_GetCustomModifiersAtOffset) DllImportEntry(TypeBuilder_DefineGenericParam) DllImportEntry(TypeBuilder_DefineType) DllImportEntry(TypeBuilder_SetParentType) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index f34765d92270c..ddfb506e67f37 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -1536,121 +1536,121 @@ FCIMPL3(INT32, SignatureNative::GetCallingConventionFromFunctionPointerAtOffsetI } FCIMPLEND -FCIMPL3(Object *, SignatureNative::GetCustomModifiersAtOffset, - SignatureNative* pSignatureUNSAFE, +extern "C" void QCALLTYPE Signature_GetCustomModifiersAtOffset( + QCall::ObjectHandleOnStack sigObj, INT32 offset, - FC_BOOL_ARG fRequired) + BOOL fRequired, + QCall::ObjectHandleOnStack result) { - FCALL_CONTRACT; + QCALL_CONTRACT; + + BEGIN_QCALL; + + GCX_COOP(); struct { SIGNATURENATIVEREF pSig; PTRARRAYREF retVal; } gc; - - gc.pSig = (SIGNATURENATIVEREF)pSignatureUNSAFE; + gc.pSig = (SIGNATURENATIVEREF)sigObj.Get(); gc.retVal = NULL; + GCPROTECT_BEGIN(gc); + SigTypeContext typeContext; + gc.pSig->GetTypeContext(&typeContext); - HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc); - { - SigTypeContext typeContext; - gc.pSig->GetTypeContext(&typeContext); + SigPointer argument(gc.pSig->GetCorSig() + offset, gc.pSig->GetCorSigSize() - offset); - SigPointer argument(gc.pSig->GetCorSig() + offset, gc.pSig->GetCorSigSize() - offset); + SigPointer sp = argument; + Module* pModule = gc.pSig->GetModule(); + INT32 cMods = 0; + CorElementType cmodType; - SigPointer sp = argument; - Module* pModule = gc.pSig->GetModule(); - INT32 cMods = 0; - CorElementType cmodType; + CorElementType cmodTypeExpected = fRequired ? ELEMENT_TYPE_CMOD_REQD : ELEMENT_TYPE_CMOD_OPT; - CorElementType cmodTypeExpected = FC_ACCESS_BOOL(fRequired) ? ELEMENT_TYPE_CMOD_REQD : ELEMENT_TYPE_CMOD_OPT; + // Discover the number of required and optional custom modifiers. + while (TRUE) + { + BYTE data; + IfFailThrow(sp.GetByte(&data)); + cmodType = (CorElementType)data; - // Discover the number of required and optional custom modifiers. - while(TRUE) + if (cmodType == ELEMENT_TYPE_CMOD_REQD || cmodType == ELEMENT_TYPE_CMOD_OPT) { - BYTE data; - IfFailThrow(sp.GetByte(&data)); - cmodType = (CorElementType)data; - - if (cmodType == ELEMENT_TYPE_CMOD_REQD || cmodType == ELEMENT_TYPE_CMOD_OPT) + if (cmodType == cmodTypeExpected) { - if (cmodType == cmodTypeExpected) - { - cMods ++; - } - - IfFailThrow(sp.GetToken(NULL)); + cMods++; } - else if (cmodType == ELEMENT_TYPE_CMOD_INTERNAL) - { - BYTE required; - IfFailThrow(sp.GetByte(&required)); - if (fRequired == (required != 0)) - { - cMods ++; - } - IfFailThrow(sp.GetPointer(NULL)); - } - else if (cmodType != ELEMENT_TYPE_SENTINEL) + IfFailThrow(sp.GetToken(NULL)); + } + else if (cmodType == ELEMENT_TYPE_CMOD_INTERNAL) + { + BYTE required; + IfFailThrow(sp.GetByte(&required)); + if (fRequired == (required != 0)) { - break; + cMods++; } + + IfFailThrow(sp.GetPointer(NULL)); } + else if (cmodType != ELEMENT_TYPE_SENTINEL) + { + break; + } + } - // Reset sp and populate the arrays for the required and optional custom - // modifiers now that we know how long they should be. - sp = argument; + // Reset sp and populate the arrays for the required and optional custom + // modifiers now that we know how long they should be. + sp = argument; - MethodTable *pMT = CoreLibBinder::GetClass(CLASS__TYPE); - TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pMT), ELEMENT_TYPE_SZARRAY); + MethodTable *pMT = CoreLibBinder::GetClass(CLASS__TYPE); + TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pMT), ELEMENT_TYPE_SZARRAY); - gc.retVal = (PTRARRAYREF) AllocateSzArray(arrayHandle, cMods); + gc.retVal = (PTRARRAYREF) AllocateSzArray(arrayHandle, cMods); - while(cMods != 0) - { - BYTE data; - IfFailThrow(sp.GetByte(&data)); - cmodType = (CorElementType)data; + while (cMods != 0) + { + BYTE data; + IfFailThrow(sp.GetByte(&data)); + cmodType = (CorElementType)data; - if (cmodType == ELEMENT_TYPE_CMOD_INTERNAL) - { - BYTE required; - IfFailThrow(sp.GetByte(&required)); + if (cmodType == ELEMENT_TYPE_CMOD_INTERNAL) + { + BYTE required; + IfFailThrow(sp.GetByte(&required)); - TypeHandle th; - IfFailThrow(sp.GetPointer((void**)&th)); + TypeHandle th; + IfFailThrow(sp.GetPointer((void**)&th)); - if (fRequired == (required != 0)) - { - OBJECTREF refType = th.GetManagedClassObject(); - gc.retVal->SetAt(--cMods, refType); - } - } - else + if (fRequired == (required != 0)) { - mdToken token; - IfFailThrow(sp.GetToken(&token)); + OBJECTREF refType = th.GetManagedClassObject(); + gc.retVal->SetAt(--cMods, refType); + } + } + else + { + mdToken token; + IfFailThrow(sp.GetToken(&token)); - if (cmodType == cmodTypeExpected) - { - TypeHandle th = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, token, - &typeContext, - ClassLoader::ThrowIfNotFound, - ClassLoader::FailIfUninstDefOrRef); + if (cmodType == cmodTypeExpected) + { + TypeHandle th = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule, token, + &typeContext, + ClassLoader::ThrowIfNotFound, + ClassLoader::FailIfUninstDefOrRef); - OBJECTREF refType = th.GetManagedClassObject(); - gc.retVal->SetAt(--cMods, refType); - } + OBJECTREF refType = th.GetManagedClassObject(); + gc.retVal->SetAt(--cMods, refType); } } } - HELPER_METHOD_FRAME_END(); - - return OBJECTREFToObject(gc.retVal); + result.Set(gc.retVal); + GCPROTECT_END(); + END_QCALL; } -FCIMPLEND FCIMPL1(INT32, RuntimeMethodHandle::GetMethodDef, ReflectMethodObject *pMethodUNSAFE) { CONTRACTL { @@ -1683,7 +1683,7 @@ FCIMPL1(INT32, RuntimeMethodHandle::GetMethodDef, ReflectMethodObject *pMethodUN FCIMPLEND extern "C" void QCALLTYPE Signature_Init( - QCall::ObjectHandleOnStack sigNative, + QCall::ObjectHandleOnStack sigObj, PCCOR_SIGNATURE pCorSig, DWORD cCorSig, FieldDesc* pFieldDesc, MethodDesc* pMethodDesc, @@ -1699,7 +1699,7 @@ extern "C" void QCALLTYPE Signature_Init( { SIGNATURENATIVEREF pSig; } gc; - gc.pSig = (SIGNATURENATIVEREF)sigNative.Get(); + gc.pSig = (SIGNATURENATIVEREF)sigObj.Get(); GCPROTECT_BEGIN(gc); TypeHandle declType = TypeHandle::FromPtr(typeHandleRaw); diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index a1300a06e2086..07cd2bf14d2ac 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -316,7 +316,7 @@ typedef PTR_SignatureNative SIGNATURENATIVEREF; #endif extern "C" void QCALLTYPE Signature_Init( - QCall::ObjectHandleOnStack sigNative, + QCall::ObjectHandleOnStack sigObj, PCCOR_SIGNATURE pCorSig, DWORD cCorSig, FieldDesc* pFieldDesc, MethodDesc* pMethodDesc, @@ -326,10 +326,16 @@ extern "C" BOOL QCALLTYPE Signature_AreEqual( PCCOR_SIGNATURE sig1, INT32 cSig1, QCall::TypeHandle handle1, PCCOR_SIGNATURE sig2, INT32 cSig2, QCall::TypeHandle handle2); +extern "C" void QCALLTYPE Signature_GetCustomModifiersAtOffset( + QCall::ObjectHandleOnStack sigObj, + INT32 offset, + BOOL fRequired, + QCall::ObjectHandleOnStack result); + class SignatureNative : public Object { friend void QCALLTYPE Signature_Init( - QCall::ObjectHandleOnStack sigNative, + QCall::ObjectHandleOnStack sigObj, PCCOR_SIGNATURE pCorSig, DWORD cCorSig, FieldDesc* pFieldDesc, MethodDesc* pMethodDesc, @@ -343,8 +349,6 @@ class SignatureNative : public Object static FCDECL3(INT32, GetCallingConventionFromFunctionPointerAtOffsetInternal, PCCOR_SIGNATURE sig, DWORD csig, INT32 offset); - static FCDECL3(Object *, GetCustomModifiersAtOffset, SignatureNative* pSig, INT32 offset, FC_BOOL_ARG fRequired); - BOOL HasThis() { LIMITED_METHOD_CONTRACT; return (m_managedCallingConvention & CALLCONV_HasThis); } INT32 NumFixedArgs() { WRAPPER_NO_CONTRACT; return m_PtrArrayarguments->GetNumComponents(); } TypeHandle GetReturnTypeHandle() From eb104fd362146ef835752063639a634871f4502f Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Mon, 9 Dec 2024 14:11:35 -0800 Subject: [PATCH 05/21] Convert RuntimeTypeHandle.GetDeclaringMethodForGenericParameter() to QCall. Rename RuntimeTypeHandle.GetDeclaringMethod() to RuntimeTypeHandle.GetDeclaringMethodForGenericParameter(). --- .../src/System/RuntimeHandles.cs | 13 +++++- .../src/System/RuntimeType.CoreCLR.cs | 3 +- src/coreclr/vm/assemblynative.cpp | 2 +- src/coreclr/vm/comdelegate.cpp | 2 +- src/coreclr/vm/comutilnative.cpp | 2 +- src/coreclr/vm/ecalllist.h | 1 - src/coreclr/vm/interoplibinterface_objc.cpp | 2 +- src/coreclr/vm/interpreter.cpp | 2 +- src/coreclr/vm/jithelpers.cpp | 4 +- src/coreclr/vm/method.cpp | 2 +- src/coreclr/vm/method.hpp | 4 +- src/coreclr/vm/qcallentrypoints.cpp | 1 + src/coreclr/vm/runtimehandles.cpp | 44 +++++++------------ src/coreclr/vm/runtimehandles.h | 3 +- 14 files changed, 41 insertions(+), 44 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index f728cbd856997..bfcb3fa182aff 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -695,8 +695,17 @@ internal static unsafe MdUtf8String GetUtf8Name(RuntimeType type) return result; } - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern IRuntimeMethodInfo GetDeclaringMethod(RuntimeType type); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetDeclaringMethodForGenericParameter")] + private static partial void GetDeclaringMethodForGenericParameter(QCallTypeHandle typeHandle, ObjectHandleOnStack result); + + internal static IRuntimeMethodInfo? GetDeclaringMethodForGenericParameter(RuntimeType type) + { + Debug.Assert(IsGenericVariable(type)); + + IRuntimeMethodInfo? method = null; + GetDeclaringMethodForGenericParameter(new QCallTypeHandle(ref type), ObjectHandleOnStack.Create(ref method)); + return method; + } [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetInstantiation")] internal static partial void GetInstantiation(QCallTypeHandle type, ObjectHandleOnStack types, Interop.BOOL fAsRuntimeTypeArray); diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs index d1591d88036b2..9d51fd8e96731 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs @@ -3276,8 +3276,7 @@ public override MethodBase? DeclaringMethod if (!IsGenericParameter) throw new InvalidOperationException(SR.Arg_NotGenericParameter); - IRuntimeMethodInfo declaringMethod = RuntimeTypeHandle.GetDeclaringMethod(this); - + IRuntimeMethodInfo? declaringMethod = RuntimeTypeHandle.GetDeclaringMethodForGenericParameter(this); if (declaringMethod == null) return null; diff --git a/src/coreclr/vm/assemblynative.cpp b/src/coreclr/vm/assemblynative.cpp index 3ca0783d65349..c2d9d8706f25e 100644 --- a/src/coreclr/vm/assemblynative.cpp +++ b/src/coreclr/vm/assemblynative.cpp @@ -1089,7 +1089,7 @@ extern "C" void QCALLTYPE AssemblyNative_GetEntryPoint(QCall::AssemblyHandle pAs if (pMeth != NULL) { GCX_COOP(); - retMethod.Set(pMeth->GetStubMethodInfo()); + retMethod.Set(pMeth->AllocateStubMethodInfo()); } END_QCALL; diff --git a/src/coreclr/vm/comdelegate.cpp b/src/coreclr/vm/comdelegate.cpp index f13e28fc3cd14..18fb1f1e10328 100644 --- a/src/coreclr/vm/comdelegate.cpp +++ b/src/coreclr/vm/comdelegate.cpp @@ -2127,7 +2127,7 @@ extern "C" void QCALLTYPE Delegate_FindMethodHandle(QCall::ObjectHandleOnStack d MethodDesc* pMD = COMDelegate::GetMethodDesc(d.Get()); pMD = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMD, TypeHandle(pMD->GetMethodTable()), pMD->GetMethodInstantiation()); - retMethodInfo.Set(pMD->GetStubMethodInfo()); + retMethodInfo.Set(pMD->AllocateStubMethodInfo()); END_QCALL; } diff --git a/src/coreclr/vm/comutilnative.cpp b/src/coreclr/vm/comutilnative.cpp index 123bf906aef7a..37839a496aa91 100644 --- a/src/coreclr/vm/comutilnative.cpp +++ b/src/coreclr/vm/comutilnative.cpp @@ -445,7 +445,7 @@ extern "C" void QCALLTYPE ExceptionNative_GetMethodFromStackTrace(QCall::ObjectH // The managed stack trace classes always return typical method definition, // so we don't need to bother providing exact instantiation. MethodDesc* pMDTypical = pMD->LoadTypicalMethodDefinition(); - retMethodInfo.Set(pMDTypical->GetStubMethodInfo()); + retMethodInfo.Set(pMDTypical->AllocateStubMethodInfo()); _ASSERTE(pMDTypical->IsRuntimeMethodHandle()); END_QCALL; diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 366e54b58b259..1dd6ad46257d6 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -82,7 +82,6 @@ FCFuncStart(gExceptionFuncs) FCFuncEnd() FCFuncStart(gCOMTypeHandleFuncs) - FCFuncElement("GetDeclaringMethod", RuntimeTypeHandle::GetDeclaringMethod) FCFuncElement("GetFirstIntroducedMethod", RuntimeTypeHandle::GetFirstIntroducedMethod) FCFuncElement("GetNextIntroducedMethod", RuntimeTypeHandle::GetNextIntroducedMethod) FCFuncElement("GetAssemblyIfExists", RuntimeTypeHandle::GetAssemblyIfExists) diff --git a/src/coreclr/vm/interoplibinterface_objc.cpp b/src/coreclr/vm/interoplibinterface_objc.cpp index a59d56a423c55..76daddfa51d41 100644 --- a/src/coreclr/vm/interoplibinterface_objc.cpp +++ b/src/coreclr/vm/interoplibinterface_objc.cpp @@ -336,7 +336,7 @@ void* ObjCMarshalNative::GetPropagatingExceptionCallback( if (CallAvailableUnhandledExceptionPropagation()) { gc.throwableRef = ObjectFromHandle(throwable); - gc.methodRef = method->GetStubMethodInfo(); + gc.methodRef = method->AllocateStubMethodInfo(); callback = CallInvokeUnhandledExceptionPropagation( &gc.throwableRef, diff --git a/src/coreclr/vm/interpreter.cpp b/src/coreclr/vm/interpreter.cpp index 80a058b3494d9..9ab7906b22bec 100644 --- a/src/coreclr/vm/interpreter.cpp +++ b/src/coreclr/vm/interpreter.cpp @@ -6536,7 +6536,7 @@ void Interpreter::LdToken() if (tok.hMethod != NULL) { MethodDesc* pMethod = (MethodDesc*)tok.hMethod; - Object* objPtr = OBJECTREFToObject((OBJECTREF)pMethod->GetStubMethodInfo()); + Object* objPtr = OBJECTREFToObject((OBJECTREF)pMethod->AllocateStubMethodInfo()); OpStackSet(m_curStackHt, objPtr); } else if (tok.hField != NULL) diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index e116ff3b26994..5289f1e46ebc0 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -1625,7 +1625,7 @@ HCIMPL1(Object*, JIT_GetRuntimeMethodStub, CORINFO_METHOD_HANDLE method) HELPER_METHOD_FRAME_BEGIN_RET_0(); // Set up a frame MethodDesc *pMethod = (MethodDesc *)method; - stubRuntimeMethod = (OBJECTREF)pMethod->GetStubMethodInfo(); + stubRuntimeMethod = (OBJECTREF)pMethod->AllocateStubMethodInfo(); HELPER_METHOD_FRAME_END(); @@ -4049,7 +4049,7 @@ bool IndirectionAllowedForJitHelper(CorInfoHelpFunc ftnNum) { return false; } - + return true; } diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index 98af92ef04879..d042dc8a8f96b 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -3724,7 +3724,7 @@ PTR_LoaderAllocator MethodDesc::GetLoaderAllocator() } #if !defined(DACCESS_COMPILE) -REFLECTMETHODREF MethodDesc::GetStubMethodInfo() +REFLECTMETHODREF MethodDesc::AllocateStubMethodInfo() { CONTRACTL { diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index 44d03a2ffd3c1..5d541b84fbb49 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -1861,8 +1861,8 @@ class MethodDesc public: MethodDesc *GetInterfaceMD(); -// StubMethodInfo for use in creating RuntimeMethodHandles - REFLECTMETHODREF GetStubMethodInfo(); + // StubMethodInfo for use in creating RuntimeMethodHandles + REFLECTMETHODREF AllocateStubMethodInfo(); PrecodeType GetPrecodeType(); diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 2c0928818ab43..e0d715efb28c8 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -128,6 +128,7 @@ static const Entry s_QCall[] = DllImportEntry(RuntimeTypeHandle_GetFields) DllImportEntry(RuntimeTypeHandle_VerifyInterfaceIsImplemented) DllImportEntry(RuntimeTypeHandle_GetInterfaceMethodImplementation) + DllImportEntry(RuntimeTypeHandle_GetDeclaringMethodForGenericParameter) DllImportEntry(RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable) DllImportEntry(RuntimeTypeHandle_GetDeclaringTypeHandle) DllImportEntry(RuntimeTypeHandle_IsVisible) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index ddfb506e67f37..183e1545c97f7 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -895,37 +895,27 @@ extern "C" MethodDesc* QCALLTYPE RuntimeTypeHandle_GetInterfaceMethodImplementat return pResult; } -FCIMPL1(ReflectMethodObject*, RuntimeTypeHandle::GetDeclaringMethod, ReflectClassBaseObject *pTypeUNSAFE) { - CONTRACTL { - FCALL_CHECK; - } - CONTRACTL_END; - - REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE); - - if (refType == NULL) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); +extern "C" void QCALLTYPE RuntimeTypeHandle_GetDeclaringMethodForGenericParameter(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack result) +{ + QCALL_CONTRACT; - TypeHandle typeHandle = refType->GetType();; + BEGIN_QCALL; - if (!typeHandle.IsTypeDesc()) - return NULL; + TypeHandle typeHandle = pTypeHandle.AsTypeHandle(); + _ASSERTE(typeHandle.IsGenericVariable()); TypeVarTypeDesc* pGenericVariable = typeHandle.AsGenericVariable(); mdToken defToken = pGenericVariable->GetTypeOrMethodDef(); - if (TypeFromToken(defToken) != mdtMethodDef) - return NULL; - - REFLECTMETHODREF pRet = NULL; - HELPER_METHOD_FRAME_BEGIN_RET_0(); - MethodDesc * pMD = pGenericVariable->LoadOwnerMethod(); - pMD->CheckRestore(); - pRet = pMD->GetStubMethodInfo(); - HELPER_METHOD_FRAME_END(); + if (TypeFromToken(defToken) == mdtMethodDef) + { + GCX_COOP(); + MethodDesc* pMD = pGenericVariable->LoadOwnerMethod(); + pMD->CheckRestore(); + result.Set(pMD->AllocateStubMethodInfo()); + } - return (ReflectMethodObject*)OBJECTREFToObject(pRet); + END_QCALL; } -FCIMPLEND extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable(EnregisteredTypeHandle pTypeHandle) { @@ -1926,7 +1916,7 @@ extern "C" void QCALLTYPE RuntimeMethodHandle_GetTypicalMethodDefinition(MethodD if (pMethodTypical != pMethod) { GCX_COOP(); - refMethod.Set(pMethodTypical->GetStubMethodInfo()); + refMethod.Set(pMethodTypical->AllocateStubMethodInfo()); } END_QCALL; @@ -1952,7 +1942,7 @@ extern "C" void QCALLTYPE RuntimeMethodHandle_StripMethodInstantiation(MethodDes if (pMethodStripped != pMethod) { GCX_COOP(); - refMethod.Set(pMethodStripped->GetStubMethodInfo()); + refMethod.Set(pMethodStripped->AllocateStubMethodInfo()); } END_QCALL; @@ -2552,7 +2542,7 @@ extern "C" void QCALLTYPE ModuleHandle_GetDynamicMethod(QCall::ModuleHandle pMod // create a handle to hold the resolver objectref OBJECTHANDLE resolverHandle = AppDomain::GetCurrentDomain()->CreateLongWeakHandle(resolver.Get()); pNewMD->GetLCGMethodResolver()->SetManagedResolver(resolverHandle); - result.Set(pNewMD->GetStubMethodInfo()); + result.Set(pNewMD->AllocateStubMethodInfo()); } LoaderAllocator *pLoaderAllocator = pModule->GetLoaderAllocator(); diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index 07cd2bf14d2ac..2be91b6a38f2a 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -118,8 +118,6 @@ class RuntimeTypeHandle static FCDECL1(LPCUTF8, GetUtf8Name, MethodTable* pMT); static FCDECL1(INT32, GetArrayRank, ReflectClassBaseObject* pType); - static FCDECL1(ReflectMethodObject*, GetDeclaringMethod, ReflectClassBaseObject *pType); - static FCDECL1(FC_BOOL_RET, IsUnmanagedFunctionPointer, ReflectClassBaseObject *pTypeUNSAFE); static FCDECL2(FC_BOOL_RET, CanCastTo, ReflectClassBaseObject *pType, ReflectClassBaseObject *pTarget); @@ -191,6 +189,7 @@ extern "C" MethodDesc* QCALLTYPE RuntimeTypeHandle_GetMethodAt(MethodTable* pMT, extern "C" BOOL QCALLTYPE RuntimeTypeHandle_GetFields(MethodTable* pMT, intptr_t* result, INT32* pCount); extern "C" void QCALLTYPE RuntimeTypeHandle_VerifyInterfaceIsImplemented(QCall::TypeHandle pTypeHandle, QCall::TypeHandle pIFaceHandle); extern "C" MethodDesc* QCALLTYPE RuntimeTypeHandle_GetInterfaceMethodImplementation(QCall::TypeHandle pTypeHandle, QCall::TypeHandle pOwner, MethodDesc * pMD); +extern "C" void QCALLTYPE RuntimeTypeHandle_GetDeclaringMethodForGenericParameter(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack result); extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable(EnregisteredTypeHandle pTypeHandle); extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandle(EnregisteredTypeHandle pTypeHandle); extern "C" void QCALLTYPE RuntimeTypeHandle_RegisterCollectibleTypeDependency(QCall::TypeHandle pTypeHandle, QCall::AssemblyHandle pAssembly); From a392aeffaa3d2213fcf303729a3dd6e0ac5979d0 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Mon, 9 Dec 2024 15:34:10 -0800 Subject: [PATCH 06/21] Convert RuntimeTypeHandle.CanCastTo to slow/fast paths using FCall/QCall. --- .../src/System/RuntimeHandles.cs | 19 ++++- src/coreclr/vm/ecalllist.h | 2 +- src/coreclr/vm/qcallentrypoints.cpp | 1 + src/coreclr/vm/runtimehandles.cpp | 72 +++++++++---------- src/coreclr/vm/runtimehandles.h | 3 +- src/coreclr/vm/typehandle.h | 3 +- .../Runtime/CompilerServices/CastCache.cs | 1 + .../src/System/RuntimeType.cs | 1 - 8 files changed, 61 insertions(+), 41 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index bfcb3fa182aff..a057d3769af42 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -660,7 +660,24 @@ internal static unsafe MdUtf8String GetUtf8Name(RuntimeType type) } [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern bool CanCastTo(RuntimeType type, RuntimeType target); + private static extern CastResult CanCastToInternal(RuntimeType type, RuntimeType target); + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_CanCastToSlow")] + private static partial Interop.BOOL CanCastToSlow(QCallTypeHandle type1, QCallTypeHandle type2); + + internal static bool CanCastTo(RuntimeType type, RuntimeType target) + { + return CanCastToInternal(type, target) switch + { + CastResult.CanCast => true, + CastResult.CannotCast => false, + _ => CanCastToWorker(type, target) + }; + + [MethodImpl(MethodImplOptions.NoInlining)] + static bool CanCastToWorker(RuntimeType type1, RuntimeType type2) + => CanCastToSlow(new QCallTypeHandle(ref type1), new QCallTypeHandle(ref type2)) != Interop.BOOL.FALSE; + } [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable")] private static partial IntPtr GetDeclaringTypeHandleForGenericVariable(IntPtr typeHandle); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 1dd6ad46257d6..00dc4688e6c1a 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -92,7 +92,7 @@ FCFuncStart(gCOMTypeHandleFuncs) FCFuncElement("GetUtf8NameInternal", RuntimeTypeHandle::GetUtf8Name) FCFuncElement("GetAttributes", RuntimeTypeHandle::GetAttributes) FCFuncElement("GetNumVirtuals", RuntimeTypeHandle::GetNumVirtuals) - FCFuncElement("CanCastTo", RuntimeTypeHandle::CanCastTo) + FCFuncElement("CanCastToInternal", RuntimeTypeHandle::CanCastToInternal) FCFuncElement("GetGenericVariableIndex", RuntimeTypeHandle::GetGenericVariableIndex) FCFuncElement("IsGenericVariable", RuntimeTypeHandle::IsGenericVariable) FCFuncElement("ContainsGenericVariables", RuntimeTypeHandle::ContainsGenericVariables) diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index e0d715efb28c8..f27bb56828cdd 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -134,6 +134,7 @@ static const Entry s_QCall[] = DllImportEntry(RuntimeTypeHandle_IsVisible) DllImportEntry(RuntimeTypeHandle_ConstructName) DllImportEntry(RuntimeTypeHandle_GetInterfaces) + DllImportEntry(RuntimeTypeHandle_CanCastToSlow) DllImportEntry(RuntimeTypeHandle_GetInstantiation) DllImportEntry(RuntimeTypeHandle_Instantiate) DllImportEntry(RuntimeTypeHandle_GetGenericTypeDefinition) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 183e1545c97f7..1abdc173494c3 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -996,59 +996,59 @@ extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHa return (EnregisteredTypeHandle)retTypeHandle.AsTAddr(); } -FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::CanCastTo, ReflectClassBaseObject *pTypeUNSAFE, ReflectClassBaseObject *pTargetUNSAFE) { - CONTRACTL { - FCALL_CHECK; - } - CONTRACTL_END; - +FCIMPL2(TypeHandle::CastResult, RuntimeTypeHandle::CanCastToInternal, ReflectClassBaseObject *pTypeUNSAFE, ReflectClassBaseObject *pTargetUNSAFE) +{ + FCALL_CONTRACT; REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE); REFLECTCLASSBASEREF refTarget = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTargetUNSAFE); - - if ((refType == NULL) || (refTarget == NULL)) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); - TypeHandle fromHandle = refType->GetType(); TypeHandle toHandle = refTarget->GetType(); + return fromHandle.CanCastToCached(toHandle); +} +FCIMPLEND + +extern "C" BOOL QCALLTYPE RuntimeTypeHandle_CanCastToSlow(QCall::TypeHandle type, QCall::TypeHandle target) +{ + QCALL_CONTRACT; + + BOOL retVal = FALSE; + + BEGIN_QCALL; + + TypeHandle fromHandle = type.AsTypeHandle(); + TypeHandle toHandle = target.AsTypeHandle(); - TypeHandle::CastResult r = fromHandle.CanCastToCached(toHandle); - if (r != TypeHandle::MaybeCast) + // We allow T to be cast to Nullable + if (!fromHandle.IsTypeDesc() + && Nullable::IsNullableForType(toHandle, fromHandle.AsMethodTable())) { - FC_RETURN_BOOL((BOOL)r); + // do not put this in the cache (see TypeHandle::CanCastTo and ObjIsInstanceOfCore). + retVal = TRUE; } - - BOOL iRetVal = FALSE; - HELPER_METHOD_FRAME_BEGIN_RET_2(refType, refTarget); + else { - // We allow T to be cast to Nullable - if (!fromHandle.IsTypeDesc() && Nullable::IsNullableForType(toHandle, fromHandle.AsMethodTable())) + GCX_COOP(); + + if (fromHandle.IsTypeDesc()) { - // do not put this in the cache (see TypeHandle::CanCastTo and ObjIsInstanceOfCore). - iRetVal = TRUE; + retVal = fromHandle.AsTypeDesc()->CanCastTo(toHandle, /* pVisited */ NULL); + } + else if (toHandle.IsTypeDesc()) + { + retVal = FALSE; + CastCache::TryAddToCache(fromHandle, toHandle, FALSE); } else { - if (fromHandle.IsTypeDesc()) - { - iRetVal = fromHandle.AsTypeDesc()->CanCastTo(toHandle, /* pVisited */ NULL); - } - else if (toHandle.IsTypeDesc()) - { - iRetVal = FALSE; - CastCache::TryAddToCache(fromHandle, toHandle, FALSE); - } - else - { - iRetVal = fromHandle.AsMethodTable()->CanCastTo(toHandle.AsMethodTable(), /* pVisited */ NULL); - } + retVal = fromHandle.AsMethodTable()->CanCastTo(toHandle.AsMethodTable(), /* pVisited */ NULL); } } - HELPER_METHOD_FRAME_END(); - FC_RETURN_BOOL(iRetVal); + END_QCALL; + + return retVal; } -FCIMPLEND FCIMPL6(FC_BOOL_RET, RuntimeTypeHandle::SatisfiesConstraints, PTR_ReflectClassBaseObject pParamTypeUNSAFE, TypeHandle *typeContextArgs, INT32 typeContextCount, TypeHandle *methodContextArgs, INT32 methodContextCount, PTR_ReflectClassBaseObject pArgumentTypeUNSAFE); { diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index 2be91b6a38f2a..da5b2bca75289 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -120,7 +120,7 @@ class RuntimeTypeHandle static FCDECL1(FC_BOOL_RET, IsUnmanagedFunctionPointer, ReflectClassBaseObject *pTypeUNSAFE); - static FCDECL2(FC_BOOL_RET, CanCastTo, ReflectClassBaseObject *pType, ReflectClassBaseObject *pTarget); + static FCDECL2(TypeHandle::CastResult, CanCastToInternal, ReflectClassBaseObject *pType, ReflectClassBaseObject *pTarget); static FCDECL6(FC_BOOL_RET, SatisfiesConstraints, PTR_ReflectClassBaseObject pGenericParameter, TypeHandle *typeContextArgs, INT32 typeContextCount, TypeHandle *methodContextArgs, INT32 methodContextCount, PTR_ReflectClassBaseObject pGenericArgument); @@ -177,6 +177,7 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_PrepareMemberInfoCache(QCall::TypeHa extern "C" void QCALLTYPE RuntimeTypeHandle_ConstructName(QCall::TypeHandle pTypeHandle, DWORD format, QCall::StringHandleOnStack retString); extern "C" void QCALLTYPE RuntimeTypeHandle_GetInterfaces(MethodTable* pMT, QCall::ObjectHandleOnStack result); extern "C" BOOL QCALLTYPE RuntimeTypeHandle_IsVisible(QCall::TypeHandle pTypeHandle); +extern "C" BOOL QCALLTYPE RuntimeTypeHandle_CanCastToSlow(QCall::TypeHandle type, QCall::TypeHandle target); extern "C" void QCALLTYPE RuntimeTypeHandle_GetInstantiation(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType, BOOL fAsRuntimeTypeArray); extern "C" void QCALLTYPE RuntimeTypeHandle_Instantiate(QCall::TypeHandle pTypeHandle, TypeHandle * pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack retType); extern "C" void QCALLTYPE RuntimeTypeHandle_GetGenericTypeDefinition(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType); diff --git a/src/coreclr/vm/typehandle.h b/src/coreclr/vm/typehandle.h index 5d20d6d5f7d00..862e2fa137aee 100644 --- a/src/coreclr/vm/typehandle.h +++ b/src/coreclr/vm/typehandle.h @@ -267,7 +267,8 @@ class TypeHandle // Note that if the TypeHandle is a valuetype, the caller is responsible // for checking that the valuetype is in its boxed form before calling // CanCastTo. Otherwise, the caller should be using IsBoxedAndCanCastTo() - typedef enum { CannotCast, CanCast, MaybeCast } CastResult; + // See CastCache.cs for matching managed type. + typedef enum { CannotCast = 0, CanCast = 1, MaybeCast = 2 } CastResult; BOOL CanCastTo(TypeHandle type, TypeHandlePairList *pVisited = NULL) const; BOOL IsBoxedAndCanCastTo(TypeHandle type, TypeHandlePairList *pVisited) const; diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastCache.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastCache.cs index 8b538af931edf..c5602eff0d282 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastCache.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastCache.cs @@ -8,6 +8,7 @@ namespace System.Runtime.CompilerServices { + // See typehandle.h for matching unmanaged type. internal enum CastResult { CannotCast = 0, diff --git a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs index 2b30db584b659..c243053aead38 100644 --- a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs @@ -268,7 +268,6 @@ public override bool IsAssignableFrom([NotNullWhen(true)] Type? c) // For runtime type, let the VM decide. if (c.UnderlyingSystemType is RuntimeType fromType) { - // both this and c (or their underlying system types) are runtime types return RuntimeTypeHandle.CanCastTo(fromType, this); } From d887c89b5c3814870f1b5ffa4fecb55ae66ef7a2 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Tue, 10 Dec 2024 11:34:30 -0800 Subject: [PATCH 07/21] Remove HMF from RuntimeMethodHandle::GetMethodDef(). --- .../src/System/RuntimeHandles.cs | 11 +++++++++- src/coreclr/vm/runtimehandles.cpp | 22 +++++-------------- src/coreclr/vm/runtimehandles.h | 2 +- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index a057d3769af42..bbfc069bba254 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -1113,7 +1113,16 @@ internal static int GetSlot(IRuntimeMethodInfo method) } [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern int GetMethodDef(IRuntimeMethodInfo method); + private static extern int GetMethodDef(RuntimeMethodHandleInternal method); + + internal static int GetMethodDef(IRuntimeMethodInfo method) + { + Debug.Assert(method != null); + + int slot = GetMethodDef(method.Value); + GC.KeepAlive(method); + return slot; + } internal static string GetName(RuntimeMethodHandleInternal method) => GetUtf8Name(method).ToString(); diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 1abdc173494c3..f485b32eece93 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -1642,25 +1642,13 @@ extern "C" void QCALLTYPE Signature_GetCustomModifiersAtOffset( END_QCALL; } -FCIMPL1(INT32, RuntimeMethodHandle::GetMethodDef, ReflectMethodObject *pMethodUNSAFE) { - CONTRACTL { - FCALL_CHECK; - } - CONTRACTL_END; - - if (!pMethodUNSAFE) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); - - MethodDesc* pMethod = pMethodUNSAFE->GetMethod(); +FCIMPL1(INT32, RuntimeMethodHandle::GetMethodDef, MethodDesc* pMethod) +{ + FCALL_CONTRACT; + _ASSERTE(pMethod != NULL); if (pMethod->HasMethodInstantiation()) - { - HELPER_METHOD_FRAME_BEGIN_RET_1(pMethodUNSAFE); - { - pMethod = pMethod->StripMethodInstantiation(); - } - HELPER_METHOD_FRAME_END(); - } + pMethod = pMethod->StripMethodInstantiation(); INT32 tkMethodDef = (INT32)pMethod->GetMemberDef(); _ASSERTE(TypeFromToken(tkMethodDef) == mdtMethodDef); diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index da5b2bca75289..c8f59135c9587 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -202,7 +202,7 @@ class RuntimeMethodHandle static FCDECL1(INT32, GetImplAttributes, ReflectMethodObject *pMethodUNSAFE); static FCDECL1(MethodTable*, GetMethodTable, MethodDesc *pMethod); static FCDECL1(INT32, GetSlot, MethodDesc *pMethod); - static FCDECL1(INT32, GetMethodDef, ReflectMethodObject *pMethodUNSAFE); + static FCDECL1(INT32, GetMethodDef, MethodDesc *pMethod); static FCDECL1(LPCUTF8, GetUtf8Name, MethodDesc *pMethod); static FCDECL1(FC_BOOL_RET, HasMethodInstantiation, MethodDesc *pMethod); From 94cfb1663f22a0b991c22ee44699adad1525000a Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Tue, 10 Dec 2024 12:31:38 -0800 Subject: [PATCH 08/21] Convert RuntimeMethodHandle.GetStubIfNeeded to fast/slow paths using FCall/QCall. --- .../src/System/RuntimeHandles.cs | 21 ++++- src/coreclr/vm/ecalllist.h | 2 +- src/coreclr/vm/qcallentrypoints.cpp | 1 + src/coreclr/vm/runtimehandles.cpp | 92 +++++++++---------- src/coreclr/vm/runtimehandles.h | 3 +- 5 files changed, 68 insertions(+), 51 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index bbfc069bba254..7f3544acd12eb 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -1243,7 +1243,26 @@ internal static bool HasMethodInstantiation(IRuntimeMethodInfo method) } [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern RuntimeMethodHandleInternal GetStubIfNeeded(RuntimeMethodHandleInternal method, RuntimeType declaringType, RuntimeType[]? methodInstantiation); + private static extern RuntimeMethodHandleInternal GetStubIfNeededInternal(RuntimeMethodHandleInternal method, RuntimeType declaringType); + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeMethodHandle_GetStubIfNeededSlow")] + private static partial RuntimeMethodHandleInternal GetStubIfNeededSlow(RuntimeMethodHandleInternal method, QCallTypeHandle declaringTypeHandle, ObjectHandleOnStack methodInstantiation); + + internal static RuntimeMethodHandleInternal GetStubIfNeeded(RuntimeMethodHandleInternal method, RuntimeType declaringType, RuntimeType[]? methodInstantiation) + { + if (methodInstantiation is null) + { + RuntimeMethodHandleInternal handle = GetStubIfNeededInternal(method, declaringType); + if (!handle.IsNullHandle()) + return handle; + } + + return GetStubIfNeededWorker(method, declaringType, methodInstantiation); + + [MethodImpl(MethodImplOptions.NoInlining)] + static RuntimeMethodHandleInternal GetStubIfNeededWorker(RuntimeMethodHandleInternal method, RuntimeType declaringType, RuntimeType[]? methodInstantiation) + => GetStubIfNeededSlow(method, new QCallTypeHandle(ref declaringType), ObjectHandleOnStack.Create(ref methodInstantiation)); + } [MethodImpl(MethodImplOptions.InternalCall)] internal static extern RuntimeMethodHandleInternal GetMethodFromCanonical(RuntimeMethodHandleInternal method, RuntimeType declaringType); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 00dc4688e6c1a..4e95974503dd0 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -147,7 +147,7 @@ FCFuncStart(gRuntimeMethodHandle) FCFuncElement("IsGenericMethodDefinition", RuntimeMethodHandle::IsGenericMethodDefinition) FCFuncElement("GetGenericParameterCount", RuntimeMethodHandle::GetGenericParameterCount) FCFuncElement("IsTypicalMethodDefinition", RuntimeMethodHandle::IsTypicalMethodDefinition) - FCFuncElement("GetStubIfNeeded", RuntimeMethodHandle::GetStubIfNeeded) + FCFuncElement("GetStubIfNeededInternal", RuntimeMethodHandle::GetStubIfNeededInternal) FCFuncElement("GetMethodFromCanonical", RuntimeMethodHandle::GetMethodFromCanonical) FCFuncElement("IsDynamicMethod", RuntimeMethodHandle::IsDynamicMethod) FCFuncElement("GetMethodBody", RuntimeMethodHandle::GetMethodBody) diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index f27bb56828cdd..cab18ccc2a767 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -161,6 +161,7 @@ static const Entry s_QCall[] = DllImportEntry(RuntimeMethodHandle_StripMethodInstantiation) DllImportEntry(RuntimeMethodHandle_IsCAVisibleFromDecoratedType) DllImportEntry(RuntimeMethodHandle_Destroy) + DllImportEntry(RuntimeMethodHandle_GetStubIfNeededSlow) DllImportEntry(RuntimeModule_GetScopeName) DllImportEntry(RuntimeModule_GetFullyQualifiedName) DllImportEntry(RuntimeModule_GetTypes) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index f485b32eece93..7d0b73a455878 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -1890,7 +1890,7 @@ FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsTypicalMethodDefinition, ReflectMeth FCIMPLEND extern "C" void QCALLTYPE RuntimeMethodHandle_GetTypicalMethodDefinition(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod) - { +{ QCALL_CONTRACT; BEGIN_QCALL; @@ -1964,75 +1964,71 @@ extern "C" void QCALLTYPE RuntimeMethodHandle_StripMethodInstantiation(MethodDes // 3. create an UnboxingStub for a method in a value type. In this case instArray will be null. // For case 2 and 3, an instantiating stub or unboxing stub might not be needed in which case the original // MethodDesc is returned. -FCIMPL3(MethodDesc*, RuntimeMethodHandle::GetStubIfNeeded, +FCIMPL2(MethodDesc*, RuntimeMethodHandle::GetStubIfNeededInternal, MethodDesc *pMethod, - ReflectClassBaseObject *pTypeUNSAFE, - PtrArray* instArrayUNSAFE) + ReflectClassBaseObject *pTypeUNSAFE) { - CONTRACTL { - FCALL_CHECK; - } - CONTRACTL_END; + FCALL_CONTRACT; REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE); - PTRARRAYREF instArray = (PTRARRAYREF)ObjectToOBJECTREF(instArrayUNSAFE); - - if (refType == NULL) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); TypeHandle instType = refType->GetType(); - MethodDesc *pNewMethod = pMethod; - - // error conditions - if (!pMethod) - FCThrowRes(kArgumentException, W("Arg_InvalidHandle")); - - if (instType.IsNull()) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); // Perf optimization: this logic is actually duplicated in FindOrCreateAssociatedMethodDescForReflection, but since it // is the more common case it's worth the duplicate check here to avoid the helper method frame - if ( instArray == NULL && - ( pMethod->HasMethodInstantiation() || - ( !instType.IsValueType() && - ( !instType.HasInstantiation() || instType.IsGenericTypeDefinition() ) ) ) ) + if (pMethod->HasMethodInstantiation() + || (!instType.IsValueType() + && (!instType.HasInstantiation() || instType.IsGenericTypeDefinition()))) { - return pNewMethod; + return pMethod; } - HELPER_METHOD_FRAME_BEGIN_RET_2(refType, instArray); - { - TypeHandle *inst = NULL; - DWORD ntypars = 0; + return NULL; +} +FCIMPLEND - if (instArray != NULL) - { - ntypars = instArray->GetNumComponents(); +// See RuntimeMethodHandle::GetStubIfNeededInternal for more details. +extern "C" MethodDesc* QCALLTYPE RuntimeMethodHandle_GetStubIfNeededSlow(MethodDesc* pMethod, QCall::TypeHandle declaringTypeHandle, QCall::ObjectHandleOnStack methodInstantiation) +{ + QCALL_CONTRACT; - size_t size = ntypars * sizeof(TypeHandle); - if ((size / sizeof(TypeHandle)) != ntypars) // uint over/underflow - COMPlusThrow(kArgumentException); - inst = (TypeHandle*) _alloca(size); + MethodDesc *pNewMethod = NULL; - for (DWORD i = 0; i < ntypars; i++) - { - REFLECTCLASSBASEREF instRef = (REFLECTCLASSBASEREF)instArray->GetAt(i); + BEGIN_QCALL; - if (instRef == NULL) - COMPlusThrowArgumentNull(W("inst"), W("ArgumentNull_ArrayElement")); + GCX_COOP(); - inst[i] = instRef->GetType(); - } - } + TypeHandle instType = declaringTypeHandle.AsTypeHandle(); + + TypeHandle* inst = NULL; + DWORD ntypars = 0; + + // Construct TypeHandle array for instantiation. + if (methodInstantiation.Get() != NULL) + { + ntypars = ((PTRARRAYREF)methodInstantiation.Get())->GetNumComponents(); + + size_t size = ntypars * sizeof(TypeHandle); + if ((size / sizeof(TypeHandle)) != ntypars) // uint over/underflow + COMPlusThrow(kArgumentException); + inst = (TypeHandle*) _alloca(size); - pNewMethod = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMethod, instType, Instantiation(inst, ntypars)); + for (DWORD i = 0; i < ntypars; i++) + { + REFLECTCLASSBASEREF instRef = (REFLECTCLASSBASEREF)((PTRARRAYREF)methodInstantiation.Get())->GetAt(i); + if (instRef == NULL) + COMPlusThrowArgumentNull(W("inst"), W("ArgumentNull_ArrayElement")); + + inst[i] = instRef->GetType(); + } } - HELPER_METHOD_FRAME_END(); + + pNewMethod = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMethod, instType, Instantiation(inst, ntypars)); + + END_QCALL; return pNewMethod; } -FCIMPLEND - FCIMPL2(MethodDesc*, RuntimeMethodHandle::GetMethodFromCanonical, MethodDesc *pMethod, ReflectClassBaseObject *pTypeUNSAFE) { diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index c8f59135c9587..9924c1aeec8be 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -217,7 +217,7 @@ class RuntimeMethodHandle FCDECL1(INT32, GetGenericParameterCount, MethodDesc * pMethod); // see comment in the cpp file - static FCDECL3(MethodDesc*, GetStubIfNeeded, MethodDesc *pMethod, ReflectClassBaseObject *pType, PtrArray* instArray); + static FCDECL2(MethodDesc*, GetStubIfNeededInternal, MethodDesc *pMethod, ReflectClassBaseObject *pType); static FCDECL2(MethodDesc*, GetMethodFromCanonical, MethodDesc *pMethod, PTR_ReflectClassBaseObject pType); static @@ -257,6 +257,7 @@ extern "C" BOOL QCALLTYPE RuntimeMethodHandle_GetIsCollectible(MethodDesc * pMet extern "C" void QCALLTYPE RuntimeMethodHandle_GetTypicalMethodDefinition(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod); extern "C" void QCALLTYPE RuntimeMethodHandle_StripMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod); extern "C" void QCALLTYPE RuntimeMethodHandle_Destroy(MethodDesc * pMethod); +extern "C" MethodDesc* QCALLTYPE RuntimeMethodHandle_GetStubIfNeededSlow(MethodDesc* pMethod, QCall::TypeHandle declaringTypeHandle, QCall::ObjectHandleOnStack methodInstantiation); class RuntimeFieldHandle { From f9ff74a6d038ca187e501e948c00d8410ce430c5 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Tue, 10 Dec 2024 19:03:17 -0800 Subject: [PATCH 09/21] Convert RuntimeTypeHandle.SatisfiesConstraints() to QCall. --- .../src/System/RuntimeHandles.cs | 6 +-- src/coreclr/vm/ecalllist.h | 1 - src/coreclr/vm/qcallentrypoints.cpp | 1 + src/coreclr/vm/runtimehandles.cpp | 45 ++++++++----------- src/coreclr/vm/runtimehandles.h | 3 +- 5 files changed, 23 insertions(+), 33 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index 7f3544acd12eb..ca75089e34ca6 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -845,8 +845,8 @@ internal bool ContainsGenericVariables() return ContainsGenericVariables(GetRuntimeTypeChecked()); } - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern bool SatisfiesConstraints(RuntimeType paramType, IntPtr* pTypeContext, int typeContextLength, IntPtr* pMethodContext, int methodContextLength, RuntimeType toType); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_SatisfiesConstraints")] + private static partial Interop.BOOL SatisfiesConstraints(QCallTypeHandle paramType, IntPtr* pTypeContext, int typeContextLength, IntPtr* pMethodContext, int methodContextLength, QCallTypeHandle toType); internal static bool SatisfiesConstraints(RuntimeType paramType, RuntimeType[]? typeContext, RuntimeType[]? methodContext, RuntimeType toType) { @@ -855,7 +855,7 @@ internal static bool SatisfiesConstraints(RuntimeType paramType, RuntimeType[]? fixed (IntPtr* pTypeContextHandles = typeContextHandles, pMethodContextHandles = methodContextHandles) { - bool result = SatisfiesConstraints(paramType, pTypeContextHandles, typeContextLength, pMethodContextHandles, methodContextLength, toType); + bool result = SatisfiesConstraints(new QCallTypeHandle(ref paramType), pTypeContextHandles, typeContextLength, pMethodContextHandles, methodContextLength, new QCallTypeHandle(ref toType)) != Interop.BOOL.FALSE; GC.KeepAlive(typeContext); GC.KeepAlive(methodContext); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 4e95974503dd0..1feb35ee358d4 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -96,7 +96,6 @@ FCFuncStart(gCOMTypeHandleFuncs) FCFuncElement("GetGenericVariableIndex", RuntimeTypeHandle::GetGenericVariableIndex) FCFuncElement("IsGenericVariable", RuntimeTypeHandle::IsGenericVariable) FCFuncElement("ContainsGenericVariables", RuntimeTypeHandle::ContainsGenericVariables) - FCFuncElement("SatisfiesConstraints", RuntimeTypeHandle::SatisfiesConstraints) FCFuncElement("IsUnmanagedFunctionPointer", RuntimeTypeHandle::IsUnmanagedFunctionPointer) FCFuncElement("CompareCanonicalHandles", RuntimeTypeHandle::CompareCanonicalHandles) FCFuncElement("GetRuntimeTypeFromHandleIfExists", RuntimeTypeHandle::GetRuntimeTypeFromHandleIfExists) diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index cab18ccc2a767..ed557aecddf7e 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -135,6 +135,7 @@ static const Entry s_QCall[] = DllImportEntry(RuntimeTypeHandle_ConstructName) DllImportEntry(RuntimeTypeHandle_GetInterfaces) DllImportEntry(RuntimeTypeHandle_CanCastToSlow) + DllImportEntry(RuntimeTypeHandle_SatisfiesConstraints) DllImportEntry(RuntimeTypeHandle_GetInstantiation) DllImportEntry(RuntimeTypeHandle_Instantiate) DllImportEntry(RuntimeTypeHandle_GetGenericTypeDefinition) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 7d0b73a455878..66c38479979d4 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -1050,47 +1050,38 @@ extern "C" BOOL QCALLTYPE RuntimeTypeHandle_CanCastToSlow(QCall::TypeHandle type return retVal; } -FCIMPL6(FC_BOOL_RET, RuntimeTypeHandle::SatisfiesConstraints, PTR_ReflectClassBaseObject pParamTypeUNSAFE, TypeHandle *typeContextArgs, INT32 typeContextCount, TypeHandle *methodContextArgs, INT32 methodContextCount, PTR_ReflectClassBaseObject pArgumentTypeUNSAFE); +extern "C" BOOL QCALLTYPE RuntimeTypeHandle_SatisfiesConstraints(QCall::TypeHandle paramType, TypeHandle* typeContextArgs, INT32 typeContextCount, TypeHandle* methodContextArgs, INT32 methodContextCount, QCall::TypeHandle toType) { - CONTRACTL { - FCALL_CHECK; + CONTRACTL + { + QCALL_CHECK; PRECONDITION(CheckPointer(typeContextArgs, NULL_OK)); PRECONDITION(CheckPointer(methodContextArgs, NULL_OK)); } CONTRACTL_END; - REFLECTCLASSBASEREF refParamType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pParamTypeUNSAFE); - REFLECTCLASSBASEREF refArgumentType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pArgumentTypeUNSAFE); - - TypeHandle thGenericParameter = refParamType->GetType(); - TypeHandle thGenericArgument = refArgumentType->GetType(); BOOL bResult = FALSE; - SigTypeContext typeContext; - Instantiation classInst; - Instantiation methodInst; + BEGIN_QCALL; - if (typeContextArgs != NULL) - { - classInst = Instantiation(typeContextArgs, typeContextCount); - } - - if (methodContextArgs != NULL) - { - methodInst = Instantiation(methodContextArgs, methodContextCount); - } + Instantiation classInst = typeContextArgs != NULL + ? Instantiation(typeContextArgs, typeContextCount) + : Instantiation{}; + Instantiation methodInst = methodContextArgs != NULL + ? Instantiation(methodContextArgs, methodContextCount) + : Instantiation{}; + SigTypeContext typeContext; SigTypeContext::InitTypeContext(classInst, methodInst, &typeContext); - HELPER_METHOD_FRAME_BEGIN_RET_2(refParamType, refArgumentType); - { - bResult = thGenericParameter.AsGenericVariable()->SatisfiesConstraints(&typeContext, thGenericArgument); - } - HELPER_METHOD_FRAME_END(); + TypeHandle thGenericParameter = paramType.AsTypeHandle(); + TypeHandle thGenericArgument = toType.AsTypeHandle(); + bResult = thGenericParameter.AsGenericVariable()->SatisfiesConstraints(&typeContext, thGenericArgument); + + END_QCALL; - FC_RETURN_BOOL(bResult); + return bResult; } -FCIMPLEND extern "C" void QCALLTYPE RuntimeTypeHandle_GetInstantiation(QCall::TypeHandle pType, QCall::ObjectHandleOnStack retTypes, BOOL fAsRuntimeTypeArray) { diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index 9924c1aeec8be..f747e42ed2ee3 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -122,8 +122,6 @@ class RuntimeTypeHandle static FCDECL2(TypeHandle::CastResult, CanCastToInternal, ReflectClassBaseObject *pType, ReflectClassBaseObject *pTarget); - static FCDECL6(FC_BOOL_RET, SatisfiesConstraints, PTR_ReflectClassBaseObject pGenericParameter, TypeHandle *typeContextArgs, INT32 typeContextCount, TypeHandle *methodContextArgs, INT32 methodContextCount, PTR_ReflectClassBaseObject pGenericArgument); - static FCDECL1(FC_BOOL_RET, IsGenericVariable, PTR_ReflectClassBaseObject pType); @@ -178,6 +176,7 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_ConstructName(QCall::TypeHandle pTyp extern "C" void QCALLTYPE RuntimeTypeHandle_GetInterfaces(MethodTable* pMT, QCall::ObjectHandleOnStack result); extern "C" BOOL QCALLTYPE RuntimeTypeHandle_IsVisible(QCall::TypeHandle pTypeHandle); extern "C" BOOL QCALLTYPE RuntimeTypeHandle_CanCastToSlow(QCall::TypeHandle type, QCall::TypeHandle target); +extern "C" BOOL QCALLTYPE RuntimeTypeHandle_SatisfiesConstraints(QCall::TypeHandle paramType, TypeHandle* typeContextArgs, INT32 typeContextCount, TypeHandle* methodContextArgs, INT32 methodContextCount, QCall::TypeHandle toType); extern "C" void QCALLTYPE RuntimeTypeHandle_GetInstantiation(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType, BOOL fAsRuntimeTypeArray); extern "C" void QCALLTYPE RuntimeTypeHandle_Instantiate(QCall::TypeHandle pTypeHandle, TypeHandle * pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack retType); extern "C" void QCALLTYPE RuntimeTypeHandle_GetGenericTypeDefinition(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType); From fffc08ee0fcda04c7ba087b22d3b522edcb59de5 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Wed, 11 Dec 2024 13:09:20 -0800 Subject: [PATCH 10/21] Convert RuntimeMethodHandle.GetMethodBody() to QCall. --- .../src/System/RuntimeHandles.cs | 13 +- src/coreclr/vm/ecalllist.h | 1 - src/coreclr/vm/qcallentrypoints.cpp | 1 + src/coreclr/vm/runtimehandles.cpp | 224 +++++++++--------- src/coreclr/vm/runtimehandles.h | 4 +- 5 files changed, 120 insertions(+), 123 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index ca75089e34ca6..a5ec37926af39 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -1321,8 +1321,17 @@ internal static IRuntimeMethodInfo StripMethodInstantiation(IRuntimeMethodInfo m [MethodImpl(MethodImplOptions.InternalCall)] internal static extern Resolver GetResolver(RuntimeMethodHandleInternal method); - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern RuntimeMethodBody? GetMethodBody(IRuntimeMethodInfo method, RuntimeType declaringType); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeMethodHandle_GetMethodBody")] + private static partial void GetMethodBody(RuntimeMethodHandleInternal method, nint declaringType, ObjectHandleOnStack result); + + internal static RuntimeMethodBody? GetMethodBody(IRuntimeMethodInfo method, RuntimeType declaringType) + { + RuntimeMethodBody? result = null; + GetMethodBody(method.Value, declaringType.GetUnderlyingNativeHandle(), ObjectHandleOnStack.Create(ref result)); + GC.KeepAlive(method); + GC.KeepAlive(declaringType); + return result; + } [MethodImpl(MethodImplOptions.InternalCall)] internal static extern bool IsConstructor(RuntimeMethodHandleInternal method); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 1feb35ee358d4..39154055db712 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -149,7 +149,6 @@ FCFuncStart(gRuntimeMethodHandle) FCFuncElement("GetStubIfNeededInternal", RuntimeMethodHandle::GetStubIfNeededInternal) FCFuncElement("GetMethodFromCanonical", RuntimeMethodHandle::GetMethodFromCanonical) FCFuncElement("IsDynamicMethod", RuntimeMethodHandle::IsDynamicMethod) - FCFuncElement("GetMethodBody", RuntimeMethodHandle::GetMethodBody) FCFuncElement("IsConstructor", RuntimeMethodHandle::IsConstructor) FCFuncElement("GetResolver", RuntimeMethodHandle::GetResolver) FCFuncElement("GetLoaderAllocatorInternal", RuntimeMethodHandle::GetLoaderAllocatorInternal) diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index ed557aecddf7e..1e79b4729b05e 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -163,6 +163,7 @@ static const Entry s_QCall[] = DllImportEntry(RuntimeMethodHandle_IsCAVisibleFromDecoratedType) DllImportEntry(RuntimeMethodHandle_Destroy) DllImportEntry(RuntimeMethodHandle_GetStubIfNeededSlow) + DllImportEntry(RuntimeMethodHandle_GetMethodBody) DllImportEntry(RuntimeModule_GetScopeName) DllImportEntry(RuntimeModule_GetFullyQualifiedName) DllImportEntry(RuntimeModule_GetTypes) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 66c38479979d4..8c2b54ddcec76 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -2039,170 +2039,160 @@ FCIMPL2(MethodDesc*, RuntimeMethodHandle::GetMethodFromCanonical, MethodDesc *pM } FCIMPLEND - -FCIMPL2(RuntimeMethodBody *, RuntimeMethodHandle::GetMethodBody, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE) +extern "C" void QCALLTYPE RuntimeMethodHandle_GetMethodBody(MethodDesc* pMethod, EnregisteredTypeHandle pDeclaringType, QCall::ObjectHandleOnStack result) { - CONTRACTL - { - FCALL_CHECK; - } - CONTRACTL_END; + QCALL_CONTRACT; - struct _gc + _ASSERTE(pMethod != NULL); + + BEGIN_QCALL; + + GCX_COOP(); + + struct { RUNTIMEMETHODBODYREF MethodBodyObj; RUNTIMEEXCEPTIONHANDLINGCLAUSEREF EHClauseObj; RUNTIMELOCALVARIABLEINFOREF RuntimeLocalVariableInfoObj; - U1ARRAYREF U1Array; - BASEARRAYREF TempArray; - REFLECTCLASSBASEREF declaringType; - REFLECTMETHODREF refMethod; + U1ARRAYREF U1Array; + BASEARRAYREF TempArray; } gc; - gc.MethodBodyObj = NULL; gc.EHClauseObj = NULL; gc.RuntimeLocalVariableInfoObj = NULL; gc.U1Array = NULL; gc.TempArray = NULL; - gc.declaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE); - gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE); - - - if (!gc.refMethod) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); - - MethodDesc* pMethod = gc.refMethod->GetMethod(); + GCPROTECT_BEGIN(gc); - TypeHandle declaringType = gc.declaringType == NULL ? TypeHandle() : gc.declaringType->GetType(); + TypeHandle declaringType = TypeHandle::FromPtr(pDeclaringType); - if (!pMethod->IsIL()) - return NULL; - - HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc); + COR_ILMETHOD* pILHeader = NULL; + if (pMethod->IsIL()) { - MethodDesc *pMethodIL = pMethod; + MethodDesc* pMethodIL = pMethod; if (pMethod->IsWrapperStub()) pMethodIL = pMethod->GetWrappedMethodDesc(); - COR_ILMETHOD* pILHeader = pMethodIL->GetILHeader(); + pILHeader = pMethodIL->GetILHeader(); + } - if (pILHeader) - { - MethodTable * pExceptionHandlingClauseMT = CoreLibBinder::GetClass(CLASS__RUNTIME_EH_CLAUSE); - TypeHandle thEHClauseArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pExceptionHandlingClauseMT), ELEMENT_TYPE_SZARRAY); + if (pILHeader) + { + MethodTable * pExceptionHandlingClauseMT = CoreLibBinder::GetClass(CLASS__RUNTIME_EH_CLAUSE); + TypeHandle thEHClauseArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pExceptionHandlingClauseMT), ELEMENT_TYPE_SZARRAY); - MethodTable * pLocalVariableMT = CoreLibBinder::GetClass(CLASS__RUNTIME_LOCAL_VARIABLE_INFO); - TypeHandle thLocalVariableArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pLocalVariableMT), ELEMENT_TYPE_SZARRAY); + MethodTable * pLocalVariableMT = CoreLibBinder::GetClass(CLASS__RUNTIME_LOCAL_VARIABLE_INFO); + TypeHandle thLocalVariableArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pLocalVariableMT), ELEMENT_TYPE_SZARRAY); - Module* pModule = pMethod->GetModule(); - COR_ILMETHOD_DECODER::DecoderStatus status; - COR_ILMETHOD_DECODER header(pILHeader, pModule->GetMDImport(), &status); + Module* pModule = pMethod->GetModule(); + COR_ILMETHOD_DECODER::DecoderStatus status; + COR_ILMETHOD_DECODER header(pILHeader, pModule->GetMDImport(), &status); - if (status != COR_ILMETHOD_DECODER::SUCCESS) + if (status != COR_ILMETHOD_DECODER::SUCCESS) + { + if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR) { - if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR) - { - // Throw a verification HR - COMPlusThrowHR(COR_E_VERIFICATION); - } - else - { - COMPlusThrowHR(COR_E_BADIMAGEFORMAT); - } + // Throw a verification HR + COMPlusThrowHR(COR_E_VERIFICATION); } + else + { + COMPlusThrowHR(COR_E_BADIMAGEFORMAT); + } + } - gc.MethodBodyObj = (RUNTIMEMETHODBODYREF)AllocateObject(CoreLibBinder::GetClass(CLASS__RUNTIME_METHOD_BODY)); + gc.MethodBodyObj = (RUNTIMEMETHODBODYREF)AllocateObject(CoreLibBinder::GetClass(CLASS__RUNTIME_METHOD_BODY)); - gc.MethodBodyObj->_maxStackSize = header.GetMaxStack(); - gc.MethodBodyObj->_initLocals = !!(header.GetFlags() & CorILMethod_InitLocals); + gc.MethodBodyObj->_maxStackSize = header.GetMaxStack(); + gc.MethodBodyObj->_initLocals = !!(header.GetFlags() & CorILMethod_InitLocals); - if (header.IsFat()) - gc.MethodBodyObj->_localVarSigToken = header.GetLocalVarSigTok(); - else - gc.MethodBodyObj->_localVarSigToken = 0; + if (header.IsFat()) + gc.MethodBodyObj->_localVarSigToken = header.GetLocalVarSigTok(); + else + gc.MethodBodyObj->_localVarSigToken = 0; - // Allocate the array of IL and fill it in from the method header. - BYTE* pIL = const_cast(header.Code); - COUNT_T cIL = header.GetCodeSize(); - gc.U1Array = (U1ARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_U1, cIL); + // Allocate the array of IL and fill it in from the method header. + BYTE* pIL = const_cast(header.Code); + COUNT_T cIL = header.GetCodeSize(); + gc.U1Array = (U1ARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_U1, cIL); - SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_IL, gc.U1Array); - memcpyNoGCRefs(gc.MethodBodyObj->_IL->GetDataPtr(), pIL, cIL); + SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_IL, gc.U1Array); + memcpyNoGCRefs(gc.MethodBodyObj->_IL->GetDataPtr(), pIL, cIL); - // Allocate the array of exception clauses. - INT32 cEh = (INT32)header.EHCount(); - const COR_ILMETHOD_SECT_EH* ehInfo = header.EH; - gc.TempArray = (BASEARRAYREF) AllocateSzArray(thEHClauseArray, cEh); + // Allocate the array of exception clauses. + INT32 cEh = (INT32)header.EHCount(); + const COR_ILMETHOD_SECT_EH* ehInfo = header.EH; + gc.TempArray = (BASEARRAYREF) AllocateSzArray(thEHClauseArray, cEh); - SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_exceptionClauses, gc.TempArray); + SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_exceptionClauses, gc.TempArray); - for (INT32 i = 0; i < cEh; i++) - { - COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff; - const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehClause = - (const COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)ehInfo->EHClause(i, &ehBuff); + for (INT32 i = 0; i < cEh; i++) + { + COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff; + const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehClause = + (const COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)ehInfo->EHClause(i, &ehBuff); - gc.EHClauseObj = (RUNTIMEEXCEPTIONHANDLINGCLAUSEREF) AllocateObject(pExceptionHandlingClauseMT); + gc.EHClauseObj = (RUNTIMEEXCEPTIONHANDLINGCLAUSEREF) AllocateObject(pExceptionHandlingClauseMT); - gc.EHClauseObj->_flags = ehClause->GetFlags(); - gc.EHClauseObj->_tryOffset = ehClause->GetTryOffset(); - gc.EHClauseObj->_tryLength = ehClause->GetTryLength(); - gc.EHClauseObj->_handlerOffset = ehClause->GetHandlerOffset(); - gc.EHClauseObj->_handlerLength = ehClause->GetHandlerLength(); + gc.EHClauseObj->_flags = ehClause->GetFlags(); + gc.EHClauseObj->_tryOffset = ehClause->GetTryOffset(); + gc.EHClauseObj->_tryLength = ehClause->GetTryLength(); + gc.EHClauseObj->_handlerOffset = ehClause->GetHandlerOffset(); + gc.EHClauseObj->_handlerLength = ehClause->GetHandlerLength(); - if ((ehClause->GetFlags() & COR_ILEXCEPTION_CLAUSE_FILTER) == 0) - gc.EHClauseObj->_catchToken = ehClause->GetClassToken(); - else - gc.EHClauseObj->_filterOffset = ehClause->GetFilterOffset(); + if ((ehClause->GetFlags() & COR_ILEXCEPTION_CLAUSE_FILTER) == 0) + gc.EHClauseObj->_catchToken = ehClause->GetClassToken(); + else + gc.EHClauseObj->_filterOffset = ehClause->GetFilterOffset(); - gc.MethodBodyObj->_exceptionClauses->SetAt(i, (OBJECTREF) gc.EHClauseObj); - SetObjectReference((OBJECTREF*)&(gc.EHClauseObj->_methodBody), (OBJECTREF)gc.MethodBodyObj); - } + gc.MethodBodyObj->_exceptionClauses->SetAt(i, (OBJECTREF) gc.EHClauseObj); + SetObjectReference((OBJECTREF*)&(gc.EHClauseObj->_methodBody), (OBJECTREF)gc.MethodBodyObj); + } - if (header.LocalVarSig != NULL) + if (header.LocalVarSig != NULL) + { + SigTypeContext sigTypeContext(pMethod, declaringType, pMethod->LoadMethodInstantiation()); + MetaSig metaSig(header.LocalVarSig, + header.cbLocalVarSig, + pModule, + &sigTypeContext, + MetaSig::sigLocalVars); + INT32 cLocals = metaSig.NumFixedArgs(); + gc.TempArray = (BASEARRAYREF) AllocateSzArray(thLocalVariableArray, cLocals); + SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_localVariables, gc.TempArray); + + for (INT32 i = 0; i < cLocals; i ++) { - SigTypeContext sigTypeContext(pMethod, declaringType, pMethod->LoadMethodInstantiation()); - MetaSig metaSig(header.LocalVarSig, - header.cbLocalVarSig, - pModule, - &sigTypeContext, - MetaSig::sigLocalVars); - INT32 cLocals = metaSig.NumFixedArgs(); - gc.TempArray = (BASEARRAYREF) AllocateSzArray(thLocalVariableArray, cLocals); - SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_localVariables, gc.TempArray); - - for (INT32 i = 0; i < cLocals; i ++) - { - gc.RuntimeLocalVariableInfoObj = (RUNTIMELOCALVARIABLEINFOREF)AllocateObject(pLocalVariableMT); + gc.RuntimeLocalVariableInfoObj = (RUNTIMELOCALVARIABLEINFOREF)AllocateObject(pLocalVariableMT); - gc.RuntimeLocalVariableInfoObj->_localIndex = i; + gc.RuntimeLocalVariableInfoObj->_localIndex = i; - metaSig.NextArg(); + metaSig.NextArg(); - CorElementType eType; - IfFailThrow(metaSig.GetArgProps().PeekElemType(&eType)); - if (ELEMENT_TYPE_PINNED == eType) - gc.RuntimeLocalVariableInfoObj->_isPinned = TRUE; + CorElementType eType; + IfFailThrow(metaSig.GetArgProps().PeekElemType(&eType)); + if (ELEMENT_TYPE_PINNED == eType) + gc.RuntimeLocalVariableInfoObj->_isPinned = TRUE; - TypeHandle tempType= metaSig.GetArgProps().GetTypeHandleThrowing(pModule, &sigTypeContext); - OBJECTREF refLocalType = tempType.GetManagedClassObject(); - gc.RuntimeLocalVariableInfoObj->SetType(refLocalType); - gc.MethodBodyObj->_localVariables->SetAt(i, (OBJECTREF) gc.RuntimeLocalVariableInfoObj); - } - } - else - { - INT32 cLocals = 0; - gc.TempArray = (BASEARRAYREF) AllocateSzArray(thLocalVariableArray, cLocals); - SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_localVariables, gc.TempArray); + TypeHandle tempType= metaSig.GetArgProps().GetTypeHandleThrowing(pModule, &sigTypeContext); + OBJECTREF refLocalType = tempType.GetManagedClassObject(); + gc.RuntimeLocalVariableInfoObj->SetType(refLocalType); + gc.MethodBodyObj->_localVariables->SetAt(i, (OBJECTREF) gc.RuntimeLocalVariableInfoObj); } } + else + { + INT32 cLocals = 0; + gc.TempArray = (BASEARRAYREF) AllocateSzArray(thLocalVariableArray, cLocals); + SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_localVariables, gc.TempArray); + } } - HELPER_METHOD_FRAME_END(); - return (RuntimeMethodBody*)OBJECTREFToObject(gc.MethodBodyObj); + result.Set(gc.MethodBodyObj); + + GCPROTECT_END(); + END_QCALL; } -FCIMPLEND FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsConstructor, MethodDesc *pMethod) { diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index f747e42ed2ee3..fa6b4015b496e 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -225,9 +225,6 @@ class RuntimeMethodHandle static FCDECL1(Object*, GetResolver, MethodDesc * pMethod); - - static FCDECL2(RuntimeMethodBody*, GetMethodBody, ReflectMethodObject *pMethodUNSAFE, PTR_ReflectClassBaseObject pDeclaringType); - static FCDECL1(FC_BOOL_RET, IsConstructor, MethodDesc *pMethod); static FCDECL1(Object*, GetLoaderAllocatorInternal, MethodDesc *pMethod); @@ -257,6 +254,7 @@ extern "C" void QCALLTYPE RuntimeMethodHandle_GetTypicalMethodDefinition(MethodD extern "C" void QCALLTYPE RuntimeMethodHandle_StripMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod); extern "C" void QCALLTYPE RuntimeMethodHandle_Destroy(MethodDesc * pMethod); extern "C" MethodDesc* QCALLTYPE RuntimeMethodHandle_GetStubIfNeededSlow(MethodDesc* pMethod, QCall::TypeHandle declaringTypeHandle, QCall::ObjectHandleOnStack methodInstantiation); +extern "C" void QCALLTYPE RuntimeMethodHandle_GetMethodBody(MethodDesc* pMethod, EnregisteredTypeHandle pDeclaringType, QCall::ObjectHandleOnStack result); class RuntimeFieldHandle { From 67080920fb1c7d908d19dfa4a0d989542bd2eb6b Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Wed, 11 Dec 2024 14:14:53 -0800 Subject: [PATCH 11/21] Fix build. --- src/coreclr/vm/runtimehandles.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index fa6b4015b496e..3d4e7cc4df161 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -59,7 +59,7 @@ class RuntimeExceptionHandlingClause : Object INT32 _filterOffset; }; -class RuntimeMethodBody : Object +class RuntimeMethodBody : public Object { private: // Disallow creation and copy construction of these. From e5c288271954434d7b4ddcef2485f93fa8ef58ea Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Wed, 11 Dec 2024 19:27:16 -0800 Subject: [PATCH 12/21] Revert "Convert RuntimeMethodHandle.GetMethodBody() to QCall." This reverts commit fffc08ee0fcda04c7ba087b22d3b522edcb59de5. --- .../src/System/RuntimeHandles.cs | 13 +- src/coreclr/vm/ecalllist.h | 1 + src/coreclr/vm/qcallentrypoints.cpp | 1 - src/coreclr/vm/runtimehandles.cpp | 224 +++++++++--------- src/coreclr/vm/runtimehandles.h | 4 +- 5 files changed, 123 insertions(+), 120 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index a5ec37926af39..ca75089e34ca6 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -1321,17 +1321,8 @@ internal static IRuntimeMethodInfo StripMethodInstantiation(IRuntimeMethodInfo m [MethodImpl(MethodImplOptions.InternalCall)] internal static extern Resolver GetResolver(RuntimeMethodHandleInternal method); - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeMethodHandle_GetMethodBody")] - private static partial void GetMethodBody(RuntimeMethodHandleInternal method, nint declaringType, ObjectHandleOnStack result); - - internal static RuntimeMethodBody? GetMethodBody(IRuntimeMethodInfo method, RuntimeType declaringType) - { - RuntimeMethodBody? result = null; - GetMethodBody(method.Value, declaringType.GetUnderlyingNativeHandle(), ObjectHandleOnStack.Create(ref result)); - GC.KeepAlive(method); - GC.KeepAlive(declaringType); - return result; - } + [MethodImpl(MethodImplOptions.InternalCall)] + internal static extern RuntimeMethodBody? GetMethodBody(IRuntimeMethodInfo method, RuntimeType declaringType); [MethodImpl(MethodImplOptions.InternalCall)] internal static extern bool IsConstructor(RuntimeMethodHandleInternal method); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index a7b3e34cb77c7..94872335cdc35 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -149,6 +149,7 @@ FCFuncStart(gRuntimeMethodHandle) FCFuncElement("GetStubIfNeededInternal", RuntimeMethodHandle::GetStubIfNeededInternal) FCFuncElement("GetMethodFromCanonical", RuntimeMethodHandle::GetMethodFromCanonical) FCFuncElement("IsDynamicMethod", RuntimeMethodHandle::IsDynamicMethod) + FCFuncElement("GetMethodBody", RuntimeMethodHandle::GetMethodBody) FCFuncElement("IsConstructor", RuntimeMethodHandle::IsConstructor) FCFuncElement("GetResolver", RuntimeMethodHandle::GetResolver) FCFuncElement("GetLoaderAllocatorInternal", RuntimeMethodHandle::GetLoaderAllocatorInternal) diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 0205c6a895d48..bbe88931dd99a 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -162,7 +162,6 @@ static const Entry s_QCall[] = DllImportEntry(RuntimeMethodHandle_IsCAVisibleFromDecoratedType) DllImportEntry(RuntimeMethodHandle_Destroy) DllImportEntry(RuntimeMethodHandle_GetStubIfNeededSlow) - DllImportEntry(RuntimeMethodHandle_GetMethodBody) DllImportEntry(RuntimeModule_GetScopeName) DllImportEntry(RuntimeModule_GetFullyQualifiedName) DllImportEntry(RuntimeModule_GetTypes) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 8c2b54ddcec76..66c38479979d4 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -2039,160 +2039,170 @@ FCIMPL2(MethodDesc*, RuntimeMethodHandle::GetMethodFromCanonical, MethodDesc *pM } FCIMPLEND -extern "C" void QCALLTYPE RuntimeMethodHandle_GetMethodBody(MethodDesc* pMethod, EnregisteredTypeHandle pDeclaringType, QCall::ObjectHandleOnStack result) -{ - QCALL_CONTRACT; - - _ASSERTE(pMethod != NULL); - BEGIN_QCALL; - - GCX_COOP(); +FCIMPL2(RuntimeMethodBody *, RuntimeMethodHandle::GetMethodBody, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE) +{ + CONTRACTL + { + FCALL_CHECK; + } + CONTRACTL_END; - struct + struct _gc { RUNTIMEMETHODBODYREF MethodBodyObj; RUNTIMEEXCEPTIONHANDLINGCLAUSEREF EHClauseObj; RUNTIMELOCALVARIABLEINFOREF RuntimeLocalVariableInfoObj; - U1ARRAYREF U1Array; - BASEARRAYREF TempArray; + U1ARRAYREF U1Array; + BASEARRAYREF TempArray; + REFLECTCLASSBASEREF declaringType; + REFLECTMETHODREF refMethod; } gc; + gc.MethodBodyObj = NULL; gc.EHClauseObj = NULL; gc.RuntimeLocalVariableInfoObj = NULL; gc.U1Array = NULL; gc.TempArray = NULL; - GCPROTECT_BEGIN(gc); + gc.declaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE); + gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE); - TypeHandle declaringType = TypeHandle::FromPtr(pDeclaringType); - COR_ILMETHOD* pILHeader = NULL; - if (pMethod->IsIL()) + if (!gc.refMethod) + FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); + + MethodDesc* pMethod = gc.refMethod->GetMethod(); + + TypeHandle declaringType = gc.declaringType == NULL ? TypeHandle() : gc.declaringType->GetType(); + + if (!pMethod->IsIL()) + return NULL; + + HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc); { - MethodDesc* pMethodIL = pMethod; + MethodDesc *pMethodIL = pMethod; if (pMethod->IsWrapperStub()) pMethodIL = pMethod->GetWrappedMethodDesc(); - pILHeader = pMethodIL->GetILHeader(); - } + COR_ILMETHOD* pILHeader = pMethodIL->GetILHeader(); - if (pILHeader) - { - MethodTable * pExceptionHandlingClauseMT = CoreLibBinder::GetClass(CLASS__RUNTIME_EH_CLAUSE); - TypeHandle thEHClauseArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pExceptionHandlingClauseMT), ELEMENT_TYPE_SZARRAY); + if (pILHeader) + { + MethodTable * pExceptionHandlingClauseMT = CoreLibBinder::GetClass(CLASS__RUNTIME_EH_CLAUSE); + TypeHandle thEHClauseArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pExceptionHandlingClauseMT), ELEMENT_TYPE_SZARRAY); - MethodTable * pLocalVariableMT = CoreLibBinder::GetClass(CLASS__RUNTIME_LOCAL_VARIABLE_INFO); - TypeHandle thLocalVariableArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pLocalVariableMT), ELEMENT_TYPE_SZARRAY); + MethodTable * pLocalVariableMT = CoreLibBinder::GetClass(CLASS__RUNTIME_LOCAL_VARIABLE_INFO); + TypeHandle thLocalVariableArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pLocalVariableMT), ELEMENT_TYPE_SZARRAY); - Module* pModule = pMethod->GetModule(); - COR_ILMETHOD_DECODER::DecoderStatus status; - COR_ILMETHOD_DECODER header(pILHeader, pModule->GetMDImport(), &status); + Module* pModule = pMethod->GetModule(); + COR_ILMETHOD_DECODER::DecoderStatus status; + COR_ILMETHOD_DECODER header(pILHeader, pModule->GetMDImport(), &status); - if (status != COR_ILMETHOD_DECODER::SUCCESS) - { - if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR) - { - // Throw a verification HR - COMPlusThrowHR(COR_E_VERIFICATION); - } - else + if (status != COR_ILMETHOD_DECODER::SUCCESS) { - COMPlusThrowHR(COR_E_BADIMAGEFORMAT); + if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR) + { + // Throw a verification HR + COMPlusThrowHR(COR_E_VERIFICATION); + } + else + { + COMPlusThrowHR(COR_E_BADIMAGEFORMAT); + } } - } - gc.MethodBodyObj = (RUNTIMEMETHODBODYREF)AllocateObject(CoreLibBinder::GetClass(CLASS__RUNTIME_METHOD_BODY)); + gc.MethodBodyObj = (RUNTIMEMETHODBODYREF)AllocateObject(CoreLibBinder::GetClass(CLASS__RUNTIME_METHOD_BODY)); - gc.MethodBodyObj->_maxStackSize = header.GetMaxStack(); - gc.MethodBodyObj->_initLocals = !!(header.GetFlags() & CorILMethod_InitLocals); + gc.MethodBodyObj->_maxStackSize = header.GetMaxStack(); + gc.MethodBodyObj->_initLocals = !!(header.GetFlags() & CorILMethod_InitLocals); - if (header.IsFat()) - gc.MethodBodyObj->_localVarSigToken = header.GetLocalVarSigTok(); - else - gc.MethodBodyObj->_localVarSigToken = 0; + if (header.IsFat()) + gc.MethodBodyObj->_localVarSigToken = header.GetLocalVarSigTok(); + else + gc.MethodBodyObj->_localVarSigToken = 0; - // Allocate the array of IL and fill it in from the method header. - BYTE* pIL = const_cast(header.Code); - COUNT_T cIL = header.GetCodeSize(); - gc.U1Array = (U1ARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_U1, cIL); + // Allocate the array of IL and fill it in from the method header. + BYTE* pIL = const_cast(header.Code); + COUNT_T cIL = header.GetCodeSize(); + gc.U1Array = (U1ARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_U1, cIL); - SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_IL, gc.U1Array); - memcpyNoGCRefs(gc.MethodBodyObj->_IL->GetDataPtr(), pIL, cIL); + SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_IL, gc.U1Array); + memcpyNoGCRefs(gc.MethodBodyObj->_IL->GetDataPtr(), pIL, cIL); - // Allocate the array of exception clauses. - INT32 cEh = (INT32)header.EHCount(); - const COR_ILMETHOD_SECT_EH* ehInfo = header.EH; - gc.TempArray = (BASEARRAYREF) AllocateSzArray(thEHClauseArray, cEh); + // Allocate the array of exception clauses. + INT32 cEh = (INT32)header.EHCount(); + const COR_ILMETHOD_SECT_EH* ehInfo = header.EH; + gc.TempArray = (BASEARRAYREF) AllocateSzArray(thEHClauseArray, cEh); - SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_exceptionClauses, gc.TempArray); + SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_exceptionClauses, gc.TempArray); - for (INT32 i = 0; i < cEh; i++) - { - COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff; - const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehClause = - (const COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)ehInfo->EHClause(i, &ehBuff); + for (INT32 i = 0; i < cEh; i++) + { + COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff; + const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehClause = + (const COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)ehInfo->EHClause(i, &ehBuff); - gc.EHClauseObj = (RUNTIMEEXCEPTIONHANDLINGCLAUSEREF) AllocateObject(pExceptionHandlingClauseMT); + gc.EHClauseObj = (RUNTIMEEXCEPTIONHANDLINGCLAUSEREF) AllocateObject(pExceptionHandlingClauseMT); - gc.EHClauseObj->_flags = ehClause->GetFlags(); - gc.EHClauseObj->_tryOffset = ehClause->GetTryOffset(); - gc.EHClauseObj->_tryLength = ehClause->GetTryLength(); - gc.EHClauseObj->_handlerOffset = ehClause->GetHandlerOffset(); - gc.EHClauseObj->_handlerLength = ehClause->GetHandlerLength(); + gc.EHClauseObj->_flags = ehClause->GetFlags(); + gc.EHClauseObj->_tryOffset = ehClause->GetTryOffset(); + gc.EHClauseObj->_tryLength = ehClause->GetTryLength(); + gc.EHClauseObj->_handlerOffset = ehClause->GetHandlerOffset(); + gc.EHClauseObj->_handlerLength = ehClause->GetHandlerLength(); - if ((ehClause->GetFlags() & COR_ILEXCEPTION_CLAUSE_FILTER) == 0) - gc.EHClauseObj->_catchToken = ehClause->GetClassToken(); - else - gc.EHClauseObj->_filterOffset = ehClause->GetFilterOffset(); + if ((ehClause->GetFlags() & COR_ILEXCEPTION_CLAUSE_FILTER) == 0) + gc.EHClauseObj->_catchToken = ehClause->GetClassToken(); + else + gc.EHClauseObj->_filterOffset = ehClause->GetFilterOffset(); - gc.MethodBodyObj->_exceptionClauses->SetAt(i, (OBJECTREF) gc.EHClauseObj); - SetObjectReference((OBJECTREF*)&(gc.EHClauseObj->_methodBody), (OBJECTREF)gc.MethodBodyObj); - } + gc.MethodBodyObj->_exceptionClauses->SetAt(i, (OBJECTREF) gc.EHClauseObj); + SetObjectReference((OBJECTREF*)&(gc.EHClauseObj->_methodBody), (OBJECTREF)gc.MethodBodyObj); + } - if (header.LocalVarSig != NULL) - { - SigTypeContext sigTypeContext(pMethod, declaringType, pMethod->LoadMethodInstantiation()); - MetaSig metaSig(header.LocalVarSig, - header.cbLocalVarSig, - pModule, - &sigTypeContext, - MetaSig::sigLocalVars); - INT32 cLocals = metaSig.NumFixedArgs(); - gc.TempArray = (BASEARRAYREF) AllocateSzArray(thLocalVariableArray, cLocals); - SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_localVariables, gc.TempArray); - - for (INT32 i = 0; i < cLocals; i ++) + if (header.LocalVarSig != NULL) { - gc.RuntimeLocalVariableInfoObj = (RUNTIMELOCALVARIABLEINFOREF)AllocateObject(pLocalVariableMT); + SigTypeContext sigTypeContext(pMethod, declaringType, pMethod->LoadMethodInstantiation()); + MetaSig metaSig(header.LocalVarSig, + header.cbLocalVarSig, + pModule, + &sigTypeContext, + MetaSig::sigLocalVars); + INT32 cLocals = metaSig.NumFixedArgs(); + gc.TempArray = (BASEARRAYREF) AllocateSzArray(thLocalVariableArray, cLocals); + SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_localVariables, gc.TempArray); + + for (INT32 i = 0; i < cLocals; i ++) + { + gc.RuntimeLocalVariableInfoObj = (RUNTIMELOCALVARIABLEINFOREF)AllocateObject(pLocalVariableMT); - gc.RuntimeLocalVariableInfoObj->_localIndex = i; + gc.RuntimeLocalVariableInfoObj->_localIndex = i; - metaSig.NextArg(); + metaSig.NextArg(); - CorElementType eType; - IfFailThrow(metaSig.GetArgProps().PeekElemType(&eType)); - if (ELEMENT_TYPE_PINNED == eType) - gc.RuntimeLocalVariableInfoObj->_isPinned = TRUE; + CorElementType eType; + IfFailThrow(metaSig.GetArgProps().PeekElemType(&eType)); + if (ELEMENT_TYPE_PINNED == eType) + gc.RuntimeLocalVariableInfoObj->_isPinned = TRUE; - TypeHandle tempType= metaSig.GetArgProps().GetTypeHandleThrowing(pModule, &sigTypeContext); - OBJECTREF refLocalType = tempType.GetManagedClassObject(); - gc.RuntimeLocalVariableInfoObj->SetType(refLocalType); - gc.MethodBodyObj->_localVariables->SetAt(i, (OBJECTREF) gc.RuntimeLocalVariableInfoObj); + TypeHandle tempType= metaSig.GetArgProps().GetTypeHandleThrowing(pModule, &sigTypeContext); + OBJECTREF refLocalType = tempType.GetManagedClassObject(); + gc.RuntimeLocalVariableInfoObj->SetType(refLocalType); + gc.MethodBodyObj->_localVariables->SetAt(i, (OBJECTREF) gc.RuntimeLocalVariableInfoObj); + } + } + else + { + INT32 cLocals = 0; + gc.TempArray = (BASEARRAYREF) AllocateSzArray(thLocalVariableArray, cLocals); + SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_localVariables, gc.TempArray); } - } - else - { - INT32 cLocals = 0; - gc.TempArray = (BASEARRAYREF) AllocateSzArray(thLocalVariableArray, cLocals); - SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_localVariables, gc.TempArray); } } + HELPER_METHOD_FRAME_END(); - result.Set(gc.MethodBodyObj); - - GCPROTECT_END(); - END_QCALL; + return (RuntimeMethodBody*)OBJECTREFToObject(gc.MethodBodyObj); } +FCIMPLEND FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsConstructor, MethodDesc *pMethod) { diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index 3d4e7cc4df161..227cf1e27f001 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -225,6 +225,9 @@ class RuntimeMethodHandle static FCDECL1(Object*, GetResolver, MethodDesc * pMethod); + + static FCDECL2(RuntimeMethodBody*, GetMethodBody, ReflectMethodObject *pMethodUNSAFE, PTR_ReflectClassBaseObject pDeclaringType); + static FCDECL1(FC_BOOL_RET, IsConstructor, MethodDesc *pMethod); static FCDECL1(Object*, GetLoaderAllocatorInternal, MethodDesc *pMethod); @@ -254,7 +257,6 @@ extern "C" void QCALLTYPE RuntimeMethodHandle_GetTypicalMethodDefinition(MethodD extern "C" void QCALLTYPE RuntimeMethodHandle_StripMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod); extern "C" void QCALLTYPE RuntimeMethodHandle_Destroy(MethodDesc * pMethod); extern "C" MethodDesc* QCALLTYPE RuntimeMethodHandle_GetStubIfNeededSlow(MethodDesc* pMethod, QCall::TypeHandle declaringTypeHandle, QCall::ObjectHandleOnStack methodInstantiation); -extern "C" void QCALLTYPE RuntimeMethodHandle_GetMethodBody(MethodDesc* pMethod, EnregisteredTypeHandle pDeclaringType, QCall::ObjectHandleOnStack result); class RuntimeFieldHandle { From 90ac98f10f2b504c1ef98f634b48ef0654e39624 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Wed, 11 Dec 2024 19:28:03 -0800 Subject: [PATCH 13/21] Update type definitions. --- src/coreclr/vm/runtimehandles.h | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index 227cf1e27f001..bd2b3e825fdab 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -41,14 +41,13 @@ typedef DPTR(RuntimeMethodBody) RUNTIMEMETHODBODYREF; typedef DPTR(RuntimeLocalVariableInfo) RUNTIMELOCALVARIABLEINFOREF; #endif -class RuntimeExceptionHandlingClause : Object +class RuntimeExceptionHandlingClause : public Object { -private: +public: // Disallow creation and copy construction of these. - RuntimeExceptionHandlingClause() { } - RuntimeExceptionHandlingClause(RuntimeExceptionHandlingClause &r) { } + RuntimeExceptionHandlingClause() = delete; + RuntimeExceptionHandlingClause(const RuntimeExceptionHandlingClause&) = delete; -public: RUNTIMEMETHODBODYREF _methodBody; CorExceptionFlag _flags; INT32 _tryOffset; @@ -61,12 +60,11 @@ class RuntimeExceptionHandlingClause : Object class RuntimeMethodBody : public Object { -private: +public: // Disallow creation and copy construction of these. - RuntimeMethodBody() { } - RuntimeMethodBody(RuntimeMethodBody &r) { } + RuntimeMethodBody() = delete; + RuntimeMethodBody(const RuntimeMethodBody&) = delete; -public: U1ARRAYREF _IL; PTRARRAYREF _exceptionClauses; PTRARRAYREF _localVariables; @@ -77,14 +75,12 @@ class RuntimeMethodBody : public Object CLR_BOOL _initLocals; }; -class RuntimeLocalVariableInfo : Object +class RuntimeLocalVariableInfo : public Object { -private: - // Disallow creation and copy construction of these. - RuntimeLocalVariableInfo() { } - RuntimeLocalVariableInfo(RuntimeLocalVariableInfo &r) { } - public: + // Disallow creation and copy construction of these. + RuntimeLocalVariableInfo() = delete; + RuntimeLocalVariableInfo(const RuntimeLocalVariableInfo&) = delete; REFLECTCLASSBASEREF GetType() { From 6b9bc4c8ded92b227511a53d0f40afacadb391e2 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Thu, 12 Dec 2024 07:44:51 -0800 Subject: [PATCH 14/21] Revert "Revert "Convert RuntimeMethodHandle.GetMethodBody() to QCall."" This reverts commit e5c288271954434d7b4ddcef2485f93fa8ef58ea. --- .../src/System/RuntimeHandles.cs | 13 +- src/coreclr/vm/ecalllist.h | 1 - src/coreclr/vm/qcallentrypoints.cpp | 1 + src/coreclr/vm/runtimehandles.cpp | 224 +++++++++--------- src/coreclr/vm/runtimehandles.h | 4 +- 5 files changed, 120 insertions(+), 123 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index ca75089e34ca6..a5ec37926af39 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -1321,8 +1321,17 @@ internal static IRuntimeMethodInfo StripMethodInstantiation(IRuntimeMethodInfo m [MethodImpl(MethodImplOptions.InternalCall)] internal static extern Resolver GetResolver(RuntimeMethodHandleInternal method); - [MethodImpl(MethodImplOptions.InternalCall)] - internal static extern RuntimeMethodBody? GetMethodBody(IRuntimeMethodInfo method, RuntimeType declaringType); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeMethodHandle_GetMethodBody")] + private static partial void GetMethodBody(RuntimeMethodHandleInternal method, nint declaringType, ObjectHandleOnStack result); + + internal static RuntimeMethodBody? GetMethodBody(IRuntimeMethodInfo method, RuntimeType declaringType) + { + RuntimeMethodBody? result = null; + GetMethodBody(method.Value, declaringType.GetUnderlyingNativeHandle(), ObjectHandleOnStack.Create(ref result)); + GC.KeepAlive(method); + GC.KeepAlive(declaringType); + return result; + } [MethodImpl(MethodImplOptions.InternalCall)] internal static extern bool IsConstructor(RuntimeMethodHandleInternal method); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 94872335cdc35..a7b3e34cb77c7 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -149,7 +149,6 @@ FCFuncStart(gRuntimeMethodHandle) FCFuncElement("GetStubIfNeededInternal", RuntimeMethodHandle::GetStubIfNeededInternal) FCFuncElement("GetMethodFromCanonical", RuntimeMethodHandle::GetMethodFromCanonical) FCFuncElement("IsDynamicMethod", RuntimeMethodHandle::IsDynamicMethod) - FCFuncElement("GetMethodBody", RuntimeMethodHandle::GetMethodBody) FCFuncElement("IsConstructor", RuntimeMethodHandle::IsConstructor) FCFuncElement("GetResolver", RuntimeMethodHandle::GetResolver) FCFuncElement("GetLoaderAllocatorInternal", RuntimeMethodHandle::GetLoaderAllocatorInternal) diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index bbe88931dd99a..0205c6a895d48 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -162,6 +162,7 @@ static const Entry s_QCall[] = DllImportEntry(RuntimeMethodHandle_IsCAVisibleFromDecoratedType) DllImportEntry(RuntimeMethodHandle_Destroy) DllImportEntry(RuntimeMethodHandle_GetStubIfNeededSlow) + DllImportEntry(RuntimeMethodHandle_GetMethodBody) DllImportEntry(RuntimeModule_GetScopeName) DllImportEntry(RuntimeModule_GetFullyQualifiedName) DllImportEntry(RuntimeModule_GetTypes) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 66c38479979d4..8c2b54ddcec76 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -2039,170 +2039,160 @@ FCIMPL2(MethodDesc*, RuntimeMethodHandle::GetMethodFromCanonical, MethodDesc *pM } FCIMPLEND - -FCIMPL2(RuntimeMethodBody *, RuntimeMethodHandle::GetMethodBody, ReflectMethodObject *pMethodUNSAFE, ReflectClassBaseObject *pDeclaringTypeUNSAFE) +extern "C" void QCALLTYPE RuntimeMethodHandle_GetMethodBody(MethodDesc* pMethod, EnregisteredTypeHandle pDeclaringType, QCall::ObjectHandleOnStack result) { - CONTRACTL - { - FCALL_CHECK; - } - CONTRACTL_END; + QCALL_CONTRACT; - struct _gc + _ASSERTE(pMethod != NULL); + + BEGIN_QCALL; + + GCX_COOP(); + + struct { RUNTIMEMETHODBODYREF MethodBodyObj; RUNTIMEEXCEPTIONHANDLINGCLAUSEREF EHClauseObj; RUNTIMELOCALVARIABLEINFOREF RuntimeLocalVariableInfoObj; - U1ARRAYREF U1Array; - BASEARRAYREF TempArray; - REFLECTCLASSBASEREF declaringType; - REFLECTMETHODREF refMethod; + U1ARRAYREF U1Array; + BASEARRAYREF TempArray; } gc; - gc.MethodBodyObj = NULL; gc.EHClauseObj = NULL; gc.RuntimeLocalVariableInfoObj = NULL; gc.U1Array = NULL; gc.TempArray = NULL; - gc.declaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE); - gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE); - - - if (!gc.refMethod) - FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle")); - - MethodDesc* pMethod = gc.refMethod->GetMethod(); + GCPROTECT_BEGIN(gc); - TypeHandle declaringType = gc.declaringType == NULL ? TypeHandle() : gc.declaringType->GetType(); + TypeHandle declaringType = TypeHandle::FromPtr(pDeclaringType); - if (!pMethod->IsIL()) - return NULL; - - HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc); + COR_ILMETHOD* pILHeader = NULL; + if (pMethod->IsIL()) { - MethodDesc *pMethodIL = pMethod; + MethodDesc* pMethodIL = pMethod; if (pMethod->IsWrapperStub()) pMethodIL = pMethod->GetWrappedMethodDesc(); - COR_ILMETHOD* pILHeader = pMethodIL->GetILHeader(); + pILHeader = pMethodIL->GetILHeader(); + } - if (pILHeader) - { - MethodTable * pExceptionHandlingClauseMT = CoreLibBinder::GetClass(CLASS__RUNTIME_EH_CLAUSE); - TypeHandle thEHClauseArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pExceptionHandlingClauseMT), ELEMENT_TYPE_SZARRAY); + if (pILHeader) + { + MethodTable * pExceptionHandlingClauseMT = CoreLibBinder::GetClass(CLASS__RUNTIME_EH_CLAUSE); + TypeHandle thEHClauseArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pExceptionHandlingClauseMT), ELEMENT_TYPE_SZARRAY); - MethodTable * pLocalVariableMT = CoreLibBinder::GetClass(CLASS__RUNTIME_LOCAL_VARIABLE_INFO); - TypeHandle thLocalVariableArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pLocalVariableMT), ELEMENT_TYPE_SZARRAY); + MethodTable * pLocalVariableMT = CoreLibBinder::GetClass(CLASS__RUNTIME_LOCAL_VARIABLE_INFO); + TypeHandle thLocalVariableArray = ClassLoader::LoadArrayTypeThrowing(TypeHandle(pLocalVariableMT), ELEMENT_TYPE_SZARRAY); - Module* pModule = pMethod->GetModule(); - COR_ILMETHOD_DECODER::DecoderStatus status; - COR_ILMETHOD_DECODER header(pILHeader, pModule->GetMDImport(), &status); + Module* pModule = pMethod->GetModule(); + COR_ILMETHOD_DECODER::DecoderStatus status; + COR_ILMETHOD_DECODER header(pILHeader, pModule->GetMDImport(), &status); - if (status != COR_ILMETHOD_DECODER::SUCCESS) + if (status != COR_ILMETHOD_DECODER::SUCCESS) + { + if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR) { - if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR) - { - // Throw a verification HR - COMPlusThrowHR(COR_E_VERIFICATION); - } - else - { - COMPlusThrowHR(COR_E_BADIMAGEFORMAT); - } + // Throw a verification HR + COMPlusThrowHR(COR_E_VERIFICATION); } + else + { + COMPlusThrowHR(COR_E_BADIMAGEFORMAT); + } + } - gc.MethodBodyObj = (RUNTIMEMETHODBODYREF)AllocateObject(CoreLibBinder::GetClass(CLASS__RUNTIME_METHOD_BODY)); + gc.MethodBodyObj = (RUNTIMEMETHODBODYREF)AllocateObject(CoreLibBinder::GetClass(CLASS__RUNTIME_METHOD_BODY)); - gc.MethodBodyObj->_maxStackSize = header.GetMaxStack(); - gc.MethodBodyObj->_initLocals = !!(header.GetFlags() & CorILMethod_InitLocals); + gc.MethodBodyObj->_maxStackSize = header.GetMaxStack(); + gc.MethodBodyObj->_initLocals = !!(header.GetFlags() & CorILMethod_InitLocals); - if (header.IsFat()) - gc.MethodBodyObj->_localVarSigToken = header.GetLocalVarSigTok(); - else - gc.MethodBodyObj->_localVarSigToken = 0; + if (header.IsFat()) + gc.MethodBodyObj->_localVarSigToken = header.GetLocalVarSigTok(); + else + gc.MethodBodyObj->_localVarSigToken = 0; - // Allocate the array of IL and fill it in from the method header. - BYTE* pIL = const_cast(header.Code); - COUNT_T cIL = header.GetCodeSize(); - gc.U1Array = (U1ARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_U1, cIL); + // Allocate the array of IL and fill it in from the method header. + BYTE* pIL = const_cast(header.Code); + COUNT_T cIL = header.GetCodeSize(); + gc.U1Array = (U1ARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_U1, cIL); - SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_IL, gc.U1Array); - memcpyNoGCRefs(gc.MethodBodyObj->_IL->GetDataPtr(), pIL, cIL); + SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_IL, gc.U1Array); + memcpyNoGCRefs(gc.MethodBodyObj->_IL->GetDataPtr(), pIL, cIL); - // Allocate the array of exception clauses. - INT32 cEh = (INT32)header.EHCount(); - const COR_ILMETHOD_SECT_EH* ehInfo = header.EH; - gc.TempArray = (BASEARRAYREF) AllocateSzArray(thEHClauseArray, cEh); + // Allocate the array of exception clauses. + INT32 cEh = (INT32)header.EHCount(); + const COR_ILMETHOD_SECT_EH* ehInfo = header.EH; + gc.TempArray = (BASEARRAYREF) AllocateSzArray(thEHClauseArray, cEh); - SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_exceptionClauses, gc.TempArray); + SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_exceptionClauses, gc.TempArray); - for (INT32 i = 0; i < cEh; i++) - { - COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff; - const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehClause = - (const COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)ehInfo->EHClause(i, &ehBuff); + for (INT32 i = 0; i < cEh; i++) + { + COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff; + const COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehClause = + (const COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)ehInfo->EHClause(i, &ehBuff); - gc.EHClauseObj = (RUNTIMEEXCEPTIONHANDLINGCLAUSEREF) AllocateObject(pExceptionHandlingClauseMT); + gc.EHClauseObj = (RUNTIMEEXCEPTIONHANDLINGCLAUSEREF) AllocateObject(pExceptionHandlingClauseMT); - gc.EHClauseObj->_flags = ehClause->GetFlags(); - gc.EHClauseObj->_tryOffset = ehClause->GetTryOffset(); - gc.EHClauseObj->_tryLength = ehClause->GetTryLength(); - gc.EHClauseObj->_handlerOffset = ehClause->GetHandlerOffset(); - gc.EHClauseObj->_handlerLength = ehClause->GetHandlerLength(); + gc.EHClauseObj->_flags = ehClause->GetFlags(); + gc.EHClauseObj->_tryOffset = ehClause->GetTryOffset(); + gc.EHClauseObj->_tryLength = ehClause->GetTryLength(); + gc.EHClauseObj->_handlerOffset = ehClause->GetHandlerOffset(); + gc.EHClauseObj->_handlerLength = ehClause->GetHandlerLength(); - if ((ehClause->GetFlags() & COR_ILEXCEPTION_CLAUSE_FILTER) == 0) - gc.EHClauseObj->_catchToken = ehClause->GetClassToken(); - else - gc.EHClauseObj->_filterOffset = ehClause->GetFilterOffset(); + if ((ehClause->GetFlags() & COR_ILEXCEPTION_CLAUSE_FILTER) == 0) + gc.EHClauseObj->_catchToken = ehClause->GetClassToken(); + else + gc.EHClauseObj->_filterOffset = ehClause->GetFilterOffset(); - gc.MethodBodyObj->_exceptionClauses->SetAt(i, (OBJECTREF) gc.EHClauseObj); - SetObjectReference((OBJECTREF*)&(gc.EHClauseObj->_methodBody), (OBJECTREF)gc.MethodBodyObj); - } + gc.MethodBodyObj->_exceptionClauses->SetAt(i, (OBJECTREF) gc.EHClauseObj); + SetObjectReference((OBJECTREF*)&(gc.EHClauseObj->_methodBody), (OBJECTREF)gc.MethodBodyObj); + } - if (header.LocalVarSig != NULL) + if (header.LocalVarSig != NULL) + { + SigTypeContext sigTypeContext(pMethod, declaringType, pMethod->LoadMethodInstantiation()); + MetaSig metaSig(header.LocalVarSig, + header.cbLocalVarSig, + pModule, + &sigTypeContext, + MetaSig::sigLocalVars); + INT32 cLocals = metaSig.NumFixedArgs(); + gc.TempArray = (BASEARRAYREF) AllocateSzArray(thLocalVariableArray, cLocals); + SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_localVariables, gc.TempArray); + + for (INT32 i = 0; i < cLocals; i ++) { - SigTypeContext sigTypeContext(pMethod, declaringType, pMethod->LoadMethodInstantiation()); - MetaSig metaSig(header.LocalVarSig, - header.cbLocalVarSig, - pModule, - &sigTypeContext, - MetaSig::sigLocalVars); - INT32 cLocals = metaSig.NumFixedArgs(); - gc.TempArray = (BASEARRAYREF) AllocateSzArray(thLocalVariableArray, cLocals); - SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_localVariables, gc.TempArray); - - for (INT32 i = 0; i < cLocals; i ++) - { - gc.RuntimeLocalVariableInfoObj = (RUNTIMELOCALVARIABLEINFOREF)AllocateObject(pLocalVariableMT); + gc.RuntimeLocalVariableInfoObj = (RUNTIMELOCALVARIABLEINFOREF)AllocateObject(pLocalVariableMT); - gc.RuntimeLocalVariableInfoObj->_localIndex = i; + gc.RuntimeLocalVariableInfoObj->_localIndex = i; - metaSig.NextArg(); + metaSig.NextArg(); - CorElementType eType; - IfFailThrow(metaSig.GetArgProps().PeekElemType(&eType)); - if (ELEMENT_TYPE_PINNED == eType) - gc.RuntimeLocalVariableInfoObj->_isPinned = TRUE; + CorElementType eType; + IfFailThrow(metaSig.GetArgProps().PeekElemType(&eType)); + if (ELEMENT_TYPE_PINNED == eType) + gc.RuntimeLocalVariableInfoObj->_isPinned = TRUE; - TypeHandle tempType= metaSig.GetArgProps().GetTypeHandleThrowing(pModule, &sigTypeContext); - OBJECTREF refLocalType = tempType.GetManagedClassObject(); - gc.RuntimeLocalVariableInfoObj->SetType(refLocalType); - gc.MethodBodyObj->_localVariables->SetAt(i, (OBJECTREF) gc.RuntimeLocalVariableInfoObj); - } - } - else - { - INT32 cLocals = 0; - gc.TempArray = (BASEARRAYREF) AllocateSzArray(thLocalVariableArray, cLocals); - SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_localVariables, gc.TempArray); + TypeHandle tempType= metaSig.GetArgProps().GetTypeHandleThrowing(pModule, &sigTypeContext); + OBJECTREF refLocalType = tempType.GetManagedClassObject(); + gc.RuntimeLocalVariableInfoObj->SetType(refLocalType); + gc.MethodBodyObj->_localVariables->SetAt(i, (OBJECTREF) gc.RuntimeLocalVariableInfoObj); } } + else + { + INT32 cLocals = 0; + gc.TempArray = (BASEARRAYREF) AllocateSzArray(thLocalVariableArray, cLocals); + SetObjectReference((OBJECTREF*)&gc.MethodBodyObj->_localVariables, gc.TempArray); + } } - HELPER_METHOD_FRAME_END(); - return (RuntimeMethodBody*)OBJECTREFToObject(gc.MethodBodyObj); + result.Set(gc.MethodBodyObj); + + GCPROTECT_END(); + END_QCALL; } -FCIMPLEND FCIMPL1(FC_BOOL_RET, RuntimeMethodHandle::IsConstructor, MethodDesc *pMethod) { diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index bd2b3e825fdab..5759e9bc71fe8 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -221,9 +221,6 @@ class RuntimeMethodHandle static FCDECL1(Object*, GetResolver, MethodDesc * pMethod); - - static FCDECL2(RuntimeMethodBody*, GetMethodBody, ReflectMethodObject *pMethodUNSAFE, PTR_ReflectClassBaseObject pDeclaringType); - static FCDECL1(FC_BOOL_RET, IsConstructor, MethodDesc *pMethod); static FCDECL1(Object*, GetLoaderAllocatorInternal, MethodDesc *pMethod); @@ -253,6 +250,7 @@ extern "C" void QCALLTYPE RuntimeMethodHandle_GetTypicalMethodDefinition(MethodD extern "C" void QCALLTYPE RuntimeMethodHandle_StripMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod); extern "C" void QCALLTYPE RuntimeMethodHandle_Destroy(MethodDesc * pMethod); extern "C" MethodDesc* QCALLTYPE RuntimeMethodHandle_GetStubIfNeededSlow(MethodDesc* pMethod, QCall::TypeHandle declaringTypeHandle, QCall::ObjectHandleOnStack methodInstantiation); +extern "C" void QCALLTYPE RuntimeMethodHandle_GetMethodBody(MethodDesc* pMethod, EnregisteredTypeHandle pDeclaringType, QCall::ObjectHandleOnStack result); class RuntimeFieldHandle { From 79a945416c9f916b23e4ced1f048ac6b3c59cd13 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Thu, 12 Dec 2024 07:59:40 -0800 Subject: [PATCH 15/21] Ensure the RuntimeMethodBody..ctor() isn't removed. Make FOR_ILLINK usage consistent in corlib.h. --- src/coreclr/vm/corelib.h | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 7a5fe8d99743b..4cdc069524c98 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -182,7 +182,7 @@ DEFINE_METHOD(COM_OBJECT, RELEASE_ALL_DATA, ReleaseAllData, DEFINE_METHOD(COM_OBJECT, GET_EVENT_PROVIDER, GetEventProvider, IM_Class_RetObj) #ifdef FOR_ILLINK DEFINE_METHOD(COM_OBJECT, CTOR, .ctor, IM_RetVoid) -#endif +#endif // FOR_ILLINK DEFINE_CLASS(LICENSE_INTEROP_PROXY, InternalInteropServices, LicenseInteropProxy) DEFINE_METHOD(LICENSE_INTEROP_PROXY, CREATE, Create, SM_RetObj) @@ -358,9 +358,9 @@ DEFINE_FIELD(RT_FIELD_INFO, HANDLE, m_fieldHandle) DEFINE_CLASS_U(System, RuntimeFieldInfoStub, ReflectFieldObject) DEFINE_FIELD_U(m_fieldHandle, ReflectFieldObject, m_pFD) DEFINE_CLASS(STUBFIELDINFO, System, RuntimeFieldInfoStub) -#if FOR_ILLINK +#ifdef FOR_ILLINK DEFINE_METHOD(STUBFIELDINFO, CTOR, .ctor, IM_RetVoid) -#endif +#endif // FOR_ILLINK DEFINE_CLASS(FIELD, Reflection, RuntimeFieldInfo) @@ -497,18 +497,18 @@ DEFINE_FIELD_U(_handlerLength, RuntimeExceptionHandlingClause, _h DEFINE_FIELD_U(_catchMetadataToken, RuntimeExceptionHandlingClause, _catchToken) DEFINE_FIELD_U(_filterOffset, RuntimeExceptionHandlingClause, _filterOffset) DEFINE_CLASS(RUNTIME_EH_CLAUSE, Reflection, RuntimeExceptionHandlingClause) -#if FOR_ILLINK +#ifdef FOR_ILLINK DEFINE_METHOD(RUNTIME_EH_CLAUSE, CTOR, .ctor, IM_RetVoid) -#endif +#endif // FOR_ILLINK DEFINE_CLASS_U(Reflection, RuntimeLocalVariableInfo, RuntimeLocalVariableInfo) DEFINE_FIELD_U(_type, RuntimeLocalVariableInfo, _type) DEFINE_FIELD_U(_localIndex, RuntimeLocalVariableInfo, _localIndex) DEFINE_FIELD_U(_isPinned, RuntimeLocalVariableInfo, _isPinned) DEFINE_CLASS(RUNTIME_LOCAL_VARIABLE_INFO, Reflection, RuntimeLocalVariableInfo) -#if FOR_ILLINK +#ifdef FOR_ILLINK DEFINE_METHOD(RUNTIME_LOCAL_VARIABLE_INFO, CTOR, .ctor, IM_RetVoid) -#endif +#endif // FOR_ILLINK DEFINE_CLASS_U(Reflection, RuntimeMethodBody, RuntimeMethodBody) DEFINE_FIELD_U(_IL, RuntimeMethodBody, _IL) @@ -518,7 +518,11 @@ DEFINE_FIELD_U(_methodBase, RuntimeMethodBody, _methodBase DEFINE_FIELD_U(_localSignatureMetadataToken, RuntimeMethodBody, _localVarSigToken) DEFINE_FIELD_U(_maxStackSize, RuntimeMethodBody, _maxStackSize) DEFINE_FIELD_U(_initLocals, RuntimeMethodBody, _initLocals) -DEFINE_CLASS(RUNTIME_METHOD_BODY, Reflection, RuntimeMethodBody) + +DEFINE_CLASS(RUNTIME_METHOD_BODY, Reflection, RuntimeMethodBody) +#ifdef FOR_ILLINK +DEFINE_METHOD(RUNTIME_METHOD_BODY, CTOR, .ctor, IM_RetVoid) +#endif // FOR_ILLINK DEFINE_CLASS(METHOD_INFO, Reflection, MethodInfo) From f39f202beeefaf4d0215e2fe0857466f636c1bf2 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Sun, 15 Dec 2024 13:11:38 -0800 Subject: [PATCH 16/21] Feedback 1 --- .../src/ILLink/ILLink.Descriptors.Shared.xml | 3 --- .../src/System/RuntimeHandles.cs | 27 ++++++++++++++----- src/coreclr/vm/corelib.h | 1 + src/coreclr/vm/runtimehandles.cpp | 25 +++-------------- src/coreclr/vm/runtimehandles.h | 19 ++++++------- 5 files changed, 34 insertions(+), 41 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml b/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml index d338a79c305ad..0c7a6d7e6259f 100644 --- a/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml +++ b/src/coreclr/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.Shared.xml @@ -9,9 +9,6 @@ - - - diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index a5ec37926af39..f00b258593593 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -667,6 +667,19 @@ internal static unsafe MdUtf8String GetUtf8Name(RuntimeType type) internal static bool CanCastTo(RuntimeType type, RuntimeType target) { + // See TypeHandle::CanCastToCached() for duplicate quick checks. + TypeHandle typeTH = type.GetNativeTypeHandle(); + TypeHandle targetTH = target.GetNativeTypeHandle(); + if (TypeHandle.AreSameType(typeTH, targetTH)) + { + return true; + } + + if (!typeTH.IsTypeDesc && targetTH.IsTypeDesc) + { + return false; + } + return CanCastToInternal(type, target) switch { CastResult.CanCast => true, @@ -1119,9 +1132,9 @@ internal static int GetMethodDef(IRuntimeMethodInfo method) { Debug.Assert(method != null); - int slot = GetMethodDef(method.Value); + int token = GetMethodDef(method.Value); GC.KeepAlive(method); - return slot; + return token; } internal static string GetName(RuntimeMethodHandleInternal method) @@ -1985,7 +1998,6 @@ private static partial void Init( RuntimeMethodHandleInternal methodHandle, IntPtr typeHandle); - [MemberNotNull(nameof(_declaringType))] [MemberNotNull(nameof(_returnTypeORfieldType))] private void Init( void* pCorSig, int cCorSig, @@ -1993,13 +2005,15 @@ private void Init( RuntimeMethodHandleInternal methodHandle) { Signature _this = this; - IntPtr typeHandle = _declaringType?.GetUnderlyingNativeHandle() ?? IntPtr.Zero; + + // Lifetime of typeHandle is extended since the RuntimeType is + // a member of Signature, whose lifetime is ensured below. + IntPtr typeHandle = _declaringType.GetUnderlyingNativeHandle(); Init(ObjectHandleOnStack.Create(ref _this), pCorSig, cCorSig, fieldHandle, methodHandle, typeHandle); - Debug.Assert(_declaringType != null); Debug.Assert(_returnTypeORfieldType != null); } @@ -2016,7 +2030,8 @@ public Signature( Debug.Assert((_managedCallingConventionAndArgIteratorFlags & 0xffffff00) == 0); _pMethod = methodHandle.Value; - Init(null, 0, default, methodHandle.Value); + _declaringType = RuntimeMethodHandle.GetDeclaringType(_pMethod); + Init(null, 0, default, _pMethod); GC.KeepAlive(methodHandle); } diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 4cdc069524c98..41b8b07733548 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -137,6 +137,7 @@ DEFINE_METHOD(ASSEMBLY, CTOR, .ctor, DEFINE_CLASS(ASYNCCALLBACK, System, AsyncCallback) DEFINE_CLASS(ATTRIBUTE, System, Attribute) +DEFINE_CLASS_U(System, Signature, SignatureNative) DEFINE_CLASS(BINDER, Reflection, Binder) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 8c2b54ddcec76..36ef3cd841ab0 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -1064,6 +1064,9 @@ extern "C" BOOL QCALLTYPE RuntimeTypeHandle_SatisfiesConstraints(QCall::TypeHand BEGIN_QCALL; + // Instantiation classInst = Instantiation{}; + // Instantiation methodInst = Instantiation{}; + Instantiation classInst = typeContextArgs != NULL ? Instantiation(typeContextArgs, typeContextCount) : Instantiation{}; @@ -1637,17 +1640,7 @@ FCIMPL1(INT32, RuntimeMethodHandle::GetMethodDef, MethodDesc* pMethod) { FCALL_CONTRACT; _ASSERTE(pMethod != NULL); - - if (pMethod->HasMethodInstantiation()) - pMethod = pMethod->StripMethodInstantiation(); - - INT32 tkMethodDef = (INT32)pMethod->GetMemberDef(); - _ASSERTE(TypeFromToken(tkMethodDef) == mdtMethodDef); - - if (IsNilToken(tkMethodDef) || TypeFromToken(tkMethodDef) != mdtMethodDef) - return mdMethodDefNil; - - return tkMethodDef; + return (INT32)pMethod->GetMemberDef(); } FCIMPLEND @@ -1672,15 +1665,6 @@ extern "C" void QCALLTYPE Signature_Init( GCPROTECT_BEGIN(gc); TypeHandle declType = TypeHandle::FromPtr(typeHandleRaw); - if (declType.IsNull()) - { - // Dynamic method case - _ASSERTE(pMethodDesc->IsDynamicMethod()); - declType = pMethodDesc->GetMethodTable(); - - REFLECTCLASSBASEREF refDeclType = (REFLECTCLASSBASEREF)declType.GetManagedClassObject(); - gc.pSig->SetDeclaringType(refDeclType); - } _ASSERTE(!declType.IsNull()); if (pMethodDesc != NULL) @@ -1751,7 +1735,6 @@ extern "C" void QCALLTYPE Signature_Init( } } - _ASSERTE(gc.pSig->m_declaringType != NULL); _ASSERTE(gc.pSig->m_returnType != NULL); GCPROTECT_END(); END_QCALL; diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index 5759e9bc71fe8..8f608b8c1fc94 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -11,7 +11,6 @@ #include "typectxt.h" typedef void* EnregisteredTypeHandle; -class SignatureNative; // NOTE: These are defined in CallingConventions.cs. typedef enum ReflectionCallConv { @@ -299,16 +298,6 @@ class AssemblyHandle extern "C" void QCALLTYPE AssemblyHandle_GetManifestModuleSlow(QCall::ObjectHandleOnStack assembly, QCall::ObjectHandleOnStack module); -class SignatureNative; - -typedef DPTR(SignatureNative) PTR_SignatureNative; - -#ifdef USE_CHECKED_OBJECTREFS -typedef REF SIGNATURENATIVEREF; -#else -typedef PTR_SignatureNative SIGNATURENATIVEREF; -#endif - extern "C" void QCALLTYPE Signature_Init( QCall::ObjectHandleOnStack sigObj, PCCOR_SIGNATURE pCorSig, DWORD cCorSig, @@ -514,6 +503,14 @@ class SignatureNative : public Object MethodDesc* m_pMethod; }; +typedef DPTR(SignatureNative) PTR_SignatureNative; + +#ifdef USE_CHECKED_OBJECTREFS +typedef REF SIGNATURENATIVEREF; +#else +typedef PTR_SignatureNative SIGNATURENATIVEREF; +#endif + class ReflectionPointer : public Object { public: From 448b19ee355925a70031d88c07adbb9d9a6f4ae5 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Sun, 15 Dec 2024 18:06:06 -0800 Subject: [PATCH 17/21] Feedback 2 --- .../src/System/RuntimeHandles.cs | 22 +++++++------------ .../src/System/RuntimeType.CoreCLR.cs | 22 +++++++------------ src/coreclr/vm/runtimehandles.cpp | 18 +++++++-------- src/coreclr/vm/runtimehandles.h | 2 +- 4 files changed, 25 insertions(+), 39 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index f00b258593593..60e862027ae5f 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -859,22 +859,16 @@ internal bool ContainsGenericVariables() } [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_SatisfiesConstraints")] - private static partial Interop.BOOL SatisfiesConstraints(QCallTypeHandle paramType, IntPtr* pTypeContext, int typeContextLength, IntPtr* pMethodContext, int methodContextLength, QCallTypeHandle toType); + private static partial Interop.BOOL SatisfiesConstraints(QCallTypeHandle paramType, nint pTypeContext, RuntimeMethodHandleInternal pMethodContext, QCallTypeHandle toType); - internal static bool SatisfiesConstraints(RuntimeType paramType, RuntimeType[]? typeContext, RuntimeType[]? methodContext, RuntimeType toType) + internal static bool SatisfiesConstraints(RuntimeType paramType, RuntimeType? typeContext, RuntimeMethodInfo? methodContext, RuntimeType toType) { - IntPtr[]? typeContextHandles = CopyRuntimeTypeHandles(typeContext, out int typeContextLength); - IntPtr[]? methodContextHandles = CopyRuntimeTypeHandles(methodContext, out int methodContextLength); - - fixed (IntPtr* pTypeContextHandles = typeContextHandles, pMethodContextHandles = methodContextHandles) - { - bool result = SatisfiesConstraints(new QCallTypeHandle(ref paramType), pTypeContextHandles, typeContextLength, pMethodContextHandles, methodContextLength, new QCallTypeHandle(ref toType)) != Interop.BOOL.FALSE; - - GC.KeepAlive(typeContext); - GC.KeepAlive(methodContext); - - return result; - } + IntPtr typeContextRaw = typeContext?.GetUnderlyingNativeHandle() ?? default; + RuntimeMethodHandleInternal methodContextRaw = ((IRuntimeMethodInfo?)methodContext)?.Value ?? RuntimeMethodHandleInternal.EmptyHandle; + bool result = SatisfiesConstraints(new QCallTypeHandle(ref paramType), typeContextRaw, methodContextRaw, new QCallTypeHandle(ref toType)) != Interop.BOOL.FALSE; + GC.KeepAlive(typeContext); + GC.KeepAlive(methodContext); + return result; } [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_RegisterCollectibleTypeDependency")] diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs index 9d51fd8e96731..ea88559efeceb 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs @@ -2011,29 +2011,23 @@ private static RuntimePropertyInfo GetPropertyInfo(RuntimeType reflectedType, in internal static void ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception? e) { - RuntimeType[]? typeContext = null; - RuntimeType[]? methodContext = null; + RuntimeType? typeContext; + RuntimeMethodInfo? methodContext = null; RuntimeType[] genericParameters; if (definition is Type) { - RuntimeType genericTypeDefinition = (RuntimeType)definition; - genericParameters = genericTypeDefinition.GetGenericArgumentsInternal(); - typeContext = genericArguments; + typeContext = (RuntimeType)definition; + genericParameters = typeContext.GetGenericArgumentsInternal(); } else { - RuntimeMethodInfo genericMethodDefinition = (RuntimeMethodInfo)definition; - genericParameters = genericMethodDefinition.GetGenericArgumentsInternal(); - methodContext = genericArguments; - - RuntimeType? declaringType = (RuntimeType?)genericMethodDefinition.DeclaringType; - if (declaringType != null) - { - typeContext = declaringType.TypeHandle.GetInstantiationInternal(); - } + methodContext = (RuntimeMethodInfo)definition; + typeContext = (RuntimeType?)methodContext.DeclaringType; + genericParameters = methodContext.GetGenericArgumentsInternal(); } + Debug.Assert(genericArguments.Length == genericParameters.Length); for (int i = 0; i < genericArguments.Length; i++) { Type genericArgument = genericArguments[i]; diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 36ef3cd841ab0..64c094b847f98 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -1050,13 +1050,13 @@ extern "C" BOOL QCALLTYPE RuntimeTypeHandle_CanCastToSlow(QCall::TypeHandle type return retVal; } -extern "C" BOOL QCALLTYPE RuntimeTypeHandle_SatisfiesConstraints(QCall::TypeHandle paramType, TypeHandle* typeContextArgs, INT32 typeContextCount, TypeHandle* methodContextArgs, INT32 methodContextCount, QCall::TypeHandle toType) +extern "C" BOOL QCALLTYPE RuntimeTypeHandle_SatisfiesConstraints(QCall::TypeHandle paramType, EnregisteredTypeHandle typeContext, MethodDesc* methodContext, QCall::TypeHandle toType) { CONTRACTL { QCALL_CHECK; - PRECONDITION(CheckPointer(typeContextArgs, NULL_OK)); - PRECONDITION(CheckPointer(methodContextArgs, NULL_OK)); + PRECONDITION(CheckPointer(typeContext, NULL_OK)); + PRECONDITION(CheckPointer(methodContext, NULL_OK)); } CONTRACTL_END; @@ -1064,14 +1064,12 @@ extern "C" BOOL QCALLTYPE RuntimeTypeHandle_SatisfiesConstraints(QCall::TypeHand BEGIN_QCALL; - // Instantiation classInst = Instantiation{}; - // Instantiation methodInst = Instantiation{}; - - Instantiation classInst = typeContextArgs != NULL - ? Instantiation(typeContextArgs, typeContextCount) + TypeHandle typeHandle = TypeHandle::FromPtr(typeContext); + Instantiation classInst = !typeHandle.IsNull() + ? typeHandle.GetMethodTable()->GetInstantiation() : Instantiation{}; - Instantiation methodInst = methodContextArgs != NULL - ? Instantiation(methodContextArgs, methodContextCount) + Instantiation methodInst = methodContext != NULL + ? methodContext->GetMethodInstantiation() : Instantiation{}; SigTypeContext typeContext; diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index 8f608b8c1fc94..e097ea51670d7 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -171,7 +171,7 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_ConstructName(QCall::TypeHandle pTyp extern "C" void QCALLTYPE RuntimeTypeHandle_GetInterfaces(MethodTable* pMT, QCall::ObjectHandleOnStack result); extern "C" BOOL QCALLTYPE RuntimeTypeHandle_IsVisible(QCall::TypeHandle pTypeHandle); extern "C" BOOL QCALLTYPE RuntimeTypeHandle_CanCastToSlow(QCall::TypeHandle type, QCall::TypeHandle target); -extern "C" BOOL QCALLTYPE RuntimeTypeHandle_SatisfiesConstraints(QCall::TypeHandle paramType, TypeHandle* typeContextArgs, INT32 typeContextCount, TypeHandle* methodContextArgs, INT32 methodContextCount, QCall::TypeHandle toType); +extern "C" BOOL QCALLTYPE RuntimeTypeHandle_SatisfiesConstraints(QCall::TypeHandle paramType, EnregisteredTypeHandle typeContext, MethodDesc* methodContext, QCall::TypeHandle toType); extern "C" void QCALLTYPE RuntimeTypeHandle_GetInstantiation(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType, BOOL fAsRuntimeTypeArray); extern "C" void QCALLTYPE RuntimeTypeHandle_Instantiate(QCall::TypeHandle pTypeHandle, TypeHandle * pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack retType); extern "C" void QCALLTYPE RuntimeTypeHandle_GetGenericTypeDefinition(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType); From 4317d9f122c4a6f1d2152a78883579c25b2c16a9 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Sun, 15 Dec 2024 21:45:59 -0800 Subject: [PATCH 18/21] Feedback --- .../RuntimeHelpers.CoreCLR.cs | 25 +++-- .../src/System/RuntimeHandles.cs | 40 +++---- src/coreclr/vm/ecalllist.h | 1 - src/coreclr/vm/runtimehandles.cpp | 103 +++++++++--------- src/coreclr/vm/runtimehandles.h | 83 ++++++-------- 5 files changed, 113 insertions(+), 139 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs index 3bb984f14e7d6..b8bb205f5b217 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs @@ -1101,18 +1101,25 @@ public static TypeHandle TypeHandleOf() [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool CanCastTo(TypeHandle destTH) { - if (m_asTAddr == destTH.m_asTAddr) - return true; - - if (!IsTypeDesc && destTH.IsTypeDesc) - return false; + return TryCanCastTo(this, destTH) switch + { + CastResult.CanCast => true, + CastResult.CannotCast => false, + _ => CanCastTo_NoCacheLookup(m_asTAddr, destTH.m_asTAddr) + }; + } - CastResult result = CastCache.TryGet(CastHelpers.s_table!, (nuint)m_asTAddr, (nuint)destTH.m_asTAddr); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static CastResult TryCanCastTo(TypeHandle srcTH, TypeHandle destTH) + { + // See TypeHandle::CanCastToCached() for duplicate quick checks. + if (srcTH.m_asTAddr == destTH.m_asTAddr) + return CastResult.CanCast; - if (result != CastResult.MaybeCast) - return result == CastResult.CanCast; + if (!srcTH.IsTypeDesc && destTH.IsTypeDesc) + return CastResult.CannotCast; - return CanCastTo_NoCacheLookup(m_asTAddr, destTH.m_asTAddr); + return CastCache.TryGet(CastHelpers.s_table!, (nuint)srcTH.m_asTAddr, (nuint)destTH.m_asTAddr); } public int GetCorElementType() => GetCorElementType(m_asTAddr); diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index 60e862027ae5f..ccf59c4ee3634 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -659,28 +659,14 @@ internal static unsafe MdUtf8String GetUtf8Name(RuntimeType type) return new MdUtf8String(name); } - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern CastResult CanCastToInternal(RuntimeType type, RuntimeType target); - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_CanCastToSlow")] private static partial Interop.BOOL CanCastToSlow(QCallTypeHandle type1, QCallTypeHandle type2); internal static bool CanCastTo(RuntimeType type, RuntimeType target) { - // See TypeHandle::CanCastToCached() for duplicate quick checks. TypeHandle typeTH = type.GetNativeTypeHandle(); TypeHandle targetTH = target.GetNativeTypeHandle(); - if (TypeHandle.AreSameType(typeTH, targetTH)) - { - return true; - } - - if (!typeTH.IsTypeDesc && targetTH.IsTypeDesc) - { - return false; - } - - return CanCastToInternal(type, target) switch + return TypeHandle.TryCanCastTo(typeTH, targetTH) switch { CastResult.CanCast => true, CastResult.CannotCast => false, @@ -1329,14 +1315,13 @@ internal static IRuntimeMethodInfo StripMethodInstantiation(IRuntimeMethodInfo m internal static extern Resolver GetResolver(RuntimeMethodHandleInternal method); [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeMethodHandle_GetMethodBody")] - private static partial void GetMethodBody(RuntimeMethodHandleInternal method, nint declaringType, ObjectHandleOnStack result); + private static partial void GetMethodBody(RuntimeMethodHandleInternal method, QCallTypeHandle declaringType, ObjectHandleOnStack result); internal static RuntimeMethodBody? GetMethodBody(IRuntimeMethodInfo method, RuntimeType declaringType) { RuntimeMethodBody? result = null; - GetMethodBody(method.Value, declaringType.GetUnderlyingNativeHandle(), ObjectHandleOnStack.Create(ref result)); + GetMethodBody(method.Value, new QCallTypeHandle(ref declaringType), ObjectHandleOnStack.Create(ref result)); GC.KeepAlive(method); - GC.KeepAlive(declaringType); return result; } @@ -1989,8 +1974,7 @@ private static partial void Init( ObjectHandleOnStack _this, void* pCorSig, int cCorSig, RuntimeFieldHandleInternal fieldHandle, - RuntimeMethodHandleInternal methodHandle, - IntPtr typeHandle); + RuntimeMethodHandleInternal methodHandle); [MemberNotNull(nameof(_returnTypeORfieldType))] private void Init( @@ -1999,15 +1983,10 @@ private void Init( RuntimeMethodHandleInternal methodHandle) { Signature _this = this; - - // Lifetime of typeHandle is extended since the RuntimeType is - // a member of Signature, whose lifetime is ensured below. - IntPtr typeHandle = _declaringType.GetUnderlyingNativeHandle(); Init(ObjectHandleOnStack.Create(ref _this), pCorSig, cCorSig, fieldHandle, - methodHandle, - typeHandle); + methodHandle); Debug.Assert(_returnTypeORfieldType != null); } @@ -2052,7 +2031,14 @@ public Signature(void* pCorSig, int cCorSig, RuntimeType declaringType) #region Internal Members internal CallingConventions CallingConvention => (CallingConventions)(_managedCallingConventionAndArgIteratorFlags & 0xff); - internal RuntimeType[] Arguments => _arguments ?? []; + internal RuntimeType[] Arguments + { + get + { + Debug.Assert(_arguments != null); + return _arguments; + } + } internal RuntimeType ReturnType => _returnTypeORfieldType; internal RuntimeType FieldType => _returnTypeORfieldType; diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index a7b3e34cb77c7..a782ae05d2d41 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -92,7 +92,6 @@ FCFuncStart(gCOMTypeHandleFuncs) FCFuncElement("GetUtf8NameInternal", RuntimeTypeHandle::GetUtf8Name) FCFuncElement("GetAttributes", RuntimeTypeHandle::GetAttributes) FCFuncElement("GetNumVirtuals", RuntimeTypeHandle::GetNumVirtuals) - FCFuncElement("CanCastToInternal", RuntimeTypeHandle::CanCastToInternal) FCFuncElement("GetGenericVariableIndex", RuntimeTypeHandle::GetGenericVariableIndex) FCFuncElement("IsGenericVariable", RuntimeTypeHandle::IsGenericVariable) FCFuncElement("ContainsGenericVariables", RuntimeTypeHandle::ContainsGenericVariables) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index 64c094b847f98..a31810f488f6b 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -996,18 +996,6 @@ extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHa return (EnregisteredTypeHandle)retTypeHandle.AsTAddr(); } -FCIMPL2(TypeHandle::CastResult, RuntimeTypeHandle::CanCastToInternal, ReflectClassBaseObject *pTypeUNSAFE, ReflectClassBaseObject *pTargetUNSAFE) -{ - FCALL_CONTRACT; - - REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE); - REFLECTCLASSBASEREF refTarget = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTargetUNSAFE); - TypeHandle fromHandle = refType->GetType(); - TypeHandle toHandle = refTarget->GetType(); - return fromHandle.CanCastToCached(toHandle); -} -FCIMPLEND - extern "C" BOOL QCALLTYPE RuntimeTypeHandle_CanCastToSlow(QCall::TypeHandle type, QCall::TypeHandle target) { QCALL_CONTRACT; @@ -1646,8 +1634,7 @@ extern "C" void QCALLTYPE Signature_Init( QCall::ObjectHandleOnStack sigObj, PCCOR_SIGNATURE pCorSig, DWORD cCorSig, FieldDesc* pFieldDesc, - MethodDesc* pMethodDesc, - EnregisteredTypeHandle typeHandleRaw) + MethodDesc* pMethodDesc) { QCALL_CONTRACT; @@ -1662,7 +1649,7 @@ extern "C" void QCALLTYPE Signature_Init( gc.pSig = (SIGNATURENATIVEREF)sigObj.Get(); GCPROTECT_BEGIN(gc); - TypeHandle declType = TypeHandle::FromPtr(typeHandleRaw); + TypeHandle declType = gc.pSig->GetDeclaringType(); _ASSERTE(!declType.IsNull()); if (pMethodDesc != NULL) @@ -1681,59 +1668,67 @@ extern "C" void QCALLTYPE Signature_Init( } _ASSERTE(pCorSig != NULL && cCorSig > 0); - gc.pSig->m_sig = pCorSig; - gc.pSig->m_cSig = cCorSig; - gc.pSig->m_pMethod = pMethodDesc; + gc.pSig->_sig = pCorSig; + gc.pSig->_csig = cCorSig; + gc.pSig->_pMethod = pMethodDesc; - uint32_t callConv; - if (FAILED(CorSigUncompressCallingConv(pCorSig, cCorSig, &callConv))) - COMPlusThrow(kBadImageFormatException); - - SigTypeContext typeContext; - if (pMethodDesc != NULL) + // Initialize _returnTypeORfieldType and _arguments if they were not initialized yet + if (gc.pSig->_returnTypeORfieldType != NULL) { - SigTypeContext::InitTypeContext( - pMethodDesc, declType.GetClassOrArrayInstantiation(), pMethodDesc->LoadMethodInstantiation(), &typeContext); + _ASSERTE(gc.pSig->_arguments != NULL); } else { - SigTypeContext::InitTypeContext(declType, &typeContext); - } + uint32_t callConv; + if (FAILED(CorSigUncompressCallingConv(pCorSig, cCorSig, &callConv))) + COMPlusThrow(kBadImageFormatException); + + SigTypeContext typeContext; + if (pMethodDesc != NULL) + { + SigTypeContext::InitTypeContext( + pMethodDesc, declType.GetClassOrArrayInstantiation(), pMethodDesc->LoadMethodInstantiation(), &typeContext); + } + else + { + SigTypeContext::InitTypeContext(declType, &typeContext); + } - Module* pModule = declType.GetModule(); - MetaSig msig(pCorSig, cCorSig, pModule, &typeContext, - (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember); + Module* pModule = declType.GetModule(); + MetaSig msig(pCorSig, cCorSig, pModule, &typeContext, + (callConv & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_FIELD ? MetaSig::sigField : MetaSig::sigMember); - if (callConv == IMAGE_CEE_CS_CALLCONV_FIELD) - { - msig.NextArgNormalized(); + if (callConv == IMAGE_CEE_CS_CALLCONV_FIELD) + { + msig.NextArgNormalized(); - OBJECTREF refRetType = msig.GetLastTypeHandleThrowing().GetManagedClassObject(); - gc.pSig->SetReturnType(refRetType); - } - else if (pMethodDesc == NULL || !pMethodDesc->IsDynamicMethod()) - { - gc.pSig->SetCallingConvention(msig.GetCallingConventionInfo()); + OBJECTREF refRetType = msig.GetLastTypeHandleThrowing().GetManagedClassObject(); + gc.pSig->SetReturnType(refRetType); + } + else + { + gc.pSig->SetCallingConvention(msig.GetCallingConventionInfo()); - OBJECTREF refRetType = msig.GetRetTypeHandleThrowing().GetManagedClassObject(); - gc.pSig->SetReturnType(refRetType); + OBJECTREF refRetType = msig.GetRetTypeHandleThrowing().GetManagedClassObject(); + gc.pSig->SetReturnType(refRetType); - INT32 nArgs = msig.NumFixedArgs(); - TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY); + INT32 nArgs = msig.NumFixedArgs(); + TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY); - PTRARRAYREF ptrArrayarguments = (PTRARRAYREF) AllocateSzArray(arrayHandle, nArgs); - gc.pSig->SetArgumentArray(ptrArrayarguments); + PTRARRAYREF ptrArrayarguments = (PTRARRAYREF) AllocateSzArray(arrayHandle, nArgs); + gc.pSig->SetArgumentArray(ptrArrayarguments); - for (INT32 i = 0; i < nArgs; i++) - { - msig.NextArg(); + for (INT32 i = 0; i < nArgs; i++) + { + msig.NextArg(); - OBJECTREF refArgType = msig.GetLastTypeHandleThrowing().GetManagedClassObject(); - gc.pSig->SetArgument(i, refArgType); + OBJECTREF refArgType = msig.GetLastTypeHandleThrowing().GetManagedClassObject(); + gc.pSig->SetArgument(i, refArgType); + } } } - _ASSERTE(gc.pSig->m_returnType != NULL); + _ASSERTE(gc.pSig->_returnTypeORfieldType != NULL); GCPROTECT_END(); END_QCALL; } @@ -2020,7 +2015,7 @@ FCIMPL2(MethodDesc*, RuntimeMethodHandle::GetMethodFromCanonical, MethodDesc *pM } FCIMPLEND -extern "C" void QCALLTYPE RuntimeMethodHandle_GetMethodBody(MethodDesc* pMethod, EnregisteredTypeHandle pDeclaringType, QCall::ObjectHandleOnStack result) +extern "C" void QCALLTYPE RuntimeMethodHandle_GetMethodBody(MethodDesc* pMethod, QCall::TypeHandle pDeclaringType, QCall::ObjectHandleOnStack result) { QCALL_CONTRACT; @@ -2045,7 +2040,7 @@ extern "C" void QCALLTYPE RuntimeMethodHandle_GetMethodBody(MethodDesc* pMethod, gc.TempArray = NULL; GCPROTECT_BEGIN(gc); - TypeHandle declaringType = TypeHandle::FromPtr(pDeclaringType); + TypeHandle declaringType = pDeclaringType.AsTypeHandle(); COR_ILMETHOD* pILHeader = NULL; if (pMethod->IsIL()) diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index e097ea51670d7..9c48cdd6770c4 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -249,7 +249,7 @@ extern "C" void QCALLTYPE RuntimeMethodHandle_GetTypicalMethodDefinition(MethodD extern "C" void QCALLTYPE RuntimeMethodHandle_StripMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack refMethod); extern "C" void QCALLTYPE RuntimeMethodHandle_Destroy(MethodDesc * pMethod); extern "C" MethodDesc* QCALLTYPE RuntimeMethodHandle_GetStubIfNeededSlow(MethodDesc* pMethod, QCall::TypeHandle declaringTypeHandle, QCall::ObjectHandleOnStack methodInstantiation); -extern "C" void QCALLTYPE RuntimeMethodHandle_GetMethodBody(MethodDesc* pMethod, EnregisteredTypeHandle pDeclaringType, QCall::ObjectHandleOnStack result); +extern "C" void QCALLTYPE RuntimeMethodHandle_GetMethodBody(MethodDesc* pMethod, QCall::TypeHandle pDeclaringType, QCall::ObjectHandleOnStack result); class RuntimeFieldHandle { @@ -302,8 +302,7 @@ extern "C" void QCALLTYPE Signature_Init( QCall::ObjectHandleOnStack sigObj, PCCOR_SIGNATURE pCorSig, DWORD cCorSig, FieldDesc* pFieldDesc, - MethodDesc* pMethodDesc, - EnregisteredTypeHandle typeHandleRaw); + MethodDesc* pMethodDesc); extern "C" BOOL QCALLTYPE Signature_AreEqual( PCCOR_SIGNATURE sig1, INT32 cSig1, QCall::TypeHandle handle1, @@ -321,8 +320,7 @@ class SignatureNative : public Object QCall::ObjectHandleOnStack sigObj, PCCOR_SIGNATURE pCorSig, DWORD cCorSig, FieldDesc* pFieldDesc, - MethodDesc* pMethodDesc, - EnregisteredTypeHandle typeHandleRaw); + MethodDesc* pMethodDesc); friend class ArgIteratorForMethodInvoke; public: @@ -332,8 +330,8 @@ class SignatureNative : public Object static FCDECL3(INT32, GetCallingConventionFromFunctionPointerAtOffsetInternal, PCCOR_SIGNATURE sig, DWORD csig, INT32 offset); - BOOL HasThis() { LIMITED_METHOD_CONTRACT; return (m_managedCallingConvention & CALLCONV_HasThis); } - INT32 NumFixedArgs() { WRAPPER_NO_CONTRACT; return m_PtrArrayarguments->GetNumComponents(); } + BOOL HasThis() { LIMITED_METHOD_CONTRACT; return (_managedCallingConventionAndArgIteratorFlags & CALLCONV_HasThis); } + INT32 NumFixedArgs() { WRAPPER_NO_CONTRACT; return _arguments->GetNumComponents(); } TypeHandle GetReturnTypeHandle() { CONTRACTL { @@ -343,11 +341,11 @@ class SignatureNative : public Object } CONTRACTL_END; - return ((REFLECTCLASSBASEREF)m_returnType)->GetType(); + return ((REFLECTCLASSBASEREF)_returnTypeORfieldType)->GetType(); } - PCCOR_SIGNATURE GetCorSig() { LIMITED_METHOD_CONTRACT; return m_sig; } - DWORD GetCorSigSize() { LIMITED_METHOD_CONTRACT; return m_cSig; } + PCCOR_SIGNATURE GetCorSig() { LIMITED_METHOD_CONTRACT; return _sig; } + DWORD GetCorSigSize() { LIMITED_METHOD_CONTRACT; return _csig; } Module* GetModule() { WRAPPER_NO_CONTRACT; return GetDeclaringType().GetModule(); } TypeHandle GetArgumentAt(INT32 position) @@ -359,31 +357,31 @@ class SignatureNative : public Object } CONTRACTL_END; - REFLECTCLASSBASEREF refArgument = (REFLECTCLASSBASEREF)m_PtrArrayarguments->GetAt(position); + REFLECTCLASSBASEREF refArgument = (REFLECTCLASSBASEREF)_arguments->GetAt(position); return refArgument->GetType(); } DWORD GetArgIteratorFlags() { LIMITED_METHOD_CONTRACT; - return VolatileLoad(&m_managedCallingConvention) >> CALLCONV_ArgIteratorFlags_Shift; + return VolatileLoad(&_managedCallingConventionAndArgIteratorFlags) >> CALLCONV_ArgIteratorFlags_Shift; } INT32 GetSizeOfArgStack() { LIMITED_METHOD_CONTRACT; - return m_nSizeOfArgStack; + return _nSizeOfArgStack; } TypeHandle GetDeclaringType() { LIMITED_METHOD_CONTRACT; - return m_declaringType->GetType(); + return _declaringType->GetType(); } MethodDesc* GetMethod() { LIMITED_METHOD_CONTRACT; - return m_pMethod; + return _pMethod; } const SigTypeContext * GetTypeContext(SigTypeContext *pTypeContext) @@ -396,9 +394,9 @@ class SignatureNative : public Object } CONTRACTL_END; - _ASSERTE(m_pMethod || !GetDeclaringType().IsNull()); - if (m_pMethod) - return SigTypeContext::GetOptionalTypeContext(m_pMethod, GetDeclaringType(), pTypeContext); + _ASSERTE(_pMethod || !GetDeclaringType().IsNull()); + if (_pMethod) + return SigTypeContext::GetOptionalTypeContext(_pMethod, GetDeclaringType(), pTypeContext); else return SigTypeContext::GetOptionalTypeContext(GetDeclaringType(), pTypeContext); } @@ -412,7 +410,7 @@ class SignatureNative : public Object MODE_COOPERATIVE; } CONTRACTL_END; - SetObjectReference(&m_returnType, returnType); + SetObjectReference(&_returnTypeORfieldType, returnType); } void SetKeepAlive(OBJECTREF keepAlive) @@ -423,18 +421,7 @@ class SignatureNative : public Object MODE_COOPERATIVE; } CONTRACTL_END; - SetObjectReference(&m_keepalive, keepAlive); - } - - void SetDeclaringType(REFLECTCLASSBASEREF declaringType) - { - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - SetObjectReference((OBJECTREF*)&m_declaringType, (OBJECTREF)declaringType); + SetObjectReference(&_keepAlive, keepAlive); } void SetArgumentArray(PTRARRAYREF ptrArrayarguments) @@ -445,7 +432,7 @@ class SignatureNative : public Object MODE_COOPERATIVE; } CONTRACTL_END; - SetObjectReference((OBJECTREF*)&m_PtrArrayarguments, (OBJECTREF)ptrArrayarguments); + SetObjectReference((OBJECTREF*)&_arguments, (OBJECTREF)ptrArrayarguments); } void SetArgument(INT32 argument, OBJECTREF argumentType) @@ -457,19 +444,19 @@ class SignatureNative : public Object } CONTRACTL_END; - m_PtrArrayarguments->SetAt(argument, argumentType); + _arguments->SetAt(argument, argumentType); } void SetArgIteratorFlags(DWORD flags) { LIMITED_METHOD_CONTRACT; - return VolatileStore(&m_managedCallingConvention, (INT32)(m_managedCallingConvention | (flags << CALLCONV_ArgIteratorFlags_Shift))); + return VolatileStore(&_managedCallingConventionAndArgIteratorFlags, (INT32)(_managedCallingConventionAndArgIteratorFlags | (flags << CALLCONV_ArgIteratorFlags_Shift))); } void SetSizeOfArgStack(INT32 nSizeOfArgStack) { LIMITED_METHOD_CONTRACT; - m_nSizeOfArgStack = nSizeOfArgStack; + _nSizeOfArgStack = nSizeOfArgStack; } void SetCallingConvention(INT32 mdCallingConvention) @@ -477,30 +464,30 @@ class SignatureNative : public Object LIMITED_METHOD_CONTRACT; if ((mdCallingConvention & IMAGE_CEE_CS_CALLCONV_MASK) == IMAGE_CEE_CS_CALLCONV_VARARG) - m_managedCallingConvention = CALLCONV_VarArgs; + _managedCallingConventionAndArgIteratorFlags = CALLCONV_VarArgs; else - m_managedCallingConvention = CALLCONV_Standard; + _managedCallingConventionAndArgIteratorFlags = CALLCONV_Standard; if ((mdCallingConvention & IMAGE_CEE_CS_CALLCONV_HASTHIS) != 0) - m_managedCallingConvention |= CALLCONV_HasThis; + _managedCallingConventionAndArgIteratorFlags |= CALLCONV_HasThis; if ((mdCallingConvention & IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS) != 0) - m_managedCallingConvention |= CALLCONV_ExplicitThis; + _managedCallingConventionAndArgIteratorFlags |= CALLCONV_ExplicitThis; } // Mirrored in the managed world (System.Signature) // // this is the layout the classloader chooses by default for the managed struct. // - PTRARRAYREF m_PtrArrayarguments; - REFLECTCLASSBASEREF m_declaringType; - OBJECTREF m_returnType; - OBJECTREF m_keepalive; - PCCOR_SIGNATURE m_sig; - DWORD m_cSig; - INT32 m_managedCallingConvention; - INT32 m_nSizeOfArgStack; - MethodDesc* m_pMethod; + PTRARRAYREF _arguments; + REFLECTCLASSBASEREF _declaringType; + OBJECTREF _returnTypeORfieldType; + OBJECTREF _keepAlive; + PCCOR_SIGNATURE _sig; + DWORD _csig; + INT32 _managedCallingConventionAndArgIteratorFlags; + INT32 _nSizeOfArgStack; + MethodDesc* _pMethod; }; typedef DPTR(SignatureNative) PTR_SignatureNative; From 908b7f438912f5d644d9902d0d02e2eb4884f5f2 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Mon, 16 Dec 2024 08:56:27 -0800 Subject: [PATCH 19/21] Update RuntimeTypeHandle_SatisfiesConstraints signature. --- .../System.Private.CoreLib/src/System/RuntimeHandles.cs | 6 ++---- src/coreclr/vm/runtimehandles.cpp | 5 ++--- src/coreclr/vm/runtimehandles.h | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index ccf59c4ee3634..d7914e94599d7 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -845,14 +845,12 @@ internal bool ContainsGenericVariables() } [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_SatisfiesConstraints")] - private static partial Interop.BOOL SatisfiesConstraints(QCallTypeHandle paramType, nint pTypeContext, RuntimeMethodHandleInternal pMethodContext, QCallTypeHandle toType); + private static partial Interop.BOOL SatisfiesConstraints(QCallTypeHandle paramType, QCallTypeHandle pTypeContext, RuntimeMethodHandleInternal pMethodContext, QCallTypeHandle toType); internal static bool SatisfiesConstraints(RuntimeType paramType, RuntimeType? typeContext, RuntimeMethodInfo? methodContext, RuntimeType toType) { - IntPtr typeContextRaw = typeContext?.GetUnderlyingNativeHandle() ?? default; RuntimeMethodHandleInternal methodContextRaw = ((IRuntimeMethodInfo?)methodContext)?.Value ?? RuntimeMethodHandleInternal.EmptyHandle; - bool result = SatisfiesConstraints(new QCallTypeHandle(ref paramType), typeContextRaw, methodContextRaw, new QCallTypeHandle(ref toType)) != Interop.BOOL.FALSE; - GC.KeepAlive(typeContext); + bool result = SatisfiesConstraints(new QCallTypeHandle(ref paramType), new QCallTypeHandle(ref typeContext!), methodContextRaw, new QCallTypeHandle(ref toType)) != Interop.BOOL.FALSE; GC.KeepAlive(methodContext); return result; } diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index a31810f488f6b..e8187587f032d 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -1038,12 +1038,11 @@ extern "C" BOOL QCALLTYPE RuntimeTypeHandle_CanCastToSlow(QCall::TypeHandle type return retVal; } -extern "C" BOOL QCALLTYPE RuntimeTypeHandle_SatisfiesConstraints(QCall::TypeHandle paramType, EnregisteredTypeHandle typeContext, MethodDesc* methodContext, QCall::TypeHandle toType) +extern "C" BOOL QCALLTYPE RuntimeTypeHandle_SatisfiesConstraints(QCall::TypeHandle paramType, QCall::TypeHandle typeContext, MethodDesc* methodContext, QCall::TypeHandle toType) { CONTRACTL { QCALL_CHECK; - PRECONDITION(CheckPointer(typeContext, NULL_OK)); PRECONDITION(CheckPointer(methodContext, NULL_OK)); } CONTRACTL_END; @@ -1052,7 +1051,7 @@ extern "C" BOOL QCALLTYPE RuntimeTypeHandle_SatisfiesConstraints(QCall::TypeHand BEGIN_QCALL; - TypeHandle typeHandle = TypeHandle::FromPtr(typeContext); + TypeHandle typeHandle = typeContext.AsTypeHandle(); Instantiation classInst = !typeHandle.IsNull() ? typeHandle.GetMethodTable()->GetInstantiation() : Instantiation{}; diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index 9c48cdd6770c4..79cea880bae61 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -171,7 +171,7 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_ConstructName(QCall::TypeHandle pTyp extern "C" void QCALLTYPE RuntimeTypeHandle_GetInterfaces(MethodTable* pMT, QCall::ObjectHandleOnStack result); extern "C" BOOL QCALLTYPE RuntimeTypeHandle_IsVisible(QCall::TypeHandle pTypeHandle); extern "C" BOOL QCALLTYPE RuntimeTypeHandle_CanCastToSlow(QCall::TypeHandle type, QCall::TypeHandle target); -extern "C" BOOL QCALLTYPE RuntimeTypeHandle_SatisfiesConstraints(QCall::TypeHandle paramType, EnregisteredTypeHandle typeContext, MethodDesc* methodContext, QCall::TypeHandle toType); +extern "C" BOOL QCALLTYPE RuntimeTypeHandle_SatisfiesConstraints(QCall::TypeHandle paramType, QCall::TypeHandle typeContext, MethodDesc* methodContext, QCall::TypeHandle toType); extern "C" void QCALLTYPE RuntimeTypeHandle_GetInstantiation(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType, BOOL fAsRuntimeTypeArray); extern "C" void QCALLTYPE RuntimeTypeHandle_Instantiate(QCall::TypeHandle pTypeHandle, TypeHandle * pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack retType); extern "C" void QCALLTYPE RuntimeTypeHandle_GetGenericTypeDefinition(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType); From 0f5ac4fc1b2aee4cecfac3ab536537465b5abd78 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Mon, 16 Dec 2024 13:33:09 -0800 Subject: [PATCH 20/21] Move more CanCastTo to managed. --- .../Runtime/CompilerServices/CastHelpers.cs | 2 +- .../RuntimeHelpers.CoreCLR.cs | 37 +++++++++++++--- .../src/System/RuntimeHandles.cs | 19 ++------- src/coreclr/vm/comutilnative.cpp | 5 --- src/coreclr/vm/qcallentrypoints.cpp | 1 - src/coreclr/vm/runtimehandles.cpp | 42 ------------------- src/coreclr/vm/runtimehandles.h | 1 - 7 files changed, 36 insertions(+), 71 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs index 6e89f50a1ea29..fad67c99946a9 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs @@ -539,7 +539,7 @@ private static bool AreTypesEquivalent(MethodTable* pMTa, MethodTable* pMTb) [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool IsNullableForType(MethodTable* typeMT, MethodTable* boxedMT) + internal static bool IsNullableForType(MethodTable* typeMT, MethodTable* boxedMT) { if (!typeMT->IsNullable) { diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs index b8bb205f5b217..b02703bdea1b5 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs @@ -1098,6 +1098,8 @@ public static TypeHandle TypeHandleOf() public static bool AreSameType(TypeHandle left, TypeHandle right) => left.m_asTAddr == right.m_asTAddr; + public int GetCorElementType() => GetCorElementType(m_asTAddr); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool CanCastTo(TypeHandle destTH) { @@ -1105,12 +1107,38 @@ public bool CanCastTo(TypeHandle destTH) { CastResult.CanCast => true, CastResult.CannotCast => false, - _ => CanCastTo_NoCacheLookup(m_asTAddr, destTH.m_asTAddr) + _ => CanCastTo_NoCacheLookup(m_asTAddr, destTH.m_asTAddr) != Interop.BOOL.FALSE }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static CastResult TryCanCastTo(TypeHandle srcTH, TypeHandle destTH) + public static bool CanCastToForReflection(TypeHandle srcTH, TypeHandle destTH) + { + return TryCanCastTo(srcTH, destTH) switch + { + CastResult.CanCast => true, + CastResult.CannotCast => false, + _ => CanCastToForReflectionWorker(srcTH, destTH) + }; + + [MethodImpl(MethodImplOptions.NoInlining)] + static bool CanCastToForReflectionWorker(TypeHandle srcTH, TypeHandle destTH) + { + // Reflection allows T to be cast to Nullable + // see TypeHandle::CanCastTo and ObjIsInstanceOfCore + if (!srcTH.IsTypeDesc + && !destTH.IsTypeDesc + && CastHelpers.IsNullableForType(destTH.AsMethodTable(), srcTH.AsMethodTable())) + { + return true; + } + + return CanCastTo_NoCacheLookup(srcTH.m_asTAddr, destTH.m_asTAddr) != Interop.BOOL.FALSE; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static CastResult TryCanCastTo(TypeHandle srcTH, TypeHandle destTH) { // See TypeHandle::CanCastToCached() for duplicate quick checks. if (srcTH.m_asTAddr == destTH.m_asTAddr) @@ -1122,11 +1150,8 @@ public static CastResult TryCanCastTo(TypeHandle srcTH, TypeHandle destTH) return CastCache.TryGet(CastHelpers.s_table!, (nuint)srcTH.m_asTAddr, (nuint)destTH.m_asTAddr); } - public int GetCorElementType() => GetCorElementType(m_asTAddr); - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "TypeHandle_CanCastTo_NoCacheLookup")] - [return: MarshalAs(UnmanagedType.Bool)] - private static partial bool CanCastTo_NoCacheLookup(void* fromTypeHnd, void* toTypeHnd); + private static partial Interop.BOOL CanCastTo_NoCacheLookup(void* fromTypeHnd, void* toTypeHnd); [SuppressGCTransition] [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "TypeHandle_GetCorElementType")] diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs index d7914e94599d7..3246c90a35f47 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs @@ -659,23 +659,12 @@ internal static unsafe MdUtf8String GetUtf8Name(RuntimeType type) return new MdUtf8String(name); } - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_CanCastToSlow")] - private static partial Interop.BOOL CanCastToSlow(QCallTypeHandle type1, QCallTypeHandle type2); - internal static bool CanCastTo(RuntimeType type, RuntimeType target) { - TypeHandle typeTH = type.GetNativeTypeHandle(); - TypeHandle targetTH = target.GetNativeTypeHandle(); - return TypeHandle.TryCanCastTo(typeTH, targetTH) switch - { - CastResult.CanCast => true, - CastResult.CannotCast => false, - _ => CanCastToWorker(type, target) - }; - - [MethodImpl(MethodImplOptions.NoInlining)] - static bool CanCastToWorker(RuntimeType type1, RuntimeType type2) - => CanCastToSlow(new QCallTypeHandle(ref type1), new QCallTypeHandle(ref type2)) != Interop.BOOL.FALSE; + bool ret = TypeHandle.CanCastToForReflection(type.GetNativeTypeHandle(), target.GetNativeTypeHandle()); + GC.KeepAlive(type); + GC.KeepAlive(target); + return ret; } [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable")] diff --git a/src/coreclr/vm/comutilnative.cpp b/src/coreclr/vm/comutilnative.cpp index 37839a496aa91..fff8e59962db2 100644 --- a/src/coreclr/vm/comutilnative.cpp +++ b/src/coreclr/vm/comutilnative.cpp @@ -1861,11 +1861,6 @@ extern "C" BOOL QCALLTYPE TypeHandle_CanCastTo_NoCacheLookup(void* fromTypeHnd, { ret = fromTH.AsTypeDesc()->CanCastTo(toTH, NULL); } - else if (Nullable::IsNullableForType(toTH, fromTH.AsMethodTable())) - { - // do not allow type T to be cast to Nullable - ret = FALSE; - } else { ret = fromTH.AsMethodTable()->CanCastTo(toTH.AsMethodTable(), NULL); diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 0205c6a895d48..b257af27bcfde 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -133,7 +133,6 @@ static const Entry s_QCall[] = DllImportEntry(RuntimeTypeHandle_IsVisible) DllImportEntry(RuntimeTypeHandle_ConstructName) DllImportEntry(RuntimeTypeHandle_GetInterfaces) - DllImportEntry(RuntimeTypeHandle_CanCastToSlow) DllImportEntry(RuntimeTypeHandle_SatisfiesConstraints) DllImportEntry(RuntimeTypeHandle_GetInstantiation) DllImportEntry(RuntimeTypeHandle_Instantiate) diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp index e8187587f032d..b016f70ba60dc 100644 --- a/src/coreclr/vm/runtimehandles.cpp +++ b/src/coreclr/vm/runtimehandles.cpp @@ -996,48 +996,6 @@ extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHa return (EnregisteredTypeHandle)retTypeHandle.AsTAddr(); } -extern "C" BOOL QCALLTYPE RuntimeTypeHandle_CanCastToSlow(QCall::TypeHandle type, QCall::TypeHandle target) -{ - QCALL_CONTRACT; - - BOOL retVal = FALSE; - - BEGIN_QCALL; - - TypeHandle fromHandle = type.AsTypeHandle(); - TypeHandle toHandle = target.AsTypeHandle(); - - // We allow T to be cast to Nullable - if (!fromHandle.IsTypeDesc() - && Nullable::IsNullableForType(toHandle, fromHandle.AsMethodTable())) - { - // do not put this in the cache (see TypeHandle::CanCastTo and ObjIsInstanceOfCore). - retVal = TRUE; - } - else - { - GCX_COOP(); - - if (fromHandle.IsTypeDesc()) - { - retVal = fromHandle.AsTypeDesc()->CanCastTo(toHandle, /* pVisited */ NULL); - } - else if (toHandle.IsTypeDesc()) - { - retVal = FALSE; - CastCache::TryAddToCache(fromHandle, toHandle, FALSE); - } - else - { - retVal = fromHandle.AsMethodTable()->CanCastTo(toHandle.AsMethodTable(), /* pVisited */ NULL); - } - } - - END_QCALL; - - return retVal; -} - extern "C" BOOL QCALLTYPE RuntimeTypeHandle_SatisfiesConstraints(QCall::TypeHandle paramType, QCall::TypeHandle typeContext, MethodDesc* methodContext, QCall::TypeHandle toType) { CONTRACTL diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h index 79cea880bae61..dd549987bb9fe 100644 --- a/src/coreclr/vm/runtimehandles.h +++ b/src/coreclr/vm/runtimehandles.h @@ -170,7 +170,6 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_PrepareMemberInfoCache(QCall::TypeHa extern "C" void QCALLTYPE RuntimeTypeHandle_ConstructName(QCall::TypeHandle pTypeHandle, DWORD format, QCall::StringHandleOnStack retString); extern "C" void QCALLTYPE RuntimeTypeHandle_GetInterfaces(MethodTable* pMT, QCall::ObjectHandleOnStack result); extern "C" BOOL QCALLTYPE RuntimeTypeHandle_IsVisible(QCall::TypeHandle pTypeHandle); -extern "C" BOOL QCALLTYPE RuntimeTypeHandle_CanCastToSlow(QCall::TypeHandle type, QCall::TypeHandle target); extern "C" BOOL QCALLTYPE RuntimeTypeHandle_SatisfiesConstraints(QCall::TypeHandle paramType, QCall::TypeHandle typeContext, MethodDesc* methodContext, QCall::TypeHandle toType); extern "C" void QCALLTYPE RuntimeTypeHandle_GetInstantiation(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType, BOOL fAsRuntimeTypeArray); extern "C" void QCALLTYPE RuntimeTypeHandle_Instantiate(QCall::TypeHandle pTypeHandle, TypeHandle * pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack retType); From f8c105c078bd868b2c33bc1b52f7edaae05ebda4 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Mon, 16 Dec 2024 16:05:55 -0800 Subject: [PATCH 21/21] Feedback --- .../RuntimeHelpers.CoreCLR.cs | 38 ++++++++++--------- src/coreclr/vm/jithelpers.cpp | 2 +- src/coreclr/vm/jitinterface.h | 1 - 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs index b02703bdea1b5..994cb70b5079b 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs @@ -1107,7 +1107,10 @@ public bool CanCastTo(TypeHandle destTH) { CastResult.CanCast => true, CastResult.CannotCast => false, - _ => CanCastTo_NoCacheLookup(m_asTAddr, destTH.m_asTAddr) != Interop.BOOL.FALSE + + // Regular casting does not allow T to be cast to Nullable. + // See TypeHandle::CanCastTo() + _ => CanCastToWorker(this, destTH, nullableCast: false) }; } @@ -1118,23 +1121,11 @@ public static bool CanCastToForReflection(TypeHandle srcTH, TypeHandle destTH) { CastResult.CanCast => true, CastResult.CannotCast => false, - _ => CanCastToForReflectionWorker(srcTH, destTH) - }; - [MethodImpl(MethodImplOptions.NoInlining)] - static bool CanCastToForReflectionWorker(TypeHandle srcTH, TypeHandle destTH) - { - // Reflection allows T to be cast to Nullable - // see TypeHandle::CanCastTo and ObjIsInstanceOfCore - if (!srcTH.IsTypeDesc - && !destTH.IsTypeDesc - && CastHelpers.IsNullableForType(destTH.AsMethodTable(), srcTH.AsMethodTable())) - { - return true; - } - - return CanCastTo_NoCacheLookup(srcTH.m_asTAddr, destTH.m_asTAddr) != Interop.BOOL.FALSE; - } + // Reflection allows T to be cast to Nullable. + // See ObjIsInstanceOfCore() + _ => CanCastToWorker(srcTH, destTH, nullableCast: true) + }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1150,6 +1141,19 @@ private static CastResult TryCanCastTo(TypeHandle srcTH, TypeHandle destTH) return CastCache.TryGet(CastHelpers.s_table!, (nuint)srcTH.m_asTAddr, (nuint)destTH.m_asTAddr); } + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool CanCastToWorker(TypeHandle srcTH, TypeHandle destTH, bool nullableCast) + { + if (!srcTH.IsTypeDesc + && !destTH.IsTypeDesc + && CastHelpers.IsNullableForType(destTH.AsMethodTable(), srcTH.AsMethodTable())) + { + return nullableCast; + } + + return CanCastTo_NoCacheLookup(srcTH.m_asTAddr, destTH.m_asTAddr) != Interop.BOOL.FALSE; + } + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "TypeHandle_CanCastTo_NoCacheLookup")] private static partial Interop.BOOL CanCastTo_NoCacheLookup(void* fromTypeHnd, void* toTypeHnd); diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index 5289f1e46ebc0..3d582b87e78f6 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -701,7 +701,7 @@ HCIMPLEND_RAW // //======================================================================== -BOOL ObjIsInstanceOfCore(Object *pObject, TypeHandle toTypeHnd, BOOL throwCastException) +static BOOL ObjIsInstanceOfCore(Object *pObject, TypeHandle toTypeHnd, BOOL throwCastException) { CONTRACTL { THROWS; diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 71012b72649d1..ecbd3adc76652 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -1045,7 +1045,6 @@ FCDECL2(Object*, JIT_Box, CORINFO_CLASS_HANDLE type, void* data); FCDECL0(VOID, JIT_PollGC); BOOL ObjIsInstanceOf(Object *pObject, TypeHandle toTypeHnd, BOOL throwCastException = FALSE); -BOOL ObjIsInstanceOfCore(Object* pObject, TypeHandle toTypeHnd, BOOL throwCastException = FALSE); #ifdef HOST_64BIT class InlinedCallFrame;