C ++具有多个继承。在组装级别的多个继承实施可能非常复杂,但是有很好的 描述 在线有关通常如何完成的(VTABLES,POINTER FIXUP,THUNKS等)。

Java没有多个实现继承,但是它确实具有多个接口继承,因此我认为每类单个VTable的直接实现都无法实现。 Java在内部如何实现接口?

我意识到与C ++相反,Java已编译为JAV,因此不同的代码可能会有所不同,并且不同的JVM可能对操作的方式有所不同。因此,是否有许多JVM遵循的一般策略,还是有人知道特定JVM中的实现?

jvms通常通常不涉及vtable或同等涉及的情况,因此询问实现虚拟/接口方法调用的实际汇编序列可能没有意义,但是我认为大多数JVM仍然保留一些,可能是没有意义的如果他们无法使所有内容变性化,则可以使用周围的课程。这个假设错误吗?此表示形式是否像C ++ vtable一样看?如果是这样,接口有单独的vtables,这些与类Vtables如何链接?如果是这样的话,对象实例可以具有多个可vtable的指针(对class/interface vtables),例如C ++中的对象实例?类型的引用和对同一对象的接口类型的引用是否始终具有相同的二进制值,或者这些值在C ++中是否需要指针修复?

(以供参考: 这个问题 询问有关CLR的类似内容,并且似乎有一个很好的解释 这篇MSDN文章 尽管现在可能已经过时了。我找不到Java类似的东西。)

编辑:

  • 我的意思是从“ GCC编译器如何实现整数添加 /函数调用 / etc”的意义上,而不是“ Java类ArrayList实现列表接口”。
  • 我知道在JVM字节码级别的工作方式,我想知道的是,JVM完成加载类文件并编译字节码后,JVM生成了哪种代码和数据架构。
有帮助吗?

解决方案

热点JVM的关键功能是 内联缓存. 。实际上,这并不意味着目标方法是内衬的,而是意味着将一个假设放在JIT代码中,即将来每个呼叫虚拟或接口方法将针对相同的实现(即呼叫站点是单态)。在这种情况下,将检查编译到机器代码中,无论假设是否实际成立(即目标对象的类型是否与上次相同),然后直接传输控制到目标方法 - 没有虚拟表完全参与。如果断言失败,则可以尝试将其转换为Megamorphic呼叫站点(即具有多种可能的类型);如果这也失败(或者是第一个呼叫),则使用VTABLES(用于虚拟方法)和ITABLE(用于接口)执行常规的长途查找。

编辑: : 这 热点Wiki 有有关VTable和Itable Stubs的更多详细信息。在多态性情况下,它仍然将直列缓存版本放入呼叫站点。但是,该代码实际上是在VTable或Itable中执行查找的存根。每个VTable偏移量(0、1、2,...)都有一个vtable存根。 接口调用 在给定偏移量的iTable(如果发现)之前,请在一系列Itables上添加线性搜索。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top