成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

.Net8的AOT是如何被C++操控運行的

開發 前端
C++和AOT無論是Roslyn,或者ILC或者引導程序BootStrap都是通過C++來啟動運行的。1.Roslyn的運行實質上是運行在虛擬機CLR上面的2.ILC同上3.BootStrap它本身就是cpp項目而llvm本身就是一套超級底層的C/C++項目,可以看到在一整套的AOT編譯運行流程中,C++始終操控C#的運行。

前言

.Net目前有兩條線,一條是正宗的.Net虛擬機CLR調用JIT的即時編譯,另外一條就是通過ILC編譯成本地的機器碼也即是AOT。上一篇【C++是如何運行C#/.Net的?】說的是前者,本篇來看下后者。

概括

前情提要:本篇以最新的.Net8 PreView5為藍本,進行的描述。

1.不同簡要比較

AOT相當于一個全新的縮減.Net版本,它和即時編譯器也即JIT機器碼照樣不同,這里舉一個例子,比如以下代碼:

static void Main(string[] args)
{
    Program pm = new Program();
}

簡單的一個對象實例化,即時編譯里面:

call        JIT_TrialAllocSFastMP_InlineGetThread (07FFC4C650650h)  
 mov         qword ptr [rbp+20h],rax  
 mov         rcx,qword ptr [rbp+20h]  
 call        Program..ctor() (07FFBECC2C078h)

可以看到它先分配內存,然后調用默認的構造函數.ctor

那么AOT呢?

00007FF72AD459E8 48 8D 0D E1 55 17 00 lea         rcx,[repro_Program::`vftable' (07FF72AEBAFD0h)]  
00007FF72AD459EF E8 9C 0A C9 FF       call        RhpNewFast (07FF72A9D6490h)

它這里很明顯用了虛函數表指針作為參數,調用了RhpNewFast。完全是不一樣的。

2.整體過程AOT的編譯如下:C#源碼-》Roslyn(DLL)->ILC(Obj)->Link(Exe)寫好了C#源代碼之后,Roslyn會接管C#源代碼把它編譯成中間語言MSIL,存放在托管的動態鏈接庫即DLL里面。ILC會接管托管的DLL把它生成目標文件.Obj,然后用NativeAot的引導程序也即Bootstrap引導Link.exe工具鏈接.Obj目標文件生成可執行文件。

3.細節生成的目標文件也即Obj依舊是通過開源界三大編譯器之一的LLVM來生成的.在Windows/Linux/MaoOS上的動態鏈接庫分別是:

objwriter.dll(pe)/libobjwriter.so(elf)/libobjwriter.dylib(Mach-O)

他們分別封裝了各個平臺的llvm后端代碼生成來完成了Obj目標文件的生成。

4.C++和AOT無論是Roslyn,或者ILC或者引導程序BootStrap都是通過C++來啟動運行的。1.Roslyn的運行實質上是運行在虛擬機CLR上面的2.ILC同上3.BootStrap它本身就是cpp項目而llvm本身就是一套超級底層的C/C++項目,可以看到在一整套的AOT編譯運行流程中,C++始終操控C#的運行。

5.核心代碼

為了更為透徹的了解到ILC調用Objwriter.dll動態鏈接庫操控llvm生成obj目標文件。在WinX64平臺上,這里演示一段簡單的代碼,步驟如下:

一.首先在nuget上面下載一個ILC編譯器,也即是:

runtime.win-x64.Microsoft.DotNet.ILCompiler

二.找到nuget目錄,里面有個objwriter.dll一般的在如下路徑:

C:\Users\Administrator\.nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\7.0.8\tools

三.新建一個C#控制臺項目名字Obj,把上面的路徑找到的objwriter.dll放入到

Obj項目bin/Debug/net7.0目錄下面。

四.Obj項目bin/Debug/net7.0目錄下面新建一個Demo.obj目標文件

五.Program.cs里面填寫如下代碼:

internal class Program
{
    [DllImport("objwriter.dll")]
    private static extern IntPtr InitObjWriter([MarshalAs(UnmanagedType.LPUTF8Str)] string objectFilePath, string triple = null);


    [DllImport("objwriter.dll")]
    private static extern void FinishObjWriter(IntPtr objWriter);


    [DllImport("objwriter.dll")]
    private static extern void EmitIntValue(IntPtr objWriter, ulong value, int size);


    private IntPtr _nativeObjectWriter = IntPtr.Zero;


    static void Main(string[] args)
    {
            IntPtr objectWriter = InitObjWriter("Demo.obj", "x86_64-pc-win32-windows");
            EmitIntValue(objectWriter, 0x10, 4);
            FinishObjWriter(objectWriter);
    }
}

運行這段代碼之后,打開Demo.obj可以看到文件里面寫入了一段內容,這就是ILC編譯器往obj目標文件里面寫入被JIT編譯后的機器碼的核心部分代碼的原型。這里因為封裝了llvm的細節,又因托管省略了大部分,看起來比較簡潔。綜合起來實際上的代碼高達百萬行之巨,暫不贅述此部分。

以上代碼GitHub下載地址:

https://github.com/tangyanzhi/jianghupt/releases/download/llvm/Obj.rar

責任編輯:武曉燕 來源: 江湖評談
相關推薦

2023-07-11 00:17:58

.Net8AOTC

2023-09-11 08:40:34

AOTVMP代碼

2023-11-17 13:42:06

.NET8C#工具

2023-11-28 12:01:06

C++STL

2023-11-17 08:52:32

.NET8C#

2023-07-14 08:29:55

AOT.Net程序

2023-10-07 10:16:18

.Net8GC內存

2025-04-02 07:40:30

2024-10-11 14:42:59

2009-10-10 14:07:56

2024-08-30 09:21:28

2020-07-31 18:33:56

C++編程語言

2019-08-28 14:21:39

C++C接口代碼

2023-12-15 17:09:28

.NET8Primitives性能

2025-04-01 04:03:00

.NET8C#CPU

2024-11-07 12:33:47

2023-11-06 10:03:01

.Net8類型轉換

2010-01-26 15:51:06

C++變量

2014-04-17 10:37:43

C++.NET Native

2024-04-01 08:23:20

代碼Javajavascript
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久久影院 | 欧美精品黄 | 国产精品视频久久久 | 国产精品成人一区二区 | 国产精品久久久久久二区 | 视频第一区 | 男女国产视频 | 中文字幕 在线观看 | 国产精品一区久久久 | 午夜ww| 91精品国产色综合久久 | 精品成人佐山爱一区二区 | 色综合视频 | 国产精品免费一区二区三区四区 | 精品免费国产 | 欧美一级特黄aaa大片在线观看 | 97在线观视频免费观看 | 亚洲欧美日韩在线 | 午夜精品久久久久久久 | 蜜桃视频在线观看免费视频网站www | 玖玖视频网| 日韩在线视频一区 | 国产精品一区二区三区久久 | 高清免费在线 | 亚洲欧美成人在线 | 久久新 | 国产欧美一区二区三区在线看 | 久久久久亚洲 | 黑人巨大精品欧美一区二区免费 | 精品国产免费人成在线观看 | 人人做人人澡人人爽欧美 | 中文字幕国产精品 | 欧美三级久久久 | 日韩 欧美 综合 | 男女在线免费观看 | 色偷偷人人澡人人爽人人模 | 中文字幕一区二区三区日韩精品 | 自拍偷拍在线视频 | 欧美一级免费观看 | 伊人春色在线 | 国产精品成人一区二区三区夜夜夜 |