Skip to content

Commit 3ea3efc

Browse files
AaronRobinsonMSFTjkotasCopilot
authored
Replace MethodDescCallSite with UnmanagedCallersOnly for Priority 1 c… (#124303)
…all sites Convert the following `MethodDescCallSite`/`CallDescrWorker` calls to use `UnmanagedCallersOnlyCaller` with `[UnmanagedCallersOnly]` managed wrappers: - EventSource.InitializeDefaultEventSources (corhost.cpp) - StartupHookProvider.CallStartupHook (ds-rt-coreclr.h) - LoaderAllocator constructor (loaderallocator.cpp) - ColorMarshaler.ConvertToManaged/ConvertToNative (interoputil.cpp) - CultureInfo get/set CurrentCulture/CurrentUICulture (threads.cpp) - CultureInfo(int) constructor (interoputil.cpp) - Resolver.GetJitContext/GetCodeInfo/GetLocalsSignature/GetStringLiteral (dynamicmethod.cpp) Contributes to #123864 --------- Co-authored-by: Jan Kotas <jkotas@microsoft.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent fbf6be5 commit 3ea3efc

25 files changed

Lines changed: 635 additions & 293 deletions

src/coreclr/System.Private.CoreLib/src/System/Reflection/LoaderAllocator.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,19 @@ private LoaderAllocator()
5454
m_scout = new LoaderAllocatorScout();
5555
}
5656

57+
[UnmanagedCallersOnly]
58+
private static unsafe void Create(object* pResult, Exception* pException)
59+
{
60+
try
61+
{
62+
*pResult = new LoaderAllocator();
63+
}
64+
catch (Exception ex)
65+
{
66+
*pException = ex;
67+
}
68+
}
69+
5770
#pragma warning disable CA1823, 414, 169
5871
private LoaderAllocatorScout m_scout;
5972
private object[] m_slots;

src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2207,5 +2207,57 @@ internal struct CORINFO_EH_CLAUSE
22072207
internal abstract byte[]? ResolveSignature(int token, int fromMethod);
22082208
//
22092209
internal abstract MethodInfo GetDynamicMethod();
2210+
2211+
[UnmanagedCallersOnly]
2212+
internal static unsafe void GetJitContext(Resolver* pResolver, int* pSecurityControlFlags, RuntimeType* ppResult, Exception* pException)
2213+
{
2214+
try
2215+
{
2216+
*ppResult = pResolver->GetJitContext(out *pSecurityControlFlags);
2217+
}
2218+
catch (Exception ex)
2219+
{
2220+
*pException = ex;
2221+
}
2222+
}
2223+
2224+
[UnmanagedCallersOnly]
2225+
internal static unsafe void GetCodeInfo(Resolver* pResolver, int* pStackSize, int* pInitLocals, int* pEHCount, byte[]* ppResult, Exception* pException)
2226+
{
2227+
try
2228+
{
2229+
*ppResult = pResolver->GetCodeInfo(out *pStackSize, out *pInitLocals, out *pEHCount);
2230+
}
2231+
catch (Exception ex)
2232+
{
2233+
*pException = ex;
2234+
}
2235+
}
2236+
2237+
[UnmanagedCallersOnly]
2238+
internal static unsafe void GetLocalsSignature(Resolver* pResolver, byte[]* ppResult, Exception* pException)
2239+
{
2240+
try
2241+
{
2242+
*ppResult = pResolver->GetLocalsSignature();
2243+
}
2244+
catch (Exception ex)
2245+
{
2246+
*pException = ex;
2247+
}
2248+
}
2249+
2250+
[UnmanagedCallersOnly]
2251+
internal static unsafe void GetStringLiteral(Resolver* pResolver, int token, string* ppResult, Exception* pException)
2252+
{
2253+
try
2254+
{
2255+
*ppResult = pResolver->GetStringLiteral(token);
2256+
}
2257+
catch (Exception ex)
2258+
{
2259+
*pException = ex;
2260+
}
2261+
}
22102262
}
22112263
}

