Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Wrighton <davidwr@microsoft.com>2021-05-31 10:36:24 +0300
committerGitHub <noreply@github.com>2021-05-31 10:36:24 +0300
commitfea7ff2cce79da2df9cf1c50ce215287750f055e (patch)
tree5b233aa1de06132180c823ff3f29d7c240428cf0 /src/coreclr/tools
parent8538a754f4fcbe190d9299d6f153db2cea39748e (diff)
Fix issues with virtuals and mdarrays (#53400)
- Change up the definition of an MDArray which doesn't need a special descriptor in the embedded signature data to match the type of mdarray thay everyone always uses. This fixes the virtual function handling behavior for all reasonable cases. (All cases where the MDArray is used for a base type in the expected fashion.) - Add a devirtualization test for this specific scenario Fixes #52444
Diffstat (limited to 'src/coreclr/tools')
-rw-r--r--src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs10
-rw-r--r--src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs21
-rw-r--r--src/coreclr/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILTestAssembly/Signature.il5
-rw-r--r--src/coreclr/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SignatureTests.cs20
4 files changed, 51 insertions, 5 deletions
diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs
index 9705ccdd179..48ca23cf1ea 100644
--- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs
+++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs
@@ -169,10 +169,16 @@ namespace Internal.TypeSystem.Ecma
var lowerBoundsCount = _reader.ReadCompressedInteger();
int []lowerBounds = lowerBoundsCount > 0 ? new int[lowerBoundsCount] : Array.Empty<int>();
+ bool nonZeroLowerBounds = false;
for (int j = 0; j < lowerBoundsCount; j++)
- lowerBounds[j] = _reader.ReadCompressedSignedInteger();
+ {
+ int loBound = _reader.ReadCompressedSignedInteger();
+ if (loBound != 0)
+ nonZeroLowerBounds = true;
+ lowerBounds[j] = loBound;
+ }
- if (boundsCount != 0 || lowerBoundsCount != 0)
+ if (boundsCount != 0 || lowerBoundsCount != rank || nonZeroLowerBounds)
{
StringBuilder arrayShapeString = new StringBuilder();
arrayShapeString.Append(string.Join(",", bounds));
diff --git a/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs b/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs
index 0d05bb92e09..5a47094605c 100644
--- a/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs
+++ b/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs
@@ -424,10 +424,29 @@ namespace Internal.TypeSystem
if (!emittedWithShape)
{
- shapeEncoder.Shape(rank, ImmutableArray<int>.Empty, ImmutableArray<int>.Empty);
+ shapeEncoder.Shape(rank, ImmutableArray<int>.Empty, GetZeroedImmutableArrayOfSize(rank));
}
}
+ private static ImmutableArray<int>[] ImmutableArraysFilledWithZeroes = CreateStaticArrayOfImmutableArraysFilledWithZeroes(33); // The max rank of an array is 32
+
+ private static ImmutableArray<int> GetZeroedImmutableArrayOfSize(int rank)
+ {
+ if (rank < ImmutableArraysFilledWithZeroes.Length)
+ return ImmutableArraysFilledWithZeroes[rank];
+
+ return new int[rank].ToImmutableArray();
+ }
+ private static ImmutableArray<int>[] CreateStaticArrayOfImmutableArraysFilledWithZeroes(int count)
+ {
+ ImmutableArray<int>[] result = new ImmutableArray<int>[count];
+ for (int i = 0; i < result.Length; i++)
+ {
+ result[i] = new int[i].ToImmutableArray();
+ }
+ return result;
+ }
+
public void EmitAtCurrentIndexStack(BlobBuilder signatureBuilder)
{
if (!Complete)
diff --git a/src/coreclr/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILTestAssembly/Signature.il b/src/coreclr/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILTestAssembly/Signature.il
index 0b9a489f4b8..32e307b7036 100644
--- a/src/coreclr/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILTestAssembly/Signature.il
+++ b/src/coreclr/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILTestAssembly/Signature.il
@@ -34,6 +34,11 @@
{
ret
}
+
+ .method public hidebysig instance int32 [0...,0...] Method5(int32 [0...,], int32 [,]) cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit Atom
diff --git a/src/coreclr/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SignatureTests.cs b/src/coreclr/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SignatureTests.cs
index 0ea96171119..41362ee5856 100644
--- a/src/coreclr/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SignatureTests.cs
+++ b/src/coreclr/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SignatureTests.cs
@@ -95,11 +95,27 @@ namespace TypeSystemTests
MetadataType modOptTester = _testModule.GetType("", "ModOptTester");
MethodSignature methodWithModOpt = modOptTester.GetMethods().Single(m => string.Equals(m.Name, "Method4")).Signature;
- Assert.Equal(6, methodWithModOpt.GetEmbeddedSignatureData().Length);
+ _output.WriteLine($"Found ModOptData '{GetModOptMethodSignatureInfo(methodWithModOpt)}'");
+ Assert.Equal(7, methodWithModOpt.GetEmbeddedSignatureData().Length);
Assert.Equal(MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(0), methodWithModOpt.GetEmbeddedSignatureData()[0].index);
Assert.Equal(MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(1), methodWithModOpt.GetEmbeddedSignatureData()[2].index);
Assert.Equal(MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(2), methodWithModOpt.GetEmbeddedSignatureData()[4].index);
- Assert.Equal("OptionalCustomModifier0.1.1.2.1.1VoidArrayShape1.2.1.1|3,4|0,1<null>OptionalCustomModifier0.1.1.2.2.1FooModifierArrayShape1.2.2.1|0,9|2,0<null>OptionalCustomModifier0.1.1.2.3.1FooModifierArrayShape1.2.3.1||0<null>", GetModOptMethodSignatureInfo(methodWithModOpt));
+ Assert.Equal("OptionalCustomModifier0.1.1.2.1.1VoidArrayShape1.2.1.1|3,4|0,1<null>OptionalCustomModifier0.1.1.2.2.1FooModifierArrayShape1.2.2.1|0,9|2,0<null>OptionalCustomModifier0.1.1.2.3.1FooModifierArrayShape1.2.3.1||0<null>ArrayShape1.2.4.1||<null>", GetModOptMethodSignatureInfo(methodWithModOpt));
+ }
+
+ [Fact]
+ public void TestSignatureMatchesForArrayShapeDetails_HandlingOfCasesWhichDoNotNeedEmbeddeSignatureData()
+ {
+ // Test that ensure the typical case (where the loBounds is 0, and the hibounds is unspecified) doesn't produce an
+ // EmbeddedSignatureData, but that other cases do. This isn't a complete test as ilasm won't actually properly generate the metadata for many of these cases
+ MetadataType modOptTester = _testModule.GetType("", "ModOptTester");
+ MethodSignature methodWithModOpt = modOptTester.GetMethods().Single(m => string.Equals(m.Name, "Method5")).Signature;
+
+ _output.WriteLine($"Found ModOptData '{GetModOptMethodSignatureInfo(methodWithModOpt)}'");
+ Assert.Equal(2, methodWithModOpt.GetEmbeddedSignatureData().Length);
+ Assert.EndsWith(methodWithModOpt.GetEmbeddedSignatureData()[0].index.Split('|')[0], MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(1));
+ Assert.EndsWith(methodWithModOpt.GetEmbeddedSignatureData()[1].index.Split('|')[0], MethodSignature.GetIndexOfCustomModifierOnPointedAtTypeByParameterIndex(2));
+ Assert.Equal("ArrayShape1.2.2.1||0<null>ArrayShape1.2.3.1||<null>", GetModOptMethodSignatureInfo(methodWithModOpt));
}
[Fact]