8050174: Support overriding of isInvokeSpecial flag in WrappedMember
authorvlivanov
Wed, 10 Sep 2014 19:19:49 +0400
changeset 26471 1de6be0c6945
parent 26470 1586df597397
child 26472 71b6a6f208c0
8050174: Support overriding of isInvokeSpecial flag in WrappedMember Reviewed-by: vlivanov, psandoz Contributed-by: john.r.rose@oracle.com
jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java
jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java
jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java
--- a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java	Wed Sep 10 19:19:49 2014 +0400
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java	Wed Sep 10 19:19:49 2014 +0400
@@ -107,7 +107,7 @@
         LambdaForm lform = invokeHandleForm(mtype, false, which);
         MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, mtype);
         String whichName = (isExact ? "invokeExact" : "invoke");
-        invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke(whichName, mtype));
+        invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke(whichName, mtype), false);
         assert(checkInvoker(invoker));
         maybeCompileToBytecode(invoker);
         return invoker;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java	Wed Sep 10 19:19:49 2014 +0400
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java	Wed Sep 10 19:19:49 2014 +0400
@@ -1356,9 +1356,9 @@
     }
 
     /*non-public*/
-    MethodHandle withInternalMemberName(MemberName member) {
+    MethodHandle withInternalMemberName(MemberName member, boolean isInvokeSpecial) {
         if (member != null) {
-            return MethodHandleImpl.makeWrappedMember(this, member);
+            return MethodHandleImpl.makeWrappedMember(this, member, isInvokeSpecial);
         } else if (internalMemberName() == null) {
             // The required internaMemberName is null, and this MH (like most) doesn't have one.
             return this;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Wed Sep 10 19:19:49 2014 +0400
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java	Wed Sep 10 19:19:49 2014 +0400
@@ -807,7 +807,7 @@
         mh = mh.bindTo(new UnsupportedOperationException("cannot reflectively invoke MethodHandle"));
         if (!method.getInvocationType().equals(mh.type()))
             throw new InternalError(method.toString());
-        mh = mh.withInternalMemberName(method);
+        mh = mh.withInternalMemberName(method, false);
         mh = mh.asVarargsCollector(Object[].class);
         assert(method.isVarargs());
         FAKE_METHOD_HANDLE_INVOKE[idx] = mh;
@@ -844,7 +844,7 @@
             MethodHandle vamh = prepareForInvoker(mh);
             // Cache the result of makeInjectedInvoker once per argument class.
             MethodHandle bccInvoker = CV_makeInjectedInvoker.get(hostClass);
-            return restoreToType(bccInvoker.bindTo(vamh), mh.type(), mh.internalMemberName(), hostClass);
+            return restoreToType(bccInvoker.bindTo(vamh), mh, hostClass);
         }
 
         private static MethodHandle makeInjectedInvoker(Class<?> hostClass) {
@@ -899,12 +899,14 @@
         }
 
         // Undo the adapter effect of prepareForInvoker:
-        private static MethodHandle restoreToType(MethodHandle vamh, MethodType type,
-                                                  MemberName member,
+        private static MethodHandle restoreToType(MethodHandle vamh,
+                                                  MethodHandle original,
                                                   Class<?> hostClass) {
+            MethodType type = original.type();
             MethodHandle mh = vamh.asCollector(Object[].class, type.parameterCount());
+            MemberName member = original.internalMemberName();
             mh = mh.asType(type);
-            mh = new WrappedMember(mh, type, member, hostClass);
+            mh = new WrappedMember(mh, type, member, original.isInvokeSpecial(), hostClass);
             return mh;
         }
 
@@ -974,12 +976,16 @@
         private final MethodHandle target;
         private final MemberName member;
         private final Class<?> callerClass;
+        private final boolean isInvokeSpecial;
 
-        private WrappedMember(MethodHandle target, MethodType type, MemberName member, Class<?> callerClass) {
+        private WrappedMember(MethodHandle target, MethodType type,
+                              MemberName member, boolean isInvokeSpecial,
+                              Class<?> callerClass) {
             super(type, reinvokerForm(target));
             this.target = target;
             this.member = member;
             this.callerClass = callerClass;
+            this.isInvokeSpecial = isInvokeSpecial;
         }
 
         @Override
@@ -1002,7 +1008,7 @@
         }
         @Override
         boolean isInvokeSpecial() {
-            return target.isInvokeSpecial();
+            return isInvokeSpecial;
         }
 
         @Override
@@ -1011,10 +1017,10 @@
         }
     }
 
-    static MethodHandle makeWrappedMember(MethodHandle target, MemberName member) {
-        if (member.equals(target.internalMemberName()))
+    static MethodHandle makeWrappedMember(MethodHandle target, MemberName member, boolean isInvokeSpecial) {
+        if (member.equals(target.internalMemberName()) && isInvokeSpecial == target.isInvokeSpecial())
             return target;
-        return new WrappedMember(target, target.type(), member, null);
+        return new WrappedMember(target, target.type(), member, isInvokeSpecial, null);
     }
 
     /// Collection of multiple arguments.