1 /*
   2  * Copyright (c) 2012, 2019, 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  * @test
  26  * @requires vm.jvmci
  27  * @library ../../../../../
  28  * @modules jdk.internal.vm.ci/jdk.vm.ci.meta
  29  *          jdk.internal.vm.ci/jdk.vm.ci.runtime
  30  *          java.base/jdk.internal.misc
  31  * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler jdk.vm.ci.runtime.test.TestMetaAccessProvider
  32  */
  33 
  34 package jdk.vm.ci.runtime.test;
  35 
  36 import jdk.vm.ci.meta.DeoptimizationAction;
  37 import jdk.vm.ci.meta.DeoptimizationReason;
  38 import jdk.vm.ci.meta.JavaConstant;
  39 import jdk.vm.ci.meta.JavaKind;
  40 import jdk.vm.ci.meta.MetaAccessProvider;
  41 import jdk.vm.ci.meta.ResolvedJavaField;
  42 import jdk.vm.ci.meta.ResolvedJavaMethod;
  43 import jdk.vm.ci.meta.ResolvedJavaType;
  44 import jdk.vm.ci.meta.Signature;
  45 import org.junit.Test;
  46 
  47 import java.lang.reflect.Field;
  48 import java.lang.reflect.Method;
  49 
  50 import static jdk.vm.ci.meta.MetaUtil.toInternalName;
  51 import static org.junit.Assert.assertEquals;
  52 import static org.junit.Assert.assertNotNull;
  53 import static org.junit.Assert.assertNull;
  54 import static org.junit.Assert.assertTrue;
  55 
  56 /**
  57  * Tests for {@link MetaAccessProvider}.
  58  */
  59 public class TestMetaAccessProvider extends TypeUniverse {
  60     private static final DeoptimizationAction DEOPT_ACTION = DeoptimizationAction.InvalidateRecompile;
  61     private static final DeoptimizationReason DEOPT_REASON = DeoptimizationReason.Aliasing;
  62     private static final int INT_23BITS_SET = 0x7FFFFF;
  63     private static final int[] DEBUG_IDS = new int[]{0, 1, 42, INT_23BITS_SET};
  64     private static final int[] VALID_ENCODED_VALUES = new int[]{
  65                     metaAccess.encodeDeoptActionAndReason(DEOPT_ACTION, DEOPT_REASON, DEBUG_IDS[0]).asInt(),
  66                     metaAccess.encodeDeoptActionAndReason(DEOPT_ACTION, DEOPT_REASON, DEBUG_IDS[1]).asInt(),
  67                     metaAccess.encodeDeoptActionAndReason(DEOPT_ACTION, DEOPT_REASON, DEBUG_IDS[2]).asInt(),
  68                     metaAccess.encodeDeoptActionAndReason(DEOPT_ACTION, DEOPT_REASON, DEBUG_IDS[3]).asInt()
  69     };
  70 
  71     private static boolean isUnsafeAnoymous(ResolvedJavaType type) {
  72         return type.getHostClass() != null;
  73     }
  74 
  75     @Test
  76     public void lookupJavaTypeTest() {
  77         for (Class<?> c : classes) {
  78             ResolvedJavaType type = metaAccess.lookupJavaType(c);
  79             assertNotNull(c.toString(), type);
  80             if (!isUnsafeAnoymous(type)) {
  81                 assertEquals(c.toString(), type.getName(), toInternalName(c.getName()));
  82                 assertEquals(c.toString(), type.getName(), toInternalName(type.toJavaName()));
  83                 assertEquals(c.toString(), c.getName(), type.toClassName());
  84                 if (!type.isArray()) {
  85                     assertEquals(c.toString(), c.getName(), type.toJavaName());
  86                 }
  87             }
  88         }
  89     }
  90 
  91     @Test(expected = IllegalArgumentException.class)
  92     public void lookupJavaTypeNegativeTest() {
  93         metaAccess.lookupJavaType((Class<?>) null);
  94     }
  95 
  96     @Test
  97     public void lookupJavaTypesTest() {
  98         ResolvedJavaType[] result = metaAccess.lookupJavaTypes(classes.toArray(new Class<?>[classes.size()]));
  99         int counter = 0;
 100         for (Class<?> aClass : classes) {
 101             if (!isUnsafeAnoymous(result[counter])) {
 102                 assertEquals("Unexpected javaType: " + result[counter] + " while expecting of class: " + aClass, result[counter].toClassName(), aClass.getName());
 103             }
 104             counter++;
 105         }
 106     }
 107 
 108     @Test(expected = NullPointerException.class)
 109     public void lookupJavaTypesNegative1Test() {
 110         assertNull("Expected null", metaAccess.lookupJavaTypes(null));
 111     }
 112 
 113     @Test(expected = IllegalArgumentException.class)
 114     public void lookupJavaTypesNegative2Test() {
 115         ResolvedJavaType[] result = metaAccess.lookupJavaTypes(new Class<?>[]{null, null, null});
 116         for (ResolvedJavaType aType : result) {
 117             assertNull("Expected null javaType", aType);
 118         }
 119         result = metaAccess.lookupJavaTypes(new Class<?>[]{String.class, String.class});
 120         assertEquals("Results not equals", result[0].getClass(), result[1].getClass());
 121         assertEquals("Result is not String.class", result[0].getClass(), String.class);
 122     }
 123 
 124     @Test
 125     public void lookupJavaMethodTest() {
 126         for (Class<?> c : classes) {
 127             for (Method reflect : c.getDeclaredMethods()) {
 128                 ResolvedJavaMethod method = metaAccess.lookupJavaMethod(reflect);
 129                 assertNotNull(method);
 130                 assertTrue(method.getDeclaringClass().equals(metaAccess.lookupJavaType(reflect.getDeclaringClass())));
 131             }
 132         }
 133     }
 134 
 135     @Test(expected = NullPointerException.class)
 136     public void lookupJavaMethodNegativeTest() {
 137         metaAccess.lookupJavaMethod(null);
 138     }
 139 
 140     @Test
 141     public void lookupJavaFieldTest() {
 142         for (Class<?> c : classes) {
 143             for (Field reflect : c.getDeclaredFields()) {
 144                 ResolvedJavaField field = metaAccess.lookupJavaField(reflect);
 145                 assertNotNull(field);
 146                 assertTrue(field.getDeclaringClass().equals(metaAccess.lookupJavaType(reflect.getDeclaringClass())));
 147             }
 148         }
 149     }
 150 
 151     @Test
 152     public void lookupJavaTypeConstantTest() {
 153         for (ConstantValue cv : constants()) {
 154             JavaConstant c = cv.value;
 155             if (c.getJavaKind() == JavaKind.Object && !c.isNull()) {
 156                 Object o = cv.boxed;
 157                 ResolvedJavaType type = metaAccess.lookupJavaType(c);
 158                 assertNotNull(type);
 159                 assertTrue(type.equals(metaAccess.lookupJavaType(o.getClass())));
 160             } else {
 161                 assertEquals(metaAccess.lookupJavaType(c), null);
 162             }
 163         }
 164     }
 165 
 166     @Test(expected = NullPointerException.class)
 167     public void lookupJavaTypeConstantNegativeTest() {
 168         metaAccess.lookupJavaType((JavaConstant) null);
 169     }
 170 
 171     @Test
 172     public void getMemorySizeTest() {
 173         for (ConstantValue cv : constants()) {
 174             JavaConstant c = cv.value;
 175             long memSize = metaAccess.getMemorySize(c);
 176             if (c.isNull()) {
 177                 assertEquals("Expected size = 0 for null", memSize, 0L);
 178             } else {
 179                 assertTrue("Expected size != 0 for " + cv, memSize != 0L);
 180             }
 181         }
 182     }
 183 
 184     @Test(expected = NullPointerException.class)
 185     public void getMemorySizeNegativeTest() {
 186         metaAccess.getMemorySize(null);
 187     }
 188 
 189     @Test
 190     public void parseMethodDescriptorTest() {
 191         for (String retType : new String[]{"V", "Z", "Ljava/lang/String;"}) {
 192             for (String paramTypes : new String[]{"", "B",
 193                             "Ljava/lang/String;", "JLjava/lang/String;",
 194                             "Ljava/lang/String;F",
 195                             "[Ljava/lang/String;ZBCDFIJLS[ILjava/lang/Object;"}) {
 196                 String signature = "(" + paramTypes + ")" + retType;
 197                 Signature result = metaAccess.parseMethodDescriptor(signature);
 198                 assertEquals("Expected signatures to be equal", result.toMethodDescriptor(), signature);
 199             }
 200         }
 201     }
 202 
 203     @Test(expected = NullPointerException.class)
 204     public void parseMethodDescriptorNegativeNullTest() {
 205         metaAccess.parseMethodDescriptor(null);
 206     }
 207 
 208     @Test(expected = NullPointerException.class)
 209     public void encodeDeoptActionAndReasonNegative1Test() {
 210         metaAccess.encodeDeoptActionAndReason(null, DeoptimizationReason.Aliasing, 0);
 211 
 212     }
 213 
 214     @Test(expected = NullPointerException.class)
 215     public void encodeDeoptActionAndReasonNegative2Test() {
 216         metaAccess.encodeDeoptActionAndReason(DeoptimizationAction.InvalidateRecompile, null, 0);
 217     }
 218 
 219     @Test
 220     public void decodeDeoptReasonTest() {
 221         for (int encoded : VALID_ENCODED_VALUES) {
 222             JavaConstant value = JavaConstant.forInt(encoded);
 223             DeoptimizationReason reason = metaAccess.decodeDeoptReason(value);
 224             assertEquals("Expected equal reasons", reason, DEOPT_REASON);
 225         }
 226     }
 227 
 228     @Test
 229     public void decodeDeoptReasonNegative1Test() {
 230         int encoded = 42;
 231         JavaConstant value = JavaConstant.forInt(encoded);
 232         metaAccess.decodeDeoptReason(value);
 233     }
 234 
 235     @Test(expected = NullPointerException.class)
 236     public void decodeDeoptReasonNegative2Test() {
 237         metaAccess.decodeDeoptReason(null);
 238     }
 239 
 240     @Test
 241     public void decodeDeoptActionTest() {
 242         for (int encoded : VALID_ENCODED_VALUES) {
 243             JavaConstant value = JavaConstant.forInt(encoded);
 244             DeoptimizationAction action = metaAccess.decodeDeoptAction(value);
 245             assertEquals("Expected equal actions", action, DEOPT_ACTION);
 246         }
 247     }
 248 
 249     @Test
 250     public void decodeDeoptActionNegative1Test() {
 251         int encoded = 123456789;
 252         JavaConstant value = JavaConstant.forInt(encoded);
 253         metaAccess.decodeDeoptAction(value);
 254     }
 255 
 256     @Test(expected = NullPointerException.class)
 257     public void decodeDeoptActionNegative2Test() {
 258         metaAccess.decodeDeoptAction(null);
 259     }
 260 
 261     @Test
 262     public void decodeDebugIdTest() {
 263         for (int i = 0; i < VALID_ENCODED_VALUES.length; i++) {
 264             JavaConstant value = JavaConstant.forInt(VALID_ENCODED_VALUES[i]);
 265             assertEquals("Unexpected debugId", metaAccess.decodeDebugId(value), DEBUG_IDS[i]);
 266         }
 267     }
 268 
 269     @Test
 270     public void parseSignatureTest() {
 271         for (String badSig : new String[]{"", "()", "(", "()Vextra", "()E", "(E)", "(Ljava.lang.Object;)V"}) {
 272             try {
 273                 metaAccess.parseMethodDescriptor(badSig);
 274                 throw new AssertionError("Expected signature to be invalid: " + badSig);
 275             } catch (IllegalArgumentException e) {
 276             }
 277         }
 278     }
 279 }