【问题标题】:What happens when JITter encounters another method call inside method's definition?当 JITter 在方法定义中遇到另一个方法调用时会发生什么?
【发布时间】:2015-11-13 23:48:17
【问题描述】:

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

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

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

【问题讨论】:

  • 这个问题很难回答。您可能想查看 JIT source code

标签: c# runtime clr jit


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2010-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多