--- old/test/compiler/jvmci/common/testcases/MultipleAbstractImplementer.java 2016-02-18 13:37:23.347616081 +0300 +++ new/test/compiler/jvmci/common/testcases/MultipleAbstractImplementer.java 2016-02-18 13:37:23.251616083 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,13 +23,93 @@ package compiler.jvmci.common.testcases; +import java.util.HashMap; +import java.util.Map; + public abstract class MultipleAbstractImplementer implements MultipleImplementersInterface { + // Different access levels on the fields of this class are used on purpose. + // It is needed to verify jdk.vm.ci.CompilerToVM constant pool related + // methods, e.g. resolveFieldInPool. + + private static int intStaticField = INT_CONSTANT; + final static long longStaticField = LONG_CONSTANT; + volatile static float floatStaticField = FLOAT_CONSTANT; + static double doubleStaticField = DOUBLE_CONSTANT; + public static String stringStaticField = STRING_CONSTANT; + protected static Object objectStaticField = OBJECT_CONSTANT; + + public int intField = INT_CONSTANT; + private long longField = LONG_CONSTANT; + protected float floatField = FLOAT_CONSTANT; + transient double doubleField = DOUBLE_CONSTANT; + volatile String stringField = STRING_CONSTANT; + String stringFieldEmpty = ""; + final Object objectField; + + public MultipleAbstractImplementer() { + intField = Integer.MAX_VALUE; + longField = Long.MAX_VALUE; + floatField = Float.MAX_VALUE; + doubleField = Double.MAX_VALUE; + stringField = "Message"; + objectField = new Object(); + } + public abstract void abstractMethod(); @Override public void finalize() throws Throwable { super.finalize(); } + + public void lambdaUsingMethod2() { + Thread t = new Thread(this::testMethod); + t.start(); + } + + /** + * This method is needed to have "getstatic" and "getfield" instructions + * in the class. These instructions are needed to test + * resolveFieldInPool method, because it needs a bytecode as one of its arguments. + */ + public void printFileds() { + System.out.println(intStaticField); + System.out.println(longStaticField); + System.out.println(floatStaticField); + System.out.println(doubleStaticField); + System.out.println(stringStaticField); + System.out.println(objectStaticField); + System.out.println(intField); + System.out.println(longField); + System.out.println(floatField); + System.out.println(doubleField); + System.out.println(stringField); + System.out.println(stringFieldEmpty); + System.out.println(objectField); + } + + public static void staticMethod() { + System.getProperties(); // calling some static method + Map map = new HashMap(); // calling some constructor + map.put(OBJECT_CONSTANT, OBJECT_CONSTANT); // calling some interface method + map.remove(OBJECT_CONSTANT); // calling some default interface method + } + + @Override + public void instanceMethod() { + toString(); // calling some virtual method + super.toString(); // calling some special method + } + + @Override + public void anonClassMethod() { + new Runnable() { + @Override + public void run() { + System.out.println("Running"); + } + }.run(); + } } --- old/test/compiler/jvmci/common/testcases/MultipleImplementer2.java 2016-02-18 13:37:23.699616074 +0300 +++ new/test/compiler/jvmci/common/testcases/MultipleImplementer2.java 2016-02-18 13:37:23.611616076 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,11 +23,18 @@ package compiler.jvmci.common.testcases; +import java.util.HashMap; +import java.util.Map; + public class MultipleImplementer2 implements MultipleImplementersInterface { + // Different access levels on the fields of this class are used on purpose. + // It is needed to verify jdk.vm.ci.CompilerToVM constant pool related + // methods, e.g. resolveFieldInPool. + private static int intStaticField = INT_CONSTANT; - static long longStaticField = LONG_CONSTANT; - static float floatStaticField = FLOAT_CONSTANT; + final static long longStaticField = LONG_CONSTANT; + volatile static float floatStaticField = FLOAT_CONSTANT; static double doubleStaticField = DOUBLE_CONSTANT; public static String stringStaticField = STRING_CONSTANT; protected static Object objectStaticField = OBJECT_CONSTANT; @@ -35,9 +42,10 @@ public int intField = INT_CONSTANT; private long longField = LONG_CONSTANT; protected float floatField = FLOAT_CONSTANT; - double doubleField = DOUBLE_CONSTANT; - String stringField = STRING_CONSTANT; - Object objectField = OBJECT_CONSTANT; + transient double doubleField = DOUBLE_CONSTANT; + volatile String stringField = STRING_CONSTANT; + String stringFieldEmpty = ""; + final Object objectField; public MultipleImplementer2() { intField = Integer.MAX_VALUE; @@ -58,12 +66,52 @@ super.finalize(); } - public void interfaceMethodReferral2(MultipleImplementersInterface obj) { - obj.interfaceMethodReferral(obj); - } - public void lambdaUsingMethod2() { Thread t = new Thread(this::testMethod); t.start(); } + + /** + * This method is needed to have "getstatic" and "getfield" instructions + * in the class. These instructions are needed to test + * resolveFieldInPool method, because it needs a bytecode as one of its arguments. + */ + public void printFileds() { + System.out.println(intStaticField); + System.out.println(longStaticField); + System.out.println(floatStaticField); + System.out.println(doubleStaticField); + System.out.println(stringStaticField); + System.out.println(objectStaticField); + System.out.println(intField); + System.out.println(longField); + System.out.println(floatField); + System.out.println(doubleField); + System.out.println(stringField); + System.out.println(stringFieldEmpty); + System.out.println(objectField); + } + + public static void staticMethod() { + System.getProperties(); // calling some static method + Map map = new HashMap(); // calling some constructor + map.put(OBJECT_CONSTANT, OBJECT_CONSTANT); // calling some interface method + map.remove(OBJECT_CONSTANT); // calling some default interface method + } + + @Override + public void instanceMethod() { + toString(); // calling some virtual method + super.toString(); // calling some special method + } + + @Override + public void anonClassMethod() { + new Runnable() { + @Override + public void run() { + System.out.println("Running"); + } + }.run(); + } } --- old/test/compiler/jvmci/common/testcases/MultipleImplementersInterface.java 2016-02-18 13:37:23.975616069 +0300 +++ new/test/compiler/jvmci/common/testcases/MultipleImplementersInterface.java 2016-02-18 13:37:23.887616070 +0300 @@ -23,6 +23,9 @@ package compiler.jvmci.common.testcases; +import java.util.HashMap; +import java.util.Map; + public interface MultipleImplementersInterface { int INT_CONSTANT = Integer.MAX_VALUE; @@ -42,12 +45,34 @@ // empty } - default void interfaceMethodReferral(MultipleImplementersInterface obj) { - obj.defaultMethod(); - } - default void lambdaUsingMethod() { Thread t = new Thread(this::defaultMethod); t.start(); } + + default void printFields() { + System.out.println(OBJECT_CONSTANT); + String s = ""; + System.out.println(s); + } + + static void staticMethod() { + System.getProperties(); // calling some static method + Map map = new HashMap(); // calling some constructor + map.put(OBJECT_CONSTANT, OBJECT_CONSTANT); // calling some interface method + map.remove(OBJECT_CONSTANT); // calling some default interface method + } + + default void instanceMethod() { + toString(); // calling some virtual method + } + + default void anonClassMethod() { + new Runnable() { + @Override + public void run() { + System.out.println("Running"); + } + }.run(); + } } --- old/test/compiler/jvmci/compilerToVM/ConstantPoolTestCase.java 2016-02-18 13:37:24.271616063 +0300 +++ new/test/compiler/jvmci/compilerToVM/ConstantPoolTestCase.java 2016-02-18 13:37:24.179616064 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,118 +27,220 @@ import java.util.HashMap; import java.util.Map; import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; -import jdk.internal.misc.SharedSecrets; +import sun.hotspot.WhiteBox; import sun.reflect.ConstantPool; /** * Common class for jdk.vm.ci.hotspot.CompilerToVM constant pool tests */ public class ConstantPoolTestCase { - private final Map typeTests; + + private static final Map TAG_TO_TYPE_MAP; + static { + TAG_TO_TYPE_MAP = new HashMap<>(); + TAG_TO_TYPE_MAP.put(ConstantPool.Tag.CLASS, ConstantTypes.CONSTANT_CLASS); + TAG_TO_TYPE_MAP.put(ConstantPool.Tag.FIELDREF, ConstantTypes.CONSTANT_FIELDREF); + TAG_TO_TYPE_MAP.put(ConstantPool.Tag.METHODREF, ConstantTypes.CONSTANT_METHODREF); + TAG_TO_TYPE_MAP.put(ConstantPool.Tag.INTERFACEMETHODREF, ConstantTypes.CONSTANT_INTERFACEMETHODREF); + TAG_TO_TYPE_MAP.put(ConstantPool.Tag.STRING, ConstantTypes.CONSTANT_STRING); + TAG_TO_TYPE_MAP.put(ConstantPool.Tag.INTEGER, ConstantTypes.CONSTANT_INTEGER); + TAG_TO_TYPE_MAP.put(ConstantPool.Tag.FLOAT, ConstantTypes.CONSTANT_FLOAT); + TAG_TO_TYPE_MAP.put(ConstantPool.Tag.LONG, ConstantTypes.CONSTANT_LONG); + TAG_TO_TYPE_MAP.put(ConstantPool.Tag.DOUBLE, ConstantTypes.CONSTANT_DOUBLE); + TAG_TO_TYPE_MAP.put(ConstantPool.Tag.NAMEANDTYPE, ConstantTypes.CONSTANT_NAMEANDTYPE); + TAG_TO_TYPE_MAP.put(ConstantPool.Tag.UTF8, ConstantTypes.CONSTANT_UTF8); + TAG_TO_TYPE_MAP.put(ConstantPool.Tag.METHODHANDLE, ConstantTypes.CONSTANT_METHODHANDLE); + TAG_TO_TYPE_MAP.put(ConstantPool.Tag.METHODTYPE, ConstantTypes.CONSTANT_METHODTYPE); + TAG_TO_TYPE_MAP.put(ConstantPool.Tag.INVOKEDYNAMIC, ConstantTypes.CONSTANT_INVOKEDYNAMIC); + TAG_TO_TYPE_MAP.put(ConstantPool.Tag.INVALID, ConstantTypes.CONSTANT_INVALID); + } + private static final WhiteBox WB = WhiteBox.getWhiteBox(); + private final Map typeTests; + + public static enum ConstantTypes { + CONSTANT_CLASS { + @Override + public TestedCPEntry getTestedCPEntry(ConstantPoolTestsHelper.DummyClasses dummyClass, + int index) { + ConstantPool constantPoolSS = dummyClass.constantPoolSS; + checkIndex(constantPoolSS, index); + Class klass = constantPoolSS.getClassAt(index); + String klassName = klass.getName(); + TestedCPEntry[] testedEntries = dummyClass.testedCP.get(this); + for (TestedCPEntry entry : testedEntries) { + if (entry.klass.replaceAll("/", "\\.").equals(klassName)) { + return entry; + } + } + return null; + } + }, + CONSTANT_FIELDREF { + @Override + public TestedCPEntry getTestedCPEntry(ConstantPoolTestsHelper.DummyClasses dummyClass, + int index) { + return this.getTestedCPEntryForMethodAndField(dummyClass, index); + } + }, + CONSTANT_METHODREF { + @Override + public TestedCPEntry getTestedCPEntry(ConstantPoolTestsHelper.DummyClasses dummyClass, + int index) { + return this.getTestedCPEntryForMethodAndField(dummyClass, index); + } + }, + CONSTANT_INTERFACEMETHODREF { + @Override + public TestedCPEntry getTestedCPEntry(ConstantPoolTestsHelper.DummyClasses dummyClass, + int index) { + return this.getTestedCPEntryForMethodAndField(dummyClass, index); + } + }, + CONSTANT_STRING { + @Override + public TestedCPEntry getTestedCPEntry(ConstantPoolTestsHelper.DummyClasses dummyClass, + int index) { + ConstantPool constantPoolSS = dummyClass.constantPoolSS; + checkIndex(constantPoolSS, index); + String value = constantPoolSS.getStringAt(index); + TestedCPEntry[] testedEntries = dummyClass.testedCP.get(this); + for (TestedCPEntry entry : testedEntries) { + if (entry.name.equals(value)) { + return entry; + } + } + return null; + } + }, + CONSTANT_INTEGER, + CONSTANT_FLOAT, + CONSTANT_LONG, + CONSTANT_DOUBLE, + CONSTANT_NAMEANDTYPE, + CONSTANT_UTF8, + CONSTANT_METHODHANDLE, + CONSTANT_METHODTYPE, + CONSTANT_INVOKEDYNAMIC { + @Override + public TestedCPEntry getTestedCPEntry(ConstantPoolTestsHelper.DummyClasses dummyClass, + int index) { + ConstantPool constantPoolSS = dummyClass.constantPoolSS; + checkIndex(constantPoolSS, index); + int nameAndTypeIndex = constantPoolSS.getNameAndTypeRefIndexAt(index); + String[] info = constantPoolSS.getNameAndTypeRefInfoAt(nameAndTypeIndex); + TestedCPEntry[] testedEntries = dummyClass.testedCP.get(this); + for (TestedCPEntry entry : testedEntries) { + if (info[0].equals(entry.name) && info[1].equals(entry.type)) { + return entry; + } + } + return null; + } + }, + CONSTANT_INVALID; + + public TestedCPEntry getTestedCPEntry( + ConstantPoolTestsHelper.DummyClasses dummyClass, int index) { + return null; // returning null by default + } + + public TestedCPEntry[] getAllCPEntriesForType(ConstantPoolTestsHelper.DummyClasses dummyClass) { + TestedCPEntry[] toReturn = dummyClass.testedCP.get(this); + if (toReturn == null) { + return new TestedCPEntry[0]; + } + return dummyClass.testedCP.get(this); + } + + protected TestedCPEntry getTestedCPEntryForMethodAndField(ConstantPoolTestsHelper.DummyClasses dummyClass, + int index) { + ConstantPool constantPoolSS = dummyClass.constantPoolSS; + checkIndex(constantPoolSS, index); + String[] info = constantPoolSS.getMemberRefInfoAt(index); + TestedCPEntry[] testedEntries = dummyClass.testedCP.get(this); + for (TestedCPEntry entry : testedEntries) { + if (info[0].equals(entry.klass) && info[1].equals(entry.name) && info[2].equals(entry.type)) { + return entry; + } + } + return null; + } + + protected void checkIndex(ConstantPool constantPoolSS, int index) { + ConstantPool.Tag tag = constantPoolSS.getTagAt(index); + ConstantTypes type = mapTagToCPType(tag); + if (!this.equals(type)) { + String msg = String.format("TESTBUG: CP tag should be a %s, but is %s", + this.name(), + type.name()); + throw new Error(msg); + } + } + } public static interface Validator { void validate(jdk.vm.ci.meta.ConstantPool constantPoolCTVM, - ConstantPool constantPoolSS, - ConstantPoolTestsHelper.DummyClasses dummyClass, int index); + ConstantTypes cpType, + ConstantPoolTestsHelper.DummyClasses dummyClass, + int index); } - public ConstantPoolTestCase(Map typeTests) { - this.typeTests = new HashMap<>(); - this.typeTests.putAll(typeTests); - } + public static class TestedCPEntry { + public final String klass; + public final String name; + public final String type; + public final byte[] opcodes; + public final long accFlags; + + public TestedCPEntry(String klass, String name, String type, byte[] opcodes, long accFlags) { + this.klass = klass; + this.name = name; + this.type = type; + if (opcodes != null) { + this.opcodes = new byte[opcodes.length]; + System.arraycopy(opcodes, 0, this.opcodes, 0, opcodes.length); + } else { + this.opcodes = null; + } + this.accFlags = accFlags; + } - private void messageOnFail(Throwable t, - ConstantPoolTestsHelper.ConstantTypes cpType, - ConstantPoolTestsHelper.DummyClasses dummyClass, int index) { - ConstantPool constantPoolSS = SharedSecrets.getJavaLangAccess(). - getConstantPool(dummyClass.klass); - String msg = String.format("Test for %s constant pool entry of" - + " type %s", - dummyClass.klass, cpType.name()); - switch (cpType) { - case CONSTANT_CLASS: - case CONSTANT_STRING: - case CONSTANT_METHODTYPE: - String utf8 = constantPoolSS - .getUTF8At((int) dummyClass.cp.get(index).value); - msg = String.format("%s (%s) failed with %s", msg, utf8, t); - break; - case CONSTANT_INTEGER: - int intValue = constantPoolSS.getIntAt(index); - msg = String.format("%s (%d) failed with %s", msg, intValue, t); - break; - case CONSTANT_LONG: - long longValue = constantPoolSS.getLongAt(index); - msg = String.format("%s (%d) failed with %s", msg, longValue, t); - break; - case CONSTANT_FLOAT: - float floatValue = constantPoolSS.getFloatAt(index); - msg = String.format("%s (%E) failed with %s", msg, floatValue, t); - break; - case CONSTANT_DOUBLE: - double doubleValue = constantPoolSS.getDoubleAt(index); - msg = String.format("%s (%E) failed with %s", msg, doubleValue, t); - break; - case CONSTANT_UTF8: - String utf8Value = constantPoolSS.getUTF8At(index); - msg = String.format("%s (%s) failed with %s", msg, utf8Value, t); - break; - case CONSTANT_INVOKEDYNAMIC: - index = ((int[]) dummyClass.cp.get(index).value)[1]; - case CONSTANT_NAMEANDTYPE: - String name = constantPoolSS - .getUTF8At(((int[]) dummyClass.cp.get(index).value)[0]); - String type = constantPoolSS - .getUTF8At(((int[]) dummyClass.cp.get(index).value)[1]); - msg = String.format("%s (%s:%s) failed with %s", - msg, name, type, t); - break; - case CONSTANT_METHODHANDLE: - index = ((int[]) dummyClass.cp.get(index).value)[1]; - case CONSTANT_METHODREF: - case CONSTANT_INTERFACEMETHODREF: - case CONSTANT_FIELDREF: - int classIndex = ((int[]) dummyClass.cp.get(index).value)[0]; - int nameAndTypeIndex = ((int[]) dummyClass.cp.get(index).value)[1]; - String cName = constantPoolSS - .getUTF8At((int) dummyClass.cp.get(classIndex).value); - String mName = constantPoolSS - .getUTF8At(((int[]) dummyClass.cp.get(nameAndTypeIndex).value)[0]); - String mType = constantPoolSS - .getUTF8At(((int[]) dummyClass.cp.get(nameAndTypeIndex).value)[1]); - msg = String.format("%s (%s.%s:%s) failed with %s ", - msg, cName, mName, mType, t); - break; - default: - msg = String.format("Test bug: unknown constant type %s ", cpType); + public TestedCPEntry(String klass, String name, String type, byte[] opcodes) { + this(klass, name, type, opcodes, 0); } - throw new Error(msg + t.getMessage(), t); + + public TestedCPEntry(String klass, String name, String type) { + this(klass, name, type, null, 0); + } + } + + public static ConstantTypes mapTagToCPType(ConstantPool.Tag tag) { + return TAG_TO_TYPE_MAP.get(tag); + } + + public ConstantPoolTestCase(Map typeTests) { + this.typeTests = new HashMap<>(); + this.typeTests.putAll(typeTests); } public void test() { for (ConstantPoolTestsHelper.DummyClasses dummyClass : ConstantPoolTestsHelper.DummyClasses.values()) { - System.out.printf("%nTesting dummy %s%n", dummyClass.klass); - HotSpotResolvedObjectType holder = HotSpotResolvedObjectType - .fromObjectClass(dummyClass.klass); - jdk.vm.ci.meta.ConstantPool constantPoolCTVM - = holder.getConstantPool(); - ConstantPool constantPoolSS = SharedSecrets.getJavaLangAccess(). - getConstantPool(dummyClass.klass); - for (Integer i : dummyClass.cp.keySet()) { - ConstantPoolTestsHelper.ConstantTypes cpType - = dummyClass.cp.get(i).type; + boolean isCPCached = WB.getConstantPoolCacheLength(dummyClass.klass) > -1; + System.out.printf("Testing dummy %s with constant pool cached = %b%n", + dummyClass.klass, + isCPCached); + HotSpotResolvedObjectType holder = HotSpotResolvedObjectType.fromObjectClass(dummyClass.klass); + jdk.vm.ci.meta.ConstantPool constantPoolCTVM = holder.getConstantPool(); + ConstantPool constantPoolSS = dummyClass.constantPoolSS; + for (int i = 0; i < constantPoolSS.getSize(); i++) { + ConstantPool.Tag tag = constantPoolSS.getTagAt(i); + ConstantTypes cpType = mapTagToCPType(tag); if (!typeTests.keySet().contains(cpType)) { continue; } - try { - typeTests.get(cpType).validate(constantPoolCTVM, - constantPoolSS, dummyClass, i); - } catch (Throwable t) { - messageOnFail(t, cpType, dummyClass, i); - } + typeTests.get(cpType).validate(constantPoolCTVM, cpType, dummyClass, i); } } } } - --- old/test/compiler/jvmci/compilerToVM/ConstantPoolTestsHelper.java 2016-02-18 13:37:24.575616056 +0300 +++ new/test/compiler/jvmci/compilerToVM/ConstantPoolTestsHelper.java 2016-02-18 13:37:24.483616058 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,17 @@ */ package compiler.jvmci.compilerToVM; +import compiler.jvmci.common.testcases.MultipleAbstractImplementer; import compiler.jvmci.common.testcases.MultipleImplementer2; import compiler.jvmci.common.testcases.MultipleImplementersInterface; +import compiler.jvmci.compilerToVM.ConstantPoolTestCase.ConstantTypes; +import compiler.jvmci.compilerToVM.ConstantPoolTestCase.TestedCPEntry; import java.util.HashMap; import java.util.Map; +import jdk.internal.misc.SharedSecrets; +import jdk.internal.org.objectweb.asm.Opcodes; +import sun.hotspot.WhiteBox; +import sun.reflect.ConstantPool; /** * Class contains hard-coded constant pool tables for dummy classes used for @@ -34,104 +41,437 @@ */ public class ConstantPoolTestsHelper { - public enum ConstantTypes { - CONSTANT_CLASS, - CONSTANT_FIELDREF, - CONSTANT_METHODREF, - CONSTANT_INTERFACEMETHODREF, - CONSTANT_STRING, - CONSTANT_INTEGER, - CONSTANT_FLOAT, - CONSTANT_LONG, - CONSTANT_DOUBLE, - CONSTANT_NAMEANDTYPE, - CONSTANT_UTF8, - CONSTANT_METHODHANDLE, - CONSTANT_METHODTYPE, - CONSTANT_INVOKEDYNAMIC; - } + public static final int NO_CP_CACHE_PRESENT = Integer.MAX_VALUE; public enum DummyClasses { DUMMY_CLASS(MultipleImplementer2.class, CP_MAP_FOR_CLASS), + DUMMY_ABS_CLASS(MultipleAbstractImplementer.class, CP_MAP_FOR_ABS_CLASS), DUMMY_INTERFACE(MultipleImplementersInterface.class, CP_MAP_FOR_INTERFACE); + private static final WhiteBox WB = WhiteBox.getWhiteBox(); public final Class klass; - public final Map cp; + public final ConstantPool constantPoolSS; + public final Map testedCP; - DummyClasses(Class klass, Map cp) { + DummyClasses(Class klass, Map testedCP) { this.klass = klass; - this.cp = cp; + this.constantPoolSS = SharedSecrets.getJavaLangAccess().getConstantPool(klass); + this.testedCP = testedCP; } - } - - public static class ConstantPoolEntry { - - public final ConstantTypes type; - public final Object value; - public ConstantPoolEntry(ConstantTypes type, Object value) { - this.type = type; - this.value = value; + public int getCPCacheIndex(int cpi) { + int cacheLength = WB.getConstantPoolCacheLength(this.klass); + int indexTag = WB.getConstantPoolCacheIndexTag(); + for (int cpci = indexTag; cpci < cacheLength + indexTag; cpci++) { + if (WB.remapInstructionOperandFromCPCache(this.klass, cpci) == cpi) { + if (constantPoolSS.getTagAt(cpi).equals(ConstantPool.Tag.INVOKEDYNAMIC)) { + return WB.encodeConstantPoolIndyIndex(cpci) + indexTag; + } + return cpci; + } + } + return NO_CP_CACHE_PRESENT; } } - private static final Map CP_MAP_FOR_CLASS + private static final Map CP_MAP_FOR_CLASS = new HashMap<>(); + static { + CP_MAP_FOR_CLASS.put(ConstantTypes.CONSTANT_CLASS, + new TestedCPEntry[] { + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementersInterface", null, null), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2", null, null), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2$1", null, null), + new TestedCPEntry("java/lang/invoke/MethodHandles$Lookup", null, null), + } + ); + CP_MAP_FOR_CLASS.put(ConstantTypes.CONSTANT_FIELDREF, + new TestedCPEntry[] { + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2", + "intStaticField", + "I", + new byte[] {(byte) Opcodes.PUTSTATIC, (byte) Opcodes.GETSTATIC}, + Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2", + "longStaticField", + "J", + new byte[] {(byte) Opcodes.PUTSTATIC, (byte) Opcodes.GETSTATIC}, + Opcodes.ACC_FINAL | Opcodes.ACC_STATIC), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2", + "floatStaticField", + "F", + new byte[] {(byte) Opcodes.PUTSTATIC, (byte) Opcodes.GETSTATIC}, + Opcodes.ACC_VOLATILE | Opcodes.ACC_STATIC), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2", + "doubleStaticField", + "D", + new byte[] {(byte) Opcodes.PUTSTATIC, (byte) Opcodes.GETSTATIC}, + Opcodes.ACC_STATIC), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2", + "stringStaticField", + "Ljava/lang/String;", + new byte[] {(byte) Opcodes.PUTSTATIC, (byte) Opcodes.GETSTATIC}, + Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2", + "objectStaticField", + "Ljava/lang/Object;", + new byte[] {(byte) Opcodes.PUTSTATIC, (byte) Opcodes.GETSTATIC}, + Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2", + "intField", + "I", + new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD}, + Opcodes.ACC_PUBLIC), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2", + "longField", + "J", + new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD}, + Opcodes.ACC_PRIVATE), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2", + "floatField", + "F", + new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD}, + Opcodes.ACC_PROTECTED), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2", + "doubleField", + "D", + new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD}, + Opcodes.ACC_TRANSIENT), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2", + "objectField", + "Ljava/lang/Object;", + new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD}, + Opcodes.ACC_FINAL), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2", + "stringField", + "Ljava/lang/String;", + new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD}, + Opcodes.ACC_VOLATILE), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2", + "stringFieldEmpty", + "Ljava/lang/String;", + new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD}, + 0L), + } + ); + CP_MAP_FOR_CLASS.put(ConstantTypes.CONSTANT_METHODREF, + new TestedCPEntry[] { + new TestedCPEntry("java/lang/System", + "getProperties", + "()Ljava/util/Properties;", + new byte[] {(byte) Opcodes.INVOKESTATIC}), + new TestedCPEntry("java/util/HashMap", + "", + "()V", + new byte[] {(byte) Opcodes.INVOKESPECIAL}), + new TestedCPEntry("java/lang/Object", + "toString", + "()Ljava/lang/String;", + new byte[] {(byte) Opcodes.INVOKESPECIAL, + (byte) Opcodes.INVOKEVIRTUAL}), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2$1", + "", + "(Lcompiler/jvmci/common/testcases/MultipleImplementer2;)V", + new byte[0]), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer$1", + "run", + "()V", + new byte[0]), + } + ); + CP_MAP_FOR_CLASS.put(ConstantTypes.CONSTANT_INTERFACEMETHODREF, + new TestedCPEntry[] { + new TestedCPEntry("java/util/Map", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + new byte[] {(byte) Opcodes.INVOKEINTERFACE}), + new TestedCPEntry("java/util/Map", + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + new byte[] {(byte) Opcodes.INVOKEINTERFACE}), + } + ); + CP_MAP_FOR_CLASS.put(ConstantTypes.CONSTANT_STRING, + new TestedCPEntry[] { + new TestedCPEntry(null, "Message", null), + new TestedCPEntry(null, "", null), + } + ); + CP_MAP_FOR_CLASS.put(ConstantTypes.CONSTANT_METHODHANDLE, + new TestedCPEntry[] { + new TestedCPEntry("java/lang/invoke/LambdaMetafactory", + "metafactory", + "(Ljava/lang/invoke/MethodHandles$Lookup;" + + "Ljava/lang/String;" + + "Ljava/lang/invoke/MethodType;" + + "Ljava/lang/invoke/MethodType;" + + "Ljava/lang/invoke/MethodHandle;" + + "Ljava/lang/invoke/MethodType;)" + + "Ljava/lang/invoke/CallSite;", + null), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementer2", + "testMethod", + "()V"), + } + ); + CP_MAP_FOR_CLASS.put(ConstantTypes.CONSTANT_METHODTYPE, + new TestedCPEntry[] { + new TestedCPEntry(null, null, "()V"), + } + ); + CP_MAP_FOR_CLASS.put(ConstantTypes.CONSTANT_INVOKEDYNAMIC, + new TestedCPEntry[] { + new TestedCPEntry(null, + "run", + "(Lcompiler/jvmci/common/testcases/MultipleImplementer2;)" + + "Ljava/lang/Runnable;"), + } + ); + } + + private static final Map CP_MAP_FOR_ABS_CLASS = new HashMap<>(); static { - CP_MAP_FOR_CLASS.put(1, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODREF, new int[]{22, 68})); - CP_MAP_FOR_CLASS.put(2, new ConstantPoolEntry(ConstantTypes.CONSTANT_CLASS, 69)); - CP_MAP_FOR_CLASS.put(3, new ConstantPoolEntry(ConstantTypes.CONSTANT_INTEGER, 2147483647)); - CP_MAP_FOR_CLASS.put(4, new ConstantPoolEntry(ConstantTypes.CONSTANT_FIELDREF, new int[]{35, 70})); - CP_MAP_FOR_CLASS.put(5, new ConstantPoolEntry(ConstantTypes.CONSTANT_LONG, 9223372036854775807L)); - CP_MAP_FOR_CLASS.put(8, new ConstantPoolEntry(ConstantTypes.CONSTANT_FLOAT, 3.4028235E38F)); - CP_MAP_FOR_CLASS.put(10, new ConstantPoolEntry(ConstantTypes.CONSTANT_DOUBLE, 1.7976931348623157E308D)); - CP_MAP_FOR_CLASS.put(13, new ConstantPoolEntry(ConstantTypes.CONSTANT_STRING, 74)); - CP_MAP_FOR_CLASS.put(22, new ConstantPoolEntry(ConstantTypes.CONSTANT_CLASS, 83)); - CP_MAP_FOR_CLASS.put(23, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODREF, new int[]{22, 84})); - CP_MAP_FOR_CLASS.put(24, new ConstantPoolEntry(ConstantTypes.CONSTANT_INTERFACEMETHODREF, new int[]{2, 85})); - CP_MAP_FOR_CLASS.put(26, new ConstantPoolEntry(ConstantTypes.CONSTANT_INVOKEDYNAMIC, new int[]{0, 91})); - CP_MAP_FOR_CLASS.put(29, new ConstantPoolEntry(ConstantTypes.CONSTANT_FIELDREF, new int[]{35, 94})); - CP_MAP_FOR_CLASS.put(35, new ConstantPoolEntry(ConstantTypes.CONSTANT_CLASS, 100)); - CP_MAP_FOR_CLASS.put(68, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{54, 55})); - CP_MAP_FOR_CLASS.put(70, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{48, 37})); - CP_MAP_FOR_CLASS.put(84, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{59, 55})); - CP_MAP_FOR_CLASS.put(85, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{103, 63})); - CP_MAP_FOR_CLASS.put(91, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{106, 107})); - CP_MAP_FOR_CLASS.put(94, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{36, 37})); - CP_MAP_FOR_CLASS.put(104, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODREF, new int[]{110, 111})); - CP_MAP_FOR_CLASS.put(105, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODREF, new int[]{35, 112})); - CP_MAP_FOR_CLASS.put(110, new ConstantPoolEntry(ConstantTypes.CONSTANT_CLASS, 113)); - CP_MAP_FOR_CLASS.put(111, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{114, 118})); - CP_MAP_FOR_CLASS.put(112, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{58, 55})); + CP_MAP_FOR_ABS_CLASS.put(ConstantTypes.CONSTANT_CLASS, + new TestedCPEntry[] { + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementersInterface", null, null), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer", null, null), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer$1", null, null), + new TestedCPEntry("java/lang/invoke/MethodHandles$Lookup", null, null), + } + ); + CP_MAP_FOR_ABS_CLASS.put(ConstantTypes.CONSTANT_FIELDREF, + new TestedCPEntry[] { + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer", + "intStaticField", + "I", + new byte[] {(byte) Opcodes.PUTSTATIC, (byte) Opcodes.GETSTATIC}, + Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer", + "longStaticField", + "J", + new byte[] {(byte) Opcodes.PUTSTATIC, (byte) Opcodes.GETSTATIC}, + Opcodes.ACC_FINAL | Opcodes.ACC_STATIC), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer", + "floatStaticField", + "F", + new byte[] {(byte) Opcodes.PUTSTATIC, (byte) Opcodes.GETSTATIC}, + Opcodes.ACC_VOLATILE | Opcodes.ACC_STATIC), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer", + "doubleStaticField", + "D", + new byte[] {(byte) Opcodes.PUTSTATIC, (byte) Opcodes.GETSTATIC}, + Opcodes.ACC_STATIC), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer", + "stringStaticField", + "Ljava/lang/String;", + new byte[] {(byte) Opcodes.PUTSTATIC, (byte) Opcodes.GETSTATIC}, + Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer", + "objectStaticField", + "Ljava/lang/Object;", + new byte[] {(byte) Opcodes.PUTSTATIC, (byte) Opcodes.GETSTATIC}, + Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer", + "intField", + "I", + new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD}, + Opcodes.ACC_PUBLIC), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer", + "longField", + "J", + new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD}, + Opcodes.ACC_PRIVATE), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer", + "floatField", + "F", + new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD}, + Opcodes.ACC_PROTECTED), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer", + "doubleField", + "D", + new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD}, + Opcodes.ACC_TRANSIENT), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer", + "objectField", + "Ljava/lang/Object;", + new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD}, + Opcodes.ACC_FINAL), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer", + "stringField", + "Ljava/lang/String;", + new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD}, + Opcodes.ACC_VOLATILE), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer", + "stringFieldEmpty", + "Ljava/lang/String;", + new byte[] {(byte) Opcodes.PUTFIELD | (byte) Opcodes.GETFIELD}, + 0L), + } + ); + CP_MAP_FOR_ABS_CLASS.put(ConstantTypes.CONSTANT_METHODREF, + new TestedCPEntry[] { + new TestedCPEntry("java/lang/System", + "getProperties", + "()Ljava/util/Properties;", + new byte[] {(byte) Opcodes.INVOKESTATIC}), + new TestedCPEntry("java/util/HashMap", + "", + "()V", + new byte[] {(byte) Opcodes.INVOKESPECIAL}), + new TestedCPEntry("java/lang/Object", + "toString", + "()Ljava/lang/String;", + new byte[] {(byte) Opcodes.INVOKESPECIAL, + (byte) Opcodes.INVOKEVIRTUAL}), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer$1", + "", + "(Lcompiler/jvmci/common/testcases/MultipleAbstractImplementer;)V", + new byte[0]), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer$1", + "run", + "()V", + new byte[0]), + } + ); + CP_MAP_FOR_ABS_CLASS.put(ConstantTypes.CONSTANT_INTERFACEMETHODREF, + new TestedCPEntry[] { + new TestedCPEntry("java/util/Map", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + new byte[] {(byte) Opcodes.INVOKEINTERFACE}), + new TestedCPEntry("java/util/Map", + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + new byte[] {(byte) Opcodes.INVOKEINTERFACE}), + } + ); + CP_MAP_FOR_ABS_CLASS.put(ConstantTypes.CONSTANT_STRING, + new TestedCPEntry[] { + new TestedCPEntry(null, "Message", null), + new TestedCPEntry(null, "", null), + } + ); + CP_MAP_FOR_ABS_CLASS.put(ConstantTypes.CONSTANT_METHODHANDLE, + new TestedCPEntry[] { + new TestedCPEntry("java/lang/invoke/LambdaMetafactory", + "metafactory", + "(Ljava/lang/invoke/MethodHandles$Lookup;" + + "Ljava/lang/String;" + + "Ljava/lang/invoke/MethodType;" + + "Ljava/lang/invoke/MethodType;" + + "Ljava/lang/invoke/MethodHandle;" + + "Ljava/lang/invoke/MethodType;)" + + "Ljava/lang/invoke/CallSite;", + null), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer", + "testMethod", + "()V"), + } + ); + CP_MAP_FOR_ABS_CLASS.put(ConstantTypes.CONSTANT_METHODTYPE, + new TestedCPEntry[] { + new TestedCPEntry(null, null, "()V"), + } + ); + CP_MAP_FOR_ABS_CLASS.put(ConstantTypes.CONSTANT_INVOKEDYNAMIC, + new TestedCPEntry[] { + new TestedCPEntry(null, + "run", + "(Lcompiler/jvmci/common/testcases/MultipleAbstractImplementer;)" + + "Ljava/lang/Runnable;"), + } + ); } - private static final Map CP_MAP_FOR_INTERFACE + private static final Map CP_MAP_FOR_INTERFACE = new HashMap<>(); static { - CP_MAP_FOR_INTERFACE.put(1, new ConstantPoolEntry(ConstantTypes.CONSTANT_CLASS, 48)); - CP_MAP_FOR_INTERFACE.put(5, new ConstantPoolEntry(ConstantTypes.CONSTANT_INTERFACEMETHODREF, new int[]{13, 52})); - CP_MAP_FOR_INTERFACE.put(6, new ConstantPoolEntry(ConstantTypes.CONSTANT_CLASS, 53)); - CP_MAP_FOR_INTERFACE.put(7, new ConstantPoolEntry(ConstantTypes.CONSTANT_INVOKEDYNAMIC, new int[]{0, 58})); - CP_MAP_FOR_INTERFACE.put(8, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODREF, new int[]{6, 59})); - CP_MAP_FOR_INTERFACE.put(9, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODREF, new int[]{6, 60})); - CP_MAP_FOR_INTERFACE.put(12, new ConstantPoolEntry(ConstantTypes.CONSTANT_FIELDREF, new int[]{13, 63})); - CP_MAP_FOR_INTERFACE.put(13, new ConstantPoolEntry(ConstantTypes.CONSTANT_CLASS, 64)); - CP_MAP_FOR_INTERFACE.put(17, new ConstantPoolEntry(ConstantTypes.CONSTANT_INTEGER, 2147483647)); - CP_MAP_FOR_INTERFACE.put(20, new ConstantPoolEntry(ConstantTypes.CONSTANT_LONG, 9223372036854775807l)); - CP_MAP_FOR_INTERFACE.put(24, new ConstantPoolEntry(ConstantTypes.CONSTANT_FLOAT, 3.4028235E38f)); - CP_MAP_FOR_INTERFACE.put(27, new ConstantPoolEntry(ConstantTypes.CONSTANT_DOUBLE, 1.7976931348623157E308d)); - CP_MAP_FOR_INTERFACE.put(31, new ConstantPoolEntry(ConstantTypes.CONSTANT_STRING, 65)); - CP_MAP_FOR_INTERFACE.put(52, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{34, 35})); - CP_MAP_FOR_INTERFACE.put(55, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODHANDLE, new int[]{6, 67})); - CP_MAP_FOR_INTERFACE.put(56, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODTYPE, 35)); - CP_MAP_FOR_INTERFACE.put(57, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODHANDLE, new int[]{9, 5})); - CP_MAP_FOR_INTERFACE.put(58, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{68, 69})); - CP_MAP_FOR_INTERFACE.put(59, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{70, 71})); - CP_MAP_FOR_INTERFACE.put(60, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{72, 35})); - CP_MAP_FOR_INTERFACE.put(63, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{32, 33})); - CP_MAP_FOR_INTERFACE.put(67, new ConstantPoolEntry(ConstantTypes.CONSTANT_METHODREF, new int[]{73, 74})); - CP_MAP_FOR_INTERFACE.put(73, new ConstantPoolEntry(ConstantTypes.CONSTANT_CLASS, 75)); - CP_MAP_FOR_INTERFACE.put(74, new ConstantPoolEntry(ConstantTypes.CONSTANT_NAMEANDTYPE, new int[]{76, 80})); - CP_MAP_FOR_INTERFACE.put(77, new ConstantPoolEntry(ConstantTypes.CONSTANT_CLASS, 82)); + CP_MAP_FOR_INTERFACE.put(ConstantTypes.CONSTANT_CLASS, + new TestedCPEntry[] { + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementersInterface", null, null), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementersInterface$1", null, null), + new TestedCPEntry("java/lang/Object", null, null), + new TestedCPEntry("java/lang/invoke/MethodHandles$Lookup", null, null), + } + ); + CP_MAP_FOR_INTERFACE.put(ConstantTypes.CONSTANT_FIELDREF, + new TestedCPEntry[] { + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementersInterface", + "OBJECT_CONSTANT", + "Ljava/lang/Object;", + new byte[] {(byte) Opcodes.PUTSTATIC, (byte) Opcodes.GETSTATIC}, + Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_PUBLIC), + } + ); + CP_MAP_FOR_INTERFACE.put(ConstantTypes.CONSTANT_METHODREF, + new TestedCPEntry[] { + new TestedCPEntry("java/lang/System", + "getProperties", + "()Ljava/util/Properties;", + new byte[] {(byte) Opcodes.INVOKESTATIC}), + new TestedCPEntry("java/util/HashMap", + "", + "()V", + new byte[] {(byte) Opcodes.INVOKESPECIAL}), + new TestedCPEntry("java/lang/Object", + "toString", + "()Ljava/lang/String;", + new byte[] {(byte) Opcodes.INVOKEVIRTUAL}), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer$1", + "", + "(Lcompiler/jvmci/common/testcases/MultipleAbstractImplementer;)V", + new byte[0]), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleAbstractImplementer$1", + "run", + "()V", + new byte[0]), + } + ); + CP_MAP_FOR_INTERFACE.put(ConstantTypes.CONSTANT_INTERFACEMETHODREF, + new TestedCPEntry[] { + new TestedCPEntry("java/util/Map", + "put", + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", + new byte[] {(byte) Opcodes.INVOKEINTERFACE}), + new TestedCPEntry("java/util/Map", + "remove", + "(Ljava/lang/Object;)Ljava/lang/Object;", + new byte[] {(byte) Opcodes.INVOKEINTERFACE}), + } + ); + CP_MAP_FOR_INTERFACE.put(ConstantTypes.CONSTANT_STRING, + new TestedCPEntry[] { + new TestedCPEntry(null, "Hello", null), + new TestedCPEntry(null, "", null), + } + ); + CP_MAP_FOR_INTERFACE.put(ConstantTypes.CONSTANT_METHODHANDLE, + new TestedCPEntry[] { + new TestedCPEntry("java/lang/invoke/LambdaMetafactory", + "metafactory", + "(Ljava/lang/invoke/MethodHandles$Lookup;" + + "Ljava/lang/String;Ljava/lang/invoke/MethodType;" + + "Ljava/lang/invoke/MethodType;" + + "Ljava/lang/invoke/MethodHandle;" + + "Ljava/lang/invoke/MethodType;)" + + "Ljava/lang/invoke/CallSite;"), + new TestedCPEntry("compiler/jvmci/common/testcases/MultipleImplementersInterface", + "defaultMethod", + "()V"), + } + ); + CP_MAP_FOR_INTERFACE.put(ConstantTypes.CONSTANT_METHODTYPE, + new TestedCPEntry[] { + new TestedCPEntry(null, null, "()V"), + } + ); + CP_MAP_FOR_INTERFACE.put(ConstantTypes.CONSTANT_INVOKEDYNAMIC, + new TestedCPEntry[] { + new TestedCPEntry(null, + "run", + "(Lcompiler/jvmci/common/testcases/MultipleImplementersInterface;)" + + "Ljava/lang/Runnable;"), + } + ); } } --- old/test/compiler/jvmci/compilerToVM/LookupKlassInPoolTest.java 2016-02-18 13:37:24.895616050 +0300 +++ new/test/compiler/jvmci/compilerToVM/LookupKlassInPoolTest.java 2016-02-18 13:37:24.803616052 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,58 +29,70 @@ * @summary Testing compiler.jvmci.CompilerToVM.lookupKlassInPool method * @library /testlibrary /test/lib / * @compile ../common/CompilerToVMHelper.java - * @build compiler.jvmci.common.testcases.MultipleImplementersInterface - * compiler.jvmci.common.testcases.MultipleImplementer2 - * compiler.jvmci.compilerToVM.ConstantPoolTestsHelper - * compiler.jvmci.compilerToVM.ConstantPoolTestCase + * @build sun.hotspot.WhiteBox * compiler.jvmci.compilerToVM.LookupKlassInPoolTest - * @run main ClassFileInstaller jdk.vm.ci.hotspot.CompilerToVMHelper - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * jdk.vm.ci.hotspot.CompilerToVMHelper + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions * -XX:+EnableJVMCI compiler.jvmci.compilerToVM.LookupKlassInPoolTest */ package compiler.jvmci.compilerToVM; +import compiler.jvmci.compilerToVM.ConstantPoolTestsHelper.DummyClasses; import java.util.HashMap; import java.util.Map; import jdk.vm.ci.hotspot.CompilerToVMHelper; import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; -import sun.reflect.ConstantPool; +import jdk.vm.ci.meta.ConstantPool; /** - * Test for {@code compiler.jvmci.CompilerToVM.lookupKlassInPool} method + * Test for {@code jdk.vm.ci.hotspot.CompilerToVM.lookupKlassInPool} method */ public class LookupKlassInPoolTest { - public static void main(String[] args) { - Map typeTests = new HashMap<>(1); - typeTests.put(ConstantPoolTestsHelper.ConstantTypes.CONSTANT_CLASS, - LookupKlassInPoolTest::validate); + public static void main(String[] args) throws Exception { + Map typeTests = new HashMap<>(); + typeTests.put(ConstantPoolTestCase.ConstantTypes.CONSTANT_CLASS, + LookupKlassInPoolTest::validate); ConstantPoolTestCase testCase = new ConstantPoolTestCase(typeTests); testCase.test(); + // The next "Class.forName" and repeating "testCase.test()" + // are here for the following reason. + // The first test run is without dummy class initialization, + // which means no constant pool cache exists. + // The second run is with initialized class (with constant pool cache available). + // Some CompilerToVM methods require different input + // depending on whether CP cache exists or not. + for (DummyClasses dummy : DummyClasses.values()) { + Class.forName(dummy.klass.getName()); + } + testCase.test(); } - public static void validate(jdk.vm.ci.meta.ConstantPool constantPoolCTVM, - ConstantPool constantPoolSS, - ConstantPoolTestsHelper.DummyClasses dummyClass, int i) { - Object classToVerify = CompilerToVMHelper - .lookupKlassInPool(constantPoolCTVM, i); - if (!(classToVerify instanceof HotSpotResolvedObjectType) - && !(classToVerify instanceof String)) { - String msg = String.format("Output of method" - + " CTVM.lookupKlassInPool is neither" - + " a HotSpotResolvedObjectType, nor a String"); + public static void validate(ConstantPool constantPoolCTVM, + ConstantPoolTestCase.ConstantTypes cpType, + ConstantPoolTestsHelper.DummyClasses dummyClass, + int i) { + ConstantPoolTestCase.TestedCPEntry entry = cpType.getTestedCPEntry(dummyClass, i); + if (entry == null) { + return; + } + Object classToVerify = CompilerToVMHelper.lookupKlassInPool(constantPoolCTVM, i); + if (!(classToVerify instanceof HotSpotResolvedObjectType) && !(classToVerify instanceof String)) { + String msg = String.format("Output of method CTVM.lookupKlassInPool is neither" + + " a HotSpotResolvedObjectType, nor a String"); throw new AssertionError(msg); } - int classNameIndex = (int) dummyClass.cp.get(i).value; - String classNameToRefer - = constantPoolSS.getUTF8At(classNameIndex); + String classNameToRefer = entry.klass; String outputToVerify = classToVerify.toString(); if (!outputToVerify.contains(classNameToRefer)) { - String msg = String.format("Wrong class accessed by constant" - + " pool index %d: %s, but should be %s", - i, outputToVerify, classNameToRefer); + String msg = String.format("Wrong class accessed by constant pool index %d: %s, but should be %s", + i, + outputToVerify, + classNameToRefer); throw new AssertionError(msg); } } --- old/test/compiler/jvmci/compilerToVM/ResolveConstantInPoolTest.java 2016-02-18 13:37:25.203616043 +0300 +++ new/test/compiler/jvmci/compilerToVM/ResolveConstantInPoolTest.java 2016-02-18 13:37:25.095616046 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,66 +28,85 @@ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9" | os.simpleArch == "aarch64") * @library /testlibrary /test/lib / * @compile ../common/CompilerToVMHelper.java - * @build compiler.jvmci.compilerToVM.ResolveConstantInPoolTest - * @run main ClassFileInstaller jdk.vm.ci.hotspot.CompilerToVMHelper - * @run main/othervm -Xbootclasspath/a:. - * -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * @build sun.hotspot.WhiteBox + * compiler.jvmci.compilerToVM.ResolveConstantInPoolTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * jdk.vm.ci.hotspot.CompilerToVMHelper + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI * compiler.jvmci.compilerToVM.ResolveConstantInPoolTest */ package compiler.jvmci.compilerToVM; +import compiler.jvmci.compilerToVM.ConstantPoolTestsHelper.DummyClasses; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodType; import java.util.HashMap; import java.util.Map; -import jdk.vm.ci.hotspot.CompilerToVMHelper; import jdk.test.lib.Asserts; -import sun.reflect.ConstantPool; +import jdk.vm.ci.hotspot.CompilerToVMHelper; +import jdk.vm.ci.meta.ConstantPool; /** - * Test for {@code compiler.jvmci.CompilerToVM.resolveConstantInPool} method + * Test for {@code jdk.vm.ci.hotspot.CompilerToVM.resolveConstantInPool} method */ public class ResolveConstantInPoolTest { + private static final String NOT_NULL_MSG + = "Object returned by resolveConstantInPool method should not be null"; + public static void main(String[] args) throws Exception { - Map typeTests = new HashMap<>(2); - typeTests.put(ConstantPoolTestsHelper.ConstantTypes.CONSTANT_METHODHANDLE, - ResolveConstantInPoolTest::validateMethodHandle); - typeTests.put(ConstantPoolTestsHelper.ConstantTypes.CONSTANT_METHODTYPE, - ResolveConstantInPoolTest::validateMethodType); + Map typeTests = new HashMap<>(); + typeTests.put(ConstantPoolTestCase.ConstantTypes.CONSTANT_METHODHANDLE, + ResolveConstantInPoolTest::validateMethodHandle); + typeTests.put(ConstantPoolTestCase.ConstantTypes.CONSTANT_METHODTYPE, + ResolveConstantInPoolTest::validateMethodType); ConstantPoolTestCase testCase = new ConstantPoolTestCase(typeTests); testCase.test(); + // The next "Class.forName" and repeating "testCase.test()" + // are here for the following reason. + // The first test run is without dummy class initialization, + // which means no constant pool cache exists. + // The second run is with initialized class (with constant pool cache available). + // Some CompilerToVM methods require different input + // depending on whether CP cache exists or not. + for (DummyClasses dummy : DummyClasses.values()) { + Class.forName(dummy.klass.getName()); + } + testCase.test(); } - private static void validateMethodHandle( - jdk.vm.ci.meta.ConstantPool constantPoolCTVM, - ConstantPool constantPoolSS, - ConstantPoolTestsHelper.DummyClasses dummyClass, int index) { - Object constantInPool = CompilerToVMHelper - .resolveConstantInPool(constantPoolCTVM, index); + private static void validateMethodHandle(ConstantPool constantPoolCTVM, + ConstantPoolTestCase.ConstantTypes cpType, + ConstantPoolTestsHelper.DummyClasses dummyClass, + int index) { + Object constantInPool = CompilerToVMHelper.resolveConstantInPool(constantPoolCTVM, index); + String msg = String.format("%s for index %d", NOT_NULL_MSG, index); + Asserts.assertNotNull(constantInPool, msg); if (!(constantInPool instanceof MethodHandle)) { - String msg = String.format( - "Wrong constant pool entry accessed by index" - + " %d: %s, but should be subclass of %s", - index + 1, constantInPool.getClass(), - MethodHandle.class.getName()); + msg = String.format("Wrong constant pool entry accessed by index" + + " %d: %s, but should be subclass of %s", + index, + constantInPool.getClass(), + MethodHandle.class.getName()); throw new AssertionError(msg); } } - private static void validateMethodType( - jdk.vm.ci.meta.ConstantPool constantPoolCTVM, - ConstantPool constantPoolSS, - ConstantPoolTestsHelper.DummyClasses dummyClass, int index) { - Object constantInPool = CompilerToVMHelper - .resolveConstantInPool(constantPoolCTVM, index); + private static void validateMethodType(ConstantPool constantPoolCTVM, + ConstantPoolTestCase.ConstantTypes cpType, + ConstantPoolTestsHelper.DummyClasses dummyClass, + int index) { + Object constantInPool = CompilerToVMHelper.resolveConstantInPool(constantPoolCTVM, index); + String msg = String.format("%s for index %d", NOT_NULL_MSG, index); + Asserts.assertNotNull(constantInPool, msg); Class mtToVerify = constantInPool.getClass(); Class mtToRefer = MethodType.class; - String msg = String.format("Wrong %s accessed by constant pool index" - + " %d: %s, but should be %s", "method type class", - index, mtToVerify, mtToRefer); + msg = String.format("Wrong method type class accessed by" + + " constant pool index %d", + index); Asserts.assertEQ(mtToRefer, mtToVerify, msg); } } --- old/test/compiler/jvmci/compilerToVM/ResolveTypeInPoolTest.java 2016-02-18 13:37:25.507616037 +0300 +++ new/test/compiler/jvmci/compilerToVM/ResolveTypeInPoolTest.java 2016-02-18 13:37:25.427616039 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,51 +29,66 @@ * @summary Testing compiler.jvmci.CompilerToVM.resolveTypeInPool method * @library /testlibrary /test/lib / * @compile ../common/CompilerToVMHelper.java - * @build compiler.jvmci.common.testcases.MultipleImplementersInterface - * compiler.jvmci.common.testcases.MultipleImplementer2 - * compiler.jvmci.compilerToVM.ConstantPoolTestsHelper - * compiler.jvmci.compilerToVM.ConstantPoolTestCase + * @build sun.hotspot.WhiteBox * compiler.jvmci.compilerToVM.ResolveTypeInPoolTest - * @run main ClassFileInstaller jdk.vm.ci.hotspot.CompilerToVMHelper - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * jdk.vm.ci.hotspot.CompilerToVMHelper + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions * -XX:+EnableJVMCI compiler.jvmci.compilerToVM.ResolveTypeInPoolTest */ package compiler.jvmci.compilerToVM; +import compiler.jvmci.compilerToVM.ConstantPoolTestsHelper.DummyClasses; import java.util.HashMap; import java.util.Map; import jdk.vm.ci.hotspot.CompilerToVMHelper; import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; -import sun.reflect.ConstantPool; +import jdk.vm.ci.meta.ConstantPool; /** - * Test for {@code compiler.jvmci.CompilerToVM.resolveTypeInPool} method + * Test for {@code jdk.vm.ci.hotspot.CompilerToVM.resolveTypeInPool} method */ public class ResolveTypeInPoolTest { public static void main(String[] args) throws Exception { - Map typeTests = new HashMap<>(1); - typeTests.put(ConstantPoolTestsHelper.ConstantTypes.CONSTANT_CLASS, - ResolveTypeInPoolTest::validate); + Map typeTests = new HashMap<>(); + typeTests.put(ConstantPoolTestCase.ConstantTypes.CONSTANT_CLASS, + ResolveTypeInPoolTest::validate); ConstantPoolTestCase testCase = new ConstantPoolTestCase(typeTests); testCase.test(); + // The next "Class.forName" and repeating "testCase.test()" + // are here for the following reason. + // The first test run is without dummy class initialization, + // which means no constant pool cache exists. + // The second run is with initialized class (with constant pool cache available). + // Some CompilerToVM methods require different input + // depending on whether CP cache exists or not. + for (DummyClasses dummy : DummyClasses.values()) { + Class.forName(dummy.klass.getName()); + } + testCase.test(); } - public static void validate( - jdk.vm.ci.meta.ConstantPool constantPoolCTVM, - ConstantPool constantPoolSS, - ConstantPoolTestsHelper.DummyClasses dummyClass, int i) { - HotSpotResolvedObjectType typeToVerify = CompilerToVMHelper - .resolveTypeInPool(constantPoolCTVM, i); - int classNameIndex = (int) dummyClass.cp.get(i).value; - String classNameToRefer = constantPoolSS.getUTF8At(classNameIndex); + public static void validate(ConstantPool constantPoolCTVM, + ConstantPoolTestCase.ConstantTypes cpType, + ConstantPoolTestsHelper.DummyClasses dummyClass, + int i) { + ConstantPoolTestCase.TestedCPEntry entry = cpType.getTestedCPEntry(dummyClass, i); + if (entry == null) { + return; + } + HotSpotResolvedObjectType typeToVerify = CompilerToVMHelper.resolveTypeInPool(constantPoolCTVM, i); + String classNameToRefer = entry.klass; String outputToVerify = typeToVerify.toString(); if (!outputToVerify.contains(classNameToRefer)) { String msg = String.format("Wrong class accessed by constant" - + " pool index %d: %s, but should be %s", - i, outputToVerify, classNameToRefer); + + " pool index %d: %s, but should be %s", + i, + outputToVerify, + classNameToRefer); throw new AssertionError(msg); } }