comparison graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java @ 2840:75e0d39833a0

new CompilerGraph, create only one Return and one Unwind per CompilerGraph
author Lukas Stadler <lukas.stadler@jku.at>
date Tue, 31 May 2011 16:53:19 +0200
parents bd17ac598c6e
children 7596ae867a7b
comparison
equal deleted inserted replaced
2837:7b5831f0e913 2840:75e0d39833a0
36 * The {@code FrameState} class encapsulates the frame state (i.e. local variables and 36 * The {@code FrameState} class encapsulates the frame state (i.e. local variables and
37 * operand stack) at a particular point in the abstract interpretation. 37 * operand stack) at a particular point in the abstract interpretation.
38 */ 38 */
39 public final class FrameState extends Value implements FrameStateAccess { 39 public final class FrameState extends Value implements FrameStateAccess {
40 40
41 private static final int INPUT_COUNT = 1;
42
43 private static final int INPUT_OUTER_FRAME_STATE = 0;
44
41 protected final int localsSize; 45 protected final int localsSize;
42 46
43 protected final int stackSize; 47 protected final int stackSize;
44 48
45 protected final int locksSize; 49 protected final int locksSize;
52 } 56 }
53 57
54 @Override 58 @Override
55 protected int successorCount() { 59 protected int successorCount() {
56 return super.successorCount() + SUCCESSOR_COUNT; 60 return super.successorCount() + SUCCESSOR_COUNT;
61 }
62
63 public Value outerFrameState() {
64 return (Value) inputs().get(super.inputCount() + INPUT_OUTER_FRAME_STATE);
65 }
66
67 public Value setOuterFrameState(Value n) {
68 assert n == null || n.kind == CiKind.Object;
69 return (Value) inputs().set(super.inputCount() + INPUT_OUTER_FRAME_STATE, n);
70 }
71
72 @Override
73 public void setValueAt(int i, Value x) {
74 inputs().set(INPUT_COUNT + i, x);
57 } 75 }
58 76
59 /** 77 /**
60 * The bytecode index to which this frame state applies. This will be {@code -1} 78 * The bytecode index to which this frame state applies. This will be {@code -1}
61 * iff this state is mutable. 79 * iff this state is mutable.
69 * @param localsSize number of locals 87 * @param localsSize number of locals
70 * @param stackSize size of the stack 88 * @param stackSize size of the stack
71 * @param lockSize number of locks 89 * @param lockSize number of locks
72 */ 90 */
73 public FrameState(int bci, int localsSize, int stackSize, int locksSize, Graph graph) { 91 public FrameState(int bci, int localsSize, int stackSize, int locksSize, Graph graph) {
74 super(CiKind.Illegal, localsSize + stackSize + locksSize, SUCCESSOR_COUNT, graph); 92 super(CiKind.Illegal, localsSize + stackSize + locksSize + INPUT_COUNT, SUCCESSOR_COUNT, graph);
75 this.bci = bci; 93 this.bci = bci;
76 this.localsSize = localsSize; 94 this.localsSize = localsSize;
77 this.stackSize = stackSize; 95 this.stackSize = stackSize;
78 this.locksSize = locksSize; 96 this.locksSize = locksSize;
79 C1XMetrics.FrameStatesCreated++; 97 C1XMetrics.FrameStatesCreated++;
80 C1XMetrics.FrameStateValuesCreated += localsSize + stackSize + locksSize; 98 C1XMetrics.FrameStateValuesCreated += localsSize + stackSize + locksSize;
81 //Exception e = new Exception();
82 //e.printStackTrace();
83 } 99 }
84 100
85 FrameState(int bci, Value[] locals, Value[] stack, int stackSize, ArrayList<Value> locks, Graph graph) { 101 FrameState(int bci, Value[] locals, Value[] stack, int stackSize, ArrayList<Value> locks, Graph graph) {
86 this(bci, locals.length, stackSize, locks.size(), graph); 102 this(bci, locals.length, stackSize, locks.size(), graph);
87 for (int i = 0; i < locals.length; i++) { 103 for (int i = 0; i < locals.length; i++) {
88 inputs().set(i, locals[i]); 104 setValueAt(i, locals[i]);
89 } 105 }
90 for (int i = 0; i < stackSize; i++) { 106 for (int i = 0; i < stackSize; i++) {
91 inputs().set(localsSize + i, stack[i]); 107 setValueAt(localsSize + i, stack[i]);
92 } 108 }
93 for (int i = 0; i < locks.size(); i++) { 109 for (int i = 0; i < locks.size(); i++) {
94 inputs().set(locals.length + stackSize + i, locks.get(i)); 110 setValueAt(locals.length + stackSize + i, locks.get(i));
95 } 111 }
96 } 112 }
97 113
98 /** 114 /**
99 * Gets a copy of this frame state. 115 * Gets a copy of this frame state.
109 */ 125 */
110 @Override 126 @Override
111 public FrameState duplicateWithEmptyStack(int bci) { 127 public FrameState duplicateWithEmptyStack(int bci) {
112 FrameState other = new FrameState(bci, localsSize, 0, locksSize(), graph()); 128 FrameState other = new FrameState(bci, localsSize, 0, locksSize(), graph());
113 for (int i = 0; i < localsSize; i++) { 129 for (int i = 0; i < localsSize; i++) {
114 other.inputs().set(i, localAt(i)); 130 other.setValueAt(i, localAt(i));
115 } 131 }
116 for (int i = 0; i < locksSize; i++) { 132 for (int i = 0; i < locksSize; i++) {
117 other.inputs().set(localsSize + i, lockAt(i)); 133 other.setValueAt(localsSize + i, lockAt(i));
118 } 134 }
135 other.setOuterFrameState(outerFrameState());
119 return other; 136 return other;
120 } 137 }
121 138
122 /** 139 /**
123 * Creates a copy of this frame state with one stack element of type popKind popped from the stack and the 140 * Creates a copy of this frame state with one stack element of type popKind popped from the stack and the
127 public FrameState duplicateModified(int bci, CiKind popKind, Value... pushedValues) { 144 public FrameState duplicateModified(int bci, CiKind popKind, Value... pushedValues) {
128 int popSlots = popKind.sizeInSlots(); 145 int popSlots = popKind.sizeInSlots();
129 int pushSlots = pushedValues.length; 146 int pushSlots = pushedValues.length;
130 FrameState other = new FrameState(bci, localsSize, stackSize - popSlots + pushSlots, locksSize(), graph()); 147 FrameState other = new FrameState(bci, localsSize, stackSize - popSlots + pushSlots, locksSize(), graph());
131 for (int i = 0; i < localsSize; i++) { 148 for (int i = 0; i < localsSize; i++) {
132 other.inputs().set(i, localAt(i)); 149 other.setValueAt(i, localAt(i));
133 } 150 }
134 for (int i = 0; i < stackSize - popSlots; i++) { 151 for (int i = 0; i < stackSize - popSlots; i++) {
135 other.inputs().set(localsSize + i, stackAt(i)); 152 other.setValueAt(localsSize + i, stackAt(i));
136 } 153 }
137 int slot = localsSize + stackSize - popSlots; 154 int slot = localsSize + stackSize - popSlots;
138 for (int i = 0; i < pushSlots; i++) { 155 for (int i = 0; i < pushSlots; i++) {
139 other.inputs().set(slot++, pushedValues[i]); 156 other.setValueAt(slot++, pushedValues[i]);
140 } 157 }
141 for (int i = 0; i < locksSize; i++) { 158 for (int i = 0; i < locksSize; i++) {
142 other.inputs().set(localsSize + other.stackSize + i, lockAt(i)); 159 other.setValueAt(localsSize + other.stackSize + i, lockAt(i));
143 } 160 }
161 other.setOuterFrameState(outerFrameState());
144 return other; 162 return other;
145 } 163 }
146 164
147 public boolean isCompatibleWith(FrameStateAccess other) { 165 public boolean isCompatibleWith(FrameStateAccess other) {
148 if (stackSize() != other.stackSize() || localsSize() != other.localsSize() || locksSize() != other.locksSize()) { 166 if (stackSize() != other.stackSize() || localsSize() != other.localsSize() || locksSize() != other.locksSize()) {
158 for (int i = 0; i < locksSize(); i++) { 176 for (int i = 0; i < locksSize(); i++) {
159 if (lockAt(i) != other.lockAt(i)) { 177 if (lockAt(i) != other.lockAt(i)) {
160 return false; 178 return false;
161 } 179 }
162 } 180 }
181 if (other.outerFrameState() != outerFrameState()) {
182 return false;
183 }
163 return true; 184 return true;
164 } 185 }
165 186
166 /** 187 /**
167 * Gets the size of the local variables. 188 * Gets the size of the local variables.
192 */ 213 */
193 public void invalidateLocal(int i) { 214 public void invalidateLocal(int i) {
194 // note that for double word locals, the high slot should already be null 215 // note that for double word locals, the high slot should already be null
195 // unless the local is actually dead and the high slot is being reused; 216 // unless the local is actually dead and the high slot is being reused;
196 // in either case, it is not necessary to null the high slot 217 // in either case, it is not necessary to null the high slot
197 inputs().set(i, null); 218 setValueAt(i, null);
198 } 219 }
199 220
200 /** 221 /**
201 * Stores a given local variable at the specified index. If the value is a {@linkplain CiKind#isDoubleWord() double word}, 222 * Stores a given local variable at the specified index. If the value is a {@linkplain CiKind#isDoubleWord() double word},
202 * then the next local variable index is also overwritten. 223 * then the next local variable index is also overwritten.
205 * @param x the instruction which produces the value for the local 226 * @param x the instruction which produces the value for the local
206 */ 227 */
207 public void storeLocal(int i, Value x) { 228 public void storeLocal(int i, Value x) {
208 assert i < localsSize : "local variable index out of range: " + i; 229 assert i < localsSize : "local variable index out of range: " + i;
209 invalidateLocal(i); 230 invalidateLocal(i);
210 inputs().set(i, x); 231 setValueAt(i, x);
211 if (isDoubleWord(x)) { 232 if (isDoubleWord(x)) {
212 // (tw) if this was a double word then kill i+1 233 // (tw) if this was a double word then kill i+1
213 inputs().set(i + 1, null); 234 setValueAt(i + 1, null);
214 } 235 }
215 if (i > 0) { 236 if (i > 0) {
216 // if there was a double word at i - 1, then kill it 237 // if there was a double word at i - 1, then kill it
217 Value p = localAt(i - 1); 238 Value p = localAt(i - 1);
218 if (isDoubleWord(p)) { 239 if (isDoubleWord(p)) {
219 inputs().set(i - 1, null); 240 setValueAt(i - 1, null);
220 } 241 }
221 } 242 }
222 } 243 }
223 244
224 /** 245 /**
227 * @param i the index into the locals 248 * @param i the index into the locals
228 * @return the instruction that produced the value for the specified local 249 * @return the instruction that produced the value for the specified local
229 */ 250 */
230 public Value localAt(int i) { 251 public Value localAt(int i) {
231 assert i < localsSize : "local variable index out of range: " + i; 252 assert i < localsSize : "local variable index out of range: " + i;
232 return (Value) inputs().get(i); 253 return valueAt(i);
233 } 254 }
234 255
235 /** 256 /**
236 * Get the value on the stack at the specified stack index. 257 * Get the value on the stack at the specified stack index.
237 * 258 *
238 * @param i the index into the stack, with {@code 0} being the bottom of the stack 259 * @param i the index into the stack, with {@code 0} being the bottom of the stack
239 * @return the instruction at the specified position in the stack 260 * @return the instruction at the specified position in the stack
240 */ 261 */
241 public Value stackAt(int i) { 262 public Value stackAt(int i) {
242 assert i >= 0 && i < (localsSize + stackSize); 263 assert i >= 0 && i < (localsSize + stackSize);
243 return (Value) inputs().get(localsSize + i); 264 return valueAt(localsSize + i);
244 } 265 }
245 266
246 /** 267 /**
247 * Retrieves the lock at the specified index in the lock stack. 268 * Retrieves the lock at the specified index in the lock stack.
248 * @param i the index into the lock stack 269 * @param i the index into the lock stack
249 * @return the instruction which produced the object at the specified location in the lock stack 270 * @return the instruction which produced the object at the specified location in the lock stack
250 */ 271 */
251 public Value lockAt(int i) { 272 public Value lockAt(int i) {
252 assert i >= 0; 273 assert i >= 0;
253 return (Value) inputs().get(localsSize + stackSize + i); 274 return valueAt(localsSize + stackSize + i);
254 } 275 }
255 276
256 /** 277 /**
257 * Inserts a phi statement into the stack at the specified stack index. 278 * Inserts a phi statement into the stack at the specified stack index.
258 * @param block the block begin for which we are creating the phi 279 * @param block the block begin for which we are creating the phi
266 if (phi.block() == block) { 287 if (phi.block() == block) {
267 return phi; 288 return phi;
268 } 289 }
269 } 290 }
270 Phi phi = new Phi(p.kind, block, graph()); 291 Phi phi = new Phi(p.kind, block, graph());
271 inputs().set(localsSize + i, phi); 292 setValueAt(localsSize + i, phi);
272 return phi; 293 return phi;
273 } 294 }
274 return null; 295 return null;
275 } 296 }
276 297
301 * 322 *
302 * @param i a value in the range {@code [0 .. valuesSize()]} 323 * @param i a value in the range {@code [0 .. valuesSize()]}
303 * @return the value at index {@code i} which may be {@code null} 324 * @return the value at index {@code i} which may be {@code null}
304 */ 325 */
305 public Value valueAt(int i) { 326 public Value valueAt(int i) {
306 assert i < (localsSize + stackSize); 327 assert i < (localsSize + stackSize + locksSize);
307 return (Value) inputs().get(i); 328 return (Value) inputs().get(INPUT_COUNT + i);
308 } 329 }
309 330
310 /** 331 /**
311 * The number of operand stack slots and local variables in this frame. 332 * The number of operand stack slots and local variables in this frame.
312 * This method should typically only be used in conjunction with {@link #valueAt(int)}. 333 * This method should typically only be used in conjunction with {@link #valueAt(int)}.
339 Phi phi = (Phi) x; 360 Phi phi = (Phi) x;
340 if (phi.block() == block) { 361 if (phi.block() == block) {
341 phi.makeDead(); 362 phi.makeDead();
342 } 363 }
343 } 364 }
344 inputs().set(i, null); 365 setValueAt(i, null);
345 continue; 366 continue;
346 } 367 }
347 Phi phi = null; 368 Phi phi = null;
348 if (i < localsSize) { 369 if (i < localsSize) {
349 // this a local 370 // this a local
482 public void visitFrameState(FrameState i) { 503 public void visitFrameState(FrameState i) {
483 // nothing to do for now 504 // nothing to do for now
484 } 505 }
485 506
486 @Override 507 @Override
487 public void setValueAt(int j, Value v) {
488 inputs().set(j, v);
489 }
490
491 @Override
492 public Node copy(Graph into) { 508 public Node copy(Graph into) {
493 FrameState x = new FrameState(bci, localsSize, stackSize, locksSize, into); 509 FrameState x = new FrameState(bci, localsSize, stackSize, locksSize, into);
494 x.setNonNull(isNonNull()); 510 x.setNonNull(isNonNull());
495 return x; 511 return x;
496 } 512 }