src/coreclr/System.Private.CoreLib/src/System/StubHelpers.cs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1628,6 +1628,54 @@ internal static void MulticastDebuggerTraceHelper(object o, int count)
16281628
} // class StubHelpers
16291629

16301630
#if FEATURE_COMINTEROP
1631+
internal static class CultureInfoMarshaler
1632+
{
1633+
[UnmanagedCallersOnly]
1634+
internal static unsafe void GetCurrentCulture(bool bUICulture, object* pResult, Exception* pException)
1635+
{
1636+
try
1637+
{
1638+
*pResult = bUICulture
1639+
? Globalization.CultureInfo.CurrentUICulture
1640+
: Globalization.CultureInfo.CurrentCulture;
1641+
}
1642+
catch (Exception ex)
1643+
{
1644+
*pException = ex;
1645+
}
1646+
}
1647+
1648+
[UnmanagedCallersOnly]
1649+
internal static unsafe void SetCurrentCulture(bool bUICulture, Globalization.CultureInfo* pValue, Exception* pException)
1650+
{
1651+
try
1652+
{
1653+
if (bUICulture)
1654+
Globalization.CultureInfo.CurrentUICulture = *pValue;
1655+
else
1656+
Globalization.CultureInfo.CurrentCulture = *pValue;
1657+
}
1658+
catch (Exception ex)
1659+
{
1660+
*pException = ex;
1661+
}
1662+
}
1663+
1664+
[UnmanagedCallersOnly]
1665+
internal static unsafe void CreateCultureInfo(int culture, object* pResult, Exception* pException)
1666+
{
1667+
try
1668+
{
1669+
// Consider calling CultureInfo.GetCultureInfo that returns a cached instance to avoid this expensive creation.
1670+
*pResult = new Globalization.CultureInfo(culture);
1671+
}
1672+
catch (Exception ex)
1673+
{
1674+
*pException = ex;
1675+
}
1676+
}
1677+
}
1678+
16311679
internal static class ColorMarshaler
16321680
{
16331681
private static readonly MethodInvoker s_oleColorToDrawingColorMethod;
@@ -1657,6 +1705,32 @@ internal static int ConvertToNative(object? managedColor)
16571705
{
16581706
return (int)s_drawingColorToOleColorMethod.Invoke(null, managedColor)!;
16591707
}
1708+
1709+
[UnmanagedCallersOnly]
1710+
internal static unsafe void ConvertToManaged(int oleColor, object* pResult, Exception* pException)
1711+
{
1712+
try
1713+
{
1714+
*pResult = ConvertToManaged(oleColor);
1715+
}
1716+
catch (Exception ex)
1717+
{
1718+
*pException = ex;
1719+
}
1720+
}
1721+
1722+
[UnmanagedCallersOnly]
1723+
internal static unsafe void ConvertToNative(object* pSrcObj, int* pResult, Exception* pException)
1724+
{
1725+
try
1726+
{
1727+
*pResult = ConvertToNative(*pSrcObj);
1728+
}
1729+
catch (Exception ex)
1730+
{
1731+
*pException = ex;
1732+
}
1733+
}
16601734
}
16611735
#endif
16621736
}

src/coreclr/vm/callhelpers.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,10 @@ void CallDefaultConstructor(OBJECTREF ref);
665665
// from native code.
666666
//
667667

668+
// Use CLR_BOOL_ARG to convert a BOOL value to a CLR_BOOL for passing to
669+
// UnmanagedCallersOnlyCaller::InvokeThrowing when the managed parameter is bool.
670+
#define CLR_BOOL_ARG(x) ((CLR_BOOL)(!!(x)))
671+
668672
// Helper class for calling managed methods marked with [UnmanagedCallersOnly].
669673
// This provides a more efficient alternative to MethodDescCallSite for methods
670674
// using the reverse P/Invoke infrastructure.

