1 /*
   2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   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
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 package compiler.jvmci.compilerToVM;
  26 
  27 import java.util.HashMap;
  28 import java.util.Map;
  29 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
  30 import jdk.internal.misc.SharedSecrets;
  31 import sun.reflect.ConstantPool;
  32 
  33 /**
  34  * Common class for jdk.vm.ci.hotspot.CompilerToVM constant pool tests
  35  */
  36 public class ConstantPoolTestCase {
  37     private final Map<ConstantPoolTestsHelper.ConstantTypes, Validator> typeTests;
  38 
  39     public static interface Validator {
  40         void validate(jdk.vm.ci.meta.ConstantPool constantPoolCTVM,
  41                 ConstantPool constantPoolSS,
  42             ConstantPoolTestsHelper.DummyClasses dummyClass, int index);
  43     }
  44 
  45     public ConstantPoolTestCase(Map<ConstantPoolTestsHelper.ConstantTypes,Validator> typeTests) {
  46         this.typeTests = new HashMap<>();
  47         this.typeTests.putAll(typeTests);
  48     }
  49 
  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() {
 119         for (ConstantPoolTestsHelper.DummyClasses dummyClass
 120                 : ConstantPoolTestsHelper.DummyClasses.values()) {
 121             System.out.printf("%nTesting dummy %s%n", dummyClass.klass);
 122             HotSpotResolvedObjectType holder = HotSpotResolvedObjectType
 123                     .fromObjectClass(dummyClass.klass);
 124             jdk.vm.ci.meta.ConstantPool constantPoolCTVM
 125                     = holder.getConstantPool();
 126             ConstantPool constantPoolSS = SharedSecrets.getJavaLangAccess().
 127                         getConstantPool(dummyClass.klass);
 128             for (Integer i : dummyClass.cp.keySet()) {
 129                 ConstantPoolTestsHelper.ConstantTypes cpType
 130                         = dummyClass.cp.get(i).type;
 131                 if (!typeTests.keySet().contains(cpType)) {
 132                     continue;
 133                 }
 134                 try {
 135                     typeTests.get(cpType).validate(constantPoolCTVM,
 136                             constantPoolSS, dummyClass, i);
 137                 } catch (Throwable t) {
 138                     messageOnFail(t, cpType, dummyClass, i);
 139                 }
 140             }
 141         }
 142     }
 143 }
 144