diff --git a/src/coreclr/src/tools/Common/Compiler/TypeExtensions.cs b/src/coreclr/src/tools/Common/Compiler/TypeExtensions.cs
index 89fd08f3dbab42..dd54a1387bdf9e 100644
--- a/src/coreclr/src/tools/Common/Compiler/TypeExtensions.cs
+++ b/src/coreclr/src/tools/Common/Compiler/TypeExtensions.cs
@@ -97,6 +97,19 @@ public static bool IsArrayAddressMethod(this MethodDesc method)
return arrayMethod != null && arrayMethod.Kind == ArrayMethodKind.Address;
}
+
+ ///
+ /// Returns true if '' is one of the special methods on multidimensional array types (set, get, address).
+ ///
+ public static bool IsArrayMethod(this MethodDesc method)
+ {
+ var arrayMethod = method as ArrayMethod;
+ return arrayMethod != null && (arrayMethod.Kind == ArrayMethodKind.Address ||
+ arrayMethod.Kind == ArrayMethodKind.Get ||
+ arrayMethod.Kind == ArrayMethodKind.Set ||
+ arrayMethod.Kind == ArrayMethodKind.Ctor);
+ }
+
///
/// Gets a value indicating whether this type has any generic virtual methods.
///
diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.cs
index 54b9849aed8cef..fd80e7e74a582a 100644
--- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.cs
+++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/SignatureBuilder.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Reflection.Metadata;
+using System.Reflection.Metadata.Ecma335;
using Internal.TypeSystem;
using Internal.TypeSystem.Ecma;
@@ -441,11 +442,18 @@ public void EmitMethodSignature(
// Owner type is needed for type specs to instantiating stubs or generics with signature variables still present
if (!method.Method.OwningType.IsDefType &&
- ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_InstantiatingStub) != 0 || method.Method.OwningType.ContainsSignatureVariables())
- || method.Method.IsArrayAddressMethod())
+ ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_InstantiatingStub) != 0 || method.Method.OwningType.ContainsSignatureVariables()))
{
flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType;
}
+ else if (method.Method.IsArrayMethod())
+ {
+ var memberRefMethod = method.Token.Module.GetMethod(MetadataTokens.EntityHandle((int)method.Token.Token));
+ if (memberRefMethod.OwningType != method.Method.OwningType)
+ {
+ flags |= (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType;
+ }
+ }
EmitUInt(flags);
if ((flags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0)
diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets
index e33de4df6132f4..ac5addebf4b3ba 100644
--- a/src/coreclr/tests/issues.targets
+++ b/src/coreclr/tests/issues.targets
@@ -920,9 +920,6 @@
https://github.com/dotnet/runtime/issues/38096
-
- https://github.com/dotnet/runtime/issues/38260
-
https://github.com/dotnet/runtime/issues/7597
@@ -959,9 +956,6 @@
https://github.com/dotnet/runtime/issues/38290
-
- https://github.com/dotnet/runtime/issues/38260
-
https://github.com/dotnet/runtime/issues/32728
diff --git a/src/tests/readytorun/crossgen2/Program.cs b/src/tests/readytorun/crossgen2/Program.cs
index bd00957a758409..e2da7433754608 100644
--- a/src/tests/readytorun/crossgen2/Program.cs
+++ b/src/tests/readytorun/crossgen2/Program.cs
@@ -1626,6 +1626,145 @@ private static bool GenericLdtokenTest()
return true;
}
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static bool CheckArrayVal(ref T refVal, T testValue) where T:IEquatable
+ {
+ return refVal.Equals(testValue);
+ }
+
+ struct SomeLargeStruct : IEquatable
+ {
+ public SomeLargeStruct(int _xVal)
+ {
+ x = _xVal;
+ y = 0;
+ z = 0;
+ w = 0;
+ }
+ public int x;
+ public int y;
+ public int z;
+ public int w;
+
+ public bool Equals(SomeLargeStruct other)
+ {
+ return (x == other.x) && (y == other.y) && (z == other.z) && (w == other.w);
+ }
+ public override bool Equals(object other)
+ {
+ return Equals((SomeLargeStruct)other);
+ }
+
+ public override int GetHashCode() { return x; }
+ }
+
+ class SomeClass : IEquatable
+ {
+ public SomeClass(int _xVal)
+ {
+ x = _xVal;
+ y = 0;
+ z = 0;
+ w = 0;
+ }
+ public int x;
+ public int y;
+ public int z;
+ public int w;
+
+ public bool Equals(SomeClass other)
+ {
+ return (x == other.x) && (y == other.y) && (z == other.z) && (w == other.w);
+ }
+ public override bool Equals(object other)
+ {
+ return Equals((SomeClass)other);
+ }
+
+ public override int GetHashCode() { return x; }
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static bool DoLargeStructMDArrayTest(SomeLargeStruct testValue)
+ {
+ SomeLargeStruct[,] array = new SomeLargeStruct[2,2];
+ array[0,0] = testValue;
+ if (!CheckArrayVal(ref array[0,0], testValue))
+ {
+ return false;
+ }
+ if (!testValue.Equals(array[0,0]))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static bool DoGenericArrayTest (T testValue) where T:IEquatable
+ {
+ T[,] array = new T[2,2];
+ array[0,0] = testValue;
+ if (!CheckArrayVal(ref array[0,0], testValue))
+ {
+ return false;
+ }
+ if (!testValue.Equals(array[0,0]))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static bool TestGenericMDArrayBehavior()
+ {
+ if (!DoGenericArrayTest(42))
+ {
+ return false;
+ }
+
+ if (!DoGenericArrayTest(new SomeClass(42)))
+ {
+ return false;
+ }
+
+ SomeLargeStruct testStruct = new SomeLargeStruct(42);
+ if (!DoGenericArrayTest(testStruct))
+ {
+ return false;
+ }
+
+ if (!DoLargeStructMDArrayTest(testStruct))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static bool ArrayLdtokenTests()
+ {
+ // We're testing that mapping from ldtoken to RuntimeMethodHandle works for various ways that
+ // ldtokens can be referenced (either via a generic token, or not.
+ // (there are slightly different codepaths in crossgen for this)
+ // Incorrect encoding will trigger a BadImageFormatException
+ RuntimeMethodHandle rmhCtor1 = default(RuntimeMethodHandle);
+ RuntimeMethodHandle rmhCtor2 = default(RuntimeMethodHandle);
+ RuntimeMethodHandle rmhSet = default(RuntimeMethodHandle);
+ RuntimeMethodHandle rmhGet = default(RuntimeMethodHandle);
+ RuntimeMethodHandle rmhAddress = default(RuntimeMethodHandle);
+ HelperGenericILCode.LdTokenArrayMethods(ref rmhCtor1, ref rmhCtor2, ref rmhSet, ref rmhGet, ref rmhAddress);
+ HelperGenericILCode