# HG changeset patch # User Lukas Stadler # Date 1398413634 -7200 # Node ID 669536c4949a83ac26ed906ec56b3f818681468b # Parent 85e1bf62208cad609dc9cce9644cd439b5203f85 clean up ExceptionObjectNode lowering diff -r 85e1bf62208c -r 669536c4949a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Thu Apr 24 23:32:30 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Fri Apr 25 10:13:54 2014 +0200 @@ -192,8 +192,10 @@ if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { newObjectSnippets.lower((NewMultiArrayNode) n, tool); } - } else if (n instanceof LoadExceptionObjectNode) { - exceptionObjectSnippets.lower((LoadExceptionObjectNode) n, registers, tool); + } else if (n instanceof ExceptionObjectNode) { + if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { + lowerExceptionObjectNode((ExceptionObjectNode) n, tool); + } } else if (n instanceof IntegerDivNode || n instanceof IntegerRemNode || n instanceof UnsignedDivNode || n instanceof UnsignedRemNode) { // Nothing to do for division nodes. The HotSpot signal handler catches divisions by // zero and the MIN_VALUE / -1 cases. @@ -732,6 +734,19 @@ } } + private void lowerExceptionObjectNode(ExceptionObjectNode n, LoweringTool tool) { + LocationIdentity locationsKilledByInvoke = ((InvokeWithExceptionNode) n.predecessor()).getLocationIdentity(); + BeginNode entry = n.graph().add(new KillingBeginNode(locationsKilledByInvoke)); + LoadExceptionObjectNode loadException = n.graph().add(new LoadExceptionObjectNode(StampFactory.declaredNonNull(metaAccess.lookupJavaType(Throwable.class)))); + + loadException.setStateAfter(n.stateAfter()); + n.replaceAtUsages(InputType.Value, loadException); + n.graph().replaceFixedWithFixed(n, entry); + entry.graph().addAfterFixed(entry, loadException); + + exceptionObjectSnippets.lower(loadException, registers, tool); + } + protected static void finishAllocatedObjects(LoweringTool tool, CommitAllocationNode commit, ValueNode[] allocations) { StructuredGraph graph = commit.graph(); for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) { diff -r 85e1bf62208c -r 669536c4949a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LoadExceptionObjectNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LoadExceptionObjectNode.java Fri Apr 25 10:13:54 2014 +0200 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.nodes; + +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; + +public class LoadExceptionObjectNode extends AbstractStateSplit implements Lowerable { + + public LoadExceptionObjectNode(Stamp stamp) { + super(stamp); + } + + @Override + public void lower(LoweringTool tool) { + tool.getLowerer().lower(this, tool); + } +} diff -r 85e1bf62208c -r 669536c4949a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java Thu Apr 24 23:32:30 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java Fri Apr 25 10:13:54 2014 +0200 @@ -30,9 +30,9 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; @@ -44,6 +44,12 @@ /** * Snippet for loading the exception object at the start of an exception dispatcher. + *

