.Net 7 新编译器ILC简析(二)
楔子
它主要是生成Native Code,跟CLR调用RyuJIT的即时编译有所不同。承接上篇:点击此处
初始化
ILC的初始化自然是核心的.Net 类库System.Private.CoreLib.dll。注意这个DLL跟CLR的System.Private.CoreLib.dll不太一样。另外就是初始化ILC所依赖的库文件,比如TypeRef此类。
R2RH
R2RH的全称是:ReadyToRunHeader。这个东西是贯穿整个ILC编译器的核心,在初始化加载全局栈_markStack的时候,它是第一个被Push到这个栈里面的。后面陆续Push: GCStaticsRegion ThreadStaticsRegion EagerCctorTable TypeManagerIndirection DispatchMapTable FrozenSegmentRegion InterfaceDispatchCellSection ModuleInitializerList 以上八大类型,除了InterfaceDispatchCellSection,又会被陆续加入到R2RH的_items项。
到整个需要被写入目标文件的全局栈Count数目为0x50十进制的80个。在这80个项里面会被筛选和循环,所有项里面依赖的函数项,包括虚函数,静态函数,以及非静态函数等,和其它一些编译需要用到的节点Node。 此次结果为:0x0000d7d8项。
并行编译
ILC相对于CLR调用JIT的一个最大好处就是同时启动并行函数编译,实质上就是对于多个函数进行一次性并行编译,而非一次性编译一个函数。其实非常简单,主要用到的函数就是:Parallel.ForEach
Parallel.ForEach(
methodsToCompile,
new ParallelOptions { MaxDegreeOfParallelism = _parallelism },
CompileSingleMethod);
在提取一部分依赖的项和函数进行编译之后,会继续遍历剩余的项以及函数进行编译。直至以上所有完成为止。
Write
写入是写入目标文件,因为不同的平台有不同的目标文件格式,比如windows的.Obj,Linux .O,MacOs Mach-O等。所以会通过ObjWriter封装调用LLVM写入不同的平台目标文件。
步骤
Source Code ->Roslyn(DLL)->ILC->RyuJit(native code)->ObjWriter(Obj)->链接(可执行文件)。
结尾
如有疏漏,请不吝赐教。
相关文章
- Linux 中如何获取文件的绝对路径
- 如何检查 Linux 服务器的运行时间
- Linux 中如何使用 id 命令,它是做什么用的呢?
- 什么是 Azure Synapse,它与 Azure Data Bricks 有何不同?
- 定价模型,该如何做分析?
- 浅谈我所见识的数据治理项目
- 跟着小白一起学鸿蒙--]简单Http客户端(十二)
- 三方库移植之NAPI开发--异步调用:Callback&Promise(四)
- 你了解 Linux 文件权限和所有权吗?
- 2022年数据治理和运营安全领域的发展趋势
- 使用 useradd 命令在 Linux 中添加新用户
- Linux 中如何检查开放的端口
- 在Linux中,怎样只显示隐藏文件?
- Github上八个优秀的React项目
- 如何在 bash shell 脚本中 echo 一个新行
- 为什么2022年仍然存在数据孤岛?
- Go 语言怎么优化重复的 if err != nil 样板代码?
- OS内核的信号机制:所有的异步都可以是同步的
- React 的 SetState 是同步还是异步?
- 微服务权限处理,为什么这么难?