.Net 7 CLR和ILC编译函数过程

news2024/11/25 2:58:28

楔子

由于甲方的需求,随着研究深入,发现CLR编译函数与ILC编译是两种不同的截然方式,除了JIT部分编译一样,其它部分貌似完全不一。

本篇来梳理这些东西。QQ:676817308。wx公众号:江湖评谈


 

示例:

作为例子,先上一段非常简单的代码:

    internal class Program
    {
        static void Main(string[] args)
        {
            A();
        }

        static void A()
        {
            B();
        }
        static void B()
        {
        }
    }


 

CLR编译

上面的例子,如果是CLR来编译,假设从Main函数入口开始,它首先是是通过CLR加载Main函数的IL代码来调用JIT,构建一个汇编层面代码。然后跳转到Main函数的起始位置,也就是函数头处执行。当执行的过程中,遇到了Main函数里面调用了A函数。它会识别A函数的IL代码,调用JIT把IL代码编译成机器码,然后跳转到A函数的函数头,在A函数执行的过程中又遇到B函数,它识别B函数的IL代码,然后调用JIT把IL代码编译成机器码。跳转到B函数的函数头汇编位置执行。执行完毕,然后又跳转到刚刚调用B函数的A函数的下一条指令开始执行,执行完毕。跳转到调用A函数的Main函数里面的下一条指令开始执行。Main执行完成之后,整个运行过程执行完毕。

这上面一大段的话语,是自己理解而成。画成图片就如下所示:


 

ILC编译

1.表位:
ILC的编译迥异于CLR的编译,它主要是通过重定位向量表IMAGE_BASE_RELOCATION来构建一个编译过程。

上面的CLR因为是通过递归来查找当前需要编译的函数,这个过程看似没问题,但是实际上当函数第一次运行的时候,就需要调用JIT。比如某一个函数运行了很多次,但是某次调用了某个特殊函数,这个特殊函数刚好第一次运行(其它时候都没调用,可能if else这种语句),恰巧如果这个函数编译时间较长,这样就拖累整体的运行性能。如果这种情况运行几次,或者十几次,或者更多,那么导致整个程序性能拉胯不堪。

2.解决
为了解决这个问题,微软团队搞了一个天才的设想。就是把所有的函数,事先编译一遍,等到运行的时候,直接调用这个编译之后的结果就行了。刚好社区有AOT编译需求,于是这个功能就用在了AOT上。

但是AOT的短处也是显而易见的,最常见的缺陷就是它的优化性能不如JIT。为了解决这个问题,于是R2R技术又天才般的冒出来了。它既解决了AOT优化问题,又解决了JIT预热问题。
所以就有了ILC与R2R的Crossgen2共享代码的现状。

3.过程

这里只是看看,ILC编译过程,其余不论。ILC是把所有函数全部事先编译一遍,然后写入到.O OR .Obj里面,最后链接到二进制可执行文件。了解了这个原理,再来看它编译过程。

如何知道一个函数它所依赖的所有函数呢?比如例子里面,你调用Main函数,Main函数里面又调用了A函数,A函数里面又调用了B函数。
如何通过Main函数知道A函数和B函数的存在,然后把Main,A,B三个函数进行事先编译呢?

要解决这个问题,需要JIT里面的重定位向量表。ILC在编译到时候,把所有需要用到的引用进行JIT编译。
当JIT编译一个函数的时候,它会在这个函数的汇编代码层面标记一些东西。比如它编译Main函数的时候,在Main函数里发现里面调用了A函数,假设上面例子编译的托管DLL是ConsoleApp1.Dll。那么A函数就会被注释成:ConsoleApp1.Program.A这种形式,然后把它放到基址重定位向量表里。
此后,它会循环被编译的函数和基址重定位向量表。把编译的函数添加到全局栈,如果发现函数包含基址向量表,就会把这个向量表进行子循环,把每个向量表里的函数添加到全局站。然后查找向量表里面的函数是否包含函数,如果有,则继续注释,放到向量表,循环。

4.图示


 

结尾

以上都是通过Debug代码理解而来,比较晦涩。
纯粹是甲方的某些需求需要用到。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/84356.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OH----基于RK3568的AB分区功能,bsp部分

1、背景: OH master 主线 ,RK3568平台添加AB分区功能,uboot部分完成对ab分区标志位的读取解析,并加载和进入对应的分区,如: kernel_a 或者 kernel_b 2、环境: rk3568 Uboot代码下载&#xff…

股票L2接口和L1接口有什么差距?

股票L2数据的主要特点是能看到资金流向和十档买卖盘,比L1数据更加清晰和全面。 但是就现在的股票市场而言,也不能全部听信L2数据。 很多数据也是庄家做出来的,就是为了给散户看,所以全面分析基本面和技术面才是最重要的。 而且…

[附源码]计算机毕业设计个人博客系统Springboot程序

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: Springboot mybatis MavenVue等等组成,B/S模式…

【CSS】多行文字保持垂直居中,移动端布局,grid布局,居中总结

❤️ Author: 老九 ☕️ 个人博客:老九的CSDN博客 🙏 个人名言:不可控之事 乐观面对 😍 系列专栏: 文章目录多行文字垂直居中方法一方法2方法3方法四移动端布局viewport标签典型的手机网页设计grid布局grid…

基于C语言+SQL Server2008实现(控制台)图书管理系统【100010024】

