001/*
002 * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.hotspot.test;
024
025import java.lang.invoke.*;
026
027import org.junit.*;
028
029import com.oracle.graal.api.directives.*;
030import com.oracle.graal.api.replacements.*;
031import com.oracle.graal.replacements.test.*;
032
033/**
034 * Tests HotSpot specific {@link MethodSubstitution}s.
035 */
036public class HotSpotMethodSubstitutionTest extends MethodSubstitutionTest {
037
038    @Test
039    public void testObjectSubstitutions() {
040        TestClassA obj = new TestClassA();
041
042        testGraph("getClass0");
043        testGraph("objectHashCode");
044
045        test("getClass0", "a string");
046        test("objectHashCode", obj);
047    }
048
049    @SuppressWarnings("all")
050    public static Class<?> getClass0(Object obj) {
051        return obj.getClass();
052    }
053
054    @SuppressWarnings("all")
055    public static int objectHashCode(TestClassA obj) {
056        return obj.hashCode();
057    }
058
059    @Test
060    public void testClassSubstitutions() {
061        testGraph("getModifiers");
062        testGraph("isInterface");
063        testGraph("isArray");
064        testGraph("isPrimitive");
065        testGraph("getSuperClass");
066        testGraph("getComponentType");
067
068        for (Class<?> c : new Class[]{getClass(), Cloneable.class, int[].class, String[][].class}) {
069            test("getModifiers", c);
070            test("isInterface", c);
071            test("isArray", c);
072            test("isPrimitive", c);
073            test("getSuperClass", c);
074            test("getComponentType", c);
075        }
076    }
077
078    @SuppressWarnings("all")
079    public static int getModifiers(Class<?> clazz) {
080        return clazz.getModifiers();
081    }
082
083    @SuppressWarnings("all")
084    public static boolean isInterface(Class<?> clazz) {
085        return clazz.isInterface();
086    }
087
088    @SuppressWarnings("all")
089    public static boolean isArray(Class<?> clazz) {
090        return clazz.isArray();
091    }
092
093    @SuppressWarnings("all")
094    public static boolean isPrimitive(Class<?> clazz) {
095        return clazz.isPrimitive();
096    }
097
098    @SuppressWarnings("all")
099    public static Class<?> getSuperClass(Class<?> clazz) {
100        return clazz.getSuperclass();
101    }
102
103    @SuppressWarnings("all")
104    public static Class<?> getComponentType(Class<?> clazz) {
105        return clazz.getComponentType();
106    }
107
108    @Test
109    public void testThreadSubstitutions() {
110        testGraph("currentThread");
111        testGraph("threadIsInterrupted");
112        testGraph("threadInterrupted");
113
114        Thread currentThread = Thread.currentThread();
115        test("currentThread", currentThread);
116        test("threadIsInterrupted", currentThread);
117    }
118
119    @SuppressWarnings("all")
120    public static boolean currentThread(Thread other) {
121        return Thread.currentThread() == other;
122    }
123
124    @SuppressWarnings("all")
125    public static boolean threadIsInterrupted(Thread thread) {
126        return thread.isInterrupted();
127    }
128
129    @SuppressWarnings("all")
130    public static boolean threadInterrupted() {
131        return Thread.interrupted();
132    }
133
134    @Test
135    public void testSystemSubstitutions() {
136        testGraph("systemTime");
137        testGraph("systemIdentityHashCode");
138
139        for (Object o : new Object[]{this, new int[5], new String[2][], new Object()}) {
140            test("systemIdentityHashCode", o);
141        }
142    }
143
144    @SuppressWarnings("all")
145    public static long systemTime() {
146        return System.currentTimeMillis() + System.nanoTime();
147    }
148
149    @SuppressWarnings("all")
150    public static int systemIdentityHashCode(Object obj) {
151        return System.identityHashCode(obj);
152    }
153
154    private static class TestClassA {
155    }
156
157    public static String testCallSiteGetTargetSnippet(int i) throws Exception {
158        ConstantCallSite site;
159        MethodHandles.Lookup lookup = MethodHandles.lookup();
160        switch (i) {
161            case 1:
162                site = GraalDirectives.opaque(new ConstantCallSite(lookup.findVirtual(String.class, "replace", MethodType.methodType(String.class, char.class, char.class))));
163                break;
164            default:
165                site = GraalDirectives.opaque(new ConstantCallSite(lookup.findStatic(java.util.Arrays.class, "asList", MethodType.methodType(java.util.List.class, Object[].class))));
166        }
167        return site.getTarget().toString();
168    }
169
170    public static String testCastSnippet(int i, Object obj) throws Exception {
171        Class<?> c;
172        switch (i) {
173            case 1:
174                c = GraalDirectives.opaque(Number.class);
175                break;
176            default:
177                c = GraalDirectives.opaque(Integer.class);
178                break;
179        }
180        return c.cast(obj).toString();
181    }
182
183    public static String testGetClassSnippet(int i) {
184        Object c;
185        switch (i) {
186            case 1:
187                c = GraalDirectives.opaque(new Object());
188                break;
189            default:
190                c = GraalDirectives.opaque("TEST");
191                break;
192        }
193        return c.getClass().toString();
194    }
195
196    /**
197     * Tests ambiguous receiver of CallSite.getTarget.
198     */
199    @Test
200    public void testCallSiteGetTarget() {
201        test("testCallSiteGetTargetSnippet", 1);
202    }
203
204    /**
205     * Tests ambiguous receiver of Class.cast.
206     */
207    @Test
208    public void testCast() {
209        test("testCastSnippet", 1, new Integer(1));
210    }
211
212    /**
213     * Tests ambiguous receiver of Object.getClass.
214     */
215    @Test
216    public void testGetClass() {
217        test("testGetClassSnippet", 1);
218    }
219}