From 984b2a8e334ce4d3dfb81f3d5bc50fd69fae28de Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Mon, 20 Apr 2020 18:52:47 -0700 Subject: [PATCH 01/14] Interesting type layout test cases --- .../src/readytorun/crossboundarylayout/a/a.cs | 82 +++++ .../readytorun/crossboundarylayout/a/a.csproj | 14 + .../src/readytorun/crossboundarylayout/b/b.cs | 218 ++++++++++++ .../readytorun/crossboundarylayout/b/b.csproj | 15 + .../buildcrossgen2image.cmd | 18 + .../crossboundarytest/c.cs | 313 ++++++++++++++++++ .../crossboundarytest.csproj | 18 + .../crossboundarytest/main.cs | 20 ++ .../crossboundarytests.cmd | 13 + .../src/readytorun/crossboundarylayout/d/d.cs | 13 + .../readytorun/crossboundarylayout/d/d.csproj | 10 + .../crossboundarylayout/runindividualtest.cmd | 15 + 12 files changed, 749 insertions(+) create mode 100644 src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs create mode 100644 src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.csproj create mode 100644 src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.cs create mode 100644 src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.csproj create mode 100644 src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd create mode 100644 src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c.cs create mode 100644 src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/crossboundarytest.csproj create mode 100644 src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/main.cs create mode 100644 src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd create mode 100644 src/coreclr/tests/src/readytorun/crossboundarylayout/d/d.cs create mode 100644 src/coreclr/tests/src/readytorun/crossboundarylayout/d/d.csproj create mode 100644 src/coreclr/tests/src/readytorun/crossboundarylayout/runindividualtest.cmd diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs b/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs new file mode 100644 index 00000000000000..cb1a9d1c0bd411 --- /dev/null +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs @@ -0,0 +1,82 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace CrossBoundaryLayout +{ + public class A + { + public byte _aVal; + } + + public class AGeneric + { + public T _aVal; + } + + public class ABoringGeneric + { + public byte _aVal; + } + + public class ATest + { + public static int Test() + { + int failure = 0; + { + var a = (A)Activator.CreateInstance(typeof(A)); + a._aVal = 1; + if (1 != (byte)typeof(A).GetField("_aVal").GetValue(a)) + { + failure++; + Console.WriteLine("A a._aVal"); + } + } + + { + var a2 = (AGeneric)Activator.CreateInstance(typeof(AGeneric)); + a2._aVal = 1; + if (1 != (byte)typeof(AGeneric).GetField("_aVal").GetValue(a2)) + { + failure++; + Console.WriteLine("A a2_aVal"); + } + } + + { + var a3 = (AGeneric)Activator.CreateInstance(typeof(AGeneric)); + a3._aVal._dVal = 1; + if (1 != ((ByteStruct)typeof(AGeneric).GetField("_aVal").GetValue(a3))._dVal) + { + failure++; + Console.WriteLine("A a3_aVal"); + } + } + + { + var a4 = (ABoringGeneric)Activator.CreateInstance(typeof(ABoringGeneric)); + a4._aVal = 1; + if (1 != (byte)typeof(ABoringGeneric).GetField("_aVal").GetValue(a4)) + { + failure++; + Console.WriteLine("A a4_aVal"); + } + } + + { + var a5 = (ABoringGeneric)Activator.CreateInstance(typeof(ABoringGeneric)); + a5._aVal = 1; + if (1 != (byte)typeof(ABoringGeneric).GetField("_aVal").GetValue(a5)) + { + failure++; + Console.WriteLine("A a5_aVal"); + } + } + + return failure; + } + } +} \ No newline at end of file diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.csproj b/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.csproj new file mode 100644 index 00000000000000..6e3c26249fc0e7 --- /dev/null +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.csproj @@ -0,0 +1,14 @@ + + + library + SharedLibrary + + + + + + + + + + diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.cs b/src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.cs new file mode 100644 index 00000000000000..86d5490d7ed3fd --- /dev/null +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.cs @@ -0,0 +1,218 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace CrossBoundaryLayout +{ + public class B_A : A + { + public byte _bVal; + } + + public class B_A_byte : AGeneric + { + public byte _bVal; + } + + public class B_A_D : AGeneric + { + public byte _bVal; + } + + public class B_A_Generic : A + { + public T _bVal; + } + + public class B_A_byte_Generic : AGeneric + { + public T _bVal; + } + + public class B_A_D_Generic : AGeneric + { + public T _bVal; + } + + public class B_ABoring_byte : ABoringGeneric + { + public byte _bVal; + } + + public class B_ABoring_D : ABoringGeneric + { + public byte _bVal; + } + + public class BTest + { + public static int Test() + { + int failure = 0; + { + var a = (A)Activator.CreateInstance(typeof(A)); + a._aVal = 1; + if (1 != (byte)typeof(A).GetField("_aVal").GetValue(a)) + { + failure++; + Console.WriteLine("B a._aVal"); + } + } + + { + var a2 = (AGeneric)Activator.CreateInstance(typeof(AGeneric)); + a2._aVal = 1; + if (1 != (byte)typeof(AGeneric).GetField("_aVal").GetValue(a2)) + { + failure++; + Console.WriteLine("B a2_aVal"); + } + } + + { + var a3 = (AGeneric)Activator.CreateInstance(typeof(AGeneric)); + a3._aVal._dVal = 1; + if (1 != ((ByteStruct)typeof(AGeneric).GetField("_aVal").GetValue(a3))._dVal) + { + failure++; + Console.WriteLine("B a3_aVal"); + } + } + + { + var a4 = (ABoringGeneric)Activator.CreateInstance(typeof(ABoringGeneric)); + a4._aVal = 1; + if (1 != (byte)typeof(ABoringGeneric).GetField("_aVal").GetValue(a4)) + { + failure++; + Console.WriteLine("B a4_aVal"); + } + } + + { + var a5 = (ABoringGeneric)Activator.CreateInstance(typeof(ABoringGeneric)); + a5._aVal = 1; + if (1 != (byte)typeof(ABoringGeneric).GetField("_aVal").GetValue(a5)) + { + failure++; + Console.WriteLine("B a5_aVal"); + } + } + + + { + var b = (B_A)Activator.CreateInstance(typeof(B_A)); + b._bVal = 1; + if (1 != (byte)typeof(B_A).GetField("_bVal").GetValue(b)) + { + failure++; + Console.WriteLine("B b._bVal"); + } + } + + { + var b2 = (B_A_byte)Activator.CreateInstance(typeof(B_A_byte)); + b2._bVal = 1; + if (1 != (byte)typeof(B_A_byte).GetField("_bVal").GetValue(b2)) + { + failure++; + Console.WriteLine("B b2._bVal"); + } + } + + { + var b3 = (B_A_D)Activator.CreateInstance(typeof(B_A_D)); + b3._bVal = 1; + if (1 != (byte)typeof(B_A_D).GetField("_bVal").GetValue(b3)) + { + failure++; + Console.WriteLine("B b3._bVal"); + } + } + + { + var b4 = (B_A_Generic)Activator.CreateInstance(typeof(B_A_Generic)); + b4._bVal = 1; + if (1 != (byte)typeof(B_A_Generic).GetField("_bVal").GetValue(b4)) + { + failure++; + Console.WriteLine("B b4._bVal"); + } + } + + { + var b5 = (B_A_byte_Generic)Activator.CreateInstance(typeof(B_A_byte_Generic)); + b5._bVal = 1; + if (1 != (byte)typeof(B_A_byte_Generic).GetField("_bVal").GetValue(b5)) + { + failure++; + Console.WriteLine("B b5._bVal"); + } + } + + { + var b6 = (B_A_D_Generic)Activator.CreateInstance(typeof(B_A_D_Generic)); + b6._bVal = 1; + if (1 != (byte)typeof(B_A_D_Generic).GetField("_bVal").GetValue(b6)) + { + failure++; + Console.WriteLine("B b6._bVal"); + } + } + + { + var b7 = (B_A_Generic)Activator.CreateInstance(typeof(B_A_Generic)); + b7._bVal._dVal = 1; + if (1 != ((ByteStruct)typeof(B_A_Generic).GetField("_bVal").GetValue(b7))._dVal) + { + failure++; + Console.WriteLine("B b7._bVal"); + } + } + + { + var b8 = (B_A_byte_Generic)Activator.CreateInstance(typeof(B_A_byte_Generic)); + b8._bVal._dVal = 1; + if (1 != ((ByteStruct)typeof(B_A_byte_Generic).GetField("_bVal").GetValue(b8))._dVal) + { + failure++; + Console.WriteLine("B b8._bVal"); + } + } + + { + var b9 = (B_A_D_Generic)Activator.CreateInstance(typeof(B_A_D_Generic)); + b9._bVal._dVal = 1; + if (1 != ((ByteStruct)typeof(B_A_D_Generic).GetField("_bVal").GetValue(b9))._dVal) + { + failure++; + Console.WriteLine("B b9._bVal"); + } + } + + { + var b10 = (B_ABoring_byte)Activator.CreateInstance(typeof(B_ABoring_byte)); + b10._bVal = 1; + if (1 != (byte)typeof(B_ABoring_byte).GetField("_bVal").GetValue(b10)) + { + failure++; + Console.WriteLine("B b10._bVal"); + } + } + + { + var b11 = (B_ABoring_D)Activator.CreateInstance(typeof(B_ABoring_D)); + b11._bVal = 1; + if (1 != (byte)typeof(B_ABoring_D).GetField("_bVal").GetValue(b11)) + { + failure++; + Console.WriteLine("B b11._bVal"); + } + } + + return failure; + } + } +} \ No newline at end of file diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.csproj b/src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.csproj new file mode 100644 index 00000000000000..4af26f07b3fe4e --- /dev/null +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.csproj @@ -0,0 +1,15 @@ + + + library + SharedLibrary + + + + + + + + + + + diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd b/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd new file mode 100644 index 00000000000000..1d2d9464e3a16c --- /dev/null +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd @@ -0,0 +1,18 @@ +@echo off +setlocal +set COMPOSITENAME= +set COMPILEARG= +set TESTINITIALBINPATH=%2 +set TESTTARGET_DIR=%3 +set TESTBATCHROOT=%1 + +:Loop +if "%4"=="" goto Continue +set COMPILEARG=%COMPILEARG% %TESTINITIALBINPATH%\%4.dll +set COMPOSITENAME=%COMPOSITENAME%%4 +shift +goto Loop +:Continue + +echo on +call %TESTBATCHROOT%\..\..\..\..\..\..\.dotnet\dotnet %CORE_ROOT%\crossgen2\crossgen2.dll -r %CORE_ROOT%\* -r %TESTINITIALBINPATH%\*.dll -o %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%Composite.dll --composite %COMPILEARG% \ No newline at end of file diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c.cs b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c.cs new file mode 100644 index 00000000000000..ee726e076bac5c --- /dev/null +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c.cs @@ -0,0 +1,313 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace CrossBoundaryLayout +{ + class C_B_A : B_A + { + public byte _cVal; + } + + class C_B_A_byte : B_A_byte + { + public byte _cVal; + } + + class C_B_A_D : B_A_D + { + public byte _cVal; + } + + class C_B_A_Generic_byte : B_A_Generic + { + public byte _cVal; + } + + class C_B_A_Generic_D : B_A_Generic + { + public byte _cVal; + } + + class C_B_A_byte_Generic_byte : B_A_byte_Generic + { + public byte _cVal; + } + + class C_B_A_byte_Generic_D : B_A_byte_Generic + { + public byte _cVal; + } + + class C_B_A_D_Generic_byte : B_A_D_Generic + { + public byte _cVal; + } + + class C_B_A_D_Generic_D : B_A_D_Generic + { + public byte _cVal; + } + + public class CTest + { + public static int Test() + { + int failure = 0; + { + var a = (A)Activator.CreateInstance(typeof(A)); + a._aVal = 1; + if (1 != (byte)typeof(A).GetField("_aVal").GetValue(a)) + { + failure++; + Console.WriteLine("C a._aVal"); + } + } + + { + var a2 = (AGeneric)Activator.CreateInstance(typeof(AGeneric)); + a2._aVal = 1; + if (1 != (byte)typeof(AGeneric).GetField("_aVal").GetValue(a2)) + { + failure++; + Console.WriteLine("C a2_aVal"); + } + } + + { + var a3 = (AGeneric)Activator.CreateInstance(typeof(AGeneric)); + a3._aVal._dVal = 1; + if (1 != ((ByteStruct)typeof(AGeneric).GetField("_aVal").GetValue(a3))._dVal) + { + failure++; + Console.WriteLine("C a3_aVal"); + } + } + + { + var a4 = (ABoringGeneric)Activator.CreateInstance(typeof(ABoringGeneric)); + a4._aVal = 1; + if (1 != (byte)typeof(ABoringGeneric).GetField("_aVal").GetValue(a4)) + { + failure++; + Console.WriteLine("C a4_aVal"); + } + } + + { + var a5 = (ABoringGeneric)Activator.CreateInstance(typeof(ABoringGeneric)); + a5._aVal = 1; + if (1 != (byte)typeof(ABoringGeneric).GetField("_aVal").GetValue(a5)) + { + failure++; + Console.WriteLine("C a5_aVal"); + } + } + + { + var b = (B_A)Activator.CreateInstance(typeof(B_A)); + b._bVal = 1; + if (1 != (byte)typeof(B_A).GetField("_bVal").GetValue(b)) + { + failure++; + Console.WriteLine("C b._bVal"); + } + } + + { + var b2 = (B_A_byte)Activator.CreateInstance(typeof(B_A_byte)); + b2._bVal = 1; + if (1 != (byte)typeof(B_A_byte).GetField("_bVal").GetValue(b2)) + { + failure++; + Console.WriteLine("C b2._bVal"); + } + } + + { + var b3 = (B_A_D)Activator.CreateInstance(typeof(B_A_D)); + b3._bVal = 1; + if (1 != (byte)typeof(B_A_D).GetField("_bVal").GetValue(b3)) + { + failure++; + Console.WriteLine("C b3._bVal"); + } + } + + { + var b4 = (B_A_Generic)Activator.CreateInstance(typeof(B_A_Generic)); + b4._bVal = 1; + if (1 != (byte)typeof(B_A_Generic).GetField("_bVal").GetValue(b4)) + { + failure++; + Console.WriteLine("C b4._bVal"); + } + } + + { + var b5 = (B_A_byte_Generic)Activator.CreateInstance(typeof(B_A_byte_Generic)); + b5._bVal = 1; + if (1 != (byte)typeof(B_A_byte_Generic).GetField("_bVal").GetValue(b5)) + { + failure++; + Console.WriteLine("C b5._bVal"); + } + } + + { + var b6 = (B_A_D_Generic)Activator.CreateInstance(typeof(B_A_D_Generic)); + b6._bVal = 1; + if (1 != (byte)typeof(B_A_D_Generic).GetField("_bVal").GetValue(b6)) + { + failure++; + Console.WriteLine("C b6._bVal"); + } + } + + { + var b7 = (B_A_Generic)Activator.CreateInstance(typeof(B_A_Generic)); + b7._bVal._dVal = 1; + if (1 != ((ByteStruct)typeof(B_A_Generic).GetField("_bVal").GetValue(b7))._dVal) + { + failure++; + Console.WriteLine("C b7._bVal"); + } + } + + { + var b8 = (B_A_byte_Generic)Activator.CreateInstance(typeof(B_A_byte_Generic)); + b8._bVal._dVal = 1; + if (1 != ((ByteStruct)typeof(B_A_byte_Generic).GetField("_bVal").GetValue(b8))._dVal) + { + failure++; + Console.WriteLine("C b8._bVal"); + } + } + + { + var b9 = (B_A_D_Generic)Activator.CreateInstance(typeof(B_A_D_Generic)); + b9._bVal._dVal = 1; + if (1 != ((ByteStruct)typeof(B_A_D_Generic).GetField("_bVal").GetValue(b9))._dVal) + { + failure++; + Console.WriteLine("C b9._bVal"); + } + } + + { + var b10 = (B_ABoring_byte)Activator.CreateInstance(typeof(B_ABoring_byte)); + b10._bVal = 1; + if (1 != (byte)typeof(B_ABoring_byte).GetField("_bVal").GetValue(b10)) + { + failure++; + Console.WriteLine("C b10._bVal"); + } + } + + { + var b11 = (B_ABoring_D)Activator.CreateInstance(typeof(B_ABoring_D)); + b11._bVal = 1; + if (1 != (byte)typeof(B_ABoring_D).GetField("_bVal").GetValue(b11)) + { + failure++; + Console.WriteLine("C b11._bVal"); + } + } + + + { + var c = (C_B_A)Activator.CreateInstance(typeof(C_B_A)); + c._cVal = 1; + if (1 != (byte)typeof(C_B_A).GetField("_cVal").GetValue(c)) + { + failure++; + Console.WriteLine("B c._cVal"); + } + } + + { + var c2 = (C_B_A_byte)Activator.CreateInstance(typeof(C_B_A_byte)); + c2._cVal = 1; + if (1 != (byte)typeof(C_B_A_byte).GetField("_cVal").GetValue(c2)) + { + failure++; + Console.WriteLine("B c2._cVal"); + } + } + + { + var c3 = (C_B_A_D)Activator.CreateInstance(typeof(C_B_A_D)); + c3._cVal = 1; + if (1 != (byte)typeof(C_B_A_D).GetField("_cVal").GetValue(c3)) + { + failure++; + Console.WriteLine("B c3._cVal"); + } + } + + { + var c4 = (C_B_A_Generic_byte)Activator.CreateInstance(typeof(C_B_A_Generic_byte)); + c4._cVal = 1; + if (1 != (byte)typeof(C_B_A_Generic_byte).GetField("_cVal").GetValue(c4)) + { + failure++; + Console.WriteLine("B c4._cVal"); + } + } + + { + var c5 = (C_B_A_byte_Generic_byte)Activator.CreateInstance(typeof(C_B_A_byte_Generic_byte)); + c5._cVal = 1; + if (1 != (byte)typeof(C_B_A_byte_Generic_byte).GetField("_cVal").GetValue(c5)) + { + failure++; + Console.WriteLine("B c5._cVal"); + } + } + + { + var c6 = (C_B_A_D_Generic_byte)Activator.CreateInstance(typeof(C_B_A_D_Generic_byte)); + c6._cVal = 1; + if (1 != (byte)typeof(C_B_A_D_Generic_byte).GetField("_cVal").GetValue(c6)) + { + failure++; + Console.WriteLine("B c6._cVal"); + } + } + + { + var c7 = (C_B_A_Generic_D)Activator.CreateInstance(typeof(C_B_A_Generic_D)); + c7._cVal = 1; + if (1 != (byte)typeof(C_B_A_Generic_D).GetField("_cVal").GetValue(c7)) + { + failure++; + Console.WriteLine("B c7._cVal"); + } + } + + { + var c8 = (C_B_A_byte_Generic_D)Activator.CreateInstance(typeof(C_B_A_byte_Generic_D)); + c8._cVal = 1; + if (1 != (byte)typeof(C_B_A_byte_Generic_D).GetField("_cVal").GetValue(c8)) + { + failure++; + Console.WriteLine("B c8._cVal"); + } + } + + { + var c9 = (C_B_A_D_Generic_D)Activator.CreateInstance(typeof(C_B_A_D_Generic_D)); + c9._cVal = 1; + if (1 != (byte)typeof(C_B_A_D_Generic_D).GetField("_cVal").GetValue(c9)) + { + failure++; + Console.WriteLine("B c9._cVal"); + } + } + + return failure; + } + } +} \ No newline at end of file diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/crossboundarytest.csproj b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/crossboundarytest.csproj new file mode 100644 index 00000000000000..7e8eee65132bd2 --- /dev/null +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/crossboundarytest.csproj @@ -0,0 +1,18 @@ + + + exe + 1 + BuildAndRun + + + + + + + + + + + + + diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/main.cs b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/main.cs new file mode 100644 index 00000000000000..3610a86651bf2d --- /dev/null +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/main.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace CrossBoundaryLayout +{ + class Program + { + public static int Main(string[] args) + { + int failure = ATest.Test(); + failure += BTest.Test(); + failure += CTest.Test(); + + return 100 + failure; + } + } +} \ No newline at end of file diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd new file mode 100644 index 00000000000000..eaf14c9f7220ae --- /dev/null +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd @@ -0,0 +1,13 @@ +setlocal +set TESTBATCHROOT=%~dp0 +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %1 all a b crossboundarytest d + +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %1 ad a d + +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %1 abd a b d + +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %1 a_crossboundarytest_d a crossboundarytest d + +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %1 a_b_crossboundarytest a b crossboundarytest + +pushd %TESTBATCHROOT% \ No newline at end of file diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/d/d.cs b/src/coreclr/tests/src/readytorun/crossboundarylayout/d/d.cs new file mode 100644 index 00000000000000..9d6b8bd8ab1667 --- /dev/null +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/d/d.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace CrossBoundaryLayout +{ + public struct ByteStruct + { + public byte _dVal; + } +} \ No newline at end of file diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/d/d.csproj b/src/coreclr/tests/src/readytorun/crossboundarylayout/d/d.csproj new file mode 100644 index 00000000000000..09eb1e5530790e --- /dev/null +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/d/d.csproj @@ -0,0 +1,10 @@ + + + library + SharedLibrary + + + + + + diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/runindividualtest.cmd b/src/coreclr/tests/src/readytorun/crossboundarylayout/runindividualtest.cmd new file mode 100644 index 00000000000000..09c6fc072bf52d --- /dev/null +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/runindividualtest.cmd @@ -0,0 +1,15 @@ +@echo off +setlocal +rd /s /q %2\%3 +md %2\%3 +copy %2\* %2\%3 > nul +call %1\buildcrossgen2image.cmd %1 %2 %3 %4 %5 %6 %7 +@echo on +%CORE_ROOT%\corerun %2\%3\crossboundarytest.dll +@echo off +if ERRORLEVEL 101 ( + echo FAILED + goto done +) +echo PASSED +:done \ No newline at end of file From ec46f20f09b3fbcd33ca934361dd8bc390cc4054 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Mon, 20 Apr 2020 21:29:37 -0700 Subject: [PATCH 02/14] Add tests for cases involving inheritance in a single module --- .../crossboundarytest/c.cs | 18 +- .../crossboundarytest/c1.cs | 407 ++++++++++++++++++ .../crossboundarytest.csproj | 1 + .../crossboundarytest/main.cs | 1 + 4 files changed, 418 insertions(+), 9 deletions(-) create mode 100644 src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c1.cs diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c.cs b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c.cs index ee726e076bac5c..0facb1e7943d2e 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c.cs +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c.cs @@ -223,7 +223,7 @@ public static int Test() if (1 != (byte)typeof(C_B_A).GetField("_cVal").GetValue(c)) { failure++; - Console.WriteLine("B c._cVal"); + Console.WriteLine("C c._cVal"); } } @@ -233,7 +233,7 @@ public static int Test() if (1 != (byte)typeof(C_B_A_byte).GetField("_cVal").GetValue(c2)) { failure++; - Console.WriteLine("B c2._cVal"); + Console.WriteLine("C c2._cVal"); } } @@ -243,7 +243,7 @@ public static int Test() if (1 != (byte)typeof(C_B_A_D).GetField("_cVal").GetValue(c3)) { failure++; - Console.WriteLine("B c3._cVal"); + Console.WriteLine("C c3._cVal"); } } @@ -253,7 +253,7 @@ public static int Test() if (1 != (byte)typeof(C_B_A_Generic_byte).GetField("_cVal").GetValue(c4)) { failure++; - Console.WriteLine("B c4._cVal"); + Console.WriteLine("C c4._cVal"); } } @@ -263,7 +263,7 @@ public static int Test() if (1 != (byte)typeof(C_B_A_byte_Generic_byte).GetField("_cVal").GetValue(c5)) { failure++; - Console.WriteLine("B c5._cVal"); + Console.WriteLine("C c5._cVal"); } } @@ -273,7 +273,7 @@ public static int Test() if (1 != (byte)typeof(C_B_A_D_Generic_byte).GetField("_cVal").GetValue(c6)) { failure++; - Console.WriteLine("B c6._cVal"); + Console.WriteLine("C c6._cVal"); } } @@ -283,7 +283,7 @@ public static int Test() if (1 != (byte)typeof(C_B_A_Generic_D).GetField("_cVal").GetValue(c7)) { failure++; - Console.WriteLine("B c7._cVal"); + Console.WriteLine("C c7._cVal"); } } @@ -293,7 +293,7 @@ public static int Test() if (1 != (byte)typeof(C_B_A_byte_Generic_D).GetField("_cVal").GetValue(c8)) { failure++; - Console.WriteLine("B c8._cVal"); + Console.WriteLine("C c8._cVal"); } } @@ -303,7 +303,7 @@ public static int Test() if (1 != (byte)typeof(C_B_A_D_Generic_D).GetField("_cVal").GetValue(c9)) { failure++; - Console.WriteLine("B c9._cVal"); + Console.WriteLine("C c9._cVal"); } } diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c1.cs b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c1.cs new file mode 100644 index 00000000000000..85c03f6a65e2a1 --- /dev/null +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c1.cs @@ -0,0 +1,407 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace CrossBoundaryLayout +{ + public class A1BoringGeneric + { + public byte _aVal; + } + + public class B1_A : A + { + public byte _bVal; + } + + public class B1_A_byte : AGeneric + { + public byte _bVal; + } + + public class B1_A_D : AGeneric + { + public byte _bVal; + } + + public class B1_A_Generic : A + { + public T _bVal; + } + + public class B1_A_byte_Generic : AGeneric + { + public T _bVal; + } + + public class B1_A_D_Generic : AGeneric + { + public T _bVal; + } + + public class B1_ABoring_byte : ABoringGeneric + { + public byte _bVal; + } + + public class B1_ABoring_D : ABoringGeneric + { + public byte _bVal; + } + + public class B1_A1Boring_byte : A1BoringGeneric + { + public byte _bVal; + } + + public class B1_A1Boring_D : A1BoringGeneric + { + public byte _bVal; + } + + class C1_B_A : B1_A + { + public byte _cVal; + } + + class C1_B_A_byte : B1_A_byte + { + public byte _cVal; + } + + class C1_B_A_D : B1_A_D + { + public byte _cVal; + } + + class C1_B_A_Generic_byte : B1_A_Generic + { + public byte _cVal; + } + + class C1_B_A_Generic_D : B1_A_Generic + { + public byte _cVal; + } + + class C1_B_A_byte_Generic_byte : B1_A_byte_Generic + { + public byte _cVal; + } + + class C1_B_A_byte_Generic_D : B1_A_byte_Generic + { + public byte _cVal; + } + + class C1_B_A_D_Generic_byte : B1_A_D_Generic + { + public byte _cVal; + } + + class C1_B_A_D_Generic_D : B1_A_D_Generic + { + public byte _cVal; + } + + public class C1Test + { + public static int Test() + { + int failure = 0; + { + var a = (A)Activator.CreateInstance(typeof(A)); + a._aVal = 1; + if (1 != (byte)typeof(A).GetField("_aVal").GetValue(a)) + { + failure++; + Console.WriteLine("C1 a._aVal"); + } + } + + { + var a2 = (AGeneric)Activator.CreateInstance(typeof(AGeneric)); + a2._aVal = 1; + if (1 != (byte)typeof(AGeneric).GetField("_aVal").GetValue(a2)) + { + failure++; + Console.WriteLine("C1 a2_aVal"); + } + } + + { + var a3 = (AGeneric)Activator.CreateInstance(typeof(AGeneric)); + a3._aVal._dVal = 1; + if (1 != ((ByteStruct)typeof(AGeneric).GetField("_aVal").GetValue(a3))._dVal) + { + failure++; + Console.WriteLine("C1 a3_aVal"); + } + } + + { + var a4 = (ABoringGeneric)Activator.CreateInstance(typeof(ABoringGeneric)); + a4._aVal = 1; + if (1 != (byte)typeof(ABoringGeneric).GetField("_aVal").GetValue(a4)) + { + failure++; + Console.WriteLine("C1 a4_aVal"); + } + } + + { + var a5 = (ABoringGeneric)Activator.CreateInstance(typeof(ABoringGeneric)); + a5._aVal = 1; + if (1 != (byte)typeof(ABoringGeneric).GetField("_aVal").GetValue(a5)) + { + failure++; + Console.WriteLine("C1 a5_aVal"); + } + } + + { + var a6 = (A1BoringGeneric)Activator.CreateInstance(typeof(A1BoringGeneric)); + a6._aVal = 1; + if (1 != (byte)typeof(A1BoringGeneric).GetField("_aVal").GetValue(a6)) + { + failure++; + Console.WriteLine("C1 a6_aVal"); + } + } + + { + var a7 = (A1BoringGeneric)Activator.CreateInstance(typeof(A1BoringGeneric)); + a7._aVal = 1; + if (1 != (byte)typeof(A1BoringGeneric).GetField("_aVal").GetValue(a7)) + { + failure++; + Console.WriteLine("C1 a7_aVal"); + } + } + + { + var b = (B1_A)Activator.CreateInstance(typeof(B1_A)); + b._bVal = 1; + if (1 != (byte)typeof(B1_A).GetField("_bVal").GetValue(b)) + { + failure++; + Console.WriteLine("C1 b._bVal"); + } + } + + { + var b2 = (B1_A_byte)Activator.CreateInstance(typeof(B1_A_byte)); + b2._bVal = 1; + if (1 != (byte)typeof(B1_A_byte).GetField("_bVal").GetValue(b2)) + { + failure++; + Console.WriteLine("C1 b2._bVal"); + } + } + + { + var b3 = (B1_A_D)Activator.CreateInstance(typeof(B1_A_D)); + b3._bVal = 1; + if (1 != (byte)typeof(B1_A_D).GetField("_bVal").GetValue(b3)) + { + failure++; + Console.WriteLine("C1 b3._bVal"); + } + } + + { + var b4 = (B1_A_Generic)Activator.CreateInstance(typeof(B1_A_Generic)); + b4._bVal = 1; + if (1 != (byte)typeof(B1_A_Generic).GetField("_bVal").GetValue(b4)) + { + failure++; + Console.WriteLine("C1 b4._bVal"); + } + } + + { + var b5 = (B1_A_byte_Generic)Activator.CreateInstance(typeof(B1_A_byte_Generic)); + b5._bVal = 1; + if (1 != (byte)typeof(B1_A_byte_Generic).GetField("_bVal").GetValue(b5)) + { + failure++; + Console.WriteLine("C1 b5._bVal"); + } + } + + { + var b6 = (B1_A_D_Generic)Activator.CreateInstance(typeof(B1_A_D_Generic)); + b6._bVal = 1; + if (1 != (byte)typeof(B1_A_D_Generic).GetField("_bVal").GetValue(b6)) + { + failure++; + Console.WriteLine("C1 b6._bVal"); + } + } + + { + var b7 = (B1_A_Generic)Activator.CreateInstance(typeof(B1_A_Generic)); + b7._bVal._dVal = 1; + if (1 != ((ByteStruct)typeof(B1_A_Generic).GetField("_bVal").GetValue(b7))._dVal) + { + failure++; + Console.WriteLine("C1 b7._bVal"); + } + } + + { + var b8 = (B1_A_byte_Generic)Activator.CreateInstance(typeof(B1_A_byte_Generic)); + b8._bVal._dVal = 1; + if (1 != ((ByteStruct)typeof(B1_A_byte_Generic).GetField("_bVal").GetValue(b8))._dVal) + { + failure++; + Console.WriteLine("C1 b8._bVal"); + } + } + + { + var b9 = (B1_A_D_Generic)Activator.CreateInstance(typeof(B1_A_D_Generic)); + b9._bVal._dVal = 1; + if (1 != ((ByteStruct)typeof(B1_A_D_Generic).GetField("_bVal").GetValue(b9))._dVal) + { + failure++; + Console.WriteLine("C1 b9._bVal"); + } + } + + { + var b10 = (B1_ABoring_byte)Activator.CreateInstance(typeof(B1_ABoring_byte)); + b10._bVal = 1; + if (1 != (byte)typeof(B1_ABoring_byte).GetField("_bVal").GetValue(b10)) + { + failure++; + Console.WriteLine("C1 b10._bVal"); + } + } + + { + var b11 = (B1_ABoring_D)Activator.CreateInstance(typeof(B1_ABoring_D)); + b11._bVal = 1; + if (1 != (byte)typeof(B1_ABoring_D).GetField("_bVal").GetValue(b11)) + { + failure++; + Console.WriteLine("C1 b11._bVal"); + } + } + + { + var b12 = (B1_A1Boring_byte)Activator.CreateInstance(typeof(B1_A1Boring_byte)); + b12._bVal = 1; + if (1 != (byte)typeof(B1_A1Boring_byte).GetField("_bVal").GetValue(b12)) + { + failure++; + Console.WriteLine("C1 b12._bVal"); + } + } + + { + var b13 = (B1_A1Boring_D)Activator.CreateInstance(typeof(B1_A1Boring_D)); + b13._bVal = 1; + if (1 != (byte)typeof(B1_A1Boring_D).GetField("_bVal").GetValue(b13)) + { + failure++; + Console.WriteLine("C1 b13._bVal"); + } + } + + { + var c = (C1_B_A)Activator.CreateInstance(typeof(C1_B_A)); + c._cVal = 1; + if (1 != (byte)typeof(C1_B_A).GetField("_cVal").GetValue(c)) + { + failure++; + Console.WriteLine("C1 c._cVal"); + } + } + + { + var c2 = (C1_B_A_byte)Activator.CreateInstance(typeof(C1_B_A_byte)); + c2._cVal = 1; + if (1 != (byte)typeof(C1_B_A_byte).GetField("_cVal").GetValue(c2)) + { + failure++; + Console.WriteLine("C1 c2._cVal"); + } + } + + { + var c3 = (C1_B_A_D)Activator.CreateInstance(typeof(C1_B_A_D)); + c3._cVal = 1; + if (1 != (byte)typeof(C1_B_A_D).GetField("_cVal").GetValue(c3)) + { + failure++; + Console.WriteLine("C1 c3._cVal"); + } + } + + { + var c4 = (C1_B_A_Generic_byte)Activator.CreateInstance(typeof(C1_B_A_Generic_byte)); + c4._cVal = 1; + if (1 != (byte)typeof(C1_B_A_Generic_byte).GetField("_cVal").GetValue(c4)) + { + failure++; + Console.WriteLine("C1 c4._cVal"); + } + } + + { + var c5 = (C1_B_A_byte_Generic_byte)Activator.CreateInstance(typeof(C1_B_A_byte_Generic_byte)); + c5._cVal = 1; + if (1 != (byte)typeof(C1_B_A_byte_Generic_byte).GetField("_cVal").GetValue(c5)) + { + failure++; + Console.WriteLine("C1 c5._cVal"); + } + } + + { + var c6 = (C1_B_A_D_Generic_byte)Activator.CreateInstance(typeof(C1_B_A_D_Generic_byte)); + c6._cVal = 1; + if (1 != (byte)typeof(C1_B_A_D_Generic_byte).GetField("_cVal").GetValue(c6)) + { + failure++; + Console.WriteLine("C1 c6._cVal"); + } + } + + { + var c7 = (C1_B_A_Generic_D)Activator.CreateInstance(typeof(C1_B_A_Generic_D)); + c7._cVal = 1; + if (1 != (byte)typeof(C1_B_A_Generic_D).GetField("_cVal").GetValue(c7)) + { + failure++; + Console.WriteLine("C1 c7._cVal"); + } + } + + { + var c8 = (C1_B_A_byte_Generic_D)Activator.CreateInstance(typeof(C1_B_A_byte_Generic_D)); + c8._cVal = 1; + if (1 != (byte)typeof(C1_B_A_byte_Generic_D).GetField("_cVal").GetValue(c8)) + { + failure++; + Console.WriteLine("C1 c8._cVal"); + } + } + + { + var c9 = (C1_B_A_D_Generic_D)Activator.CreateInstance(typeof(C1_B_A_D_Generic_D)); + c9._cVal = 1; + if (1 != (byte)typeof(C1_B_A_D_Generic_D).GetField("_cVal").GetValue(c9)) + { + failure++; + Console.WriteLine("C1 c9._cVal"); + } + } + + return failure; + } + } +} \ No newline at end of file diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/crossboundarytest.csproj b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/crossboundarytest.csproj index 7e8eee65132bd2..a1eb9a74a4a525 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/crossboundarytest.csproj +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/crossboundarytest.csproj @@ -7,6 +7,7 @@ + diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/main.cs b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/main.cs index 3610a86651bf2d..8b757a7bfa20d8 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/main.cs +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/main.cs @@ -13,6 +13,7 @@ public static int Main(string[] args) int failure = ATest.Test(); failure += BTest.Test(); failure += CTest.Test(); + failure += C1Test.Test(); return 100 + failure; } From b1d4305cbbeacf741e8fd4943fd3cde33ab5199b Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Mon, 20 Apr 2020 22:54:06 -0700 Subject: [PATCH 03/14] Syncronize and correct NeedsAlignedBaseOffset - Crossgen2 and the runtime had different models for when the base type size needed to be aligned up - This only caused issues for composite crossgen2 builds as the logic was heavily module focussed - Also, the IsInSameVersionBubble logic was non-functional for composite build All of the following conditions must hold, or there shall be alignment inserted between a base and derived type - The derived type must declare that the base type is in the same version bubble as the derived type - The base type must declare that it was able to derive from its base type without needing alignment - The base type must not be instantiated over a valuetype where the valuetype instantiation contributes to the instance field layout of the base type, and that valuetype is not wholly defined in one bubble --- .../ReadyToRunCompilationModuleGroupBase.cs | 2 +- .../ReadyToRunMetadataFieldLayoutAlgorithm.cs | 12 +--- src/coreclr/src/vm/ceeload.cpp | 28 +++++++--- src/coreclr/src/vm/methodtablebuilder.cpp | 56 ++++++++++++------- 4 files changed, 61 insertions(+), 37 deletions(-) diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs index 7d55bc55e32b47..763d6b16da47bb 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs @@ -89,7 +89,7 @@ private bool ContainsTypeLayoutUncached(TypeDesc type) return true; } var defType = (MetadataType)type; - if (!ContainsType(defType)) + if (!VersionsWithModule(defType.Module)) { return false; } diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs index 5079e20cd04560..da6776a5a065c1 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs @@ -822,17 +822,9 @@ protected override void AlignBaseOffsetIfNecessary(MetadataType type, ref Layout return; } - if (_compilationGroup.ContainsType(baseType)) + if (_compilationGroup.ContainsTypeLayout(baseType)) { - if (_compilationGroup.ContainsTypeLayout(baseType)) - { - // The type is defined in the module that's currently being compiled and the type layout doesn't depend on other modules - return; - } - } - else if (_compilationGroup.VersionsWithType(baseType)) - { - // The baseType is in the current version bubble, but in a module different from the one that's currently being compiled + // The type is defined in the module that's currently being compiled and the type layout doesn't depend on other modules return; } diff --git a/src/coreclr/src/vm/ceeload.cpp b/src/coreclr/src/vm/ceeload.cpp index dc76c751edc34a..9b9c59449c954d 100644 --- a/src/coreclr/src/vm/ceeload.cpp +++ b/src/coreclr/src/vm/ceeload.cpp @@ -3374,15 +3374,29 @@ BOOL Module::IsInSameVersionBubble(Module *target) return FALSE; } - // Check if the current module's image has native manifest metadata, otherwise the current->GetNativeAssemblyImport() asserts. - COUNT_T cMeta=0; - const void* pMeta = GetFile()->GetOpenedILimage()->GetNativeManifestMetadata(&cMeta); - if (pMeta == NULL) + NativeImage *nativeImage = this->GetCompositeNativeImage(); + IMDInternalImport* pMdImport = NULL; + + if (nativeImage != NULL) { - return FALSE; + if (nativeImage == target->GetCompositeNativeImage()) + { + // Fast path for modules contained within the same native image + return TRUE; + } + pMdImport = nativeImage->GetManifestMetadata(); + } + else + { + // Check if the current module's image has native manifest metadata, otherwise the current->GetNativeAssemblyImport() asserts. + COUNT_T cMeta=0; + const void* pMeta = GetFile()->GetOpenedILimage()->GetNativeManifestMetadata(&cMeta); + if (pMeta == NULL) + { + return FALSE; + } + pMdImport = GetNativeAssemblyImport(); } - - IMDInternalImport* pMdImport = GetNativeAssemblyImport(); LPCUTF8 targetName = target->GetAssembly()->GetSimpleName(); diff --git a/src/coreclr/src/vm/methodtablebuilder.cpp b/src/coreclr/src/vm/methodtablebuilder.cpp index 14ccfd4371061d..2511d0e1d2a789 100644 --- a/src/coreclr/src/vm/methodtablebuilder.cpp +++ b/src/coreclr/src/vm/methodtablebuilder.cpp @@ -11244,7 +11244,26 @@ VOID MethodTableBuilder::CheckLayoutDependsOnOtherModules(MethodTable * pDepende // not take into account NonVersionable attribute. Otherwise, adding NonVersionable attribute to existing // type would be ReadyToRun incompatible change. // - if (pDependencyMT->GetModule() == GetModule()) + bool treatAsIfInSameModule = pDependencyMT->GetModule() == GetModule(); +#ifdef FEATURE_READYTORUN_COMPILER + if (!treatAsIfInSameModule && IsReadyToRunCompilation()) + { + if (pDependencyMT->GetModule()->IsInCurrentVersionBubble()) + { + treatAsIfInSameModule = true; + } + } +#else // FEATURE_READYTORUN_COMPILER + if (!treatAsIfInSameModule && GetModule()->GetFile()->IsILImageReadyToRun()) + { + if (GetModule()->IsInSameVersionBubble(pDependencyMT->GetModule())) + { + treatAsIfInSameModule = true; + } + } +#endif + + if (treatAsIfInSameModule) { if (!pDependencyMT->GetClass()->HasLayoutDependsOnOtherModules()) return; @@ -11282,30 +11301,29 @@ BOOL MethodTableBuilder::NeedsAlignedBaseOffset() return FALSE; } - if (pParentMT->GetModule() == GetModule()) - { - if (!pParentMT->GetClass()->HasLayoutDependsOnOtherModules()) - return FALSE; - } - else - { + bool treatAsIfInSameModule = pParentMT->GetModule() == GetModule(); #ifdef FEATURE_READYTORUN_COMPILER - if (IsReadyToRunCompilation()) + if (!treatAsIfInSameModule && IsReadyToRunCompilation()) + { + if (pParentMT->GetModule()->IsInCurrentVersionBubble()) { - if (pParentMT->GetModule()->IsInCurrentVersionBubble()) - { - return FALSE; - } + treatAsIfInSameModule = true; } + } #else // FEATURE_READYTORUN_COMPILER - if (GetModule()->GetFile()->IsILImageReadyToRun()) + if (!treatAsIfInSameModule && GetModule()->GetFile()->IsILImageReadyToRun()) + { + if (GetModule()->IsInSameVersionBubble(pParentMT->GetModule())) { - if (GetModule()->IsInSameVersionBubble(pParentMT->GetModule())) - { - return FALSE; - } + treatAsIfInSameModule = true; } -#endif // FEATURE_READYTORUN_COMPILER + } +#endif + + if (treatAsIfInSameModule) + { + if (!pParentMT->GetClass()->HasLayoutDependsOnOtherModules()) + return FALSE; } return TRUE; From 9d247dead6ce5a3fa1546d09cfca5a5cecbeced4 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Wed, 22 Apr 2020 11:07:00 -0700 Subject: [PATCH 04/14] Add testing for 45 different variations of compiling the tests with crossgen, crossgen2, and crossgen2 with input bubble enable --- .../buildcrossgen2image.cmd | 54 +++++++++++- .../crossboundarytests.cmd | 83 +++++++++++++++++-- .../crossboundarylayout/runindividualtest.cmd | 4 +- 3 files changed, 131 insertions(+), 10 deletions(-) diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd b/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd index 1d2d9464e3a16c..799da0ac8e4fa2 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd @@ -6,13 +6,63 @@ set TESTINITIALBINPATH=%2 set TESTTARGET_DIR=%3 set TESTBATCHROOT=%1 + :Loop if "%4"=="" goto Continue + set COMPILEARG=%COMPILEARG% %TESTINITIALBINPATH%\%4.dll set COMPOSITENAME=%COMPOSITENAME%%4 + +if "%5"=="CG2Single" ( + call :CG2Single + shift +) ELSE ( + if "%5"=="CG2SingleInputBubble" ( + call :CG2SingleInputBubble + shift + ) ELSE ( + if "%5"=="CG1Single" ( + call :CG1Single + shift + ) ELSE ( + if "%5"=="CG2Composite" ( + shift + call :Continue + ) + ) + ) +) + shift goto Loop :Continue -echo on -call %TESTBATCHROOT%\..\..\..\..\..\..\.dotnet\dotnet %CORE_ROOT%\crossgen2\crossgen2.dll -r %CORE_ROOT%\* -r %TESTINITIALBINPATH%\*.dll -o %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%Composite.dll --composite %COMPILEARG% \ No newline at end of file +if "%COMPOSITENAME%"=="" goto done + +set BUILDCMD=%TESTBATCHROOT%\..\..\..\..\..\..\.dotnet\dotnet %CORE_ROOT%\crossgen2\crossgen2.dll -r %CORE_ROOT%\* -r %TESTINITIALBINPATH%\*.dll -o %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%Composite.dll --composite %COMPILEARG% +call %BUILDCMD% > %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%Composite.dll.log 2>&1 +if NOT EXIST %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%Composite.dll del %TESTINITIALBINPATH%\%TESTTARGET_DIR%\a.dll +goto done + +:CG2Single +del %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll +set BUILDCMD=%TESTBATCHROOT%\..\..\..\..\..\..\.dotnet\dotnet %CORE_ROOT%\crossgen2\crossgen2.dll -r %CORE_ROOT%\* -r %TESTINITIALBINPATH%\*.dll -o %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll %TESTINITIALBINPATH%\%COMPOSITENAME%.dll +call %BUILDCMD% > %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log 2>&1 +goto done + +:CG2SingleInputBubble +del %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll +set BUILDCMD=%TESTBATCHROOT%\..\..\..\..\..\..\.dotnet\dotnet %CORE_ROOT%\crossgen2\crossgen2.dll -r %CORE_ROOT%\* -r %TESTINITIALBINPATH%\*.dll -o %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll --inputbubble %TESTINITIALBINPATH%\%COMPOSITENAME%.dll +call %BUILDCMD% > %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log 2>&1 +goto done + +:CG1Single +del %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll +set BUILDCMD=%CORE_ROOT%\crossgen.exe /Platform_Assemblies_Paths %CORE_ROOT%;%TESTINITIALBINPATH% /out %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll /in %TESTINITIALBINPATH%\%COMPOSITENAME%.dll +call %BUILDCMD% > %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log 2>&1 +goto done + +:done +shift +set COMPILEARG= +set COMPOSITENAME= diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd index eaf14c9f7220ae..fb5b5119faf326 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd @@ -1,13 +1,84 @@ +echo off setlocal +set TESTDIR=%~dp0\..\..\..\..\..\..\artifacts\tests\coreclr\Windows_NT.x64.Debug\readytorun\crossboundarylayout\crossboundarytest\crossboundarytest set TESTBATCHROOT=%~dp0 -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %1 all a b crossboundarytest d -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %1 ad a d +call :testCG2SingleInputBubbleAll -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %1 abd a b d +goto done -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %1 a_crossboundarytest_d a crossboundarytest d +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% all a b crossboundarytest d -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %1 a_b_crossboundarytest a b crossboundarytest +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% ad a d -pushd %TESTBATCHROOT% \ No newline at end of file +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% abd a b d + +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% a_crossboundarytest_d a crossboundarytest d + +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% a_b_crossboundarytest a b crossboundarytest + +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A a CG2Single + +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_ABubble a CG2SingleInputBubble + +:testCG1All + +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A___ a CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__B__ b CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_AB__ a CG1Single b CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1___C_ c CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A_C_ a CG1Single crossboundarytest CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__BC_ b CG1Single crossboundarytest CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_ABC_ a CG1Single b CG1Single crossboundarytest CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1____D d CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A__D a CG1Single d CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__B_D b CG1Single d CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_AB_D a CG1Single b CG1Single d CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1___CD crossboundarytest CG1Single d CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A_CD a CG1Single crossboundarytest CG1Single d CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__BCD b CG1Single crossboundarytest CG1Single d CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_ABCD a CG1Single b CG1Single crossboundarytest CG1Single d CG1Single + +goto done + +:testCG2SingleInputBubbleAll + +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A___ a CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__B__ b CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_AB__ a CG2SingleInputBubble b CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble___C_ c CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A_C_ a CG2SingleInputBubble crossboundarytest CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__BC_ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_ABC_ a CG2SingleInputBubble b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble____D d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A__D a CG2SingleInputBubble d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__B_D b CG2SingleInputBubble d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_AB_D a CG2SingleInputBubble b CG2SingleInputBubble d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble___CD crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A_CD a CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__BCD b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_ABCD a CG2SingleInputBubble b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble + +goto done + +:testCG2All + +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A___ a CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2__B__ b CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_AB__ a CG2Single b CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2___C_ c CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A_C_ a CG2Single crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2__BC_ b CG2Single crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_ABC_ a CG2Single b CG2Single crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2____D d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A__D a CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2__B_D b CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_AB_D a CG2Single b CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2___CD crossboundarytest CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A_CD a CG2Single crossboundarytest CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2__BCD b CG2Single crossboundarytest CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_ABCD a CG2Single b CG2Single crossboundarytest CG2Single d CG2Single + +goto done + +:done diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/runindividualtest.cmd b/src/coreclr/tests/src/readytorun/crossboundarylayout/runindividualtest.cmd index 09c6fc072bf52d..e12a875e30a731 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/runindividualtest.cmd +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/runindividualtest.cmd @@ -1,4 +1,4 @@ -@echo off +rem @echo off setlocal rd /s /q %2\%3 md %2\%3 @@ -7,7 +7,7 @@ call %1\buildcrossgen2image.cmd %1 %2 %3 %4 %5 %6 %7 @echo on %CORE_ROOT%\corerun %2\%3\crossboundarytest.dll @echo off -if ERRORLEVEL 101 ( +if %ERRORLEVEL% NEQ 100 ( echo FAILED goto done ) From 26ea12d540e44659c45699e72f7d28a70d022cde Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 23 Apr 2020 18:11:02 -0700 Subject: [PATCH 05/14] Use new layout algorithm Mostly works --- .../Compiler/ReadyToRunCodegenCompilation.cs | 60 ++++++- .../ReadyToRunCodegenCompilationBuilder.cs | 2 +- .../ReadyToRunCompilationModuleGroupBase.cs | 159 +++++++++++++++-- .../Compiler/ReadyToRunCompilerContext.cs | 2 +- .../ReadyToRunMetadataFieldLayoutAlgorithm.cs | 6 +- .../JitInterface/CorInfoImpl.ReadyToRun.cs | 55 +----- .../ReadyToRunReader.cs | 17 ++ .../ReadyToRunSignature.cs | 36 +++- src/coreclr/src/vm/class.h | 17 +- src/coreclr/src/vm/methodtablebuilder.cpp | 167 ++++++++++++------ .../buildcrossgen2image.cmd | 12 +- .../crossboundarytests.cmd | 7 +- 12 files changed, 406 insertions(+), 134 deletions(-) diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs index 5baf77fe2a38e1..e0ef8aa1af3635 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Reflection.PortableExecutable; using System.Runtime.CompilerServices; @@ -333,9 +334,64 @@ public override void WriteDependencyLog(string outputFileName) } } - internal bool IsInheritanceChainLayoutFixedInCurrentVersionBubble(TypeDesc type) + public bool IsLayoutFixedInCurrentVersionBubble(TypeDesc type) { - // TODO: implement + // Primitive types and enums have fixed layout + if (type.IsPrimitive || type.IsEnum) + { + return true; + } + + if (!(type is MetadataType defType)) + { + // Non metadata backed types have layout defined in all version bubbles + return true; + } + + if (!NodeFactory.CompilationModuleGroup.VersionsWithModule(defType.Module)) + { + if (!type.IsValueType) + { + // Eventually, we may respect the non-versionable attribute for reference types too. For now, we are going + // to play it safe and ignore it. + return false; + } + + // Valuetypes with non-versionable attribute are candidates for fixed layout. Reject the rest. + return type is MetadataType metadataType && metadataType.IsNonVersionable(); + } + + // If the above condition passed, check that all instance fields have fixed layout as well. In particular, + // it is important for generic types with non-versionable layout (e.g. Nullable) + foreach (var field in type.GetFields()) + { + var fieldType = field.FieldType; + if (!fieldType.IsValueType) + continue; + + if (!IsLayoutFixedInCurrentVersionBubble(fieldType)) + { + return false; + } + } + + return true; + } + + public bool IsInheritanceChainLayoutFixedInCurrentVersionBubble(TypeDesc type) + { + // This method is not expected to be called for value types + Debug.Assert(!type.IsValueType); + + while (!type.IsObject && type != null) + { + if (!IsLayoutFixedInCurrentVersionBubble(type)) + { + return false; + } + type = type.BaseType; + } + return true; } diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs index 72ce7fae981048..a889d469051b09 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs @@ -34,7 +34,7 @@ public sealed class ReadyToRunCodegenCompilationBuilder : CompilationBuilder private KeyValuePair[] _ryujitOptions = Array.Empty>(); private ILProvider _ilProvider = new ReadyToRunILProvider(); - public ReadyToRunCodegenCompilationBuilder(CompilerTypeSystemContext context, CompilationModuleGroup group, IEnumerable inputFiles) + public ReadyToRunCodegenCompilationBuilder(CompilerTypeSystemContext context, ReadyToRunCompilationModuleGroupBase group, IEnumerable inputFiles) : base(context, group, new CoreRTNameMangler()) { _inputFiles = inputFiles; diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs index 763d6b16da47bb..9049d75d514337 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs @@ -21,7 +21,8 @@ public abstract class ReadyToRunCompilationModuleGroupBase : CompilationModuleGr private readonly bool _compileGenericDependenciesFromVersionBubbleModuleSet; private readonly bool _isCompositeBuildMode; private readonly bool _isInputBubble; - private readonly ConcurrentDictionary _containsTypeLayoutCache = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _layoutDependsOnOtherModules = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _layoutDependsOnOtherVersionBubbles = new ConcurrentDictionary(); private readonly ConcurrentDictionary _versionsWithTypeCache = new ConcurrentDictionary(); private readonly ConcurrentDictionary _versionsWithMethodCache = new ConcurrentDictionary(); @@ -69,15 +70,17 @@ protected bool CompileVersionBubbleGenericsIntoCurrentModule(MethodDesc method) return true; } - /// - /// If true, the type is fully contained in the current compilation group. - /// - public override bool ContainsTypeLayout(TypeDesc type) + public virtual bool TypeLayoutDependsOnOtherModules(TypeDesc type) { - return _containsTypeLayoutCache.GetOrAdd(type, ContainsTypeLayoutUncached); + return _layoutDependsOnOtherModules.GetOrAdd(type, TypeLayoutDependsOnOtherModulesUncached); } - private bool ContainsTypeLayoutUncached(TypeDesc type) + public virtual bool TypeLayoutDependsOnOtherVersionBubbles(TypeDesc type) + { + return _layoutDependsOnOtherVersionBubbles.GetOrAdd(type, TypeLayoutDependsOnOtherVersionBubblesUncached); + } + + private bool TypeLayoutDependsOnOtherModulesUncached(TypeDesc type) { if (type.IsObject || type.IsPrimitive || @@ -86,17 +89,134 @@ private bool ContainsTypeLayoutUncached(TypeDesc type) type.IsFunctionPointer || type.IsCanonicalDefinitionType(CanonicalFormKind.Any)) { - return true; + return false; } + var defType = (MetadataType)type; - if (!VersionsWithModule(defType.Module)) + + if (type.BaseType != null) + { + if (CompareTypeLayoutForModuleCheck((MetadataType)type.BaseType)) + return true; + } + + foreach (FieldDesc field in defType.GetFields()) { + if (field.IsStatic) + continue; + + TypeDesc fieldType = field.FieldType; + + if (fieldType.IsValueType && + !fieldType.IsPrimitive) + { + if (CompareTypeLayoutForModuleCheck((MetadataType)fieldType)) + { + return true; + } + } + } + + return false; + + bool CompareTypeLayoutForModuleCheck(MetadataType otherType) + { + if (otherType.Module != defType.Module || + TypeLayoutDependsOnOtherModules(otherType)) + { + return true; + } + return false; + } + } + + private bool ModuleInMatchingVersionBubble(ModuleDesc module1, ModuleDesc module2) + { + return VersionsWithModule(module1) == VersionsWithModule(module2); + } + + public bool NeedsAlignmentBetweenBaseTypeAndDerived(MetadataType baseType, MetadataType derivedType) + { + + if (!ModuleInMatchingVersionBubble(derivedType.Module, baseType.Module) || + TypeLayoutDependsOnOtherVersionBubbles(baseType) || + LayoutDependsOnTypeVariableInstantiationWhichDependsOnOtherModules(baseType)) + { + return true; + } + + return false; + + bool LayoutDependsOnTypeVariableInstantiationWhichDependsOnOtherModules(MetadataType type) + { + // Types without instantiations do not depend on their type variables for layout + if (!type.HasInstantiation) + return false; + + // Types that are not instantiated do not depend on their type variables for layout. + if (type.IsTypeDefinition) + return false; + + // If no part of the layout of this type depends on other modules, then there is no need + // to check for a type variable caused case + if (!TypeLayoutDependsOnOtherModules(type)) + return false; + + foreach (var field in type.GetFields()) + { + var fieldType = field.FieldType; + + // non valuetypes are uninteresting for this check + if (!fieldType.IsValueType) + continue; + + // As primitive types are considered part of all version bubbles, they are also unconsidered + if (fieldType.IsPrimitive) + continue; + + var fieldTypeOnOpenType = field.GetTypicalFieldDefinition().FieldType; + + if (fieldType == fieldTypeOnOpenType) + { + // If the field type is the same, it isn't dependent on a type variable + continue; + } + + if (TypeLayoutDependsOnOtherModules(fieldType) || + ((MetadataType)fieldType).Module != type.Module) + { + // The layout of this field depends on other modules. + return true; + } + } + return false; } - if (!defType.IsValueType && !ContainsTypeLayout(defType.BaseType)) + } + + private bool TypeLayoutDependsOnOtherVersionBubblesUncached(TypeDesc type) + { + if (type.IsObject || + type.IsPrimitive || + type.IsEnum || + type.IsPointer || + type.IsFunctionPointer || + type.IsCanonicalDefinitionType(CanonicalFormKind.Any)) { return false; } + + var defType = (MetadataType)type; + + if ((type.BaseType != null) && !type.BaseType.IsObject) + { + if (CompareTypeLayoutForVersionBubble((MetadataType)type.BaseType)) + return true; + + if (NeedsAlignmentBetweenBaseTypeAndDerived(baseType: (MetadataType)type.BaseType, derivedType: defType)) + return true; + } + foreach (FieldDesc field in defType.GetFields()) { if (field.IsStatic) @@ -105,13 +225,26 @@ private bool ContainsTypeLayoutUncached(TypeDesc type) TypeDesc fieldType = field.FieldType; if (fieldType.IsValueType && - !ContainsTypeLayout(fieldType)) + !fieldType.IsPrimitive) { - return false; + if (CompareTypeLayoutForVersionBubble((MetadataType)fieldType)) + { + return true; + } } } - return true; + return false; + + bool CompareTypeLayoutForVersionBubble(MetadataType otherType) + { + if (!ModuleInMatchingVersionBubble(otherType.Module, defType.Module) || + TypeLayoutDependsOnOtherVersionBubbles(otherType)) + { + return true; + } + return false; + } } public sealed override bool VersionsWithModule(ModuleDesc module) diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs index 8a443acefbdf54..5f2d1663ff5cdd 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs @@ -67,7 +67,7 @@ public override FieldLayoutAlgorithm GetLayoutAlgorithmForType(DefType type) } } - public void SetCompilationGroup(CompilationModuleGroup compilationModuleGroup) + public void SetCompilationGroup(ReadyToRunCompilationModuleGroupBase compilationModuleGroup) { _r2rFieldLayoutAlgorithm.SetCompilationGroup(compilationModuleGroup); } diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs index da6776a5a065c1..f19140fde558a3 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunMetadataFieldLayoutAlgorithm.cs @@ -27,7 +27,7 @@ internal class ReadyToRunMetadataFieldLayoutAlgorithm : MetadataFieldLayoutAlgor /// /// Compilation module group is used to identify which types extend beyond the current version bubble. /// - private CompilationModuleGroup _compilationGroup; + private ReadyToRunCompilationModuleGroupBase _compilationGroup; public ReadyToRunMetadataFieldLayoutAlgorithm() { @@ -38,7 +38,7 @@ public ReadyToRunMetadataFieldLayoutAlgorithm() /// Set up compilation group needed for proper calculation of base class alignment in auto layout. /// /// - public void SetCompilationGroup(CompilationModuleGroup compilationGroup) + public void SetCompilationGroup(ReadyToRunCompilationModuleGroupBase compilationGroup) { _compilationGroup = compilationGroup; } @@ -822,7 +822,7 @@ protected override void AlignBaseOffsetIfNecessary(MetadataType type, ref Layout return; } - if (_compilationGroup.ContainsTypeLayout(baseType)) + if (!_compilationGroup.NeedsAlignmentBetweenBaseTypeAndDerived(baseType: (MetadataType)baseType, derivedType: type)) { // The type is defined in the module that's currently being compiled and the type layout doesn't depend on other modules return; diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index 433b69a0d56156..d976b8e7ce110f 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -1914,30 +1914,6 @@ private void embedGenericHandle(ref CORINFO_RESOLVED_TOKEN pResolvedToken, bool throw new RequiresRuntimeJitException("embedMethodHandle: " + methodDesc.ToString()); } - private bool IsLayoutFixedInCurrentVersionBubble(TypeDesc type) - { - // Primitive types and enums have fixed layout - if (type.IsPrimitive || type.IsEnum) - { - return true; - } - - if (!_compilation.NodeFactory.CompilationModuleGroup.VersionsWithType(type)) - { - if (!type.IsValueType) - { - // Eventually, we may respect the non-versionable attribute for reference types too. For now, we are going - // to play it safe and ignore it. - return false; - } - - // Valuetypes with non-versionable attribute are candidates for fixed layout. Reject the rest. - return type is MetadataType metadataType && metadataType.IsNonVersionable(); - } - - return true; - } - private bool NeedsTypeLayoutCheck(TypeDesc type) { if (!type.IsDefType) @@ -1946,27 +1922,7 @@ private bool NeedsTypeLayoutCheck(TypeDesc type) if (!type.IsValueType) return false; - return !IsLayoutFixedInCurrentVersionBubble(type); - } - - /// - /// Is field layout of the inheritance chain fixed within the current version bubble? - /// - private bool IsInheritanceChainLayoutFixedInCurrentVersionBubble(TypeDesc type) - { - // This method is not expected to be called for value types - Debug.Assert(!type.IsValueType); - - while (!type.IsObject && type != null) - { - if (!IsLayoutFixedInCurrentVersionBubble(type)) - { - return false; - } - type = type.BaseType; - } - - return true; + return !_compilation.IsLayoutFixedInCurrentVersionBubble(type); } private bool HasLayoutMetadata(TypeDesc type) @@ -2002,14 +1958,13 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult, { // No-op except for instance fields } - else if (!IsLayoutFixedInCurrentVersionBubble(pMT)) + else if (!_compilation.IsLayoutFixedInCurrentVersionBubble(pMT)) { if (pMT.IsValueType) { // ENCODE_CHECK_FIELD_OFFSET - pResult->offset = 0; - pResult->fieldAccessor = CORINFO_FIELD_ACCESSOR.CORINFO_FIELD_INSTANCE_WITH_BASE; - pResult->fieldLookup = CreateConstLookupToSymbol(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); + _methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); + // No-op other than generating the check field offset fixup } else { @@ -2025,7 +1980,7 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult, { // ENCODE_NONE } - else if (IsInheritanceChainLayoutFixedInCurrentVersionBubble(pMT.BaseType)) + else if (_compilation.IsInheritanceChainLayoutFixedInCurrentVersionBubble(pMT.BaseType)) { // ENCODE_NONE } diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs index 3683fe906f9d44..cbbab23daa975d 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs @@ -72,6 +72,7 @@ public sealed class ReadyToRunReader private OperatingSystem _operatingSystem; private Machine _machine; private Architecture _architecture; + private int _pointerSize; private bool _composite; private ulong _imageBase; private int _readyToRunHeaderRVA; @@ -174,6 +175,18 @@ public Architecture Architecture } } + /// + /// Size of a pointer on the architecture + /// + public int TargetPointerSize + { + get + { + EnsureHeader(); + return _pointerSize; + } + } + /// /// Return true when the executable is a composite R2R image. /// @@ -476,20 +489,24 @@ private unsafe void EnsureHeader() { case Machine.I386: _architecture = Architecture.X86; + _pointerSize = 4; break; case Machine.Amd64: _architecture = Architecture.X64; + _pointerSize = 8; break; case Machine.Arm: case Machine.Thumb: case Machine.ArmThumb2: _architecture = Architecture.Arm; + _pointerSize = 4; break; case Machine.Arm64: _architecture = Architecture.Arm64; + _pointerSize = 8; break; default: diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs index 8da2119e58fbb3..355af566a46b86 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunSignature.cs @@ -831,12 +831,44 @@ private void ParseSignature(ReadyToRunFixupKind fixupType, StringBuilder builder case ReadyToRunFixupKind.Check_TypeLayout: ParseType(builder); + ReadyToRunTypeLayoutFlags layoutFlags = (ReadyToRunTypeLayoutFlags)ReadUInt(); + builder.Append($" Flags {layoutFlags}"); + int actualSize = (int)ReadUInt(); + builder.Append($" Size {actualSize}"); + + if (layoutFlags.HasFlag(ReadyToRunTypeLayoutFlags.READYTORUN_LAYOUT_HFA)) + { + builder.Append($" HFAType {ReadUInt()}"); + } + + if (layoutFlags.HasFlag(ReadyToRunTypeLayoutFlags.READYTORUN_LAYOUT_Alignment)) + { + if (!layoutFlags.HasFlag(ReadyToRunTypeLayoutFlags.READYTORUN_LAYOUT_Alignment_Native)) + { + builder.Append($" Align {ReadUInt()}"); + } + } + + if (layoutFlags.HasFlag(ReadyToRunTypeLayoutFlags.READYTORUN_LAYOUT_GCLayout)) + { + if (!layoutFlags.HasFlag(ReadyToRunTypeLayoutFlags.READYTORUN_LAYOUT_GCLayout_Empty)) + { + int cbGCRefMap = (actualSize / _contextReader.TargetPointerSize + 7) / 8; + builder.Append(" GCLayout "); + for (int i = 0; i < cbGCRefMap; i++) + { + builder.Append(ReadByte().ToString("X")); + } + } + } + builder.Append(" (CHECK_TYPE_LAYOUT)"); break; case ReadyToRunFixupKind.Check_FieldOffset: - builder.Append("CHECK_FIELD_OFFSET"); - // TODO + builder.Append($"{ReadUInt()} "); + ParseField(builder); + builder.Append(" (CHECK_FIELD_OFFSET)"); break; case ReadyToRunFixupKind.Check_InstructionSetSupport: diff --git a/src/coreclr/src/vm/class.h b/src/coreclr/src/vm/class.h index 9158760e0861b8..f52fc4522cbcfe 100644 --- a/src/coreclr/src/vm/class.h +++ b/src/coreclr/src/vm/class.h @@ -1297,6 +1297,18 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! LIMITED_METHOD_CONTRACT; m_VMFlags |= VMFLAG_LAYOUT_DEPENDS_ON_OTHER_MODULES; } + + inline BOOL HasLayoutDependsOnOtherVersionBubbles() + { + LIMITED_METHOD_CONTRACT; + return m_VMFlags & VMFLAG_LAYOUT_DEPENDS_ON_OTHER_VERSIONBUBBLE; + } + + inline void SetHasLayoutDependsOnOtherVersionBubbles() + { + LIMITED_METHOD_CONTRACT; + m_VMFlags |= VMFLAG_LAYOUT_DEPENDS_ON_OTHER_VERSIONBUBBLE; + } #endif // Is this delegate? Returns false for System.Delegate and System.MulticastDelegate. @@ -1701,7 +1713,10 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! #endif VMFLAG_DELEGATE = 0x00000002, - // VMFLAG_UNUSED = 0x0000001c, +#ifdef FEATURE_READYTORUN + VMFLAG_LAYOUT_DEPENDS_ON_OTHER_VERSIONBUBBLE = 0x0000004, +#endif + // VMFLAG_UNUSED = 0x00000018, VMFLAG_FIXED_ADDRESS_VT_STATICS = 0x00000020, // Value type Statics in this class will be pinned VMFLAG_HASLAYOUT = 0x00000040, diff --git a/src/coreclr/src/vm/methodtablebuilder.cpp b/src/coreclr/src/vm/methodtablebuilder.cpp index 2511d0e1d2a789..1ff15be4db186b 100644 --- a/src/coreclr/src/vm/methodtablebuilder.cpp +++ b/src/coreclr/src/vm/methodtablebuilder.cpp @@ -11226,6 +11226,93 @@ VOID MethodTableBuilder::CheckForSpecialTypes() } #ifdef FEATURE_READYTORUN + +bool ModuleInMatchingVersionBubble(Module *pModule, Module *pSecondModule) +{ + STANDARD_VM_CONTRACT; +#ifdef FEATURE_READYTORUN_COMPILER + if (IsReadyToRunCompilation() && + !pSecondModule->IsInCurrentVersionBubble()) + { + return false; + } + else +#else + if (!pModule->IsInSameVersionBubble(pSecondModule)) + { + return false; + } +#endif + return true; +} + +bool LayoutDependsOnTypeVariableInstantiationWhichDependsOnOtherModules(MethodTable *pMT) +{ + STANDARD_VM_CONTRACT; + + // Types without instantiations do not depend on their type variables for layout + if (!pMT->HasInstantiation()) + return false; + + // Types that are not instantiated do not depend on their type variables for layout. + if (pMT->IsGenericTypeDefinition()) + return false; + + // If no part of the layout of this type depends on other modules, then there is no need + // to check for a type variable caused case + if (!pMT->GetClass()->HasLayoutDependsOnOtherModules()) + return false; + + MethodTable *pMTTypical = ClassLoader::LoadTypeDefOrRefThrowing( + pMT->GetModule(), + pMT->GetCl(), + ClassLoader::ThrowIfNotFound, + ClassLoader::PermitUninstDefOrRef, + tdNoTypes, + CLASS_LOAD_APPROXPARENTS).AsMethodTable(); + + DWORD cParentInstanceFields; + + MethodTable *pParentMT = pMT->GetParentMethodTable(); + if (pParentMT != NULL) + { + cParentInstanceFields = pParentMT->GetClass()->GetNumInstanceFields(); + } + else + { + cParentInstanceFields = 0; + } + + DWORD numFields = pMT->GetNumInstanceFields() - cParentInstanceFields; + FieldDesc *pStartFieldMT = pMT->GetClass()->GetFieldDescList(); + FieldDesc *pStartFieldMTTypical = pMTTypical->GetClass()->GetFieldDescList(); + for (DWORD iField = 0; iField < numFields; iField++) + { + _ASSERTE(pStartFieldMT[iField].GetMemberDef() == pStartFieldMTTypical[iField].GetMemberDef()); + if (pStartFieldMT[iField].GetFieldType() != ELEMENT_TYPE_VALUETYPE) + { + // non valuetypes are uninteresting for this check + continue; + } + + TypeHandle thField = pStartFieldMT[iField].GetApproxFieldTypeHandleThrowing(); + // The field type is known to be a MethodTable as the GetFieldType call above returned ELEMENT_TYPE_VALUETYPE + MethodTable* pMTField = thField.AsMethodTable(); + if (pMTField->GetClass()->HasLayoutDependsOnOtherModules() || pMTField->GetModule() != pMT->GetModule()) + { + // The layout of this field depends on other modules. Check to see if the field type is the same + // as in the open type, if it isn't, this variation is caused by the valuetype instantiation + TypeHandle thTypicalField = pStartFieldMTTypical[iField].GetApproxFieldTypeHandleThrowing(); + if (thField != thTypicalField) + { + return true; + } + } + } + + return false; +} + //******************************************************************************* VOID MethodTableBuilder::CheckLayoutDependsOnOtherModules(MethodTable * pDependencyMT) { @@ -11237,39 +11324,37 @@ VOID MethodTableBuilder::CheckLayoutDependsOnOtherModules(MethodTable * pDepende // // WARNING: Changes in this algorithm are potential ReadyToRun breaking changes !!! // - // Track whether field layout of this type depend on information outside its containing module + // Track whether field layout of this type depend on information outside its containing module and version bubble // // It is a stronger condition than MethodTable::IsInheritanceChainLayoutFixedInCurrentVersionBubble(). // It has to remain fixed accross versioning changes in the module dependencies. In particular, it does // not take into account NonVersionable attribute. Otherwise, adding NonVersionable attribute to existing // type would be ReadyToRun incompatible change. // - bool treatAsIfInSameModule = pDependencyMT->GetModule() == GetModule(); -#ifdef FEATURE_READYTORUN_COMPILER - if (!treatAsIfInSameModule && IsReadyToRunCompilation()) - { - if (pDependencyMT->GetModule()->IsInCurrentVersionBubble()) - { - treatAsIfInSameModule = true; - } - } -#else // FEATURE_READYTORUN_COMPILER - if (!treatAsIfInSameModule && GetModule()->GetFile()->IsILImageReadyToRun()) + bool dependencyDefinedInOtherModule = (pDependencyMT->GetModule() != GetModule()); + bool dependsOnOtherModules = dependencyDefinedInOtherModule || pDependencyMT->GetClass()->HasLayoutDependsOnOtherModules(); + + // If the dependency itself has dependency outside of its version bubble, this type will clearly also have a dependency + // outside of its version bubble. + bool dependsOnOtherVersionBubbles = pDependencyMT->GetClass()->HasLayoutDependsOnOtherVersionBubbles(); + if (!dependsOnOtherVersionBubbles) { - if (GetModule()->IsInSameVersionBubble(pDependencyMT->GetModule())) + // Now check to see if the dependency itself is defined within the version bubble. + // First, if the dependency was defined in the same module as this type, then we know it matches + // version bubbles. + if (dependencyDefinedInOtherModule) { - treatAsIfInSameModule = true; + // But if it doesn't, then check to see if the module that defined the dependency is + // in the same version bubble as this type. + dependsOnOtherVersionBubbles = !ModuleInMatchingVersionBubble(GetModule(), pDependencyMT->GetModule()); } } -#endif - if (treatAsIfInSameModule) - { - if (!pDependencyMT->GetClass()->HasLayoutDependsOnOtherModules()) - return; - } + if (dependsOnOtherModules) + GetHalfBakedClass()->SetHasLayoutDependsOnOtherModules(); - GetHalfBakedClass()->SetHasLayoutDependsOnOtherModules(); + if (dependsOnOtherVersionBubbles) + GetHalfBakedClass()->SetHasLayoutDependsOnOtherVersionBubbles(); } BOOL MethodTableBuilder::NeedsAlignedBaseOffset() @@ -11291,42 +11376,16 @@ BOOL MethodTableBuilder::NeedsAlignedBaseOffset() if (pParentMT == NULL || pParentMT == g_pObjectClass) return FALSE; - // Always use the ReadyToRun field layout algorithm if the source IL image was ReadyToRun, independent on - // whether ReadyToRun is actually enabled for the module. It is required to allow mixing and matching - // ReadyToRun images with NGen. - if (!GetModule()->GetFile()->IsILImageReadyToRun()) - { - // Always use ReadyToRun field layout algorithm to produce ReadyToRun images - if (!IsReadyToRunCompilation()) - return FALSE; - } - - bool treatAsIfInSameModule = pParentMT->GetModule() == GetModule(); -#ifdef FEATURE_READYTORUN_COMPILER - if (!treatAsIfInSameModule && IsReadyToRunCompilation()) - { - if (pParentMT->GetModule()->IsInCurrentVersionBubble()) - { - treatAsIfInSameModule = true; - } - } -#else // FEATURE_READYTORUN_COMPILER - if (!treatAsIfInSameModule && GetModule()->GetFile()->IsILImageReadyToRun()) + bool needsAlign = false; + if (!ModuleInMatchingVersionBubble(GetModule(), pParentMT->GetModule()) || + pParentMT->GetClass()->HasLayoutDependsOnOtherVersionBubbles() || + LayoutDependsOnTypeVariableInstantiationWhichDependsOnOtherModules(pParentMT)) { - if (GetModule()->IsInSameVersionBubble(pParentMT->GetModule())) - { - treatAsIfInSameModule = true; - } - } -#endif - - if (treatAsIfInSameModule) - { - if (!pParentMT->GetClass()->HasLayoutDependsOnOtherModules()) - return FALSE; + GetHalfBakedClass()->SetHasLayoutDependsOnOtherVersionBubbles(); + return TRUE; } - return TRUE; + return FALSE; } #endif // FEATURE_READYTORUN diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd b/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd index 799da0ac8e4fa2..b907191769fe5d 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd @@ -40,26 +40,30 @@ goto Loop if "%COMPOSITENAME%"=="" goto done set BUILDCMD=%TESTBATCHROOT%\..\..\..\..\..\..\.dotnet\dotnet %CORE_ROOT%\crossgen2\crossgen2.dll -r %CORE_ROOT%\* -r %TESTINITIALBINPATH%\*.dll -o %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%Composite.dll --composite %COMPILEARG% -call %BUILDCMD% > %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%Composite.dll.log 2>&1 +echo %BUILDCMD% > %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%Composite.dll.log +call %BUILDCMD% >> %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%Composite.dll.log 2>&1 if NOT EXIST %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%Composite.dll del %TESTINITIALBINPATH%\%TESTTARGET_DIR%\a.dll goto done :CG2Single del %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll set BUILDCMD=%TESTBATCHROOT%\..\..\..\..\..\..\.dotnet\dotnet %CORE_ROOT%\crossgen2\crossgen2.dll -r %CORE_ROOT%\* -r %TESTINITIALBINPATH%\*.dll -o %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll %TESTINITIALBINPATH%\%COMPOSITENAME%.dll -call %BUILDCMD% > %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log 2>&1 +echo %BUILDCMD% > %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log +call %BUILDCMD% >> %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log 2>&1 goto done :CG2SingleInputBubble del %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll set BUILDCMD=%TESTBATCHROOT%\..\..\..\..\..\..\.dotnet\dotnet %CORE_ROOT%\crossgen2\crossgen2.dll -r %CORE_ROOT%\* -r %TESTINITIALBINPATH%\*.dll -o %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll --inputbubble %TESTINITIALBINPATH%\%COMPOSITENAME%.dll -call %BUILDCMD% > %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log 2>&1 +echo %BUILDCMD% > %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log +call %BUILDCMD% >> %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log 2>&1 goto done :CG1Single del %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll set BUILDCMD=%CORE_ROOT%\crossgen.exe /Platform_Assemblies_Paths %CORE_ROOT%;%TESTINITIALBINPATH% /out %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll /in %TESTINITIALBINPATH%\%COMPOSITENAME%.dll -call %BUILDCMD% > %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log 2>&1 +echo %BUILDCMD% > %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log +call %BUILDCMD% >> %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log 2>&1 goto done :done diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd index fb5b5119faf326..425075274247ca 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd @@ -26,7 +26,7 @@ call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_ABubble call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A___ a CG1Single call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__B__ b CG1Single call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_AB__ a CG1Single b CG1Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1___C_ c CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1___C_ crossboundarytest CG1Single call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A_C_ a CG1Single crossboundarytest CG1Single call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__BC_ b CG1Single crossboundarytest CG1Single call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_ABC_ a CG1Single b CG1Single crossboundarytest CG1Single @@ -46,7 +46,7 @@ goto done call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A___ a CG2SingleInputBubble call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__B__ b CG2SingleInputBubble call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_AB__ a CG2SingleInputBubble b CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble___C_ c CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble___C_ crossboundarytest CG2SingleInputBubble call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A_C_ a CG2SingleInputBubble crossboundarytest CG2SingleInputBubble call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__BC_ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_ABC_ a CG2SingleInputBubble b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble @@ -66,7 +66,7 @@ goto done call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A___ a CG2Single call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2__B__ b CG2Single call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_AB__ a CG2Single b CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2___C_ c CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2___C_ crossboundarytest CG2Single call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A_C_ a CG2Single crossboundarytest CG2Single call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2__BC_ b CG2Single crossboundarytest CG2Single call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_ABC_ a CG2Single b CG2Single crossboundarytest CG2Single @@ -82,3 +82,4 @@ call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_ABCD a goto done :done + \ No newline at end of file From c94a078c45c07d2c1dbaad98c9c714664015979c Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 23 Apr 2020 10:25:49 -0700 Subject: [PATCH 06/14] Make test crashes more diagnosable --- .../src/readytorun/crossboundarylayout/a/a.cs | 28 ++++-- .../src/readytorun/crossboundarylayout/b/b.cs | 48 ++++------ .../crossboundarytest/c.cs | 78 ++++++----------- .../crossboundarytest/c1.cs | 87 +++++++------------ 4 files changed, 91 insertions(+), 150 deletions(-) diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs b/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs index cb1a9d1c0bd411..ea076299133583 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Threading; namespace CrossBoundaryLayout { @@ -23,6 +24,19 @@ public class ABoringGeneric public class ATest { + public static volatile object s_testFailObj; + public static void ReportTestFailure(string test, object o, ref int failCount) + { + Console.WriteLine(test); + s_testFailObj = o; + failCount++; + while (true) + { + s_testFailObj = o; + Thread.Sleep(1000); + } + } + public static int Test() { int failure = 0; @@ -31,8 +45,7 @@ public static int Test() a._aVal = 1; if (1 != (byte)typeof(A).GetField("_aVal").GetValue(a)) { - failure++; - Console.WriteLine("A a._aVal"); + ATest.ReportTestFailure("A a._aVal", a, ref failure); } } @@ -42,7 +55,7 @@ public static int Test() if (1 != (byte)typeof(AGeneric).GetField("_aVal").GetValue(a2)) { failure++; - Console.WriteLine("A a2_aVal"); + ATest.ReportTestFailure("A a2_aVal", a2, ref failure); } } @@ -51,8 +64,7 @@ public static int Test() a3._aVal._dVal = 1; if (1 != ((ByteStruct)typeof(AGeneric).GetField("_aVal").GetValue(a3))._dVal) { - failure++; - Console.WriteLine("A a3_aVal"); + ATest.ReportTestFailure("A a3_aVal", a3, ref failure); } } @@ -61,8 +73,7 @@ public static int Test() a4._aVal = 1; if (1 != (byte)typeof(ABoringGeneric).GetField("_aVal").GetValue(a4)) { - failure++; - Console.WriteLine("A a4_aVal"); + ATest.ReportTestFailure("A a4_aVal", a4, ref failure); } } @@ -71,8 +82,7 @@ public static int Test() a5._aVal = 1; if (1 != (byte)typeof(ABoringGeneric).GetField("_aVal").GetValue(a5)) { - failure++; - Console.WriteLine("A a5_aVal"); + ATest.ReportTestFailure("A a5_aVal", a5, ref failure); } } diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.cs b/src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.cs index 86d5490d7ed3fd..304a61e2373f28 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.cs +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.cs @@ -56,8 +56,7 @@ public static int Test() a._aVal = 1; if (1 != (byte)typeof(A).GetField("_aVal").GetValue(a)) { - failure++; - Console.WriteLine("B a._aVal"); + ATest.ReportTestFailure("B a_aVal", a, ref failure); } } @@ -66,8 +65,7 @@ public static int Test() a2._aVal = 1; if (1 != (byte)typeof(AGeneric).GetField("_aVal").GetValue(a2)) { - failure++; - Console.WriteLine("B a2_aVal"); + ATest.ReportTestFailure("B a2_aVal", a2, ref failure); } } @@ -76,8 +74,7 @@ public static int Test() a3._aVal._dVal = 1; if (1 != ((ByteStruct)typeof(AGeneric).GetField("_aVal").GetValue(a3))._dVal) { - failure++; - Console.WriteLine("B a3_aVal"); + ATest.ReportTestFailure("B a3_aVal", a3, ref failure); } } @@ -86,8 +83,7 @@ public static int Test() a4._aVal = 1; if (1 != (byte)typeof(ABoringGeneric).GetField("_aVal").GetValue(a4)) { - failure++; - Console.WriteLine("B a4_aVal"); + ATest.ReportTestFailure("B a4_aVal", a4, ref failure); } } @@ -96,8 +92,7 @@ public static int Test() a5._aVal = 1; if (1 != (byte)typeof(ABoringGeneric).GetField("_aVal").GetValue(a5)) { - failure++; - Console.WriteLine("B a5_aVal"); + ATest.ReportTestFailure("B a5_aVal", a5, ref failure); } } @@ -107,8 +102,7 @@ public static int Test() b._bVal = 1; if (1 != (byte)typeof(B_A).GetField("_bVal").GetValue(b)) { - failure++; - Console.WriteLine("B b._bVal"); + ATest.ReportTestFailure("B b_bVal", b, ref failure); } } @@ -117,8 +111,7 @@ public static int Test() b2._bVal = 1; if (1 != (byte)typeof(B_A_byte).GetField("_bVal").GetValue(b2)) { - failure++; - Console.WriteLine("B b2._bVal"); + ATest.ReportTestFailure("B b2_bVal", b2, ref failure); } } @@ -127,8 +120,7 @@ public static int Test() b3._bVal = 1; if (1 != (byte)typeof(B_A_D).GetField("_bVal").GetValue(b3)) { - failure++; - Console.WriteLine("B b3._bVal"); + ATest.ReportTestFailure("B b3_bVal", b3, ref failure); } } @@ -137,8 +129,7 @@ public static int Test() b4._bVal = 1; if (1 != (byte)typeof(B_A_Generic).GetField("_bVal").GetValue(b4)) { - failure++; - Console.WriteLine("B b4._bVal"); + ATest.ReportTestFailure("B b4_bVal", b4, ref failure); } } @@ -147,8 +138,7 @@ public static int Test() b5._bVal = 1; if (1 != (byte)typeof(B_A_byte_Generic).GetField("_bVal").GetValue(b5)) { - failure++; - Console.WriteLine("B b5._bVal"); + ATest.ReportTestFailure("B b5_bVal", b5, ref failure); } } @@ -157,8 +147,7 @@ public static int Test() b6._bVal = 1; if (1 != (byte)typeof(B_A_D_Generic).GetField("_bVal").GetValue(b6)) { - failure++; - Console.WriteLine("B b6._bVal"); + ATest.ReportTestFailure("B b6_bVal", b6, ref failure); } } @@ -167,8 +156,7 @@ public static int Test() b7._bVal._dVal = 1; if (1 != ((ByteStruct)typeof(B_A_Generic).GetField("_bVal").GetValue(b7))._dVal) { - failure++; - Console.WriteLine("B b7._bVal"); + ATest.ReportTestFailure("B b7_bVal", b7, ref failure); } } @@ -177,8 +165,7 @@ public static int Test() b8._bVal._dVal = 1; if (1 != ((ByteStruct)typeof(B_A_byte_Generic).GetField("_bVal").GetValue(b8))._dVal) { - failure++; - Console.WriteLine("B b8._bVal"); + ATest.ReportTestFailure("B b8_bVal", b8, ref failure); } } @@ -187,8 +174,7 @@ public static int Test() b9._bVal._dVal = 1; if (1 != ((ByteStruct)typeof(B_A_D_Generic).GetField("_bVal").GetValue(b9))._dVal) { - failure++; - Console.WriteLine("B b9._bVal"); + ATest.ReportTestFailure("B b9_bVal", b9, ref failure); } } @@ -197,8 +183,7 @@ public static int Test() b10._bVal = 1; if (1 != (byte)typeof(B_ABoring_byte).GetField("_bVal").GetValue(b10)) { - failure++; - Console.WriteLine("B b10._bVal"); + ATest.ReportTestFailure("B b10_bVal", b10, ref failure); } } @@ -207,8 +192,7 @@ public static int Test() b11._bVal = 1; if (1 != (byte)typeof(B_ABoring_D).GetField("_bVal").GetValue(b11)) { - failure++; - Console.WriteLine("B b11._bVal"); + ATest.ReportTestFailure("B b11_bVal", b11, ref failure); } } diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c.cs b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c.cs index 0facb1e7943d2e..2e2bc2e42928bf 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c.cs +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c.cs @@ -56,13 +56,13 @@ public class CTest public static int Test() { int failure = 0; + { var a = (A)Activator.CreateInstance(typeof(A)); a._aVal = 1; if (1 != (byte)typeof(A).GetField("_aVal").GetValue(a)) { - failure++; - Console.WriteLine("C a._aVal"); + ATest.ReportTestFailure("C a_aVal", a, ref failure); } } @@ -71,8 +71,7 @@ public static int Test() a2._aVal = 1; if (1 != (byte)typeof(AGeneric).GetField("_aVal").GetValue(a2)) { - failure++; - Console.WriteLine("C a2_aVal"); + ATest.ReportTestFailure("C a2_aVal", a2, ref failure); } } @@ -81,8 +80,7 @@ public static int Test() a3._aVal._dVal = 1; if (1 != ((ByteStruct)typeof(AGeneric).GetField("_aVal").GetValue(a3))._dVal) { - failure++; - Console.WriteLine("C a3_aVal"); + ATest.ReportTestFailure("C a3_aVal", a3, ref failure); } } @@ -91,8 +89,7 @@ public static int Test() a4._aVal = 1; if (1 != (byte)typeof(ABoringGeneric).GetField("_aVal").GetValue(a4)) { - failure++; - Console.WriteLine("C a4_aVal"); + ATest.ReportTestFailure("C a4_aVal", a4, ref failure); } } @@ -101,18 +98,17 @@ public static int Test() a5._aVal = 1; if (1 != (byte)typeof(ABoringGeneric).GetField("_aVal").GetValue(a5)) { - failure++; - Console.WriteLine("C a5_aVal"); + ATest.ReportTestFailure("C a5_aVal", a5, ref failure); } } + { var b = (B_A)Activator.CreateInstance(typeof(B_A)); b._bVal = 1; if (1 != (byte)typeof(B_A).GetField("_bVal").GetValue(b)) { - failure++; - Console.WriteLine("C b._bVal"); + ATest.ReportTestFailure("C b_bVal", b, ref failure); } } @@ -121,8 +117,7 @@ public static int Test() b2._bVal = 1; if (1 != (byte)typeof(B_A_byte).GetField("_bVal").GetValue(b2)) { - failure++; - Console.WriteLine("C b2._bVal"); + ATest.ReportTestFailure("C b2_bVal", b2, ref failure); } } @@ -131,8 +126,7 @@ public static int Test() b3._bVal = 1; if (1 != (byte)typeof(B_A_D).GetField("_bVal").GetValue(b3)) { - failure++; - Console.WriteLine("C b3._bVal"); + ATest.ReportTestFailure("C b3_bVal", b3, ref failure); } } @@ -141,8 +135,7 @@ public static int Test() b4._bVal = 1; if (1 != (byte)typeof(B_A_Generic).GetField("_bVal").GetValue(b4)) { - failure++; - Console.WriteLine("C b4._bVal"); + ATest.ReportTestFailure("C b4_bVal", b4, ref failure); } } @@ -151,8 +144,7 @@ public static int Test() b5._bVal = 1; if (1 != (byte)typeof(B_A_byte_Generic).GetField("_bVal").GetValue(b5)) { - failure++; - Console.WriteLine("C b5._bVal"); + ATest.ReportTestFailure("C b5_bVal", b5, ref failure); } } @@ -161,8 +153,7 @@ public static int Test() b6._bVal = 1; if (1 != (byte)typeof(B_A_D_Generic).GetField("_bVal").GetValue(b6)) { - failure++; - Console.WriteLine("C b6._bVal"); + ATest.ReportTestFailure("C b6_bVal", b6, ref failure); } } @@ -171,8 +162,7 @@ public static int Test() b7._bVal._dVal = 1; if (1 != ((ByteStruct)typeof(B_A_Generic).GetField("_bVal").GetValue(b7))._dVal) { - failure++; - Console.WriteLine("C b7._bVal"); + ATest.ReportTestFailure("C b7_bVal", b7, ref failure); } } @@ -181,8 +171,7 @@ public static int Test() b8._bVal._dVal = 1; if (1 != ((ByteStruct)typeof(B_A_byte_Generic).GetField("_bVal").GetValue(b8))._dVal) { - failure++; - Console.WriteLine("C b8._bVal"); + ATest.ReportTestFailure("C b8_bVal", b8, ref failure); } } @@ -191,8 +180,7 @@ public static int Test() b9._bVal._dVal = 1; if (1 != ((ByteStruct)typeof(B_A_D_Generic).GetField("_bVal").GetValue(b9))._dVal) { - failure++; - Console.WriteLine("C b9._bVal"); + ATest.ReportTestFailure("C b9_bVal", b9, ref failure); } } @@ -201,8 +189,7 @@ public static int Test() b10._bVal = 1; if (1 != (byte)typeof(B_ABoring_byte).GetField("_bVal").GetValue(b10)) { - failure++; - Console.WriteLine("C b10._bVal"); + ATest.ReportTestFailure("C b10_bVal", b10, ref failure); } } @@ -211,19 +198,16 @@ public static int Test() b11._bVal = 1; if (1 != (byte)typeof(B_ABoring_D).GetField("_bVal").GetValue(b11)) { - failure++; - Console.WriteLine("C b11._bVal"); + ATest.ReportTestFailure("C b11_bVal", b11, ref failure); } } - { var c = (C_B_A)Activator.CreateInstance(typeof(C_B_A)); c._cVal = 1; if (1 != (byte)typeof(C_B_A).GetField("_cVal").GetValue(c)) { - failure++; - Console.WriteLine("C c._cVal"); + ATest.ReportTestFailure("C c_bVal", c, ref failure); } } @@ -232,8 +216,7 @@ public static int Test() c2._cVal = 1; if (1 != (byte)typeof(C_B_A_byte).GetField("_cVal").GetValue(c2)) { - failure++; - Console.WriteLine("C c2._cVal"); + ATest.ReportTestFailure("C c2_bVal", c2, ref failure); } } @@ -242,8 +225,7 @@ public static int Test() c3._cVal = 1; if (1 != (byte)typeof(C_B_A_D).GetField("_cVal").GetValue(c3)) { - failure++; - Console.WriteLine("C c3._cVal"); + ATest.ReportTestFailure("C c3_bVal", c3, ref failure); } } @@ -252,8 +234,7 @@ public static int Test() c4._cVal = 1; if (1 != (byte)typeof(C_B_A_Generic_byte).GetField("_cVal").GetValue(c4)) { - failure++; - Console.WriteLine("C c4._cVal"); + ATest.ReportTestFailure("C c4_bVal", c4, ref failure); } } @@ -262,8 +243,7 @@ public static int Test() c5._cVal = 1; if (1 != (byte)typeof(C_B_A_byte_Generic_byte).GetField("_cVal").GetValue(c5)) { - failure++; - Console.WriteLine("C c5._cVal"); + ATest.ReportTestFailure("C c5_bVal", c5, ref failure); } } @@ -272,8 +252,7 @@ public static int Test() c6._cVal = 1; if (1 != (byte)typeof(C_B_A_D_Generic_byte).GetField("_cVal").GetValue(c6)) { - failure++; - Console.WriteLine("C c6._cVal"); + ATest.ReportTestFailure("C c6_bVal", c6, ref failure); } } @@ -282,8 +261,7 @@ public static int Test() c7._cVal = 1; if (1 != (byte)typeof(C_B_A_Generic_D).GetField("_cVal").GetValue(c7)) { - failure++; - Console.WriteLine("C c7._cVal"); + ATest.ReportTestFailure("C c7_bVal", c7, ref failure); } } @@ -292,8 +270,7 @@ public static int Test() c8._cVal = 1; if (1 != (byte)typeof(C_B_A_byte_Generic_D).GetField("_cVal").GetValue(c8)) { - failure++; - Console.WriteLine("C c8._cVal"); + ATest.ReportTestFailure("C c8_bVal", c8, ref failure); } } @@ -302,8 +279,7 @@ public static int Test() c9._cVal = 1; if (1 != (byte)typeof(C_B_A_D_Generic_D).GetField("_cVal").GetValue(c9)) { - failure++; - Console.WriteLine("C c9._cVal"); + ATest.ReportTestFailure("C c9_bVal", c9, ref failure); } } diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c1.cs b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c1.cs index 85c03f6a65e2a1..859a20aa5a68d0 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c1.cs +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytest/c1.cs @@ -116,8 +116,7 @@ public static int Test() a._aVal = 1; if (1 != (byte)typeof(A).GetField("_aVal").GetValue(a)) { - failure++; - Console.WriteLine("C1 a._aVal"); + ATest.ReportTestFailure("C1 a_aVal", a, ref failure); } } @@ -126,8 +125,7 @@ public static int Test() a2._aVal = 1; if (1 != (byte)typeof(AGeneric).GetField("_aVal").GetValue(a2)) { - failure++; - Console.WriteLine("C1 a2_aVal"); + ATest.ReportTestFailure("C1 a2_aVal", a2, ref failure); } } @@ -136,8 +134,7 @@ public static int Test() a3._aVal._dVal = 1; if (1 != ((ByteStruct)typeof(AGeneric).GetField("_aVal").GetValue(a3))._dVal) { - failure++; - Console.WriteLine("C1 a3_aVal"); + ATest.ReportTestFailure("C1 a3_aVal", a3, ref failure); } } @@ -146,8 +143,7 @@ public static int Test() a4._aVal = 1; if (1 != (byte)typeof(ABoringGeneric).GetField("_aVal").GetValue(a4)) { - failure++; - Console.WriteLine("C1 a4_aVal"); + ATest.ReportTestFailure("C1 a4_aVal", a4, ref failure); } } @@ -156,8 +152,7 @@ public static int Test() a5._aVal = 1; if (1 != (byte)typeof(ABoringGeneric).GetField("_aVal").GetValue(a5)) { - failure++; - Console.WriteLine("C1 a5_aVal"); + ATest.ReportTestFailure("C1 a5_aVal", a5, ref failure); } } @@ -166,8 +161,7 @@ public static int Test() a6._aVal = 1; if (1 != (byte)typeof(A1BoringGeneric).GetField("_aVal").GetValue(a6)) { - failure++; - Console.WriteLine("C1 a6_aVal"); + ATest.ReportTestFailure("C1 a6_aVal", a6, ref failure); } } @@ -176,8 +170,7 @@ public static int Test() a7._aVal = 1; if (1 != (byte)typeof(A1BoringGeneric).GetField("_aVal").GetValue(a7)) { - failure++; - Console.WriteLine("C1 a7_aVal"); + ATest.ReportTestFailure("C1 a7_aVal", a7, ref failure); } } @@ -186,8 +179,7 @@ public static int Test() b._bVal = 1; if (1 != (byte)typeof(B1_A).GetField("_bVal").GetValue(b)) { - failure++; - Console.WriteLine("C1 b._bVal"); + ATest.ReportTestFailure("C1 b_bVal", b, ref failure); } } @@ -196,8 +188,7 @@ public static int Test() b2._bVal = 1; if (1 != (byte)typeof(B1_A_byte).GetField("_bVal").GetValue(b2)) { - failure++; - Console.WriteLine("C1 b2._bVal"); + ATest.ReportTestFailure("C1 b2_bVal", b2, ref failure); } } @@ -206,8 +197,7 @@ public static int Test() b3._bVal = 1; if (1 != (byte)typeof(B1_A_D).GetField("_bVal").GetValue(b3)) { - failure++; - Console.WriteLine("C1 b3._bVal"); + ATest.ReportTestFailure("C1 b3_bVal", b3, ref failure); } } @@ -216,8 +206,7 @@ public static int Test() b4._bVal = 1; if (1 != (byte)typeof(B1_A_Generic).GetField("_bVal").GetValue(b4)) { - failure++; - Console.WriteLine("C1 b4._bVal"); + ATest.ReportTestFailure("C1 b4_bVal", b4, ref failure); } } @@ -226,8 +215,7 @@ public static int Test() b5._bVal = 1; if (1 != (byte)typeof(B1_A_byte_Generic).GetField("_bVal").GetValue(b5)) { - failure++; - Console.WriteLine("C1 b5._bVal"); + ATest.ReportTestFailure("C1 b5_bVal", b5, ref failure); } } @@ -236,8 +224,7 @@ public static int Test() b6._bVal = 1; if (1 != (byte)typeof(B1_A_D_Generic).GetField("_bVal").GetValue(b6)) { - failure++; - Console.WriteLine("C1 b6._bVal"); + ATest.ReportTestFailure("C1 b6_bVal", b6, ref failure); } } @@ -246,8 +233,7 @@ public static int Test() b7._bVal._dVal = 1; if (1 != ((ByteStruct)typeof(B1_A_Generic).GetField("_bVal").GetValue(b7))._dVal) { - failure++; - Console.WriteLine("C1 b7._bVal"); + ATest.ReportTestFailure("C1 b7_bVal", b7, ref failure); } } @@ -256,8 +242,7 @@ public static int Test() b8._bVal._dVal = 1; if (1 != ((ByteStruct)typeof(B1_A_byte_Generic).GetField("_bVal").GetValue(b8))._dVal) { - failure++; - Console.WriteLine("C1 b8._bVal"); + ATest.ReportTestFailure("C1 b8_bVal", b8, ref failure); } } @@ -266,8 +251,7 @@ public static int Test() b9._bVal._dVal = 1; if (1 != ((ByteStruct)typeof(B1_A_D_Generic).GetField("_bVal").GetValue(b9))._dVal) { - failure++; - Console.WriteLine("C1 b9._bVal"); + ATest.ReportTestFailure("C1 b9_bVal", b9, ref failure); } } @@ -276,8 +260,7 @@ public static int Test() b10._bVal = 1; if (1 != (byte)typeof(B1_ABoring_byte).GetField("_bVal").GetValue(b10)) { - failure++; - Console.WriteLine("C1 b10._bVal"); + ATest.ReportTestFailure("C1 b10_bVal", b10, ref failure); } } @@ -286,8 +269,7 @@ public static int Test() b11._bVal = 1; if (1 != (byte)typeof(B1_ABoring_D).GetField("_bVal").GetValue(b11)) { - failure++; - Console.WriteLine("C1 b11._bVal"); + ATest.ReportTestFailure("C1 b11_bVal", b11, ref failure); } } @@ -296,8 +278,7 @@ public static int Test() b12._bVal = 1; if (1 != (byte)typeof(B1_A1Boring_byte).GetField("_bVal").GetValue(b12)) { - failure++; - Console.WriteLine("C1 b12._bVal"); + ATest.ReportTestFailure("C1 b12_bVal", b12, ref failure); } } @@ -306,8 +287,7 @@ public static int Test() b13._bVal = 1; if (1 != (byte)typeof(B1_A1Boring_D).GetField("_bVal").GetValue(b13)) { - failure++; - Console.WriteLine("C1 b13._bVal"); + ATest.ReportTestFailure("C1 b13_bVal", b13, ref failure); } } @@ -316,8 +296,7 @@ public static int Test() c._cVal = 1; if (1 != (byte)typeof(C1_B_A).GetField("_cVal").GetValue(c)) { - failure++; - Console.WriteLine("C1 c._cVal"); + ATest.ReportTestFailure("C1 c_bVal", c, ref failure); } } @@ -326,8 +305,7 @@ public static int Test() c2._cVal = 1; if (1 != (byte)typeof(C1_B_A_byte).GetField("_cVal").GetValue(c2)) { - failure++; - Console.WriteLine("C1 c2._cVal"); + ATest.ReportTestFailure("C1 c2_bVal", c2, ref failure); } } @@ -336,8 +314,7 @@ public static int Test() c3._cVal = 1; if (1 != (byte)typeof(C1_B_A_D).GetField("_cVal").GetValue(c3)) { - failure++; - Console.WriteLine("C1 c3._cVal"); + ATest.ReportTestFailure("C1 c3_bVal", c3, ref failure); } } @@ -346,8 +323,7 @@ public static int Test() c4._cVal = 1; if (1 != (byte)typeof(C1_B_A_Generic_byte).GetField("_cVal").GetValue(c4)) { - failure++; - Console.WriteLine("C1 c4._cVal"); + ATest.ReportTestFailure("C1 c4_bVal", c4, ref failure); } } @@ -356,8 +332,7 @@ public static int Test() c5._cVal = 1; if (1 != (byte)typeof(C1_B_A_byte_Generic_byte).GetField("_cVal").GetValue(c5)) { - failure++; - Console.WriteLine("C1 c5._cVal"); + ATest.ReportTestFailure("C1 c5_bVal", c5, ref failure); } } @@ -366,8 +341,7 @@ public static int Test() c6._cVal = 1; if (1 != (byte)typeof(C1_B_A_D_Generic_byte).GetField("_cVal").GetValue(c6)) { - failure++; - Console.WriteLine("C1 c6._cVal"); + ATest.ReportTestFailure("C1 c6_bVal", c6, ref failure); } } @@ -376,8 +350,7 @@ public static int Test() c7._cVal = 1; if (1 != (byte)typeof(C1_B_A_Generic_D).GetField("_cVal").GetValue(c7)) { - failure++; - Console.WriteLine("C1 c7._cVal"); + ATest.ReportTestFailure("C1 c7_bVal", c7, ref failure); } } @@ -386,8 +359,7 @@ public static int Test() c8._cVal = 1; if (1 != (byte)typeof(C1_B_A_byte_Generic_D).GetField("_cVal").GetValue(c8)) { - failure++; - Console.WriteLine("C1 c8._cVal"); + ATest.ReportTestFailure("C1 c8_bVal", c8, ref failure); } } @@ -396,8 +368,7 @@ public static int Test() c9._cVal = 1; if (1 != (byte)typeof(C1_B_A_D_Generic_D).GetField("_cVal").GetValue(c9)) { - failure++; - Console.WriteLine("C1 c9._cVal"); + ATest.ReportTestFailure("C1 c9_bVal", c9, ref failure); } } From a59000b6db5e6526e8e9b6412193822b124a4a7a Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 23 Apr 2020 10:53:10 -0700 Subject: [PATCH 07/14] Passing Current Test Suite --- src/coreclr/src/vm/methodtablebuilder.cpp | 11 +++++++++-- .../crossboundarylayout/crossboundarytests.cmd | 9 ++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/coreclr/src/vm/methodtablebuilder.cpp b/src/coreclr/src/vm/methodtablebuilder.cpp index 1ff15be4db186b..5887b312a36396 100644 --- a/src/coreclr/src/vm/methodtablebuilder.cpp +++ b/src/coreclr/src/vm/methodtablebuilder.cpp @@ -11238,9 +11238,16 @@ bool ModuleInMatchingVersionBubble(Module *pModule, Module *pSecondModule) } else #else - if (!pModule->IsInSameVersionBubble(pSecondModule)) { - return false; + if (!pModule->GetFile()->IsILImageReadyToRun()) + { + // Non-R2R modules claim to be in the same version bubble as ALL other modules + return true; + } + if (!pModule->IsInSameVersionBubble(pSecondModule)) + { + return false; + } } #endif return true; diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd index 425075274247ca..d867acd221e6ba 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd @@ -3,10 +3,15 @@ setlocal set TESTDIR=%~dp0\..\..\..\..\..\..\artifacts\tests\coreclr\Windows_NT.x64.Debug\readytorun\crossboundarylayout\crossboundarytest\crossboundarytest set TESTBATCHROOT=%~dp0 +call :testCompositeScenarios call :testCG2SingleInputBubbleAll +call :testCG2All +call :testCG1All goto done +:testCompositeScenarios + call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% all a b crossboundarytest d call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% ad a d @@ -17,9 +22,7 @@ call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% a_crossboun call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% a_b_crossboundarytest a b crossboundarytest -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A a CG2Single - -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_ABubble a CG2SingleInputBubble +goto done :testCG1All From bdc07b4311915ee7cc50be6e0dc787efdb5995c9 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 23 Apr 2020 10:54:07 -0700 Subject: [PATCH 08/14] Remove halt from test --- src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs b/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs index ea076299133583..271a8f6e15ee21 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs @@ -30,11 +30,6 @@ public static void ReportTestFailure(string test, object o, ref int failCount) Console.WriteLine(test); s_testFailObj = o; failCount++; - while (true) - { - s_testFailObj = o; - Thread.Sleep(1000); - } } public static int Test() From 39d28b2e696edb45f68620b43eac3c5e4b257fa0 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 23 Apr 2020 17:38:58 -0700 Subject: [PATCH 09/14] Expand testing to cover more complex cases and in more thoroughness --- .../src/readytorun/crossboundarylayout/b/b.cs | 71 ++++ .../readytorun/crossboundarylayout/b/b.csproj | 1 + .../buildcrossgen2image.cmd | 17 +- .../crossboundarytests.cmd | 319 +++++++++++++++--- .../src/readytorun/crossboundarylayout/e/e.cs | 13 + .../readytorun/crossboundarylayout/e/e.csproj | 10 + .../crossboundarylayout/runindividualtest.cmd | 5 +- 7 files changed, 377 insertions(+), 59 deletions(-) create mode 100644 src/coreclr/tests/src/readytorun/crossboundarylayout/e/e.cs create mode 100644 src/coreclr/tests/src/readytorun/crossboundarylayout/e/e.csproj diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.cs b/src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.cs index 304a61e2373f28..6a7187c1f43ad1 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.cs +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.cs @@ -6,6 +6,11 @@ namespace CrossBoundaryLayout { + public struct ByteStructB + { + public byte _bsVal; + } + public class B_A : A { public byte _bVal; @@ -21,6 +26,16 @@ public class B_A_D : AGeneric public byte _bVal; } + public class B_A_BS : AGeneric + { + public byte _bVal; + } + + public class B_A_E : AGeneric + { + public byte _bVal; + } + public class B_A_Generic : A { public T _bVal; @@ -36,6 +51,16 @@ public class B_A_D_Generic : AGeneric public T _bVal; } + public class B_A_BS_Generic : AGeneric + { + public T _bVal; + } + + public class B_A_E_Generic : AGeneric + { + public T _bVal; + } + public class B_ABoring_byte : ABoringGeneric { public byte _bVal; @@ -46,6 +71,16 @@ public class B_ABoring_D : ABoringGeneric public byte _bVal; } + public class B_ABoring_BS : ABoringGeneric + { + public byte _bVal; + } + + public class B_ABoring_E : ABoringGeneric + { + public byte _bVal; + } + public class BTest { public static int Test() @@ -196,6 +231,42 @@ public static int Test() } } + { + var b12 = (B_A_BS)Activator.CreateInstance(typeof(B_A_BS)); + b12._bVal = 1; + if (1 != (byte)typeof(B_A_BS).GetField("_bVal").GetValue(b12)) + { + ATest.ReportTestFailure("B b12_bVal", b12, ref failure); + } + } + + { + var b13 = (B_A_E)Activator.CreateInstance(typeof(B_A_E)); + b13._bVal = 1; + if (1 != (byte)typeof(B_A_E).GetField("_bVal").GetValue(b13)) + { + ATest.ReportTestFailure("B b12_bVal", b13, ref failure); + } + } + + { + var b14 = (B_ABoring_BS)Activator.CreateInstance(typeof(B_ABoring_BS)); + b14._bVal = 1; + if (1 != (byte)typeof(B_ABoring_BS).GetField("_bVal").GetValue(b14)) + { + ATest.ReportTestFailure("B b12_bVal", b14, ref failure); + } + } + + { + var b15 = (B_ABoring_E)Activator.CreateInstance(typeof(B_ABoring_E)); + b15._bVal = 1; + if (1 != (byte)typeof(B_ABoring_E).GetField("_bVal").GetValue(b15)) + { + ATest.ReportTestFailure("B b12_bVal", b15, ref failure); + } + } + return failure; } } diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.csproj b/src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.csproj index 4af26f07b3fe4e..1eb8e6e923bcc7 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.csproj +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/b/b.csproj @@ -11,5 +11,6 @@ + diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd b/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd index b907191769fe5d..f392d825a8ed64 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd @@ -1,4 +1,3 @@ -@echo off setlocal set COMPOSITENAME= set COMPILEARG= @@ -25,9 +24,14 @@ if "%5"=="CG2Single" ( call :CG1Single shift ) ELSE ( - if "%5"=="CG2Composite" ( + if "%5"=="CG2SingleBubbleADOnly" ( + call :CG2SingleBubbleADOnly shift - call :Continue + ) ELSE ( + if "%5"=="CG2Composite" ( + shift + call :Continue + ) ) ) ) @@ -59,6 +63,13 @@ echo %BUILDCMD% > %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log call %BUILDCMD% >> %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log 2>&1 goto done +:CG2SingleBubbleADOnly +del %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll +set BUILDCMD=%TESTBATCHROOT%\..\..\..\..\..\..\.dotnet\dotnet %CORE_ROOT%\crossgen2\crossgen2.dll -r %CORE_ROOT%\* -r %TESTINITIALBINPATH%\d.dll -o %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll --inputbubble %TESTINITIALBINPATH%\%COMPOSITENAME%.dll +echo %BUILDCMD% > %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log +call %BUILDCMD% >> %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log 2>&1 +goto done + :CG1Single del %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll set BUILDCMD=%CORE_ROOT%\crossgen.exe /Platform_Assemblies_Paths %CORE_ROOT%;%TESTINITIALBINPATH% /out %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll /in %TESTINITIALBINPATH%\%COMPOSITENAME%.dll diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd index d867acd221e6ba..9a42e69026fb33 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd @@ -3,84 +3,297 @@ setlocal set TESTDIR=%~dp0\..\..\..\..\..\..\artifacts\tests\coreclr\Windows_NT.x64.Debug\readytorun\crossboundarylayout\crossboundarytest\crossboundarytest set TESTBATCHROOT=%~dp0 -call :testCompositeScenarios +rem call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B2C2D2E1 a e CG2Composite b crossboundarytest d CG2Composite +rem goto done + +call :testSpecificCompositeScenarios +call :testAllCombinationsOfCompositeAndR2R +call :testCG2SingleInputBubbleCompiledWithoutReferenceToBCE +call :testCG2SingleMixedInputBubble call :testCG2SingleInputBubbleAll call :testCG2All call :testCG1All goto done -:testCompositeScenarios +:testSpecificCompositeScenarios +echo Test some of the interesting composite scenarios first +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B2C2D2E1 a e CG2Composite b crossboundarytest d CG2Composite call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% all a b crossboundarytest d - call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% ad a d - call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% abd a b d - call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% a_crossboundarytest_d a crossboundarytest d - call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% a_b_crossboundarytest a b crossboundarytest goto done -:testCG1All - -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A___ a CG1Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__B__ b CG1Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_AB__ a CG1Single b CG1Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1___C_ crossboundarytest CG1Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A_C_ a CG1Single crossboundarytest CG1Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__BC_ b CG1Single crossboundarytest CG1Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_ABC_ a CG1Single b CG1Single crossboundarytest CG1Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1____D d CG1Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A__D a CG1Single d CG1Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__B_D b CG1Single d CG1Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_AB_D a CG1Single b CG1Single d CG1Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1___CD crossboundarytest CG1Single d CG1Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A_CD a CG1Single crossboundarytest CG1Single d CG1Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__BCD b CG1Single crossboundarytest CG1Single d CG1Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_ABCD a CG1Single b CG1Single crossboundarytest CG1Single d CG1Single +:testAllCombinationsOfCompositeAndR2R +echo testing all possible combinations of 1 regular R2R image mixed with the rest of the files being in a single composite image or alone +echo Also test all possible arrangements of 2 composite images +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B1C0D0E0 a b CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B0C1D0E0 a crossboundarytest CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B1C1D0E0 b crossboundarytest CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B1C1D0E0 a b crossboundarytest CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B1C1D0E0 b crossboundarytest CG2Composite a CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B2C1D0E0 a crossboundarytest CG2Composite b CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B2C1D0E0 crossboundarytest CG2Single a b CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B0C0D1E0 a d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B1C0D1E0 b d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B1C0D1E0 a b d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B1C0D1E0 b d CG2Composite a CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B2C0D1E0 a d CG2Composite b CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B2C0D1E0 d CG2Single a b CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B0C1D1E0 crossboundarytest d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B0C1D1E0 a crossboundarytest d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B0C1D1E0 crossboundarytest d CG2Composite a CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B1C1D1E0 b crossboundarytest d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B1C1D1E0 a b crossboundarytest d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B1C1D1E0 b crossboundarytest d CG2Composite a CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B2C1D1E0 crossboundarytest d CG2Composite b CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B2C1D1E0 a crossboundarytest d CG2Composite b CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B2C1D1E0 crossboundarytest d CG2Composite a b CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B0C2D1E0 a d CG2Composite crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B0C2D1E0 d CG2Single a crossboundarytest CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B1C2D1E0 b d CG2Composite crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B1C2D1E0 a b d CG2Composite crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B1C2D1E0 b d CG2Composite a crossboundarytest CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B2C2D1E0 d CG2Single b crossboundarytest CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B2C2D1E0 a d CG2Composite b crossboundarytest CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B2C2D1E0 d CG2Single a b crossboundarytest CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B0C0D0E1 a e CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B1C0D0E1 b e CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B1C0D0E1 a b e CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B1C0D0E1 b e CG2Composite a CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B2C0D0E1 a e CG2Composite b CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B2C0D0E1 e CG2Single a b CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B0C1D0E1 crossboundarytest e CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B0C1D0E1 a crossboundarytest e CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B0C1D0E1 crossboundarytest e CG2Composite a CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B1C1D0E1 b crossboundarytest e CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B1C1D0E1 a b crossboundarytest e CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B1C1D0E1 b crossboundarytest e CG2Composite a CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B2C1D0E1 crossboundarytest e CG2Composite b CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B2C1D0E1 a crossboundarytest e CG2Composite b CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B2C1D0E1 crossboundarytest e CG2Composite a b CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B0C2D0E1 a e CG2Composite crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B0C2D0E1 e CG2Single a crossboundarytest CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B1C2D0E1 b e CG2Composite crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B1C2D0E1 a b e CG2Composite crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B1C2D0E1 b e CG2Composite a crossboundarytest CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B2C2D0E1 e CG2Single b crossboundarytest CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B2C2D0E1 a e CG2Composite b crossboundarytest CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B2C2D0E1 e CG2Single a b crossboundarytest CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B0C0D1E1 d e CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B0C0D1E1 a d e CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B0C0D1E1 d e CG2Composite a CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B1C0D1E1 b d e CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B1C0D1E1 a b d e CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B1C0D1E1 b d e CG2Composite a CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B2C0D1E1 d e CG2Composite b CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B2C0D1E1 a d e CG2Composite b CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B2C0D1E1 d e CG2Composite a b CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B0C1D1E1 crossboundarytest d e CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B0C1D1E1 a crossboundarytest d e CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B0C1D1E1 crossboundarytest d e CG2Composite a CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B1C1D1E1 b crossboundarytest d e CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B1C1D1E1 a b crossboundarytest d e CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B1C1D1E1 b crossboundarytest d e CG2Composite a CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B2C1D1E1 crossboundarytest d e CG2Composite b CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B2C1D1E1 a crossboundarytest d e CG2Composite b CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B2C1D1E1 crossboundarytest d e CG2Composite a b CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B0C2D1E1 d e CG2Composite crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B0C2D1E1 a d e CG2Composite crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B0C2D1E1 d e CG2Composite a crossboundarytest CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B1C2D1E1 b d e CG2Composite crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B1C2D1E1 a b d e CG2Composite crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B1C2D1E1 b d e CG2Composite a crossboundarytest CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B2C2D1E1 d e CG2Composite b crossboundarytest CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B2C2D1E1 a d e CG2Composite b crossboundarytest CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B2C2D1E1 d e CG2Composite a b crossboundarytest CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B0C0D2E1 a e CG2Composite d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B0C0D2E1 e CG2Single a d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B1C0D2E1 b e CG2Composite d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B1C0D2E1 a b e CG2Composite d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B1C0D2E1 b e CG2Composite a d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B2C0D2E1 e CG2Single b d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B2C0D2E1 a e CG2Composite b d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B2C0D2E1 e CG2Single a b d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B0C1D2E1 crossboundarytest e CG2Composite d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B0C1D2E1 a crossboundarytest e CG2Composite d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B0C1D2E1 crossboundarytest e CG2Composite a d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B1C1D2E1 b crossboundarytest e CG2Composite d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B1C1D2E1 a b crossboundarytest e CG2Composite d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B1C1D2E1 b crossboundarytest e CG2Composite a d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B2C1D2E1 crossboundarytest e CG2Composite b d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B2C1D2E1 a crossboundarytest e CG2Composite b d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B2C1D2E1 crossboundarytest e CG2Composite a b d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B0C2D2E1 e CG2Single crossboundarytest d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B0C2D2E1 a e CG2Composite crossboundarytest d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B0C2D2E1 e CG2Single a crossboundarytest d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B1C2D2E1 b e CG2Composite crossboundarytest d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B1C2D2E1 a b e CG2Composite crossboundarytest d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B1C2D2E1 b e CG2Composite a crossboundarytest d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA0B2C2D2E1 e CG2Single b crossboundarytest d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B2C2D2E1 a e CG2Composite b crossboundarytest d CG2Composite +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA2B2C2D2E1 e CG2Single a b crossboundarytest d CG2Composite goto done :testCG2SingleInputBubbleAll -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A___ a CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__B__ b CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_AB__ a CG2SingleInputBubble b CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble___C_ crossboundarytest CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A_C_ a CG2SingleInputBubble crossboundarytest CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__BC_ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_ABC_ a CG2SingleInputBubble b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble____D d CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A__D a CG2SingleInputBubble d CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__B_D b CG2SingleInputBubble d CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_AB_D a CG2SingleInputBubble b CG2SingleInputBubble d CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble___CD crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A_CD a CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__BCD b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_ABCD a CG2SingleInputBubble b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble +echo TEST All combinations of the 5 dlls compiled with Crossgen2 with input bubble enabled and all assemblies passed as reference inputs to crossgen2 +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A____ a CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__B___ b CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_AB___ a CG2SingleInputBubble b CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble___C__ crossboundarytest CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A_C__ a CG2SingleInputBubble crossboundarytest CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__BC__ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_ABC__ a CG2SingleInputBubble b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble____D_ d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A__D_ a CG2SingleInputBubble d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__B_D_ b CG2SingleInputBubble d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_AB_D_ a CG2SingleInputBubble b CG2SingleInputBubble d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble___CD_ crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A_CD_ a CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__BCD_ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_ABCD_ a CG2SingleInputBubble b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_____E e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A___E a CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__B__E b CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_AB__E a CG2SingleInputBubble b CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble___C_E crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A_C_E a CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__BC_E b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_ABC_E a CG2SingleInputBubble b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble____DE d CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A__DE a CG2SingleInputBubble d CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__B_DE b CG2SingleInputBubble d CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_AB_DE a CG2SingleInputBubble b CG2SingleInputBubble d CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble___CDE crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A_CDE a CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__BCDE b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_ABCDE a CG2SingleInputBubble b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble e CG2SingleInputBubble goto done -:testCG2All +:testCG2SingleInputBubbleCompiledWithoutReferenceToBCE +echo TEST All combinations of the 5 dlls compiled with Crossgen2 with input bubble enabled and all assemblies passed as +echo reference inputs to crossgen2 when compiled b, crossboundarytest and e. a, and d are compiled with the reference +echo set limited to a and d. This simulates a the model of two different sets of input bubble matched assemblies where there is a +echo root set such as the runtime repo worth of libraries, and a seperately compiled application set. + +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A____ a CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__B___ b CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_AB___ a CG2SingleBubbleADOnly b CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2___C__ crossboundarytest CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A_C__ a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__BC__ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_ABC__ a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2____D_ d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A__D_ a CG2SingleBubbleADOnly d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__B_D_ b CG2SingleInputBubble d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_AB_D_ a CG2SingleBubbleADOnly b CG2SingleInputBubble d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2___CD_ crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A_CD_ a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__BCD_ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_ABCD_ a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_____E e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A___E a CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__B__E b CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_AB__E a CG2SingleBubbleADOnly b CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2___C_E crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A_C_E a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__BC_E b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_ABC_E a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2____DE d CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A__DE a CG2SingleBubbleADOnly d CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__B_DE b CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_AB_DE a CG2SingleBubbleADOnly b CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2___CDE crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A_CDE a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__BCDE b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_ABCDE a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble + +goto done +:testCG2SingleMixedInputBubble +echo TEST All combinations of the 5 dlls compiled with Crossgen2 with input bubble enabled for the root set and not +echo for the more derived set of assemblies. b, crossboundarytest, and e are compiled as standard R2R and +echo a, and d are compiled with the reference echo set limited to a and d with input bubble enabled. This simulates a the model +echo of a framework that ships with input bubble enabled, and the application with standard R2R rules. + +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A____ a CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__B___ b CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_AB___ a CG2SingleBubbleADOnly b CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3___C__ crossboundarytest CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A_C__ a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__BC__ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_ABC__ a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3____D_ d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A__D_ a CG2SingleBubbleADOnly d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__B_D_ b CG2SingleInputBubble d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_AB_D_ a CG2SingleBubbleADOnly b CG2SingleInputBubble d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3___CD_ crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A_CD_ a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__BCD_ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_ABCD_ a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_____E e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A___E a CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__B__E b CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_AB__E a CG2SingleBubbleADOnly b CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3___C_E crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A_C_E a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__BC_E b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_ABC_E a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3____DE d CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A__DE a CG2SingleBubbleADOnly d CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__B_DE b CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_AB_DE a CG2SingleBubbleADOnly b CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3___CDE crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A_CDE a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__BCDE b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_ABCDE a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble + +goto done + + +:testCG2All +echo TEST All combinations of compiling standard R2R with the crossgen2 tool instad of crossgen1 call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A___ a CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2__B__ b CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_AB__ a CG2Single b CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2___C_ crossboundarytest CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A_C_ a CG2Single crossboundarytest CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2__BC_ b CG2Single crossboundarytest CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_ABC_ a CG2Single b CG2Single crossboundarytest CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2____D d CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A__D a CG2Single d CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2__B_D b CG2Single d CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_AB_D a CG2Single b CG2Single d CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2___CD crossboundarytest CG2Single d CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A_CD a CG2Single crossboundarytest CG2Single d CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2__BCD b CG2Single crossboundarytest CG2Single d CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_ABCD a CG2Single b CG2Single crossboundarytest CG2Single d CG2Single + +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A____ a CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__B___ b CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_AB___ a CG2Single b CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1___C__ crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A_C__ a CG2Single crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__BC__ b CG2Single crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_ABC__ a CG2Single b CG2Single crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1____D_ d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A__D_ a CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__B_D_ b CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_AB_D_ a CG2Single b CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1___CD_ crossboundarytest CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A_CD_ a CG2Single crossboundarytest CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__BCD_ b CG2Single crossboundarytest CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_ABCD_ a CG2Single b CG2Single crossboundarytest CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_____E e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A___E a CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__B__E b CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_AB__E a CG2Single b CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1___C_E crossboundarytest CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A_C_E a CG2Single crossboundarytest CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__BC_E b CG2Single crossboundarytest CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_ABC_E a CG2Single b CG2Single crossboundarytest CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1____DE d CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A__DE a CG2Single d CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__B_DE b CG2Single d CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_AB_DE a CG2Single b CG2Single d CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1___CDE crossboundarytest CG2Single d CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A_CDE a CG2Single crossboundarytest CG2Single d CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__BCDE b CG2Single crossboundarytest CG2Single d CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_ABCDE a CG2Single b CG2Single crossboundarytest CG2Single d CG2Single e CG2Single + goto done diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/e/e.cs b/src/coreclr/tests/src/readytorun/crossboundarylayout/e/e.cs new file mode 100644 index 00000000000000..bbbc3387f43c6b --- /dev/null +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/e/e.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace CrossBoundaryLayout +{ + public struct ByteStructE + { + public byte _eVal; + } +} \ No newline at end of file diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/e/e.csproj b/src/coreclr/tests/src/readytorun/crossboundarylayout/e/e.csproj new file mode 100644 index 00000000000000..3e752d68f2ea7e --- /dev/null +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/e/e.csproj @@ -0,0 +1,10 @@ + + + library + SharedLibrary + + + + + + diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/runindividualtest.cmd b/src/coreclr/tests/src/readytorun/crossboundarylayout/runindividualtest.cmd index e12a875e30a731..55d86f9e91e057 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/runindividualtest.cmd +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/runindividualtest.cmd @@ -1,9 +1,8 @@ -rem @echo off setlocal -rd /s /q %2\%3 +rd /s /q %2\%3 2> nul md %2\%3 copy %2\* %2\%3 > nul -call %1\buildcrossgen2image.cmd %1 %2 %3 %4 %5 %6 %7 +call %1\buildcrossgen2image.cmd %* @echo on %CORE_ROOT%\corerun %2\%3\crossboundarytest.dll @echo off From c7f997a15d4081a39cbb0a4a8ba107dd719053c5 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 24 Apr 2020 18:15:54 -0700 Subject: [PATCH 10/14] Field layout static-ness is entirely dependent on the instance layout, not the static layout. --- .../Compiler/ReadyToRunCodegenCompilation.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs index e0ef8aa1af3635..4c6210b8fa23bb 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs @@ -365,6 +365,10 @@ public bool IsLayoutFixedInCurrentVersionBubble(TypeDesc type) // it is important for generic types with non-versionable layout (e.g. Nullable) foreach (var field in type.GetFields()) { + // Only instance fields matter here + if (field.IsStatic) + continue; + var fieldType = field.FieldType; if (!fieldType.IsValueType) continue; From 2cd3f3bcabe377680d61adb3134ab359a237c263 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Tue, 28 Apr 2020 17:41:17 -0700 Subject: [PATCH 11/14] Rework of algorithm --- .../NoMethodsCompilationModuleGroup.cs | 51 ++++ .../Compiler/ReadyToRunCodegenCompilation.cs | 28 ++- .../ReadyToRunCompilationModuleGroupBase.cs | 221 +++++++++--------- .../ILCompiler.ReadyToRun.csproj | 1 + .../crossgen2/crossgen2/CommandLineOptions.cs | 2 + .../src/tools/crossgen2/crossgen2/Program.cs | 14 +- .../crossgen2/Properties/Resources.resx | 3 + src/coreclr/src/vm/class.h | 17 +- src/coreclr/src/vm/methodtablebuilder.cpp | 133 ++--------- 9 files changed, 230 insertions(+), 240 deletions(-) create mode 100644 src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/NoMethodsCompilationModuleGroup.cs diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/NoMethodsCompilationModuleGroup.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/NoMethodsCompilationModuleGroup.cs new file mode 100644 index 00000000000000..cc97f72a952613 --- /dev/null +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/NoMethodsCompilationModuleGroup.cs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using Internal.ReadyToRunConstants; +using Internal.TypeSystem; +using Internal.TypeSystem.Ecma; + +namespace ILCompiler +{ + /// + /// A compilation group that only contains no methods. Used for creating an R2R image without + /// any method compiled into it. Needed for handling inputbubble scenarios where a dependent + /// assembly should not be R2R'd. + /// + public class NoMethodsCompilationModuleGroup : ReadyToRunCompilationModuleGroupBase + { + public NoMethodsCompilationModuleGroup( + TypeSystemContext context, + bool isCompositeBuildMode, + bool isInputBubble, + IEnumerable compilationModuleSet, + IEnumerable versionBubbleModuleSet, + bool compileGenericDependenciesFromVersionBubbleModuleSet) : + base(context, + isCompositeBuildMode, + isInputBubble, + compilationModuleSet, + versionBubbleModuleSet, + compileGenericDependenciesFromVersionBubbleModuleSet) + { + } + + public override bool ContainsMethodBody(MethodDesc method, bool unboxingStub) + { + return false; + } + + public override void ApplyProfilerGuidedCompilationRestriction(ProfileDataManager profileGuidedCompileRestriction) + { + return; + } + + public override ReadyToRunFlags GetReadyToRunFlags() + { + // Partial by definition. + return ReadyToRunFlags.READYTORUN_FLAG_Partial; + } + } +} diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs index 4c6210b8fa23bb..a03c94d68f4997 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs @@ -228,6 +228,7 @@ public sealed class ReadyToRunCodegenCompilation : Compilation private bool _generateMapFile; public ReadyToRunSymbolNodeFactory SymbolNodeFactory { get; } + public ReadyToRunCompilationModuleGroupBase CompilationModuleGroup { get; } internal ReadyToRunCodegenCompilation( DependencyAnalyzerBase dependencyGraph, @@ -257,6 +258,7 @@ internal ReadyToRunCodegenCompilation( SymbolNodeFactory = new ReadyToRunSymbolNodeFactory(nodeFactory); _corInfoImpls = new ConditionalWeakTable(); _inputFiles = inputFiles; + CompilationModuleGroup = (ReadyToRunCompilationModuleGroupBase)nodeFactory.CompilationModuleGroup; // Generate baseline support specification for InstructionSetSupport. This will prevent usage of the generated // code if the runtime environment doesn't support the specified instruction set @@ -387,13 +389,31 @@ public bool IsInheritanceChainLayoutFixedInCurrentVersionBubble(TypeDesc type) // This method is not expected to be called for value types Debug.Assert(!type.IsValueType); - while (!type.IsObject && type != null) + if (type.IsObject) + return true; + + if (!IsLayoutFixedInCurrentVersionBubble(type)) { - if (!IsLayoutFixedInCurrentVersionBubble(type)) - { + return false; + } + + type = type.BaseType; + + if (type != null) + { + // If there are multiple inexact compilation units in the layout of the type, then the exact offset + // of a derived given field is unknown as there may or may not be alignment inserted between a type and its base + if (CompilationModuleGroup.TypeLayoutCompilationUnits(type).HasMultipleInexactCompilationUnits) return false; + + while (!type.IsObject && type != null) + { + if (!IsLayoutFixedInCurrentVersionBubble(type)) + { + return false; + } + type = type.BaseType; } - type = type.BaseType; } return true; diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs index 9049d75d514337..0c4cdc2bfdf2f5 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using Internal.TypeSystem; @@ -21,10 +22,11 @@ public abstract class ReadyToRunCompilationModuleGroupBase : CompilationModuleGr private readonly bool _compileGenericDependenciesFromVersionBubbleModuleSet; private readonly bool _isCompositeBuildMode; private readonly bool _isInputBubble; - private readonly ConcurrentDictionary _layoutDependsOnOtherModules = new ConcurrentDictionary(); - private readonly ConcurrentDictionary _layoutDependsOnOtherVersionBubbles = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _layoutCompilationUnits = new ConcurrentDictionary(); private readonly ConcurrentDictionary _versionsWithTypeCache = new ConcurrentDictionary(); private readonly ConcurrentDictionary _versionsWithMethodCache = new ConcurrentDictionary(); + private readonly Dictionary _moduleCompilationUnits = new Dictionary(); + private int _maxCompilationUnitsKnown = 3; public ReadyToRunCompilationModuleGroupBase( TypeSystemContext context, @@ -70,131 +72,135 @@ protected bool CompileVersionBubbleGenericsIntoCurrentModule(MethodDesc method) return true; } - public virtual bool TypeLayoutDependsOnOtherModules(TypeDesc type) + public CompilationUnitSet TypeLayoutCompilationUnits(TypeDesc type) { - return _layoutDependsOnOtherModules.GetOrAdd(type, TypeLayoutDependsOnOtherModulesUncached); + return _layoutCompilationUnits.GetOrAdd(type, TypeLayoutCompilationUnitsUncached); } - public virtual bool TypeLayoutDependsOnOtherVersionBubbles(TypeDesc type) + // Compilation Unit Index is the compilation unit of a given module. If the compilation unit + // is unknown the module will be given an independent index from other modules, but + // IsCompilationUnitIndexExact will return false for that index. All compilation unit indices + // are >= 2, to allow for 0 to be a sentinel value. + private int ModuleToCompilationUnitIndex(ModuleDesc nonEcmaModule) { - return _layoutDependsOnOtherVersionBubbles.GetOrAdd(type, TypeLayoutDependsOnOtherVersionBubblesUncached); + EcmaModule module = (EcmaModule)nonEcmaModule; + if (IsModuleInCompilationGroup(module)) + return 2; + + if (!VersionsWithModule(module)) + return 3; + + lock (_moduleCompilationUnits) + { + if (!_moduleCompilationUnits.TryGetValue(module, out int compilationUnit)) + { + compilationUnit = ++_maxCompilationUnitsKnown; + _moduleCompilationUnits.Add(module, compilationUnit); + } + + return compilationUnit; + } } - private bool TypeLayoutDependsOnOtherModulesUncached(TypeDesc type) + // Indicate + private bool IsCompilationUnitIndexExact(int compilationUnitIndex) { - if (type.IsObject || - type.IsPrimitive || - type.IsEnum || - type.IsPointer || - type.IsFunctionPointer || - type.IsCanonicalDefinitionType(CanonicalFormKind.Any)) - { + if (compilationUnitIndex != 2) return false; - } + else + return true; + } - var defType = (MetadataType)type; + public struct CompilationUnitSet + { + private BitArray _bits; - if (type.BaseType != null) + public CompilationUnitSet(ReadyToRunCompilationModuleGroupBase compilationGroup, ModuleDesc module) { - if (CompareTypeLayoutForModuleCheck((MetadataType)type.BaseType)) - return true; + int compilationIndex = compilationGroup.ModuleToCompilationUnitIndex(module); + _bits = new BitArray(compilationIndex + 1); + _bits.Set(compilationIndex, true); } - foreach (FieldDesc field in defType.GetFields()) + public bool HasMultipleInexactCompilationUnits { - if (field.IsStatic) - continue; - - TypeDesc fieldType = field.FieldType; - - if (fieldType.IsValueType && - !fieldType.IsPrimitive) + get { - if (CompareTypeLayoutForModuleCheck((MetadataType)fieldType)) - { - return true; - } + if (_bits == null) + return false; + + return _bits[0]; } } - return false; - - bool CompareTypeLayoutForModuleCheck(MetadataType otherType) + public bool HasMultipleCompilationUnits { - if (otherType.Module != defType.Module || - TypeLayoutDependsOnOtherModules(otherType)) + get { - return true; + if (_bits == null) + return false; + + return _bits[1]; } - return false; } - } - - private bool ModuleInMatchingVersionBubble(ModuleDesc module1, ModuleDesc module2) - { - return VersionsWithModule(module1) == VersionsWithModule(module2); - } - public bool NeedsAlignmentBetweenBaseTypeAndDerived(MetadataType baseType, MetadataType derivedType) - { - - if (!ModuleInMatchingVersionBubble(derivedType.Module, baseType.Module) || - TypeLayoutDependsOnOtherVersionBubbles(baseType) || - LayoutDependsOnTypeVariableInstantiationWhichDependsOnOtherModules(baseType)) + public void UnionWith(ReadyToRunCompilationModuleGroupBase compilationGroup, CompilationUnitSet other) { - return true; - } + if (other._bits == null) + return; - return false; - - bool LayoutDependsOnTypeVariableInstantiationWhichDependsOnOtherModules(MetadataType type) - { - // Types without instantiations do not depend on their type variables for layout - if (!type.HasInstantiation) - return false; - - // Types that are not instantiated do not depend on their type variables for layout. - if (type.IsTypeDefinition) - return false; + if (HasMultipleInexactCompilationUnits) + return; - // If no part of the layout of this type depends on other modules, then there is no need - // to check for a type variable caused case - if (!TypeLayoutDependsOnOtherModules(type)) - return false; - - foreach (var field in type.GetFields()) + if (other.HasMultipleInexactCompilationUnits) { - var fieldType = field.FieldType; - - // non valuetypes are uninteresting for this check - if (!fieldType.IsValueType) - continue; + _bits[1] = true; + return; + } - // As primitive types are considered part of all version bubbles, they are also unconsidered - if (fieldType.IsPrimitive) - continue; + if (other._bits.Length > _bits.Length) + _bits.Length = other._bits.Length; + + if (other._bits.Length < _bits.Length) + { + for (int i = 0; i < other._bits.Length; i++) + { + if (other._bits[i]) + _bits[i] = true; + } + } + else + { + _bits.Or(other._bits); + } - var fieldTypeOnOpenType = field.GetTypicalFieldDefinition().FieldType; + int inexactCompilationUnitCount = 0; + int compilationUnitCount = 0; + for (int i = 2; i < _bits.Length; i++) + { + if (_bits[i]) + { + if (!compilationGroup.IsCompilationUnitIndexExact(i)) + inexactCompilationUnitCount++; - if (fieldType == fieldTypeOnOpenType) + compilationUnitCount++; + } + if (inexactCompilationUnitCount == 2) { - // If the field type is the same, it isn't dependent on a type variable - continue; + // Multiple compilation units found + _bits[1] = true; } - - if (TypeLayoutDependsOnOtherModules(fieldType) || - ((MetadataType)fieldType).Module != type.Module) + if (inexactCompilationUnitCount > 1) { - // The layout of this field depends on other modules. - return true; + // Multiple inexact compilation units involved + _bits[0] = true; + break; } } - - return false; } } - private bool TypeLayoutDependsOnOtherVersionBubblesUncached(TypeDesc type) + private CompilationUnitSet TypeLayoutCompilationUnitsUncached(TypeDesc type) { if (type.IsObject || type.IsPrimitive || @@ -203,18 +209,16 @@ private bool TypeLayoutDependsOnOtherVersionBubblesUncached(TypeDesc type) type.IsFunctionPointer || type.IsCanonicalDefinitionType(CanonicalFormKind.Any)) { - return false; + return default(CompilationUnitSet); } var defType = (MetadataType)type; + CompilationUnitSet moduleDependencySet = new CompilationUnitSet(this, defType.Module); + if ((type.BaseType != null) && !type.BaseType.IsObject) { - if (CompareTypeLayoutForVersionBubble((MetadataType)type.BaseType)) - return true; - - if (NeedsAlignmentBetweenBaseTypeAndDerived(baseType: (MetadataType)type.BaseType, derivedType: defType)) - return true; + moduleDependencySet.UnionWith(this, TypeLayoutCompilationUnits(type.BaseType)); } foreach (FieldDesc field in defType.GetFields()) @@ -227,24 +231,27 @@ private bool TypeLayoutDependsOnOtherVersionBubblesUncached(TypeDesc type) if (fieldType.IsValueType && !fieldType.IsPrimitive) { - if (CompareTypeLayoutForVersionBubble((MetadataType)fieldType)) - { - return true; - } + moduleDependencySet.UnionWith(this, TypeLayoutCompilationUnits((MetadataType)fieldType)); } } - return false; + return moduleDependencySet; + } + + private bool ModuleMatchesCompilationUnitIndex(ModuleDesc module1, ModuleDesc module2) + { + return ModuleToCompilationUnitIndex(module1) == ModuleToCompilationUnitIndex(module2); + } - bool CompareTypeLayoutForVersionBubble(MetadataType otherType) + public bool NeedsAlignmentBetweenBaseTypeAndDerived(MetadataType baseType, MetadataType derivedType) + { + if (!ModuleMatchesCompilationUnitIndex(derivedType.Module, baseType.Module) || + TypeLayoutCompilationUnits(baseType).HasMultipleCompilationUnits) { - if (!ModuleInMatchingVersionBubble(otherType.Module, defType.Module) || - TypeLayoutDependsOnOtherVersionBubbles(otherType)) - { - return true; - } - return false; + return true; } + + return false; } public sealed override bool VersionsWithModule(ModuleDesc module) diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj index f36eb5fd382cdf..8d78625a2beaba 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/ILCompiler.ReadyToRun.csproj @@ -198,6 +198,7 @@ + diff --git a/src/coreclr/src/tools/crossgen2/crossgen2/CommandLineOptions.cs b/src/coreclr/src/tools/crossgen2/crossgen2/CommandLineOptions.cs index 4fa9271d1c20cc..534bec5b6970f9 100644 --- a/src/coreclr/src/tools/crossgen2/crossgen2/CommandLineOptions.cs +++ b/src/coreclr/src/tools/crossgen2/crossgen2/CommandLineOptions.cs @@ -23,6 +23,7 @@ public class CommandLineOptions public bool CompileBubbleGenerics { get; set; } public bool Verbose { get; set; } public bool Composite { get; set; } + public bool CompileNoMethods { get; set; } public FileInfo DgmlLogFileName { get; set; } public bool GenerateFullDgmlLog { get; set; } @@ -100,6 +101,7 @@ public static Command RootCommand() new Option(new[] { "--optimize-time", "--Ot" }, SR.OptimizeSpeedOption), new Option(new[] { "--inputbubble" }, SR.InputBubbleOption), new Option(new[] { "--composite" }, SR.CompositeBuildMode), + new Option(new[] { "--compile-no-methods" }, SR.CompileNoMethodsOption), new Option(new[] { "--tuning" }, SR.TuningImageOption) { Argument = new Argument() diff --git a/src/coreclr/src/tools/crossgen2/crossgen2/Program.cs b/src/coreclr/src/tools/crossgen2/crossgen2/Program.cs index d6f98eb7d905b7..72843451e10e26 100644 --- a/src/coreclr/src/tools/crossgen2/crossgen2/Program.cs +++ b/src/coreclr/src/tools/crossgen2/crossgen2/Program.cs @@ -400,6 +400,16 @@ private int Run() singleMethod); compilationRoots.Add(new SingleMethodRootProvider(singleMethod)); } + else if (_commandLineOptions.CompileNoMethods) + { + compilationGroup = new NoMethodsCompilationModuleGroup( + typeSystemContext, + _commandLineOptions.Composite, + _commandLineOptions.InputBubble, + inputModules, + versionBubbleModules, + _commandLineOptions.CompileBubbleGenerics); + } else { // Single assembly compilation. @@ -428,9 +438,9 @@ private int Run() else compilationGroup.ApplyProfilerGuidedCompilationRestriction(null); - if (singleMethod == null) + if ((singleMethod == null) && !_commandLineOptions.CompileNoMethods) { - // For non-single-method compilations add compilation roots. + // For normal compilations add compilation roots. foreach (var module in rootingModules) { compilationRoots.Add(new ReadyToRunRootProvider( diff --git a/src/coreclr/src/tools/crossgen2/crossgen2/Properties/Resources.resx b/src/coreclr/src/tools/crossgen2/crossgen2/Properties/Resources.resx index f809bfa1a8879b..58c6319f28f863 100644 --- a/src/coreclr/src/tools/crossgen2/crossgen2/Properties/Resources.resx +++ b/src/coreclr/src/tools/crossgen2/crossgen2/Properties/Resources.resx @@ -138,6 +138,9 @@ True when the entire input forms a version bubble (default = per-assembly bubble) + + True to not compile any methods into the R2R image (default = false) + Emit a composite R2R image comprising a number of input assemblies diff --git a/src/coreclr/src/vm/class.h b/src/coreclr/src/vm/class.h index f52fc4522cbcfe..9158760e0861b8 100644 --- a/src/coreclr/src/vm/class.h +++ b/src/coreclr/src/vm/class.h @@ -1297,18 +1297,6 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! LIMITED_METHOD_CONTRACT; m_VMFlags |= VMFLAG_LAYOUT_DEPENDS_ON_OTHER_MODULES; } - - inline BOOL HasLayoutDependsOnOtherVersionBubbles() - { - LIMITED_METHOD_CONTRACT; - return m_VMFlags & VMFLAG_LAYOUT_DEPENDS_ON_OTHER_VERSIONBUBBLE; - } - - inline void SetHasLayoutDependsOnOtherVersionBubbles() - { - LIMITED_METHOD_CONTRACT; - m_VMFlags |= VMFLAG_LAYOUT_DEPENDS_ON_OTHER_VERSIONBUBBLE; - } #endif // Is this delegate? Returns false for System.Delegate and System.MulticastDelegate. @@ -1713,10 +1701,7 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! #endif VMFLAG_DELEGATE = 0x00000002, -#ifdef FEATURE_READYTORUN - VMFLAG_LAYOUT_DEPENDS_ON_OTHER_VERSIONBUBBLE = 0x0000004, -#endif - // VMFLAG_UNUSED = 0x00000018, + // VMFLAG_UNUSED = 0x0000001c, VMFLAG_FIXED_ADDRESS_VT_STATICS = 0x00000020, // Value type Statics in this class will be pinned VMFLAG_HASLAYOUT = 0x00000040, diff --git a/src/coreclr/src/vm/methodtablebuilder.cpp b/src/coreclr/src/vm/methodtablebuilder.cpp index 5887b312a36396..32fc2fd89a1deb 100644 --- a/src/coreclr/src/vm/methodtablebuilder.cpp +++ b/src/coreclr/src/vm/methodtablebuilder.cpp @@ -11227,94 +11227,15 @@ VOID MethodTableBuilder::CheckForSpecialTypes() #ifdef FEATURE_READYTORUN -bool ModuleInMatchingVersionBubble(Module *pModule, Module *pSecondModule) +bool ModulesAreDistributedAsAnIndivisibleUnit(Module* module1, Module* module2) { - STANDARD_VM_CONTRACT; -#ifdef FEATURE_READYTORUN_COMPILER - if (IsReadyToRunCompilation() && - !pSecondModule->IsInCurrentVersionBubble()) - { - return false; - } - else -#else - { - if (!pModule->GetFile()->IsILImageReadyToRun()) - { - // Non-R2R modules claim to be in the same version bubble as ALL other modules - return true; - } - if (!pModule->IsInSameVersionBubble(pSecondModule)) - { - return false; - } - } -#endif - return true; -} - -bool LayoutDependsOnTypeVariableInstantiationWhichDependsOnOtherModules(MethodTable *pMT) -{ - STANDARD_VM_CONTRACT; - - // Types without instantiations do not depend on their type variables for layout - if (!pMT->HasInstantiation()) - return false; + if (module1 == module2) + return true; - // Types that are not instantiated do not depend on their type variables for layout. - if (pMT->IsGenericTypeDefinition()) - return false; - - // If no part of the layout of this type depends on other modules, then there is no need - // to check for a type variable caused case - if (!pMT->GetClass()->HasLayoutDependsOnOtherModules()) - return false; - - MethodTable *pMTTypical = ClassLoader::LoadTypeDefOrRefThrowing( - pMT->GetModule(), - pMT->GetCl(), - ClassLoader::ThrowIfNotFound, - ClassLoader::PermitUninstDefOrRef, - tdNoTypes, - CLASS_LOAD_APPROXPARENTS).AsMethodTable(); - - DWORD cParentInstanceFields; - - MethodTable *pParentMT = pMT->GetParentMethodTable(); - if (pParentMT != NULL) - { - cParentInstanceFields = pParentMT->GetClass()->GetNumInstanceFields(); - } - else - { - cParentInstanceFields = 0; - } - - DWORD numFields = pMT->GetNumInstanceFields() - cParentInstanceFields; - FieldDesc *pStartFieldMT = pMT->GetClass()->GetFieldDescList(); - FieldDesc *pStartFieldMTTypical = pMTTypical->GetClass()->GetFieldDescList(); - for (DWORD iField = 0; iField < numFields; iField++) + bool nativeImagesIdentical = false; + if (module1->GetCompositeNativeImage() != NULL) { - _ASSERTE(pStartFieldMT[iField].GetMemberDef() == pStartFieldMTTypical[iField].GetMemberDef()); - if (pStartFieldMT[iField].GetFieldType() != ELEMENT_TYPE_VALUETYPE) - { - // non valuetypes are uninteresting for this check - continue; - } - - TypeHandle thField = pStartFieldMT[iField].GetApproxFieldTypeHandleThrowing(); - // The field type is known to be a MethodTable as the GetFieldType call above returned ELEMENT_TYPE_VALUETYPE - MethodTable* pMTField = thField.AsMethodTable(); - if (pMTField->GetClass()->HasLayoutDependsOnOtherModules() || pMTField->GetModule() != pMT->GetModule()) - { - // The layout of this field depends on other modules. Check to see if the field type is the same - // as in the open type, if it isn't, this variation is caused by the valuetype instantiation - TypeHandle thTypicalField = pStartFieldMTTypical[iField].GetApproxFieldTypeHandleThrowing(); - if (thField != thTypicalField) - { - return true; - } - } + return module1->GetCompositeNativeImage() == module2->GetCompositeNativeImage(); } return false; @@ -11331,37 +11252,18 @@ VOID MethodTableBuilder::CheckLayoutDependsOnOtherModules(MethodTable * pDepende // // WARNING: Changes in this algorithm are potential ReadyToRun breaking changes !!! // - // Track whether field layout of this type depend on information outside its containing module and version bubble + // Track whether field layout of this type depend on information outside its containing module and compilation unit // // It is a stronger condition than MethodTable::IsInheritanceChainLayoutFixedInCurrentVersionBubble(). // It has to remain fixed accross versioning changes in the module dependencies. In particular, it does // not take into account NonVersionable attribute. Otherwise, adding NonVersionable attribute to existing // type would be ReadyToRun incompatible change. // - bool dependencyDefinedInOtherModule = (pDependencyMT->GetModule() != GetModule()); - bool dependsOnOtherModules = dependencyDefinedInOtherModule || pDependencyMT->GetClass()->HasLayoutDependsOnOtherModules(); - - // If the dependency itself has dependency outside of its version bubble, this type will clearly also have a dependency - // outside of its version bubble. - bool dependsOnOtherVersionBubbles = pDependencyMT->GetClass()->HasLayoutDependsOnOtherVersionBubbles(); - if (!dependsOnOtherVersionBubbles) - { - // Now check to see if the dependency itself is defined within the version bubble. - // First, if the dependency was defined in the same module as this type, then we know it matches - // version bubbles. - if (dependencyDefinedInOtherModule) - { - // But if it doesn't, then check to see if the module that defined the dependency is - // in the same version bubble as this type. - dependsOnOtherVersionBubbles = !ModuleInMatchingVersionBubble(GetModule(), pDependencyMT->GetModule()); - } - } + bool modulesDefinedInSameDistrubutionUnit = ModulesAreDistributedAsAnIndivisibleUnit(pDependencyMT->GetModule(), GetModule()); + bool dependsOnOtherModules = modulesDefinedInSameDistrubutionUnit || pDependencyMT->GetClass()->HasLayoutDependsOnOtherModules(); if (dependsOnOtherModules) GetHalfBakedClass()->SetHasLayoutDependsOnOtherModules(); - - if (dependsOnOtherVersionBubbles) - GetHalfBakedClass()->SetHasLayoutDependsOnOtherVersionBubbles(); } BOOL MethodTableBuilder::NeedsAlignedBaseOffset() @@ -11383,12 +11285,21 @@ BOOL MethodTableBuilder::NeedsAlignedBaseOffset() if (pParentMT == NULL || pParentMT == g_pObjectClass) return FALSE; + // Always use the ReadyToRun field layout algorithm if the source IL image was ReadyToRun, independent on + // whether ReadyToRun is actually enabled for the module. It is required to allow mixing and matching + // ReadyToRun images with and without input bubble enabled. + if (!GetModule()->GetFile()->IsILImageReadyToRun()) + { + // Always use ReadyToRun field layout algorithm to produce ReadyToRun images + if (!IsReadyToRunCompilation()) + return FALSE; + } + bool needsAlign = false; - if (!ModuleInMatchingVersionBubble(GetModule(), pParentMT->GetModule()) || - pParentMT->GetClass()->HasLayoutDependsOnOtherVersionBubbles() || - LayoutDependsOnTypeVariableInstantiationWhichDependsOnOtherModules(pParentMT)) + if (!ModulesAreDistributedAsAnIndivisibleUnit(GetModule(), pParentMT->GetModule()) || + pParentMT->GetClass()->HasLayoutDependsOnOtherModules()) { - GetHalfBakedClass()->SetHasLayoutDependsOnOtherVersionBubbles(); + GetHalfBakedClass()->SetHasLayoutDependsOnOtherModules(); return TRUE; } From 5a856dd44398247be10254253bd3d6f1a56d70af Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Tue, 28 Apr 2020 22:02:35 -0700 Subject: [PATCH 12/14] Fix the tests to match the requirement that all dependencies of an inputbubble compiled assembly must be r2r compiled Fix R2RDump for composite images --- .../ReadyToRunCompilationModuleGroupBase.cs | 7 +- .../ReadyToRunReader.cs | 2 +- src/coreclr/src/vm/methodtablebuilder.cpp | 4 +- .../src/readytorun/crossboundarylayout/a/a.cs | 5 + .../buildcrossgen2image.cmd | 16 +- .../crossboundarytests.cmd | 249 ++++++++++-------- 6 files changed, 161 insertions(+), 122 deletions(-) diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs index 0c4cdc2bfdf2f5..39930841ec6b28 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs @@ -154,6 +154,7 @@ public void UnionWith(ReadyToRunCompilationModuleGroupBase compilationGroup, Com if (other.HasMultipleInexactCompilationUnits) { + _bits[0] = true; _bits[1] = true; return; } @@ -185,12 +186,12 @@ public void UnionWith(ReadyToRunCompilationModuleGroupBase compilationGroup, Com compilationUnitCount++; } - if (inexactCompilationUnitCount == 2) + if (compilationUnitCount == 2) { // Multiple compilation units found _bits[1] = true; } - if (inexactCompilationUnitCount > 1) + if (inexactCompilationUnitCount == 2) { // Multiple inexact compilation units involved _bits[0] = true; @@ -216,7 +217,7 @@ private CompilationUnitSet TypeLayoutCompilationUnitsUncached(TypeDesc type) CompilationUnitSet moduleDependencySet = new CompilationUnitSet(this, defType.Module); - if ((type.BaseType != null) && !type.BaseType.IsObject) + if ((type.BaseType != null) && !type.BaseType.IsObject && !type.IsValueType) { moduleDependencySet.UnionWith(this, TypeLayoutCompilationUnits(type.BaseType)); } diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs index cbbab23daa975d..651c0cc36ac591 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.Reflection.ReadyToRun/ReadyToRunReader.cs @@ -729,7 +729,7 @@ private void ParseInstanceMethodEntrypoints(bool[] isEntryPoint) if ((methodFlags & (uint)ReadyToRunMethodSigFlags.READYTORUN_METHOD_SIG_OwnerType) != 0) { mdReader = decoder.GetMetadataReaderFromModuleOverride() ?? mdReader; - if (_composite) + if ((_composite) && mdReader == null) { // The only types that don't have module overrides on them in composite images are primitive types within the system module mdReader = GetSystemModuleMetadataReader(); diff --git a/src/coreclr/src/vm/methodtablebuilder.cpp b/src/coreclr/src/vm/methodtablebuilder.cpp index 32fc2fd89a1deb..ef393c0ae1a5f3 100644 --- a/src/coreclr/src/vm/methodtablebuilder.cpp +++ b/src/coreclr/src/vm/methodtablebuilder.cpp @@ -11259,8 +11259,8 @@ VOID MethodTableBuilder::CheckLayoutDependsOnOtherModules(MethodTable * pDepende // not take into account NonVersionable attribute. Otherwise, adding NonVersionable attribute to existing // type would be ReadyToRun incompatible change. // - bool modulesDefinedInSameDistrubutionUnit = ModulesAreDistributedAsAnIndivisibleUnit(pDependencyMT->GetModule(), GetModule()); - bool dependsOnOtherModules = modulesDefinedInSameDistrubutionUnit || pDependencyMT->GetClass()->HasLayoutDependsOnOtherModules(); + bool modulesDefinedInSameDistributionUnit = ModulesAreDistributedAsAnIndivisibleUnit(pDependencyMT->GetModule(), GetModule()); + bool dependsOnOtherModules = !modulesDefinedInSameDistributionUnit || pDependencyMT->GetClass()->HasLayoutDependsOnOtherModules(); if (dependsOnOtherModules) GetHalfBakedClass()->SetHasLayoutDependsOnOtherModules(); diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs b/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs index 271a8f6e15ee21..e8c3195507c001 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs @@ -30,6 +30,11 @@ public static void ReportTestFailure(string test, object o, ref int failCount) Console.WriteLine(test); s_testFailObj = o; failCount++; + while (true) + { + Thread.Sleep(1000); + s_testFailObj = o; + } } public static int Test() diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd b/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd index f392d825a8ed64..e75f4808a4d9e1 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/buildcrossgen2image.cmd @@ -28,9 +28,14 @@ if "%5"=="CG2Single" ( call :CG2SingleBubbleADOnly shift ) ELSE ( - if "%5"=="CG2Composite" ( + if "%5"=="CG2NoMethods" ( + call :CG2NoMethods shift - call :Continue + ) ELSE ( + if "%5"=="CG2Composite" ( + shift + call :Continue + ) ) ) ) @@ -56,6 +61,13 @@ echo %BUILDCMD% > %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log call %BUILDCMD% >> %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log 2>&1 goto done +:CG2NoMethods +del %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll +set BUILDCMD=%TESTBATCHROOT%\..\..\..\..\..\..\.dotnet\dotnet %CORE_ROOT%\crossgen2\crossgen2.dll --compile-no-methods -r %CORE_ROOT%\* -r %TESTINITIALBINPATH%\*.dll -o %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll %TESTINITIALBINPATH%\%COMPOSITENAME%.dll +echo %BUILDCMD% > %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log +call %BUILDCMD% >> %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll.log 2>&1 +goto done + :CG2SingleInputBubble del %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll set BUILDCMD=%TESTBATCHROOT%\..\..\..\..\..\..\.dotnet\dotnet %CORE_ROOT%\crossgen2\crossgen2.dll -r %CORE_ROOT%\* -r %TESTINITIALBINPATH%\*.dll -o %TESTINITIALBINPATH%\%TESTTARGET_DIR%\%COMPOSITENAME%.dll --inputbubble %TESTINITIALBINPATH%\%COMPOSITENAME%.dll diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd index 9a42e69026fb33..f634952a02a7f3 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/crossboundarytests.cmd @@ -3,9 +3,6 @@ setlocal set TESTDIR=%~dp0\..\..\..\..\..\..\artifacts\tests\coreclr\Windows_NT.x64.Debug\readytorun\crossboundarylayout\crossboundarytest\crossboundarytest set TESTBATCHROOT=%~dp0 -rem call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% compositeA1B2C2D2E1 a e CG2Composite b crossboundarytest d CG2Composite -rem goto done - call :testSpecificCompositeScenarios call :testAllCombinationsOfCompositeAndR2R call :testCG2SingleInputBubbleCompiledWithoutReferenceToBCE @@ -143,36 +140,36 @@ goto done :testCG2SingleInputBubbleAll echo TEST All combinations of the 5 dlls compiled with Crossgen2 with input bubble enabled and all assemblies passed as reference inputs to crossgen2 -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A____ a CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__B___ b CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_AB___ a CG2SingleInputBubble b CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble___C__ crossboundarytest CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A_C__ a CG2SingleInputBubble crossboundarytest CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__BC__ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_ABC__ a CG2SingleInputBubble b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A____ a CG2SingleInputBubble d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__B___ b CG2SingleInputBubble a CG2NoMethods d CG2NoMethods e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_AB___ a CG2SingleInputBubble b CG2SingleInputBubble d CG2NoMethods e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble___C__ crossboundarytest CG2SingleInputBubble a CG2NoMethods d CG2NoMethods b CG2NoMethods e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A_C__ a CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2NoMethods b CG2NoMethods e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__BC__ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble a CG2NoMethods d CG2NoMethods e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_ABC__ a CG2SingleInputBubble b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2NoMethods call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble____D_ d CG2SingleInputBubble call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A__D_ a CG2SingleInputBubble d CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__B_D_ b CG2SingleInputBubble d CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_AB_D_ a CG2SingleInputBubble b CG2SingleInputBubble d CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble___CD_ crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A_CD_ a CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__BCD_ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_ABCD_ a CG2SingleInputBubble b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__B_D_ b CG2SingleInputBubble d CG2SingleInputBubble a CG2NoMethods e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_AB_D_ a CG2SingleInputBubble b CG2SingleInputBubble d CG2SingleInputBubble e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble___CD_ crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble a CG2NoMethods b CG2NoMethods e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A_CD_ a CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble b CG2NoMethods e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__BCD_ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble a CG2NoMethods e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_ABCD_ a CG2SingleInputBubble b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble e CG2NoMethods call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_____E e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A___E a CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__B__E b CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_AB__E a CG2SingleInputBubble b CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble___C_E crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A_C_E a CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__BC_E b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_ABC_E a CG2SingleInputBubble b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A___E a CG2SingleInputBubble e CG2SingleInputBubble d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__B__E b CG2SingleInputBubble e CG2SingleInputBubble a CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_AB__E a CG2SingleInputBubble b CG2SingleInputBubble e CG2SingleInputBubble d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble___C_E crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble a CG2NoMethods b CG2NoMethods d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A_C_E a CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble d CG2NoMethods b CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__BC_E b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble a CG2NoMethods d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_ABC_E a CG2SingleInputBubble b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble d CG2NoMethods call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble____DE d CG2SingleInputBubble e CG2SingleInputBubble call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A__DE a CG2SingleInputBubble d CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__B_DE b CG2SingleInputBubble d CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__B_DE b CG2SingleInputBubble d CG2SingleInputBubble e CG2SingleInputBubble a CG2NoMethods call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_AB_DE a CG2SingleInputBubble b CG2SingleInputBubble d CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble___CDE crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A_CDE a CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__BCDE b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble___CDE crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble e CG2SingleInputBubble a CG2NoMethods b CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_A_CDE a CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble e CG2SingleInputBubble b CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble__BCDE b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble e CG2SingleInputBubble a CG2NoMethods call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble_ABCDE a CG2SingleInputBubble b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleInputBubble e CG2SingleInputBubble goto done @@ -183,36 +180,36 @@ echo reference inputs to crossgen2 when compiled b, crossboundarytest and e. a, echo set limited to a and d. This simulates a the model of two different sets of input bubble matched assemblies where there is a echo root set such as the runtime repo worth of libraries, and a seperately compiled application set. -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A____ a CG2SingleBubbleADOnly -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__B___ b CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_AB___ a CG2SingleBubbleADOnly b CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2___C__ crossboundarytest CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A_C__ a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__BC__ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_ABC__ a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A____ a CG2SingleBubbleADOnly d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__B___ b CG2SingleInputBubble a CG2NoMethods d CG2NoMethods e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_AB___ a CG2SingleBubbleADOnly b CG2SingleInputBubble d CG2NoMethods e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2___C__ crossboundarytest CG2SingleInputBubble a CG2NoMethods d CG2NoMethods b CG2NoMethods e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A_C__ a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble d CG2NoMethods b CG2NoMethods e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__BC__ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble a CG2NoMethods d CG2NoMethods e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_ABC__ a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2NoMethods call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2____D_ d CG2SingleInputBubble call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A__D_ a CG2SingleBubbleADOnly d CG2SingleBubbleADOnly -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__B_D_ b CG2SingleInputBubble d CG2SingleBubbleADOnly -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_AB_D_ a CG2SingleBubbleADOnly b CG2SingleInputBubble d CG2SingleBubbleADOnly -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2___CD_ crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A_CD_ a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__BCD_ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_ABCD_ a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__B_D_ b CG2SingleInputBubble d CG2SingleBubbleADOnly a CG2NoMethods e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_AB_D_ a CG2SingleBubbleADOnly b CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2___CD_ crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly a CG2NoMethods b CG2NoMethods e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A_CD_ a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly b CG2NoMethods e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__BCD_ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly a CG2NoMethods e CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_ABCD_ a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2NoMethods call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_____E e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A___E a CG2SingleBubbleADOnly e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__B__E b CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_AB__E a CG2SingleBubbleADOnly b CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2___C_E crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A_C_E a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__BC_E b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_ABC_E a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A___E a CG2SingleBubbleADOnly e CG2SingleInputBubble d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__B__E b CG2SingleInputBubble e CG2SingleInputBubble a CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_AB__E a CG2SingleBubbleADOnly b CG2SingleInputBubble e CG2SingleInputBubble d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2___C_E crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble a CG2NoMethods b CG2NoMethods d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A_C_E a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble b CG2NoMethods d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__BC_E b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_ABC_E a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble d CG2NoMethods call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2____DE d CG2SingleBubbleADOnly e CG2SingleInputBubble call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A__DE a CG2SingleBubbleADOnly d CG2SingleBubbleADOnly e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__B_DE b CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__B_DE b CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble a CG2NoMethods call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_AB_DE a CG2SingleBubbleADOnly b CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2___CDE crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A_CDE a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__BCDE b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2___CDE crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble a CG2NoMethods b CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_A_CDE a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble b CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2__BCDE b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble a CG2NoMethods call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble2_ABCDE a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble goto done @@ -223,79 +220,103 @@ echo for the more derived set of assemblies. b, crossboundarytest, and e are com echo a, and d are compiled with the reference echo set limited to a and d with input bubble enabled. This simulates a the model echo of a framework that ships with input bubble enabled, and the application with standard R2R rules. -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A____ a CG2SingleBubbleADOnly -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__B___ b CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_AB___ a CG2SingleBubbleADOnly b CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3___C__ crossboundarytest CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A_C__ a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__BC__ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_ABC__ a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3____D_ d CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A____ a CG2SingleBubbleADOnly d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_AB___ a CG2SingleBubbleADOnly b CG2Single d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A_C__ a CG2SingleBubbleADOnly crossboundarytest CG2Single d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_ABC__ a CG2SingleBubbleADOnly b CG2Single crossboundarytest CG2Single d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3____D_ d CG2SingleBubbleADOnly call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A__D_ a CG2SingleBubbleADOnly d CG2SingleBubbleADOnly -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__B_D_ b CG2SingleInputBubble d CG2SingleBubbleADOnly -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_AB_D_ a CG2SingleBubbleADOnly b CG2SingleInputBubble d CG2SingleBubbleADOnly -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3___CD_ crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A_CD_ a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__BCD_ b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_ABCD_ a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_____E e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A___E a CG2SingleBubbleADOnly e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__B__E b CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_AB__E a CG2SingleBubbleADOnly b CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3___C_E crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A_C_E a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__BC_E b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_ABC_E a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3____DE d CG2SingleBubbleADOnly e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A__DE a CG2SingleBubbleADOnly d CG2SingleBubbleADOnly e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__B_DE b CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_AB_DE a CG2SingleBubbleADOnly b CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3___CDE crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A_CDE a CG2SingleBubbleADOnly crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__BCDE b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_ABCDE a CG2SingleBubbleADOnly b CG2SingleInputBubble crossboundarytest CG2SingleInputBubble d CG2SingleBubbleADOnly e CG2SingleInputBubble +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__B_D_ b CG2Single d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_AB_D_ a CG2SingleBubbleADOnly b CG2Single d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3___CD_ crossboundarytest CG2Single d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A_CD_ a CG2SingleBubbleADOnly crossboundarytest CG2Single d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__BCD_ b CG2Single crossboundarytest CG2Single d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_ABCD_ a CG2SingleBubbleADOnly b CG2Single crossboundarytest CG2Single d CG2SingleBubbleADOnly +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A___E a CG2SingleBubbleADOnly e CG2Single d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_AB__E a CG2SingleBubbleADOnly b CG2Single e CG2Single d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A_C_E a CG2SingleBubbleADOnly crossboundarytest CG2Single e CG2Single d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_ABC_E a CG2SingleBubbleADOnly b CG2Single crossboundarytest CG2Single e CG2Single d CG2NoMethods +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3____DE d CG2SingleBubbleADOnly e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A__DE a CG2SingleBubbleADOnly d CG2SingleBubbleADOnly e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__B_DE b CG2Single d CG2SingleBubbleADOnly e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_AB_DE a CG2SingleBubbleADOnly b CG2Single d CG2SingleBubbleADOnly e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3___CDE crossboundarytest CG2Single d CG2SingleBubbleADOnly e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_A_CDE a CG2SingleBubbleADOnly crossboundarytest CG2Single d CG2SingleBubbleADOnly e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3__BCDE b CG2Single crossboundarytest CG2Single d CG2SingleBubbleADOnly e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2bubble3_ABCDE a CG2SingleBubbleADOnly b CG2Single crossboundarytest CG2Single d CG2SingleBubbleADOnly e CG2Single goto done :testCG2All echo TEST All combinations of compiling standard R2R with the crossgen2 tool instad of crossgen1 -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A___ a CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A____ a CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2__B___ b CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_AB___ a CG2Single b CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2___C__ crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A_C__ a CG2Single crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2__BC__ b CG2Single crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_ABC__ a CG2Single b CG2Single crossboundarytest CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2____D_ d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A__D_ a CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2__B_D_ b CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_AB_D_ a CG2Single b CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2___CD_ crossboundarytest CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A_CD_ a CG2Single crossboundarytest CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2__BCD_ b CG2Single crossboundarytest CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_ABCD_ a CG2Single b CG2Single crossboundarytest CG2Single d CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_____E e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A___E a CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2__B__E b CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_AB__E a CG2Single b CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2___C_E crossboundarytest CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A_C_E a CG2Single crossboundarytest CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2__BC_E b CG2Single crossboundarytest CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_ABC_E a CG2Single b CG2Single crossboundarytest CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2____DE d CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A__DE a CG2Single d CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2__B_DE b CG2Single d CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_AB_DE a CG2Single b CG2Single d CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2___CDE crossboundarytest CG2Single d CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_A_CDE a CG2Single crossboundarytest CG2Single d CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2__BCDE b CG2Single crossboundarytest CG2Single d CG2Single e CG2Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg2_ABCDE a CG2Single b CG2Single crossboundarytest CG2Single d CG2Single e CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A____ a CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__B___ b CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_AB___ a CG2Single b CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1___C__ crossboundarytest CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A_C__ a CG2Single crossboundarytest CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__BC__ b CG2Single crossboundarytest CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_ABC__ a CG2Single b CG2Single crossboundarytest CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1____D_ d CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A__D_ a CG2Single d CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__B_D_ b CG2Single d CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_AB_D_ a CG2Single b CG2Single d CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1___CD_ crossboundarytest CG2Single d CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A_CD_ a CG2Single crossboundarytest CG2Single d CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__BCD_ b CG2Single crossboundarytest CG2Single d CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_ABCD_ a CG2Single b CG2Single crossboundarytest CG2Single d CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_____E e CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A___E a CG2Single e CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__B__E b CG2Single e CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_AB__E a CG2Single b CG2Single e CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1___C_E crossboundarytest CG2Single e CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A_C_E a CG2Single crossboundarytest CG2Single e CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__BC_E b CG2Single crossboundarytest CG2Single e CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_ABC_E a CG2Single b CG2Single crossboundarytest CG2Single e CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1____DE d CG2Single e CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A__DE a CG2Single d CG2Single e CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__B_DE b CG2Single d CG2Single e CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_AB_DE a CG2Single b CG2Single d CG2Single e CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1___CDE crossboundarytest CG2Single d CG2Single e CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A_CDE a CG2Single crossboundarytest CG2Single d CG2Single e CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__BCDE b CG2Single crossboundarytest CG2Single d CG2Single e CG2Single -call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_ABCDE a CG2Single b CG2Single crossboundarytest CG2Single d CG2Single e CG2Single +:testCG1All +echo TEST All combinations of compiling standard R2R with the crossgen tool instad of crossgen2 +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A____ a CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__B___ b CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_AB___ a CG1Single b CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1___C__ crossboundarytest CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A_C__ a CG1Single crossboundarytest CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__BC__ b CG1Single crossboundarytest CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_ABC__ a CG1Single b CG1Single crossboundarytest CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1____D_ d CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A__D_ a CG1Single d CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__B_D_ b CG1Single d CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_AB_D_ a CG1Single b CG1Single d CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1___CD_ crossboundarytest CG1Single d CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A_CD_ a CG1Single crossboundarytest CG1Single d CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__BCD_ b CG1Single crossboundarytest CG1Single d CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_ABCD_ a CG1Single b CG1Single crossboundarytest CG1Single d CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_____E e CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A___E a CG1Single e CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__B__E b CG1Single e CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_AB__E a CG1Single b CG1Single e CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1___C_E crossboundarytest CG1Single e CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A_C_E a CG1Single crossboundarytest CG1Single e CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__BC_E b CG1Single crossboundarytest CG1Single e CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_ABC_E a CG1Single b CG1Single crossboundarytest CG1Single e CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1____DE d CG1Single e CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A__DE a CG1Single d CG1Single e CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__B_DE b CG1Single d CG1Single e CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_AB_DE a CG1Single b CG1Single d CG1Single e CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1___CDE crossboundarytest CG1Single d CG1Single e CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_A_CDE a CG1Single crossboundarytest CG1Single d CG1Single e CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1__BCDE b CG1Single crossboundarytest CG1Single d CG1Single e CG1Single +call %TESTBATCHROOT%\runindividualtest.cmd %TESTBATCHROOT% %TESTDIR% cg1_ABCDE a CG1Single b CG1Single crossboundarytest CG1Single d CG1Single e CG1Single goto done :done - \ No newline at end of file From c61651bfcb9d19d7055c3ada91d0f14869058259 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Wed, 29 Apr 2020 11:35:46 -0700 Subject: [PATCH 13/14] Address code review feedback --- .../ReadyToRunCompilationModuleGroupBase.cs | 68 +++++++++++++------ .../crossgen2/Properties/Resources.resx | 2 +- src/coreclr/src/vm/methodtablebuilder.cpp | 2 - .../src/readytorun/crossboundarylayout/a/a.cs | 5 -- 4 files changed, 47 insertions(+), 30 deletions(-) diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs index 39930841ec6b28..d7317ff61c4335 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs @@ -25,8 +25,8 @@ public abstract class ReadyToRunCompilationModuleGroupBase : CompilationModuleGr private readonly ConcurrentDictionary _layoutCompilationUnits = new ConcurrentDictionary(); private readonly ConcurrentDictionary _versionsWithTypeCache = new ConcurrentDictionary(); private readonly ConcurrentDictionary _versionsWithMethodCache = new ConcurrentDictionary(); - private readonly Dictionary _moduleCompilationUnits = new Dictionary(); - private int _maxCompilationUnitsKnown = 3; + private readonly Dictionary _moduleCompilationUnits = new Dictionary(); + private CompilationUnitIndex _nextCompilationUnit = CompilationUnitIndex.FirstDynamicallyAssigned; public ReadyToRunCompilationModuleGroupBase( TypeSystemContext context, @@ -77,24 +77,40 @@ public CompilationUnitSet TypeLayoutCompilationUnits(TypeDesc type) return _layoutCompilationUnits.GetOrAdd(type, TypeLayoutCompilationUnitsUncached); } + private enum CompilationUnitIndex + { + RESERVEDForHasMultipleInexactCompilationUnits = 0, + RESERVEDForHasMultipleCompilationUnits = 1, + First = 2, + Current = 2, + OutsideOfVersionBubble = 3, + FirstDynamicallyAssigned = 4, + } + // Compilation Unit Index is the compilation unit of a given module. If the compilation unit // is unknown the module will be given an independent index from other modules, but // IsCompilationUnitIndexExact will return false for that index. All compilation unit indices - // are >= 2, to allow for 0 to be a sentinel value. - private int ModuleToCompilationUnitIndex(ModuleDesc nonEcmaModule) + // are >= 2, to allow for 0 and 1 to be sentinel values. + private CompilationUnitIndex ModuleToCompilationUnitIndex(ModuleDesc nonEcmaModule) { EcmaModule module = (EcmaModule)nonEcmaModule; if (IsModuleInCompilationGroup(module)) - return 2; + return CompilationUnitIndex.Current; if (!VersionsWithModule(module)) - return 3; + return CompilationUnitIndex.OutsideOfVersionBubble; + // Assemblies within the version bubble, but not compiled as part of this compilation unit are given + // unique seperate compilation units. The practical effect of this is that the compiler can assume that + // types which are entirely defined in one module can be laid out in an optimal fashion, but types + // which are laid out relying on multiple modules cannot have their type layout precisely known as + // it is unknown if the modules are bounding into a single composite image or into individual assemblies. lock (_moduleCompilationUnits) { - if (!_moduleCompilationUnits.TryGetValue(module, out int compilationUnit)) + if (!_moduleCompilationUnits.TryGetValue(module, out CompilationUnitIndex compilationUnit)) { - compilationUnit = ++_maxCompilationUnitsKnown; + compilationUnit = _nextCompilationUnit; + _nextCompilationUnit = (CompilationUnitIndex)(((int)_nextCompilationUnit) + 1); _moduleCompilationUnits.Add(module, compilationUnit); } @@ -102,10 +118,18 @@ private int ModuleToCompilationUnitIndex(ModuleDesc nonEcmaModule) } } - // Indicate - private bool IsCompilationUnitIndexExact(int compilationUnitIndex) + // Indicate whether or not the compiler can take a hard dependency on the meaning + // the compilation unit index. + private bool IsCompilationUnitIndexExact(CompilationUnitIndex compilationUnitIndex) { - if (compilationUnitIndex != 2) + // Currently the implementation is only allowed to assume 2 details. + // 1. That any assembly which is compiled with inputbubble set shall have its entire set of dependencies compiled as R2R + // 2. That any assembly which is compiled in the current process may be considered to be part of a single unit. + // + // At some point, the compiler could take new parameters to allow the compiler to know that assemblies not in the current compilation + // unit are to be compiled into composite images or into seperate binaries, and this helper function could return true for these other + // compilation unit shapes. + if (compilationUnitIndex != CompilationUnitIndex.Current) return false; else return true; @@ -117,9 +141,9 @@ public struct CompilationUnitSet public CompilationUnitSet(ReadyToRunCompilationModuleGroupBase compilationGroup, ModuleDesc module) { - int compilationIndex = compilationGroup.ModuleToCompilationUnitIndex(module); - _bits = new BitArray(compilationIndex + 1); - _bits.Set(compilationIndex, true); + CompilationUnitIndex compilationIndex = compilationGroup.ModuleToCompilationUnitIndex(module); + _bits = new BitArray(((int)compilationIndex) + 1); + _bits.Set((int)compilationIndex, true); } public bool HasMultipleInexactCompilationUnits @@ -129,7 +153,7 @@ public bool HasMultipleInexactCompilationUnits if (_bits == null) return false; - return _bits[0]; + return _bits[(int)CompilationUnitIndex.RESERVEDForHasMultipleInexactCompilationUnits]; } } @@ -140,7 +164,7 @@ public bool HasMultipleCompilationUnits if (_bits == null) return false; - return _bits[1]; + return _bits[(int)CompilationUnitIndex.RESERVEDForHasMultipleCompilationUnits]; } } @@ -154,8 +178,8 @@ public void UnionWith(ReadyToRunCompilationModuleGroupBase compilationGroup, Com if (other.HasMultipleInexactCompilationUnits) { - _bits[0] = true; - _bits[1] = true; + _bits[(int)CompilationUnitIndex.RESERVEDForHasMultipleCompilationUnits] = true; + _bits[(int)CompilationUnitIndex.RESERVEDForHasMultipleInexactCompilationUnits] = true; return; } @@ -177,11 +201,11 @@ public void UnionWith(ReadyToRunCompilationModuleGroupBase compilationGroup, Com int inexactCompilationUnitCount = 0; int compilationUnitCount = 0; - for (int i = 2; i < _bits.Length; i++) + for (int i = (int)CompilationUnitIndex.First; i < _bits.Length; i++) { if (_bits[i]) { - if (!compilationGroup.IsCompilationUnitIndexExact(i)) + if (!compilationGroup.IsCompilationUnitIndexExact((CompilationUnitIndex)i)) inexactCompilationUnitCount++; compilationUnitCount++; @@ -189,12 +213,12 @@ public void UnionWith(ReadyToRunCompilationModuleGroupBase compilationGroup, Com if (compilationUnitCount == 2) { // Multiple compilation units found - _bits[1] = true; + _bits[(int)CompilationUnitIndex.RESERVEDForHasMultipleCompilationUnits] = true; } if (inexactCompilationUnitCount == 2) { // Multiple inexact compilation units involved - _bits[0] = true; + _bits[(int)CompilationUnitIndex.RESERVEDForHasMultipleInexactCompilationUnits] = true; break; } } diff --git a/src/coreclr/src/tools/crossgen2/crossgen2/Properties/Resources.resx b/src/coreclr/src/tools/crossgen2/crossgen2/Properties/Resources.resx index 58c6319f28f863..3bd33829741079 100644 --- a/src/coreclr/src/tools/crossgen2/crossgen2/Properties/Resources.resx +++ b/src/coreclr/src/tools/crossgen2/crossgen2/Properties/Resources.resx @@ -139,7 +139,7 @@ True when the entire input forms a version bubble (default = per-assembly bubble) - True to not compile any methods into the R2R image (default = false) + True to skip compiling methods into the R2R image (default = false) Emit a composite R2R image comprising a number of input assemblies diff --git a/src/coreclr/src/vm/methodtablebuilder.cpp b/src/coreclr/src/vm/methodtablebuilder.cpp index ef393c0ae1a5f3..5f389b12865fce 100644 --- a/src/coreclr/src/vm/methodtablebuilder.cpp +++ b/src/coreclr/src/vm/methodtablebuilder.cpp @@ -11295,11 +11295,9 @@ BOOL MethodTableBuilder::NeedsAlignedBaseOffset() return FALSE; } - bool needsAlign = false; if (!ModulesAreDistributedAsAnIndivisibleUnit(GetModule(), pParentMT->GetModule()) || pParentMT->GetClass()->HasLayoutDependsOnOtherModules()) { - GetHalfBakedClass()->SetHasLayoutDependsOnOtherModules(); return TRUE; } diff --git a/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs b/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs index e8c3195507c001..271a8f6e15ee21 100644 --- a/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs +++ b/src/coreclr/tests/src/readytorun/crossboundarylayout/a/a.cs @@ -30,11 +30,6 @@ public static void ReportTestFailure(string test, object o, ref int failCount) Console.WriteLine(test); s_testFailObj = o; failCount++; - while (true) - { - Thread.Sleep(1000); - s_testFailObj = o; - } } public static int Test() From d1d01550f2a70e171f09df0ae3b3afdadea2b7a5 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Wed, 29 Apr 2020 13:09:10 -0700 Subject: [PATCH 14/14] Update src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs Co-Authored-By: Jan Vorlicek --- .../Compiler/ReadyToRunCompilationModuleGroupBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs index d7317ff61c4335..7524c5089523b5 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilationModuleGroupBase.cs @@ -118,7 +118,7 @@ private CompilationUnitIndex ModuleToCompilationUnitIndex(ModuleDesc nonEcmaModu } } - // Indicate whether or not the compiler can take a hard dependency on the meaning + // Indicate whether or not the compiler can take a hard dependency on the meaning of // the compilation unit index. private bool IsCompilationUnitIndexExact(CompilationUnitIndex compilationUnitIndex) {