# HG changeset patch # User Doug Simon # Date 1336602972 -7200 # Node ID 4485e0edd1af42f5d1a610ce34f514f26237f1b8 # Parent 3fd6b0ab1146eaa2d9f064c93a0926c4e9b5dc21 made CheckCastNode be a FixedNode instead of a BooleanNode diff -r 3fd6b0ab1146 -r 4485e0edd1af graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/SnippetIntrinsificationPhase.java --- 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); } } } diff -r 3fd6b0ab1146 -r 4485e0edd1af graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/types/PropagateTypeCachePhase.java --- 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()); } } diff -r 3fd6b0ab1146 -r 4485e0edd1af graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java --- 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)); diff -r 3fd6b0ab1146 -r 4485e0edd1af graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/LowerCheckCastPhase.java --- 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); diff -r 3fd6b0ab1146 -r 4485e0edd1af graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- 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(); diff -r 3fd6b0ab1146 -r 4485e0edd1af 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 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; diff -r 3fd6b0ab1146 -r 4485e0edd1af graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/LowerCheckCastTest.java --- 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);