diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index 6e62f81bdbf34a..f51650f0b07195 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -2403,6 +2403,12 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult, } // ENCODE_NONE } + else if (TypeCannotUseBasePlusOffsetEncoding(pMT.BaseType as MetadataType)) + { + // ENCODE_CHECK_FIELD_OFFSET + AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); + // No-op other than generating the check field offset fixup + } else { PreventRecursiveFieldInlinesOutsideVersionBubble(field, callerMethod); @@ -2422,6 +2428,22 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult, } } + private bool TypeCannotUseBasePlusOffsetEncoding(MetadataType type) + { + if (type == null) + return true; + + // Types which are encoded with sequential or explicit layout do not support an aligned base offset, and so we just encode with the exact offset + // of the field, and if that offset is incorrect, the method cannot be used. + if (type.IsSequentialLayout || type.IsExplicitLayout) + return true; + else if (type.BaseType is MetadataType metadataType) + { + return TypeCannotUseBasePlusOffsetEncoding(metadataType); + } + return false; + } + private void getGSCookie(IntPtr* pCookieVal, IntPtr** ppCookieVal) { *pCookieVal = IntPtr.Zero; @@ -2547,6 +2569,13 @@ private bool pInvokeMarshalingRequired(CORINFO_METHOD_STRUCT_* handle, CORINFO_S return false; } + // If this method is in another versioning unit, then the compilation cannot inline the pinvoke (as we aren't currently + // able to construct a token correctly to refer to the pinvoke method. + if (!_compilation.CompilationModuleGroup.VersionsWithMethodBody(method)) + { + return true; + } + MethodIL stubIL = null; try { diff --git a/src/tests/readytorun/tests/main.cs b/src/tests/readytorun/tests/main.cs index 09313a7c3d0dbe..5a13733db28bdf 100644 --- a/src/tests/readytorun/tests/main.cs +++ b/src/tests/readytorun/tests/main.cs @@ -330,7 +330,7 @@ public MyLoadContext() : base(AssemblyLoadContext.GetLoadContext(Assembly.GetExe public void TestMultipleLoads() { - Assembly a = LoadFromAssemblyPath(Path.Combine(Directory.GetCurrentDirectory(), "test.ni.dll")); + Assembly a = LoadFromAssemblyPath(Path.Combine(Directory.GetCurrentDirectory(), "test.dll")); Assert.AreEqual(AssemblyLoadContext.GetLoadContext(a), this); } @@ -424,58 +424,88 @@ static void TestLoadR2RImageFromByteArray() static void RunAllTests() { + Console.WriteLine("TestVirtualMethodCalls"); TestVirtualMethodCalls(); + Console.WriteLine("TestMovedVirtualMethod"); TestMovedVirtualMethods(); + Console.WriteLine("TestConstrainedMethodCalls"); TestConstrainedMethodCalls(); + Console.WriteLine("TestConstrainedMethodCalls_Unsupported"); TestConstrainedMethodCalls_Unsupported(); + Console.WriteLine("TestInterop"); TestInterop(); + Console.WriteLine("TestStaticFields"); TestStaticFields(); + Console.WriteLine("TestPreInitializedArray"); TestPreInitializedArray(); + Console.WriteLine("TestMultiDimmArray"); TestMultiDimmArray(); + Console.WriteLine("TestGenericVirtualMethod"); TestGenericVirtualMethod(); + Console.WriteLine("TestMovedGenericVirtualMethod"); TestMovedGenericVirtualMethod(); + Console.WriteLine("TestGenericNonVirtualMethod"); TestGenericNonVirtualMethod(); + Console.WriteLine("TestGenericOverStruct"); TestGenericOverStruct(); + Console.WriteLine("TestInstanceFields"); TestInstanceFields(); + Console.WriteLine("TestInstanceFieldsWithLayout"); TestInstanceFieldsWithLayout(); + Console.WriteLine("TestInheritingFromGrowingBase"); TestInheritingFromGrowingBase(); + Console.WriteLine("TestGrowingStruct"); TestGrowingStruct(); + Console.WriteLine("TestChangingStruct"); TestChangingStruct(); + Console.WriteLine("TestChangingHFAStruct"); TestChangingHFAStruct(); + Console.WriteLine("TestGetType"); TestGetType(); + Console.WriteLine("TestMultipleLoads"); TestMultipleLoads(); + Console.WriteLine("TestFieldLayoutNGenMixAndMatch"); TestFieldLayoutNGenMixAndMatch(); + Console.WriteLine("TestStaticBaseCSE"); TestStaticBaseCSE(); + Console.WriteLine("TestIsInstCSE"); TestIsInstCSE(); + Console.WriteLine("TestCastClassCSE"); TestCastClassCSE(); + Console.WriteLine("TestRangeCheckElimination"); TestRangeCheckElimination(); + Console.WriteLine("TestOpenClosedDelegate"); TestOpenClosedDelegate(); + Console.WriteLine("GenericLdtokenFieldsTest"); GenericLdtokenFieldsTest(); + Console.WriteLine("RVAFieldTest"); RVAFieldTest(); - TestLoadR2RImageFromByteArray(); +// Disable for https://github.com/dotnet/runtime/issues/71507 +// Console.WriteLine("TestLoadR2RImageFromByteArray"); +// TestLoadR2RImageFromByteArray(); } static int Main() diff --git a/src/tests/readytorun/tests/mainv1.csproj b/src/tests/readytorun/tests/mainv1.csproj index 9e463a8d8aaa3d..ee71d03f3c1feb 100644 --- a/src/tests/readytorun/tests/mainv1.csproj +++ b/src/tests/readytorun/tests/mainv1.csproj @@ -24,50 +24,55 @@ set "COMPlus_GCStress=" set "COMPlus_HeapVerify=" set "COMPlus_ReadyToRun=" -DEL test.dll -if exist test.dll ( - echo FAILED to delete test.dll +md IL_DLLS +if not exist IL_DLLS\fieldgetter.dll ( + copy /y fieldgetter.dll IL_DLLS\fieldgetter.dll +) +if not exist IL_DLLS\fieldgetter.dll ( + echo FAILED to copy fieldgetter.dll to IL_DLLS exit /b 1 ) -COPY /Y ..\testv1\test\test.dll test.dll -if not exist test.dll ( - echo FAILED to copy test.dll +if not exist IL_DLLS\mainv1.dll ( + copy /y mainv1.dll IL_DLLS\mainv1.dll +) +if not exist IL_DLLS\mainv1.dll ( + echo FAILED to copy mainv1.dll to IL_DLLS exit /b 1 ) -%Core_Root%\CoreRun.exe %Core_Root%\crossgen2\crossgen2.dll -r:%Core_Root%\*.dll -r:%25CD% -o:test.ni.dll test.dll +%Core_Root%\CoreRun.exe %Core_Root%\crossgen2\crossgen2.dll --map -r:%Core_Root%\*.dll -r:%25CD%\IL_DLLS\fieldgetter.dll -r:%25CD%\IL_DLLS\mainv1.dll -o:test.dll ..\testv1\test\test.dll set CrossGenStatus=!ERRORLEVEL! IF NOT !CrossGenStatus!==0 ( ECHO Crossgen failed with exitcode - !CrossGenStatus! Exit /b 1 ) -if not exist test.ni.dll ( - echo FAILED to build test.ni.dll +if not exist test.map ( + echo FAILED to build test.dll exit /b 1 ) -%Core_Root%\CoreRun.exe %Core_Root%\crossgen2\crossgen2.dll -r:%Core_Root%\*.dll -r:%25CD% -o:fieldgetter.ni.dll fieldgetter.dll +%Core_Root%\CoreRun.exe %Core_Root%\crossgen2\crossgen2.dll --map -r:%Core_Root%\*.dll -r:%25CD%\IL_DLLS\mainv1.dll -r:..\testv1\test\test.dll -o:fieldgetter.dll IL_DLLS\fieldgetter.dll set CrossGenStatus=!ERRORLEVEL! IF NOT !CrossGenStatus!==0 ( ECHO Crossgen failed with exitcode - !CrossGenStatus! Exit /b 1 ) -if not exist fieldgetter.ni.dll ( - echo FAILED to build fieldgetter.ni.dll +if not exist fieldgetter.map ( + echo FAILED to build fieldgetter.dll exit /b 1 ) -%Core_Root%\CoreRun.exe %Core_Root%\crossgen2\crossgen2.dll -r:%Core_Root%\*.dll -r:%25CD% -o:mainv1.ni.dll mainv1.dll +%Core_Root%\CoreRun.exe %Core_Root%\crossgen2\crossgen2.dll --map -r:%Core_Root%\*.dll -r:%25CD%\IL_DLLS\fieldgetter.dll -r:..\testv1\test\test.dll -o:mainv1.dll IL_DLLS\mainv1.dll set CrossGenStatus=!ERRORLEVEL! IF NOT !CrossGenStatus!==0 ( ECHO Crossgen failed with exitcode - !CrossGenStatus! Exit /b 1 ) -if not exist mainv1.ni.dll ( - echo FAILED to build mainv1.ni.dll +if not exist mainv1.map ( + echo FAILED to build mainv1.dll exit /b 1 ) @@ -79,19 +84,29 @@ $(BashCLRTestPreCommands) # Suppress some COMPlus variables for the duration of Crossgen2 execution export -n COMPlus_GCName COMPlus_GCStress COMPlus_HeapVerify COMPlus_ReadyToRun -rm -f test.dll -if [ -f test.dll ] +mkdir IL_DLLS + +if [ ! -f IL_DLLS/fieldgetter.dll ] +then + cp fieldgetter.dll IL_DLLS/fieldgetter.dll +fi +if [ ! -f IL_DLLS/fieldgetter.dll ] then - echo Failed to delete test.dll + echo Failed to copy fieldgetter.dll to IL_DLLS exit 1 fi -cp ../testv1/test/test.dll test.dll -if [ ! -f test.dll ] + +if [ ! -f IL_DLLS/mainv1.dll ] +then + cp mainv1.dll IL_DLLS/mainv1.dll +fi +if [ ! -f IL_DLLS/mainv1.dll ] then - echo Failed to copy test.dll + echo Failed to copy mainv1.dll to IL_DLLS exit 1 fi -$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll -r:$CORE_ROOT/*.dll -r:`pwd` -o:test.ni.dll test.dll + +$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll --map -r:$CORE_ROOT/*.dll -r:IL_DLLS/fieldgetter.dll -r:IL_DLLS/mainv1.dll -o:test.dll ../testv1/test/test.dll __cgExitCode=$? if [ $__cgExitCode -ne 0 ] @@ -99,13 +114,13 @@ then echo Crossgen failed with exitcode: $__cgExitCode exit 1 fi -if [ ! -f test.ni.dll ] +if [ ! -f test.map ] then - echo Failed to build test.ni.dll + echo Failed to build test.dll exit 1 fi -$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll -r:$CORE_ROOT/*.dll -r:`pwd` -o:fieldgetter.ni.dll fieldgetter.dll +$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll --map -r:$CORE_ROOT/*.dll -r:../testv1/test/test.dll -r:IL_DLLS/mainv1.dll -o:fieldgetter.dll IL_DLLS/fieldgetter.dll __cgExitCode=$? if [ $__cgExitCode -ne 0 ] @@ -113,13 +128,13 @@ then echo Crossgen failed with exitcode: $__cgExitCode exit 1 fi -if [ ! -f fieldgetter.ni.dll ] +if [ ! -f fieldgetter.map ] then - echo Failed to build fieldgetter.ni.dll + echo Failed to build fieldgetter.dll exit 1 fi -$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll -r:$CORE_ROOT/*.dll -r:`pwd` -o:mainv1.ni.dll mainv1.dll +$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll --map -r:$CORE_ROOT/*.dll -r:../testv1/test/test.dll -r:IL_DLLS/fieldgetter.dll -o:mainv1.dll IL_DLLS/mainv1.dll __cgExitCode=$? if [ $__cgExitCode -ne 0 ] @@ -127,9 +142,9 @@ then echo Crossgen failed with exitcode: $__cgExitCode exit 1 fi -if [ ! -f mainv1.ni.dll ] +if [ ! -f mainv1.map ] then - echo Failed to build mainv1.ni.dll + echo Failed to build mainv1.dll exit 1 fi diff --git a/src/tests/readytorun/tests/mainv2.csproj b/src/tests/readytorun/tests/mainv2.csproj index e15b93a3d7fd91..d37f8aa6cba5d7 100644 --- a/src/tests/readytorun/tests/mainv2.csproj +++ b/src/tests/readytorun/tests/mainv2.csproj @@ -22,60 +22,56 @@ set "COMPlus_GCStress=" set "COMPlus_HeapVerify=" set "COMPlus_ReadyToRun=" -DEL test.dll -if exist test.dll ( - echo FAILED to delete test.dll +md IL_DLLS +if not exist IL_DLLS\fieldgetter.dll ( + copy /y fieldgetter.dll IL_DLLS\fieldgetter.dll +) +if not exist IL_DLLS\fieldgetter.dll ( + echo FAILED to copy fieldgetter.dll to IL_DLLS exit /b 1 ) -COPY /Y ..\testv1\test\test.dll test.dll -if not exist test.dll ( - echo FAILED to copy test.dll +if not exist IL_DLLS\mainv2.dll ( + copy /y mainv2.dll IL_DLLS\mainv2.dll +) +if not exist IL_DLLS\mainv2.dll ( + echo FAILED to copy mainv2.dll to IL_DLLS exit /b 1 ) -%Core_Root%\CoreRun.exe %Core_Root%\crossgen2\crossgen2.dll -r:%Core_Root%\*.dll -r:%25CD% -o:mainv2.ni.dll mainv2.dll +REM NOTE THAT THIS IS WHERE WE BUILD THE R2R IMAGE using V2 of test not V1 +%Core_Root%\CoreRun.exe %Core_Root%\crossgen2\crossgen2.dll --map -r:%Core_Root%\*.dll -r:%25CD%\IL_DLLS\fieldgetter.dll -r:%25CD%\IL_DLLS\mainv2.dll -o:test.dll ..\testv2\test\test.dll set CrossGenStatus=!ERRORLEVEL! IF NOT !CrossGenStatus!==0 ( ECHO Crossgen failed with exitcode - !CrossGenStatus! Exit /b 1 ) -if not exist mainv2.ni.dll ( - echo FAILED to build mainv2.ni.dll +if not exist test.map ( + echo FAILED to build test.dll exit /b 1 ) -%Core_Root%\CoreRun.exe %Core_Root%\crossgen2\crossgen2.dll -r:%Core_Root%\*.dll -r:%25CD% -o:fieldgetter.ni.dll fieldgetter.dll +%Core_Root%\CoreRun.exe %Core_Root%\crossgen2\crossgen2.dll --map -r:%Core_Root%\*.dll -r:%25CD%\IL_DLLS\mainv2.dll -r:..\testv1\test\test.dll -o:fieldgetter.dll IL_DLLS\fieldgetter.dll set CrossGenStatus=!ERRORLEVEL! IF NOT !CrossGenStatus!==0 ( ECHO Crossgen failed with exitcode - !CrossGenStatus! Exit /b 1 ) -if not exist fieldgetter.ni.dll ( - echo FAILED to build fieldgetter.ni.dll - exit /b 1 -) -DEL test.dll -if exist test.dll ( - echo FAILED to delete test.dll - exit /b 1 -) -COPY /Y ..\testv2\test\test.dll test.dll -if not exist test.dll ( - echo FAILED to copy test.dll +if not exist fieldgetter.map ( + echo FAILED to build fieldgetter.dll exit /b 1 ) -%Core_Root%\CoreRun.exe %Core_Root%\crossgen2\crossgen2.dll -r:%Core_Root%\*.dll -r:%25CD% -o:test.ni.dll test.dll +%Core_Root%\CoreRun.exe %Core_Root%\crossgen2\crossgen2.dll --map -r:%Core_Root%\*.dll -r:%25CD%\IL_DLLS\fieldgetter.dll -r:..\testv1\test\test.dll -o:mainv2.dll IL_DLLS\mainv2.dll set CrossGenStatus=!ERRORLEVEL! IF NOT !CrossGenStatus!==0 ( ECHO Crossgen failed with exitcode - !CrossGenStatus! Exit /b 1 ) -if not exist test.ni.dll ( - echo FAILED to build test.ni.dll +if not exist mainv2.map ( + echo FAILED to build mainv2.dll exit /b 1 ) @@ -87,34 +83,30 @@ $(BashCLRTestPreCommands) # Suppress some COMPlus variables for the duration of Crossgen2 execution export -n COMPlus_GCName COMPlus_GCStress COMPlus_HeapVerify COMPlus_ReadyToRun -rm -f test.dll -if [ -f test.dll ] +mkdir IL_DLLS + +if [ ! -f IL_DLLS/fieldgetter.dll ] then - echo Failed to delete test.dll - exit 1 + cp fieldgetter.dll IL_DLLS/fieldgetter.dll fi -cp ../testv1/test/test.dll test.dll -if [ ! -f test.dll ] +if [ ! -f IL_DLLS/fieldgetter.dll ] then - echo Failed to copy test.dll + echo Failed to copy fieldgetter.dll to IL_DLLS exit 1 fi -$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll -r:$CORE_ROOT/*.dll -r:`pwd` -o:mainv2.ni.dll mainv2.dll - -__cgExitCode=$? -if [ $__cgExitCode -ne 0 ] +if [ ! -f IL_DLLS/mainv2.dll ] then - echo Crossgen failed with exitcode: $__cgExitCode - exit 1 + cp mainv2.dll IL_DLLS/mainv2.dll fi -if [ ! -f mainv2.ni.dll ] +if [ ! -f IL_DLLS/mainv2.dll ] then - echo Failed to build mainv2.ni.dll + echo Failed to copy mainv2.dll to IL_DLLS exit 1 fi -$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll -r:$CORE_ROOT/*.dll -r:`pwd` -o:fieldgetter.ni.dll fieldgetter.dll +# NOTE THAT THIS IS WHERE WE BUILD THE R2R IMAGE using V2 of test not V1 +$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll --map -r:$CORE_ROOT/*.dll -r:IL_DLLS/fieldgetter.dll -r:IL_DLLS/mainv2.dll -o:test.dll ../testv2/test/test.dll __cgExitCode=$? if [ $__cgExitCode -ne 0 ] @@ -122,25 +114,27 @@ then echo Crossgen failed with exitcode: $__cgExitCode exit 1 fi -if [ ! -f fieldgetter.ni.dll ] +if [ ! -f test.map ] then - echo Failed to build fieldgetter.ni.dll + echo Failed to build test.dll exit 1 fi -rm -f test.dll -if [ -f test.dll ] + +$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll --map -r:$CORE_ROOT/*.dll -r:../testv1/test/test.dll -r:IL_DLLS/mainv2.dll -o:fieldgetter.dll IL_DLLS/fieldgetter.dll + +__cgExitCode=$? +if [ $__cgExitCode -ne 0 ] then - echo Failed to delete test.dll + echo Crossgen failed with exitcode: $__cgExitCode exit 1 fi -cp ../testv2/test/test.dll test.dll -if [ ! -f test.dll ] +if [ ! -f fieldgetter.map ] then - echo Failed to copy test.dll + echo Failed to build fieldgetter.dll exit 1 fi -$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll -r:$CORE_ROOT/*.dll -r:`pwd` -o:test.ni.dll test.dll +$CORE_ROOT/corerun $CORE_ROOT/crossgen2/crossgen2.dll --map -r:$CORE_ROOT/*.dll -r:../testv1/test/test.dll -r:IL_DLLS/fieldgetter.dll -o:mainv2.dll IL_DLLS/mainv2.dll __cgExitCode=$? if [ $__cgExitCode -ne 0 ] @@ -148,9 +142,9 @@ then echo Crossgen failed with exitcode: $__cgExitCode exit 1 fi -if [ ! -f test.ni.dll ] +if [ ! -f mainv2.map ] then - echo Failed to build test.ni.dll + echo Failed to build mainv2.dll exit 1 fi