# HG changeset patch # User Gilles Duboscq # Date 1411054879 -7200 # Node ID 7716c6993546ddba6c75fc27364fb30db5a3a240 # Parent 646ddd52d79adccae2b0abd8b5b3737302f0961e Stamp: interface types can not be trusted except after explicit runtime checks diff -r 646ddd52d79a -r 7716c6993546 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Thu Sep 18 23:19:03 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Thu Sep 18 17:41:19 2014 +0200 @@ -165,9 +165,9 @@ ResolvedJavaType asExactType(); /** - * Gets the super class of this type. If this type represents either the {@code Object} class, a - * primitive type, or void, then null is returned. If this object represents an array class or - * an interface then the type object representing the {@code Object} class is returned. + * Gets the super class of this type. If this type represents either the {@code Object} class, + * an interface, a primitive type, or void, then null is returned. If this object represents an + * array class then the type object representing the {@code Object} class is returned. */ ResolvedJavaType getSuperclass(); diff -r 646ddd52d79a -r 7716c6993546 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java Thu Sep 18 23:19:03 2014 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java Thu Sep 18 17:41:19 2014 +0200 @@ -224,19 +224,48 @@ } public static Stamp declared(ResolvedJavaType type, boolean nonNull) { - return object(type, false, nonNull); + return object(type, false, nonNull, false); + } + + public static Stamp declaredNonNull(ResolvedJavaType type, boolean trustInterfaces) { + return declared(type, true, trustInterfaces); + } + + public static Stamp declared(ResolvedJavaType type, boolean nonNull, boolean trustInterfaces) { + return object(type, false, nonNull, trustInterfaces); } - public static Stamp object(ResolvedJavaType type, boolean exactType, boolean nonNull) { + private static ResolvedJavaType filterInterfaceTypesOut(ResolvedJavaType type) { + if (type.isArray()) { + ResolvedJavaType componentType = filterInterfaceTypesOut(type.getComponentType()); + if (componentType != null) { + return componentType.getArrayClass(); + } + return type.getSuperclass().getArrayClass(); // arrayType.getSuperClass() == Object type + } + if (type.isInterface()) { + return null; + } + return type; + } + + public static Stamp object(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean trustInterfaces) { assert type != null; assert type.getKind() == Kind.Object; - ResolvedJavaType exact = type.asExactType(); + ResolvedJavaType trustedtype; + if (!trustInterfaces) { + trustedtype = filterInterfaceTypesOut(type); + assert !exactType || trustedtype.equals(type); + } else { + trustedtype = type; + } + ResolvedJavaType exact = trustedtype != null ? trustedtype.asExactType() : null; if (exact != null) { - assert !exactType || type.equals(exact); + assert !exactType || trustedtype.equals(exact); return new ObjectStamp(exact, true, nonNull, false); - } else { - return new ObjectStamp(type, exactType, nonNull, false); } + assert !exactType || AbstractObjectStamp.isConcreteType(trustedtype); + return new ObjectStamp(trustedtype, exactType, nonNull, false); } public static Stamp exactNonNull(ResolvedJavaType type) { diff -r 646ddd52d79a -r 7716c6993546 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Thu Sep 18 23:19:03 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Thu Sep 18 17:41:19 2014 +0200 @@ -76,7 +76,7 @@ } protected PiNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) { - this(object, StampFactory.object(toType, exactType, nonNull || StampTool.isObjectNonNull(object.stamp()))); + this(object, StampFactory.object(toType, exactType, nonNull || StampTool.isObjectNonNull(object.stamp()), true)); } @Override diff -r 646ddd52d79a -r 7716c6993546 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Thu Sep 18 23:19:03 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Thu Sep 18 17:41:19 2014 +0200 @@ -65,7 +65,7 @@ } UnsafeCastNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) { - this(object, toType.getKind() == Kind.Object ? StampFactory.object(toType, exactType, nonNull || StampTool.isObjectNonNull(object.stamp())) : StampFactory.forKind(toType.getKind())); + this(object, toType.getKind() == Kind.Object ? StampFactory.object(toType, exactType, nonNull || StampTool.isObjectNonNull(object.stamp()), true) : StampFactory.forKind(toType.getKind())); } @Override diff -r 646ddd52d79a -r 7716c6993546 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Thu Sep 18 23:19:03 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Thu Sep 18 17:41:19 2014 +0200 @@ -64,7 +64,7 @@ } protected CheckCastNode(ResolvedJavaType type, ValueNode object, JavaTypeProfile profile, boolean forStoreCheck) { - super(StampFactory.declared(type)); + super(StampFactory.declared(type, false, true)); assert type != null; this.type = type; this.object = object; @@ -104,7 +104,7 @@ */ @Override public void lower(LoweringTool tool) { - Stamp stamp = StampFactory.declared(type); + Stamp stamp = StampFactory.declared(type, false, true); if (stamp() instanceof ObjectStamp && object().stamp() instanceof ObjectStamp) { stamp = ((ObjectStamp) object().stamp()).castTo((ObjectStamp) stamp); } @@ -113,7 +113,7 @@ if (stamp instanceof IllegalStamp) { // This is a check cast that will always fail condition = LogicConstantNode.contradiction(graph()); - stamp = StampFactory.declared(type); + stamp = StampFactory.declared(type, false, true); } else if (StampTool.isObjectNonNull(object)) { condition = graph().addWithoutUnique(InstanceOfNode.create(type, object, profile)); } else { @@ -146,7 +146,7 @@ @Override public boolean inferStamp() { if (object().stamp() instanceof ObjectStamp) { - ObjectStamp castStamp = (ObjectStamp) StampFactory.declared(type); + ObjectStamp castStamp = (ObjectStamp) StampFactory.declared(type, false, true); return updateStamp(((ObjectStamp) object().stamp()).castTo(castStamp)); } return false; diff -r 646ddd52d79a -r 7716c6993546 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Thu Sep 18 23:19:03 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Thu Sep 18 17:41:19 2014 +0200 @@ -718,7 +718,7 @@ ConstantNode nullObject = ConstantNode.defaultForKind(Kind.Object, graph); piNode = graph.unique(PiNode.create(nullObject, StampFactory.forConstant(nullObject.getValue(), metaAccess), replacementAnchor.asNode())); } else { - piNode = graph.unique(PiNode.create(object, StampFactory.declared(type, nonNull), replacementAnchor.asNode())); + piNode = graph.unique(PiNode.create(object, StampFactory.declared(type, nonNull, true), replacementAnchor.asNode())); } checkCast.replaceAtUsages(piNode); graph.removeFixed(checkCast); diff -r 646ddd52d79a -r 7716c6993546 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CheckCastReduction.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CheckCastReduction.java Thu Sep 18 23:19:03 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CheckCastReduction.java Thu Sep 18 17:41:19 2014 +0200 @@ -206,7 +206,7 @@ ObjectStamp subjectStamp = (ObjectStamp) subject.stamp(); final ResolvedJavaType toType = checkCast.type(); - ObjectStamp resultStamp = (ObjectStamp) StampFactory.declared(toType); + ObjectStamp resultStamp = (ObjectStamp) StampFactory.declared(toType, false, true); JavaTypeProfile profile = checkCast.profile(); assert FlowUtil.isLegalObjectStamp(subjectStamp); @@ -214,13 +214,13 @@ /* * Depending on what is known about the subject: - * + * * (a) definitely-non-null - * + * * (b) null-not-seen-in-profiling - * + * * (c) runtime-null-check-needed - * + * * the condition (of the cast-guard to be emitted) and the stamp (of the PiNode to be * emitted) are going to be different. Each of the three branches below deals with one of * the cases above. diff -r 646ddd52d79a -r 7716c6993546 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java Thu Sep 18 23:19:03 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java Thu Sep 18 17:41:19 2014 +0200 @@ -181,7 +181,7 @@ } public static GuardedValueNode createAnchoredReceiver(StructuredGraph graph, GuardingNode anchor, ResolvedJavaType commonType, ValueNode receiver, boolean exact) { - return createAnchoredReceiver(graph, anchor, receiver, exact ? StampFactory.exactNonNull(commonType) : StampFactory.declaredNonNull(commonType)); + return createAnchoredReceiver(graph, anchor, receiver, exact ? StampFactory.exactNonNull(commonType) : StampFactory.declaredNonNull(commonType, true)); } private static GuardedValueNode createAnchoredReceiver(StructuredGraph graph, GuardingNode anchor, ValueNode receiver, Stamp stamp) { diff -r 646ddd52d79a -r 7716c6993546 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java Thu Sep 18 23:19:03 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java Thu Sep 18 17:41:19 2014 +0200 @@ -67,7 +67,7 @@ private static Stamp createStamp(ValueNode array, Kind kind) { ResolvedJavaType type = StampTool.typeOrNull(array); if (kind == Kind.Object && type != null) { - return StampFactory.declared(type.getComponentType()); + return StampFactory.declared(type.getComponentType(), false, true); } else { return StampFactory.forKind(kind); } diff -r 646ddd52d79a -r 7716c6993546 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java Thu Sep 18 23:19:03 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java Thu Sep 18 17:41:19 2014 +0200 @@ -67,7 +67,7 @@ replaceAtUsages(objectArgument); GraphUtil.removeFixedWithUnusedInputs(this); } else { - Stamp stamp = StampFactory.declared(lookupJavaType, nonNullArgument.asConstant().asInt() != 0); + Stamp stamp = StampFactory.declared(lookupJavaType, nonNullArgument.asConstant().asInt() != 0, true); ConditionAnchorNode valueAnchorNode = graph().add( ConditionAnchorNode.create(CompareNode.createCompareNode(graph(), Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph())))); PiNode piCast = graph().unique(PiNode.create(objectArgument, stamp, valueAnchorNode));