hotspot/test/compiler/jvmci/compilerToVM/ConstantPoolTestCase.java
changeset 36305 55c7fe59d6d7
parent 33632 038347770a9e
child 37301 a936b4e01afb
equal deleted inserted replaced
36304:3a742df23055 36305:55c7fe59d6d7
     1 /*
     1 /*
     2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    25 package compiler.jvmci.compilerToVM;
    25 package compiler.jvmci.compilerToVM;
    26 
    26 
    27 import java.util.HashMap;
    27 import java.util.HashMap;
    28 import java.util.Map;
    28 import java.util.Map;
    29 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
    29 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
    30 import jdk.internal.misc.SharedSecrets;
    30 import sun.hotspot.WhiteBox;
    31 import sun.reflect.ConstantPool;
    31 import sun.reflect.ConstantPool;
       
    32 import sun.reflect.ConstantPool.Tag;
       
    33 import compiler.jvmci.compilerToVM.ConstantPoolTestsHelper.DummyClasses;
       
    34 import static compiler.jvmci.compilerToVM.ConstantPoolTestCase.ConstantTypes.*;
    32 
    35 
    33 /**
    36 /**
    34  * Common class for jdk.vm.ci.hotspot.CompilerToVM constant pool tests
    37  * Common class for jdk.vm.ci.hotspot.CompilerToVM constant pool tests
    35  */
    38  */
    36 public class ConstantPoolTestCase {
    39 public class ConstantPoolTestCase {
    37     private final Map<ConstantPoolTestsHelper.ConstantTypes, Validator> typeTests;
    40 
       
    41     private static final Map<Tag, ConstantTypes> TAG_TO_TYPE_MAP;
       
    42     static {
       
    43         TAG_TO_TYPE_MAP = new HashMap<>();
       
    44         TAG_TO_TYPE_MAP.put(Tag.CLASS, CONSTANT_CLASS);
       
    45         TAG_TO_TYPE_MAP.put(Tag.FIELDREF, CONSTANT_FIELDREF);
       
    46         TAG_TO_TYPE_MAP.put(Tag.METHODREF, CONSTANT_METHODREF);
       
    47         TAG_TO_TYPE_MAP.put(Tag.INTERFACEMETHODREF, CONSTANT_INTERFACEMETHODREF);
       
    48         TAG_TO_TYPE_MAP.put(Tag.STRING, CONSTANT_STRING);
       
    49         TAG_TO_TYPE_MAP.put(Tag.INTEGER, CONSTANT_INTEGER);
       
    50         TAG_TO_TYPE_MAP.put(Tag.FLOAT, CONSTANT_FLOAT);
       
    51         TAG_TO_TYPE_MAP.put(Tag.LONG, CONSTANT_LONG);
       
    52         TAG_TO_TYPE_MAP.put(Tag.DOUBLE, CONSTANT_DOUBLE);
       
    53         TAG_TO_TYPE_MAP.put(Tag.NAMEANDTYPE, CONSTANT_NAMEANDTYPE);
       
    54         TAG_TO_TYPE_MAP.put(Tag.UTF8, CONSTANT_UTF8);
       
    55         TAG_TO_TYPE_MAP.put(Tag.METHODHANDLE, CONSTANT_METHODHANDLE);
       
    56         TAG_TO_TYPE_MAP.put(Tag.METHODTYPE, CONSTANT_METHODTYPE);
       
    57         TAG_TO_TYPE_MAP.put(Tag.INVOKEDYNAMIC, CONSTANT_INVOKEDYNAMIC);
       
    58         TAG_TO_TYPE_MAP.put(Tag.INVALID, CONSTANT_INVALID);
       
    59     }
       
    60     private static final WhiteBox WB = WhiteBox.getWhiteBox();
       
    61     private final Map<ConstantTypes, Validator> typeTests;
       
    62 
       
    63     public static enum ConstantTypes {
       
    64         CONSTANT_CLASS {
       
    65             @Override
       
    66             public TestedCPEntry getTestedCPEntry(DummyClasses dummyClass, int index) {
       
    67                 ConstantPool constantPoolSS = dummyClass.constantPoolSS;
       
    68                 checkIndex(constantPoolSS, index);
       
    69                 Class<?> klass = constantPoolSS.getClassAt(index);
       
    70                 String klassName = klass.getName();
       
    71                 TestedCPEntry[] testedEntries = dummyClass.testedCP.get(this);
       
    72                 for (TestedCPEntry entry : testedEntries) {
       
    73                     if (entry.klass.replaceAll("/", "\\.").equals(klassName)) {
       
    74                         return entry;
       
    75                     }
       
    76                 }
       
    77                 return null;
       
    78             }
       
    79         },
       
    80         CONSTANT_FIELDREF {
       
    81             @Override
       
    82             public TestedCPEntry getTestedCPEntry(DummyClasses dummyClass, int index) {
       
    83                 return this.getTestedCPEntryForMethodAndField(dummyClass, index);
       
    84             }
       
    85         },
       
    86         CONSTANT_METHODREF {
       
    87             @Override
       
    88             public TestedCPEntry getTestedCPEntry(DummyClasses dummyClass, int index) {
       
    89                 return this.getTestedCPEntryForMethodAndField(dummyClass, index);
       
    90             }
       
    91         },
       
    92         CONSTANT_INTERFACEMETHODREF {
       
    93             @Override
       
    94             public TestedCPEntry getTestedCPEntry(DummyClasses dummyClass, int index) {
       
    95                 return this.getTestedCPEntryForMethodAndField(dummyClass, index);
       
    96             }
       
    97         },
       
    98         CONSTANT_STRING {
       
    99             @Override
       
   100             public TestedCPEntry getTestedCPEntry(DummyClasses dummyClass, int index) {
       
   101                 ConstantPool constantPoolSS = dummyClass.constantPoolSS;
       
   102                 checkIndex(constantPoolSS, index);
       
   103                 String value = constantPoolSS.getStringAt(index);
       
   104                 TestedCPEntry[] testedEntries = dummyClass.testedCP.get(this);
       
   105                 for (TestedCPEntry entry : testedEntries) {
       
   106                     if (entry.name.equals(value)) {
       
   107                         return entry;
       
   108                     }
       
   109                 }
       
   110                 return null;
       
   111             }
       
   112         },
       
   113         CONSTANT_INTEGER,
       
   114         CONSTANT_FLOAT,
       
   115         CONSTANT_LONG,
       
   116         CONSTANT_DOUBLE,
       
   117         CONSTANT_NAMEANDTYPE,
       
   118         CONSTANT_UTF8,
       
   119         CONSTANT_METHODHANDLE,
       
   120         CONSTANT_METHODTYPE,
       
   121         CONSTANT_INVOKEDYNAMIC {
       
   122             @Override
       
   123             public TestedCPEntry getTestedCPEntry(DummyClasses dummyClass, int index) {
       
   124                 ConstantPool constantPoolSS = dummyClass.constantPoolSS;
       
   125                 checkIndex(constantPoolSS, index);
       
   126                 int nameAndTypeIndex = constantPoolSS.getNameAndTypeRefIndexAt(index);
       
   127                 String[] info = constantPoolSS.getNameAndTypeRefInfoAt(nameAndTypeIndex);
       
   128                 TestedCPEntry[] testedEntries = dummyClass.testedCP.get(this);
       
   129                 for (TestedCPEntry entry : testedEntries) {
       
   130                     if (info[0].equals(entry.name) && info[1].equals(entry.type)) {
       
   131                         return entry;
       
   132                     }
       
   133                 }
       
   134                 return null;
       
   135             }
       
   136         },
       
   137         CONSTANT_INVALID;
       
   138 
       
   139         public TestedCPEntry getTestedCPEntry(DummyClasses dummyClass, int index) {
       
   140             return null; // returning null by default
       
   141         }
       
   142 
       
   143         public TestedCPEntry[] getAllCPEntriesForType(DummyClasses dummyClass) {
       
   144             TestedCPEntry[] toReturn = dummyClass.testedCP.get(this);
       
   145             if (toReturn == null) {
       
   146                 return new TestedCPEntry[0];
       
   147             }
       
   148             return dummyClass.testedCP.get(this);
       
   149         }
       
   150 
       
   151         protected TestedCPEntry getTestedCPEntryForMethodAndField(DummyClasses dummyClass, int index) {
       
   152             ConstantPool constantPoolSS = dummyClass.constantPoolSS;
       
   153             checkIndex(constantPoolSS, index);
       
   154             String[] info = constantPoolSS.getMemberRefInfoAt(index);
       
   155             TestedCPEntry[] testedEntries = dummyClass.testedCP.get(this);
       
   156             for (TestedCPEntry entry : testedEntries) {
       
   157                 if (info[0].equals(entry.klass) && info[1].equals(entry.name) && info[2].equals(entry.type)) {
       
   158                     return entry;
       
   159                 }
       
   160             }
       
   161             return null;
       
   162         }
       
   163 
       
   164         protected void checkIndex(ConstantPool constantPoolSS, int index) {
       
   165             ConstantPool.Tag tag = constantPoolSS.getTagAt(index);
       
   166             ConstantTypes type = mapTagToCPType(tag);
       
   167             if (!this.equals(type)) {
       
   168                 String msg = String.format("TESTBUG: CP tag should be a %s, but is %s",
       
   169                                            this.name(),
       
   170                                            type.name());
       
   171                throw new Error(msg);
       
   172             }
       
   173         }
       
   174     }
    38 
   175 
    39     public static interface Validator {
   176     public static interface Validator {
    40         void validate(jdk.vm.ci.meta.ConstantPool constantPoolCTVM,
   177         void validate(jdk.vm.ci.meta.ConstantPool constantPoolCTVM,
    41                 ConstantPool constantPoolSS,
   178                       ConstantTypes cpType,
    42             ConstantPoolTestsHelper.DummyClasses dummyClass, int index);
   179                       DummyClasses dummyClass,
    43     }
   180                       int index);
    44 
   181     }
    45     public ConstantPoolTestCase(Map<ConstantPoolTestsHelper.ConstantTypes,Validator> typeTests) {
   182 
       
   183     public static class TestedCPEntry {
       
   184         public final String klass;
       
   185         public final String name;
       
   186         public final String type;
       
   187         public final byte[] opcodes;
       
   188         public final long accFlags;
       
   189 
       
   190         public TestedCPEntry(String klass, String name, String type, byte[] opcodes, long accFlags) {
       
   191             this.klass = klass;
       
   192             this.name = name;
       
   193             this.type = type;
       
   194             if (opcodes != null) {
       
   195                 this.opcodes = new byte[opcodes.length];
       
   196                 System.arraycopy(opcodes, 0, this.opcodes, 0, opcodes.length);
       
   197             } else {
       
   198                 this.opcodes = null;
       
   199             }
       
   200             this.accFlags = accFlags;
       
   201         }
       
   202 
       
   203         public TestedCPEntry(String klass, String name, String type, byte[] opcodes) {
       
   204             this(klass, name, type, opcodes, 0);
       
   205         }
       
   206 
       
   207         public TestedCPEntry(String klass, String name, String type) {
       
   208             this(klass, name, type, null, 0);
       
   209         }
       
   210     }
       
   211 
       
   212     public static ConstantTypes mapTagToCPType(Tag tag) {
       
   213         return TAG_TO_TYPE_MAP.get(tag);
       
   214     }
       
   215 
       
   216     public ConstantPoolTestCase(Map<ConstantTypes, Validator> typeTests) {
    46         this.typeTests = new HashMap<>();
   217         this.typeTests = new HashMap<>();
    47         this.typeTests.putAll(typeTests);
   218         this.typeTests.putAll(typeTests);
    48     }
   219     }
    49 
   220 
    50     private void messageOnFail(Throwable t,
       
    51             ConstantPoolTestsHelper.ConstantTypes cpType,
       
    52             ConstantPoolTestsHelper.DummyClasses dummyClass, int index) {
       
    53         ConstantPool constantPoolSS = SharedSecrets.getJavaLangAccess().
       
    54                         getConstantPool(dummyClass.klass);
       
    55         String msg = String.format("Test for %s constant pool entry of"
       
    56                         + " type %s",
       
    57                         dummyClass.klass, cpType.name());
       
    58         switch (cpType) {
       
    59             case CONSTANT_CLASS:
       
    60             case CONSTANT_STRING:
       
    61             case CONSTANT_METHODTYPE:
       
    62                 String utf8 = constantPoolSS
       
    63                         .getUTF8At((int) dummyClass.cp.get(index).value);
       
    64                 msg = String.format("%s (%s) failed with %s", msg, utf8, t);
       
    65                 break;
       
    66             case CONSTANT_INTEGER:
       
    67                 int intValue = constantPoolSS.getIntAt(index);
       
    68                 msg = String.format("%s (%d) failed with %s", msg, intValue, t);
       
    69                 break;
       
    70             case CONSTANT_LONG:
       
    71                 long longValue = constantPoolSS.getLongAt(index);
       
    72                 msg = String.format("%s (%d) failed with %s", msg, longValue, t);
       
    73                 break;
       
    74             case CONSTANT_FLOAT:
       
    75                 float floatValue = constantPoolSS.getFloatAt(index);
       
    76                 msg = String.format("%s (%E) failed with %s", msg, floatValue, t);
       
    77                 break;
       
    78             case CONSTANT_DOUBLE:
       
    79                 double doubleValue = constantPoolSS.getDoubleAt(index);
       
    80                 msg = String.format("%s (%E) failed with %s", msg, doubleValue, t);
       
    81                 break;
       
    82             case CONSTANT_UTF8:
       
    83                 String utf8Value = constantPoolSS.getUTF8At(index);
       
    84                 msg = String.format("%s (%s) failed with %s", msg, utf8Value, t);
       
    85                 break;
       
    86             case CONSTANT_INVOKEDYNAMIC:
       
    87                 index = ((int[]) dummyClass.cp.get(index).value)[1];
       
    88             case CONSTANT_NAMEANDTYPE:
       
    89                 String name = constantPoolSS
       
    90                         .getUTF8At(((int[]) dummyClass.cp.get(index).value)[0]);
       
    91                 String type = constantPoolSS
       
    92                         .getUTF8At(((int[]) dummyClass.cp.get(index).value)[1]);
       
    93                 msg = String.format("%s (%s:%s) failed with %s",
       
    94                         msg, name, type, t);
       
    95                 break;
       
    96             case CONSTANT_METHODHANDLE:
       
    97                 index = ((int[]) dummyClass.cp.get(index).value)[1];
       
    98             case CONSTANT_METHODREF:
       
    99             case CONSTANT_INTERFACEMETHODREF:
       
   100             case CONSTANT_FIELDREF:
       
   101                 int classIndex = ((int[]) dummyClass.cp.get(index).value)[0];
       
   102                 int nameAndTypeIndex = ((int[]) dummyClass.cp.get(index).value)[1];
       
   103                 String cName = constantPoolSS
       
   104                         .getUTF8At((int) dummyClass.cp.get(classIndex).value);
       
   105                 String mName = constantPoolSS
       
   106                         .getUTF8At(((int[]) dummyClass.cp.get(nameAndTypeIndex).value)[0]);
       
   107                 String mType = constantPoolSS
       
   108                         .getUTF8At(((int[]) dummyClass.cp.get(nameAndTypeIndex).value)[1]);
       
   109                 msg = String.format("%s (%s.%s:%s) failed with %s ",
       
   110                         msg, cName, mName, mType, t);
       
   111                 break;
       
   112             default:
       
   113                 msg = String.format("Test bug: unknown constant type %s ", cpType);
       
   114         }
       
   115         throw new Error(msg + t.getMessage(), t);
       
   116     }
       
   117 
       
   118     public void test() {
   221     public void test() {
   119         for (ConstantPoolTestsHelper.DummyClasses dummyClass
   222         for (DummyClasses dummyClass : DummyClasses.values()) {
   120                 : ConstantPoolTestsHelper.DummyClasses.values()) {
   223             boolean isCPCached = WB.getConstantPoolCacheLength(dummyClass.klass) > -1;
   121             System.out.printf("%nTesting dummy %s%n", dummyClass.klass);
   224             System.out.printf("Testing dummy %s with constant pool cached = %b%n",
   122             HotSpotResolvedObjectType holder = HotSpotResolvedObjectType
   225                               dummyClass.klass,
   123                     .fromObjectClass(dummyClass.klass);
   226                               isCPCached);
   124             jdk.vm.ci.meta.ConstantPool constantPoolCTVM
   227             HotSpotResolvedObjectType holder = HotSpotResolvedObjectType.fromObjectClass(dummyClass.klass);
   125                     = holder.getConstantPool();
   228             jdk.vm.ci.meta.ConstantPool constantPoolCTVM = holder.getConstantPool();
   126             ConstantPool constantPoolSS = SharedSecrets.getJavaLangAccess().
   229             ConstantPool constantPoolSS = dummyClass.constantPoolSS;
   127                         getConstantPool(dummyClass.klass);
   230             for (int i = 0; i < constantPoolSS.getSize(); i++) {
   128             for (Integer i : dummyClass.cp.keySet()) {
   231                 Tag tag = constantPoolSS.getTagAt(i);
   129                 ConstantPoolTestsHelper.ConstantTypes cpType
   232                 ConstantTypes cpType = mapTagToCPType(tag);
   130                         = dummyClass.cp.get(i).type;
       
   131                 if (!typeTests.keySet().contains(cpType)) {
   233                 if (!typeTests.keySet().contains(cpType)) {
   132                     continue;
   234                     continue;
   133                 }
   235                 }
   134                 try {
   236                 typeTests.get(cpType).validate(constantPoolCTVM, cpType, dummyClass, i);
   135                     typeTests.get(cpType).validate(constantPoolCTVM,
       
   136                             constantPoolSS, dummyClass, i);
       
   137                 } catch (Throwable t) {
       
   138                     messageOnFail(t, cpType, dummyClass, i);
       
   139                 }
       
   140             }
   237             }
   141         }
   238         }
   142     }
   239     }
   143 }
   240 }
   144