changeset 430:7325272c5eb4

meth-info-7087570.patch: first cut
author jrose
date Fri, 21 Sep 2012 23:50:31 -0700
parents a8e6272996ec
children c78764535f4e
files meth-info-7087570.patch series
diffstat 2 files changed, 117 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/meth-info-7087570.patch	Fri Sep 21 23:50:31 2012 -0700
@@ -0,0 +1,116 @@
+7087570: java.lang.invoke.MemberName information wrong for method handles created with findConstructor
+Summary: REF_invokeSpecial DMHs (which are unusual) get marked explicitly; tweak the MHI to use this bit
+Reviewed-by: ?
+
+diff --git a/src/share/classes/java/lang/invoke/DirectMethodHandle.java b/src/share/classes/java/lang/invoke/DirectMethodHandle.java
+--- a/src/share/classes/java/lang/invoke/DirectMethodHandle.java
++++ b/src/share/classes/java/lang/invoke/DirectMethodHandle.java
+@@ -54,15 +54,19 @@
+         this.member = member;
+     }
+ 
+-    // Factory methods:
+-
+-    static DirectMethodHandle make(Class<?> receiver, MemberName member) {
++    private static MethodType computeMethodType(Class<?> receiver, MemberName member) {
+         MethodType mtype = member.getMethodOrFieldType();
+         if (!member.isStatic()) {
+             if (!member.getDeclaringClass().isAssignableFrom(receiver) || member.isConstructor())
+                 throw new InternalError(member.toString());
+             mtype = mtype.insertParameterTypes(0, receiver);
+         }
++        return mtype;
++    }
++
++    // Factory methods:
++    static DirectMethodHandle make(Class<?> receiver, MemberName member) {
++        MethodType mtype = computeMethodType(receiver, member);
+         if (!member.isField()) {
+             LambdaForm lform = preparedLambdaForm(member);
+             return new DirectMethodHandle(mtype, lform, member);
+@@ -84,6 +88,12 @@
+             return makeAllocator(member);
+         return make(member.getDeclaringClass(), member);
+     }
++    static DirectMethodHandle makeSpecial(Class<?> receiver, MemberName member) {
++        assert(member.getReferenceKind() == REF_invokeSpecial) : member;
++        MethodType mtype = computeMethodType(receiver, member);
++        LambdaForm lform = preparedLambdaForm(member);
++        return new Special(mtype, lform, member);
++    }
+     static DirectMethodHandle make(Method method) {
+         return make(method.getDeclaringClass(), new MemberName(method));
+     }
+@@ -357,6 +367,18 @@
+         ((DirectMethodHandle)mh).ensureInitialized();
+     }
+ 
++    /** This subclass represents invokespecial instructions. */
++    static class Special extends DirectMethodHandle {
++        private Special(MethodType mtype, LambdaForm form, MemberName member) {
++            super(mtype, form, member);
++        }
++        /*non-public*/
++        @Override
++        boolean isInvokeSpecial() {
++            return true;
++        }
++    }
++
+     /** This subclass handles constructor references. */
+     static class Constructor extends DirectMethodHandle {
+         final MemberName initMethod;
+diff --git a/src/share/classes/java/lang/invoke/MethodHandle.java b/src/share/classes/java/lang/invoke/MethodHandle.java
+--- a/src/share/classes/java/lang/invoke/MethodHandle.java
++++ b/src/share/classes/java/lang/invoke/MethodHandle.java
+@@ -1268,6 +1268,11 @@
+     }
+ 
+     /*non-public*/
++    boolean isInvokeSpecial() {
++        return false;  // DMH.Special returns true
++    }
++
++    /*non-public*/
+     Object internalValues() {
+         return null;
+     }
+diff --git a/src/share/classes/java/lang/invoke/MethodHandleInfo.java b/src/share/classes/java/lang/invoke/MethodHandleInfo.java
+--- a/src/share/classes/java/lang/invoke/MethodHandleInfo.java
++++ b/src/share/classes/java/lang/invoke/MethodHandleInfo.java
+@@ -45,12 +45,17 @@
+    private final MethodType methodType;
+    private final int referenceKind;
+ 
+-   public MethodHandleInfo(MethodHandle mh) throws ReflectiveOperationException {
++   public MethodHandleInfo(MethodHandle mh) {
+        MemberName mn = mh.internalMemberName();
++       if (mn == null)  throw new IllegalArgumentException("not a direct method handle");
+        this.declaringClass = mn.getDeclaringClass();
+        this.name = mn.getName();
+        this.methodType = mn.getMethodType();
+-       this.referenceKind = mn.getReferenceKind();
++       byte refKind = mn.getReferenceKind();
++       if (refKind == REF_invokeSpecial && !mh.isInvokeSpecial())
++           // Devirtualized method invocation is usually formally virtual.
++           refKind = REF_invokeVirtual;
++       this.referenceKind = refKind;
+    }
+ 
+    public Class<?> getDeclaringClass() {
+diff --git a/src/share/classes/java/lang/invoke/MethodHandles.java b/src/share/classes/java/lang/invoke/MethodHandles.java
+--- a/src/share/classes/java/lang/invoke/MethodHandles.java
++++ b/src/share/classes/java/lang/invoke/MethodHandles.java
+@@ -1211,7 +1211,11 @@
+             checkMethod(refKind, refc, method);
+             if (method.isMethodHandleInvoke())
+                 return fakeMethodHandleInvoke(method);
+-            MethodHandle mh = DirectMethodHandle.make(refc, method);
++            MethodHandle mh;
++            if (refKind != REF_invokeSpecial)
++                mh = DirectMethodHandle.make(refc, method);
++            else
++                mh = DirectMethodHandle.makeSpecial(refc, method.asSpecial());
+             mh = maybeBindCaller(method, mh);
+             mh = mh.setVarargs(method);
+             if (doRestrict)
--- a/series	Sat Sep 01 16:44:35 2012 -0700
+++ b/series	Fri Sep 21 23:50:31 2012 -0700
@@ -6,6 +6,7 @@
 # review pending before push to hotspot-comp:
 
 # non-pushed files are under review or development, or merely experimental:
+meth-info-7087570.patch         #-/meth #+59231f2cb6e1
 meth.patch                      #-/meth #+59231f2cb6e1
 meth-7177472.patch              #-/meth #+59231f2cb6e1 #-buildable
 indy.pack.patch                 #-/meth #+59231f2cb6e1 #-buildable