# HG changeset patch # User Tom Rodriguez # Date 1436978954 25200 # Node ID a85ef0434dbaac66d23b49e92f6da0af3456e3b7 # Parent fc0892fed0f59941f4ebe1b16809dc2f3f7534ea TypeCheckNode should fold obviously failing types diff -r fc0892fed0f5 -r a85ef0434dba graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java Wed Jul 15 09:49:11 2015 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java Wed Jul 15 09:49:14 2015 -0700 @@ -3026,7 +3026,9 @@ ResolvedJavaType singleType = profile.asSingleType(); if (singleType != null) { LogicNode typeCheck = append(TypeCheckNode.create(singleType, object)); - append(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile)); + if (!typeCheck.isTautology()) { + append(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile)); + } instanceOfNode = LogicConstantNode.forBoolean(resolvedType.isAssignableFrom(singleType)); } } diff -r fc0892fed0f5 -r a85ef0434dba graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeCheckNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeCheckNode.java Wed Jul 15 09:49:11 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeCheckNode.java Wed Jul 15 09:49:14 2015 -0700 @@ -104,7 +104,7 @@ return LogicConstantNode.tautology(); } } else { - if (exactType) { + if (exactType || !inputType.isAssignableFrom(type)) { // since this type check failed for an exact type we know that it can never // succeed at run time. we also don't care about null values, since they will // also make the check fail. diff -r fc0892fed0f5 -r a85ef0434dba graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java Wed Jul 15 09:49:11 2015 -0700 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java Wed Jul 15 09:49:14 2015 -0700 @@ -25,11 +25,14 @@ import java.util.*; import jdk.internal.jvmci.code.CompilationResult.*; +import jdk.internal.jvmci.debug.*; +import jdk.internal.jvmci.debug.Debug.*; import jdk.internal.jvmci.meta.*; import org.junit.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.StructuredGraph.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.replacements.test.CheckCastTest.Depth12; @@ -430,4 +433,64 @@ test("conditionalInstantiation", new StringBuilder()); test("conditionalInstantiation", 1); } + + public boolean exactlyObject(Thread thread) { + return thread != null && ((Object) thread).getClass() == Object.class; + } + + public boolean exactlyObjectArray(Thread[] threads) { + return threads != null && ((Object[]) threads).getClass() == Object[].class; + } + + public boolean exactlyString(Thread thread) { + return thread != null && ((Object) thread).getClass() == String.class; + } + + public boolean exactlyStringArray(Thread[] threads) { + return threads != null && ((Object[]) threads).getClass() == String[].class; + } + + @SuppressWarnings("cast") + public boolean instanceofStringArray(Thread[] threads) { + return threads != null && ((Object[]) threads) instanceof String[]; + } + + @SuppressWarnings("cast") + public boolean instanceofString(Thread thread) { + return thread != null && ((Object) thread) instanceof String; + } + + /** + * {@link TypeCheckNode} and {@link InstanceOfNode} should be equivalently powerful when + * comparing disjoint types. + */ + @Test + public void testTypeCheck() { + testConstantReturn("exactlyObject", 0); + testConstantReturn("exactlyObjectArray", 0); + testConstantReturn("exactlyString", 0); + testConstantReturn("exactlyStringArray", 0); + testConstantReturn("instanceofString", 0); + testConstantReturn("instanceofStringArray", 0); + } + + private void testConstantReturn(String name, Object value) { + StructuredGraph result = buildGraph(name); + ReturnNode ret = result.getNodes(ReturnNode.TYPE).first(); + assertDeepEquals(1, result.getNodes(ReturnNode.TYPE).count()); + + assertDeepEquals(true, ret.result().isConstant()); + assertDeepEquals(value, ret.result().asJavaConstant().asBoxedPrimitive()); + } + + protected StructuredGraph buildGraph(final String snippet) { + try (Scope s = Debug.scope("InstanceOfTest", getMetaAccess().lookupJavaMethod(getMethod(snippet)))) { + StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); + compile(graph.method(), graph); + Debug.dump(graph, snippet); + return graph; + } catch (Throwable e) { + throw Debug.handle(e); + } + } }