changeset 5372:4485e0edd1af

made CheckCastNode be a FixedNode instead of a BooleanNode
author Doug Simon <doug.simon@oracle.com>
date Thu, 10 May 2012 00:36:12 +0200
parents 3fd6b0ab1146
children 53cc37c27b04 31ec401eb592 80ae8033fe01
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/SnippetIntrinsificationPhase.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/types/PropagateTypeCachePhase.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/LowerCheckCastPhase.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/LowerCheckCastTest.java
diffstat 7 files changed, 30 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/SnippetIntrinsificationPhase.java	Thu May 10 00:33:58 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/SnippetIntrinsificationPhase.java	Thu May 10 00:36:12 2012 +0200
@@ -255,7 +255,10 @@
                         assert false : "unexpected checkcast usage: " + checkCastUsage;
                     }
                 }
-                checkCastNode.safeDelete();
+                FixedNode next = checkCastNode.next();
+                checkCastNode.setNext(null);
+                checkCastNode.replaceAtPredecessors(next);
+                GraphUtil.killCFG(checkCastNode);
             }
         }
     }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/types/PropagateTypeCachePhase.java	Thu May 10 00:33:58 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/types/PropagateTypeCachePhase.java	Thu May 10 00:36:12 2012 +0200
@@ -228,7 +228,12 @@
                                 }
                             }
                             ValueNode replacement = canonical.replacement;
-                            currentGraph.replaceFloating((FloatingNode) node, replacement);
+                            if (node instanceof FloatingNode) {
+                                currentGraph.replaceFloating((FloatingNode) node, replacement);
+                            } else {
+                                assert node instanceof FixedWithNextNode;
+                                currentGraph.replaceFixed((FixedWithNextNode) node, replacement);
+                            }
                             changedNodes.addAll(replacement.usages());
                         }
                     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java	Thu May 10 00:33:58 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java	Thu May 10 00:36:12 2012 +0200
@@ -336,21 +336,21 @@
                 if (array.exactType() != null) {
                     RiResolvedType elementType = array.exactType().componentType();
                     if (elementType.superType() != null) {
-                        AnchorNode anchor = graph.add(new AnchorNode());
-                        graph.addBeforeFixed(storeIndexed, anchor);
                         ConstantNode type = ConstantNode.forCiConstant(elementType.getEncoding(Representation.ObjectHub), this, graph);
-                        value = graph.unique(new CheckCastNode(anchor, type, elementType, value));
+                        CheckCastNode checkcast = graph.add(new CheckCastNode(type, elementType, value));
+                        graph.addBeforeFixed(storeIndexed, checkcast);
+                        value = checkcast;
                     } else {
                         assert elementType.name().equals("Ljava/lang/Object;") : elementType.name();
                     }
                 } else {
-                    AnchorNode anchor = graph.add(new AnchorNode());
-                    graph.addBeforeFixed(storeIndexed, anchor);
                     GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(array, false)), RiDeoptReason.NullCheckException, RiDeoptAction.InvalidateReprofile, StructuredGraph.INVALID_GRAPH_ID);
                     FloatingReadNode arrayClass = graph.unique(new FloatingReadNode(array, null, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.hubOffset, graph), StampFactory.objectNonNull()));
                     arrayClass.setGuard(guard);
                     FloatingReadNode arrayElementKlass = graph.unique(new FloatingReadNode(arrayClass, null, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.arrayClassElementOffset, graph), StampFactory.objectNonNull()));
-                    value = graph.unique(new CheckCastNode(anchor, arrayElementKlass, null, value));
+                    CheckCastNode checkcast = graph.add(new CheckCastNode(arrayElementKlass, null, value));
+                    graph.addBeforeFixed(storeIndexed, checkcast);
+                    value = checkcast;
                 }
             }
             WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation));
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/LowerCheckCastPhase.java	Thu May 10 00:33:58 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/LowerCheckCastPhase.java	Thu May 10 00:36:12 2012 +0200
@@ -77,7 +77,7 @@
             hintHubsSet.put(hintHubsConst, hintHubsConst);
             Debug.log("Lowering checkcast in %s: node=%s, hintsHubs=%s, exact=%b", graph, node, Arrays.toString(hints.types), hints.exact);
 
