【发布时间】:2021-07-17 08:12:27
【问题描述】:
这里是an article介绍虚调用的jit优化策略。
但令我惊讶的是,所有优化的虚拟调用都使用相同的地址,比如文章中的callq 0x000000011418ea00。
所以我很好奇它在该地址中实际做了什么,以及它如何知道要调用哪个函数,因为所有优化的虚拟调用都指向同一个地址。
【问题讨论】:
-
文章不是已经说明了吗?虚拟调用需要查找 VMT,该 VMT 由正在调用其方法的对象的实例所指向。所有对象的查找代码都是相同的。或者至少它可以处理不同的对象实例。
-
@MargaretBloom 我有两个问题。首先是查找代码是如何知道当前调用方法的索引的,我没有找到任何地方设置这样的索引。其次,如果该地址后面的代码只是进行 VMT 查找,为什么称为“优化虚拟调用”?或者更确切地说,优化是什么?
-
你没有在哪里找到它?这就像 C++ vtable。每个对象实例都是用一个指针列表创建的。派生对象使用所有基类指针,但会覆盖那些对应于被覆盖方法的指针。索引由方法固定,改变的是指针值。我简要阅读了那篇文章,优化是内联方法并完全跳过 VMT 查找。
-
@MargaretBloom 跳过 VMT 查找是什么意思?实际上我很好奇它是如何跳过 VMT 查找的,因为我可以从程序集中学到的只是所有函数调用都指向同一个地址。
-
我只浏览了那篇文章,但据我所见,当一个方法被优化时,它被内联并且
virtualcall字节码被完全发出。您正在查看未优化方法的汇编代码。优化后不会有virtualcall及其相关的汇编代码。如果您自己反汇编这些类,可能会更容易看到这一点,查看上下文陈述不佳的代码摘录会令人困惑:)