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.HotSpotConstantPool;
  30 import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
  31 import jdk.internal.misc.SharedSecrets;
  32 import sun.reflect.ConstantPool;
  33 
  34 /**
  35  * Common class for jdk.vm.ci.hotspot.CompilerToVM constant pool tests
  36  */
  37 public class ConstantPoolTestCase {
  38 
  39     private final Map<ConstantPoolTestsHelper.ConstantTypes, Validator> typeTests;
  40     
  41     public static interface Validator {
  42         void validate(HotSpotConstantPool constantPoolCTVM, ConstantPool constantPoolSS,
  43             ConstantPoolTestsHelper.DummyClasses dummyClass, int index);
  44     }
  45 
  46     public ConstantPoolTestCase(Map<ConstantPoolTestsHelper.ConstantTypes, Validator> typeTests) {
  47         this.typeTests = new HashMap<>();
  48         this.typeTests.putAll(typeTests);
  49     }   
  50        
  51     private void messageOnFail(Throwable t,
  52             ConstantPoolTestsHelper.ConstantTypes cpType,
  53             ConstantPoolTestsHelper.DummyClasses dummyClass, int index) {
  54         ConstantPool constantPoolSS = SharedSecrets.getJavaLangAccess().
  55                         getConstantPool(dummyClass.klass);
  56         String msg = String.format("Test for %s constant pool entry of"
  57                         + " type %s",
  58                         dummyClass.klass, cpType.name());
  59         switch (cpType) {
  60             case CONSTANT_CLASS:
  61             case CONSTANT_STRING:
  62             case CONSTANT_METHODTYPE:    
  63                 String utf8 = constantPoolSS
  64                         .getUTF8At((int) dummyClass.cp.get(index).value);
  65                 msg = String.format("%s (%s) failed with %s", msg, utf8, t);
  66                 break;
  67             case CONSTANT_INTEGER:
  68                 int intValue = constantPoolSS.getIntAt(index);
  69                 msg = String.format("%s (%d) failed with %s", msg, intValue, t);
  70                 break;
  71             case CONSTANT_LONG:
  72                 long longValue = constantPoolSS.getLongAt(index);
  73                 msg = String.format("%s (%d) failed with %s", msg, longValue, t);
  74                 break;
  75             case CONSTANT_FLOAT:
  76                 float floatValue = constantPoolSS.getFloatAt(index);
  77                 msg = String.format("%s (%E) failed with %s", msg, floatValue, t);
  78                 break;
  79             case CONSTANT_DOUBLE:
  80                 double doubleValue = constantPoolSS.getDoubleAt(index);
  81                 msg = String.format("%s (%E) failed with %s", msg, doubleValue, t);
  82                 break;
  83             case CONSTANT_UTF8:
  84                 String utf8Value = constantPoolSS.getUTF8At(index);
  85                 msg = String.format("%s (%s) failed with %s", msg, utf8Value, t);
  86                 break;
  87             case CONSTANT_INVOKEDYNAMIC:
  88                 index = ((int[]) dummyClass.cp.get(index).value)[1];
  89             case CONSTANT_NAMEANDTYPE:
  90                 String name = constantPoolSS
  91                         .getUTF8At(((int[]) dummyClass.cp.get(index).value)[0]);
  92                 String type = constantPoolSS
  93                         .getUTF8At(((int[]) dummyClass.cp.get(index).value)[1]);
  94                 msg = String.format("%s (%s:%s) failed with %s",
  95                         msg, name, type, t);
  96                 break;
  97             case CONSTANT_METHODHANDLE:
  98                 index = ((int[]) dummyClass.cp.get(index).value)[1]; 
  99             case CONSTANT_METHODREF:
 100             case CONSTANT_INTERFACEMETHODREF:
 101             case CONSTANT_FIELDREF:
 102                 int classIndex = ((int[]) dummyClass.cp.get(index).value)[0];
 103                 int nameAndTypeIndex = ((int[]) dummyClass.cp.get(index).value)[1];
 104                 String cName = constantPoolSS
 105                         .getUTF8At((int) dummyClass.cp.get(classIndex).value);
 106                 String mName = constantPoolSS
 107                         .getUTF8At(((int[]) dummyClass.cp.get(nameAndTypeIndex).value)[0]);
 108                 String mType = constantPoolSS
 109                         .getUTF8At(((int[]) dummyClass.cp.get(nameAndTypeIndex).value)[1]);
 110                 msg = String.format("%s (%s.%s:%s) failed with %s ",
 111                         msg, cName, mName, mType, t);
 112                 break;
 113             default:
 114                 msg = String.format("Test bug: unknown constant type %s ", cpType);
 115         }
 116         throw new Error(msg + t.getMessage(), t);
 117     }
 118 
 119     public void test() {
 120         for (ConstantPoolTestsHelper.DummyClasses dummyClass
 121                 : ConstantPoolTestsHelper.DummyClasses.values()) {
 122             System.out.printf("%nTesting dummy %s%n", dummyClass.klass);
 123             HotSpotResolvedObjectTypeImpl holder = HotSpotResolvedObjectTypeImpl
 124                     .fromObjectClass(dummyClass.klass);
 125             HotSpotConstantPool constantPoolCTVM = 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