This issue tracks the work to replace MethodDescCallSite / CallDescrWorker infrastructure with more efficient UnmanagedCallersOnly reverse P/Invoke calls for invoking managed code from native code.
Benefits
- Significantly reduced overhead for VM-to-managed calls
- Uses existing reverse P/Invoke infrastructure instead of the expensive
CallDescrWorker mechanism
- Better alignment with modern interop patterns
Pattern
The conversion pattern involves:
- Adding
[UnmanagedCallersOnly] wrappers to managed methods with an Exception* out-parameter
- Using the
UnmanagedCallersOnlyCaller template class in C++ to invoke these methods
- Updating
metasig.h and corelib.h with appropriate signatures
Notes
- The
UnmanagedCallersOnlyCaller template class is defined in callhelpers.h and can be used to invoke the target.
- WASM builds require regenerating
callhelpers-reverse.cpp when adding new UCO methods.
Example PR to follow: #123832
Conversion Tasks
Priority 1: Cross-Platform, Simple Conversions
These are straightforward conversions on code paths that run on all platforms.
AppDomain / Assembly Loading (appdomain.cpp) - #123967
Loader Allocator (loaderallocator.cpp) - #124303
Custom Marshaler (custommarshalerinfo.cpp) - #124440
Dynamic Methods / Resolver (dynamicmethod.cpp) - #124303
Interop Utilities (interoputil.cpp) - #124303
Threads / Culture (threads.cpp) - #124303
Event Sources (corhost.cpp) - #124303
Diagnostics (ds-rt-coreclr.h) - #124303
Priority 2: Cross-Platform, Exception Handling
Exception Construction (clrex.cpp) - #126061
Exception Construction (excep.cpp) - #124834
Exception Utilities (excep.cpp) - #124834
Exception Info Retrieval (comutilnative.cpp) - #123986
Priority 3: Cross-Platform, Entry Points (Complex)
These are entry points or thread-related and require careful consideration.
Application Entry Points (assembly.cpp)
Process Lifecycle (appdomain.cpp) - #124854
Invoke / Reflection (invokeutil.cpp) - #124854
Host Callbacks (corhost.cpp) - #126222
Exception handling
Runtime threads
Reflection Invoke and similar
Priority 4: Platform-Specific (ObjC - macOS/iOS)
ObjC Interop (interoplibinterface_objc.cpp) - #124446
Priority 5: Windows-Only (COM Interop)
These files are only compiled on Windows and are lowest priority.
COM Connection Points (comconnectionpoints.cpp) - #123864
Standard Interfaces (stdinterfaces.cpp) - #123864
CLR to COM Calls (clrtocomcall.cpp)
COM Callable Wrapper (comcallablewrapper.cpp) - #123864
Custom Marshaler (custommarshalerinfo.cpp) - #125326
Runtime Callable Wrapper (runtimecallablewrapper.cpp)
OLE Variant (olevariant.cpp) - #125326
Dispatch Info (dispatchinfo.cpp) - ~30 call sites - #126074
Various reflection-based calls in:
Follow up cleanup
This issue tracks the work to replace
MethodDescCallSite/CallDescrWorkerinfrastructure with more efficientUnmanagedCallersOnlyreverse P/Invoke calls for invoking managed code from native code.Benefits
CallDescrWorkermechanismPattern
The conversion pattern involves:
[UnmanagedCallersOnly]wrappers to managed methods with anException*out-parameterUnmanagedCallersOnlyCallertemplate class in C++ to invoke these methodsmetasig.handcorelib.hwith appropriate signaturesNotes
UnmanagedCallersOnlyCallertemplate class is defined incallhelpers.hand can be used to invoke the target.callhelpers-reverse.cppwhen adding new UCO methods.Example PR to follow: #123832
Conversion Tasks
Priority 1: Cross-Platform, Simple Conversions
These are straightforward conversions on code paths that run on all platforms.
AppDomain / Assembly Loading (
appdomain.cpp) - #123967METHOD__ASSEMBLYLOADCONTEXT__ON_ASSEMBLY_LOADinAppDomain::RaiseAssemblyLoadEventMETHOD__ASSEMBLYLOADCONTEXT__ON_TYPE_RESOLVEinAppDomain::RaiseTypeResolveEventThrowingMETHOD__ASSEMBLYLOADCONTEXT__ON_RESOURCE_RESOLVEinAppDomain::RaiseResourceResolveEventMETHOD__ASSEMBLYLOADCONTEXT__ON_ASSEMBLY_RESOLVEinAppDomain::RaiseAssemblyResolveEventMETHOD__ASSEMBLYLOADCONTEXT__RESOLVEinAppDomain::BindAssemblySpecMETHOD__ASSEMBLYLOADCONTEXT__RESOLVESATELLITEASSEMBLYinAppDomain::BindSatelliteResourceByResourceRootsMETHOD__ASSEMBLYLOADCONTEXT__RESOLVEUSINGEVENTinAppDomain::RaiseLoadFileEventLoader Allocator (
loaderallocator.cpp) - #124303METHOD__LOADERALLOCATOR__CTORinLoaderAllocator::InitCustom Marshaler (
custommarshalerinfo.cpp) - #124440GetCustomMarshalermethod lookup inCustomMarshalerInfo::CustomMarshalerInfoDynamic Methods / Resolver (
dynamicmethod.cpp) - #124303METHOD__RESOLVER__GET_JIT_CONTEXTinLCGMethodResolver::GetJitContextMETHOD__RESOLVER__GET_CODE_INFOinLCGMethodResolver::GetCodeInfoMETHOD__RESOLVER__GET_LOCALS_SIGNATUREinLCGMethodResolver::GetLocalSigMETHOD__RESOLVER__GET_STRING_LITERALinLCGMethodResolver::GetStringLiteralInterop Utilities (
interoputil.cpp) - #124303METHOD__CULTURE_INFO__INT_CTORinGetCultureInfoForLCIDMETHOD__COLORMARSHALER__CONVERT_TO_MANAGEDinConvertOleColorToSystemColorMETHOD__COLORMARSHALER__CONVERT_TO_NATIVEinConvertSystemColorToOleColorThreads / Culture (
threads.cpp) - #124303METHOD__CULTURE_INFO__GET_CURRENT_CULTURE/METHOD__CULTURE_INFO__GET_CURRENT_UI_CULTUREinThread::GetCultureInfoMETHOD__CULTURE_INFO__SET_CURRENT_CULTURE/METHOD__CULTURE_INFO__SET_CURRENT_UI_CULTUREinThread::SetCultureInfoEvent Sources (
corhost.cpp) - #124303METHOD__EVENT_SOURCE__INITIALIZE_DEFAULT_EVENT_SOURCESinCorHost2::CreateAppDomainDiagnostics (
ds-rt-coreclr.h) - #124303METHOD__STARTUP_HOOK_PROVIDER__CALL_STARTUP_HOOKinds_rt_apply_startup_hookPriority 2: Cross-Platform, Exception Handling
Exception Construction (
clrex.cpp) - #126061EEException::CreateThrowableEEMessageException::CreateThrowableEEResourceException::CreateThrowableException Construction (
excep.cpp) - #124834METHOD__RUNTIME_WRAPPED_EXCEPTION__OBJ_CTORinWrapThrowableInRuntimeWrappedExceptionCreateTypeInitializationExceptionObjectException Utilities (
excep.cpp) - #124834METHOD__OBJECT__TO_STRINGinGetExceptionMessageMETHOD__EXCEPTION__INTERNAL_PRESERVE_STACK_TRACEinRaiseTheExceptionInternalOnlyMETHOD__ENVIRONMENT__GET_RESOURCE_STRING_LOCALinGetResourceStringFromManagedExceptionNotifications::DeliverExceptionNotificationException Info Retrieval (
comutilnative.cpp) - #123986METHOD__EXCEPTION__GET_MESSAGEinExceptionNative::GetMessageFromExceptionMETHOD__EXCEPTION__GET_CLASS_NAMEinExceptionNative::GetMessageFromExceptionMETHOD__EXCEPTION__GET_SOURCEinExceptionNative::GetSourceMETHOD__EXCEPTION__GET_HELP_CONTEXTinExceptionNative::GetHelpContextPriority 3: Cross-Platform, Entry Points (Complex)
These are entry points or thread-related and require careful consideration.
Application Entry Points (
assembly.cpp)RunMainInternal- Convert MethodDescCallSite to UCO in entrypoints #126222METHOD__STARTUP_HOOK_PROVIDER__MANAGED_STARTUPinAssembly::ExecuteMainMethod- Convert priority 3 MethodDescCallSite calls to UnmanagedCallersOnly #124854Process Lifecycle (
appdomain.cpp) - #124854METHOD__APPCONTEXT__ON_UNHANDLED_EXCEPTIONinAppDomain::RaiseUnhandledExceptionEventMETHOD__APPCONTEXT__ON_PROCESS_EXITinAppDomain::RaiseExitProcessEventInvoke / Reflection (
invokeutil.cpp) - #124854InvokeUtil::CreateObjectInvokeUtil::CreateValueTypeHost Callbacks (
corhost.cpp) - #126222CorHost2::ExecuteAssemblyException handling
ThrowExin DispatchManagedExceptionRethrowinDispatchRethrownManagedExceptionRuntime threads
FinalizerThread::FinalizeAllObjectsKickOffThread_WorkerReflection Invoke and similar
RuntimeMethodHandle_InvokeMethodCOMCustomAttribute::CreateCaObjectFuncEvalWrapper()andDoNormalFuncEval()Priority 4: Platform-Specific (ObjC - macOS/iOS)
ObjC Interop (
interoplibinterface_objc.cpp) - #124446METHOD__OBJCMARSHAL__AVAILABLEUNHANDLEDEXCEPTIONPROPAGATIONinObjCMarshalNative::GetPropagatingExceptionCallbackPriority 5: Windows-Only (COM Interop)
These files are only compiled on Windows and are lowest priority.
COM Connection Points (
comconnectionpoints.cpp) - #123864ConnectionPoint::AdviseConnectionPoint::AdviseStandard Interfaces (
stdinterfaces.cpp) - #123864CanReadproperty getter inIDispatchExInfo::GetIDsOfNamesCanWriteproperty getter inIDispatchExInfo::GetIDsOfNamesCLR to COM Calls (
clrtocomcall.cpp)METHOD__COM_OBJECT__GET_EVENT_PROVIDERinComPlusMethodFrame::DoSlowPathComPlusCall- Convert some COM interop to UCO #125326METHOD__CLASS__FORWARD_CALL_TO_INVOKEinCLRToCOMLateBoundWorker- Convert some COM interop to UCO #125326CLRToCOMEventCallWorkerCOM Callable Wrapper (
comcallablewrapper.cpp) - #123864ICustomQueryInterface::GetInterfaceinComCallWrapper::CallICustomQueryInterfaceCustom Marshaler (
custommarshalerinfo.cpp) - #125326METHOD__STUBHELPERS__GET_IENUMERATOR_TO_ENUM_VARIANT_MARSHALERinCustomMarshalerInfo::GetIEnumeratorToEnumVariantMarshalerRuntime Callable Wrapper (
runtimecallablewrapper.cpp)METHOD__LICENSE_INTEROP_PROXY__CREATEinLicenseInteropHelper::GetCurrentContextInfo- Revert "Partially revert PR #125326: revert ComActivator/LicenseInter… #126141METHOD__LICENSE_INTEROP_PROXY__GETCURRENTCONTEXTINFOinLicenseInteropHelper::GetCurrentContextInfo- Revert "Partially revert PR #125326: revert ComActivator/LicenseInter… #126141METHOD__LICENSE_INTEROP_PROXY__SAVEKEYINCURRENTCONTEXTinLicenseInteropHelper::SaveKeyInCurrentContext- Revert "Partially revert PR #125326: revert ComActivator/LicenseInter… #126141OLE Variant (
olevariant.cpp) - #125326METHOD__VARIANT__CAST_VARIANTinOleVariant::MarshalOleVariantForObjectMETHOD__VARIANT__CONVERT_VARIANT_TO_OBJECTinOleVariant::MarshalObjectForOleVariantMETHOD__VARIANT__CONVERT_OBJECT_TO_VARIANTinOleVariant::MarshalOleVariantForObjectDispatch Info (
dispatchinfo.cpp) - ~30 call sites - #126074Various reflection-based calls in:
DispatchMemberInfo::GetParamInfo- parameter name retrievalDispatchMemberInfo::SetUpMethodMarshalerInfo- method handle retrievalDispatchMemberInfo::GetMemberInfoValue- property gettersDispatchMemberInfo::SetMemberInfoValue- property settersDispatchExInfo::InvokeMember- member invocationDispatchExInfo::SynchWithManagedView-GetProperties,GetFields,GetMethodsDispatchInfo::GetExceptionDescription- exception property getterFollow up cleanup