Skip to content

Replace CallDescrWorker with UnmanagedCallersOnlyAttribute pattern #123864

@AaronRobinsonMSFT

Description

@AaronRobinsonMSFT

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:

  1. Adding [UnmanagedCallersOnly] wrappers to managed methods with an Exception* out-parameter
  2. Using the UnmanagedCallersOnlyCaller template class in C++ to invoke these methods
  3. 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

  • METHOD__ASSEMBLYLOADCONTEXT__ON_ASSEMBLY_LOAD in AppDomain::RaiseAssemblyLoadEvent
  • METHOD__ASSEMBLYLOADCONTEXT__ON_TYPE_RESOLVE in AppDomain::RaiseTypeResolveEventThrowing
  • METHOD__ASSEMBLYLOADCONTEXT__ON_RESOURCE_RESOLVE in AppDomain::RaiseResourceResolveEvent
  • METHOD__ASSEMBLYLOADCONTEXT__ON_ASSEMBLY_RESOLVE in AppDomain::RaiseAssemblyResolveEvent
  • METHOD__ASSEMBLYLOADCONTEXT__RESOLVE in AppDomain::BindAssemblySpec
  • METHOD__ASSEMBLYLOADCONTEXT__RESOLVESATELLITEASSEMBLY in AppDomain::BindSatelliteResourceByResourceRoots
  • METHOD__ASSEMBLYLOADCONTEXT__RESOLVEUSINGEVENT in AppDomain::RaiseLoadFileEvent

Loader Allocator (loaderallocator.cpp) - #124303

  • METHOD__LOADERALLOCATOR__CTOR in LoaderAllocator::Init

Custom Marshaler (custommarshalerinfo.cpp) - #124440

  • GetCustomMarshaler method lookup in CustomMarshalerInfo::CustomMarshalerInfo

Dynamic Methods / Resolver (dynamicmethod.cpp) - #124303

  • METHOD__RESOLVER__GET_JIT_CONTEXT in LCGMethodResolver::GetJitContext
  • METHOD__RESOLVER__GET_CODE_INFO in LCGMethodResolver::GetCodeInfo
  • METHOD__RESOLVER__GET_LOCALS_SIGNATURE in LCGMethodResolver::GetLocalSig
  • METHOD__RESOLVER__GET_STRING_LITERAL in LCGMethodResolver::GetStringLiteral

Interop Utilities (interoputil.cpp) - #124303

  • METHOD__CULTURE_INFO__INT_CTOR in GetCultureInfoForLCID
  • METHOD__COLORMARSHALER__CONVERT_TO_MANAGED in ConvertOleColorToSystemColor
  • METHOD__COLORMARSHALER__CONVERT_TO_NATIVE in ConvertSystemColorToOleColor

Threads / Culture (threads.cpp) - #124303

  • METHOD__CULTURE_INFO__GET_CURRENT_CULTURE / METHOD__CULTURE_INFO__GET_CURRENT_UI_CULTURE in Thread::GetCultureInfo
  • METHOD__CULTURE_INFO__SET_CURRENT_CULTURE / METHOD__CULTURE_INFO__SET_CURRENT_UI_CULTURE in Thread::SetCultureInfo

Event Sources (corhost.cpp) - #124303

  • METHOD__EVENT_SOURCE__INITIALIZE_DEFAULT_EVENT_SOURCES in CorHost2::CreateAppDomain

Diagnostics (ds-rt-coreclr.h) - #124303

  • METHOD__STARTUP_HOOK_PROVIDER__CALL_STARTUP_HOOK in ds_rt_apply_startup_hook

Priority 2: Cross-Platform, Exception Handling

Exception Construction (clrex.cpp) - #126061

  • Exception constructor in EEException::CreateThrowable
  • Exception constructor in EEMessageException::CreateThrowable
  • Exception constructor in EEResourceException::CreateThrowable

Exception Construction (excep.cpp) - #124834

  • METHOD__RUNTIME_WRAPPED_EXCEPTION__OBJ_CTOR in WrapThrowableInRuntimeWrappedException
  • Various exception constructors in CreateTypeInitializationExceptionObject

Exception Utilities (excep.cpp) - #124834

  • METHOD__OBJECT__TO_STRING in GetExceptionMessage
  • METHOD__EXCEPTION__INTERNAL_PRESERVE_STACK_TRACE in RaiseTheExceptionInternalOnly
  • METHOD__ENVIRONMENT__GET_RESOURCE_STRING_LOCAL in GetResourceStringFromManaged
  • Event args constructor in ExceptionNotifications::DeliverExceptionNotification

