如何在内部实现java接口? (虚函数表?) [英] How are java interfaces implemented internally? (vtables?)

查看:147
本文介绍了如何在内部实现java接口? (虚函数表?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++有多重继承。在程序集级别实现多重继承可能非常复杂,但在线有很好的描述关于如何正常完成(vtables,指针修正,thunks等)。

C++ has multiple inheritance. The implementation of multiple inheritance at the assembly level can be quite complicated, but there are good descriptions online on how this is normally done (vtables, pointer fixups, thunks, etc).

Java没有多个实现继承,但它确实有多个接口继承,所以我认为每个类只有一个vtable的直接实现可以实现那。 java如何在内部实现接口?

Java doesn't have multiple implementation inheritance, but it does have multiple interface inheritance, so I don't think a straight forward implementation with a single vtable per class can implement that. How does java implement interfaces internally?

我意识到与C ++相反,Java是Jit编译的,所以不同的代码片段可能会有不同的优化,不同的JVM可能会以不同的方式做事。那么,是否存在许多JVM遵循的一般策略,或者有人知道特定JVM中的实现吗?

I realize that contrary to C++, Java is Jit compiled, so different pieces of code might be optimized differently, and different JVMs might do things differently. So, is there some general strategy that many JVMs follow on this, or does anyone know the implementation in a specific JVM?

此外,JVM通常是虚拟化和内联方法调用,在这种情况下根本没有涉及vtable或等效项,因此询问实现的实际汇编序列可能没有意义虚拟/接口方法调用,但我假设大多数JVM仍然保留某种类的一般表示,如果它们无法虚拟化所有内容。这个假设是错的吗?这种表示形式是否像C ++ vtable一样?如果是这样,接口有单独的vtable,它们如何与类vtable链接?如果是这样,对象实例可以有多个vtable指针(对于类/接口vtable),就像C ++中的对象实例一样吗?类类型和接口类型对同一对象的引用是否总是具有相同的二进制值,或者它们是否可以像C ++中那样需要指针修复?

Also JVMs often devirtualize and inline method calls in which case there are no vtables or equivalent involved at all, so it might not make sense to ask about actual assembly sequences that implement virtual/interface method calls, but I assume that most JVMs still keep some kind of general representation of classes around to use if they haven't been able to devirtualize everything. Is this assumption wrong? Does this representation look in any way like a C++ vtable? If so do interfaces have separate vtables and how are these linked with class vtables? If so can object instances have multiple vtable pointers (to class/interface vtables) like object instances in C++ can? Do references of a class type and an interface type to the same object always have the same binary value or can these differ like in C++ where they require pointer fixups?

(供参考:这个问题询问有关CLR的类似内容,似乎在这篇msdn文章虽然现在可能已经过时了。我找不到类似Java的东西。)

(for reference: this question asks something similar about the CLR, and there appears to be a good explanation in this msdn article though that may be outdated by now. I haven't been able to find anything similar for Java.)

编辑:


  • 我的意思是实现,意思是GCC编译器如何实现整数加法/函数调用/ etc,不是Java类ArrayList实现List接口的意思。

  • 我知道这在JVM字节码级别是如何工作的,我想知道的是JVM在加载类文件后生成了什么样的代码和数据结构编译字节码。

推荐答案

HotSpot JVM的主要功能是内联缓存
这实际上并不意味着目标方法是内联的,而是意味着假设
被放入JIT代码中,以后对虚拟或接口方法的每个调用都将以
为目标相同的实现(即调用站点是单态的)。在这种情况下,
检查被编译到机器代码中,无论假设是否实际成立(即
目标对象的类型是否与上次相同),然后转移控制
直接到目标方法 - 根本没有涉及虚拟表。如果断言失败,则可以尝试将其转换为变形呼叫站点(即具有多种可能类型);如果这也失败了(或者如果它是第一次调用),则使用vtables(用于虚拟方法)和itables(用于接口)执行常规的长卷查找。

The key feature of the HotSpot JVM is inline caching. This doesn't actually mean that the target method is inlined, but means that an assumption is put into the JIT code that every future call to the virtual or interface method will target the very same implementation (i.e. that the call site is monomorphic). In this case, a check is compiled into the machine code whether the assumption actually holds (i.e. whether the type of the target object is the same as it was last time), and then transfer control directly to the target method - with no virtual tables involved at all. If the assertion fails, an attempt may be made to convert this to a megamorphic call site (i.e. with multiple possible types); if this also fails (or if it is the first call), a regular long-winded lookup is performed, using vtables (for virtual methods) and itables (for interfaces).

修改 :本热点Wiki 有关vtable和itable存根的更多细节。在多态的情况下,它仍然将内联缓存版本放入调用站点。但是,代码实际上是一个在vtable或itable中执行查找的存根。每个vtable偏移量(0,1,2,...)都有一个vtable stub。 接口调用窥视itable之前添加超出itables的阵列的线性搜索(如果找到)在给定的偏移处。

Edit: The Hotspot Wiki has more details on the vtable and itable stubs. In the polymorphic case, it still puts an inline cache version into the call site. However, the code actually is a stub that performs a lookup in a vtable, or an itable. There is one vtable stub for each vtable offset (0, 1, 2, ...). Interface calls add a linear search over an array of itables before looking into the itable (if found) at the given offset.

这篇关于如何在内部实现java接口? (虚函数表?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