第1章 概述 1.1项目背景 随着科技的发展,尤其是计算机技术的迅猛发展,图书馆管理的问题从以往的人工管理,到现在的电脑化,系统化,是对图书馆管理方法的质的飞跃,这些技术不仅让图书馆管理变得更加方便、快…

【Java EE初阶】创建线程的五种方式

文章目录1. 继承Tread,重写run()2. 实现Runnable接口,重写run()3. 使用匿名内部类,继承Thread4. 使用匿名内部类,实现Runnable5. 使用lambda表达式1. 继承Tread,重写run() 示例:pandas 是基于NumPy 的一种工具,该工具…

Kafka系列之:使用Kafka Manager实现leader分区平衡和broker节点上分区平衡

Kafka系列之:使用Kafka Manager实现leader分区平衡和broker节点上分区平衡 一、需求背景二、leader分区不平衡三、实现leader分区不平衡四、分区在节点不平衡五、实现分区在节点平衡一、需求背景 kafka节点扩容,分区不平衡现在需要leader分区平均分配在每个节点上同时分区副本…

基于Python+Django的项目申报审核平台系统

在各学校的教学过程中,django项目校内申报平台系统是一项非常重要的事情。随着计算机多媒体技术的发展和网络的普及。采用当前流行的B/S模式以及3层架构的设计思想通过Python技术来开发此系统的目的是建立一个配合网络环境的django高校学生项目校内申报平台&#xf…

OMV 5.6入坑指南(一)-openmediavalut 5.6安装

一、DIY NAS服务器 百度网盘里攒了一堆电影、电视剧,想下载到电脑里,买了个4T硬盘,然后发现不够用,然后又买了个还是不够用,然后自己又不想开电脑看电视电影,平时看电视电影都是在ipad上看的,台…

可视化管线

VTK中的可视化管线可用于读取或创建数据、分析和创建此数据的派生版本,并将数据写入磁盘或将其传递给渲染引擎进行显示。例如,您可以从磁盘读取一个三维数据体,对其进行处理以创建一组三角形,这些三角形通过该数据体表示一个等值曲…

全栈Jmeter接口测试(六):json断言元件,jmeter参数化实现

Jmeter(12):json断言元件 json断言元件介绍: json断言元件与响应断言元件的功能类型,它只针对响应正文为json数据格 式的内容进行断言功能。 添加路径:右击http请求——断言——json断言 如下图展示: json断言元件字…

JAVA毕业设计——基于SpringBoot和thymeleaf的疫情信息管理系统 (源码+数据库)

github代码地址 https://github.com/ynwynw/CoronavirusManage-public 毕业设计所有选题地址 https://github.com/ynwynw/allProject 基于SpringBoot及thymeleaf搭建的疫情信息管理系统 (源码数据库)034 一、系统介绍 疫情信息管理系统应当具备两种对象,疫情管理…

【论文精读10】MVSNet系列论文详解-PatchmatchNet

PatchmatchNet,论文名为:PatchmatchNet: Learned Multi-View Patchmatch Stereo,本篇论文结合了较多过往文章的优化思想和类似模块,因此可能要更复杂一些。 本文是MVSNet系列的第10篇,建议看过【论文精读1】MVSNet系列…

【嵌入式linux】修改网口MAC地址

使用带有网络功能的设备时,如果局域网内可能会连接很多台设备,为了保证网络通信正常,要确保每台设备的硬件MAC地址都不相同,一般在批量生产的时候可以根据产品序列号(sn号)固化每台设备的MAC地址,防止出现MAC冲突的问题…

【云原生】Prometheus PromQL讲解与实战操作

文章目录一、PromQL介绍二、四种指标类型1)counter(计数器)2)gauge (仪表类型)3)Histogram(直方图类型) 和 Summary(摘要类型)三、表达式四种数据…

8Manage PMO:多项目管理工作经验分享

在现代企业日常项目管理中,同时开展不同业务项目可说已经是“家常便饭”,项目经理手上开展多个项目,便需要兼顾各项目的人力资源、进度、问题、风险等。而在这种情况下,面对多项目管理该如何有效进行管理,有没有多项目…

换天空的几个方式技巧

1.魔棒工具 现将图层复制一层,用魔棒工具选中被复制的一层图中的天空将他删除。(如果天空有一些未选中的位置,那么我们按住shift用鼠标去点击需要删除的位置他就会一起选中) 这个就是我们删除之后的效果。 然后我们打开一张需要加…

体验了一下火爆全球的 ChatGPT,我震惊了

这几天,要说编程圈最热的话题,莫过于OpenAI的ChatGPT,写小说,写代码,找BUG,写论文,画漫画,谱曲……简直没有它干不了的事。 趁着下班时间,我也光速注册体验了一下&#…

VS Code 1.74 发布!

欢迎来到 VS Code 11月更新,此版本更新包括自定义资源管理器自动显示、隐藏活动栏和面板徽章、合并编辑器撤消/重做、管理不安全的存储库、Go to Definition on return、远程隧道等等,让我们一起看看完整更新吧! 自定义资源管理器自动显示 引…

Linux Centos离线地图开发

相关教程: 1、如何搭建离线地图开发环境 视频教程 2、下载离线地图数据(金字塔瓦片数据) 视频教程 3、下载离线地图地形数据库(实现地表高低起伏) 4、添加离线地图数据到本地服务器 (含3D) 视频…