Exception Info Retrieval (comutilnative.cpp) - #123986

  • METHOD__EXCEPTION__GET_MESSAGE in ExceptionNative::GetMessageFromException
  • METHOD__EXCEPTION__GET_CLASS_NAME in ExceptionNative::GetMessageFromException
  • METHOD__EXCEPTION__GET_SOURCE in ExceptionNative::GetSource
  • METHOD__EXCEPTION__GET_HELP_CONTEXT in ExceptionNative::GetHelpContext

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

  • METHOD__APPCONTEXT__ON_UNHANDLED_EXCEPTION in AppDomain::RaiseUnhandledExceptionEvent
  • METHOD__APPCONTEXT__ON_PROCESS_EXIT in AppDomain::RaiseExitProcessEvent

Invoke / Reflection (invokeutil.cpp) - #124854

  • Constructor invocation in InvokeUtil::CreateObject
  • Constructor invocation in InvokeUtil::CreateValueType

Host Callbacks (corhost.cpp) - #126222

  • Method invocation in CorHost2::ExecuteAssembly

Exception handling

  • ThrowHwEx` in HandleManagedFault and HandleHardwareException
  • ThrowEx in DispatchManagedException
  • Rethrow in DispatchRethrownManagedException

Runtime threads

  • FinalizerThread::FinalizeAllObjects
  • Thread.Start - KickOffThread_Worker

Reflection Invoke and similar

  • MethodInfo.Invoke - RuntimeMethodHandle_InvokeMethod
  • Custom attribute constructor in COMCustomAttribute::CreateCaObject
  • FuncEvalWrapper() and DoNormalFuncEval()

Priority 4: Platform-Specific (ObjC - macOS/iOS)

ObjC Interop (interoplibinterface_objc.cpp) - #124446

  • METHOD__OBJCMARSHAL__AVAILABLEUNHANDLEDEXCEPTIONPROPAGATION in ObjCMarshalNative::GetPropagatingExceptionCallback

Priority 5: Windows-Only (COM Interop)

These files are only compiled on Windows and are lowest priority.

COM Connection Points (comconnectionpoints.cpp) - #123864

  • Delegate constructor in ConnectionPoint::Advise
  • Provider method in ConnectionPoint::Advise

Standard Interfaces (stdinterfaces.cpp) - #123864

  • CanRead property getter in IDispatchExInfo::GetIDsOfNames
  • CanWrite property getter in IDispatchExInfo::GetIDsOfNames

CLR to COM Calls (clrtocomcall.cpp)

COM Callable Wrapper (comcallablewrapper.cpp) - #123864

  • Custom ICustomQueryInterface::GetInterface in ComCallWrapper::CallICustomQueryInterface

Custom Marshaler (custommarshalerinfo.cpp) - #125326

  • METHOD__STUBHELPERS__GET_IENUMERATOR_TO_ENUM_VARIANT_MARSHALER in CustomMarshalerInfo::GetIEnumeratorToEnumVariantMarshaler

Runtime Callable Wrapper (runtimecallablewrapper.cpp)

OLE Variant (olevariant.cpp) - #125326

  • METHOD__VARIANT__CAST_VARIANT in OleVariant::MarshalOleVariantForObject
  • METHOD__VARIANT__CONVERT_VARIANT_TO_OBJECT in OleVariant::MarshalObjectForOleVariant
  • METHOD__VARIANT__CONVERT_OBJECT_TO_VARIANT in OleVariant::MarshalOleVariantForObject

Dispatch Info (dispatchinfo.cpp) - ~30 call sites - #126074

Various reflection-based calls in:

  • DispatchMemberInfo::GetParamInfo - parameter name retrieval
  • DispatchMemberInfo::SetUpMethodMarshalerInfo - method handle retrieval
  • DispatchMemberInfo::GetMemberInfoValue - property getters
  • DispatchMemberInfo::SetMemberInfoValue - property setters
  • DispatchExInfo::InvokeMember - member invocation
  • DispatchExInfo::SynchWithManagedView - GetProperties, GetFields, GetMethods
  • DispatchInfo::GetExceptionDescription - exception property getter

Follow up cleanup

  • Delete CallDescrWorker

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status

    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions