# HG changeset patch # User vlivanov # Date 1394553273 -14400 # Node ID 0a84d339822a9ca50d8578d9cce7845e969ea192 # Parent d4a11c730d92c3eef29e36bed6f61acfdcde849b 8036117: MethodHandles.catchException doesn't handle VarargsCollector right (8034120 failed) Reviewed-by: jrose, twisti diff -r d4a11c730d92 -r 0a84d339822a jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Tue Mar 11 14:18:46 2014 +0100 +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Tue Mar 11 19:54:33 2014 +0400 @@ -736,16 +736,17 @@ @LambdaForm.Hidden static Object guardWithCatch(MethodHandle target, Class exType, MethodHandle catcher, Object... av) throws Throwable { + // Use asFixedArity() to avoid unnecessary boxing of last argument for VarargsCollector case. try { - return target.invokeWithArguments(av); + return target.asFixedArity().invokeWithArguments(av); } catch (Throwable t) { if (!exType.isInstance(t)) throw t; - Object[] args = prepend(t, av); - return catcher.invokeWithArguments(args); + return catcher.asFixedArity().invokeWithArguments(prepend(t, av)); } } /** Prepend an element {@code elem} to an {@code array}. */ + @LambdaForm.Hidden private static Object[] prepend(Object elem, Object[] array) { Object[] newArray = new Object[array.length+1]; newArray[0] = elem; diff -r d4a11c730d92 -r 0a84d339822a jdk/test/java/lang/invoke/MethodHandles/TestCatchException.java --- a/jdk/test/java/lang/invoke/MethodHandles/TestCatchException.java Tue Mar 11 14:18:46 2014 +0100 +++ b/jdk/test/java/lang/invoke/MethodHandles/TestCatchException.java Tue Mar 11 19:54:33 2014 +0400 @@ -72,19 +72,55 @@ assertEquals(x, 17); } + final static Object masterParam = new Object(); + final static Object[] masterTail = new Object[] { "str" }; + static Exception masterEx = new Exception(); public static Object m1(Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object... tail) { + assertEquals(masterParam, o1); + assertEquals(masterParam, o2); + assertEquals(masterParam, o3); + assertEquals(masterParam, o4); + assertEquals(masterParam, o5); + assertEquals(masterParam, o6); + assertEquals(masterParam, o7); + assertEquals(masterParam, o8); + assertEquals(masterTail, tail); return tail; } public static Object m2(Exception e, Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object... tail) { + assertEquals(masterEx, e); + assertEquals(masterParam, o1); + assertEquals(masterParam, o2); + assertEquals(masterParam, o3); + assertEquals(masterParam, o4); + assertEquals(masterParam, o5); + assertEquals(masterParam, o6); + assertEquals(masterParam, o7); + assertEquals(masterParam, o8); + assertEquals(masterTail, tail); return tail; } + public static Object throwEx(Object o1, Object o2, Object o3, Object o4, Object o5, + Object o6, Object o7, Object o8, Object... tail) throws Exception { + assertEquals(masterParam, o1); + assertEquals(masterParam, o2); + assertEquals(masterParam, o3); + assertEquals(masterParam, o4); + assertEquals(masterParam, o5); + assertEquals(masterParam, o6); + assertEquals(masterParam, o7); + assertEquals(masterParam, o8); + assertEquals(masterTail, tail); + throw masterEx; + } + @Test - public void testVarargsCollector() throws Throwable { + public void testVarargsCollectorNoThrow() throws Throwable { MethodType t1 = MethodType.methodType(Object.class, Object.class, Object.class, Object.class, Object.class, Object.class, Object.class, Object.class, Object.class, Object[].class); @@ -92,17 +128,34 @@ MethodHandle target = LOOKUP.findStatic(TestCatchException.class, "m1", t1) .asVarargsCollector(Object[].class); - - MethodHandle catcher = LOOKUP.findStatic(TestCatchException.class, "m2", t2); - + MethodHandle catcher = LOOKUP.findStatic(TestCatchException.class, "m2", t2) + .asVarargsCollector(Object[].class); MethodHandle gwc = MethodHandles.catchException(target, Exception.class, catcher); - Object o = new Object(); - Object[] obj1 = new Object[] { "str" }; + Object o = masterParam; + Object[] obj1 = masterTail; + + Object r2 = gwc.invokeExact(o, o, o, o, o, o, o, o, obj1); + assertEquals(r2, obj1); + } + + @Test + public void testVarargsCollectorThrow() throws Throwable { + MethodType t1 = MethodType.methodType(Object.class, Object.class, Object.class, Object.class, Object.class, + Object.class, Object.class, Object.class, Object.class, Object[].class); - Object r1 = target.invokeExact(o, o, o, o, o, o, o, o, obj1); + MethodType t2 = t1.insertParameterTypes(0, Exception.class); + + MethodHandle target = LOOKUP.findStatic(TestCatchException.class, "throwEx", t1) + .asVarargsCollector(Object[].class); + MethodHandle catcher = LOOKUP.findStatic(TestCatchException.class, "m2", t2) + .asVarargsCollector(Object[].class); + MethodHandle gwc = MethodHandles.catchException(target, Exception.class, catcher); + + Object o = masterParam; + Object[] obj1 = masterTail; + Object r2 = gwc.invokeExact(o, o, o, o, o, o, o, o, obj1); - assertEquals(r1, obj1); assertEquals(r2, obj1); } @@ -110,7 +163,8 @@ TestCatchException test = new TestCatchException(); test.testNoThrowPath(); test.testThrowPath(); - test.testVarargsCollector(); + test.testVarargsCollectorNoThrow(); + test.testVarargsCollectorThrow(); System.out.println("TEST PASSED"); } }