From 9d59eb2da17cfd0691d4c83c5d9cde2e6e3178e3 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Tue, 11 Mar 2014 19:54:33 +0400 Subject: [PATCH] 8036117: MethodHandles.catchException doesn't handle VarargsCollector right (8034120 failed) Reviewed-by: jrose, twisti --- .../java/lang/invoke/MethodHandleImpl.java | 7 +- .../MethodHandles/TestCatchException.java | 72 ++++++++++++++++--- 2 files changed, 67 insertions(+), 12 deletions(-) diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java index e2dbfc852b0..cdf6e5a75ce 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -736,16 +736,17 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; @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 --git a/jdk/test/java/lang/invoke/MethodHandles/TestCatchException.java b/jdk/test/java/lang/invoke/MethodHandles/TestCatchException.java index 8f1abfc83d8..8197129b870 100644 --- a/jdk/test/java/lang/invoke/MethodHandles/TestCatchException.java +++ b/jdk/test/java/lang/invoke/MethodHandles/TestCatchException.java @@ -72,19 +72,55 @@ public class TestCatchException { 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 @@ public class TestCatchException { 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); + + 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 r1 = target.invokeExact(o, o, o, o, o, o, o, o, obj1); Object r2 = gwc.invokeExact(o, o, o, o, o, o, o, o, obj1); - assertEquals(r1, obj1); assertEquals(r2, obj1); } @@ -110,7 +163,8 @@ public class TestCatchException { TestCatchException test = new TestCatchException(); test.testNoThrowPath(); test.testThrowPath(); - test.testVarargsCollector(); + test.testVarargsCollectorNoThrow(); + test.testVarargsCollectorThrow(); System.out.println("TEST PASSED"); } }