1 /* 2 * Copyright (c) 2013, 2016, 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 static org.graalvm.compiler.core.GraalCompiler.compileGraph; 26 import static org.graalvm.compiler.core.common.GraalOptions.ImmutableCode; 27 import static org.graalvm.compiler.nodes.ConstantNode.getConstantNodes; 28 29 import org.junit.Assert; 30 import org.junit.Ignore; 31 import org.junit.Test; 32 33 import org.graalvm.compiler.api.test.Graal; 34 import org.graalvm.compiler.code.CompilationResult; 35 import org.graalvm.compiler.core.common.type.Stamp; 36 import org.graalvm.compiler.core.test.GraalCompilerTest; 37 import org.graalvm.compiler.graph.iterators.NodeIterable; 38 import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp; 39 import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory; 40 import org.graalvm.compiler.lir.phases.LIRSuites; 41 import org.graalvm.compiler.nodes.ConstantNode; 42 import org.graalvm.compiler.nodes.PiNode; 43 import org.graalvm.compiler.nodes.StructuredGraph; 44 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; 45 import org.graalvm.compiler.nodes.memory.FloatingReadNode; 46 import org.graalvm.compiler.nodes.memory.ReadNode; 47 import org.graalvm.compiler.options.OptionValue; 48 import org.graalvm.compiler.options.OptionValue.OverrideScope; 49 import org.graalvm.compiler.phases.OptimisticOptimizations; 50 import org.graalvm.compiler.phases.tiers.Suites; 51 import org.graalvm.compiler.phases.tiers.SuitesProvider; 52 import org.graalvm.compiler.runtime.RuntimeProvider; 53 54 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType; 55 import jdk.vm.ci.meta.JavaConstant; 56 import jdk.vm.ci.meta.JavaKind; 57 import jdk.vm.ci.meta.ResolvedJavaMethod; 58 59 /** 60 * use 61 * 62 * <pre> 63 * mx unittest AheadOfTimeCompilationTest @-XX:CompileCommand='print,*AheadOfTimeCompilationTest.*' 64 * </pre> 65 * 66 * to print disassembly. 67 */ 68 public class AheadOfTimeCompilationTest extends GraalCompilerTest { 69 70 public static final Object STATICFINALOBJECT = new Object(); 71 public static final String STATICFINALSTRING = "test string"; 72 73 public static Object getStaticFinalObject() { 74 return AheadOfTimeCompilationTest.STATICFINALOBJECT; 75 } 76 77 @Test 78 public void testStaticFinalObjectAOT() { 79 StructuredGraph result = compile("getStaticFinalObject", true); 80 assertDeepEquals(1, getConstantNodes(result).count()); 81 Stamp constantStamp = getConstantNodes(result).first().stamp(); 82 Assert.assertTrue(constantStamp.toString(), constantStamp instanceof KlassPointerStamp); 83 assertDeepEquals(2, result.getNodes().filter(FloatingReadNode.class).count()); 84 assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count()); 85 } 86 87 @Test 88 public void testStaticFinalObject() { 89 StructuredGraph result = compile("getStaticFinalObject", false); 90 assertDeepEquals(1, getConstantNodes(result).count()); 91 assertDeepEquals(JavaKind.Object, getConstantNodes(result).first().getStackKind()); 92 assertDeepEquals(0, result.getNodes().filter(FloatingReadNode.class).count()); 93 assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count()); 94 } 95 96 public static Class<AheadOfTimeCompilationTest> getClassObject() { 97 return AheadOfTimeCompilationTest.class; 98 } 99 100 @Test 101 public void testClassObjectAOT() { 102 StructuredGraph result = compile("getClassObject", true); 103 104 NodeIterable<ConstantNode> filter = getConstantNodes(result); 105 assertDeepEquals(1, filter.count()); 106 HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) getMetaAccess().lookupJavaType(AheadOfTimeCompilationTest.class); 107 assertDeepEquals(type.klass(), filter.first().asConstant()); 108 109 assertDeepEquals(1, result.getNodes().filter(FloatingReadNode.class).count()); 110 assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count()); 111 } 112 113 @Test 114 public void testClassObject() { 115 StructuredGraph result = compile("getClassObject", false); 116 117 NodeIterable<ConstantNode> filter = getConstantNodes(result); 118 assertDeepEquals(1, filter.count()); 119 JavaConstant c = filter.first().asJavaConstant(); 120 Assert.assertEquals(getSnippetReflection().asObject(Class.class, c), AheadOfTimeCompilationTest.class); 121 122 assertDeepEquals(0, result.getNodes().filter(FloatingReadNode.class).count()); 123 assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count()); 124 } 125 126 public static Class<Integer> getPrimitiveClassObject() { 127 return int.class; 128 } 129 130 @Test 131 public void testPrimitiveClassObjectAOT() { 132 StructuredGraph result = compile("getPrimitiveClassObject", true); 133 NodeIterable<ConstantNode> filter = getConstantNodes(result); 134 assertDeepEquals(1, filter.count()); 135 Stamp constantStamp = filter.first().stamp(); 136 Assert.assertTrue(constantStamp instanceof KlassPointerStamp); 137 138 assertDeepEquals(2, result.getNodes().filter(FloatingReadNode.class).count()); 139 assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count()); 140 } 141 142 @Test 143 public void testPrimitiveClassObject() { 144 StructuredGraph result = compile("getPrimitiveClassObject", false); 145 NodeIterable<ConstantNode> filter = getConstantNodes(result); 146 assertDeepEquals(1, filter.count()); 147 JavaConstant c = filter.first().asJavaConstant(); 148 Assert.assertEquals(getSnippetReflection().asObject(Class.class, c), Integer.TYPE); 149 150 assertDeepEquals(0, result.getNodes().filter(FloatingReadNode.class).count()); 151 assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count()); 152 } 153 154 public static String getStringObject() { 155 return AheadOfTimeCompilationTest.STATICFINALSTRING; 156 } 157 158 @Test 159 public void testStringObjectAOT() { 160 // embedded strings are fine 161 testStringObjectCommon(true); 162 } 163 164 @Test 165 public void testStringObject() { 166 testStringObjectCommon(false); 167 } 168 169 private void testStringObjectCommon(boolean compileAOT) { 170 StructuredGraph result = compile("getStringObject", compileAOT); 171 172 NodeIterable<ConstantNode> filter = getConstantNodes(result); 173 assertDeepEquals(1, filter.count()); 174 JavaConstant c = filter.first().asJavaConstant(); 175 Assert.assertEquals(getSnippetReflection().asObject(String.class, c), "test string"); 176 177 assertDeepEquals(0, result.getNodes().filter(FloatingReadNode.class).count()); 178 assertDeepEquals(0, result.getNodes().filter(ReadNode.class).count()); 179 } 180 181 public static Boolean getBoxedBoolean() { 182 return Boolean.valueOf(true); 183 } 184 185 @Ignore("ImmutableCode override may not work reliably in non-hosted mode") 186 @Test 187 public void testBoxedBooleanAOT() { 188 StructuredGraph result = compile("getBoxedBoolean", true); 189 190 assertDeepEquals(2, result.getNodes().filter(FloatingReadNode.class).count()); 191 assertDeepEquals(1, result.getNodes(PiNode.TYPE).count()); 192 assertDeepEquals(1, getConstantNodes(result).count()); 193 ConstantNode constant = getConstantNodes(result).first(); 194 assertDeepEquals(JavaKind.Long, constant.getStackKind()); 195 assertDeepEquals(((HotSpotResolvedObjectType) getMetaAccess().lookupJavaType(Boolean.class)).klass(), constant.asConstant()); 196 } 197 198 @Test 199 public void testBoxedBoolean() { 200 StructuredGraph result = compile("getBoxedBoolean", false); 201 assertDeepEquals(0, result.getNodes().filter(FloatingReadNode.class).count()); 202 assertDeepEquals(0, result.getNodes(PiNode.TYPE).count()); 203 assertDeepEquals(1, getConstantNodes(result).count()); 204 ConstantNode constant = getConstantNodes(result).first(); 205 assertDeepEquals(JavaKind.Object, constant.getStackKind()); 206 207 JavaConstant c = constant.asJavaConstant(); 208 Assert.assertEquals(getSnippetReflection().asObject(Boolean.class, c), Boolean.TRUE); 209 } 210 211 @SuppressWarnings("try") 212 private StructuredGraph compile(String test, boolean compileAOT) { 213 try (OverrideScope s = OptionValue.override(ImmutableCode, compileAOT)) { 214 StructuredGraph graph = parseEager(test, AllowAssumptions.YES); 215 ResolvedJavaMethod method = graph.method(); 216 // create suites everytime, as we modify options for the compiler 217 SuitesProvider suitesProvider = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites(); 218 final Suites suitesLocal = suitesProvider.getDefaultSuites(); 219 final LIRSuites lirSuitesLocal = suitesProvider.getDefaultLIRSuites(); 220 final CompilationResult compResult = compileGraph(graph, method, getProviders(), getBackend(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, graph.getProfilingInfo(), 221 suitesLocal, lirSuitesLocal, new CompilationResult(), CompilationResultBuilderFactory.Default); 222 addMethod(method, compResult); 223 return graph; 224 } 225 } 226 }