--- old/src/java.base/share/classes/java/lang/invoke/MethodHandles.java 2017-10-03 06:49:50.691173830 -0400 +++ new/src/java.base/share/classes/java/lang/invoke/MethodHandles.java 2017-10-03 06:49:48.539050904 -0400 @@ -1395,13 +1395,7 @@ checkSpecialCaller(specialCaller, refc); Lookup specialLookup = this.in(specialCaller); MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type); - Class callerCls = findBoundCallerClass(method); - boolean restrict = !(method.isPrivate() && Reflection.areNestMates(specialCaller, refc)); - - if (restrict) - return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method, callerCls); - else - return specialLookup.getDirectMethodNoRestrictInvokeSpecial(refc, method, callerCls); + return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method, findBoundCallerClass(method)); } /** --- old/test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestMethodHandles.java 2017-10-03 06:49:56.943530954 -0400 +++ new/test/hotspot/jtreg/runtime/Nestmates/privateMethods/TestMethodHandles.java 2017-10-03 06:49:54.699402774 -0400 @@ -49,36 +49,53 @@ // Methods that will access private methods of nestmates void access_priv(TestMethodHandles o) throws Throwable { - MethodHandle mh = - lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, new StaticNested()); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + // findSpecial also works when this and o are the same class + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); mh.invoke(o); mh.invokeExact(o); checkBadInvoke(mh, new StaticNested()); // wrong nestmate checkBadInvoke(mh, mh); // completely wrong type } void access_priv(InnerNested o) throws Throwable { - MethodHandle mh = - lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); mh.invoke(o); mh.invokeExact(o); checkBadInvoke(mh, this); // wrong nestmate checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} } void access_priv(StaticNested o) throws Throwable { - MethodHandle mh = - lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); mh.invoke(o); mh.invokeExact(o); checkBadInvoke(mh, this); // wrong nestmate checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} } void access_priv(StaticIface o) throws Throwable { - MethodHandle mh = - lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, this.getClass()); + MethodHandle mh = lookup().findVirtual(StaticIface.class, "priv_invoke", M_T); mh.invoke(o); mh.invokeExact(o); checkBadInvoke(mh, this); // wrong nestmate checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} } // The various nestmates @@ -93,31 +110,49 @@ default void access_priv(TestMethodHandles o) throws Throwable { MethodHandle mh = - lookup().findSpecial(o.getClass(), "priv_invoke", M_T, StaticIface.class); + lookup().findVirtual(o.getClass(), "priv_invoke", M_T); mh.invoke(o); mh.invokeExact(o); checkBadInvoke(mh, this); // wrong nestmate checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} } default void access_priv(InnerNested o) throws Throwable { - MethodHandle mh = - lookup().findSpecial(o.getClass(), "priv_invoke", M_T, StaticIface.class); + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); mh.invoke(o); mh.invokeExact(o); checkBadInvoke(mh, this); // wrong nestmate checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} } default void access_priv(StaticNested o) throws Throwable { - MethodHandle mh = - lookup().findSpecial(o.getClass(), "priv_invoke", M_T, StaticIface.class); + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); mh.invoke(o); mh.invokeExact(o); checkBadInvoke(mh, this); // wrong nestmate checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} } default void access_priv(StaticIface o) throws Throwable { - MethodHandle mh = - lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, StaticIface.class); + MethodHandle mh = lookup().findVirtual(StaticIface.class, "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, new StaticNested()); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + // findSpecial also works when this and o are the same interface + mh = lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, StaticIface.class); mh.invoke(o); mh.invokeExact(o); checkBadInvoke(mh, new StaticNested()); // wrong nestmate @@ -137,36 +172,53 @@ // Methods that will access private methods of nestmates void access_priv(TestMethodHandles o) throws Throwable { - MethodHandle mh = - lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); mh.invoke(o); mh.invokeExact(o); checkBadInvoke(mh, this); // wrong nestmate checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} } void access_priv(InnerNested o) throws Throwable { - MethodHandle mh = - lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); mh.invoke(o); mh.invokeExact(o); checkBadInvoke(mh, this); // wrong nestmate checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} } void access_priv(StaticNested o) throws Throwable { - MethodHandle mh = - lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, new TestMethodHandles()); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + // findSpecial also works when this and o are the same class + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); mh.invoke(o); mh.invokeExact(o); checkBadInvoke(mh, new TestMethodHandles()); // wrong nestmate checkBadInvoke(mh, mh); // completely wrong type } void access_priv(StaticIface o) throws Throwable { - MethodHandle mh = - lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, this.getClass()); + MethodHandle mh = lookup().findVirtual(StaticIface.class, "priv_invoke", M_T); mh.invoke(o); mh.invokeExact(o); checkBadInvoke(mh, this); // wrong nestmate checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} } } @@ -180,36 +232,53 @@ public InnerNested() {} void access_priv(TestMethodHandles o) throws Throwable { - MethodHandle mh = - lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); mh.invoke(o); mh.invokeExact(o); checkBadInvoke(mh, this); // wrong nestmate checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} } void access_priv(InnerNested o) throws Throwable { - MethodHandle mh = - lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); + mh.invoke(o); + mh.invokeExact(o); + checkBadInvoke(mh, new StaticNested()); // wrong nestmate + checkBadInvoke(mh, mh); // completely wrong type + // findSpecial also works when this and o are the same class + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); mh.invoke(o); mh.invokeExact(o); checkBadInvoke(mh, new StaticNested()); // wrong nestmate checkBadInvoke(mh, mh); // completely wrong type } void access_priv(StaticNested o) throws Throwable { - MethodHandle mh = - lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + MethodHandle mh = lookup().findVirtual(o.getClass(), "priv_invoke", M_T); mh.invoke(o); mh.invokeExact(o); checkBadInvoke(mh, this); // wrong nestmate checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(o.getClass(), "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} } void access_priv(StaticIface o) throws Throwable { - MethodHandle mh = - lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, this.getClass()); + MethodHandle mh = lookup().findVirtual(StaticIface.class, "priv_invoke", M_T); mh.invoke(o); mh.invokeExact(o); checkBadInvoke(mh, this); // wrong nestmate checkBadInvoke(mh, mh); // completely wrong type + try { + mh = lookup().findSpecial(StaticIface.class, "priv_invoke", M_T, this.getClass()); + throw new Error("findSpecial() succeeded unexpectedly"); + } + catch (IllegalAccessException expected) {} } }