# HG changeset patch # User Gilles Duboscq # Date 1380209419 -7200 # Node ID d72c314260dc32e7103291ef9b6bd015a1d54d75 # Parent 2d74afd9e5ed15857e299411bfc401957f5325ea Add a DynamicDeoptimizeNode where the action and reason is a input node. diff -r 2d74afd9e5ed -r d72c314260dc graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java --- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Thu Sep 26 16:26:56 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Thu Sep 26 17:30:19 2013 +0200 @@ -579,7 +579,7 @@ } @Override - public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason, DeoptimizingNode deopting) { + public void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting) { append(new ReturnOp(Value.ILLEGAL)); } diff -r 2d74afd9e5ed -r d72c314260dc graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Thu Sep 26 16:26:56 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Thu Sep 26 17:30:19 2013 +0200 @@ -619,7 +619,7 @@ } @Override - public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason, DeoptimizingNode deopting) { + public void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting) { append(new ReturnOp(Value.ILLEGAL)); } diff -r 2d74afd9e5ed -r d72c314260dc graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Thu Sep 26 16:26:56 2013 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Thu Sep 26 17:30:19 2013 +0200 @@ -837,7 +837,7 @@ } @Override - public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason, DeoptimizingNode deopting) { + public void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting) { append(new ReturnOp(Value.ILLEGAL)); } diff -r 2d74afd9e5ed -r d72c314260dc graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Thu Sep 26 16:26:56 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Thu Sep 26 17:30:19 2013 +0200 @@ -363,27 +363,28 @@ append(new AMD64HotSpotUnwindOp(exceptionParameter)); } - private void moveDeoptimizationActionAndReasonToThread(DeoptimizationAction action, DeoptimizationReason reason) { - Constant encoded = runtime.encodeDeoptActionAndReason(action, reason); + private void moveDeoptimizationActionAndReasonToThread(Value actionAndReason) { int pendingDeoptimizationOffset = graalRuntime().getConfig().pendingDeoptimizationOffset; RegisterValue thread = runtime().threadRegister().asValue(HotSpotGraalRuntime.wordKind()); - AMD64AddressValue pendingDeoptAddress = new AMD64AddressValue(encoded.getKind(), thread, pendingDeoptimizationOffset); - if (runtime.needsDataPatch(encoded)) { - append(new StoreOp(encoded.getKind(), pendingDeoptAddress, emitMove(encoded), null)); + AMD64AddressValue pendingDeoptAddress = new AMD64AddressValue(actionAndReason.getKind(), thread, pendingDeoptimizationOffset); + if (actionAndReason instanceof Constant && !runtime.needsDataPatch((Constant) actionAndReason)) { + Constant constantActionAndReason = (Constant) actionAndReason; + assert !runtime.needsDataPatch(constantActionAndReason); + append(new StoreConstantOp(constantActionAndReason.getKind(), pendingDeoptAddress, constantActionAndReason, null)); } else { - append(new StoreConstantOp(encoded.getKind(), pendingDeoptAddress, encoded, null)); + append(new StoreOp(actionAndReason.getKind(), pendingDeoptAddress, load(actionAndReason), null)); } } @Override - public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason, DeoptimizingNode deopting) { - moveDeoptimizationActionAndReasonToThread(action, reason); + public void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting) { + moveDeoptimizationActionAndReasonToThread(actionAndReason); append(new AMD64DeoptimizeOp(state(deopting))); } @Override public void emitDeoptimizeCaller(DeoptimizationAction action, DeoptimizationReason reason) { - moveDeoptimizationActionAndReasonToThread(action, reason); + moveDeoptimizationActionAndReasonToThread(runtime.encodeDeoptActionAndReason(action, reason)); append(new AMD64HotSpotDeoptimizeCallerOp()); } diff -r 2d74afd9e5ed -r d72c314260dc graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Thu Sep 26 16:26:56 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Thu Sep 26 17:30:19 2013 +0200 @@ -184,23 +184,22 @@ append(new SPARCHotSpotUnwindOp(exceptionParameter)); } - private void moveDeoptimizationActionAndReasonToThread(DeoptimizationAction action, DeoptimizationReason reason) { - Constant encoded = runtime.encodeDeoptActionAndReason(action, reason); + private void moveDeoptimizationActionAndReasonToThread(Value actionAndReason) { int pendingDeoptimizationOffset = graalRuntime().getConfig().pendingDeoptimizationOffset; RegisterValue thread = runtime().threadRegister().asValue(HotSpotGraalRuntime.wordKind()); - SPARCAddressValue pendingDeoptAddress = new SPARCAddressValue(encoded.getKind(), thread, pendingDeoptimizationOffset); - append(new StoreOp(encoded.getKind(), pendingDeoptAddress, emitMove(encoded), null)); + SPARCAddressValue pendingDeoptAddress = new SPARCAddressValue(actionAndReason.getKind(), thread, pendingDeoptimizationOffset); + append(new StoreOp(actionAndReason.getKind(), pendingDeoptAddress, emitMove(actionAndReason), null)); } @Override - public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason, DeoptimizingNode deopting) { - moveDeoptimizationActionAndReasonToThread(action, reason); + public void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting) { + moveDeoptimizationActionAndReasonToThread(actionAndReason); append(new SPARCDeoptimizeOp(state(deopting))); } @Override public void emitDeoptimizeCaller(DeoptimizationAction action, DeoptimizationReason reason) { - moveDeoptimizationActionAndReasonToThread(action, reason); + moveDeoptimizationActionAndReasonToThread(runtime.encodeDeoptActionAndReason(action, reason)); append(new SPARCHotSpotDeoptimizeCallerOp()); } diff -r 2d74afd9e5ed -r d72c314260dc graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractDeoptimizeNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractDeoptimizeNode.java Thu Sep 26 17:30:19 2013 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013, 2013, 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; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.type.*; + +/** + * This node represents an unconditional explicit request for immediate deoptimization. + * + * After this node, execution will continue using a fallback execution engine (such as an + * interpreter) at the position described by the {@link #getDeoptimizationState() deoptimization + * state}. + * + */ +@NodeInfo(shortName = "Deopt", nameTemplate = "Deopt {p#reason/s}") +public abstract class AbstractDeoptimizeNode extends ControlSinkNode implements IterableNodeType, DeoptimizingNode { + + @Input private FrameState deoptState; + + public AbstractDeoptimizeNode() { + super(StampFactory.forVoid()); + } + + @Override + public boolean canDeoptimize() { + return true; + } + + @Override + public FrameState getDeoptimizationState() { + return deoptState; + } + + @Override + public void setDeoptimizationState(FrameState f) { + updateUsages(deoptState, f); + deoptState = f; + } + + public FrameState getState() { + return deoptState; + } +} diff -r 2d74afd9e5ed -r d72c314260dc graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Thu Sep 26 16:26:56 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Thu Sep 26 17:30:19 2013 +0200 @@ -24,28 +24,14 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; -/** - * This node represents an unconditional explicit request for immediate deoptimization. - * - * After this node, execution will continue using a fallback execution engine (such as an - * interpreter) at the position described by the {@link #getDeoptimizationState() deoptimization - * state}. - * - */ -@NodeInfo(shortName = "Deopt", nameTemplate = "Deopt {p#reason/s}") -public class DeoptimizeNode extends ControlSinkNode implements IterableNodeType, LIRLowerable, DeoptimizingNode { - - @Input private FrameState deoptState; +public class DeoptimizeNode extends AbstractDeoptimizeNode implements LIRLowerable { private final DeoptimizationAction action; private final DeoptimizationReason reason; public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason) { - super(StampFactory.forVoid()); this.action = action; this.reason = reason; } @@ -60,29 +46,9 @@ @Override public void generate(LIRGeneratorTool gen) { - gen.emitDeoptimize(action, reason, this); + gen.emitDeoptimize(gen.getRuntime().encodeDeoptActionAndReason(action, reason), this); } @NodeIntrinsic public static native void deopt(@ConstantNodeParameter DeoptimizationAction action, @ConstantNodeParameter DeoptimizationReason reason); - - @Override - public boolean canDeoptimize() { - return true; - } - - @Override - public FrameState getDeoptimizationState() { - return deoptState; - } - - @Override - public void setDeoptimizationState(FrameState f) { - updateUsages(deoptState, f); - deoptState = f; - } - - public FrameState getState() { - return deoptState; - } } diff -r 2d74afd9e5ed -r d72c314260dc graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java Thu Sep 26 17:30:19 2013 +0200 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013, 2013, 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; + +import com.oracle.graal.nodes.spi.*; + +public class DynamicDeoptimizeNode extends AbstractDeoptimizeNode implements LIRLowerable { + @Input private ValueNode actionAndReason; + + public DynamicDeoptimizeNode(ValueNode actionAndReason) { + this.actionAndReason = actionAndReason; + } + + public ValueNode getActionAndReason() { + return actionAndReason; + } + + public void generate(LIRGeneratorTool generator) { + generator.emitDeoptimize(generator.operand(actionAndReason), this); + } +} diff -r 2d74afd9e5ed -r d72c314260dc graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Thu Sep 26 16:26:56 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Thu Sep 26 17:30:19 2013 +0200 @@ -63,7 +63,7 @@ void emitMembar(int barriers); - void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason, DeoptimizingNode deopting); + void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting); void emitNullCheck(ValueNode v, DeoptimizingNode deopting); diff -r 2d74afd9e5ed -r d72c314260dc graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java Thu Sep 26 16:26:56 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java Thu Sep 26 17:30:19 2013 +0200 @@ -29,7 +29,7 @@ import com.oracle.graal.phases.*; /** - * This phase tries to find {@link DeoptimizeNode DeoptimizeNodes} which use the same + * This phase tries to find {@link AbstractDeoptimizeNode DeoptimizeNodes} which use the same * {@link FrameState} and merges them together. */ public class DeoptimizationGroupingPhase extends Phase { @@ -39,8 +39,8 @@ ControlFlowGraph cfg = null; for (FrameState fs : graph.getNodes(FrameState.class)) { FixedNode target = null; - List obsoletes = null; - for (DeoptimizeNode deopt : fs.usages().filter(DeoptimizeNode.class)) { + List obsoletes = null; + for (AbstractDeoptimizeNode deopt : fs.usages().filter(AbstractDeoptimizeNode.class)) { if (target == null) { target = deopt; } else { @@ -48,12 +48,12 @@ cfg = ControlFlowGraph.compute(graph, true, true, false, false); } MergeNode merge; - if (target instanceof DeoptimizeNode) { + if (target instanceof AbstractDeoptimizeNode) { merge = graph.add(new MergeNode()); EndNode firstEnd = graph.add(new EndNode()); merge.addForwardEnd(firstEnd); target.predecessor().replaceFirstSuccessor(target, firstEnd); - exitLoops((DeoptimizeNode) target, firstEnd, cfg); + exitLoops((AbstractDeoptimizeNode) target, firstEnd, cfg); merge.setNext(target); obsoletes = new LinkedList<>(); target = merge; @@ -68,14 +68,14 @@ } } if (obsoletes != null) { - for (DeoptimizeNode obsolete : obsoletes) { + for (AbstractDeoptimizeNode obsolete : obsoletes) { obsolete.safeDelete(); } } } } - private static void exitLoops(DeoptimizeNode deopt, EndNode end, ControlFlowGraph cfg) { + private static void exitLoops(AbstractDeoptimizeNode deopt, EndNode end, ControlFlowGraph cfg) { Block block = cfg.blockFor(deopt); Loop loop = block.getLoop(); while (loop != null) { diff -r 2d74afd9e5ed -r d72c314260dc graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java Thu Sep 26 16:26:56 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java Thu Sep 26 17:30:19 2013 +0200 @@ -77,8 +77,8 @@ private void adjustControlSplitProbabilities() { HashSet result = new HashSet<>(); NodeBitMap visitedNodes = new NodeBitMap(graph); - for (DeoptimizeNode n : graph.getNodes(DeoptimizeNode.class)) { - if (n.action().doesInvalidateCompilation()) { + for (AbstractDeoptimizeNode n : graph.getNodes(AbstractDeoptimizeNode.class)) { + if (!(n instanceof DeoptimizeNode) || ((DeoptimizeNode) n).action().doesInvalidateCompilation()) { findParentControlSplitNodes(result, n, visitedNodes); } } @@ -90,7 +90,7 @@ } } - private static void findParentControlSplitNodes(HashSet result, DeoptimizeNode n, NodeBitMap visitedNodes) { + private static void findParentControlSplitNodes(HashSet result, AbstractDeoptimizeNode n, NodeBitMap visitedNodes) { ArrayDeque nodes = new ArrayDeque<>(); nodes.push(n); @@ -142,9 +142,9 @@ private boolean verifyProbabilities() { if (doesNotAlwaysDeopt(graph)) { - for (DeoptimizeNode n : graph.getNodes(DeoptimizeNode.class)) { - if (n.action().doesInvalidateCompilation() && nodeProbabilities.get(n) > 0.01) { - throw new AssertionError(String.format("%s with reason %s and probability %f in graph %s", n, n.reason(), nodeProbabilities.get(n), graph)); + for (AbstractDeoptimizeNode n : graph.getNodes(AbstractDeoptimizeNode.class)) { + if (nodeProbabilities.get(n) > 0.01 && (!(n instanceof DeoptimizeNode) || ((DeoptimizeNode) n).action().doesInvalidateCompilation())) { + throw new AssertionError(String.format("%s with probability %f in graph %s", n, nodeProbabilities.get(n), graph)); } } }