+ * The frame state upon entry to an exception handler is such that it is a + * {@link BytecodeFrame#rethrowException rethrow exception} state and the stack contains exactly the + * exception object (per the JVM spec) to rethrow. This means that the code generated for this node + * must not cause a deoptimization as the runtime/interpreter would not have a valid location to + * find the exception object to be rethrown. */ public class LoadExceptionObjectSnippets implements Snippets { diff -r 85e1bf62208c -r 669536c4949a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Thu Apr 24 23:32:30 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Fri Apr 25 10:13:54 2014 +0200 @@ -37,7 +37,7 @@ private static final double EXCEPTION_PROBA = 1e-5; @Successor private BeginNode next; - @Successor private DispatchBeginNode exceptionEdge; + @Successor private BeginNode exceptionEdge; @Input(InputType.Extension) private CallTargetNode callTarget; @Input(InputType.State) private FrameState stateDuring; @Input(InputType.State) private FrameState stateAfter; @@ -47,7 +47,7 @@ private boolean useForInlining; private double exceptionProbability; - public InvokeWithExceptionNode(CallTargetNode callTarget, DispatchBeginNode exceptionEdge, int bci) { + public InvokeWithExceptionNode(CallTargetNode callTarget, BeginNode exceptionEdge, int bci) { super(callTarget.returnStamp()); this.exceptionEdge = exceptionEdge; this.bci = bci; @@ -57,11 +57,11 @@ this.exceptionProbability = EXCEPTION_PROBA; } - public DispatchBeginNode exceptionEdge() { + public BeginNode exceptionEdge() { return exceptionEdge; } - public void setExceptionEdge(DispatchBeginNode x) { + public void setExceptionEdge(BeginNode x) { updatePredecessor(exceptionEdge, x); exceptionEdge = x; } diff -r 85e1bf62208c -r 669536c4949a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java Thu Apr 24 23:32:30 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java Fri Apr 25 10:13:54 2014 +0200 @@ -25,8 +25,8 @@ import java.util.*; import com.oracle.graal.compiler.common.cfg.*; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.java.*; public final class Block extends AbstractBlockBase { @@ -67,7 +67,8 @@ } public boolean isExceptionEntry() { - return getBeginNode() instanceof ExceptionObjectNode; + Node predecessor = getBeginNode().predecessor(); + return predecessor != null && predecessor instanceof InvokeWithExceptionNode && getBeginNode() != ((InvokeWithExceptionNode) predecessor).exceptionEdge(); } public Block getFirstPredecessor() { diff -r 85e1bf62208c -r 669536c4949a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryNode.java Thu Apr 24 23:32:30 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryNode.java Fri Apr 25 10:13:54 2014 +0200 @@ -22,12 +22,13 @@ */ package com.oracle.graal.nodes.extended; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; /** * This interface marks nodes that are part of the memory graph. */ -public interface MemoryNode { +public interface MemoryNode extends NodeInterface { ValueNode asNode(); diff -r 85e1bf62208c -r 669536c4949a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Thu Apr 24 23:32:30 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Fri Apr 25 10:13:54 2014 +0200 @@ -22,13 +22,9 @@ */ package com.oracle.graal.nodes.java; -import java.util.*; - -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; -import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; @@ -37,6 +33,7 @@ * The entry to an exception handler with the exception coming from a call (as opposed to a local * throw instruction or implicit exception). */ +@NodeInfo(allowedUsageTypes = {InputType.Memory}) public class ExceptionObjectNode extends DispatchBeginNode implements Lowerable, MemoryCheckpoint.Single { public ExceptionObjectNode(MetaAccessProvider metaAccess) { @@ -49,56 +46,13 @@ } @Override - public void simplify(SimplifierTool tool) { - // - } - - private boolean isLowered() { - return (stamp() == StampFactory.forVoid()); - } - - /** - * The frame state upon entry to an exception handler is such that it is a - * {@link BytecodeFrame#rethrowException rethrow exception} state and the stack contains exactly - * the exception object (per the JVM spec) to rethrow. This means that the code creating this - * state (i.e. the {@link LoadExceptionObjectNode}) cannot cause a deoptimization as the - * runtime/interpreter would not have a valid location for the exception object to be rethrown. - */ - @Override public void lower(LoweringTool tool) { - if (isLowered()) { - return; - } - LoadExceptionObjectNode loadException = graph().add(new LoadExceptionObjectNode(stamp())); - loadException.setStateAfter(stateAfter()); - List guardedNodes = new ArrayList<>(); - for (Node usage : usages().snapshot()) { - if (usage instanceof GuardedNode) { - // can't replace the guard with LoadExceptionObjectNode as it is not a GuardingNode - // so temporarily change it to remove the GuardedNode from usages - GuardedNode guardedNode = (GuardedNode) usage; - guardedNode.setGuard(graph().add(new BeginNode())); - guardedNodes.add(guardedNode); - } - } - replaceAtUsages(loadException); - for (GuardedNode guardedNode : guardedNodes) { - BeginNode dummyGuard = (BeginNode) guardedNode.getGuard(); - guardedNode.setGuard(this); - graph().removeFixed(dummyGuard); - } - graph().addAfterFixed(this, loadException); - setStateAfter(null); - setStamp(StampFactory.forVoid()); - loadException.lower(tool); + tool.getLowerer().lower(this, tool); } @Override public boolean verify() { - if (isLowered()) { - return true; - } - assertTrue(stateAfter() != null || stamp() == StampFactory.forVoid(), "an exception handler needs a frame state"); + assertTrue(stateAfter() != null, "an exception handler needs a frame state"); return super.verify(); } diff -r 85e1bf62208c -r 669536c4949a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java Thu Apr 24 23:32:30 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.nodes.java; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; - -/** - * Loads an exception object passed by the runtime from a callee to an exception handler in a - * caller. The node is only produced when lowering an {@link ExceptionObjectNode}. - *

- * The frame state upon entry to an exception handler is such that it is a - * {@link BytecodeFrame#rethrowException rethrow exception} state and the stack contains exactly the - * exception object (per the JVM spec) to rethrow. This means that the code generated for this node - * must not cause a deoptimization as the runtime/interpreter would not have a valid location to - * find the exception object to be rethrown. - */ -public class LoadExceptionObjectNode extends AbstractStateSplit implements Lowerable { - - public LoadExceptionObjectNode(Stamp stamp) { - super(stamp); - } - - @Override - public void lower(LoweringTool tool) { - tool.getLowerer().lower(this, tool); - } -}