Mercurial > hg > graal-compiler
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 } |