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

What happens when JITter encounters another method call inside method's definition?

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

不幸的是,我在网上找到的所有描述都是说方法的 IL 代码只是编译成本机代码然后执行。

所以如果我的假设不正确,请提出您的意见。
谢谢!

在进行了一些额外的研究后,我偶然发现了 "Essential .NET: The Common Language Runtime" 中提供的详细描述。 最初在程序中初始化的每个类型都由一个数据结构表示,由一个方法 table 组成。 table 的每个条目都通过调用 JITter 过程 (JITter) 进行初始化。

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

已编译 IL 代码 JITter returns 存储本机指令的地址到方法的相应条目 table。

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