Skip to content

Commit e78ee77

Browse files
Remove Helper Method Frames (HMF) from Reflection (#110627)
Convert Signature.GetSignature() to QCall. Rename Signature.GetSignature() to Signature.Init(). Remove HMF from Signature.GetTypeParameterOffset(). Remove HMF from Signature.GetCallingConventionFromFunctionPointerAtOffset(). Convert Signature.GetCustomModifiersAtOffset() to QCall. Convert RuntimeTypeHandle.GetDeclaringMethodForGenericParameter() to QCall. Rename RuntimeTypeHandle.GetDeclaringMethod() to RuntimeTypeHandle.GetDeclaringMethodForGenericParameter(). Convert RuntimeTypeHandle.CanCastTo() to slow/fast paths using FCall/QCall. Remove HMF from RuntimeMethodHandle::GetMethodDef(). Convert RuntimeMethodHandle.GetStubIfNeeded() to fast/slow paths using FCall/QCall. Convert RuntimeTypeHandle.SatisfiesConstraints() to QCall. Convert RuntimeMethodHandle.GetMethodBody() to QCall.
1 parent 144dcae commit e78ee77

File tree

21 files changed

+723
-742
lines changed

21 files changed

+723
-742
lines changed

src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ private static bool AreTypesEquivalent(MethodTable* pMTa, MethodTable* pMTb)
539539

540540
[DebuggerHidden]
541541
[MethodImpl(MethodImplOptions.AggressiveInlining)]
542-
private static bool IsNullableForType(MethodTable* typeMT, MethodTable* boxedMT)
542+
internal static bool IsNullableForType(MethodTable* typeMT, MethodTable* boxedMT)
543543
{
544544
if (!typeMT->IsNullable)
545545
{

src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,28 +1098,64 @@ public static TypeHandle TypeHandleOf<T>()
10981098

10991099
public static bool AreSameType(TypeHandle left, TypeHandle right) => left.m_asTAddr == right.m_asTAddr;
11001100

1101+
public int GetCorElementType() => GetCorElementType(m_asTAddr);
1102+
11011103
[MethodImpl(MethodImplOptions.AggressiveInlining)]
11021104
public bool CanCastTo(TypeHandle destTH)
11031105
{
1104-
if (m_asTAddr == destTH.m_asTAddr)
1105-
return true;
1106+
return TryCanCastTo(this, destTH) switch
1107+
{
1108+
CastResult.CanCast => true,
1109+
CastResult.CannotCast => false,
11061110

1107-
if (!IsTypeDesc && destTH.IsTypeDesc)
1108-
return false;
1111+
// Regular casting does not allow T to be cast to Nullable<T>.
1112+
// See TypeHandle::CanCastTo()
1113+
_ => CanCastToWorker(this, destTH, nullableCast: false)
1114+
};
1115+
}
11091116

1110-
CastResult result = CastCache.TryGet(CastHelpers.s_table!, (nuint)m_asTAddr, (nuint)destTH.m_asTAddr);
1117+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
1118+
public static bool CanCastToForReflection(TypeHandle srcTH, TypeHandle destTH)
1119+
{
1120+
return TryCanCastTo(srcTH, destTH) switch
1121+
{
1122+
CastResult.CanCast => true,
1123+
CastResult.CannotCast => false,
11111124

1112-
if (result != CastResult.MaybeCast)
1113-
return result == CastResult.CanCast;
1125+
// Reflection allows T to be cast to Nullable<T>.
1126+
// See ObjIsInstanceOfCore()
1127+
_ => CanCastToWorker(srcTH, destTH, nullableCast: true)
1128+
};
1129+
}
11141130

1115-
return CanCastTo_NoCacheLookup(m_asTAddr, destTH.m_asTAddr);
1131+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
1132+
private static CastResult TryCanCastTo(TypeHandle srcTH, TypeHandle destTH)
1133+
{
1134+
// See TypeHandle::CanCastToCached() for duplicate quick checks.
1135+
if (srcTH.m_asTAddr == destTH.m_asTAddr)
1136+
return CastResult.CanCast;
1137+
1138+
if (!srcTH.IsTypeDesc && destTH.IsTypeDesc)
1139+
return CastResult.CannotCast;
1140+
1141+
return CastCache.TryGet(CastHelpers.s_table!, (nuint)srcTH.m_asTAddr, (nuint)destTH.m_asTAddr);
11161142
}
11171143

1118-
public int GetCorElementType() => GetCorElementType(m_asTAddr);
1144+
[MethodImpl(MethodImplOptions.NoInlining)]
1145+
private static bool CanCastToWorker(TypeHandle srcTH, TypeHandle destTH, bool nullableCast)
1146+
{
1147+
if (!srcTH.IsTypeDesc
1148+
&& !destTH.IsTypeDesc
1149+
&& CastHelpers.IsNullableForType(destTH.AsMethodTable(), srcTH.AsMethodTable()))
1150+
{
1151+
return nullableCast;
1152+
}
1153+
1154+
return CanCastTo_NoCacheLookup(srcTH.m_asTAddr, destTH.m_asTAddr) != Interop.BOOL.FALSE;
1155+
}
11191156

11201157
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "TypeHandle_CanCastTo_NoCacheLookup")]
1121-
[return: MarshalAs(UnmanagedType.Bool)]
1122-
private static partial bool CanCastTo_NoCacheLookup(void* fromTypeHnd, void* toTypeHnd);
1158+
private static partial Interop.BOOL CanCastTo_NoCacheLookup(void* fromTypeHnd, void* toTypeHnd);
11231159

11241160
[SuppressGCTransition]
11251161
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "TypeHandle_GetCorElementType")]

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

