Request for review (M): JDK-7087570: java.lang.invoke.MemberName information wrong for method handles created with findConstructor (original) (raw)

Krystal Mo krystal.mo at oracle.com
Tue Feb 12 02:34:12 UTC 2013


Thank you for the review, Chris. Comments inline:

On 02/11/2013 06:06 PM, Christian Thalinger wrote:

src/share/classes/java/lang/invoke/DirectMethodHandle.java: + static DirectMethodHandle make(Class<?> receiver, MemberName member) { + byte refKind = member.getReferenceKind(); + if (refKind == REFinvokeSpecial) + refKind = REFinvokeVirtual; + return make(refKind, receiver, member); + } We are replacing all invokespecials with invokevirtuals? -- Chris

This might look a bit hacky...

The idea is, DirectMethodHandle.make(Class<?> receiver, MemberName member) should keep its behavior as it used to be.

The newly added DirectMethodHandle.make(byte refKind, Class receiver, MemberName member) treats (refKind == invokespecial) "specially", which is necessary when called from MethodHandles.getDirectMethodCommon(...), where invokevirtual got strength-reduced to invokespecial matters; but when called from DirectMethodHandle.make(Class receiver, MemberName member), refKind would need to be something other than invokespecial to keep the original behavior, thus the normalization in DirectMethodHandle.make(Class<?> receiver, MemberName member). This is safe.

Let's get John's comment and see if my understanding of that part is correct.

Thanks, Kris

Bug: http://bugs.sun.com/bugdatabase/viewbug.do?bugid=7087570 ( And a duplicate of this: http://bugs.sun.com/bugdatabase/viewbug.do?bugid=8005119 )

Background: When linking methods, HotSpot VM may strength-reduce the invocation mode of some virtual methods from invokevirtual to invokespecial. e.g. virtual methods in a final class, or non-private member methods marked as final. When that happens, a method's invocation mode may be nominally "invokevirtual", but the VM actually treats it as "invokespecial". Before this fix, the Java-level MethodHandle implementation didn't tell apart the "real" invokespecials with the strength-reduced ones. When creating a MethodHandle via lookup/ldc/unreflect, wrong metadata may be returned if this strength-reduction happened. This broke a few things, including the two scenarios in JDK-7087570 and JDK-8005119. With the fix, special handling is added so that a "real" invokespecial is truly a "Special" version of DirectMethodHandle, so users of the MethodHandle will not be affected by the mismatch between the nominal and the actual invocation mode. For the record, credit goes to John Rose who did the actual fix. I only added the unit test to verify the fix. Tested with JPRT, jtreg test/java/lang/invoke, including the new unit test. I intend to push this to jdk8/tl/jdk as it's a Java-only change; I believe langtool people could get the bits earlier this way. Could somebody from the jdk side help with the push? Thanks, Kris



More information about the core-libs-dev mailing list