1 /* 2 * Copyright (c) 2017, 2017, 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.core.test; 26 27 import static org.hamcrest.CoreMatchers.instanceOf; 28 import static org.hamcrest.CoreMatchers.is; 29 30 import jdk.vm.ci.meta.ResolvedJavaType; 31 import org.graalvm.compiler.api.directives.GraalDirectives; 32 import org.graalvm.compiler.core.common.type.Stamp; 33 import org.graalvm.compiler.nodeinfo.Verbosity; 34 import org.graalvm.compiler.nodes.StructuredGraph; 35 import org.graalvm.compiler.nodes.ValueNode; 36 import org.graalvm.compiler.nodes.debug.BlackholeNode; 37 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext; 38 import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin; 39 import org.graalvm.compiler.nodes.spi.UncheckedInterfaceProvider; 40 import org.graalvm.compiler.nodes.type.StampTool; 41 import org.junit.Assert; 42 import org.junit.BeforeClass; 43 import org.junit.Test; 44 45 import jdk.vm.ci.meta.ResolvedJavaMethod; 46 47 public class UncheckedInterfaceProviderTest extends GraalCompilerTest { 48 private Runnable interfaceField; 49 private Runnable[] interfaceArrayField; 50 51 public void snippet(Runnable interfaceParameter, Runnable[] interfaceArrayParameter) { 52 GraalDirectives.blackhole(interfaceParameter); 53 GraalDirectives.blackhole(interfaceArrayParameter); 54 GraalDirectives.blackhole(interfaceField); 55 GraalDirectives.blackhole(interfaceArrayField); 56 GraalDirectives.blackhole(interfaceReturn()); 57 GraalDirectives.blackhole(interfaceArrayReturn()); 58 GraalDirectives.blackhole(interfaceReturnException()); 59 GraalDirectives.blackhole(interfaceArrayReturnException()); 60 } 61 62 public static Runnable interfaceReturn() { 63 return new A(); 64 } 65 66 public static Runnable[] interfaceArrayReturn() { 67 return new Runnable[]{new A(), new B(), new C(), new D()}; 68 } 69 70 public static Runnable interfaceReturnException() { 71 return new A(); 72 } 73 74 public static Runnable[] interfaceArrayReturnException() { 75 return new Runnable[]{new A(), new B(), new C(), new D()}; 76 } 77 78 @Override 79 protected InlineInvokePlugin.InlineInfo bytecodeParserShouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) { 80 if (method.getName().startsWith("interfaceReturn") || method.getName().startsWith("interfaceArrayReturn")) { 81 if (method.getName().equals("Exception")) { 82 return InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION; 83 } 84 return InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_NO_EXCEPTION; 85 } 86 return super.bytecodeParserShouldInlineInvoke(b, method, args); 87 } 88 89 @BeforeClass 90 public static void setup() { 91 interfaceArrayReturn(); 92 } 93 94 @Test 95 public void test() { 96 StructuredGraph graph = parseEager("snippet", StructuredGraph.AllowAssumptions.YES); 97 for (BlackholeNode b : graph.getNodes().filter(BlackholeNode.class)) { 98 Assert.assertThat(b.getValue(), is(instanceOf(UncheckedInterfaceProvider.class))); 99 Stamp uncheckedStamp = ((UncheckedInterfaceProvider) b.getValue()).uncheckedStamp(); 100 String context = b.getValue().toString(Verbosity.Debugger); 101 Assert.assertNotNull(context, uncheckedStamp); 102 ResolvedJavaType uncheckedType = StampTool.typeOrNull(uncheckedStamp); 103 ResolvedJavaType type = StampTool.typeOrNull(b.getValue()); 104 Assert.assertEquals(context, arrayDepth(type), arrayDepth(uncheckedType)); 105 Assert.assertTrue(context + ": " + type, type == null || type.getElementalType().isJavaLangObject()); 106 Assert.assertNotNull(context, uncheckedType); 107 Assert.assertTrue(context, uncheckedType.getElementalType().isInterface()); 108 } 109 } 110 111 private static int arrayDepth(ResolvedJavaType type) { 112 int depth = 0; 113 ResolvedJavaType t = type; 114 while (t != null && t.isArray()) { 115 depth += 1; 116 t = t.getComponentType(); 117 } 118 return depth; 119 } 120 121 public static class A implements Runnable { 122 @Override 123 public void run() { 124 // nop 125 } 126 } 127 128 public static class B implements Runnable { 129 @Override 130 public void run() { 131 // nop 132 } 133 } 134 135 public static class C implements Runnable { 136 @Override 137 public void run() { 138 // nop 139 } 140 } 141 142 public static class D implements Runnable { 143 @Override 144 public void run() { 145 // nop 146 } 147 } 148 }