Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Helper Method Frames (HMF) from Reflection #109996

Merged
merged 12 commits into from
Nov 25, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -1085,7 +1085,7 @@ public CustomAttributeType(RuntimeType parameterType)

if (encodedType == CustomAttributeEncoding.Array)
{
parameterType = (RuntimeType)parameterType.GetElementType();
parameterType = (RuntimeType)parameterType.GetElementType()!;
encodedArrayType = RuntimeCustomAttributeData.TypeToCustomAttributeEncoding(parameterType);
}

Expand Down
68 changes: 57 additions & 11 deletions src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ internal RuntimeType GetTypeChecked() =>
/// </summary>
/// <param name="value">An IntPtr handle to a RuntimeType to create a <see cref="RuntimeTypeHandle"/> object from.</param>
/// <returns>A new <see cref="RuntimeTypeHandle"/> object that corresponds to the value parameter.</returns>
public static RuntimeTypeHandle FromIntPtr(IntPtr value) => new RuntimeTypeHandle(GetTypeFromHandle(value));
public static RuntimeTypeHandle FromIntPtr(IntPtr value) =>
new RuntimeTypeHandle(value == IntPtr.Zero ? null : GetRuntimeTypeFromHandle(value));

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetTypeFromHandleSlow")]
private static partial void GetTypeFromHandleSlow(
Expand All @@ -48,13 +49,8 @@ private static RuntimeType GetTypeFromHandleSlow(IntPtr handle)
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern RuntimeType? GetTypeFromHandleIfExists(IntPtr handle);

private static RuntimeType? GetTypeFromHandle(IntPtr handle)
private static RuntimeType GetRuntimeTypeFromHandle(IntPtr handle)
{
if (handle == IntPtr.Zero)
{
return null;
}

return GetTypeFromHandleIfExists(handle) ?? GetTypeFromHandleSlow(handle);
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved
}

Expand Down Expand Up @@ -386,7 +382,20 @@ public ModuleHandle GetModuleHandle()
internal static extern TypeAttributes GetAttributes(RuntimeType type);

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern RuntimeType GetElementType(RuntimeType type);
private static extern IntPtr GetElementTypeHandle(IntPtr handle);

internal static RuntimeType? GetElementType(RuntimeType type)
{
IntPtr handle = GetElementTypeHandle(type.GetUnderlyingNativeHandle());
if (handle == IntPtr.Zero)
{
return null;
}

RuntimeType result = GetRuntimeTypeFromHandle(handle);
GC.KeepAlive(type);
return result;
}

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool CompareCanonicalHandles(RuntimeType left, RuntimeType right);
Expand Down Expand Up @@ -565,8 +574,38 @@ internal static unsafe MdUtf8String GetUtf8Name(RuntimeType type)
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern bool CanCastTo(RuntimeType type, RuntimeType target);

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern RuntimeType GetDeclaringType(RuntimeType type);
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable")]
private static partial IntPtr GetDeclaringTypeHandleForGenericVariable(IntPtr typeHandle);

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetDeclaringTypeHandle")]
private static partial IntPtr GetDeclaringTypeHandle(IntPtr typeHandle);

internal static unsafe RuntimeType? GetDeclaringType(RuntimeType type)
{
IntPtr retTypeHandle = IntPtr.Zero;
TypeHandle typeHandle = type.GetNativeTypeHandle();
if (typeHandle.IsTypeDesc)
{
CorElementType elementType = (CorElementType)typeHandle.GetCorElementType();
if (elementType is CorElementType.ELEMENT_TYPE_VAR or CorElementType.ELEMENT_TYPE_MVAR)
{
retTypeHandle = GetDeclaringTypeHandleForGenericVariable(type.GetUnderlyingNativeHandle());
}
}
else
{
retTypeHandle = GetDeclaringTypeHandle(type.GetUnderlyingNativeHandle());
}

if (retTypeHandle == IntPtr.Zero)
{
return null;
}

RuntimeType result = GetRuntimeTypeFromHandle(retTypeHandle);
GC.KeepAlive(type);
return result;
}

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern IRuntimeMethodInfo GetDeclaringMethod(RuntimeType type);
Expand Down Expand Up @@ -928,7 +967,14 @@ internal static string ConstructInstantiation(IRuntimeMethodInfo method, TypeNam
}

[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern RuntimeType GetDeclaringType(RuntimeMethodHandleInternal method);
private static extern unsafe MethodTable* GetMethodTable(RuntimeMethodHandleInternal method);
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved

internal static unsafe RuntimeType GetDeclaringType(RuntimeMethodHandleInternal method)
{
Debug.Assert(!method.IsNullHandle());
MethodTable* pMT = GetMethodTable(method);
return RuntimeTypeHandle.GetRuntimeType(pMT);
}

internal static RuntimeType GetDeclaringType(IRuntimeMethodInfo method)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1038,7 +1038,7 @@ private RuntimeType[] PopulateInterfaces(Filter filter)

if (ReflectedType.IsSZArray)
{
RuntimeType arrayType = (RuntimeType)ReflectedType.GetElementType();
RuntimeType arrayType = (RuntimeType)ReflectedType.GetElementType()!;

if (!arrayType.IsPointer)
{
Expand Down Expand Up @@ -1597,7 +1597,7 @@ internal TypeCode TypeCode
if (m_enclosingType == null)
{
// Use void as a marker of null enclosing type
RuntimeType enclosingType = RuntimeTypeHandle.GetDeclaringType(GetRuntimeType());
RuntimeType? enclosingType = RuntimeTypeHandle.GetDeclaringType(GetRuntimeType());
Debug.Assert(enclosingType != typeof(void));
m_enclosingType = enclosingType ?? (RuntimeType)typeof(void);
}
Expand Down
5 changes: 2 additions & 3 deletions src/coreclr/vm/ecalllist.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,11 @@ FCFuncEnd()

FCFuncStart(gCOMTypeHandleFuncs)
FCFuncElement("GetDeclaringMethod", RuntimeTypeHandle::GetDeclaringMethod)
FCFuncElement("GetDeclaringType", RuntimeTypeHandle::GetDeclaringType)
FCFuncElement("GetFirstIntroducedMethod", RuntimeTypeHandle::GetFirstIntroducedMethod)
FCFuncElement("GetNextIntroducedMethod", RuntimeTypeHandle::GetNextIntroducedMethod)
FCFuncElement("GetAssemblyIfExists", RuntimeTypeHandle::GetAssemblyIfExists)
FCFuncElement("GetModuleIfExists", RuntimeTypeHandle::GetModuleIfExists)
FCFuncElement("GetElementType", RuntimeTypeHandle::GetElementType)
FCFuncElement("GetElementTypeHandle", RuntimeTypeHandle::GetElementTypeHandle)
FCFuncElement("GetArrayRank", RuntimeTypeHandle::GetArrayRank)
FCFuncElement("GetToken", RuntimeTypeHandle::GetToken)
FCFuncElement("GetUtf8NameInternal", RuntimeTypeHandle::GetUtf8Name)
Expand Down Expand Up @@ -152,7 +151,7 @@ FCFuncStart(gRuntimeMethodHandle)
FCFuncElement("ReboxToNullable", RuntimeMethodHandle::ReboxToNullable)
FCFuncElement("GetImplAttributes", RuntimeMethodHandle::GetImplAttributes)
FCFuncElement("GetAttributes", RuntimeMethodHandle::GetAttributes)
FCFuncElement("GetDeclaringType", RuntimeMethodHandle::GetDeclaringType)
FCFuncElement("GetMethodTable", RuntimeMethodHandle::GetMethodTable)
FCFuncElement("GetSlot", RuntimeMethodHandle::GetSlot)
FCFuncElement("GetMethodDef", RuntimeMethodHandle::GetMethodDef)
FCFuncElement("GetUtf8NameInternal", RuntimeMethodHandle::GetUtf8Name)
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/vm/qcallentrypoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ static const Entry s_QCall[] =
DllImportEntry(RuntimeTypeHandle_GetNumVirtualsAndStaticVirtuals)
DllImportEntry(RuntimeTypeHandle_VerifyInterfaceIsImplemented)
DllImportEntry(RuntimeTypeHandle_GetInterfaceMethodImplementation)
DllImportEntry(RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable)
DllImportEntry(RuntimeTypeHandle_GetDeclaringTypeHandle)
DllImportEntry(RuntimeTypeHandle_IsVisible)
DllImportEntry(RuntimeTypeHandle_ConstructName)
DllImportEntry(RuntimeTypeHandle_GetInstantiation)
Expand Down
Loading
Loading