# HG changeset patch # User Doug Simon # Date 1370423778 -7200 # Node ID 5ba11d51fe80e4b4032a7e2dd85858dc59b312e0 # Parent 9006bc30a951073378f0412f5fb9e9c2e8641edd# Parent 49fb2675c66579157b6ee5455da0baa9f66fecdb Merge. diff -r 9006bc30a951 -r 5ba11d51fe80 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Tue Jun 04 18:11:01 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Wed Jun 05 11:16:18 2013 +0200 @@ -634,7 +634,9 @@ graph.replaceFixed(loadMethodNode, metaspaceMethod); } else if (n instanceof FixedGuardNode) { FixedGuardNode node = (FixedGuardNode) n; - ValueAnchorNode newAnchor = graph.add(new ValueAnchorNode(tool.createGuard(node.condition(), node.getReason(), node.getAction(), node.isNegated()).asNode())); + GuardingNode guard = tool.createGuard(node.condition(), node.getReason(), node.getAction(), node.isNegated()); + ValueAnchorNode newAnchor = graph.add(new ValueAnchorNode(guard.asNode())); + node.replaceAtUsages(guard.asNode()); graph.replaceFixedWithFixed(node, newAnchor); } else if (n instanceof CommitAllocationNode) { CommitAllocationNode commit = (CommitAllocationNode) n; diff -r 9006bc30a951 -r 5ba11d51fe80 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Tue Jun 04 18:11:01 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Wed Jun 05 11:16:18 2013 +0200 @@ -25,12 +25,13 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; @NodeInfo(nameTemplate = "FixedGuard(!={p#negated}) {p#reason/s}") -public final class FixedGuardNode extends FixedWithNextNode implements Simplifiable, Lowerable, Node.IterableNodeType, Negatable { +public final class FixedGuardNode extends FixedWithNextNode implements Simplifiable, Lowerable, Node.IterableNodeType, Negatable, GuardingNode { @Input private LogicNode condition; private final DeoptimizationReason reason; @@ -51,7 +52,7 @@ } public FixedGuardNode(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) { - super(StampFactory.forVoid()); + super(StampFactory.dependency()); this.action = action; this.negated = negated; this.condition = condition; @@ -84,6 +85,7 @@ if (condition instanceof LogicConstantNode) { LogicConstantNode c = (LogicConstantNode) condition; if (c.getValue() != negated) { + this.replaceAtUsages(BeginNode.prevBegin(this)); graph().removeFixed(this); } else { FixedNode next = this.next(); @@ -121,4 +123,9 @@ negated = !negated; return this; } + + @Override + public FixedGuardNode asNode() { + return this; + } } diff -r 9006bc30a951 -r 5ba11d51fe80 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Tue Jun 04 18:11:01 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Wed Jun 05 11:16:18 2013 +0200 @@ -83,8 +83,8 @@ // UnsafeAccess only have an // object base ObjectStamp receiverStamp = object().objectStamp(); - if (receiverStamp.nonNull()) { - ResolvedJavaType receiverType = receiverStamp.type(); + ResolvedJavaType receiverType = receiverStamp.type(); + if (receiverStamp.nonNull() && receiverType != null) { ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement()); if (field != null) { return this.graph().add(new LoadFieldNode(object(), field)); diff -r 9006bc30a951 -r 5ba11d51fe80 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Tue Jun 04 18:11:01 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Wed Jun 05 11:16:18 2013 +0200 @@ -61,6 +61,10 @@ } } + public void removeAnchoredNode(ValueNode value) { + this.anchored.remove(value); + } + @Override public ValueNode canonical(CanonicalizerTool tool) { if (permanent) { diff -r 9006bc30a951 -r 5ba11d51fe80 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Tue Jun 04 18:11:01 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Wed Jun 05 11:16:18 2013 +0200 @@ -1271,6 +1271,10 @@ FrameState stateAfter = invoke.stateAfter(); assert stateAfter == null || stateAfter.isAlive(); + GuardingNode receiverNullCheckNode = null; + if (receiverNullCheck) { + receiverNullCheckNode = receiverNullCheck(invoke); + } IdentityHashMap replacements = new IdentityHashMap<>(); ArrayList nodes = new ArrayList<>(); @@ -1282,7 +1286,18 @@ if (node == entryPointNode || node == entryPointNode.stateAfter()) { // Do nothing. } else if (node instanceof LocalNode) { - replacements.put(node, parameters.get(((LocalNode) node).index())); + int localIndex = ((LocalNode) node).index(); + ValueNode parameter = parameters.get(localIndex); + if (receiverNullCheckNode != null && localIndex == 0) { + Stamp piStamp = parameter.stamp(); + if (piStamp instanceof ObjectStamp) { + piStamp = piStamp.join(StampFactory.objectNonNull()); + } + PiNode piReceiver = graph.add(new PiNode(parameter, piStamp)); + piReceiver.setGuard(receiverNullCheckNode); + parameter = piReceiver; + } + replacements.put(node, parameter); } else { nodes.add(node); if (node instanceof ReturnNode) { @@ -1302,9 +1317,6 @@ Map duplicates = graph.addDuplicates(nodes, replacements); FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode); - if (receiverNullCheck) { - receiverNullCheck(invoke); - } invoke.asNode().replaceAtPredecessor(firstCFGNodeDuplicate); FrameState stateAtExceptionEdge = null; @@ -1410,15 +1422,17 @@ return true; } - public static void receiverNullCheck(Invoke invoke) { + public static GuardingNode receiverNullCheck(Invoke invoke) { MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget(); StructuredGraph graph = callTarget.graph(); NodeInputList parameters = callTarget.arguments(); ValueNode firstParam = parameters.size() <= 0 ? null : parameters.get(0); if (!callTarget.isStatic() && firstParam.kind() == Kind.Object && !firstParam.objectStamp().nonNull()) { - graph.addBeforeFixed(invoke.asNode(), - graph.add(new FixedGuardNode(graph.unique(new IsNullNode(firstParam)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true))); + FixedGuardNode guard = graph.add(new FixedGuardNode(graph.unique(new IsNullNode(firstParam)), DeoptimizationReason.NullCheckException, DeoptimizationAction.InvalidateReprofile, true)); + graph.addBeforeFixed(invoke.asNode(), guard); + return guard; } + return null; } public static boolean canIntrinsify(Replacements replacements, ResolvedJavaMethod target) { diff -r 9006bc30a951 -r 5ba11d51fe80 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Tue Jun 04 18:11:01 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Wed Jun 05 11:16:18 2013 +0200 @@ -33,6 +33,7 @@ import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; @@ -284,34 +285,8 @@ if (newInstance instanceof ValueNode && (((ValueNode) newInstance).kind() != Kind.Object || ((ValueNode) newInstance).stamp() == StampFactory.forNodeIntrinsic())) { StructuredGraph graph = (StructuredGraph) newInstance.graph(); for (CheckCastNode checkCastNode : newInstance.usages().filter(CheckCastNode.class).snapshot()) { - for (ProxyNode vpn : checkCastNode.usages().filter(ProxyNode.class).snapshot()) { - graph.replaceFloating(vpn, checkCastNode); - } for (Node checkCastUsage : checkCastNode.usages().snapshot()) { - if (checkCastUsage instanceof ValueAnchorNode) { - ValueAnchorNode valueAnchorNode = (ValueAnchorNode) checkCastUsage; - graph.removeFixed(valueAnchorNode); - } else if (checkCastUsage instanceof UnboxNode) { - UnboxNode unbox = (UnboxNode) checkCastUsage; - unbox.replaceAtUsages(newInstance); - graph.removeFixed(unbox); - } else if (checkCastUsage instanceof MethodCallTargetNode) { - MethodCallTargetNode checkCastCallTarget = (MethodCallTargetNode) checkCastUsage; - assert checkCastCallTarget.targetMethod().getAnnotation(NodeIntrinsic.class) != null : "checkcast at " + sourceLocation(checkCastNode) + - " not used by an unboxing method or node intrinsic, but by a call at " + sourceLocation(checkCastCallTarget.usages().first()) + " to " + - checkCastCallTarget.targetMethod(); - checkCastUsage.replaceFirstInput(checkCastNode, checkCastNode.object()); - } else if (checkCastUsage instanceof FrameState) { - checkCastUsage.replaceFirstInput(checkCastNode, null); - } else if (checkCastUsage instanceof ReturnNode && checkCastNode.object().stamp() == StampFactory.forNodeIntrinsic()) { - checkCastUsage.replaceFirstInput(checkCastNode, checkCastNode.object()); - } else if (checkCastUsage instanceof IsNullNode) { - assert checkCastUsage.usages().count() == 1 && checkCastUsage.usages().first().predecessor() == checkCastNode; - graph.replaceFloating((FloatingNode) checkCastUsage, LogicConstantNode.contradiction(graph)); - } else { - Debug.dump(graph, "exception"); - assert false : sourceLocation(checkCastUsage) + " has unexpected usage " + checkCastUsage + " of checkcast at " + sourceLocation(checkCastNode); - } + checkCheckCastUsage(graph, newInstance, checkCastNode, checkCastUsage); } FixedNode next = checkCastNode.next(); checkCastNode.setNext(null); @@ -320,4 +295,47 @@ } } } + + private static void checkCheckCastUsage(StructuredGraph graph, Node intrinsifiedNode, Node input, Node usage) { + if (usage instanceof ValueAnchorNode) { + ValueAnchorNode valueAnchorNode = (ValueAnchorNode) usage; + valueAnchorNode.removeAnchoredNode((ValueNode) input); + Debug.log("%s: Removed a ValueAnchor input", Debug.contextSnapshot(JavaMethod.class)); + } else if (usage instanceof UnboxNode) { + UnboxNode unbox = (UnboxNode) usage; + unbox.replaceAtUsages(intrinsifiedNode); + graph.removeFixed(unbox); + Debug.log("%s: Removed an UnboxNode", Debug.contextSnapshot(JavaMethod.class)); + } else if (usage instanceof MethodCallTargetNode) { + MethodCallTargetNode checkCastCallTarget = (MethodCallTargetNode) usage; + assert checkCastCallTarget.targetMethod().getAnnotation(NodeIntrinsic.class) != null : "checkcast at " + sourceLocation(input) + + " not used by an unboxing method or node intrinsic, but by a call at " + sourceLocation(checkCastCallTarget.usages().first()) + " to " + checkCastCallTarget.targetMethod(); + usage.replaceFirstInput(input, intrinsifiedNode); + Debug.log("%s: Checkcast used in an other node intrinsic", Debug.contextSnapshot(JavaMethod.class)); + } else if (usage instanceof FrameState) { + usage.replaceFirstInput(input, null); + Debug.log("%s: Checkcast used in a FS", Debug.contextSnapshot(JavaMethod.class)); + } else if (usage instanceof ReturnNode && ((ValueNode) intrinsifiedNode).stamp() == StampFactory.forNodeIntrinsic()) { + usage.replaceFirstInput(input, intrinsifiedNode); + Debug.log("%s: Checkcast used in a return with forNodeIntrinsic stamp", Debug.contextSnapshot(JavaMethod.class)); + } else if (usage instanceof IsNullNode) { + assert usage.usages().count() == 1 && usage.usages().first().predecessor() == input; + graph.replaceFloating((FloatingNode) usage, LogicConstantNode.contradiction(graph)); + Debug.log("%s: Replaced IsNull with false", Debug.contextSnapshot(JavaMethod.class)); + } else if (usage instanceof ProxyNode) { + ProxyNode proxy = (ProxyNode) usage; + assert proxy.type() == PhiType.Value; + ProxyNode newProxy = graph.unique(new ProxyNode((ValueNode) intrinsifiedNode, proxy.proxyPoint(), PhiType.Value, proxy.getIdentity())); + for (Node proxyUsage : usage.usages().snapshot()) { + checkCheckCastUsage(graph, newProxy, proxy, proxyUsage); + } + } else if (usage instanceof PiNode) { + for (Node piUsage : usage.usages().snapshot()) { + checkCheckCastUsage(graph, intrinsifiedNode, usage, piUsage); + } + } else { + Debug.dump(graph, "exception"); + assert false : sourceLocation(usage) + " has unexpected usage " + usage + " of checkcast at " + sourceLocation(input); + } + } }