Is bytecode invokeinterface correct when resolved method from Object?
Alex Buckley
alex.buckley at oracle.com
Wed Dec 1 18:07:56 UTC 2021
On 12/1/2021 2:17 AM, Liu, Xin wrote:
> Not only each call takes 2 more bytes, I feel it doesn't comply with JVM
> spec. JVMS says that 'invokeinterface' resolves an 'interface method'.
> j.l.Object.getClass() is not an interface method, is it?
> https://docs.oracle.com/javase/specs/jvms/se17/html/jvms-6.html#jvms-6.5.invokeinterface
>
> Is it an intentional change of javac? My concern is that this ambiguity
> makes HotSpot more complex. Further, if it does violate JVMS, it will
> make javac implementation-dependent.
Emitting invokeinterface rather than invokevirtual in this scenario is
legitimate, correct, desirable, and documented (CSR: JDK-8272715).
`o.getClass()` is a method invocation whose receiver, `o`, has a static
type that is an interface, I. The compiler knows from JLS 9.2 that
`getClass()` is a member of I, so it is proper for the compiler to treat
`getClass()` as an interface method and thus emit an invokeinterface of
I.getClass. When the invokeinterface instruction is executed, its first
task is to resolve the interface method I.getClass -- happily, since the
Java SE 8 Edition, JVMS 5.4.3.4 has aligned with JLS 9.2 by
understanding that certain methods can be resolved in interfaces:
"Otherwise, if the class Object declares a method with the name and
descriptor specified by the interface method reference, which has its
ACC_PUBLIC flag set and does not have its ACC_STATIC flag set, method
lookup succeeds."
Alex
More information about the compiler-dev
mailing list