Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/lang/invoke/ThrowExceptionsTest.java
47209 views
/*1* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* @test24* @summary unit tests for method handles which permute their arguments25* @run testng test.java.lang.invoke.ThrowExceptionsTest26*/2728package test.java.lang.invoke;2930import org.testng.*;31import org.testng.annotations.*;3233import java.util.*;34import java.lang.reflect.*;3536import java.lang.invoke.*;37import static java.lang.invoke.MethodHandles.*;38import static java.lang.invoke.MethodType.*;3940public class ThrowExceptionsTest {41private static final Class<?> CLASS = ThrowExceptionsTest.class;42private static final Lookup LOOKUP = lookup();4344public static void main(String argv[]) throws Throwable {45new ThrowExceptionsTest().testAll((argv.length == 0 ? null : Arrays.asList(argv).toString()));46}4748@Test49public void testWMT() throws Throwable {50// mostly call testWMTCallee, but sometimes call its void-returning variant51MethodHandle mh = testWMTCallee();52MethodHandle mh1 = mh.asType(mh.type().changeReturnType(void.class));53assert(mh1 != mh);54testWMT(mh, mh1, 1000);55}5657@Test58public void testBoundWMT() throws Throwable {59// mostly call exactInvoker.bindTo(testWMTCallee), but sometimes call its void-returning variant60MethodHandle callee = testWMTCallee();61MethodHandle callee1 = callee.asType(callee.type().changeReturnType(void.class));62MethodHandle invoker = exactInvoker(callee.type());63MethodHandle mh = invoker.bindTo(callee);64MethodHandle mh1 = invoker.bindTo(callee1);65testWMT(mh, mh1, 1000);66}6768@Test69public void testFoldWMT() throws Throwable {70// mostly call exactInvoker.fold(constant(testWMTCallee)), but sometimes call its void-returning variant71MethodHandle callee = testWMTCallee();72MethodHandle callee1 = callee.asType(callee.type().changeReturnType(void.class));73MethodHandle invoker = exactInvoker(callee.type());74MethodHandle mh = foldArguments(invoker, constant(MethodHandle.class, callee));75MethodHandle mh1 = foldArguments(invoker, constant(MethodHandle.class, callee1));76testWMT(mh, mh1, 1000);77}7879@Test80public void testFoldCCE() throws Throwable {81MethodHandle callee = testWMTCallee();82MethodHandle callee1 = callee.asType(callee.type().changeParameterType(1, Number.class)).asType(callee.type());83MethodHandle invoker = exactInvoker(callee.type());84MethodHandle mh = foldArguments(invoker, constant(MethodHandle.class, callee));85MethodHandle mh1 = foldArguments(invoker, constant(MethodHandle.class, callee1));86testWMT(mh, mh1, 1000);87}8889@Test90public void testStackOverflow() throws Throwable {91MethodHandle callee = testWMTCallee();92MethodHandle callee1 = makeStackOverflow().asType(callee.type());93MethodHandle invoker = exactInvoker(callee.type());94MethodHandle mh = foldArguments(invoker, constant(MethodHandle.class, callee));95MethodHandle mh1 = foldArguments(invoker, constant(MethodHandle.class, callee1));96for (int i = 0; i < REPEAT; i++) {97try {98testWMT(mh, mh1, 1000);99} catch (StackOverflowError ex) {100// OK, try again101}102}103}104105private static MethodHandle makeStackOverflow() {106MethodType cellType = methodType(void.class);107MethodHandle[] cell = { null }; // recursion point108MethodHandle getCell = insertArguments(arrayElementGetter(cell.getClass()), 0, cell, 0);109MethodHandle invokeCell = foldArguments(exactInvoker(cellType), getCell);110assert(invokeCell.type() == cellType);111cell[0] = invokeCell;112// make it conformable to any type:113invokeCell = dropArguments(invokeCell, 0, Object[].class).asVarargsCollector(Object[].class);114return invokeCell;115}116117static int testCases;118119private void testAll(String match) throws Throwable {120testCases = 0;121Lookup lookup = lookup();122for (Method m : CLASS.getDeclaredMethods()) {123String name = m.getName();124if (name.startsWith("test") &&125(match == null || match.contains(name.substring("test".length()))) &&126m.getParameterTypes().length == 0 &&127Modifier.isPublic(m.getModifiers()) &&128!Modifier.isStatic(m.getModifiers())) {129System.out.println("["+name+"]");130int tc = testCases;131try {132m.invoke(this);133} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {134System.out.println("*** "+ex);135ex.printStackTrace(System.out);136}137if (testCases == tc) testCases++;138}139}140if (testCases == 0) throw new RuntimeException("no test cases found");141System.out.println("ran a total of "+testCases+" test cases");142}143144private static MethodHandle findStatic(String name) {145return findMethod(name, true);146}147private static MethodHandle findVirtual(String name) {148return findMethod(name, false);149}150private static MethodHandle findMethod(String name, boolean isStatic) {151MethodHandle mh = null;152for (Method m : CLASS.getDeclaredMethods()) {153if (m.getName().equals(name) &&154Modifier.isStatic(m.getModifiers()) == isStatic) {155if (mh != null)156throw new RuntimeException("duplicate methods: "+name);157try {158mh = LOOKUP.unreflect(m);159} catch (ReflectiveOperationException ex) {160throw new RuntimeException(ex);161}162}163}164if (mh == null)165throw new RuntimeException("no method: "+name);166return mh;167}168169int testWMTCallee;170private int testWMTCallee(String x) {171return testWMTCallee++;172}173private static MethodHandle testWMTCallee() {174MethodHandle callee = findVirtual("testWMTCallee");175// FIXME: should not have to retype callee176callee = callee.asType(callee.type().changeParameterType(0, Object.class));177return callee;178}179180private Exception testWMT(MethodHandle[] mhs, int reps) throws Throwable {181testCases += 1;182testWMTCallee = 0;183int catches = 0;184Exception savedEx = null;185for (int i = 0; i < reps; i++) {186MethodHandle mh = mhs[i % mhs.length];187int n;188try {189// FIXME: should not have to retype this190n = (int) mh.invokeExact((Object)this, "x");191assertEquals(n, i - catches);192// Using the exact type for this causes endless deopt due to193// 'non_cached_result' in SystemDictionary::find_method_handle_invoke.194// The problem is that the compiler thread needs to access a cached195// invoke method, but invoke methods are not cached if one of the196// component types is not on the BCP.197} catch (Exception ex) {198savedEx = ex;199catches++;200}201}202//VERBOSE: System.out.println("reps="+reps+" catches="+catches);203return savedEx;204}205206private static final int REPEAT = Integer.getInteger(CLASS.getSimpleName()+".REPEAT", 10);207208private Exception testWMT(MethodHandle mh, MethodHandle mh1, int reps) throws Throwable {209//VERBOSE: System.out.println("mh="+mh+" mh1="+mh1);210MethodHandle[] mhs = new MethodHandle[100];211Arrays.fill(mhs, mh);212int patch = mhs.length-1;213Exception savedEx = null;214for (int i = 0; i < REPEAT; i++) {215mhs[patch] = mh;216testWMT(mhs, 10000);217mhs[patch] = mh1;218savedEx = testWMT(mhs, reps);219}220return savedEx;221}222223private static void assertEquals(Object x, Object y) {224if (x == y || x != null && x.equals(y)) return;225throw new RuntimeException(x+" != "+y);226}227}228229230