From d9217e3865f9f1d5bddfbf74718871318237e9ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 19 Sep 2022 09:22:10 +0900 Subject: [PATCH 1/4] Add an option to not generate precise GC info Follow up to #75803. If enabled, conservative GC stack scanning will be used and metadata related to GC stack reporting will not be generated. The generated executable file will be smaller, but the GC will be less efficient (garbage collection might take longer and keep objects alive for longer periods of time than usual). Saves 4.4% in size on a Hello World. I'll take that. --- .../BuildIntegration/Microsoft.NETCore.Native.targets | 3 +++ src/coreclr/nativeaot/docs/optimizing.md | 1 + .../ILCompiler.Compiler/Compiler/CompilationBuilder.Aot.cs | 7 +++++++ .../Compiler/DependencyAnalysis/ObjectWriter.cs | 5 +++-- .../aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs | 4 ++++ .../ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs | 3 +++ src/coreclr/tools/aot/ILCompiler/Program.cs | 5 ++++- 7 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets index e78e9b01bfbd8..d0a66f431cefe 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets @@ -256,6 +256,9 @@ The .NET Foundation licenses this file to you under the MIT license. + + + diff --git a/src/coreclr/nativeaot/docs/optimizing.md b/src/coreclr/nativeaot/docs/optimizing.md index 2a404b793083c..27d6ce19eca3d 100644 --- a/src/coreclr/nativeaot/docs/optimizing.md +++ b/src/coreclr/nativeaot/docs/optimizing.md @@ -40,6 +40,7 @@ Since `PublishTrimmed` is implied to be true with Native AOT, some framework fea * `Speed`: when generating optimized code, favor code execution speed. * `Size`: when generating optimized code, favor smaller code size. * ``: By default, the compiler targets the minimum instruction set supported by the target OS and architecture. This option allows targeting newer instruction sets for better performance. The native binary will require the instruction sets to be supported by the hardware in order to run. For example, `avx2,bmi2,fma,pclmul,popcnt,aes` will produce binary that takes advantage of instruction sets that are typically present on current Intel and AMD processors. Run `ilc --help` for the full list of available instruction sets. `ilc` can be executed from the NativeAOT package in your local nuget cache e.g. `%USERPROFILE%\.nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\8.0.0-...\tools\ilc.exe` on Windows or `~/.nuget/packages/runtime.linux-arm64.microsoft.dotnet.ilcompiler/8.0.0-.../tools/ilc` on Linux. +* ``: if set to `true`, conservative GC stack scanning will be used and metadata related to GC stack reporting will not be generated. The generated executable file will be smaller, but the GC will be less efficient (garbage collection might take longer and keep objects alive for longer periods of time than usual). ## Special considerations for Linux/macOS diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilationBuilder.Aot.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilationBuilder.Aot.cs index bf1a053c0c612..599dc7e449f53 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilationBuilder.Aot.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/CompilationBuilder.Aot.cs @@ -23,6 +23,7 @@ public partial class CompilationBuilder protected InstructionSetSupport _instructionSetSupport; protected SecurityMitigationOptions _mitigationOptions; protected bool _useDwarf5; + protected bool _isPreciseGc = true; partial void InitializePartial() { @@ -108,6 +109,12 @@ public CompilationBuilder UseDwarf5(bool value) return this; } + public CompilationBuilder UseGCStackReporting(bool isPrecise) + { + _isPreciseGc = isPrecise; + return this; + } + protected PreinitializationManager GetPreinitializationManager() { if (_preinitializationManager == null) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectWriter.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectWriter.cs index fb1f38266fbb1..adb116ab66e3e 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectWriter.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectWriter.cs @@ -559,7 +559,7 @@ public void PublishUnwindInfo(ObjectNode node) ehInfo = null; } - if (gcInfo != null) + if (gcInfo != null && ((_options & ObjectWritingOptions.NoGcInfo) == 0)) { EmitBlob(gcInfo); gcInfo = null; @@ -645,7 +645,7 @@ public void BuildCFIMap(NodeFactory factory, ObjectNode node) ehInfo = null; } - if (gcInfo != null) + if (gcInfo != null && ((_options & ObjectWritingOptions.NoGcInfo) == 0)) { EmitBlob(gcInfo); gcInfo = null; @@ -1327,5 +1327,6 @@ public enum ObjectWritingOptions GenerateDebugInfo = 0x01, ControlFlowGuard = 0x02, UseDwarf5 = 0x4, + NoGcInfo = 0x8, } } diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs index a7615fc54fc87..0c5501727d870 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilation.cs @@ -100,6 +100,9 @@ protected override void CompileInternal(string outputFile, ObjectDumper dumper) if ((_compilationOptions & RyuJitCompilationOptions.ControlFlowGuardAnnotations) != 0) options |= ObjectWritingOptions.ControlFlowGuard; + if ((_compilationOptions & RyuJitCompilationOptions.NoPreciseGc) != 0) + options |= ObjectWritingOptions.NoGcInfo; + ObjectWriter.EmitObject(outputFile, nodes, NodeFactory, options, dumper, _logger); } @@ -244,5 +247,6 @@ public enum RyuJitCompilationOptions ControlFlowGuardAnnotations = 0x2, UseDwarf5 = 0x4, UseResilience = 0x8, + NoPreciseGc = 0x10, } } diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs index 3c20598ffb099..4faed03a4746d 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/Compiler/RyuJitCompilationBuilder.cs @@ -123,6 +123,9 @@ public override ICompilation ToCompilation() if (_resilient) options |= RyuJitCompilationOptions.UseResilience; + if (!_isPreciseGc) + options |= RyuJitCompilationOptions.NoPreciseGc; + var factory = new RyuJitNodeFactory(_context, _compilationGroup, _metadataManager, _interopStubManager, _nameMangler, _vtableSliceProvider, _dictionaryLayoutProvider, GetPreinitializationManager()); JitConfigProvider.Initialize(_context.Target, jitFlagBuilder.ToArray(), _ryujitOptions, _jitPath); diff --git a/src/coreclr/tools/aot/ILCompiler/Program.cs b/src/coreclr/tools/aot/ILCompiler/Program.cs index 7adb06231ed9a..51476c64a8fbb 100644 --- a/src/coreclr/tools/aot/ILCompiler/Program.cs +++ b/src/coreclr/tools/aot/ILCompiler/Program.cs @@ -62,6 +62,7 @@ internal sealed class Program private bool _completeTypesMetadata; private bool _scanReflection; private bool _methodBodyFolding; + private bool _noPreciseGc; private int _parallelism = Environment.ProcessorCount; private string _instructionSet; private string _guard; @@ -221,6 +222,7 @@ private ArgumentSyntax ParseCommandLine(string[] args) syntax.DefineOption("ildump", ref _ilDump, "Dump IL assembly listing for compiler-generated IL"); syntax.DefineOption("stacktracedata", ref _emitStackTraceData, "Emit data to support generating stack trace strings at runtime"); syntax.DefineOption("methodbodyfolding", ref _methodBodyFolding, "Fold identical method bodies"); + syntax.DefineOption("noprecisegc", ref _noPreciseGc, "Do not generate precise stack GC information"); syntax.DefineOptionList("initassembly", ref _initAssemblies, "Assembly(ies) with a library initializer"); syntax.DefineOptionList("appcontextswitch", ref _appContextSwitches, "System.AppContext switches to set (format: 'Key=Value')"); syntax.DefineOptionList("feature", ref _featureSwitches, "Feature switches to apply (format: 'Namespace.Name=[true|false]'"); @@ -943,7 +945,8 @@ void RunScanner() .UseOptimizationMode(_optimizationMode) .UseSecurityMitigationOptions(securityMitigationOptions) .UseDebugInfoProvider(debugInfoProvider) - .UseDwarf5(_useDwarf5); + .UseDwarf5(_useDwarf5) + .UseGCStackReporting(isPrecise: !_noPreciseGc); builder.UseResilience(_resilient); From ca825f80a69b8b2652902027893de2990889f9c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 19 Sep 2022 09:25:53 +0900 Subject: [PATCH 2/4] Temporarily enable for all tests --- eng/testing/tests.singlefile.targets | 2 ++ src/tests/nativeaot/Directory.Build.props | 7 +++++++ 2 files changed, 9 insertions(+) create mode 100644 src/tests/nativeaot/Directory.Build.props diff --git a/eng/testing/tests.singlefile.targets b/eng/testing/tests.singlefile.targets index d307e837e6235..ec8981f0d492a 100644 --- a/eng/testing/tests.singlefile.targets +++ b/eng/testing/tests.singlefile.targets @@ -1,5 +1,7 @@ + true + Exe $(DefineConstants);SINGLE_FILE_TEST_RUNNER diff --git a/src/tests/nativeaot/Directory.Build.props b/src/tests/nativeaot/Directory.Build.props new file mode 100644 index 0000000000000..435a402af343f --- /dev/null +++ b/src/tests/nativeaot/Directory.Build.props @@ -0,0 +1,7 @@ + + + + + true + + From 83b13bc5db198653d6637c65b3d32136d83eaee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 19 Sep 2022 09:27:51 +0900 Subject: [PATCH 3/4] Update optimizing.md --- src/coreclr/nativeaot/docs/optimizing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/nativeaot/docs/optimizing.md b/src/coreclr/nativeaot/docs/optimizing.md index 27d6ce19eca3d..24f993bc867dd 100644 --- a/src/coreclr/nativeaot/docs/optimizing.md +++ b/src/coreclr/nativeaot/docs/optimizing.md @@ -35,12 +35,12 @@ Since `PublishTrimmed` is implied to be true with Native AOT, some framework fea ## Options related to metadata generation * `false`: this disables generation of stack trace metadata that provides textual names in stack traces. This is for example the text string one gets by calling `Exception.ToString()` on a caught exception. With this option disabled, stack traces will still be generated, but will be based on reflection metadata alone (they might be less complete). +* ``: if set to `true`, conservative GC stack scanning will be used and metadata related to GC stack reporting will not be generated. The generated executable file will be smaller, but the GC will be less efficient (garbage collection might take longer and keep objects alive for longer periods of time than usual). ## Options related to code generation * `Speed`: when generating optimized code, favor code execution speed. * `Size`: when generating optimized code, favor smaller code size. * ``: By default, the compiler targets the minimum instruction set supported by the target OS and architecture. This option allows targeting newer instruction sets for better performance. The native binary will require the instruction sets to be supported by the hardware in order to run. For example, `avx2,bmi2,fma,pclmul,popcnt,aes` will produce binary that takes advantage of instruction sets that are typically present on current Intel and AMD processors. Run `ilc --help` for the full list of available instruction sets. `ilc` can be executed from the NativeAOT package in your local nuget cache e.g. `%USERPROFILE%\.nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\8.0.0-...\tools\ilc.exe` on Windows or `~/.nuget/packages/runtime.linux-arm64.microsoft.dotnet.ilcompiler/8.0.0-.../tools/ilc` on Linux. -* ``: if set to `true`, conservative GC stack scanning will be used and metadata related to GC stack reporting will not be generated. The generated executable file will be smaller, but the GC will be less efficient (garbage collection might take longer and keep objects alive for longer periods of time than usual). ## Special considerations for Linux/macOS From 246de00ead7f563365c46b96b34a404e9bd6ffeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 19 Sep 2022 10:09:49 +0900 Subject: [PATCH 4/4] Update Microsoft.NETCore.Native.targets --- .../BuildIntegration/Microsoft.NETCore.Native.targets | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets index d0a66f431cefe..5c8c90814ab3f 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets @@ -256,8 +256,8 @@ The .NET Foundation licenses this file to you under the MIT license. - - + +