1 /*
2  * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 package org.graalvm.compiler.nodes;
26 
27 import org.graalvm.compiler.debug.DebugContext;
28 import org.graalvm.compiler.graph.NodeClass;
29 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
30 import org.graalvm.compiler.nodeinfo.NodeInfo;
31 import org.graalvm.compiler.nodes.spi.LIRLowerable;
32 import org.graalvm.compiler.nodes.spi.Lowerable;
33 import org.graalvm.compiler.nodes.spi.LoweringTool;
34 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
35 
36 import jdk.vm.ci.meta.DeoptimizationAction;
37 import jdk.vm.ci.meta.DeoptimizationReason;
38 import jdk.vm.ci.meta.MetaAccessProvider;
39 import jdk.vm.ci.meta.SpeculationLog;
40 import jdk.vm.ci.meta.SpeculationLog.Speculation;
41 import jdk.vm.ci.meta.Value;
42 
43 @NodeInfo(shortName = "Deopt", nameTemplate = "Deopt {p#reason/s}")
44 public final class DeoptimizeNode extends AbstractDeoptimizeNode implements Lowerable, LIRLowerable, StaticDeoptimizingNode {
45     public static final int DEFAULT_DEBUG_ID = 0;
46 
47     public static final NodeClass<DeoptimizeNode> TYPE = NodeClass.create(DeoptimizeNode.class);
48     protected DeoptimizationAction action;
49     protected DeoptimizationReason reason;
50     protected int debugId;
51     protected final Speculation speculation;
52 
DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason)53     public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason) {
54         this(action, reason, DEFAULT_DEBUG_ID, SpeculationLog.NO_SPECULATION, null);
55     }
56 
DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason, Speculation speculation)57     public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason, Speculation speculation) {
58         this(action, reason, DEFAULT_DEBUG_ID, speculation, null);
59     }
60 
DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason, int debugId, Speculation speculation, FrameState stateBefore)61     public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason, int debugId, Speculation speculation, FrameState stateBefore) {
62         super(TYPE, stateBefore);
63         assert action != null;
64         assert reason != null;
65         this.action = action;
66         this.reason = reason;
67         this.debugId = debugId;
68         assert speculation != null;
69         this.speculation = speculation;
70     }
71 
72     @Override
getAction()73     public DeoptimizationAction getAction() {
74         return action;
75     }
76 
77     @Override
setAction(DeoptimizationAction action)78     public void setAction(DeoptimizationAction action) {
79         this.action = action;
80     }
81 
82     @Override
getReason()83     public DeoptimizationReason getReason() {
84         return reason;
85     }
86 
87     @Override
setReason(DeoptimizationReason reason)88     public void setReason(DeoptimizationReason reason) {
89         this.reason = reason;
90     }
91 
92     @Override
lower(LoweringTool tool)93     public void lower(LoweringTool tool) {
94         tool.getLowerer().lower(this, tool);
95     }
96 
97     @SuppressWarnings("deprecation")
getDebugId()98     public int getDebugId() {
99         int deoptDebugId = debugId;
100         if (deoptDebugId == DEFAULT_DEBUG_ID) {
101             DebugContext debug = getDebug();
102             if ((debug.isDumpEnabledForMethod() || debug.isLogEnabledForMethod())) {
103                 deoptDebugId = this.getId();
104             }
105         }
106         return deoptDebugId;
107     }
108 
setDebugId(int debugId)109     public void setDebugId(int debugId) {
110         assert debugId != DEFAULT_DEBUG_ID;
111         this.debugId = debugId;
112     }
113 
114     @Override
generate(NodeLIRBuilderTool gen)115     public void generate(NodeLIRBuilderTool gen) {
116         LIRGeneratorTool tool = gen.getLIRGeneratorTool();
117         Value actionAndReason = tool.emitJavaConstant(tool.getMetaAccess().encodeDeoptActionAndReason(action, reason, getDebugId()));
118         Value speculationValue = tool.emitJavaConstant(tool.getMetaAccess().encodeSpeculation(speculation));
119         gen.getLIRGeneratorTool().emitDeoptimize(actionAndReason, speculationValue, gen.state(this));
120     }
121 
122     @Override
getActionAndReason(MetaAccessProvider metaAccess)123     public ValueNode getActionAndReason(MetaAccessProvider metaAccess) {
124         return ConstantNode.forConstant(metaAccess.encodeDeoptActionAndReason(action, reason, getDebugId()), metaAccess, graph());
125     }
126 
127     @Override
getSpeculation(MetaAccessProvider metaAccess)128     public ValueNode getSpeculation(MetaAccessProvider metaAccess) {
129         return ConstantNode.forConstant(metaAccess.encodeSpeculation(speculation), metaAccess, graph());
130     }
131 
132     @Override
getSpeculation()133     public Speculation getSpeculation() {
134         return speculation;
135     }
136 
137     @NodeIntrinsic
deopt(@onstantNodeParameter DeoptimizationAction action, @ConstantNodeParameter DeoptimizationReason reason)138     public static native void deopt(@ConstantNodeParameter DeoptimizationAction action, @ConstantNodeParameter DeoptimizationReason reason);
139 }
140