点击上方 蓝字 江湖评谈 设为关注
前言
.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=1
Powershell: $env: DOTNET_USE_LLVM_OBJWRITER=1
Unix/Linux: export DOTNET_USE_LLVM_OBJWRITER=1
dotnet xxx.dll
先设置环境变量,然后通过dotnet命令行运行托管DLL即可复现之前的LLVM后端生成。以上是各个平台的设置。
往期精彩回顾