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

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
79 changes: 68 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)
internal static RuntimeType GetRuntimeTypeFromHandle(IntPtr handle)
{
if (handle == IntPtr.Zero)
{
return null;
}

return GetTypeFromHandleIfExists(handle) ?? GetTypeFromHandleSlow(handle);
}

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 GetElementTypeHandleFromHandle(IntPtr handle);

internal static RuntimeType? GetElementType(RuntimeType type)
{
IntPtr handle = GetElementTypeHandleFromHandle(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,25 @@ 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);

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeMethodHandle_GetHandleForArray")]
private static unsafe partial IntPtr GetHandleForArray(MethodTable* pMT);

internal static unsafe RuntimeType GetDeclaringType(RuntimeMethodHandleInternal method)
{
Debug.Assert(!method.IsNullHandle());
MethodTable* pMT = GetMethodTable(method);
if (pMT->IsArray)
{
IntPtr handle = GetHandleForArray(pMT);
return RuntimeTypeHandle.GetRuntimeTypeFromHandle(handle);
}
else
{
Comment on lines +979 to +985
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (pMT->IsArray)
{
IntPtr handle = GetHandleForArray(pMT);
return RuntimeTypeHandle.GetRuntimeTypeFromHandle(handle);
}
else
{

I do not think that this is needed. We got rid of the sharing of methodtable for arrays.

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("GetElementTypeHandleFromHandle", RuntimeTypeHandle::GetElementTypeHandleFromHandle)
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
3 changes: 3 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 All @@ -144,6 +146,7 @@ static const Entry s_QCall[] =
DllImportEntry(RuntimeMethodHandle_ConstructInstantiation)
DllImportEntry(RuntimeMethodHandle_GetFunctionPointer)
DllImportEntry(RuntimeMethodHandle_GetIsCollectible)
DllImportEntry(RuntimeMethodHandle_GetHandleForArray)
DllImportEntry(RuntimeMethodHandle_GetMethodInstantiation)
DllImportEntry(RuntimeMethodHandle_GetTypicalMethodDefinition)
DllImportEntry(RuntimeMethodHandle_StripMethodInstantiation)
Expand Down
Loading
Loading