From fffc08ee0fcda04c7ba087b22d3b522edcb59de5 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Wed, 11 Dec 2024 13:09:20 -0800 Subject: [PATCH] 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 ca75089e34ca65..a5ec37926af399 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 1feb35ee358d48..39154055db712e 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 ed557aecddf7e7..1e79b4729b05ef 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 66c38479979d45..8c2b54ddcec76e 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 f747e42ed2ee31..fa6b4015b496ef 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 {