當前位置: 妍妍網 > 碼農

.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後端生成。以上是各個平台的設定。

往期精彩回顧