Jan*_*nis 39 java interface language-implementation internals vtable
C++有多重继承.在程序集级别实现多重继承可能非常复杂,但在线上有关于如何正常完成(vtables,指针修正,thunks等)的良好描述.
Java没有多个实现继承,但它确实有多个接口继承,所以我不认为每个类有一个vtable的直接实现可以实现它.java如何在内部实现接口?
我意识到与C++相反,Java是Jit编译的,因此不同的代码片段可能会有不同的优化,不同的JVM可能会做不同的事情.那么,是否存在许多JVM遵循的一般策略,或者有人知道特定JVM中的实现吗?
此外,JVM通常是虚拟化和内联方法调用,在这种情况下根本没有涉及vtable或等效项,因此询问实现虚拟/接口方法调用的实际汇编序列可能没有意义,但我认为大多数JVM仍然保留一些如果类无法将所有内容虚拟化,那么这些类的一般表示形式即可使用.这个假设是错的吗?这种表示形式是否像C++ vtable一样?如果是这样,接口有单独的vtable,它们如何与类vtable链接?如果是这样,对象实例可以有多个vtable指针(对于类/接口vtable),就像C++中的对象实例一样吗?对同一对象的类类型和接口类型的引用是否总是具有相同的二进制值,或者它们是否可以像C++中那样需要指针修复?
(供参考:这个问题提出了类似CLR的相似之处,这篇msdn文章似乎有一个很好的解释,虽然现在可能已经过时了.我找不到任何类似的Java.)
编辑:
Mar*_*wis 27
HotSpot JVM的主要功能是内联缓存.这实际上并不意味着目标方法是内联的,而是意味着将假设放入JIT代码中,以后对虚拟或接口方法的每个调用都将针对相同的实现(即调用站点是单态的).在这种情况下,检查被编译到机器代码中,无论假设是否实际成立(即目标对象的类型是否与上次相同),然后将控制直接转移到目标方法 - 没有虚拟表参与其中.如果断言失败,则可以尝试将其转换为变形呼叫站点(即具有多种可能类型); 如果这也失败了(或者如果它是第一次调用),则使用vtables(用于虚拟方法)和itables(用于接口)执行常规的长卷查找.
编辑: Hotspot Wiki有关于vtable和itable存根的更多细节.在多态的情况下,它仍然将内联缓存版本放入调用站点.但是,代码实际上是一个在vtable或itable中执行查找的存根.每个vtable偏移量(0,1,2,...)都有一个vtable stub.接口调用在查找给定偏移处的itable(如果找到)之前,在itables数组上添加线性搜索.