当前位置: 欣欣网 > 码农

.NET9 AOT ILC的重大变化

2024-03-19码农

点击上方 蓝字 江湖评谈 设为关注




前言

.NET9 AOT编译器ILC出现了重大更新,前一篇:
里面并没有介绍这个功能。其功能概括下,即是通过C#自举的代码取代了之前用LLVM后端生成的代码。本篇来看下。

详细

AOT编译分成两个阶段,其一是生成Obj目标文件,其二则是通过链接器链接目标文件生成可执行二进制文件。这里的目标文件和可执行二进制文件都是分别对于相应的平台,比如MacOS/Linux/Win等等平台。

第一步生成Obj目标文件,因为多平台生成。所以.NET9之前,微软采用了LLVM后端生成了目标文件。 因为LLVM后端近乎绝对的统治力,它有一百多个指令集级别的后端生成,所以采用LLVM更符合开源特征。

但这一情况到了.NET9发生了变化,.NET9里面微软首次引入了C#代码生成目标文件,取代了LLVM默认的生成。但是LLVM并没有删除,而是同时存在。

这部分代码可以参考:

publicstaticvoidEmitObject(string objectFilePath, IReadOnlyCollection<DependencyNode> nodes, NodeFactory factory, ObjectWritingOptions options, IObjectDumper dumper, Logger logger) {var stopwatch = new Stopwatch(); stopwatch.Start();if (Environment.GetEnvironmentVariable("DOTNET_USE_LLVM_OBJWRITER") == "1") { LegacyObjectWriter.EmitObject(objectFilePath, nodes, factory, options, dumper, logger); }else { ObjectWriter objectWriter = factory.Target.IsApplePlatform ? new MachObjectWriter(factory, options) : factory.Target.OperatingSystem == TargetOS.Windows ? new CoffObjectWriter(factory, options) :new ElfObjectWriter(factory, options); objectWriter.EmitObject(objectFilePath, nodes, dumper, logger); } stopwatch.Stop();if (logger.IsVerbose) logger.LogMessage($"Done writing object file in {stopwatch.Elapsed}"); }

如果你不作任何设置,.NET9默认的目标文件生成即是C#自举的代码。但是你如果习惯了LLVM的生成,也可以通过设置环境变量来开启之前的LLVM后端。具体如下:

CMD: set DOTNET_USE_LLVM_OBJWRITER=1Powershell: $env: DOTNET_USE_LLVM_OBJWRITER=1Unix/Linux: export DOTNET_USE_LLVM_OBJWRITER=1dotnet xxx.dll

先设置环境变量,然后通过dotnet命令行运行托管DLL即可复现之前的LLVM后端生成。以上是各个平台的设置。

往期精彩回顾