From adb9b34ef2689a86057ccdce73b6a92513067083 Mon Sep 17 00:00:00 2001 From: vlivanov Date: Wed, 10 Sep 2014 18:34:03 +0400 Subject: [PATCH] 8050174: Support overriding of isInvokeSpecial flag in WrappedMember Reviewed-by: vlivanov, psandoz Contributed-by: john.r.rose@oracle.com --- .../classes/java/lang/invoke/Invokers.java | 2 +- .../java/lang/invoke/MethodHandle.java | 4 +-- .../java/lang/invoke/MethodHandleImpl.java | 26 ++++++++++++------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/share/classes/java/lang/invoke/Invokers.java b/src/share/classes/java/lang/invoke/Invokers.java index e0fb4631d..a0b6f6d83 100644 --- a/src/share/classes/java/lang/invoke/Invokers.java +++ b/src/share/classes/java/lang/invoke/Invokers.java @@ -107,7 +107,7 @@ class Invokers { 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; diff --git a/src/share/classes/java/lang/invoke/MethodHandle.java b/src/share/classes/java/lang/invoke/MethodHandle.java index 71df51509..fc12f21d6 100644 --- a/src/share/classes/java/lang/invoke/MethodHandle.java +++ b/src/share/classes/java/lang/invoke/MethodHandle.java @@ -1356,9 +1356,9 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString()); } /*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; diff --git a/src/share/classes/java/lang/invoke/MethodHandleImpl.java b/src/share/classes/java/lang/invoke/MethodHandleImpl.java index 0ac175fba..3913a77d7 100644 --- a/src/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/src/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -807,7 +807,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; 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 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; 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 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; } // 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 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; 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 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; } @Override boolean isInvokeSpecial() { - return target.isInvokeSpecial(); + return isInvokeSpecial; } @Override @@ -1011,10 +1017,10 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; } } - 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. -- GitLab