001/*
002 * Copyright (c) 2013, 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 static com.oracle.graal.compiler.GraalCompiler.*;
026import static com.oracle.graal.compiler.common.GraalOptions.*;
027import static com.oracle.graal.nodes.ConstantNode.*;
028import static jdk.internal.jvmci.code.CodeUtil.*;
029import jdk.internal.jvmci.code.*;
030import jdk.internal.jvmci.code.CallingConvention.*;
031import jdk.internal.jvmci.hotspot.*;
032import jdk.internal.jvmci.meta.*;
033import jdk.internal.jvmci.options.*;
034import jdk.internal.jvmci.options.OptionValue.*;
035
036import org.junit.*;
037
038import com.oracle.graal.api.runtime.*;
039import com.oracle.graal.compiler.common.type.*;
040import com.oracle.graal.compiler.test.*;
041import com.oracle.graal.graph.iterators.*;
042import com.oracle.graal.hotspot.nodes.type.*;
043import com.oracle.graal.lir.asm.*;
044import com.oracle.graal.lir.phases.*;
045import com.oracle.graal.nodes.*;
046import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
047import com.oracle.graal.nodes.memory.*;
048import com.oracle.graal.phases.*;
049import com.oracle.graal.phases.tiers.*;
050import com.oracle.graal.runtime.*;
051
052/**
053 * use
054 *
055 * <pre>
056 * mx unittest AheadOfTimeCompilationTest @-XX:CompileCommand='print,*AheadOfTimeCompilationTest.*'
057 * </pre>
058 *
059 * to print disassembly.
060 */
061public class AheadOfTimeCompilationTest extends GraalCompilerTest {
062
063    public static final Object STATICFINALOBJECT = new Object();
064    public static final String STATICFINALSTRING = "test string";
065
066    public static Object getStaticFinalObject() {
067        return AheadOfTimeCompilationTest.STATICFINALOBJECT;
068    }
069
070    @Test
071    public void testStaticFinalObjectAOT() {
072        StructuredGraph result = compile("getStaticFinalObject", true);
073        assertDeepEquals(1, getConstantNodes(result).count());
074        Stamp constantStamp = getConstantNodes(result).first().stamp();
075        Assert.assertTrue(constantStamp.toString(), constantStamp instanceof KlassPointerStamp);
076        assertDeepEquals(2, result.getNodes().filter(FloatingReadNode.class).count());
077        assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count());
078    }
079
080    @Test
081    public void testStaticFinalObject() {
082        StructuredGraph result = compile("getStaticFinalObject", false);
083        assertDeepEquals(1, getConstantNodes(result).count());
084        assertDeepEquals(Kind.Object, getConstantNodes(result).first().getKind());
085        assertDeepEquals(0, result.getNodes().filter(FloatingReadNode.class).count());
086        assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count());
087    }
088
089    public static Class<AheadOfTimeCompilationTest> getClassObject() {
090        return AheadOfTimeCompilationTest.class;
091    }
092
093    @Test
094    public void testClassObjectAOT() {
095        StructuredGraph result = compile("getClassObject", true);
096
097        NodeIterable<ConstantNode> filter = getConstantNodes(result);
098        assertDeepEquals(1, filter.count());
099        HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) getMetaAccess().lookupJavaType(AheadOfTimeCompilationTest.class);
100        assertDeepEquals(type.klass(), filter.first().asConstant());
101
102        assertDeepEquals(1, result.getNodes().filter(FloatingReadNode.class).count());
103        assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count());
104    }
105
106    @Test
107    public void testClassObject() {
108        StructuredGraph result = compile("getClassObject", false);
109
110        NodeIterable<ConstantNode> filter = getConstantNodes(result);
111        assertDeepEquals(1, filter.count());
112        HotSpotObjectConstantImpl c = (HotSpotObjectConstantImpl) filter.first().asConstant();
113        Assert.assertEquals(Class.class, c.getObjectClass());
114        Assert.assertTrue(c.isEqualTo(AheadOfTimeCompilationTest.class));
115
116        assertDeepEquals(0, result.getNodes().filter(FloatingReadNode.class).count());
117        assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count());
118    }
119
120    public static Class<Integer> getPrimitiveClassObject() {
121        return int.class;
122    }
123
124    @Test
125    public void testPrimitiveClassObjectAOT() {
126        StructuredGraph result = compile("getPrimitiveClassObject", true);
127        NodeIterable<ConstantNode> filter = getConstantNodes(result);
128        assertDeepEquals(1, filter.count());
129        Stamp constantStamp = filter.first().stamp();
130        Assert.assertTrue(constantStamp instanceof KlassPointerStamp);
131
132        assertDeepEquals(2, result.getNodes().filter(FloatingReadNode.class).count());
133        assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count());
134    }
135
136    @Test
137    public void testPrimitiveClassObject() {
138        StructuredGraph result = compile("getPrimitiveClassObject", false);
139        NodeIterable<ConstantNode> filter = getConstantNodes(result);
140        assertDeepEquals(1, filter.count());
141        HotSpotObjectConstantImpl c = (HotSpotObjectConstantImpl) filter.first().asConstant();
142        Assert.assertEquals(Class.class, c.getObjectClass());
143        Assert.assertTrue(c.isEqualTo(Integer.TYPE));
144
145        assertDeepEquals(0, result.getNodes().filter(FloatingReadNode.class).count());
146        assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count());
147    }
148
149    public static String getStringObject() {
150        return AheadOfTimeCompilationTest.STATICFINALSTRING;
151    }
152
153    @Test
154    public void testStringObjectAOT() {
155        // embedded strings are fine
156        testStringObjectCommon(true);
157    }
158
159    @Test
160    public void testStringObject() {
161        testStringObjectCommon(false);
162    }
163
164    private void testStringObjectCommon(boolean compileAOT) {
165        StructuredGraph result = compile("getStringObject", compileAOT);
166
167        NodeIterable<ConstantNode> filter = getConstantNodes(result);
168        assertDeepEquals(1, filter.count());
169        HotSpotObjectConstantImpl c = (HotSpotObjectConstantImpl) filter.first().asConstant();
170        Assert.assertEquals(String.class, c.getObjectClass());
171        Assert.assertTrue(c.isEqualTo("test string"));
172
173        assertDeepEquals(0, result.getNodes().filter(FloatingReadNode.class).count());
174        assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count());
175    }
176
177    public static Boolean getBoxedBoolean() {
178        return Boolean.valueOf(true);
179    }
180
181    @Ignore("ImmutableCode override may not work reliably in non-hosted mode")
182    @Test
183    public void testBoxedBooleanAOT() {
184        StructuredGraph result = compile("getBoxedBoolean", true);
185
186        assertDeepEquals(2, result.getNodes().filter(FloatingReadNode.class).count());
187        assertDeepEquals(1, result.getNodes(PiNode.TYPE).count());
188        assertDeepEquals(1, getConstantNodes(result).count());
189        ConstantNode constant = getConstantNodes(result).first();
190        assertDeepEquals(Kind.Long, constant.getKind());
191        assertDeepEquals(((HotSpotResolvedObjectType) getMetaAccess().lookupJavaType(Boolean.class)).klass(), constant.asConstant());
192    }
193
194    @Test
195    public void testBoxedBoolean() {
196        StructuredGraph result = compile("getBoxedBoolean", false);
197        assertDeepEquals(0, result.getNodes().filter(FloatingReadNode.class).count());
198        assertDeepEquals(0, result.getNodes(PiNode.TYPE).count());
199        assertDeepEquals(1, getConstantNodes(result).count());
200        ConstantNode constant = getConstantNodes(result).first();
201        assertDeepEquals(Kind.Object, constant.getKind());
202
203        HotSpotObjectConstantImpl c = (HotSpotObjectConstantImpl) constant.asConstant();
204        Assert.assertTrue(c.isEqualTo(Boolean.TRUE));
205    }
206
207    private StructuredGraph compile(String test, boolean compileAOT) {
208        try (OverrideScope s = OptionValue.override(ImmutableCode, compileAOT)) {
209            StructuredGraph graph = parseEager(test, AllowAssumptions.YES);
210            ResolvedJavaMethod method = graph.method();
211            CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
212            // create suites everytime, as we modify options for the compiler
213            SuitesProvider suitesProvider = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites();
214            final Suites suitesLocal = suitesProvider.createSuites();
215            final LIRSuites lirSuitesLocal = suitesProvider.createLIRSuites();
216            final CompilationResult compResult = compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL,
217                            getProfilingInfo(graph), suitesLocal, lirSuitesLocal, new CompilationResult(), CompilationResultBuilderFactory.Default);
218            addMethod(method, compResult);
219            return graph;
220        }
221    }
222}