当JITter在方法定义中遇到另一个方法调用时会发生什么?

时间:2015-08-20 11:02:03

标签: c# runtime clr jit

请考虑以下情况。 如您所知,在Main()执行之前,CLR为Main()内的每个引用类型分配一个内部数据结构,其中包含引用类型中定义的每个方法的条目。随后,每个条目保持对存储相应本机代码的存储器块的引用(存根)。 让我们假设在Main()中执行代码时,JITter遇到方法 SomeClass1.M1()。引用SomeClass1来查找相关的IL代码 所以问题如下:
- 当CLR碰到M1()内的另一个方法调用时会发生什么,让我们说 SomeClass2.M2()。这是否意味着创建包含SomeClass2方法的第二个数据结构,然后将本机代码的地址绑定到相应的方法?如果是,那么:
- 将在第一个数据结构中存储什么? - 如果M1()的描述立即以调用M2()开始,并且M1()内部还有一些代码跟在M2()之后,将存储在第一个数据结构中的内容。

不幸的是,我在网上发现的一个描述是说方法的IL代码只是被编译成本机代码然后被执行。

因此,如果我的假设不正确,请提供您的意见。
谢谢!

1 个答案:

答案 0 :(得分:1)

在进行了一些额外的研究后,我碰到了基本的.NET:公共语言运行时"中提供的详细描述。 最初,程序中初始化的每个类型都由一个数据结构表示,该结构由一个方法表组成。通过调用JITter过程(JITter)初始化表的每个条目。

因此调用SomeClass1.M1()意味着控制被传递给JITter过程(通过JMP指令),该过程将相应的IL代码编译成机器代码。如果在M1()中有一些其他子方法(如SomeClass2.M2()),它们将通过" call"从机器代码内引用。指令(每个调用指令将引用前面提到的方法表中的相应方法条目)。

编译了IL代码后,JITter将本机指令的存储地址返回到方法表的相应条目。

之后执行一个刚刚编译的代码片段,一旦CLR遇到子方法调用,它将引用方法表的相应条目,以查看它是否包含本机指令'地址或JITer调用。如果是后者,则再次调用JITter,否则使用JMP instuction(带地址引用)来执行本机代码块。