CSR :
|
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.