Skip to content

Commit 97db32f

Browse files
Use reflection metadata to represent methods/fields in native layout (#113413)
Native layout is a parallel form of metadata that was introduced in .NET Native mostly because in the structuring of that compiler, the decisions about reflection metadata and decisions about native layout happened in different components written in different languages (reflection metadata in C# during IL2IL transforms, native layout in C++ in NUTC). Native layout has its own representation of methods and fields. There is a bunch of code to read and reconcile those two formats at runtime. This then introduces problems such as in #91381 where updating one format necessitates updating the other one. Instead of adding more code to native layout generation/reading/reconciliation to account for custom modifiers, I'm just deleting ~2000 lines of code responsible for native layout metadata from the product instead. One thing I needed to adjust was that native layout metadata is more compact than reflection metadata - so I added a new way of emitting reflection metadata for methods where the generated method won't have any custom attributes or parameter names. This hobbled method is not reachable with trim safe code. If someone gets a hold of it, more things will be broken than just the ability to invoke it.
1 parent 7a4839b commit 97db32f

File tree

58 files changed

+713
-2244
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+713
-2244
lines changed

src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml

+8-12
Original file line numberDiff line numberDiff line change
@@ -717,18 +717,6 @@
717717
<DiagnosticId>CP0001</DiagnosticId>
718718
<Target>T:Internal.Runtime.CompilerServices.OpenMethodResolver</Target>
719719
</Suppression>
720-
<Suppression>
721-
<DiagnosticId>CP0001</DiagnosticId>
722-
<Target>T:Internal.Runtime.CompilerServices.RuntimeFieldHandleInfo</Target>
723-
</Suppression>
724-
<Suppression>
725-
<DiagnosticId>CP0001</DiagnosticId>
726-
<Target>T:Internal.Runtime.CompilerServices.RuntimeMethodHandleInfo</Target>
727-
</Suppression>
728-
<Suppression>
729-
<DiagnosticId>CP0001</DiagnosticId>
730-
<Target>T:Internal.Runtime.CompilerServices.RuntimeSignature</Target>
731-
</Suppression>
732720
<Suppression>
733721
<DiagnosticId>CP0001</DiagnosticId>
734722
<Target>T:Internal.Runtime.TypeManagerHandle</Target>
@@ -753,6 +741,14 @@
753741
<DiagnosticId>CP0001</DiagnosticId>
754742
<Target>T:System.MDArray</Target>
755743
</Suppression>
744+
<Suppression>
745+
<DiagnosticId>CP0001</DiagnosticId>
746+
<Target>T:System.FieldHandleInfo</Target>
747+
</Suppression>
748+
<Suppression>
749+
<DiagnosticId>CP0001</DiagnosticId>
750+
<Target>T:System.MethodHandleInfo</Target>
751+
</Suppression>
756752
<Suppression>
757753
<DiagnosticId>CP0001</DiagnosticId>
758754
<Target>T:System.Reflection.BinderBundle</Target>

src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/TypeLoaderCallbacks.cs

+2-5
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,10 @@ public abstract class TypeLoaderCallbacks
1919
public abstract bool TryGetConstructedGenericTypeForComponents(RuntimeTypeHandle genericTypeDefinitionHandle, RuntimeTypeHandle[] genericTypeArgumentHandles, out RuntimeTypeHandle runtimeTypeHandle);
2020
public abstract IntPtr GetThreadStaticGCDescForDynamicType(TypeManagerHandle handle, int index);
2121
public abstract IntPtr GenericLookupFromContextAndSignature(IntPtr context, IntPtr signature, out IntPtr auxResult);
22-
public abstract bool GetRuntimeMethodHandleComponents(RuntimeMethodHandle runtimeMethodHandle, out RuntimeTypeHandle declaringTypeHandle, out MethodNameAndSignature nameAndSignature, out RuntimeTypeHandle[] genericMethodArgs);
23-
public abstract RuntimeMethodHandle GetRuntimeMethodHandleForComponents(RuntimeTypeHandle declaringTypeHandle, string methodName, RuntimeSignature methodSignature, RuntimeTypeHandle[] genericMethodArgs);
24-
public abstract bool CompareMethodSignatures(RuntimeSignature signature1, RuntimeSignature signature2);
22+
public abstract RuntimeMethodHandle GetRuntimeMethodHandleForComponents(RuntimeTypeHandle declaringTypeHandle, MethodHandle handle, RuntimeTypeHandle[] genericMethodArgs);
2523
public abstract IntPtr TryGetDefaultConstructorForType(RuntimeTypeHandle runtimeTypeHandle);
2624
public abstract IntPtr ResolveGenericVirtualMethodTarget(RuntimeTypeHandle targetTypeHandle, RuntimeMethodHandle declMethod);
27-
public abstract bool GetRuntimeFieldHandleComponents(RuntimeFieldHandle runtimeFieldHandle, out RuntimeTypeHandle declaringTypeHandle, out string fieldName);
28-
public abstract RuntimeFieldHandle GetRuntimeFieldHandleForComponents(RuntimeTypeHandle declaringTypeHandle, string fieldName);
25+
public abstract RuntimeFieldHandle GetRuntimeFieldHandleForComponents(RuntimeTypeHandle declaringTypeHandle, FieldHandle handle);
2926
public abstract bool TryGetPointerTypeForTargetType(RuntimeTypeHandle pointeeTypeHandle, out RuntimeTypeHandle pointerTypeHandle);
3027
public abstract bool TryGetArrayTypeForElementType(RuntimeTypeHandle elementTypeHandle, bool isMdArray, int rank, out RuntimeTypeHandle arrayTypeHandle);
3128
/// <summary>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Diagnostics;
6+
7+
using Internal.Metadata.NativeFormat;
8+
9+
namespace Internal.Runtime.CompilerServices
10+
{
11+
[CLSCompliant(false)]
12+
public class MethodNameAndSignature
13+
{
14+
public MetadataReader Reader { get; }
15+
public MethodHandle Handle { get; }
16+
17+
public MethodNameAndSignature(MetadataReader reader, MethodHandle handle)
18+
{
19+
Reader = reader;
20+
Handle = handle;
21+
}
22+
23+
public string GetName()
24+
{
25+
Method method = Reader.GetMethod(Handle);
26+
return Reader.GetString(method.Name);
27+
}
28+
29+
public override bool Equals(object? compare)
30+
{
31+
if (compare == null)
32+
return false;
33+
34+
MethodNameAndSignature? other = compare as MethodNameAndSignature;
35+
if (other == null)
36+
return false;
37+
38+
// Comparing handles is enough if there's only one metadata blob
39+
// (Same assumption in GetHashCode below!)
40+
Debug.Assert(Reader == other.Reader);
41+
42+
Method thisMethod = Reader.GetMethod(Handle);
43+
Method otherMethod = other.Reader.GetMethod(other.Handle);
44+
45+
return thisMethod.Signature.Equals(otherMethod.Signature)
46+
&& thisMethod.Name.Equals(otherMethod.Name);
47+
}
48+
49+
public override int GetHashCode()
50+
{
51+
Method method = Reader.GetMethod(Handle);
52+
53+
// Assumes we only have one metadata blob
54+
return method.Signature.GetHashCode() ^ method.Name.GetHashCode();
55+
}
56+
}
57+
}

src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/RuntimeFieldHandleInfo.cs

-15
This file was deleted.

src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/RuntimeMethodHandleInfo.cs

-53
This file was deleted.

src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerServices/RuntimeSignature.cs

-127
This file was deleted.

src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj

+1-3
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,7 @@
119119
<Compile Include="Internal\Runtime\CompilerHelpers\MathHelpers.cs" />
120120
<Compile Include="Internal\Runtime\CompilerServices\FunctionPointerOps.cs" />
121121
<Compile Include="Internal\Runtime\CompilerServices\GenericMethodDescriptor.cs" />
122-
<Compile Include="Internal\Runtime\CompilerServices\RuntimeFieldHandleInfo.cs" />
123-
<Compile Include="Internal\Runtime\CompilerServices\RuntimeMethodHandleInfo.cs" />
124-
<Compile Include="Internal\Runtime\CompilerServices\RuntimeSignature.cs" />
122+
<Compile Include="Internal\Runtime\CompilerServices\MethodNameAndSignature.cs" />
125123
<Compile Include="Internal\Runtime\CompilerServices\OpenMethodResolver.cs" />
126124
<Compile Include="Internal\Runtime\TypeLoaderExceptionHelper.cs" />
127125
<Compile Include="Internal\DeveloperExperience\DeveloperExperience.cs" />

src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ public sealed override RuntimeFieldHandle FieldHandle
130130
{
131131
return RuntimeAugments.TypeLoaderCallbacks.GetRuntimeFieldHandleForComponents(
132132
DeclaringType.TypeHandle,
133-
Name);
133+
_fieldHandle);
134134
}
135135
}
136136

src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/NativeFormat/NativeFormatMethodCommon.cs

+1-4
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,9 @@ public RuntimeMethodHandle GetRuntimeMethodHandle(Type[] genericArgs)
201201
genericArgHandles = null;
202202
}
203203

204-
TypeManagerHandle typeManager = RuntimeAugments.TypeLoaderCallbacks.GetModuleForMetadataReader(Reader);
205-
206204
return RuntimeAugments.TypeLoaderCallbacks.GetRuntimeMethodHandleForComponents(
207205
DeclaringType.TypeHandle,
208-
Name,
209-
RuntimeSignature.CreateFromMethodHandle(typeManager, MethodHandle.AsInt()),
206+
_methodHandle,
210207
genericArgHandles);
211208
}
212209

0 commit comments

Comments
 (0)