Lines changed: 182 additions & 65 deletions
Large diffs are not rendered by default.

src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2011,29 +2011,23 @@ private static RuntimePropertyInfo GetPropertyInfo(RuntimeType reflectedType, in
20112011

20122012
internal static void ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception? e)
20132013
{
2014-
RuntimeType[]? typeContext = null;
2015-
RuntimeType[]? methodContext = null;
2014+
RuntimeType? typeContext;
2015+
RuntimeMethodInfo? methodContext = null;
20162016
RuntimeType[] genericParameters;
20172017

20182018
if (definition is Type)
20192019
{
2020-
RuntimeType genericTypeDefinition = (RuntimeType)definition;
2021-
genericParameters = genericTypeDefinition.GetGenericArgumentsInternal();
2022-
typeContext = genericArguments;
2020+
typeContext = (RuntimeType)definition;
2021+
genericParameters = typeContext.GetGenericArgumentsInternal();
20232022
}
20242023
else
20252024
{
2026-
RuntimeMethodInfo genericMethodDefinition = (RuntimeMethodInfo)definition;
2027-
genericParameters = genericMethodDefinition.GetGenericArgumentsInternal();
2028-
methodContext = genericArguments;
2029-
2030-
RuntimeType? declaringType = (RuntimeType?)genericMethodDefinition.DeclaringType;
2031-
if (declaringType != null)
2032-
{
2033-
typeContext = declaringType.TypeHandle.GetInstantiationInternal();
2034-
}
2025+
methodContext = (RuntimeMethodInfo)definition;
2026+
typeContext = (RuntimeType?)methodContext.DeclaringType;
2027+
genericParameters = methodContext.GetGenericArgumentsInternal();
20352028
}
20362029

2030+
Debug.Assert(genericArguments.Length == genericParameters.Length);
20372031
for (int i = 0; i < genericArguments.Length; i++)
20382032
{
20392033
Type genericArgument = genericArguments[i];
@@ -3276,8 +3270,7 @@ public override MethodBase? DeclaringMethod
32763270
if (!IsGenericParameter)
32773271
throw new InvalidOperationException(SR.Arg_NotGenericParameter);
32783272

3279-
IRuntimeMethodInfo declaringMethod = RuntimeTypeHandle.GetDeclaringMethod(this);
3280-
3273+
IRuntimeMethodInfo? declaringMethod = RuntimeTypeHandle.GetDeclaringMethodForGenericParameter(this);
32813274
if (declaringMethod == null)
32823275
return null;
32833276

src/coreclr/vm/assemblynative.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,7 @@ extern "C" void QCALLTYPE AssemblyNative_GetEntryPoint(QCall::AssemblyHandle pAs
10891089
if (pMeth != NULL)
10901090
{
10911091
GCX_COOP();
1092-
retMethod.Set(pMeth->GetStubMethodInfo());
1092+
retMethod.Set(pMeth->AllocateStubMethodInfo());
10931093
}
10941094

10951095
END_QCALL;

src/coreclr/vm/comdelegate.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2127,7 +2127,7 @@ extern "C" void QCALLTYPE Delegate_FindMethodHandle(QCall::ObjectHandleOnStack d
21272127

21282128
MethodDesc* pMD = COMDelegate::GetMethodDesc(d.Get());
21292129
pMD = MethodDesc::FindOrCreateAssociatedMethodDescForReflection(pMD, TypeHandle(pMD->GetMethodTable()), pMD->GetMethodInstantiation());
2130-
retMethodInfo.Set(pMD->GetStubMethodInfo());
2130+
retMethodInfo.Set(pMD->AllocateStubMethodInfo());
21312131

21322132
END_QCALL;
21332133
}

src/coreclr/vm/comutilnative.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ extern "C" void QCALLTYPE ExceptionNative_GetMethodFromStackTrace(QCall::ObjectH
445445
// The managed stack trace classes always return typical method definition,
446446
// so we don't need to bother providing exact instantiation.
447447
MethodDesc* pMDTypical = pMD->LoadTypicalMethodDefinition();
448-
retMethodInfo.Set(pMDTypical->GetStubMethodInfo());
448+
retMethodInfo.Set(pMDTypical->AllocateStubMethodInfo());
449449
_ASSERTE(pMDTypical->IsRuntimeMethodHandle());
450450

451451
END_QCALL;
@@ -1861,11 +1861,6 @@ extern "C" BOOL QCALLTYPE TypeHandle_CanCastTo_NoCacheLookup(void* fromTypeHnd,
18611861
{
18621862
ret = fromTH.AsTypeDesc()->CanCastTo(toTH, NULL);
18631863
}
1864-
else if (Nullable::IsNullableForType(toTH, fromTH.AsMethodTable()))
1865-
{
1866-
// do not allow type T to be cast to Nullable<T>
1867-
ret = FALSE;
1868-
}
18691864
else
18701865
{
18711866
ret = fromTH.AsMethodTable()->CanCastTo(toTH.AsMethodTable(), NULL);

src/coreclr/vm/corelib.h

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ DEFINE_METHOD(ASSEMBLY, CTOR, .ctor,
137137
DEFINE_CLASS(ASYNCCALLBACK, System, AsyncCallback)
138138
DEFINE_CLASS(ATTRIBUTE, System, Attribute)
139139

140+
DEFINE_CLASS_U(System, Signature, SignatureNative)
140141

141142
DEFINE_CLASS(BINDER, Reflection, Binder)
142143

@@ -182,7 +183,7 @@ DEFINE_METHOD(COM_OBJECT, RELEASE_ALL_DATA, ReleaseAllData,
182183
DEFINE_METHOD(COM_OBJECT, GET_EVENT_PROVIDER, GetEventProvider, IM_Class_RetObj)
183184
#ifdef FOR_ILLINK
184185
DEFINE_METHOD(COM_OBJECT, CTOR, .ctor, IM_RetVoid)
185-
#endif
186+
#endif // FOR_ILLINK
186187

187188
DEFINE_CLASS(LICENSE_INTEROP_PROXY, InternalInteropServices, LicenseInteropProxy)
188189
DEFINE_METHOD(LICENSE_INTEROP_PROXY, CREATE, Create, SM_RetObj)
@@ -358,9 +359,9 @@ DEFINE_FIELD(RT_FIELD_INFO, HANDLE, m_fieldHandle)
358359
DEFINE_CLASS_U(System, RuntimeFieldInfoStub, ReflectFieldObject)
359360
DEFINE_FIELD_U(m_fieldHandle, ReflectFieldObject, m_pFD)
360361
DEFINE_CLASS(STUBFIELDINFO, System, RuntimeFieldInfoStub)
361-
#if FOR_ILLINK
362+
#ifdef FOR_ILLINK
362363
DEFINE_METHOD(STUBFIELDINFO, CTOR, .ctor, IM_RetVoid)
363-
#endif
364+
#endif // FOR_ILLINK
364365

365366
DEFINE_CLASS(FIELD, Reflection, RuntimeFieldInfo)
366367

@@ -497,18 +498,18 @@ DEFINE_FIELD_U(_handlerLength, RuntimeExceptionHandlingClause, _h
497498
DEFINE_FIELD_U(_catchMetadataToken, RuntimeExceptionHandlingClause, _catchToken)
498499
DEFINE_FIELD_U(_filterOffset, RuntimeExceptionHandlingClause, _filterOffset)
499500
DEFINE_CLASS(RUNTIME_EH_CLAUSE, Reflection, RuntimeExceptionHandlingClause)
500-
#if FOR_ILLINK
501+
#ifdef FOR_ILLINK
501502
DEFINE_METHOD(RUNTIME_EH_CLAUSE, CTOR, .ctor, IM_RetVoid)
502-
#endif
503+
#endif // FOR_ILLINK
503504

504505
DEFINE_CLASS_U(Reflection, RuntimeLocalVariableInfo, RuntimeLocalVariableInfo)
505506
DEFINE_FIELD_U(_type, RuntimeLocalVariableInfo, _type)
506507
DEFINE_FIELD_U(_localIndex, RuntimeLocalVariableInfo, _localIndex)
507508
DEFINE_FIELD_U(_isPinned, RuntimeLocalVariableInfo, _isPinned)
508509
DEFINE_CLASS(RUNTIME_LOCAL_VARIABLE_INFO, Reflection, RuntimeLocalVariableInfo)
509-
#if FOR_ILLINK
510+
#ifdef FOR_ILLINK
510511
DEFINE_METHOD(RUNTIME_LOCAL_VARIABLE_INFO, CTOR, .ctor, IM_RetVoid)
511-
#endif
512+
#endif // FOR_ILLINK
512513

513514
DEFINE_CLASS_U(Reflection, RuntimeMethodBody, RuntimeMethodBody)
514515
DEFINE_FIELD_U(_IL, RuntimeMethodBody, _IL)
@@ -518,7 +519,11 @@ DEFINE_FIELD_U(_methodBase, RuntimeMethodBody, _methodBase
518519
DEFINE_FIELD_U(_localSignatureMetadataToken, RuntimeMethodBody, _localVarSigToken)
519520
DEFINE_FIELD_U(_maxStackSize, RuntimeMethodBody, _maxStackSize)
520521
DEFINE_FIELD_U(_initLocals, RuntimeMethodBody, _initLocals)
521-
DEFINE_CLASS(RUNTIME_METHOD_BODY, Reflection, RuntimeMethodBody)
522+
523+
DEFINE_CLASS(RUNTIME_METHOD_BODY, Reflection, RuntimeMethodBody)
524+
#ifdef FOR_ILLINK
525+
DEFINE_METHOD(RUNTIME_METHOD_BODY, CTOR, .ctor, IM_RetVoid)
526+
#endif // FOR_ILLINK
522527

523528
DEFINE_CLASS(METHOD_INFO, Reflection, MethodInfo)
524529

src/coreclr/vm/ecalllist.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ FCFuncStart(gExceptionFuncs)
8282
FCFuncEnd()
8383

8484
FCFuncStart(gCOMTypeHandleFuncs)
85-
FCFuncElement("GetDeclaringMethod", RuntimeTypeHandle::GetDeclaringMethod)
8685
FCFuncElement("GetFirstIntroducedMethod", RuntimeTypeHandle::GetFirstIntroducedMethod)
8786
FCFuncElement("GetNextIntroducedMethod", RuntimeTypeHandle::GetNextIntroducedMethod)
8887
FCFuncElement("GetAssemblyIfExists", RuntimeTypeHandle::GetAssemblyIfExists)
@@ -93,11 +92,9 @@ FCFuncStart(gCOMTypeHandleFuncs)
9392
FCFuncElement("GetUtf8NameInternal", RuntimeTypeHandle::GetUtf8Name)
9493
FCFuncElement("GetAttributes", RuntimeTypeHandle::GetAttributes)
9594
FCFuncElement("GetNumVirtuals", RuntimeTypeHandle::GetNumVirtuals)
96-
FCFuncElement("CanCastTo", RuntimeTypeHandle::CanCastTo)
9795
FCFuncElement("GetGenericVariableIndex", RuntimeTypeHandle::GetGenericVariableIndex)
9896
FCFuncElement("IsGenericVariable", RuntimeTypeHandle::IsGenericVariable)
9997
FCFuncElement("ContainsGenericVariables", RuntimeTypeHandle::ContainsGenericVariables)
100-
FCFuncElement("SatisfiesConstraints", RuntimeTypeHandle::SatisfiesConstraints)
10198
FCFuncElement("IsUnmanagedFunctionPointer", RuntimeTypeHandle::IsUnmanagedFunctionPointer)
10299
FCFuncElement("CompareCanonicalHandles", RuntimeTypeHandle::CompareCanonicalHandles)
103100
FCFuncElement("GetRuntimeTypeFromHandleIfExists", RuntimeTypeHandle::GetRuntimeTypeFromHandleIfExists)
@@ -132,11 +129,9 @@ FCFuncStart(gMetaDataImport)
132129
FCFuncEnd()
133130

134131
FCFuncStart(gSignatureNative)
135-
FCFuncElement("GetSignature", SignatureNative::GetSignature)
136132
FCFuncElement("GetParameterOffsetInternal", SignatureNative::GetParameterOffsetInternal)
137-
FCFuncElement("GetTypeParameterOffset", SignatureNative::GetTypeParameterOffset)
138-
FCFuncElement("GetCustomModifiersAtOffset", SignatureNative::GetCustomModifiersAtOffset)
139-
FCFuncElement("GetCallingConventionFromFunctionPointerAtOffset", SignatureNative::GetCallingConventionFromFunctionPointerAtOffset)
133+
FCFuncElement("GetTypeParameterOffsetInternal", SignatureNative::GetTypeParameterOffsetInternal)
134+
FCFuncElement("GetCallingConventionFromFunctionPointerAtOffsetInternal", SignatureNative::GetCallingConventionFromFunctionPointerAtOffsetInternal)
140135
FCFuncEnd()
141136

142137
FCFuncStart(gRuntimeMethodHandle)
@@ -150,10 +145,9 @@ FCFuncStart(gRuntimeMethodHandle)
150145
FCFuncElement("IsGenericMethodDefinition", RuntimeMethodHandle::IsGenericMethodDefinition)
151146
FCFuncElement("GetGenericParameterCount", RuntimeMethodHandle::GetGenericParameterCount)
152147
FCFuncElement("IsTypicalMethodDefinition", RuntimeMethodHandle::IsTypicalMethodDefinition)
153-
FCFuncElement("GetStubIfNeeded", RuntimeMethodHandle::GetStubIfNeeded)
148+
FCFuncElement("GetStubIfNeededInternal", RuntimeMethodHandle::GetStubIfNeededInternal)
154149
FCFuncElement("GetMethodFromCanonical", RuntimeMethodHandle::GetMethodFromCanonical)
155150
FCFuncElement("IsDynamicMethod", RuntimeMethodHandle::IsDynamicMethod)
156-
FCFuncElement("GetMethodBody", RuntimeMethodHandle::GetMethodBody)
157151
FCFuncElement("IsConstructor", RuntimeMethodHandle::IsConstructor)
158152
FCFuncElement("GetResolver", RuntimeMethodHandle::GetResolver)
159153
FCFuncElement("GetLoaderAllocatorInternal", RuntimeMethodHandle::GetLoaderAllocatorInternal)

src/coreclr/vm/interoplibinterface_objc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ void* ObjCMarshalNative::GetPropagatingExceptionCallback(
336336
if (CallAvailableUnhandledExceptionPropagation())
337337
{
338338
gc.throwableRef = ObjectFromHandle(throwable);
339-
gc.methodRef = method->GetStubMethodInfo();
339+
gc.methodRef = method->AllocateStubMethodInfo();
340340

341341
callback = CallInvokeUnhandledExceptionPropagation(
342342
&gc.throwableRef,

0 commit comments

Comments
 (0)