24
25 import static jdk.vm.ci.code.BytecodeFrame.getPlaceholderBciName;
26 import static jdk.vm.ci.code.BytecodeFrame.isPlaceholderBci;
27 import static org.graalvm.compiler.nodeinfo.InputType.Association;
28 import static org.graalvm.compiler.nodeinfo.InputType.State;
29 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0;
30 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED;
31 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
32 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED;
33
34 import java.util.ArrayList;
35 import java.util.Collections;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Objects;
39
40 import org.graalvm.compiler.api.replacements.MethodSubstitution;
41 import org.graalvm.compiler.bytecode.Bytecode;
42 import org.graalvm.compiler.bytecode.Bytecodes;
43 import org.graalvm.compiler.core.common.type.StampFactory;
44 import org.graalvm.compiler.debug.Debug;
45 import org.graalvm.compiler.debug.DebugCounter;
46 import org.graalvm.compiler.debug.GraalError;
47 import org.graalvm.compiler.graph.IterableNodeType;
48 import org.graalvm.compiler.graph.NodeClass;
49 import org.graalvm.compiler.graph.NodeInputList;
50 import org.graalvm.compiler.graph.NodeSourcePosition;
51 import org.graalvm.compiler.graph.iterators.NodeIterable;
52 import org.graalvm.compiler.nodeinfo.InputType;
53 import org.graalvm.compiler.nodeinfo.NodeInfo;
54 import org.graalvm.compiler.nodeinfo.Verbosity;
55 import org.graalvm.compiler.nodes.java.ExceptionObjectNode;
56 import org.graalvm.compiler.nodes.java.MonitorIdNode;
57 import org.graalvm.compiler.nodes.virtual.EscapeObjectState;
58 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
59
60 import jdk.vm.ci.code.BytecodeFrame;
61 import jdk.vm.ci.code.CodeUtil;
62 import jdk.vm.ci.meta.JavaKind;
63 import jdk.vm.ci.meta.ResolvedJavaMethod;
64
65 /**
66 * The {@code FrameState} class encapsulates the frame state (i.e. local variables and operand
67 * stack) at a particular point in the abstract interpretation.
68 *
69 * This can be used as debug or deoptimization information.
70 */
71 @NodeInfo(nameTemplate = "@{p#code/s}:{p#bci}", cycles = CYCLES_0, size = SIZE_1)
72 public final class FrameState extends VirtualState implements IterableNodeType {
73 public static final NodeClass<FrameState> TYPE = NodeClass.create(FrameState.class);
74
75 private static final DebugCounter FRAMESTATES_COUNTER = Debug.counter("FrameStateCount");
76
77 /**
78 * Marker value for the second slot of values that occupy two local variable or expression stack
79 * slots. The marker value is used by the bytecode parser, but replaced with {@code null} in the
80 * {@link #values} of the {@link FrameState}.
81 */
82 public static final ValueNode TWO_SLOT_MARKER = new TwoSlotMarker();
83
84 @NodeInfo(cycles = CYCLES_IGNORED, size = SIZE_IGNORED)
85 private static final class TwoSlotMarker extends ValueNode {
86 public static final NodeClass<TwoSlotMarker> TYPE = NodeClass.create(TwoSlotMarker.class);
87
88 protected TwoSlotMarker() {
89 super(TYPE, StampFactory.forKind(JavaKind.Illegal));
90 }
91 }
92
93 protected final int localsSize;
94
95 protected final int stackSize;
96
140 this.outerFrameState = outerFrameState;
141 assert outerFrameState == null || outerFrameState.bci >= 0;
142 this.code = code;
143 this.bci = bci;
144 this.localsSize = localsSize;
145 this.stackSize = stackSize;
146 this.values = new NodeInputList<>(this, localsSize + stackSize + lockSize);
147
148 if (monitorIds != null && monitorIds.size() > 0) {
149 this.monitorIds = new NodeInputList<>(this, monitorIds);
150 }
151
152 if (virtualObjectMappings != null && virtualObjectMappings.size() > 0) {
153 this.virtualObjectMappings = new NodeInputList<>(this, virtualObjectMappings);
154 }
155
156 this.rethrowException = rethrowException;
157 this.duringCall = duringCall;
158 assert !this.rethrowException || this.stackSize == 1 : "must have exception on top of the stack";
159 assert this.locksSize() == this.monitorIdCount();
160 FRAMESTATES_COUNTER.increment();
161 }
162
163 public FrameState(FrameState outerFrameState, Bytecode code, int bci, List<ValueNode> values, int localsSize, int stackSize, boolean rethrowException, boolean duringCall,
164 List<MonitorIdNode> monitorIds, List<EscapeObjectState> virtualObjectMappings) {
165 this(outerFrameState, code, bci, localsSize, stackSize, values.size() - localsSize - stackSize, rethrowException, duringCall, monitorIds, virtualObjectMappings);
166 for (int i = 0; i < values.size(); ++i) {
167 this.values.initialize(i, values.get(i));
168 }
169 }
170
171 private void verifyAfterExceptionState() {
172 if (this.bci == BytecodeFrame.AFTER_EXCEPTION_BCI) {
173 assert this.outerFrameState == null;
174 for (int i = 0; i < this.localsSize; i++) {
175 assertTrue(this.values.get(i) == null, "locals should be null in AFTER_EXCEPTION_BCI state");
176 }
177 }
178 }
179
180 public FrameState(int bci) {
|
24
25 import static jdk.vm.ci.code.BytecodeFrame.getPlaceholderBciName;
26 import static jdk.vm.ci.code.BytecodeFrame.isPlaceholderBci;
27 import static org.graalvm.compiler.nodeinfo.InputType.Association;
28 import static org.graalvm.compiler.nodeinfo.InputType.State;
29 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0;
30 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED;
31 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
32 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED;
33
34 import java.util.ArrayList;
35 import java.util.Collections;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Objects;
39
40 import org.graalvm.compiler.api.replacements.MethodSubstitution;
41 import org.graalvm.compiler.bytecode.Bytecode;
42 import org.graalvm.compiler.bytecode.Bytecodes;
43 import org.graalvm.compiler.core.common.type.StampFactory;
44 import org.graalvm.compiler.debug.GraalError;
45 import org.graalvm.compiler.graph.IterableNodeType;
46 import org.graalvm.compiler.graph.NodeClass;
47 import org.graalvm.compiler.graph.NodeInputList;
48 import org.graalvm.compiler.graph.NodeSourcePosition;
49 import org.graalvm.compiler.graph.iterators.NodeIterable;
50 import org.graalvm.compiler.nodeinfo.InputType;
51 import org.graalvm.compiler.nodeinfo.NodeInfo;
52 import org.graalvm.compiler.nodeinfo.Verbosity;
53 import org.graalvm.compiler.nodes.java.ExceptionObjectNode;
54 import org.graalvm.compiler.nodes.java.MonitorIdNode;
55 import org.graalvm.compiler.nodes.virtual.EscapeObjectState;
56 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
57
58 import jdk.vm.ci.code.BytecodeFrame;
59 import jdk.vm.ci.code.CodeUtil;
60 import jdk.vm.ci.meta.JavaKind;
61 import jdk.vm.ci.meta.ResolvedJavaMethod;
62
63 /**
64 * The {@code FrameState} class encapsulates the frame state (i.e. local variables and operand
65 * stack) at a particular point in the abstract interpretation.
66 *
67 * This can be used as debug or deoptimization information.
68 */
69 @NodeInfo(nameTemplate = "@{p#code/s}:{p#bci}", cycles = CYCLES_0, size = SIZE_1)
70 public final class FrameState extends VirtualState implements IterableNodeType {
71 public static final NodeClass<FrameState> TYPE = NodeClass.create(FrameState.class);
72
73 /**
74 * Marker value for the second slot of values that occupy two local variable or expression stack
75 * slots. The marker value is used by the bytecode parser, but replaced with {@code null} in the
76 * {@link #values} of the {@link FrameState}.
77 */
78 public static final ValueNode TWO_SLOT_MARKER = new TwoSlotMarker();
79
80 @NodeInfo(cycles = CYCLES_IGNORED, size = SIZE_IGNORED)
81 private static final class TwoSlotMarker extends ValueNode {
82 public static final NodeClass<TwoSlotMarker> TYPE = NodeClass.create(TwoSlotMarker.class);
83
84 protected TwoSlotMarker() {
85 super(TYPE, StampFactory.forKind(JavaKind.Illegal));
86 }
87 }
88
89 protected final int localsSize;
90
91 protected final int stackSize;
92
136 this.outerFrameState = outerFrameState;
137 assert outerFrameState == null || outerFrameState.bci >= 0;
138 this.code = code;
139 this.bci = bci;
140 this.localsSize = localsSize;
141 this.stackSize = stackSize;
142 this.values = new NodeInputList<>(this, localsSize + stackSize + lockSize);
143
144 if (monitorIds != null && monitorIds.size() > 0) {
145 this.monitorIds = new NodeInputList<>(this, monitorIds);
146 }
147
148 if (virtualObjectMappings != null && virtualObjectMappings.size() > 0) {
149 this.virtualObjectMappings = new NodeInputList<>(this, virtualObjectMappings);
150 }
151
152 this.rethrowException = rethrowException;
153 this.duringCall = duringCall;
154 assert !this.rethrowException || this.stackSize == 1 : "must have exception on top of the stack";
155 assert this.locksSize() == this.monitorIdCount();
156 }
157
158 public FrameState(FrameState outerFrameState, Bytecode code, int bci, List<ValueNode> values, int localsSize, int stackSize, boolean rethrowException, boolean duringCall,
159 List<MonitorIdNode> monitorIds, List<EscapeObjectState> virtualObjectMappings) {
160 this(outerFrameState, code, bci, localsSize, stackSize, values.size() - localsSize - stackSize, rethrowException, duringCall, monitorIds, virtualObjectMappings);
161 for (int i = 0; i < values.size(); ++i) {
162 this.values.initialize(i, values.get(i));
163 }
164 }
165
166 private void verifyAfterExceptionState() {
167 if (this.bci == BytecodeFrame.AFTER_EXCEPTION_BCI) {
168 assert this.outerFrameState == null;
169 for (int i = 0; i < this.localsSize; i++) {
170 assertTrue(this.values.get(i) == null, "locals should be null in AFTER_EXCEPTION_BCI state");
171 }
172 }
173 }
174
175 public FrameState(int bci) {
|