1 /*
   2  * Copyright (c) 2012, 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 package org.graalvm.compiler.hotspot.test;
  24 
  25 import java.lang.invoke.ConstantCallSite;
  26 import java.lang.invoke.MethodHandles;
  27 import java.lang.invoke.MethodType;
  28 
  29 import org.junit.Test;
  30 
  31 import org.graalvm.compiler.api.directives.GraalDirectives;
  32 import org.graalvm.compiler.api.replacements.MethodSubstitution;
  33 import org.graalvm.compiler.replacements.test.MethodSubstitutionTest;
  34 
  35 /**
  36  * Tests HotSpot specific {@link MethodSubstitution}s.
  37  */
  38 public class HotSpotMethodSubstitutionTest extends MethodSubstitutionTest {
  39 
  40     @Test
  41     public void testObjectSubstitutions() {
  42         TestClassA obj = new TestClassA();
  43 
  44         testGraph("getClass0");
  45         testGraph("objectHashCode");
  46 
  47         test("getClass0", "a string");
  48         test("objectHashCode", obj);
  49     }
  50 
  51     @SuppressWarnings("all")
  52     public static Class<?> getClass0(Object obj) {
  53         return obj.getClass();
  54     }
  55 
  56     @SuppressWarnings("all")
  57     public static int objectHashCode(TestClassA obj) {
  58         return obj.hashCode();
  59     }
  60 
  61     @Test
  62     public void testClassSubstitutions() {
  63         testGraph("getModifiers");
  64         testGraph("isInterface");
  65         testGraph("isArray");
  66         testGraph("isPrimitive");
  67         testGraph("getSuperClass");
  68         testGraph("getComponentType");
  69 
  70         for (Class<?> c : new Class<?>[]{getClass(), Cloneable.class, int[].class, String[][].class}) {
  71             test("getModifiers", c);
  72             test("isInterface", c);
  73             test("isArray", c);
  74             test("isPrimitive", c);
  75             test("getSuperClass", c);
  76             test("getComponentType", c);
  77         }
  78     }
  79 
  80     @SuppressWarnings("all")
  81     public static int getModifiers(Class<?> clazz) {
  82         return clazz.getModifiers();
  83     }
  84 
  85     @SuppressWarnings("all")
  86     public static boolean isInterface(Class<?> clazz) {
  87         return clazz.isInterface();
  88     }
  89 
  90     @SuppressWarnings("all")
  91     public static boolean isArray(Class<?> clazz) {
  92         return clazz.isArray();
  93     }
  94 
  95     @SuppressWarnings("all")
  96     public static boolean isPrimitive(Class<?> clazz) {
  97         return clazz.isPrimitive();
  98     }
  99 
 100     @SuppressWarnings("all")
 101     public static Class<?> getSuperClass(Class<?> clazz) {
 102         return clazz.getSuperclass();
 103     }
 104 
 105     @SuppressWarnings("all")
 106     public static Class<?> getComponentType(Class<?> clazz) {
 107         return clazz.getComponentType();
 108     }
 109 
 110     @Test
 111     public void testThreadSubstitutions() {
 112         testGraph("currentThread");
 113         testGraph("threadIsInterrupted");
 114         testGraph("threadInterrupted");
 115 
 116         Thread currentThread = Thread.currentThread();
 117         test("currentThread", currentThread);
 118         test("threadIsInterrupted", currentThread);
 119     }
 120 
 121     @SuppressWarnings("all")
 122     public static boolean currentThread(Thread other) {
 123         return Thread.currentThread() == other;
 124     }
 125 
 126     @SuppressWarnings("all")
 127     public static boolean threadIsInterrupted(Thread thread) {
 128         return thread.isInterrupted();
 129     }
 130 
 131     @SuppressWarnings("all")
 132     public static boolean threadInterrupted() {
 133         return Thread.interrupted();
 134     }
 135 
 136     @Test
 137     public void testSystemSubstitutions() {
 138         testGraph("systemTime");
 139         testGraph("systemIdentityHashCode");
 140 
 141         for (Object o : new Object[]{this, new int[5], new String[2][], new Object()}) {
 142             test("systemIdentityHashCode", o);
 143         }
 144     }
 145 
 146     @SuppressWarnings("all")
 147     public static long systemTime() {
 148         return System.currentTimeMillis() + System.nanoTime();
 149     }
 150 
 151     @SuppressWarnings("all")
 152     public static int systemIdentityHashCode(Object obj) {
 153         return System.identityHashCode(obj);
 154     }
 155 
 156     private static class TestClassA {
 157     }
 158 
 159     public static String testCallSiteGetTargetSnippet(int i) throws Exception {
 160         ConstantCallSite site;
 161         MethodHandles.Lookup lookup = MethodHandles.lookup();
 162         switch (i) {
 163             case 1:
 164                 site = GraalDirectives.opaque(new ConstantCallSite(lookup.findVirtual(String.class, "replace", MethodType.methodType(String.class, char.class, char.class))));
 165                 break;
 166             default:
 167                 site = GraalDirectives.opaque(new ConstantCallSite(lookup.findStatic(java.util.Arrays.class, "asList", MethodType.methodType(java.util.List.class, Object[].class))));
 168         }
 169         return site.getTarget().toString();
 170     }
 171 
 172     public static String testCastSnippet(int i, Object obj) throws Exception {
 173         Class<?> c;
 174         switch (i) {
 175             case 1:
 176                 c = GraalDirectives.opaque(Number.class);
 177                 break;
 178             default:
 179                 c = GraalDirectives.opaque(Integer.class);
 180                 break;
 181         }
 182         return c.cast(obj).toString();
 183     }
 184 
 185     public static String testGetClassSnippet(int i) {
 186         Object c;
 187         switch (i) {
 188             case 1:
 189                 c = GraalDirectives.opaque(new Object());
 190                 break;
 191             default:
 192                 c = GraalDirectives.opaque("TEST");
 193                 break;
 194         }
 195         return c.getClass().toString();
 196     }
 197 
 198     /**
 199      * Tests ambiguous receiver of CallSite.getTarget.
 200      */
 201     @Test
 202     public void testCallSiteGetTarget() {
 203         test("testCallSiteGetTargetSnippet", 1);
 204     }
 205 
 206     /**
 207      * Tests ambiguous receiver of Class.cast.
 208      */
 209     @Test
 210     public void testCast() {
 211         test("testCastSnippet", 1, new Integer(1));
 212     }
 213 
 214     /**
 215      * Tests ambiguous receiver of Object.getClass.
 216      */
 217     @Test
 218     public void testGetClass() {
 219         test("testGetClassSnippet", 1);
 220     }
 221 }