From 882f81897ca39646045db80da4f1484a38c014f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Rylek?= Date: Wed, 10 Jun 2020 21:15:24 +0200 Subject: [PATCH] Crossgen2 ARM64 runs & initial cross-targeting support (#37331) This change introduces initial provisions for dynamically loading the native JIT based on the targeting OS and architecture; the change expects the potentially multiple versions of clrjit to coexist with Crossgen2 in the same folder, marked by a OS / arch suffix. Based on these prerequisites the change adds ARM64 jobs to the Crossgen2 pipeline. Thanks Tomas --- eng/Signing.props | 4 +- eng/pipelines/coreclr/crossgen2.yml | 4 ++ src/coreclr/build-test.cmd | 37 ++++++------- src/coreclr/build-test.sh | 6 ++- src/coreclr/crosscomponents.cmake | 1 + .../Common/JitInterface/JitConfigProvider.cs | 41 ++++++++++---- .../ReadyToRunCodegenCompilationBuilder.cs | 3 +- .../crossgen2/crossgen2/crossgen2.csproj | 54 +++++++++++++++---- src/coreclr/tests/issues.targets | 28 ++++++---- .../tests/src/CLRTest.CrossGen.targets | 4 +- .../Microsoft.NETCore.App.Crossgen2.pkgproj | 8 ++- 11 files changed, 131 insertions(+), 59 deletions(-) diff --git a/eng/Signing.props b/eng/Signing.props index d2bd5b84e50198..81179505a9e350 100644 --- a/eng/Signing.props +++ b/eng/Signing.props @@ -44,9 +44,11 @@ - + + + diff --git a/eng/pipelines/coreclr/crossgen2.yml b/eng/pipelines/coreclr/crossgen2.yml index e20ebb4152b999..6ecdb931150a26 100644 --- a/eng/pipelines/coreclr/crossgen2.yml +++ b/eng/pipelines/coreclr/crossgen2.yml @@ -22,8 +22,10 @@ jobs: buildConfig: checked platforms: - Linux_x64 + - Linux_arm64 - OSX_x64 - Windows_NT_x64 + - Windows_NT_arm64 - CoreClrTestBuildHost # Either OSX_x64 or Linux_x64 jobParameters: testGroup: innerloop @@ -45,8 +47,10 @@ jobs: buildConfig: checked platforms: - Linux_x64 + - Linux_arm64 - OSX_x64 - Windows_NT_x64 + - Windows_NT_arm64 jobParameters: testGroup: innerloop readyToRun: true diff --git a/src/coreclr/build-test.cmd b/src/coreclr/build-test.cmd index ceeca835dc7b6c..a3e16dcffac262 100644 --- a/src/coreclr/build-test.cmd +++ b/src/coreclr/build-test.cmd @@ -557,15 +557,11 @@ if defined __DoCrossgen ( if defined __DoCrossgen2 ( set __CrossgenArg="/p:Crossgen2=true" - if "%__BuildArch%" == "x64" ( - echo %__MsgPrefix%Running crossgen2 on framework assemblies in CORE_ROOT: %CORE_ROOT% - call :PrecompileFX - if ERRORLEVEL 1 ( - echo %__ErrMsgPrefix%%__MsgPrefix%Error: crossgen2 precompilation of framework assemblies failed - exit /b 1 - ) - ) else ( - echo "%__MsgPrefix%Crossgen2 only supported on x64, for now" + echo %__MsgPrefix%Running crossgen2 on framework assemblies in CORE_ROOT: %CORE_ROOT% + call :PrecompileFX + if ERRORLEVEL 1 ( + echo %__ErrMsgPrefix%%__MsgPrefix%Error: crossgen2 precompilation of framework assemblies failed + exit /b 1 ) ) @@ -642,10 +638,19 @@ set __FailedAssemblies= set __CompositeOutputDir=%CORE_ROOT%\composite.out set __CompositeResponseFile=%__CompositeOutputDir%\framework-r2r.dll.rsp +set __CrossgenDir=%__BinDir% +if /i "%__BuildArch%" == "arm" (set __CrossgenDir=!__CrossgenDir!\x86) +if /i "%__BuildArch%" == "arm64" (set __CrossgenDir=!__CrossgenDir!\x64) + +set __CrossgenExe="%__CrossgenDir%\crossgen.exe" +set __Crossgen2Dll="%__RepoRootDir%\dotnet.cmd" "%__CrossgenDir%\crossgen2\crossgen2.dll" + if defined __CompositeBuildMode ( mkdir !__CompositeOutputDir! + del /Q !__CompositeResponseFile! echo --composite>>!__CompositeResponseFile! echo -O>>!__CompositeResponseFile! + echo --targetarch:%__BuildArch%>>!__CompositeResponseFile! echo --out^:%__CompositeOutputDir%\framework-r2r.dll>>!__CompositeResponseFile! ) @@ -669,8 +674,7 @@ if defined __CompositeBuildMode ( ) if defined __CompositeBuildMode ( - set __CompositeCommandLine="%__RepoRootDir%\dotnet.cmd" - set __CompositeCommandLine=!__CompositeCommandLine! "%CORE_ROOT%\crossgen2\crossgen2.dll" + set __CompositeCommandLine=%__Crossgen2Dll% set __CompositeCommandLine=!__CompositeCommandLine! "@%__CompositeResponseFile%" echo Building composite R2R framework^: !__CompositeCommandLine! call !__CompositeCommandLine! @@ -691,15 +695,6 @@ REM Compile the managed assemblies in Core_ROOT before running the tests set AssemblyPath=%1 set AssemblyName=%2 -set __CrossgenExe="%__BinDir%\crossgen.exe" -if /i "%__BuildArch%" == "arm" ( set __CrossgenExe="%__BinDir%\x86\crossgen.exe" ) -if /i "%__BuildArch%" == "arm64" ( set __CrossgenExe="%__BinDir%\x64\crossgen.exe" ) -set __CrossgenExe=%__CrossgenExe% - -if defined __DoCrossgen2 ( - set __CrossgenExe="%__RepoRootDir%\dotnet.cmd" "%CORE_ROOT%\crossgen2\crossgen2.dll" -) - REM Intentionally avoid using the .dll extension to prevent REM subsequent compilations from picking it up as a reference set __CrossgenOutputFile="%CORE_ROOT%\temp.ni._dll" @@ -710,7 +705,7 @@ if defined __DoCrossgen ( echo !__CrossgenCmd! !__CrossgenCmd! ) else ( - set __CrossgenCmd=!__CrossgenExe! -r:"!CORE_ROOT!\System.*.dll" -r:"!CORE_ROOT!\Microsoft.*.dll" -r:"!CORE_ROOT!\mscorlib.dll" -r:"!CORE_ROOT!\netstandard.dll" -O --inputbubble --out:!__CrossgenOutputFile! !AssemblyPath! + set __CrossgenCmd=!__Crossgen2Dll! -r:"!CORE_ROOT!\System.*.dll" -r:"!CORE_ROOT!\Microsoft.*.dll" -r:"!CORE_ROOT!\mscorlib.dll" -r:"!CORE_ROOT!\netstandard.dll" -O --inputbubble --out:!__CrossgenOutputFile! !AssemblyPath! --targetarch %__BuildArch% echo !__CrossgenCmd! call !__CrossgenCmd! ) diff --git a/src/coreclr/build-test.sh b/src/coreclr/build-test.sh index 9ad2fde6224152..fb4fe83f43ff50 100755 --- a/src/coreclr/build-test.sh +++ b/src/coreclr/build-test.sh @@ -181,10 +181,11 @@ precompile_coreroot_fx() local totalPrecompiled=0 local failedToPrecompile=0 local compositeCommandLine="${__DotNetCli}" - compositeCommandLine+=" $__BinDir/crossgen2/crossgen2.dll" + compositeCommandLine+=" $__Crossgen2Dll" compositeCommandLine+=" --composite" compositeCommandLine+=" -O" compositeCommandLine+=" --out:$outputDir/framework-r2r.dll" + compositeCommandLine+=" --targetarch ${__BuildArch}" declare -a failedAssemblies filesToPrecompile=$(find -L "$overlayDir" -maxdepth 1 -iname Microsoft.\*.dll -o -iname System.\*.dll -o -iname netstandard.dll -o -iname mscorlib.dll -type f) @@ -206,7 +207,7 @@ precompile_coreroot_fx() fi if [[ "$__DoCrossgen2" != 0 ]]; then - commandLine="${__DotNetCli} $overlayDir/crossgen2/crossgen2.dll $crossgen2References -O --inputbubble --out $outputDir/$(basename $filename) $filename" + commandLine="${__DotNetCli} $__Crossgen2Dll $crossgen2References -O --inputbubble --out $outputDir/$(basename $filename) $filename --targetarch ${__BuildArch}" fi echo Precompiling "$filename" @@ -696,6 +697,7 @@ if [[ "$__CrossBuild" == 1 ]]; then fi __CrossgenCoreLibLog="$__LogsDir/CrossgenCoreLib_$__TargetOS.$BuildArch.$__BuildType.log" __CrossgenExe="$__CrossComponentBinDir/crossgen" +__Crossgen2Dll="$__CrossComponentBinDir/crossgen2/crossgen2.dll" # CI_SPECIFIC - On CI machines, $HOME may not be set. In such a case, create a subfolder and set the variable to it. # This is needed by CLI to function. diff --git a/src/coreclr/crosscomponents.cmake b/src/coreclr/crosscomponents.cmake index f8ea417471ca6e..5bb0b5bef5c738 100644 --- a/src/coreclr/crosscomponents.cmake +++ b/src/coreclr/crosscomponents.cmake @@ -8,6 +8,7 @@ if (CLR_CMAKE_HOST_OS STREQUAL CLR_CMAKE_TARGET_OS) set (CLR_CROSS_COMPONENTS_LIST crossgen clrjit + jitinterface ) endif() diff --git a/src/coreclr/src/tools/Common/JitInterface/JitConfigProvider.cs b/src/coreclr/src/tools/Common/JitInterface/JitConfigProvider.cs index 78fbd064bf7252..13044997af0041 100644 --- a/src/coreclr/src/tools/Common/JitInterface/JitConfigProvider.cs +++ b/src/coreclr/src/tools/Common/JitInterface/JitConfigProvider.cs @@ -8,6 +8,7 @@ using System.Runtime.InteropServices; using System.Threading; using ILCompiler; +using Internal.TypeSystem; using NumberStyles = System.Globalization.NumberStyles; namespace Internal.JitInterface @@ -29,7 +30,11 @@ public static JitConfigProvider Instance private Dictionary _config = new Dictionary(StringComparer.OrdinalIgnoreCase); private object _keepAlive; // Keeps callback delegates alive - public static void Initialize(IEnumerable jitFlags, IEnumerable> parameters, string jitPath = null) + public static void Initialize( + TargetDetails target, + IEnumerable jitFlags, + IEnumerable> parameters, + string jitPath = null) { var config = new JitConfigProvider(jitFlags, parameters); @@ -39,18 +44,22 @@ public static void Initialize(IEnumerable jitFlags, IEnumerable { - NativeLibrary.SetDllImportResolver(typeof(CorInfoImpl).Assembly, (libName, assembly, searchPath) => + IntPtr libHandle = IntPtr.Zero; + if (libName == CorInfoImpl.JitLibrary) { - IntPtr libHandle = IntPtr.Zero; - if (libName == CorInfoImpl.JitLibrary) + if (!string.IsNullOrEmpty(jitPath)) { - libHandle = NativeLibrary.Load(jitPath, assembly, searchPath); + libHandle = NativeLibrary.Load(jitPath); } - return libHandle; - }); - } + else + { + libHandle = NativeLibrary.Load("clrjit-" + GetTargetSpec(target), assembly, searchPath); + } + } + return libHandle; + }); #else Debug.Assert(jitPath == null); #endif @@ -122,6 +131,20 @@ public string GetStringConfigValue(string name) return String.Empty; } + private static string GetTargetSpec(TargetDetails target) + { + string targetOSComponent = (target.OperatingSystem == TargetOS.Windows ? "win" : "unix"); + string targetArchComponent = target.Architecture switch + { + TargetArchitecture.X86 => "x86", + TargetArchitecture.X64 => "x64", + TargetArchitecture.ARM => "arm", + TargetArchitecture.ARM64 => "arm64", + _ => throw new NotImplementedException(target.Architecture.ToString()) + }; + return targetOSComponent + '-' + targetArchComponent; + } + #region Unmanaged instance private unsafe IntPtr CreateUnmanagedInstance() 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 e2b69ed60661a8..d7ac45c9e37935 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs @@ -13,7 +13,6 @@ using Internal.IL; using Internal.JitInterface; using Internal.ReadyToRunConstants; -using Internal.TypeSystem; using Internal.TypeSystem.Ecma; namespace ILCompiler @@ -208,7 +207,7 @@ public override ICompilation ToCompilation() if (_ibcTuning) corJitFlags.Add(CorJitFlag.CORJIT_FLAG_BBINSTR); - JitConfigProvider.Initialize(corJitFlags, _ryujitOptions, _jitPath); + JitConfigProvider.Initialize(_context.Target, corJitFlags, _ryujitOptions, _jitPath); return new ReadyToRunCodegenCompilation( graph, diff --git a/src/coreclr/src/tools/crossgen2/crossgen2/crossgen2.csproj b/src/coreclr/src/tools/crossgen2/crossgen2/crossgen2.csproj index b3c21b883c576c..05051a5cd6e62e 100644 --- a/src/coreclr/src/tools/crossgen2/crossgen2/crossgen2.csproj +++ b/src/coreclr/src/tools/crossgen2/crossgen2/crossgen2.csproj @@ -40,30 +40,64 @@ - + + + x64 + + unix + win + $(TargetOSComponent)-$(TargetArchitecture) + lib - .so - .dylib - - - - .dll + + .dll + .so + .dylib + + $(LibraryNamePrefix)jitinterface$(LibraryNameExtension) - - + + + + $(BinDir)\$(CrossHostArch)\crossgen2 + + + + + + + + + + + + + + diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index 31ac86f26a9c58..dd27a6b49c51ea 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -913,29 +913,35 @@ https://github.com/dotnet/runtime/issues/32725 + + https://github.com/dotnet/runtime/issues/7597 + + + Not compatible with crossgen2 + https://github.com/dotnet/runtime/issues/615 - - https://github.com/dotnet/runtime/issues/32725 + + https://github.com/dotnet/runtime/issues/37579 - - https://github.com/dotnet/runtime/issues/32728 + + https://github.com/dotnet/runtime/issues/34316 + + + https://github.com/dotnet/runtime/issues/35724 - - Not compatible with crossgen2 + + https://github.com/dotnet/runtime/issues/32725 Not compatible with crossgen2 - - https://github.com/dotnet/runtime/issues/7597 - https://github.com/dotnet/runtime/issues/34905 - - https://github.com/dotnet/runtime/issues/35724 + + https://github.com/dotnet/runtime/issues/32728 diff --git a/src/coreclr/tests/src/CLRTest.CrossGen.targets b/src/coreclr/tests/src/CLRTest.CrossGen.targets index 0dcc732202f752..e5b1da870e4f20 100644 --- a/src/coreclr/tests/src/CLRTest.CrossGen.targets +++ b/src/coreclr/tests/src/CLRTest.CrossGen.targets @@ -106,7 +106,7 @@ if [ ! -z ${RunCrossGen2+x} ]%3B then echo -r:$CORE_ROOT/System.*.dll>>$__ResponseFile echo -r:$CORE_ROOT/Microsoft.*.dll>>$__ResponseFile echo -r:$CORE_ROOT/mscorlib.dll>>$__ResponseFile - echo --targetarch=x64>>$__ResponseFile + echo --targetarch:$(TargetArchitecture)>>$__ResponseFile echo -O>>$__ResponseFile echo "Response file: $__ResponseFile" @@ -204,7 +204,7 @@ if defined RunCrossGen2 ( ) echo -o:!__OutputFile!>>!__ResponseFile! - echo --targetarch:x64>>!__ResponseFile! + echo --targetarch:$(TargetArchitecture)>>!__ResponseFile! echo -O>>!__ResponseFile! echo -r:!CORE_ROOT!\System.*.dll>>!__ResponseFile! echo -r:!CORE_ROOT!\Microsoft.*.dll>>!__ResponseFile! diff --git a/src/installer/pkg/projects/netcoreapp/pkg/Microsoft.NETCore.App.Crossgen2.pkgproj b/src/installer/pkg/projects/netcoreapp/pkg/Microsoft.NETCore.App.Crossgen2.pkgproj index 7eacc16697c6eb..a6df67996ac404 100644 --- a/src/installer/pkg/projects/netcoreapp/pkg/Microsoft.NETCore.App.Crossgen2.pkgproj +++ b/src/installer/pkg/projects/netcoreapp/pkg/Microsoft.NETCore.App.Crossgen2.pkgproj @@ -42,14 +42,20 @@ + + unix + win + $(TargetOSComponent)-$(TargetArchitecture) + + - +