1 /* 2 * Copyright (c) 2014, 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 package org.graalvm.compiler.hotspot.test; 25 26 import org.graalvm.compiler.core.test.GraalCompilerTest; 27 import org.graalvm.compiler.debug.DebugContext; 28 import org.graalvm.compiler.graph.Node; 29 import org.graalvm.compiler.nodes.Invoke; 30 import org.graalvm.compiler.nodes.ReturnNode; 31 import org.graalvm.compiler.nodes.StructuredGraph; 32 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; 33 import org.junit.Test; 34 35 public class ClassSubstitutionsTests extends GraalCompilerTest { 36 37 public Number instanceField; 38 39 public Object[] arrayField; 40 41 public String[] stringArrayField; 42 43 @SuppressWarnings("try") 44 protected StructuredGraph test(final String snippet) { 45 DebugContext debug = getDebugContext(); 46 try (DebugContext.Scope s = debug.scope("ClassSubstitutionsTest", getMetaAccess().lookupJavaMethod(getMethod(snippet)))) { 47 StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES, debug); 48 compile(graph.method(), graph); 49 assertNotInGraph(graph, Invoke.class); 50 debug.dump(DebugContext.BASIC_LEVEL, graph, snippet); 51 return graph; 52 } catch (Throwable e) { 53 throw debug.handle(e); 54 } 55 } 56 57 protected static StructuredGraph assertNotInGraph(StructuredGraph graph, Class<?> clazz) { 58 for (Node node : graph.getNodes()) { 59 if (clazz.isInstance(node)) { 60 fail(node.toString()); 61 } 62 } 63 return graph; 64 } 65 66 public boolean constantIsArray() { 67 return "".getClass().isArray(); 68 } 69 70 public boolean constantIsInterface() { 71 return "".getClass().isInterface(); 72 } 73 74 public boolean constantIsPrimitive() { 75 return "".getClass().isPrimitive(); 76 } 77 78 @Test 79 public void testIsArray() { 80 testConstantReturn("constantIsArray", 0); 81 } 82 83 @Test 84 public void testIsInterface() { 85 testConstantReturn("constantIsInterface", 0); 86 } 87 88 @Test 89 public void testIsPrimitive() { 90 testConstantReturn("constantIsPrimitive", 0); 91 } 92 93 public boolean fieldIsNotArray() { 94 if (instanceField != null) { 95 // The base type of instanceField is not Object or an Interface, so it's provably an 96 // instance type, so isArray will always return false. 97 return instanceField.getClass().isArray(); 98 } 99 return false; 100 } 101 102 @Test 103 public void testFieldIsNotArray() { 104 testConstantReturn("fieldIsNotArray", 0); 105 } 106 107 public boolean foldComponentType() { 108 return stringArrayField.getClass().getComponentType() == String.class; 109 } 110 111 @Test 112 public void testFoldComponentType() { 113 testConstantReturn("foldComponentType", 1); 114 } 115 116 @Test 117 public void testFieldIsArray() { 118 testConstantReturn("fieldIsArray", 1); 119 } 120 121 public boolean fieldIsArray() { 122 if (arrayField != null) { 123 // The base type of arrayField is an array of some sort so isArray will always return 124 // true. 125 return arrayField.getClass().isArray(); 126 } 127 return true; 128 } 129 130 private static class A { 131 } 132 133 private static class B extends A { 134 } 135 136 private static class C { 137 } 138 139 private static final A a = new A(); 140 private static final B b = new B(); 141 private static final C c = new C(); 142 143 public boolean classIsAssignable1() { 144 return a.getClass().isAssignableFrom(a.getClass()); 145 } 146 147 public boolean classIsAssignable2() { 148 return a.getClass().isAssignableFrom(b.getClass()); 149 } 150 151 public boolean classIsAssignable3() { 152 return a.getClass().isAssignableFrom(c.getClass()); 153 } 154 155 public boolean classIsAssignable4() { 156 return b.getClass().isAssignableFrom(a.getClass()); 157 } 158 159 public boolean classIsAssignable5() { 160 return c.getClass().isAssignableFrom(b.getClass()); 161 } 162 163 public boolean classIsAssignable6() { 164 return int.class.isAssignableFrom(b.getClass()); 165 } 166 167 public boolean classIsAssignable7() { 168 return int.class.isAssignableFrom(int.class); 169 } 170 171 @Test 172 public void testClassIsAssignable() { 173 testConstantReturn("classIsAssignable1", 1); 174 testConstantReturn("classIsAssignable2", 1); 175 testConstantReturn("classIsAssignable3", 0); 176 testConstantReturn("classIsAssignable4", 0); 177 testConstantReturn("classIsAssignable5", 0); 178 testConstantReturn("classIsAssignable6", 0); 179 testConstantReturn("classIsAssignable7", 1); 180 } 181 182 private void testConstantReturn(String name, Object value) { 183 StructuredGraph result = test(name); 184 ReturnNode ret = result.getNodes(ReturnNode.TYPE).first(); 185 assertDeepEquals(1, result.getNodes(ReturnNode.TYPE).count()); 186 187 assertDeepEquals(true, ret.result().isConstant()); 188 assertDeepEquals(value, ret.result().asJavaConstant().asBoxedPrimitive()); 189 } 190 }