1 /*
   2  * Copyright (c) 2013, 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 package org.graalvm.compiler.hotspot.test;
  26 
  27 import jdk.vm.ci.aarch64.AArch64;
  28 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
  29 import jdk.vm.ci.meta.JavaConstant;
  30 import jdk.vm.ci.meta.JavaKind;
  31 import org.graalvm.compiler.core.common.type.Stamp;
  32 import org.graalvm.compiler.graph.iterators.NodeIterable;
  33 import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
  34 import org.graalvm.compiler.nodes.ConstantNode;
  35 import org.graalvm.compiler.nodes.NodeView;
  36 import org.graalvm.compiler.nodes.PiNode;
  37 import org.graalvm.compiler.nodes.StructuredGraph;
  38 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
  39 import org.graalvm.compiler.nodes.memory.FloatingReadNode;
  40 import org.graalvm.compiler.nodes.memory.ReadNode;
  41 import org.graalvm.compiler.options.OptionValues;
  42 import org.junit.Assert;
  43 import org.junit.Assume;
  44 import org.junit.Before;
  45 import org.junit.Test;
  46 
  47 import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode;
  48 import static org.graalvm.compiler.nodes.ConstantNode.getConstantNodes;
  49 
  50 /**
  51  * use
  52  *
  53  * <pre>
  54  * mx unittest AheadOfTimeCompilationTest @-XX:CompileCommand='print,*AheadOfTimeCompilationTest.*'
  55  * </pre>
  56  *
  57  * to print disassembly.
  58  */
  59 public class AheadOfTimeCompilationTest extends HotSpotGraalCompilerTest {
  60 
  61     public static final Object STATICFINALOBJECT = new Object();
  62     public static final String STATICFINALSTRING = "test string";
  63 
  64     public static Object getStaticFinalObject() {
  65         return AheadOfTimeCompilationTest.STATICFINALOBJECT;
  66     }
  67 
  68     @Before
  69     public void setUp() {
  70         // Ignore on SPARC
  71         Assume.assumeFalse("skipping on AArch64", getTarget().arch instanceof AArch64);
  72     }
  73 
  74     @Test
  75     public void testStaticFinalObjectAOT() {
  76         StructuredGraph result = compile("getStaticFinalObject", true);
  77         assertDeepEquals(1, getConstantNodes(result).count());
  78         Stamp constantStamp = getConstantNodes(result).first().stamp(NodeView.DEFAULT);
  79         Assert.assertTrue(constantStamp.toString(), constantStamp instanceof KlassPointerStamp);
  80         int expected = runtime().getVMConfig().classMirrorIsHandle ? 3 : 2;
  81         assertDeepEquals(expected, result.getNodes().filter(ReadNode.class).count());
  82     }
  83 
  84     @Test
  85     public void testStaticFinalObject() {
  86         StructuredGraph result = compile("getStaticFinalObject", false);
  87         assertDeepEquals(1, getConstantNodes(result).count());
  88         assertDeepEquals(JavaKind.Object, getConstantNodes(result).first().getStackKind());
  89         assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count());
  90     }
  91 
  92     public static Class<AheadOfTimeCompilationTest> getClassObject() {
  93         return AheadOfTimeCompilationTest.class;
  94     }
  95 
  96     @Test
  97     public void testClassObjectAOT() {
  98         StructuredGraph result = compile("getClassObject", true);
  99 
 100         NodeIterable<ConstantNode> filter = getConstantNodes(result);
 101         assertDeepEquals(1, filter.count());
 102         HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) getMetaAccess().lookupJavaType(AheadOfTimeCompilationTest.class);
 103         assertDeepEquals(type.klass(), filter.first().asConstant());
 104         int expected = runtime().getVMConfig().classMirrorIsHandle ? 2 : 1;
 105         assertDeepEquals(expected, result.getNodes().filter(ReadNode.class).count());
 106     }
 107 
 108     @Test
 109     public void testClassObject() {
 110         StructuredGraph result = compile("getClassObject", false);
 111 
 112         NodeIterable<ConstantNode> filter = getConstantNodes(result);
 113         assertDeepEquals(1, filter.count());
 114         JavaConstant c = filter.first().asJavaConstant();
 115         Assert.assertEquals(getSnippetReflection().asObject(Class.class, c), AheadOfTimeCompilationTest.class);
 116 
 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(NodeView.DEFAULT);
 130         Assert.assertTrue(constantStamp instanceof KlassPointerStamp);
 131         int expected = runtime().getVMConfig().classMirrorIsHandle ? 3 : 2;
 132         assertDeepEquals(expected, result.getNodes().filter(ReadNode.class).count());
 133     }
 134 
 135     @Test
 136     public void testPrimitiveClassObject() {
 137         StructuredGraph result = compile("getPrimitiveClassObject", false);
 138         NodeIterable<ConstantNode> filter = getConstantNodes(result);
 139         assertDeepEquals(1, filter.count());
 140         JavaConstant c = filter.first().asJavaConstant();
 141         Assert.assertEquals(getSnippetReflection().asObject(Class.class, c), Integer.TYPE);
 142 
 143         assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count());
 144     }
 145 
 146     public static String getStringObject() {
 147         return AheadOfTimeCompilationTest.STATICFINALSTRING;
 148     }
 149 
 150     @Test
 151     public void testStringObjectAOT() {
 152         // embedded strings are fine
 153         testStringObjectCommon(true);
 154     }
 155 
 156     @Test
 157     public void testStringObject() {
 158         testStringObjectCommon(false);
 159     }
 160 
 161     private void testStringObjectCommon(boolean compileAOT) {
 162         StructuredGraph result = compile("getStringObject", compileAOT);
 163 
 164         NodeIterable<ConstantNode> filter = getConstantNodes(result);
 165         assertDeepEquals(1, filter.count());
 166         JavaConstant c = filter.first().asJavaConstant();
 167         Assert.assertEquals(getSnippetReflection().asObject(String.class, c), "test string");
 168 
 169         assertDeepEquals(0, result.getNodes().filter(FloatingReadNode.class).count());
 170         assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count());
 171     }
 172 
 173     public static Boolean getBoxedBoolean() {
 174         return Boolean.valueOf(true);
 175     }
 176 
 177     @Test
 178     public void testBoxedBooleanAOT() {
 179         StructuredGraph result = compile("getBoxedBoolean", true);
 180 
 181         assertDeepEquals(0, result.getNodes().filter(FloatingReadNode.class).count());
 182         assertDeepEquals(0, result.getNodes().filter(PiNode.class).count());
 183         assertDeepEquals(1, getConstantNodes(result).count());
 184         ConstantNode constant = getConstantNodes(result).first();
 185         assertDeepEquals(JavaKind.Object, constant.getStackKind());
 186 
 187         JavaConstant c = constant.asJavaConstant();
 188         Assert.assertEquals(getSnippetReflection().asObject(Boolean.class, c), Boolean.TRUE);
 189     }
 190 
 191     @Test
 192     public void testBoxedBoolean() {
 193         StructuredGraph result = compile("getBoxedBoolean", false);
 194         assertDeepEquals(0, result.getNodes().filter(FloatingReadNode.class).count());
 195         assertDeepEquals(0, result.getNodes().filter(PiNode.class).count());
 196         assertDeepEquals(1, getConstantNodes(result).count());
 197         ConstantNode constant = getConstantNodes(result).first();
 198         assertDeepEquals(JavaKind.Object, constant.getStackKind());
 199 
 200         JavaConstant c = constant.asJavaConstant();
 201         Assert.assertEquals(getSnippetReflection().asObject(Boolean.class, c), Boolean.TRUE);
 202     }
 203 
 204     @SuppressWarnings("try")
 205     private StructuredGraph compile(String test, boolean compileAOT) {
 206         OptionValues options = new OptionValues(getInitialOptions(), ImmutableCode, compileAOT);
 207         StructuredGraph graph = parseEager(test, AllowAssumptions.YES, options);
 208         compile(graph.method(), graph);
 209         return graph;
 210     }
 211 }