Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/lang/invoke/InvokeDynamicPrintArgs.java
47216 views
/*1* Copyright (c) 2010, 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* @bug 7050328 800703525* @summary smoke test for invokedynamic instructions26* @build indify.Indify27* @compile InvokeDynamicPrintArgs.java28* @run main/othervm29* indify.Indify30* --verify-specifier-count=331* --expand-properties --classpath ${test.classes}32* --java test.java.lang.invoke.InvokeDynamicPrintArgs --check-output33* @run main/othervm34* indify.Indify35* --expand-properties --classpath ${test.classes}36* --java test.java.lang.invoke.InvokeDynamicPrintArgs --security-manager37*/3839package test.java.lang.invoke;4041import java.util.*;42import java.io.*;4344import java.lang.invoke.*;45import java.security.*;46import static java.lang.invoke.MethodHandles.*;47import static java.lang.invoke.MethodType.*;4849public class InvokeDynamicPrintArgs {50public static void main(String... av) throws Throwable {51if (av.length > 0 && av[0].equals("--check-output")) openBuf();52if (av.length > 0 && av[0].equals("--security-manager")) setSM();53System.out.println("Printing some argument lists, starting with a empty one:");54INDY_nothing().invokeExact(); // BSM specifier #0 = {bsm}55INDY_bar().invokeExact("bar arg", 1); // BSM specifier #1 = {bsm2, Void.class, "void type"}56INDY_bar2().invokeExact("bar2 arg", 222); // BSM specifier #1 = (same)57INDY_baz().invokeExact("baz arg", 2, 3.14); // BSM specifier #2 = {bsm2, 1234.5}58INDY_foo().invokeExact("foo arg"); // BSM specifier #0 = (same)59// Hence, BSM specifier count should be 3. See "--verify-specifier-count=3" above.60System.out.println("Done printing argument lists.");61closeBuf();62checkConstantRefs();63}6465private static void checkConstantRefs() throws Throwable {66// check some constant references to its self class67assertEquals(MT_bsm(), MH_bsm().type());68assertEquals(MT_bsm2(), MH_bsm2().type());69assertEquals(MT_bsm(), non_MH_bsm().type());70}71private static void assertEquals(Object exp, Object act) {72if (exp == act || (exp != null && exp.equals(act))) return;73throw new AssertionError("not equal: "+exp+", "+act);74}7576private static void setSM() {77Policy.setPolicy(new TestPolicy());78System.setSecurityManager(new SecurityManager());79}8081private static PrintStream oldOut;82private static ByteArrayOutputStream buf;83private static void openBuf() {84oldOut = System.out;85buf = new ByteArrayOutputStream();86System.setOut(new PrintStream(buf));87}88private static void closeBuf() {89if (buf == null) return;90System.out.flush();91System.setOut(oldOut);92String[] haveLines = new String(buf.toByteArray()).split("[\n\r]+");93for (String line : haveLines) System.out.println(line);94Iterator<String> iter = Arrays.asList(haveLines).iterator();95for (String want : EXPECT_OUTPUT) {96String have = iter.hasNext() ? iter.next() : "[EOF]";97if (want.equals(have)) continue;98System.err.println("want line: "+want);99System.err.println("have line: "+have);100throw new AssertionError("unexpected output: "+have);101}102if (iter.hasNext())103throw new AssertionError("unexpected output: "+iter.next());104}105private static final String[] EXPECT_OUTPUT = {106"Printing some argument lists, starting with a empty one:",107"[test.java.lang.invoke.InvokeDynamicPrintArgs, nothing, ()void][]",108"[test.java.lang.invoke.InvokeDynamicPrintArgs, bar, (String,int)void, class java.lang.Void, void type!, 1, 234.5, 67.5, 89][bar arg, 1]",109"[test.java.lang.invoke.InvokeDynamicPrintArgs, bar2, (String,int)void, class java.lang.Void, void type!, 1, 234.5, 67.5, 89][bar2 arg, 222]",110"[test.java.lang.invoke.InvokeDynamicPrintArgs, baz, (String,int,double)void, 1234.5][baz arg, 2, 3.14]",111"[test.java.lang.invoke.InvokeDynamicPrintArgs, foo, (String)void][foo arg]",112"Done printing argument lists."113};114115private static boolean doPrint = true;116private static void printArgs(Object bsmInfo, Object... args) {117String message = bsmInfo+Arrays.deepToString(args);118if (doPrint) System.out.println(message);119}120private static MethodHandle MH_printArgs() throws ReflectiveOperationException {121shouldNotCallThis();122return lookup().findStatic(lookup().lookupClass(),123"printArgs", methodType(void.class, Object.class, Object[].class));124}125126private static CallSite bsm(Lookup caller, String name, MethodType type) throws ReflectiveOperationException {127// ignore caller and name, but match the type:128Object bsmInfo = Arrays.asList(caller, name, type);129return new ConstantCallSite(MH_printArgs().bindTo(bsmInfo).asCollector(Object[].class, type.parameterCount()).asType(type));130}131private static MethodType MT_bsm() {132shouldNotCallThis();133return methodType(CallSite.class, Lookup.class, String.class, MethodType.class);134}135private static MethodHandle MH_bsm() throws ReflectiveOperationException {136shouldNotCallThis();137return lookup().findStatic(lookup().lookupClass(), "bsm", MT_bsm());138}139private static MethodHandle non_MH_bsm() throws ReflectiveOperationException {140return lookup().findStatic(lookup().lookupClass(), "bsm", MT_bsm());141}142143/* Example of a constant call site with user-data.144* In this case, the user data is exactly the BSM data.145* Note that a CCS with user data must use the "hooked" constructor146* to bind the CCS itself into the resulting target.147* A normal constructor would not allow a circular relation148* between the CCS and its target.149*/150public static class PrintingCallSite extends ConstantCallSite {151final Lookup caller;152final String name;153final Object[] staticArgs;154155PrintingCallSite(Lookup caller, String name, MethodType type, Object... staticArgs) throws Throwable {156super(type, MH_createTarget());157this.caller = caller;158this.name = name;159this.staticArgs = staticArgs;160}161162public MethodHandle createTarget() {163try {164return lookup().bind(this, "runTarget", genericMethodType(0, true)).asType(type());165} catch (ReflectiveOperationException ex) {166throw new RuntimeException(ex);167}168}169170public Object runTarget(Object... dynamicArgs) {171List<Object> bsmInfo = new ArrayList<>(Arrays.asList(caller, name, type()));172bsmInfo.addAll(Arrays.asList(staticArgs));173printArgs(bsmInfo, dynamicArgs);174return null;175}176177private static MethodHandle MH_createTarget() throws ReflectiveOperationException {178shouldNotCallThis();179return lookup().findVirtual(lookup().lookupClass(), "createTarget", methodType(MethodHandle.class));180}181}182private static CallSite bsm2(Lookup caller, String name, MethodType type, Object... arg) throws Throwable {183// ignore caller and name, but match the type:184return new PrintingCallSite(caller, name, type, arg);185}186private static MethodType MT_bsm2() {187shouldNotCallThis();188return methodType(CallSite.class, Lookup.class, String.class, MethodType.class, Object[].class);189}190private static MethodHandle MH_bsm2() throws ReflectiveOperationException {191shouldNotCallThis();192return lookup().findStatic(lookup().lookupClass(), "bsm2", MT_bsm2());193}194195private static MethodHandle INDY_nothing() throws Throwable {196shouldNotCallThis();197return ((CallSite) MH_bsm().invoke(lookup(),198"nothing", methodType(void.class)199)).dynamicInvoker();200}201private static MethodHandle INDY_foo() throws Throwable {202shouldNotCallThis();203return ((CallSite) MH_bsm().invoke(lookup(),204"foo", methodType(void.class, String.class)205)).dynamicInvoker();206}207private static MethodHandle INDY_bar() throws Throwable {208shouldNotCallThis();209return ((CallSite) MH_bsm2().invoke(lookup(),210"bar", methodType(void.class, String.class, int.class)211, Void.class, "void type!", 1, 234.5F, 67.5, (long)89212)).dynamicInvoker();213}214private static MethodHandle INDY_bar2() throws Throwable {215shouldNotCallThis();216return ((CallSite) MH_bsm2().invoke(lookup(),217"bar2", methodType(void.class, String.class, int.class)218, Void.class, "void type!", 1, 234.5F, 67.5, (long)89219)).dynamicInvoker();220}221private static MethodHandle INDY_baz() throws Throwable {222shouldNotCallThis();223return ((CallSite) MH_bsm2().invoke(lookup(),224"baz", methodType(void.class, String.class, int.class, double.class)225, 1234.5226)).dynamicInvoker();227}228229private static void shouldNotCallThis() {230// if this gets called, the transformation has not taken place231if (System.getProperty("InvokeDynamicPrintArgs.allow-untransformed") != null) return;232throw new AssertionError("this code should be statically transformed away by Indify");233}234235static class TestPolicy extends Policy {236final PermissionCollection permissions = new Permissions();237TestPolicy() {238permissions.add(new java.io.FilePermission("<<ALL FILES>>", "read"));239}240public PermissionCollection getPermissions(ProtectionDomain domain) {241return permissions;242}243244public PermissionCollection getPermissions(CodeSource codesource) {245return permissions;246}247248public boolean implies(ProtectionDomain domain, Permission perm) {249return permissions.implies(perm);250}251}252}253254255