Path: blob/master/test/jdk/java/lang/invoke/MethodHandlesAsCollectorTest.java
41149 views
/*1* Copyright (c) 2018, 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 java.lang.invoke.MethodHandles25* @library /test/lib /java/lang/invoke/common26* @compile MethodHandlesTest.java MethodHandlesAsCollectorTest.java remote/RemoteExample.java27* @run junit/othervm/timeout=2500 -XX:+IgnoreUnrecognizedVMOptions28* -XX:-VerifyDependencies29* -esa30* test.java.lang.invoke.MethodHandlesAsCollectorTest31*/3233package test.java.lang.invoke;3435import org.junit.*;36import test.java.lang.invoke.lib.CodeCacheOverflowProcessor;3738import java.lang.invoke.MethodHandle;39import java.lang.invoke.MethodType;40import java.util.Arrays;4142import static org.junit.Assert.*;4344public class MethodHandlesAsCollectorTest extends MethodHandlesTest {4546@Test // SLOW47public void testAsCollector() throws Throwable {48CodeCacheOverflowProcessor.runMHTest(this::testAsCollector0);49CodeCacheOverflowProcessor.runMHTest(this::testAsCollector1);50}5152public void testAsCollector0() throws Throwable {53if (CAN_SKIP_WORKING) return;54startTest("asCollector");55for (Class<?> argType : new Class<?>[]{Object.class, Integer.class, int.class}) {56if (verbosity >= 3)57System.out.println("asCollector "+argType);58for (int nargs = 0; nargs < 50; nargs++) {59if (CAN_TEST_LIGHTLY && nargs > 11) break;60for (int pos = 0; pos <= nargs; pos++) {61if (CAN_TEST_LIGHTLY && pos > 2 && pos < nargs-2) continue;62if (nargs > 10 && pos > 4 && pos < nargs-4 && pos % 10 != 3)63continue;64testAsCollector(argType, pos, nargs);65}66}67}68}6970public void testAsCollector(Class<?> argType, int pos, int nargs) throws Throwable {71countTest();72// fake up a MH with the same type as the desired adapter:73MethodHandle fake = varargsArray(nargs);74fake = changeArgTypes(fake, argType);75MethodType newType = fake.type();76Object[] args = randomArgs(newType.parameterArray());77// here is what should happen:78Object[] collectedArgs = Arrays.copyOfRange(args, 0, pos+1);79collectedArgs[pos] = Arrays.copyOfRange(args, pos, args.length);80// here is the MH which will witness the collected argument tail:81MethodHandle target = varargsArray(pos+1);82target = changeArgTypes(target, 0, pos, argType);83target = changeArgTypes(target, pos, pos+1, Object[].class);84if (verbosity >= 3)85System.out.println("collect from "+Arrays.asList(args)+" ["+pos+".."+nargs+"]");86MethodHandle result = target.asCollector(Object[].class, nargs-pos).asType(newType);87Object[] returnValue = (Object[]) result.invokeWithArguments(args);88assertArrayEquals(collectedArgs, returnValue);89}9091public void testAsCollector1() throws Throwable {92if (CAN_SKIP_WORKING) return;93startTest("asCollector/pos");94for (Class<?> argType : new Class<?>[]{Object.class, Integer.class, int.class}) {95if (verbosity >= 3)96System.out.println("asCollector/pos "+argType);97for (int nargs = 0; nargs < 50; nargs++) {98if (CAN_TEST_LIGHTLY && nargs > 11) break;99for (int pos = 0; pos <= nargs; pos++) {100if (CAN_TEST_LIGHTLY && pos > 2 && pos < nargs-2) continue;101if (nargs > 10 && pos > 4 && pos < nargs-4 && pos % 10 != 3)102continue;103for (int coll = 1; coll < nargs - pos; ++coll) {104if (coll > 4 && coll != 7 && coll != 11 && coll != 20 && coll < nargs - pos - 4) continue;105testAsCollector(argType, pos, coll, nargs);106}107}108}109}110}111112public void testAsCollector(Class<?> argType, int pos, int collect, int nargs) throws Throwable {113countTest();114// fake up a MH with the same type as the desired adapter:115MethodHandle fake = varargsArray(nargs);116fake = changeArgTypes(fake, argType);117MethodType newType = fake.type();118Object[] args = randomArgs(newType.parameterArray());119// here is what should happen:120// new arg list has "collect" less arguments, but one extra for collected arguments array121int collectedLength = nargs-(collect-1);122Object[] collectedArgs = new Object[collectedLength];123System.arraycopy(args, 0, collectedArgs, 0, pos);124collectedArgs[pos] = Arrays.copyOfRange(args, pos, pos+collect);125System.arraycopy(args, pos+collect, collectedArgs, pos+1, args.length-(pos+collect));126// here is the MH which will witness the collected argument part (not tail!):127MethodHandle target = varargsArray(collectedLength);128target = changeArgTypes(target, 0, pos, argType);129target = changeArgTypes(target, pos, pos+1, Object[].class);130target = changeArgTypes(target, pos+1, collectedLength, argType);131if (verbosity >= 3)132System.out.println("collect "+collect+" from "+Arrays.asList(args)+" ["+pos+".."+(pos+collect)+"[");133MethodHandle result = target.asCollector(pos, Object[].class, collect).asType(newType);134Object[] returnValue = (Object[]) result.invokeWithArguments(args);135assertArrayEquals(collectedArgs, returnValue);136}137}138139140