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 == REF_invokeSpecial)
+ refKind = REF_invokeVirtual;
+ 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/view_bug.do?bug_id=7087570
( And a duplicate of this:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=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