JDK-8276255 : LambdaMetaFactory::metafactory on REF_invokeSpecial impl method has incorrect behavior
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.lang.invoke
  • Priority: P3
  • Status: Draft
  • Resolution: Unresolved
  • Fix Versions: 18
  • Submitted: 2021-11-01
  • Updated: 2021-11-01
Related Reports
CSR :  
Description
Summary
-------

`LambdaMetaFactory::metafactory` on a `REF_invokeSpecial` implementation method should behave as if `invokespecial` instruction unless it's a private method in the caller class.

Problem
-------

It's a regression introduced by the implementation of JDK-8238358 in JDK 15. 
A lambda class, a nestmate of the original class, does not have access to use `invokespecial` on the original class's super methods. For such case, the lambda class will invoke the implementation method directly on the method handle (i.e. via `MethodHandle::invoke`). On the other hand, `invokespecial` was used to invoke private methods prior to Java 11 (JEP 181). Since Java 11, `invokespecial` is only used to invoke private nestmate constructor. `invokevirtual` or `invokeinterface` is used to invoke private implementation method instead.   However, existing classes use REF_invokeSpecial to invoke private methods prior to Java11.    For compatibility, JDK-8238358 converts `REF_invokeSpecial` method handle to `REF_invokeVirtual` or `REF_invokeInterface` method handle.   Such conversion should only apply private methods but the conversion mistakenly applies to non-private method.  This causes the behavioral change of `REF_invokeSpecial` implementation method be invoked with `REF_invokeVirtual/REF_invokeInterface` if it's a public/protected method (i.e. the method in a subclass may be invoked instead of the method in the superclass).

Solution
--------

Fix the implementation to convert REF_invokeSpecial to REF_invokeVirtual/REF_invokeInterface only if the implementation method is a private method of the caller class.

Specification
-------------

No specification change.