changeset 17154:7716c6993546

Stamp: interface types can not be trusted except after explicit runtime checks
author Gilles Duboscq <duboscq@ssw.jku.at>
date Thu, 18 Sep 2014 17:41:19 +0200
parents 646ddd52d79a
children a8eb7473d58a
files graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/CheckCastReduction.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java
diffstat 10 files changed, 53 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- 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();
 
--- 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) {
--- 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
--- 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
--- 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;
--- 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);
--- 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.
--- 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) {
--- 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);
         }
--- 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));