-            InliningUtil.inlineSnippet(runtime, node, (FixedWithNextNode) node.anchor(), snippetGraph, true, immutabilityPredicate, hub, object, hintHubsConst, CiConstant.forBoolean(hints.exact));
+            InliningUtil.inlineSnippet(runtime, node, node, snippetGraph, true, immutabilityPredicate, hub, object, hintHubsConst, CiConstant.forBoolean(hints.exact));
         }
         if (!hintHubsSet.isEmpty()) {
             Debug.log("Lowered %d checkcasts in %s ", hintHubsSet.size(), graph);
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Thu May 10 00:33:58 2012 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Thu May 10 00:36:12 2012 +0200
@@ -610,11 +610,8 @@
         if (initialized) {
             ConstantNode typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, true);
             ValueNode object = frameState.apop();
-            AnchorNode anchor = currentGraph.add(new AnchorNode());
-            append(anchor);
-            CheckCastNode checkCast;
-            checkCast = currentGraph.unique(new CheckCastNode(anchor, typeInstruction, (RiResolvedType) type, object, getProfileForTypeCheck((RiResolvedType) type)));
-            append(currentGraph.add(new ValueAnchorNode(checkCast)));
+            CheckCastNode checkCast = currentGraph.add(new CheckCastNode(typeInstruction, (RiResolvedType) type, object, getProfileForTypeCheck((RiResolvedType) type)));
+            append(checkCast);
             frameState.apush(checkCast);
         } else {
             ValueNode object = frameState.apop();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Thu May 10 00:33:58 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Thu May 10 00:36:12 2012 +0200
@@ -25,7 +25,6 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.spi.types.*;
 import com.oracle.graal.nodes.type.*;
@@ -33,40 +32,31 @@
 import com.oracle.max.cri.ri.*;
 
 /**
- * The {@code CheckCastNode} represents a {@link Bytecodes#CHECKCAST}.
- *
- * The {@link #targetClass()} of a CheckCastNode can be null for array store checks!
+ * Implements a type check that results in a {@link ClassCastException} if it fails.
  */
-public final class CheckCastNode extends BooleanNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType, TypeFeedbackProvider, TypeCanonicalizable {
+public final class CheckCastNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType, TypeFeedbackProvider, TypeCanonicalizable {
 
-    @Input(notDataflow = true) protected final FixedNode anchor;
     @Input private ValueNode object;
     @Input private ValueNode targetClassInstruction;
     private final RiResolvedType targetClass;
     private final RiTypeProfile profile;
 
-    public FixedNode anchor() {
-        return anchor;
-    }
-
     /**
      * Creates a new CheckCast instruction.
-     *
      * @param targetClassInstruction the instruction which produces the class which is being cast to
      * @param targetClass the class being cast to
      * @param object the instruction producing the object
      */
-    public CheckCastNode(FixedNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object) {
-        this(anchor, targetClassInstruction, targetClass, object, null);
+    public CheckCastNode(ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object) {
+        this(targetClassInstruction, targetClass, object, null);
     }
 
-    public CheckCastNode(FixedNode anchor, ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, RiTypeProfile profile) {
+    public CheckCastNode(ValueNode targetClassInstruction, RiResolvedType targetClass, ValueNode object, RiTypeProfile profile) {
         super(targetClass == null ? StampFactory.forKind(CiKind.Object) : StampFactory.declared(targetClass));
         this.targetClassInstruction = targetClassInstruction;
         this.targetClass = targetClass;
         this.object = object;
         this.profile = profile;
-        this.anchor = anchor;
     }
 
     @Override
@@ -81,7 +71,6 @@
         RiResolvedType objectDeclaredType = object().declaredType();
         if (objectDeclaredType != null && targetClass != null && objectDeclaredType.isSubtypeOf(targetClass)) {
             // we don't have to check for null types here because they will also pass the checkcast.
-            freeAnchor();
             return object();
         }
 
@@ -89,26 +78,12 @@
         if (constant != null) {
             assert constant.kind == CiKind.Object;
             if (constant.isNull()) {
-                freeAnchor();
                 return object();
             }
         }
         return this;
     }
 
-    // TODO (thomaswue): Find a better way to handle anchors.
-    private void freeAnchor() {
-        ValueAnchorNode anchorUsage = usages().filter(ValueAnchorNode.class).first();
-        if (anchorUsage != null) {
-            anchorUsage.replaceFirstInput(this, null);
-        }
-    }
-
-    @Override
-    public BooleanNode negate() {
-        throw new Error("A CheckCast does not produce a boolean value, so it should actually not be a subclass of BooleanNode");
-    }
-
     @Override
     public void typeFeedback(TypeFeedbackTool tool) {
         if (targetClass() != null) {
@@ -139,7 +114,10 @@
 
     /**
      * Gets the target class, i.e. the class being cast to, or the class being tested against.
-     * @return the target class
+     * This may be null in the case where the type being tested is dynamically loaded such as
+     * when checking an object array store.
+     *
+     * @return the target class or null if not known
      */
     public RiResolvedType targetClass() {
         return targetClass;
--- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/LowerCheckCastTest.java	Thu May 10 00:33:58 2012 +0200
+++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/LowerCheckCastTest.java	Thu May 10 00:36:12 2012 +0200
@@ -50,8 +50,8 @@
 
         CheckCastNode ccn = graph.getNodes(CheckCastNode.class).first();
         assert ccn != null;
-        CheckCastNode ccnNew = graph.add(new CheckCastNode(ccn.anchor(), ccn.targetClassInstruction(), ccn.targetClass(), ccn.object(), profile));
-        graph.replaceFloating(ccn, ccnNew);
+        CheckCastNode ccnNew = graph.add(new CheckCastNode(ccn.targetClassInstruction(), ccn.targetClass(), ccn.object(), profile));
+        graph.replaceFixedWithFixed(ccn, ccnNew);
 
         final RiResolvedMethod riMethod = runtime.getRiMethod(method);
         CiTargetMethod targetMethod = runtime.compile(riMethod, graph);