blob: 09013de467874cd25e5a2788a4128e93577417f9 [file] [log] [blame]
/*
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.core.test;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import jdk.vm.ci.meta.ResolvedJavaType;
import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.nodeinfo.Verbosity;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.debug.BlackholeNode;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
import org.graalvm.compiler.nodes.spi.UncheckedInterfaceProvider;
import org.graalvm.compiler.nodes.type.StampTool;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import jdk.vm.ci.meta.ResolvedJavaMethod;
public class UncheckedInterfaceProviderTest extends GraalCompilerTest {
private Runnable interfaceField;
private Runnable[] interfaceArrayField;
public void snippet(Runnable interfaceParameter, Runnable[] interfaceArrayParameter) {
GraalDirectives.blackhole(interfaceParameter);
GraalDirectives.blackhole(interfaceArrayParameter);
GraalDirectives.blackhole(interfaceField);
GraalDirectives.blackhole(interfaceArrayField);
GraalDirectives.blackhole(interfaceReturn());
GraalDirectives.blackhole(interfaceArrayReturn());
GraalDirectives.blackhole(interfaceReturnException());
GraalDirectives.blackhole(interfaceArrayReturnException());
}
public static Runnable interfaceReturn() {
return new A();
}
public static Runnable[] interfaceArrayReturn() {
return new Runnable[]{new A(), new B(), new C(), new D()};
}
public static Runnable interfaceReturnException() {
return new A();
}
public static Runnable[] interfaceArrayReturnException() {
return new Runnable[]{new A(), new B(), new C(), new D()};
}
@Override
protected InlineInvokePlugin.InlineInfo bytecodeParserShouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
if (method.getName().startsWith("interfaceReturn") || method.getName().startsWith("interfaceArrayReturn")) {
if (method.getName().equals("Exception")) {
return InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_WITH_EXCEPTION;
}
return InlineInvokePlugin.InlineInfo.DO_NOT_INLINE_NO_EXCEPTION;
}
return super.bytecodeParserShouldInlineInvoke(b, method, args);
}
@BeforeClass
public static void setup() {
interfaceArrayReturn();
}
@Test
public void test() {
StructuredGraph graph = parseEager("snippet", StructuredGraph.AllowAssumptions.YES);
for (BlackholeNode b : graph.getNodes().filter(BlackholeNode.class)) {
Assert.assertThat(b.getValue(), is(instanceOf(UncheckedInterfaceProvider.class)));
Stamp uncheckedStamp = ((UncheckedInterfaceProvider) b.getValue()).uncheckedStamp();
String context = b.getValue().toString(Verbosity.Debugger);
Assert.assertNotNull(context, uncheckedStamp);
ResolvedJavaType uncheckedType = StampTool.typeOrNull(uncheckedStamp);
ResolvedJavaType type = StampTool.typeOrNull(b.getValue());
Assert.assertEquals(context, arrayDepth(type), arrayDepth(uncheckedType));
Assert.assertTrue(context + ": " + type, type == null || type.getElementalType().isJavaLangObject());
Assert.assertNotNull(context, uncheckedType);
Assert.assertTrue(context, uncheckedType.getElementalType().isInterface());
}
}
private static int arrayDepth(ResolvedJavaType type) {
int depth = 0;
ResolvedJavaType t = type;
while (t != null && t.isArray()) {
depth += 1;
t = t.getComponentType();
}
return depth;
}
public static class A implements Runnable {
@Override
public void run() {
// nop
}
}
public static class B implements Runnable {
@Override
public void run() {
// nop
}
}
public static class C implements Runnable {
@Override
public void run() {
// nop
}
}
public static class D implements Runnable {
@Override
public void run() {
// nop
}
}
}