src/coreclr/vm/corelib.h

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -659,12 +659,12 @@ DEFINE_METHOD(PROPERTY, GET_GETTER, GetGetMethod,
659659
DEFINE_CLASS(PROPERTY_INFO, Reflection, PropertyInfo)
660660

661661
DEFINE_CLASS(RESOLVER, System, Resolver)
662-
DEFINE_METHOD(RESOLVER, GET_JIT_CONTEXT, GetJitContext, IM_RefInt_RetRuntimeType)
663-
DEFINE_METHOD(RESOLVER, GET_CODE_INFO, GetCodeInfo, IM_RefInt_RefInt_RefInt_RetArrByte)
664-
DEFINE_METHOD(RESOLVER, GET_LOCALS_SIGNATURE, GetLocalsSignature, IM_RetArrByte)
662+
DEFINE_METHOD(RESOLVER, GET_JIT_CONTEXT, GetJitContext, SM_PtrResolver_PtrInt_PtrClass_PtrException_RetVoid)
663+
DEFINE_METHOD(RESOLVER, GET_CODE_INFO, GetCodeInfo, SM_PtrResolver_PtrInt_PtrInt_PtrInt_PtrArrByte_PtrException_RetVoid)
664+
DEFINE_METHOD(RESOLVER, GET_LOCALS_SIGNATURE, GetLocalsSignature, SM_PtrResolver_PtrArrByte_PtrException_RetVoid)
665665
DEFINE_METHOD(RESOLVER, GET_EH_INFO, GetEHInfo, IM_Int_VoidPtr_RetVoid)
666666
DEFINE_METHOD(RESOLVER, GET_RAW_EH_INFO, GetRawEHInfo, IM_RetArrByte)
667-
DEFINE_METHOD(RESOLVER, GET_STRING_LITERAL, GetStringLiteral, IM_Int_RetStr)
667+
DEFINE_METHOD(RESOLVER, GET_STRING_LITERAL, GetStringLiteral, SM_PtrResolver_Int_PtrStr_PtrException_RetVoid)
668668
DEFINE_METHOD(RESOLVER, RESOLVE_TOKEN, ResolveToken, IM_Int_RefIntPtr_RefIntPtr_RefIntPtr_RetVoid)
669669
DEFINE_METHOD(RESOLVER, RESOLVE_SIGNATURE, ResolveSignature, IM_IntInt_RetArrByte)
670670

@@ -892,11 +892,11 @@ DEFINE_FIELD_U(rgiLastFrameFromForeignExceptionStackTrace, StackFrame
892892
DEFINE_FIELD_U(iFrameCount, StackFrameHelper, iFrameCount)
893893

894894
DEFINE_CLASS(EVENT_SOURCE, Tracing, EventSource)
895-
DEFINE_METHOD(EVENT_SOURCE, INITIALIZE_DEFAULT_EVENT_SOURCES, InitializeDefaultEventSources, SM_RetVoid)
895+
DEFINE_METHOD(EVENT_SOURCE, INITIALIZE_DEFAULT_EVENT_SOURCES, InitializeDefaultEventSources, SM_PtrException_RetVoid)
896896

897897
DEFINE_CLASS(STARTUP_HOOK_PROVIDER, System, StartupHookProvider)
898898
DEFINE_METHOD(STARTUP_HOOK_PROVIDER, MANAGED_STARTUP, ManagedStartup, SM_PtrChar_RetVoid)
899-
DEFINE_METHOD(STARTUP_HOOK_PROVIDER, CALL_STARTUP_HOOK, CallStartupHook, SM_PtrChar_RetVoid)
899+
DEFINE_METHOD(STARTUP_HOOK_PROVIDER, CALL_STARTUP_HOOK, CallStartupHook, SM_PtrChar_PtrException_RetVoid)
900900

901901
DEFINE_CLASS(STREAM, IO, Stream)
902902
DEFINE_METHOD(STREAM, BEGIN_READ, BeginRead, IM_ArrByte_Int_Int_AsyncCallback_Object_RetIAsyncResult)
@@ -1124,9 +1124,16 @@ DEFINE_METHOD(MNGD_SAFE_ARRAY_MARSHALER, CONVERT_SPACE_TO_MANAGED, ConvertSpa
11241124
DEFINE_METHOD(MNGD_SAFE_ARRAY_MARSHALER, CONVERT_CONTENTS_TO_MANAGED, ConvertContentsToManaged, SM_IntPtr_RefObj_IntPtr_RetVoid)
11251125
DEFINE_METHOD(MNGD_SAFE_ARRAY_MARSHALER, CLEAR_NATIVE, ClearNative, SM_IntPtr_RefObj_IntPtr_RetVoid)
11261126

1127+
DEFINE_CLASS(CULTUREINFOMARSHALER, StubHelpers, CultureInfoMarshaler)
1128+
DEFINE_METHOD(CULTUREINFOMARSHALER, GET_CURRENT_CULTURE, GetCurrentCulture, NoSig)
1129+
DEFINE_METHOD(CULTUREINFOMARSHALER, SET_CURRENT_CULTURE, SetCurrentCulture, NoSig)
1130+
DEFINE_METHOD(CULTUREINFOMARSHALER, CREATE_CULTURE_INFO, CreateCultureInfo, NoSig)
1131+
11271132
DEFINE_CLASS(COLORMARSHALER, StubHelpers, ColorMarshaler)
1128-
DEFINE_METHOD(COLORMARSHALER, CONVERT_TO_NATIVE, ConvertToNative, SM_Obj_RetInt)
1129-
DEFINE_METHOD(COLORMARSHALER, CONVERT_TO_MANAGED, ConvertToManaged, SM_Int_RetObj)
1133+
DEFINE_METHOD(COLORMARSHALER, CONVERT_TO_NATIVE, ConvertToNative, SM_Obj_RetInt)
1134+
DEFINE_METHOD(COLORMARSHALER, CONVERT_TO_MANAGED, ConvertToManaged, SM_Int_RetObj)
1135+
DEFINE_METHOD(COLORMARSHALER, CONVERT_TO_NATIVE_UCO, ConvertToNative, SM_PtrObj_PtrInt_PtrException_RetVoid)
1136+
DEFINE_METHOD(COLORMARSHALER, CONVERT_TO_MANAGED_UCO, ConvertToManaged, SM_Int_PtrObj_PtrException_RetVoid)
11301137
DEFINE_FIELD(COLORMARSHALER, COLOR_TYPE, s_colorType)
11311138
#endif // FEATURE_COMINTEROP
11321139
END_ILLINK_FEATURE_SWITCH()
@@ -1223,7 +1230,7 @@ DEFINE_CLASS_U(Reflection, LoaderAllocator, LoaderAllocator
12231230
DEFINE_FIELD_U(m_slots, LoaderAllocatorObject, m_pSlots)
12241231
DEFINE_FIELD_U(m_slotsUsed, LoaderAllocatorObject, m_slotsUsed)
12251232
DEFINE_CLASS(LOADERALLOCATOR, Reflection, LoaderAllocator)
1226-
DEFINE_METHOD(LOADERALLOCATOR, CTOR, .ctor, IM_RetVoid)
1233+
DEFINE_METHOD(LOADERALLOCATOR, CREATE, Create, NoSig)
12271234

12281235
DEFINE_CLASS_U(Reflection, LoaderAllocatorScout, LoaderAllocatorScoutObject)
12291236
DEFINE_FIELD_U(m_nativeLoaderAllocator, LoaderAllocatorScoutObject, m_nativeLoaderAllocator)

src/coreclr/vm/corhost.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,8 +659,8 @@ HRESULT CorHost2::CreateAppDomainWithManager(
659659
// Initialize default event sources
660660
{
661661
GCX_COOP();
662-
MethodDescCallSite initEventSources(METHOD__EVENT_SOURCE__INITIALIZE_DEFAULT_EVENT_SOURCES);
663-
initEventSources.Call(NULL);
662+
UnmanagedCallersOnlyCaller initEventSources(METHOD__EVENT_SOURCE__INITIALIZE_DEFAULT_EVENT_SOURCES);
663+
initEventSources.InvokeThrowing();
664664
}
665665
#endif // FEATURE_PERFTRACING
666666

src/coreclr/vm/dispatchinfo.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1555,8 +1555,8 @@ void DispatchInfo::InvokeMemberWorker(DispatchMemberInfo* pDispMemberInfo,
15551555
{
15561556
// If the method is culture aware, then set the specified culture on the thread.
15571557
GetCultureInfoForLCID(lcid, &pObjs->CultureInfo);
1558-
pObjs->OldCultureInfo = Thread::GetCulture(FALSE);
1559-
Thread::SetCulture(&pObjs->CultureInfo, FALSE);
1558+
pObjs->OldCultureInfo = GetCurrentCulture(FALSE);
1559+
SetCurrentCulture(&pObjs->CultureInfo, FALSE);
15601560
}
15611561

15621562
// If the method has custom marshalers then we will need to call
@@ -2284,7 +2284,7 @@ HRESULT DispatchInfo::InvokeMember(SimpleComCallWrapper *pSimpleWrap, DISPID id,
22842284

22852285
// If the culture was changed then restore it to the old culture.
22862286
if (Objs.OldCultureInfo != NULL)
2287-
Thread::SetCulture(&Objs.OldCultureInfo, FALSE);
2287+
SetCurrentCulture(&Objs.OldCultureInfo, FALSE);
22882288
}
22892289
GCPROTECT_END();
22902290
GCPROTECT_END();

src/coreclr/vm/dllimport.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6168,7 +6168,7 @@ EXTERN_C void STDCALL GenericPInvokeCalliStubWorker(TransitionBlock * pTransitio
61686168
pFrame->Pop(CURRENT_THREAD);
61696169
}
61706170

6171-
EXTERN_C void LookupMethodByName(const char* fullQualifiedTypeName, const char* methodName, MethodDesc** ppMD)
6171+
EXTERN_C void LookupUnmanagedCallersOnlyMethodByName(const char* fullQualifiedTypeName, const char* methodName, MethodDesc** ppMD)
61726172
{
61736173
CONTRACTL
61746174
{
@@ -6185,7 +6185,24 @@ EXTERN_C void LookupMethodByName(const char* fullQualifiedTypeName, const char*
61856185
TypeHandle type = TypeName::GetTypeFromAsmQualifiedName(fullQualifiedTypeNameUtf8.GetUnicode(), /*bThrowIfNotFound*/ TRUE);
61866186
_ASSERTE(!type.IsTypeDesc());
61876187

6188-
*ppMD = MemberLoader::FindMethodByName(type.GetMethodTable(), methodName);
6188+
// Iterate the type looking for a method with the given name that has the
6189+
// UnmanagedCallersOnly attribute.
6190+
MethodTable* pMT = type.GetMethodTable();
6191+
MethodTable::MethodIterator it(pMT);
6192+
it.MoveToEnd();
6193+
for (; it.IsValid(); it.Prev())
6194+
{
6195+
MethodDesc* pMD = it.GetMethodDesc();
6196+
if (strcmp(pMD->GetNameOnNonArrayClass(), methodName) == 0
6197+
&& pMD->HasUnmanagedCallersOnlyAttribute())
6198+
{
6199+
*ppMD = pMD;
6200+
return;
6201+
}
6202+
}
6203+
6204+
// Fallback if no UCO match found.
6205+
*ppMD = MemberLoader::FindMethodByName(pMT, methodName);
61896206
}
61906207

61916208
namespace

0 commit comments

Comments
 (0)