Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/lang/invoke/7087570/Test7087570.java
47311 views
/*1* Copyright (c) 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*22*/2324/* @test25* @bug 708757026* @summary REF_invokeSpecial DMHs (which are unusual) get marked explicitly; tweak the MHI to use this bit27*28* @run main Test708757029*/3031import java.lang.invoke.*;32import java.lang.reflect.*;33import java.util.*;3435import static java.lang.invoke.MethodHandles.*;36import static java.lang.invoke.MethodType.*;37import static java.lang.invoke.MethodHandleInfo.*;3839public class Test7087570 {4041private static final TestMethodData[] TESTS = new TestMethodData[] {42// field accessors43data(DummyFieldHolder.class, "instanceField", getterMethodType(String.class), DummyFieldHolder.class, REF_getField),44data(DummyFieldHolder.class, "instanceField", setterMethodType(String.class), DummyFieldHolder.class, REF_putField),45data(DummyFieldHolder.class, "staticField", getterMethodType(Integer.class), DummyFieldHolder.class, REF_getStatic),46data(DummyFieldHolder.class, "staticField", setterMethodType(Integer.class), DummyFieldHolder.class, REF_putStatic),47data(DummyFieldHolder.class, "instanceByteField", getterMethodType(byte.class), DummyFieldHolder.class, REF_getField),48data(DummyFieldHolder.class, "instanceByteField", setterMethodType(byte.class), DummyFieldHolder.class, REF_putField),4950// REF_invokeVirtual51data(Object.class, "hashCode", methodType(int.class), Object.class, REF_invokeVirtual),5253// REF_invokeVirtual strength-reduced to REF_invokeSpecial,54// test if it normalizes back to REF_invokeVirtual in MethodHandleInfo as expected55data(String.class, "hashCode", methodType(int.class), String.class, REF_invokeVirtual),5657// REF_invokeStatic58data(Collections.class, "sort", methodType(void.class, List.class), Collections.class, REF_invokeStatic),59data(Arrays.class, "asList", methodType(List.class, Object[].class), Arrays.class, REF_invokeStatic), // varargs case6061// REF_invokeSpecial62data(Object.class, "hashCode", methodType(int.class), Object.class, REF_invokeSpecial),6364// REF_newInvokeSpecial65data(String.class, "<init>", methodType(void.class, char[].class), String.class, REF_newInvokeSpecial),66data(DummyFieldHolder.class, "<init>", methodType(void.class, byte.class, Long[].class), DummyFieldHolder.class, REF_newInvokeSpecial), // varargs case6768// REF_invokeInterface69data(List.class, "size", methodType(int.class), List.class, REF_invokeInterface)70};7172public static void main(String... args) throws Throwable {73testWithLookup();74testWithUnreflect();75}7677private static void doTest(MethodHandle mh, TestMethodData testMethod) {78MethodHandleInfo mhi = LOOKUP.revealDirect(mh);7980System.out.printf("%s.%s: %s, nominal refKind: %s, actual refKind: %s\n",81testMethod.clazz.getName(), testMethod.name, testMethod.methodType,82referenceKindToString(testMethod.referenceKind),83referenceKindToString(mhi.getReferenceKind()));84assertEquals(testMethod.name, mhi.getName());85assertEquals(testMethod.methodType, mhi.getMethodType());86assertEquals(testMethod.declaringClass, mhi.getDeclaringClass());87assertEquals(testMethod.referenceKind == REF_invokeSpecial, isInvokeSpecial(mh));88assertRefKindEquals(testMethod.referenceKind, mhi.getReferenceKind());89}9091private static void testWithLookup() throws Throwable {92for (TestMethodData testMethod : TESTS) {93MethodHandle mh = lookupFrom(testMethod);94doTest(mh, testMethod);95}96}9798private static void testWithUnreflect() throws Throwable {99for (TestMethodData testMethod : TESTS) {100MethodHandle mh = unreflectFrom(testMethod);101doTest(mh, testMethod);102}103}104105private static MethodType getterMethodType(Class<?> clazz) {106return methodType(clazz);107}108109private static MethodType setterMethodType(Class<?> clazz) {110return methodType(void.class, clazz);111}112113private static final Lookup LOOKUP = lookup();114115private static class TestMethodData {116final Class<?> clazz;117final String name;118final MethodType methodType;119final Class<?> declaringClass;120final int referenceKind; // the nominal refKind121122public TestMethodData(Class<?> clazz, String name,123MethodType methodType, Class<?> declaringClass,124int referenceKind) {125this.clazz = clazz;126this.name = name;127this.methodType = methodType;128this.declaringClass = declaringClass;129this.referenceKind = referenceKind;130}131}132133private static TestMethodData data(Class<?> clazz, String name,134MethodType methodType, Class<?> declaringClass,135int referenceKind) {136return new TestMethodData(clazz, name, methodType, declaringClass, referenceKind);137}138139private static MethodHandle lookupFrom(TestMethodData testMethod)140throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException {141switch (testMethod.referenceKind) {142case REF_getField:143return LOOKUP.findGetter(testMethod.clazz, testMethod.name, testMethod.methodType.returnType());144case REF_putField:145return LOOKUP.findSetter(testMethod.clazz, testMethod.name, testMethod.methodType.parameterType(0));146case REF_getStatic:147return LOOKUP.findStaticGetter(testMethod.clazz, testMethod.name, testMethod.methodType.returnType());148case REF_putStatic:149return LOOKUP.findStaticSetter(testMethod.clazz, testMethod.name, testMethod.methodType.parameterType(0));150case REF_invokeVirtual:151case REF_invokeInterface:152return LOOKUP.findVirtual(testMethod.clazz, testMethod.name, testMethod.methodType);153case REF_invokeStatic:154return LOOKUP.findStatic(testMethod.clazz, testMethod.name, testMethod.methodType);155case REF_invokeSpecial:156Class<?> thisClass = LOOKUP.lookupClass();157MethodHandle smh = LOOKUP.findSpecial(testMethod.clazz, testMethod.name, testMethod.methodType, thisClass);158noteInvokeSpecial(smh);159return smh;160case REF_newInvokeSpecial:161return LOOKUP.findConstructor(testMethod.clazz, testMethod.methodType);162default:163throw new Error("ERROR: unexpected referenceKind in test data");164}165}166167private static MethodHandle unreflectFrom(TestMethodData testMethod)168throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException {169switch (testMethod.referenceKind) {170case REF_getField:171case REF_getStatic: {172Field f = testMethod.clazz.getDeclaredField(testMethod.name);173return LOOKUP.unreflectGetter(f);174}175case REF_putField:176case REF_putStatic: {177Field f = testMethod.clazz.getDeclaredField(testMethod.name);178return LOOKUP.unreflectSetter(f);179}180case REF_invokeVirtual:181case REF_invokeStatic:182case REF_invokeInterface: {183Method m = testMethod.clazz.getDeclaredMethod(testMethod.name, testMethod.methodType.parameterArray());184return LOOKUP.unreflect(m);185}186case REF_invokeSpecial: {187Method m = testMethod.clazz.getDeclaredMethod(testMethod.name, testMethod.methodType.parameterArray());188Class<?> thisClass = LOOKUP.lookupClass();189MethodHandle smh = LOOKUP.unreflectSpecial(m, thisClass);190noteInvokeSpecial(smh);191return smh;192}193case REF_newInvokeSpecial: {194Constructor c = testMethod.clazz.getDeclaredConstructor(testMethod.methodType.parameterArray());195return LOOKUP.unreflectConstructor(c);196}197default:198throw new Error("ERROR: unexpected referenceKind in test data");199}200}201202private static List<MethodHandle> specialMethodHandles = new ArrayList<>();203private static void noteInvokeSpecial(MethodHandle mh) {204specialMethodHandles.add(mh);205assert(isInvokeSpecial(mh));206}207private static boolean isInvokeSpecial(MethodHandle mh) {208return specialMethodHandles.contains(mh);209}210211private static void assertRefKindEquals(int expect, int observed) {212if (expect == observed) return;213214String msg = "expected " + referenceKindToString(expect) +215" but observed " + referenceKindToString(observed);216System.out.println("FAILED: " + msg);217throw new AssertionError(msg);218}219220private static void assertEquals(Object expect, Object observed) {221if (java.util.Objects.equals(expect, observed)) return;222223String msg = "expected " + expect + " but observed " + observed;224System.out.println("FAILED: " + msg);225throw new AssertionError(msg);226}227}228229class DummyFieldHolder {230public static Integer staticField;231public String instanceField;232public byte instanceByteField;233234public DummyFieldHolder(byte unused1, Long... unused2) {235}236}237238239240