Repository: dotnet/runtime
File: src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs (C#)

Code before:
        {
            ClearNative(pMarshalState, pNativeHome);
        }
#pragma warning restore IDE0060

        [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdSafeArrayMarshaler_ClearNative")]
        private static partial void ClearNative(IntPtr pMarshalState, IntPtr pNativeHome);
    }  // class MngdSafeArrayMarshaler
#endif // FEATURE_COMINTEROP

    internal static unsafe partial class MngdRefCustomMarshaler
    {
        [UnmanagedCallersOnly]
        internal static void ConvertContentsToNative(ObjectHandleOnStack marshaler, ObjectHandleOnStack pManagedHome, IntPtr* pNativeHome, ObjectHandleOnStack exception)
        {
            try
            {
                ICustomMarshaler customMarshaler = (ICustomMarshaler)marshaler.Value!;
                object managedHome = pManagedHome.Value!;
                ConvertContentsToNative(customMarshaler, in managedHome, pNativeHome);
            }
            catch (Exception ex)
            {
                exception.Value = ex;
            }
        }

        internal static void ConvertContentsToNative(ICustomMarshaler marshaler, in object pManagedHome, IntPtr* pNativeHome)
        {
            // COMPAT: We never pass null to MarshalManagedToNative.
            if (pManagedHome is null)
            {
                *pNativeHome = IntPtr.Zero;
                return;
            }

            *pNativeHome = marshaler.MarshalManagedToNative(pManagedHome);
        }

        [UnmanagedCallersOnly]
        internal static void ConvertContentsToManaged(ObjectHandleOnStack marshaler, ObjectHandleOnStack pManagedHome, IntPtr* pNativeHome, ObjectHandleOnStack exception)
        {
            try
            {
                ICustomMarshaler customMarshaler = (ICustomMarshaler)marshaler.Value!;
                object? managedHome = pManagedHome.Value;
                ConvertContentsToManaged(customMarshaler, ref managedHome, pNativeHome);
                pManagedHome.Value = managedHome!;
            }
            catch (Exception ex)
            {

Review comment (suggestion):
I assume we will want to switch the remaining VM calls to these methods to the UCO as well. Should we keep `pManagedHome` in the UCO as byref? (It would have to be passed as `ByteRef* managedHome`.)

Code after:
        {
            ClearNative(pMarshalState, pNativeHome);
        }
#pragma warning restore IDE0060

        [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "MngdSafeArrayMarshaler_ClearNative")]
        private static partial void ClearNative(IntPtr pMarshalState, IntPtr pNativeHome);
    }  // class MngdSafeArrayMarshaler
#endif // FEATURE_COMINTEROP

    internal static unsafe partial class MngdRefCustomMarshaler
    {
        [UnmanagedCallersOnly]
        internal static void ConvertContentsToNative(ICustomMarshaler* pMarshaler, object* pManagedHome, IntPtr* pNativeHome, Exception* pException)
        {
            try
            {
                ConvertContentsToNative(*pMarshaler, in *pManagedHome, pNativeHome);
            }
            catch (Exception ex)
            {
                *pException = ex;
            }
        }

        internal static void ConvertContentsToNative(ICustomMarshaler marshaler, in object pManagedHome, IntPtr* pNativeHome)
        {
            // COMPAT: We never pass null to MarshalManagedToNative.
            if (pManagedHome is null)
            {
                *pNativeHome = IntPtr.Zero;
                return;
            }

            *pNativeHome = marshaler.MarshalManagedToNative(pManagedHome);
        }

        [UnmanagedCallersOnly]
        internal static void ConvertContentsToManaged(ICustomMarshaler* pMarshaler, object* pManagedHome, IntPtr* pNativeHome, Exception* pException)
        {
            try
            {
                ConvertContentsToManaged(*pMarshaler, ref *pManagedHome, pNativeHome);
            }
            catch (Exception ex)
            {
                *pException = ex;
            }
        }

        internal static void ConvertContentsToManaged(ICustomMarshaler marshaler, ref object? pManagedHome, IntPtr* pNativeHome)