Mercurial > hg > graal-jvmci-8
comparison graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java @ 2611:bd235cb4375a
FrameState cleanup: split into FrameStateBuilder and fixed-size FrameState, removed MutableFrameState
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Fri, 06 May 2011 17:08:00 +0200 |
parents | 01c5c0443158 |
children | 2523de4d378e |
comparison
equal
deleted
inserted
replaced
2610:39aa89baa165 | 2611:bd235cb4375a |
---|---|
79 NoSafepoints; | 79 NoSafepoints; |
80 | 80 |
81 public final int mask = 1 << ordinal(); | 81 public final int mask = 1 << ordinal(); |
82 } | 82 } |
83 | 83 |
84 final IR ir; | 84 private final IR ir; |
85 final C1XCompilation compilation; | 85 private final C1XCompilation compilation; |
86 final CiStatistics stats; | 86 private final CiStatistics stats; |
87 | 87 |
88 /** | 88 /** |
89 * Map used to implement local value numbering for the current block. | 89 * Map used to implement local value numbering for the current block. |
90 */ | 90 */ |
91 final ValueMap localValueMap; | 91 private final ValueMap localValueMap; |
92 | 92 |
93 /** | 93 /** |
94 * Map used for local load elimination (i.e. within the current block). | 94 * Map used for local load elimination (i.e. within the current block). |
95 */ | 95 */ |
96 final MemoryMap memoryMap; | 96 private final MemoryMap memoryMap; |
97 | 97 |
98 final BytecodeStream stream; // the bytecode stream | 98 private final BytecodeStream stream; // the bytecode stream |
99 // bci-to-block mapping | 99 // bci-to-block mapping |
100 BlockMap blockMap; | 100 private BlockMap blockMap; |
101 | 101 |
102 // the constant pool | 102 // the constant pool |
103 final RiConstantPool constantPool; | 103 private final RiConstantPool constantPool; |
104 | 104 |
105 // the worklist of blocks, managed like a sorted list | 105 // the worklist of blocks, managed like a sorted list |
106 BlockBegin[] workList; | 106 private BlockBegin[] workList; |
107 | 107 |
108 // the current position in the worklist | 108 // the current position in the worklist |
109 int workListIndex; | 109 private int workListIndex; |
110 | 110 |
111 /** | 111 /** |
112 * Mask of {@link Flag} values. | 112 * Mask of {@link Flag} values. |
113 */ | 113 */ |
114 int flags; | 114 private int flags; |
115 | 115 |
116 // Exception handler list | 116 // Exception handler list |
117 List<ExceptionHandler> exceptionHandlers; | 117 private List<ExceptionHandler> exceptionHandlers; |
118 | 118 |
119 BlockBegin curBlock; // the current block | 119 private BlockBegin curBlock; // the current block |
120 MutableFrameState curState; // the current execution state | 120 private FrameStateBuilder frameState; // the current execution state |
121 Instruction lastInstr; // the last instruction added | 121 private Instruction lastInstr; // the last instruction added |
122 final LogStream log; | 122 private final LogStream log; |
123 | 123 |
124 boolean skipBlock; // skip processing of the rest of this block | 124 private boolean skipBlock; // skip processing of the rest of this block |
125 private Value rootMethodSynchronizedObject; | 125 private Value rootMethodSynchronizedObject; |
126 | 126 |
127 private final Graph graph; | 127 private final Graph graph; |
128 | 128 |
129 /** | 129 /** |
141 this.localValueMap = C1XOptions.OptLocalValueNumbering ? new ValueMap() : null; | 141 this.localValueMap = C1XOptions.OptLocalValueNumbering ? new ValueMap() : null; |
142 log = C1XOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null; | 142 log = C1XOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null; |
143 stream = new BytecodeStream(compilation.method.code()); | 143 stream = new BytecodeStream(compilation.method.code()); |
144 constantPool = compilation.runtime.getConstantPool(compilation.method); | 144 constantPool = compilation.runtime.getConstantPool(compilation.method); |
145 this.graph = graph; | 145 this.graph = graph; |
146 this.frameState = new FrameStateBuilder(compilation.method, graph); | |
146 } | 147 } |
147 | 148 |
148 /** | 149 /** |
149 * Builds the graph for a the specified {@code IRScope}. | 150 * Builds the graph for a the specified {@code IRScope}. |
150 * @param scope the top IRScope | 151 * @param scope the top IRScope |
179 exceptionHandlers.add(h); | 180 exceptionHandlers.add(h); |
180 } | 181 } |
181 flags |= Flag.HasHandler.mask; | 182 flags |= Flag.HasHandler.mask; |
182 } | 183 } |
183 | 184 |
184 MutableFrameState initialState = stateAtEntry(rootMethod); | 185 FrameState initialState = frameState.create(-1); |
185 startBlock.mergeOrClone(initialState, rootMethod); | 186 startBlock.mergeOrClone(initialState, rootMethod); |
186 BlockBegin syncHandler = null; | 187 BlockBegin syncHandler = null; |
187 | 188 |
188 // 3. setup internal state for appending instructions | 189 // 3. setup internal state for appending instructions |
189 curBlock = startBlock; | 190 curBlock = startBlock; |
190 lastInstr = startBlock; | 191 lastInstr = startBlock; |
191 lastInstr.appendNext(null, -1); | 192 lastInstr.appendNext(null, -1); |
192 curState = initialState; | |
193 | 193 |
194 if (isSynchronized(rootMethod.accessFlags())) { | 194 if (isSynchronized(rootMethod.accessFlags())) { |
195 // 4A.1 add a monitor enter to the start block | 195 // 4A.1 add a monitor enter to the start block |
196 rootMethodSynchronizedObject = synchronizedObject(initialState, compilation.method); | 196 rootMethodSynchronizedObject = synchronizedObject(initialState, compilation.method); |
197 genMonitorEnter(rootMethodSynchronizedObject, Instruction.SYNCHRONIZATION_ENTRY_BCI); | 197 genMonitorEnter(rootMethodSynchronizedObject, Instruction.SYNCHRONIZATION_ENTRY_BCI); |
226 | 226 |
227 private void finishStartBlock(BlockBegin startBlock, BlockBegin stdEntry) { | 227 private void finishStartBlock(BlockBegin startBlock, BlockBegin stdEntry) { |
228 assert curBlock == startBlock; | 228 assert curBlock == startBlock; |
229 Base base = new Base(stdEntry, graph); | 229 Base base = new Base(stdEntry, graph); |
230 appendWithoutOptimization(base, 0); | 230 appendWithoutOptimization(base, 0); |
231 FrameState stateAfter = curState.immutableCopy(bci()); | 231 FrameState stateAfter = frameState.create(bci()); |
232 base.setStateAfter(stateAfter); | 232 base.setStateAfter(stateAfter); |
233 startBlock.setEnd(base); | 233 startBlock.setEnd(base); |
234 assert stdEntry.stateBefore() == null; | 234 assert stdEntry.stateBefore() == null; |
235 stdEntry.mergeOrClone(stateAfter, method()); | 235 stdEntry.mergeOrClone(stateAfter, method()); |
236 } | 236 } |
250 public int nextBCI() { | 250 public int nextBCI() { |
251 return stream.nextBCI(); | 251 return stream.nextBCI(); |
252 } | 252 } |
253 | 253 |
254 private void ipush(Value x) { | 254 private void ipush(Value x) { |
255 curState.ipush(x); | 255 frameState.ipush(x); |
256 } | 256 } |
257 | 257 |
258 private void lpush(Value x) { | 258 private void lpush(Value x) { |
259 curState.lpush(x); | 259 frameState.lpush(x); |
260 } | 260 } |
261 | 261 |
262 private void fpush(Value x) { | 262 private void fpush(Value x) { |
263 curState.fpush(x); | 263 frameState.fpush(x); |
264 } | 264 } |
265 | 265 |
266 private void dpush(Value x) { | 266 private void dpush(Value x) { |
267 curState.dpush(x); | 267 frameState.dpush(x); |
268 } | 268 } |
269 | 269 |
270 private void apush(Value x) { | 270 private void apush(Value x) { |
271 curState.apush(x); | 271 frameState.apush(x); |
272 } | 272 } |
273 | 273 |
274 private void wpush(Value x) { | 274 private void wpush(Value x) { |
275 curState.wpush(x); | 275 frameState.wpush(x); |
276 } | 276 } |
277 | 277 |
278 private void push(CiKind kind, Value x) { | 278 private void push(CiKind kind, Value x) { |
279 curState.push(kind, x); | 279 frameState.push(kind, x); |
280 } | 280 } |
281 | 281 |
282 private void pushReturn(CiKind kind, Value x) { | 282 private void pushReturn(CiKind kind, Value x) { |
283 if (kind != CiKind.Void) { | 283 if (kind != CiKind.Void) { |
284 curState.push(kind.stackKind(), x); | 284 frameState.push(kind.stackKind(), x); |
285 } | 285 } |
286 } | 286 } |
287 | 287 |
288 private Value ipop() { | 288 private Value ipop() { |
289 return curState.ipop(); | 289 return frameState.ipop(); |
290 } | 290 } |
291 | 291 |
292 private Value lpop() { | 292 private Value lpop() { |
293 return curState.lpop(); | 293 return frameState.lpop(); |
294 } | 294 } |
295 | 295 |
296 private Value fpop() { | 296 private Value fpop() { |
297 return curState.fpop(); | 297 return frameState.fpop(); |
298 } | 298 } |
299 | 299 |
300 private Value dpop() { | 300 private Value dpop() { |
301 return curState.dpop(); | 301 return frameState.dpop(); |
302 } | 302 } |
303 | 303 |
304 private Value apop() { | 304 private Value apop() { |
305 return curState.apop(); | 305 return frameState.apop(); |
306 } | 306 } |
307 | 307 |
308 private Value wpop() { | 308 private Value wpop() { |
309 return curState.wpop(); | 309 return frameState.wpop(); |
310 } | 310 } |
311 | 311 |
312 private Value pop(CiKind kind) { | 312 private Value pop(CiKind kind) { |
313 return curState.pop(kind); | 313 return frameState.pop(kind); |
314 } | 314 } |
315 | 315 |
316 private CiKind peekKind() { | 316 private CiKind peekKind() { |
317 Value top = curState.stackAt(curState.stackSize() - 1); | 317 Value top = frameState.stackAt(frameState.stackSize() - 1); |
318 if (top == null) { | 318 if (top == null) { |
319 top = curState.stackAt(curState.stackSize() - 2); | 319 top = frameState.stackAt(frameState.stackSize() - 2); |
320 assert top != null; | 320 assert top != null; |
321 assert top.kind.isDoubleWord(); | 321 assert top.kind.isDoubleWord(); |
322 } | 322 } |
323 return top.kind; | 323 return top.kind; |
324 } | 324 } |
325 | 325 |
326 private void loadLocal(int index, CiKind kind) { | 326 private void loadLocal(int index, CiKind kind) { |
327 push(kind, curState.loadLocal(index)); | 327 push(kind, frameState.loadLocal(index)); |
328 } | 328 } |
329 | 329 |
330 private void storeLocal(CiKind kind, int index) { | 330 private void storeLocal(CiKind kind, int index) { |
331 curState.storeLocal(index, pop(kind)); | 331 frameState.storeLocal(index, pop(kind)); |
332 } | 332 } |
333 | 333 |
334 List<ExceptionHandler> handleException(Instruction x, int bci) { | 334 List<ExceptionHandler> handleException(Instruction x, int bci) { |
335 if (!hasHandler()) { | 335 if (!hasHandler()) { |
336 return Util.uncheckedCast(Collections.EMPTY_LIST); | 336 return Util.uncheckedCast(Collections.EMPTY_LIST); |
378 | 378 |
379 assert entry.bci() == handler.handler.handlerBCI(); | 379 assert entry.bci() == handler.handler.handlerBCI(); |
380 assert entryState == null || curState.locksSize() == entryState.locksSize() : "locks do not match : cur:" + curState.locksSize() + " entry:" + entryState.locksSize(); | 380 assert entryState == null || curState.locksSize() == entryState.locksSize() : "locks do not match : cur:" + curState.locksSize() + " entry:" + entryState.locksSize(); |
381 | 381 |
382 // exception handler starts with an empty expression stack | 382 // exception handler starts with an empty expression stack |
383 curState = curState.immutableCopyWithEmptyStack(); | 383 curState = curState.copyWithEmptyStack(); |
384 | 384 |
385 entry.mergeOrClone(curState, method()); | 385 entry.mergeOrClone(curState, method()); |
386 | 386 |
387 // add current state for correct handling of phi functions | 387 // add current state for correct handling of phi functions |
388 int phiOperand = entry.addExceptionState(curState); | 388 int phiOperand = entry.addExceptionState(curState); |
433 throw new Error("lookupConstant returned an object of incorrect type"); | 433 throw new Error("lookupConstant returned an object of incorrect type"); |
434 } | 434 } |
435 } | 435 } |
436 | 436 |
437 void genLoadIndexed(CiKind kind) { | 437 void genLoadIndexed(CiKind kind) { |
438 FrameState stateBefore = curState.immutableCopy(bci()); | 438 FrameState stateBefore = frameState.create(bci()); |
439 Value index = ipop(); | 439 Value index = ipop(); |
440 Value array = apop(); | 440 Value array = apop(); |
441 Value length = null; | 441 Value length = null; |
442 if (cseArrayLength(array)) { | 442 if (cseArrayLength(array)) { |
443 length = append(new ArrayLength(array, stateBefore, graph)); | 443 length = append(new ArrayLength(array, stateBefore, graph)); |
445 Value v = append(new LoadIndexed(array, index, length, kind, stateBefore, graph)); | 445 Value v = append(new LoadIndexed(array, index, length, kind, stateBefore, graph)); |
446 push(kind.stackKind(), v); | 446 push(kind.stackKind(), v); |
447 } | 447 } |
448 | 448 |
449 void genStoreIndexed(CiKind kind) { | 449 void genStoreIndexed(CiKind kind) { |
450 FrameState stateBefore = curState.immutableCopy(bci()); | 450 FrameState stateBefore = frameState.create(bci()); |
451 Value value = pop(kind.stackKind()); | 451 Value value = pop(kind.stackKind()); |
452 Value index = ipop(); | 452 Value index = ipop(); |
453 Value array = apop(); | 453 Value array = apop(); |
454 Value length = null; | 454 Value length = null; |
455 if (cseArrayLength(array)) { | 455 if (cseArrayLength(array)) { |
463 } | 463 } |
464 | 464 |
465 void stackOp(int opcode) { | 465 void stackOp(int opcode) { |
466 switch (opcode) { | 466 switch (opcode) { |
467 case POP: { | 467 case POP: { |
468 curState.xpop(); | 468 frameState.xpop(); |
469 break; | 469 break; |
470 } | 470 } |
471 case POP2: { | 471 case POP2: { |
472 curState.xpop(); | 472 frameState.xpop(); |
473 curState.xpop(); | 473 frameState.xpop(); |
474 break; | 474 break; |
475 } | 475 } |
476 case DUP: { | 476 case DUP: { |
477 Value w = curState.xpop(); | 477 Value w = frameState.xpop(); |
478 curState.xpush(w); | 478 frameState.xpush(w); |
479 curState.xpush(w); | 479 frameState.xpush(w); |
480 break; | 480 break; |
481 } | 481 } |
482 case DUP_X1: { | 482 case DUP_X1: { |
483 Value w1 = curState.xpop(); | 483 Value w1 = frameState.xpop(); |
484 Value w2 = curState.xpop(); | 484 Value w2 = frameState.xpop(); |
485 curState.xpush(w1); | 485 frameState.xpush(w1); |
486 curState.xpush(w2); | 486 frameState.xpush(w2); |
487 curState.xpush(w1); | 487 frameState.xpush(w1); |
488 break; | 488 break; |
489 } | 489 } |
490 case DUP_X2: { | 490 case DUP_X2: { |
491 Value w1 = curState.xpop(); | 491 Value w1 = frameState.xpop(); |
492 Value w2 = curState.xpop(); | 492 Value w2 = frameState.xpop(); |
493 Value w3 = curState.xpop(); | 493 Value w3 = frameState.xpop(); |
494 curState.xpush(w1); | 494 frameState.xpush(w1); |
495 curState.xpush(w3); | 495 frameState.xpush(w3); |
496 curState.xpush(w2); | 496 frameState.xpush(w2); |
497 curState.xpush(w1); | 497 frameState.xpush(w1); |
498 break; | 498 break; |
499 } | 499 } |
500 case DUP2: { | 500 case DUP2: { |
501 Value w1 = curState.xpop(); | 501 Value w1 = frameState.xpop(); |
502 Value w2 = curState.xpop(); | 502 Value w2 = frameState.xpop(); |
503 curState.xpush(w2); | 503 frameState.xpush(w2); |
504 curState.xpush(w1); | 504 frameState.xpush(w1); |
505 curState.xpush(w2); | 505 frameState.xpush(w2); |
506 curState.xpush(w1); | 506 frameState.xpush(w1); |
507 break; | 507 break; |
508 } | 508 } |
509 case DUP2_X1: { | 509 case DUP2_X1: { |
510 Value w1 = curState.xpop(); | 510 Value w1 = frameState.xpop(); |
511 Value w2 = curState.xpop(); | 511 Value w2 = frameState.xpop(); |
512 Value w3 = curState.xpop(); | 512 Value w3 = frameState.xpop(); |
513 curState.xpush(w2); | 513 frameState.xpush(w2); |
514 curState.xpush(w1); | 514 frameState.xpush(w1); |
515 curState.xpush(w3); | 515 frameState.xpush(w3); |
516 curState.xpush(w2); | 516 frameState.xpush(w2); |
517 curState.xpush(w1); | 517 frameState.xpush(w1); |
518 break; | 518 break; |
519 } | 519 } |
520 case DUP2_X2: { | 520 case DUP2_X2: { |
521 Value w1 = curState.xpop(); | 521 Value w1 = frameState.xpop(); |
522 Value w2 = curState.xpop(); | 522 Value w2 = frameState.xpop(); |
523 Value w3 = curState.xpop(); | 523 Value w3 = frameState.xpop(); |
524 Value w4 = curState.xpop(); | 524 Value w4 = frameState.xpop(); |
525 curState.xpush(w2); | 525 frameState.xpush(w2); |
526 curState.xpush(w1); | 526 frameState.xpush(w1); |
527 curState.xpush(w4); | 527 frameState.xpush(w4); |
528 curState.xpush(w3); | 528 frameState.xpush(w3); |
529 curState.xpush(w2); | 529 frameState.xpush(w2); |
530 curState.xpush(w1); | 530 frameState.xpush(w1); |
531 break; | 531 break; |
532 } | 532 } |
533 case SWAP: { | 533 case SWAP: { |
534 Value w1 = curState.xpop(); | 534 Value w1 = frameState.xpop(); |
535 Value w2 = curState.xpop(); | 535 Value w2 = frameState.xpop(); |
536 curState.xpush(w1); | 536 frameState.xpush(w1); |
537 curState.xpush(w2); | 537 frameState.xpush(w2); |
538 break; | 538 break; |
539 } | 539 } |
540 default: | 540 default: |
541 throw Util.shouldNotReachHere(); | 541 throw Util.shouldNotReachHere(); |
542 } | 542 } |
590 } | 590 } |
591 | 591 |
592 void genIncrement() { | 592 void genIncrement() { |
593 int index = stream().readLocalIndex(); | 593 int index = stream().readLocalIndex(); |
594 int delta = stream().readIncrement(); | 594 int delta = stream().readIncrement(); |
595 Value x = curState.localAt(index); | 595 Value x = frameState.localAt(index); |
596 Value y = append(Constant.forInt(delta, graph)); | 596 Value y = append(Constant.forInt(delta, graph)); |
597 curState.storeLocal(index, append(new ArithmeticOp(IADD, CiKind.Int, x, y, isStrict(method().accessFlags()), null, graph))); | 597 frameState.storeLocal(index, append(new ArithmeticOp(IADD, CiKind.Int, x, y, isStrict(method().accessFlags()), null, graph))); |
598 } | 598 } |
599 | 599 |
600 void genGoto(int fromBCI, int toBCI) { | 600 void genGoto(int fromBCI, int toBCI) { |
601 boolean isSafepoint = !noSafepoints() && toBCI <= fromBCI; | 601 boolean isSafepoint = !noSafepoints() && toBCI <= fromBCI; |
602 append(new Goto(blockAt(toBCI), null, isSafepoint, graph)); | 602 append(new Goto(blockAt(toBCI), null, isSafepoint, graph)); |
610 append(new If(x, cond, y, tsucc, fsucc, isSafepoint ? stateBefore : null, isSafepoint, graph)); | 610 append(new If(x, cond, y, tsucc, fsucc, isSafepoint ? stateBefore : null, isSafepoint, graph)); |
611 } | 611 } |
612 | 612 |
613 void genIfZero(Condition cond) { | 613 void genIfZero(Condition cond) { |
614 Value y = appendConstant(CiConstant.INT_0); | 614 Value y = appendConstant(CiConstant.INT_0); |
615 FrameState stateBefore = curState.immutableCopy(bci()); | 615 FrameState stateBefore = frameState.create(bci()); |
616 Value x = ipop(); | 616 Value x = ipop(); |
617 ifNode(x, cond, y, stateBefore); | 617 ifNode(x, cond, y, stateBefore); |
618 } | 618 } |
619 | 619 |
620 void genIfNull(Condition cond) { | 620 void genIfNull(Condition cond) { |
621 FrameState stateBefore = curState.immutableCopy(bci()); | 621 FrameState stateBefore = frameState.create(bci()); |
622 Value y = appendConstant(CiConstant.NULL_OBJECT); | 622 Value y = appendConstant(CiConstant.NULL_OBJECT); |
623 Value x = apop(); | 623 Value x = apop(); |
624 ifNode(x, cond, y, stateBefore); | 624 ifNode(x, cond, y, stateBefore); |
625 } | 625 } |
626 | 626 |
627 void genIfSame(CiKind kind, Condition cond) { | 627 void genIfSame(CiKind kind, Condition cond) { |
628 FrameState stateBefore = curState.immutableCopy(bci()); | 628 FrameState stateBefore = frameState.create(bci()); |
629 Value y = pop(kind); | 629 Value y = pop(kind); |
630 Value x = pop(kind); | 630 Value x = pop(kind); |
631 ifNode(x, cond, y, stateBefore); | 631 ifNode(x, cond, y, stateBefore); |
632 } | 632 } |
633 | 633 |
634 void genThrow(int bci) { | 634 void genThrow(int bci) { |
635 FrameState stateBefore = curState.immutableCopy(bci()); | 635 FrameState stateBefore = frameState.create(bci()); |
636 Throw t = new Throw(apop(), stateBefore, !noSafepoints(), graph); | 636 Throw t = new Throw(apop(), stateBefore, !noSafepoints(), graph); |
637 appendWithoutOptimization(t, bci); | 637 appendWithoutOptimization(t, bci); |
638 } | 638 } |
639 | 639 |
640 void genCheckCast() { | 640 void genCheckCast() { |
663 return; | 663 return; |
664 } | 664 } |
665 } | 665 } |
666 | 666 |
667 void genNewInstance(int cpi) { | 667 void genNewInstance(int cpi) { |
668 FrameState stateBefore = curState.immutableCopy(bci()); | 668 FrameState stateBefore = frameState.create(bci()); |
669 RiType type = constantPool().lookupType(cpi, NEW); | 669 RiType type = constantPool().lookupType(cpi, NEW); |
670 NewInstance n = new NewInstance(type, cpi, constantPool(), stateBefore, graph); | 670 NewInstance n = new NewInstance(type, cpi, constantPool(), stateBefore, graph); |
671 if (memoryMap != null) { | 671 if (memoryMap != null) { |
672 memoryMap.newInstance(n); | 672 memoryMap.newInstance(n); |
673 } | 673 } |
674 apush(append(n)); | 674 apush(append(n)); |
675 } | 675 } |
676 | 676 |
677 void genNewTypeArray(int typeCode) { | 677 void genNewTypeArray(int typeCode) { |
678 FrameState stateBefore = curState.immutableCopy(bci()); | 678 FrameState stateBefore = frameState.create(bci()); |
679 CiKind kind = CiKind.fromArrayTypeCode(typeCode); | 679 CiKind kind = CiKind.fromArrayTypeCode(typeCode); |
680 RiType elementType = compilation.runtime.asRiType(kind); | 680 RiType elementType = compilation.runtime.asRiType(kind); |
681 apush(append(new NewTypeArray(ipop(), elementType, stateBefore, graph))); | 681 apush(append(new NewTypeArray(ipop(), elementType, stateBefore, graph))); |
682 } | 682 } |
683 | 683 |
684 void genNewObjectArray(int cpi) { | 684 void genNewObjectArray(int cpi) { |
685 RiType type = constantPool().lookupType(cpi, ANEWARRAY); | 685 RiType type = constantPool().lookupType(cpi, ANEWARRAY); |
686 FrameState stateBefore = curState.immutableCopy(bci()); | 686 FrameState stateBefore = frameState.create(bci()); |
687 NewArray n = new NewObjectArray(type, ipop(), stateBefore, graph); | 687 NewArray n = new NewObjectArray(type, ipop(), stateBefore, graph); |
688 apush(append(n)); | 688 apush(append(n)); |
689 } | 689 } |
690 | 690 |
691 void genNewMultiArray(int cpi) { | 691 void genNewMultiArray(int cpi) { |
692 RiType type = constantPool().lookupType(cpi, MULTIANEWARRAY); | 692 RiType type = constantPool().lookupType(cpi, MULTIANEWARRAY); |
693 FrameState stateBefore = curState.immutableCopy(bci()); | 693 FrameState stateBefore = frameState.create(bci()); |
694 int rank = stream().readUByte(bci() + 3); | 694 int rank = stream().readUByte(bci() + 3); |
695 Value[] dims = new Value[rank]; | 695 Value[] dims = new Value[rank]; |
696 for (int i = rank - 1; i >= 0; i--) { | 696 for (int i = rank - 1; i >= 0; i--) { |
697 dims[i] = ipop(); | 697 dims[i] = ipop(); |
698 } | 698 } |
700 apush(append(n)); | 700 apush(append(n)); |
701 } | 701 } |
702 | 702 |
703 void genGetField(int cpi, RiField field) { | 703 void genGetField(int cpi, RiField field) { |
704 // Must copy the state here, because the field holder must still be on the stack. | 704 // Must copy the state here, because the field holder must still be on the stack. |
705 FrameState stateBefore = curState.immutableCopy(bci()); | 705 FrameState stateBefore = frameState.create(bci()); |
706 LoadField load = new LoadField(apop(), field, stateBefore, graph); | 706 LoadField load = new LoadField(apop(), field, stateBefore, graph); |
707 appendOptimizedLoadField(field.kind(), load); | 707 appendOptimizedLoadField(field.kind(), load); |
708 } | 708 } |
709 | 709 |
710 void genPutField(int cpi, RiField field) { | 710 void genPutField(int cpi, RiField field) { |
711 // Must copy the state here, because the field holder must still be on the stack. | 711 // Must copy the state here, because the field holder must still be on the stack. |
712 FrameState stateBefore = curState.immutableCopy(bci()); | 712 FrameState stateBefore = frameState.create(bci()); |
713 Value value = pop(field.kind().stackKind()); | 713 Value value = pop(field.kind().stackKind()); |
714 appendOptimizedStoreField(new StoreField(apop(), field, value, stateBefore, graph)); | 714 appendOptimizedStoreField(new StoreField(apop(), field, value, stateBefore, graph)); |
715 } | 715 } |
716 | 716 |
717 void genGetStatic(int cpi, RiField field) { | 717 void genGetStatic(int cpi, RiField field) { |
785 // the result of resolution is not used by the invocation (only the side effect | 785 // the result of resolution is not used by the invocation (only the side effect |
786 // of initialization is required), it can be commoned with static field accesses. | 786 // of initialization is required), it can be commoned with static field accesses. |
787 genResolveClass(RiType.Representation.StaticFields, holder, isInitialized, cpi); | 787 genResolveClass(RiType.Representation.StaticFields, holder, isInitialized, cpi); |
788 } | 788 } |
789 | 789 |
790 Value[] args = curState.popArguments(target.signature().argumentSlots(false)); | 790 Value[] args = frameState.popArguments(target.signature().argumentSlots(false)); |
791 appendInvoke(INVOKESTATIC, target, args, cpi, constantPool); | 791 appendInvoke(INVOKESTATIC, target, args, cpi, constantPool); |
792 } | 792 } |
793 | 793 |
794 void genInvokeInterface(RiMethod target, int cpi, RiConstantPool constantPool) { | 794 void genInvokeInterface(RiMethod target, int cpi, RiConstantPool constantPool) { |
795 Value[] args = curState.popArguments(target.signature().argumentSlots(true)); | 795 Value[] args = frameState.popArguments(target.signature().argumentSlots(true)); |
796 | 796 |
797 genInvokeIndirect(INVOKEINTERFACE, target, args, cpi, constantPool); | 797 genInvokeIndirect(INVOKEINTERFACE, target, args, cpi, constantPool); |
798 | 798 |
799 } | 799 } |
800 | 800 |
801 void genInvokeVirtual(RiMethod target, int cpi, RiConstantPool constantPool) { | 801 void genInvokeVirtual(RiMethod target, int cpi, RiConstantPool constantPool) { |
802 Value[] args = curState.popArguments(target.signature().argumentSlots(true)); | 802 Value[] args = frameState.popArguments(target.signature().argumentSlots(true)); |
803 genInvokeIndirect(INVOKEVIRTUAL, target, args, cpi, constantPool); | 803 genInvokeIndirect(INVOKEVIRTUAL, target, args, cpi, constantPool); |
804 | 804 |
805 } | 805 } |
806 | 806 |
807 void genInvokeSpecial(RiMethod target, RiType knownHolder, int cpi, RiConstantPool constantPool) { | 807 void genInvokeSpecial(RiMethod target, RiType knownHolder, int cpi, RiConstantPool constantPool) { |
808 Value[] args = curState.popArguments(target.signature().argumentSlots(true)); | 808 Value[] args = frameState.popArguments(target.signature().argumentSlots(true)); |
809 invokeDirect(target, args, knownHolder, cpi, constantPool); | 809 invokeDirect(target, args, knownHolder, cpi, constantPool); |
810 | 810 |
811 } | 811 } |
812 | 812 |
813 /** | 813 /** |
965 } | 965 } |
966 return assumed; | 966 return assumed; |
967 } | 967 } |
968 | 968 |
969 void callRegisterFinalizer() { | 969 void callRegisterFinalizer() { |
970 Value receiver = curState.loadLocal(0); | 970 Value receiver = frameState.loadLocal(0); |
971 RiType declaredType = receiver.declaredType(); | 971 RiType declaredType = receiver.declaredType(); |
972 RiType receiverType = declaredType; | 972 RiType receiverType = declaredType; |
973 RiType exactType = receiver.exactType(); | 973 RiType exactType = receiver.exactType(); |
974 if (exactType == null && declaredType != null) { | 974 if (exactType == null && declaredType != null) { |
975 exactType = declaredType.exactType(); | 975 exactType = declaredType.exactType(); |
998 } | 998 } |
999 } | 999 } |
1000 | 1000 |
1001 if (needsCheck) { | 1001 if (needsCheck) { |
1002 // append a call to the finalizer registration | 1002 // append a call to the finalizer registration |
1003 append(new RegisterFinalizer(curState.loadLocal(0), curState.immutableCopy(bci()), graph)); | 1003 append(new RegisterFinalizer(frameState.loadLocal(0), frameState.create(bci()), graph)); |
1004 C1XMetrics.InlinedFinalizerChecks++; | 1004 C1XMetrics.InlinedFinalizerChecks++; |
1005 } | 1005 } |
1006 } | 1006 } |
1007 | 1007 |
1008 void genReturn(Value x) { | 1008 void genReturn(Value x) { |
1009 if (method().isConstructor() && method().holder().superType() == null) { | 1009 if (method().isConstructor() && method().holder().superType() == null) { |
1010 callRegisterFinalizer(); | 1010 callRegisterFinalizer(); |
1011 } | 1011 } |
1012 | 1012 |
1013 curState.truncateStack(0); | 1013 frameState.clearStack(); |
1014 if (Modifier.isSynchronized(method().accessFlags())) { | 1014 if (Modifier.isSynchronized(method().accessFlags())) { |
1015 FrameState stateBefore = curState.immutableCopy(bci()); | 1015 FrameState stateBefore = frameState.create(bci()); |
1016 // unlock before exiting the method | 1016 // unlock before exiting the method |
1017 int lockNumber = curState.locksSize() - 1; | 1017 int lockNumber = frameState.locksSize() - 1; |
1018 MonitorAddress lockAddress = null; | 1018 MonitorAddress lockAddress = null; |
1019 if (compilation.runtime.sizeOfBasicObjectLock() != 0) { | 1019 if (compilation.runtime.sizeOfBasicObjectLock() != 0) { |
1020 lockAddress = new MonitorAddress(lockNumber, graph); | 1020 lockAddress = new MonitorAddress(lockNumber, graph); |
1021 append(lockAddress); | 1021 append(lockAddress); |
1022 } | 1022 } |
1023 append(new MonitorExit(rootMethodSynchronizedObject, lockAddress, lockNumber, stateBefore, graph)); | 1023 append(new MonitorExit(rootMethodSynchronizedObject, lockAddress, lockNumber, stateBefore, graph)); |
1024 curState.unlock(); | 1024 frameState.unlock(); |
1025 } | 1025 } |
1026 append(new Return(x, !noSafepoints(), graph)); | 1026 append(new Return(x, !noSafepoints(), graph)); |
1027 } | 1027 } |
1028 | 1028 |
1029 /** | 1029 /** |
1030 * Gets the number of locks held. | 1030 * Gets the number of locks held. |
1031 */ | 1031 */ |
1032 private int locksSize() { | 1032 private int locksSize() { |
1033 return curState.locksSize(); | 1033 return frameState.locksSize(); |
1034 } | 1034 } |
1035 | 1035 |
1036 void genMonitorEnter(Value x, int bci) { | 1036 void genMonitorEnter(Value x, int bci) { |
1037 int lockNumber = locksSize(); | 1037 int lockNumber = locksSize(); |
1038 MonitorAddress lockAddress = null; | 1038 MonitorAddress lockAddress = null; |
1040 lockAddress = new MonitorAddress(lockNumber, graph); | 1040 lockAddress = new MonitorAddress(lockNumber, graph); |
1041 append(lockAddress); | 1041 append(lockAddress); |
1042 } | 1042 } |
1043 MonitorEnter monitorEnter = new MonitorEnter(x, lockAddress, lockNumber, null, graph); | 1043 MonitorEnter monitorEnter = new MonitorEnter(x, lockAddress, lockNumber, null, graph); |
1044 appendWithoutOptimization(monitorEnter, bci); | 1044 appendWithoutOptimization(monitorEnter, bci); |
1045 curState.lock(ir, x, lockNumber + 1); | 1045 frameState.lock(ir, x, lockNumber + 1); |
1046 monitorEnter.setStateAfter(curState.immutableCopy(bci)); | 1046 monitorEnter.setStateAfter(frameState.create(bci)); |
1047 killMemoryMap(); // prevent any optimizations across synchronization | 1047 killMemoryMap(); // prevent any optimizations across synchronization |
1048 } | 1048 } |
1049 | 1049 |
1050 void genMonitorExit(Value x, int bci) { | 1050 void genMonitorExit(Value x, int bci) { |
1051 int lockNumber = curState.locksSize() - 1; | 1051 int lockNumber = frameState.locksSize() - 1; |
1052 if (lockNumber < 0) { | 1052 if (lockNumber < 0) { |
1053 throw new CiBailout("monitor stack underflow"); | 1053 throw new CiBailout("monitor stack underflow"); |
1054 } | 1054 } |
1055 MonitorAddress lockAddress = null; | 1055 MonitorAddress lockAddress = null; |
1056 if (compilation.runtime.sizeOfBasicObjectLock() != 0) { | 1056 if (compilation.runtime.sizeOfBasicObjectLock() != 0) { |
1057 lockAddress = new MonitorAddress(lockNumber, graph); | 1057 lockAddress = new MonitorAddress(lockNumber, graph); |
1058 append(lockAddress); | 1058 append(lockAddress); |
1059 } | 1059 } |
1060 appendWithoutOptimization(new MonitorExit(x, lockAddress, lockNumber, null, graph), bci); | 1060 appendWithoutOptimization(new MonitorExit(x, lockAddress, lockNumber, null, graph), bci); |
1061 curState.unlock(); | 1061 frameState.unlock(); |
1062 killMemoryMap(); // prevent any optimizations across synchronization | 1062 killMemoryMap(); // prevent any optimizations across synchronization |
1063 } | 1063 } |
1064 | 1064 |
1065 void genJsr(int dest) { | 1065 void genJsr(int dest) { |
1066 throw new CiBailout("jsr/ret not supported"); | 1066 throw new CiBailout("jsr/ret not supported"); |
1084 } | 1084 } |
1085 int offset = ts.defaultOffset(); | 1085 int offset = ts.defaultOffset(); |
1086 isBackwards |= offset < 0; // if the default successor is backwards | 1086 isBackwards |= offset < 0; // if the default successor is backwards |
1087 list.add(blockAt(bci + offset)); | 1087 list.add(blockAt(bci + offset)); |
1088 boolean isSafepoint = isBackwards && !noSafepoints(); | 1088 boolean isSafepoint = isBackwards && !noSafepoints(); |
1089 FrameState stateBefore = isSafepoint ? curState.immutableCopy(bci()) : null; | 1089 FrameState stateBefore = isSafepoint ? frameState.create(bci()) : null; |
1090 append(new TableSwitch(ipop(), list, ts.lowKey(), stateBefore, isSafepoint, graph)); | 1090 append(new TableSwitch(ipop(), list, ts.lowKey(), stateBefore, isSafepoint, graph)); |
1091 } | 1091 } |
1092 | 1092 |
1093 void genLookupswitch() { | 1093 void genLookupswitch() { |
1094 int bci = bci(); | 1094 int bci = bci(); |
1106 } | 1106 } |
1107 int offset = ls.defaultOffset(); | 1107 int offset = ls.defaultOffset(); |
1108 isBackwards |= offset < 0; // if the default successor is backwards | 1108 isBackwards |= offset < 0; // if the default successor is backwards |
1109 list.add(blockAt(bci + offset)); | 1109 list.add(blockAt(bci + offset)); |
1110 boolean isSafepoint = isBackwards && !noSafepoints(); | 1110 boolean isSafepoint = isBackwards && !noSafepoints(); |
1111 FrameState stateBefore = isSafepoint ? curState.immutableCopy(bci()) : null; | 1111 FrameState stateBefore = isSafepoint ? frameState.create(bci()) : null; |
1112 append(new LookupSwitch(ipop(), list, keys, stateBefore, isSafepoint, graph)); | 1112 append(new LookupSwitch(ipop(), list, keys, stateBefore, isSafepoint, graph)); |
1113 } | 1113 } |
1114 | 1114 |
1115 /** | 1115 /** |
1116 * Determines whether the length of an array should be extracted out as a separate instruction | 1116 * Determines whether the length of an array should be extracted out as a separate instruction |
1184 } | 1184 } |
1185 | 1185 |
1186 if (x instanceof StateSplit) { | 1186 if (x instanceof StateSplit) { |
1187 StateSplit stateSplit = (StateSplit) x; | 1187 StateSplit stateSplit = (StateSplit) x; |
1188 if (stateSplit.stateBefore() == null) { | 1188 if (stateSplit.stateBefore() == null) { |
1189 stateSplit.setStateBefore(curState.immutableCopy(bci)); | 1189 stateSplit.setStateBefore(frameState.create(bci)); |
1190 } | 1190 } |
1191 } | 1191 } |
1192 | 1192 |
1193 if (x.canTrap()) { | 1193 if (x.canTrap()) { |
1194 // connect the instruction to any exception handlers | 1194 // connect the instruction to any exception handlers |
1208 | 1208 |
1209 private BlockBegin blockAt(int bci) { | 1209 private BlockBegin blockAt(int bci) { |
1210 BlockBegin result = blockAtOrNull(bci); | 1210 BlockBegin result = blockAtOrNull(bci); |
1211 assert result != null : "Expected a block to begin at " + bci; | 1211 assert result != null : "Expected a block to begin at " + bci; |
1212 return result; | 1212 return result; |
1213 } | |
1214 | |
1215 MutableFrameState stateAtEntry(RiMethod method) { | |
1216 MutableFrameState state = new MutableFrameState(-1, method.maxLocals(), method.maxStackSize()); | |
1217 int index = 0; | |
1218 if (!isStatic(method.accessFlags())) { | |
1219 // add the receiver and assume it is non null | |
1220 Local local = new Local(method.holder().kind(), index, graph); | |
1221 local.setFlag(Value.Flag.NonNull, true); | |
1222 local.setDeclaredType(method.holder()); | |
1223 state.storeLocal(index, local); | |
1224 index = 1; | |
1225 } | |
1226 RiSignature sig = method.signature(); | |
1227 int max = sig.argumentCount(false); | |
1228 RiType accessingClass = method.holder(); | |
1229 for (int i = 0; i < max; i++) { | |
1230 RiType type = sig.argumentTypeAt(i, accessingClass); | |
1231 CiKind kind = type.kind().stackKind(); | |
1232 Local local = new Local(kind, index, graph); | |
1233 if (type.isResolved()) { | |
1234 local.setDeclaredType(type); | |
1235 } | |
1236 state.storeLocal(index, local); | |
1237 index += kind.sizeInSlots(); | |
1238 } | |
1239 return state; | |
1240 } | 1213 } |
1241 | 1214 |
1242 private Value synchronizedObject(FrameState curState2, RiMethod target) { | 1215 private Value synchronizedObject(FrameState curState2, RiMethod target) { |
1243 if (isStatic(target.accessFlags())) { | 1216 if (isStatic(target.accessFlags())) { |
1244 Constant classConstant = new Constant(target.holder().getEncoding(Representation.JavaClass), graph); | 1217 Constant classConstant = new Constant(target.holder().getEncoding(Representation.JavaClass), graph); |
1248 } | 1221 } |
1249 } | 1222 } |
1250 | 1223 |
1251 private void fillSyncHandler(Value lock, BlockBegin syncHandler) { | 1224 private void fillSyncHandler(Value lock, BlockBegin syncHandler) { |
1252 BlockBegin origBlock = curBlock; | 1225 BlockBegin origBlock = curBlock; |
1253 MutableFrameState origState = curState; | 1226 FrameState origState = frameState.create(-1); |
1254 Instruction origLast = lastInstr; | 1227 Instruction origLast = lastInstr; |
1255 | 1228 |
1256 lastInstr = curBlock = syncHandler; | 1229 lastInstr = curBlock = syncHandler; |
1257 while (lastInstr.next() != null) { | 1230 while (lastInstr.next() != null) { |
1258 // go forward to the end of the block | 1231 // go forward to the end of the block |
1259 lastInstr = lastInstr.next(); | 1232 lastInstr = lastInstr.next(); |
1260 } | 1233 } |
1261 curState = syncHandler.stateBefore().copy(); | 1234 frameState.initializeFrom(syncHandler.stateBefore()); |
1262 | 1235 |
1263 int bci = Instruction.SYNCHRONIZATION_ENTRY_BCI; | 1236 int bci = Instruction.SYNCHRONIZATION_ENTRY_BCI; |
1264 Value exception = appendWithoutOptimization(new ExceptionObject(curState.immutableCopy(bci), graph), bci); | 1237 Value exception = appendWithoutOptimization(new ExceptionObject(frameState.create(bci), graph), bci); |
1265 | 1238 |
1266 assert lock != null; | 1239 assert lock != null; |
1267 assert curState.locksSize() > 0 && curState.lockAt(locksSize() - 1) == lock; | 1240 assert frameState.locksSize() > 0 && frameState.lockAt(locksSize() - 1) == lock; |
1268 if (lock instanceof Instruction) { | 1241 if (lock instanceof Instruction) { |
1269 Instruction l = (Instruction) lock; | 1242 Instruction l = (Instruction) lock; |
1270 if (!l.isAppended()) { | 1243 if (!l.isAppended()) { |
1271 lock = appendWithoutOptimization(l, Instruction.SYNCHRONIZATION_ENTRY_BCI); | 1244 lock = appendWithoutOptimization(l, Instruction.SYNCHRONIZATION_ENTRY_BCI); |
1272 } | 1245 } |
1276 | 1249 |
1277 apush(exception); | 1250 apush(exception); |
1278 genThrow(bci); | 1251 genThrow(bci); |
1279 BlockEnd end = (BlockEnd) lastInstr; | 1252 BlockEnd end = (BlockEnd) lastInstr; |
1280 curBlock.setEnd(end); | 1253 curBlock.setEnd(end); |
1281 end.setStateAfter(curState.immutableCopy(bci())); | 1254 end.setStateAfter(frameState.create(bci())); |
1282 | 1255 |
1283 curBlock = origBlock; | 1256 curBlock = origBlock; |
1284 curState = origState; | 1257 frameState.initializeFrom(origState); |
1285 lastInstr = origLast; | 1258 lastInstr = origLast; |
1286 } | 1259 } |
1287 | 1260 |
1288 private void iterateAllBlocks() { | 1261 private void iterateAllBlocks() { |
1289 BlockBegin b; | 1262 BlockBegin b; |
1291 if (!b.wasVisited()) { | 1264 if (!b.wasVisited()) { |
1292 b.setWasVisited(true); | 1265 b.setWasVisited(true); |
1293 // now parse the block | 1266 // now parse the block |
1294 killMemoryMap(); | 1267 killMemoryMap(); |
1295 curBlock = b; | 1268 curBlock = b; |
1296 curState = b.stateBefore().copy(); | 1269 frameState.initializeFrom(b.stateBefore()); |
1297 lastInstr = b; | 1270 lastInstr = b; |
1298 b.appendNext(null, -1); | 1271 b.appendNext(null, -1); |
1299 | 1272 |
1300 iterateBytecodesForBlock(b.bci(), false); | 1273 iterateBytecodesForBlock(b.bci(), false); |
1301 } | 1274 } |
1302 } | 1275 } |
1303 } | 1276 } |
1304 | 1277 |
1305 private BlockEnd iterateBytecodesForBlock(int bci, boolean inliningIntoCurrentBlock) { | 1278 private BlockEnd iterateBytecodesForBlock(int bci, boolean inliningIntoCurrentBlock) { |
1306 skipBlock = false; | 1279 skipBlock = false; |
1307 assert curState != null; | 1280 assert frameState != null; |
1308 stream.setBCI(bci); | 1281 stream.setBCI(bci); |
1309 | 1282 |
1310 BlockBegin block = curBlock; | 1283 BlockBegin block = curBlock; |
1311 BlockEnd end = null; | 1284 BlockEnd end = null; |
1312 boolean pushException = block.isExceptionEntry() && block.next() == null; | 1285 boolean pushException = block.isExceptionEntry() && block.next() == null; |
1333 // read the opcode | 1306 // read the opcode |
1334 int opcode = stream.currentBC(); | 1307 int opcode = stream.currentBC(); |
1335 | 1308 |
1336 // push an exception object onto the stack if we are parsing an exception handler | 1309 // push an exception object onto the stack if we are parsing an exception handler |
1337 if (pushException) { | 1310 if (pushException) { |
1338 FrameState stateBefore = curState.immutableCopy(bci()); | 1311 FrameState stateBefore = frameState.create(bci()); |
1339 apush(append(new ExceptionObject(stateBefore, graph))); | 1312 apush(append(new ExceptionObject(stateBefore, graph))); |
1340 pushException = false; | 1313 pushException = false; |
1341 } | 1314 } |
1342 | 1315 |
1343 traceState(); | 1316 traceState(); |
1361 return (BlockEnd) lastInstr; | 1334 return (BlockEnd) lastInstr; |
1362 } | 1335 } |
1363 | 1336 |
1364 // if the method terminates, we don't need the stack anymore | 1337 // if the method terminates, we don't need the stack anymore |
1365 if (end instanceof Return || end instanceof Throw) { | 1338 if (end instanceof Return || end instanceof Throw) { |
1366 curState.clearStack(); | 1339 frameState.clearStack(); |
1367 } | 1340 } |
1368 | 1341 |
1369 // connect to begin and set state | 1342 // connect to begin and set state |
1370 // NOTE that inlining may have changed the block we are parsing | 1343 // NOTE that inlining may have changed the block we are parsing |
1371 assert end != null : "end should exist after iterating over bytecodes"; | 1344 assert end != null : "end should exist after iterating over bytecodes"; |
1372 end.setStateAfter(curState.immutableCopy(bci())); | 1345 end.setStateAfter(frameState.create(bci())); |
1373 curBlock.setEnd(end); | 1346 curBlock.setEnd(end); |
1374 // propagate the state | 1347 // propagate the state |
1375 for (BlockBegin succ : end.blockSuccessors()) { | 1348 for (BlockBegin succ : end.blockSuccessors()) { |
1376 assert succ.blockPredecessors().contains(curBlock); | 1349 assert succ.blockPredecessors().contains(curBlock); |
1377 succ.mergeOrClone(end.stateAfter(), method()); | 1350 succ.mergeOrClone(end.stateAfter(), method()); |
1380 return end; | 1353 return end; |
1381 } | 1354 } |
1382 | 1355 |
1383 private void traceState() { | 1356 private void traceState() { |
1384 if (C1XOptions.TraceBytecodeParserLevel >= TRACELEVEL_STATE && !TTY.isSuppressed()) { | 1357 if (C1XOptions.TraceBytecodeParserLevel >= TRACELEVEL_STATE && !TTY.isSuppressed()) { |
1385 log.println(String.format("| state [nr locals = %d, stack depth = %d, method = %s]", curState.localsSize(), curState.stackSize(), method())); | 1358 log.println(String.format("| state [nr locals = %d, stack depth = %d, method = %s]", frameState.localsSize(), frameState.stackSize(), method())); |
1386 for (int i = 0; i < curState.localsSize(); ++i) { | 1359 for (int i = 0; i < frameState.localsSize(); ++i) { |
1387 Value value = curState.localAt(i); | 1360 Value value = frameState.localAt(i); |
1388 log.println(String.format("| local[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind.javaName, value)); | 1361 log.println(String.format("| local[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind.javaName, value)); |
1389 } | 1362 } |
1390 for (int i = 0; i < curState.stackSize(); ++i) { | 1363 for (int i = 0; i < frameState.stackSize(); ++i) { |
1391 Value value = curState.stackAt(i); | 1364 Value value = frameState.stackAt(i); |
1392 log.println(String.format("| stack[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind.javaName, value)); | 1365 log.println(String.format("| stack[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind.javaName, value)); |
1393 } | 1366 } |
1394 for (int i = 0; i < curState.locksSize(); ++i) { | 1367 for (int i = 0; i < frameState.locksSize(); ++i) { |
1395 Value value = curState.lockAt(i); | 1368 Value value = frameState.lockAt(i); |
1396 log.println(String.format("| lock[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind.javaName, value)); | 1369 log.println(String.format("| lock[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind.javaName, value)); |
1397 } | 1370 } |
1398 } | 1371 } |
1399 } | 1372 } |
1400 | 1373 |
1501 case SWAP : stackOp(opcode); break; | 1474 case SWAP : stackOp(opcode); break; |
1502 case IADD : // fall through | 1475 case IADD : // fall through |
1503 case ISUB : // fall through | 1476 case ISUB : // fall through |
1504 case IMUL : genArithmeticOp(CiKind.Int, opcode); break; | 1477 case IMUL : genArithmeticOp(CiKind.Int, opcode); break; |
1505 case IDIV : // fall through | 1478 case IDIV : // fall through |
1506 case IREM : genArithmeticOp(CiKind.Int, opcode, curState.immutableCopy(bci())); break; | 1479 case IREM : genArithmeticOp(CiKind.Int, opcode, frameState.create(bci())); break; |
1507 case LADD : // fall through | 1480 case LADD : // fall through |
1508 case LSUB : // fall through | 1481 case LSUB : // fall through |
1509 case LMUL : genArithmeticOp(CiKind.Long, opcode); break; | 1482 case LMUL : genArithmeticOp(CiKind.Long, opcode); break; |
1510 case LDIV : // fall through | 1483 case LDIV : // fall through |
1511 case LREM : genArithmeticOp(CiKind.Long, opcode, curState.immutableCopy(bci())); break; | 1484 case LREM : genArithmeticOp(CiKind.Long, opcode, frameState.create(bci())); break; |
1512 case FADD : // fall through | 1485 case FADD : // fall through |
1513 case FSUB : // fall through | 1486 case FSUB : // fall through |
1514 case FMUL : // fall through | 1487 case FMUL : // fall through |
1515 case FDIV : // fall through | 1488 case FDIV : // fall through |
1516 case FREM : genArithmeticOp(CiKind.Float, opcode); break; | 1489 case FREM : genArithmeticOp(CiKind.Float, opcode); break; |
1627 log.println(sb.toString()); | 1600 log.println(sb.toString()); |
1628 } | 1601 } |
1629 } | 1602 } |
1630 | 1603 |
1631 private void genArrayLength() { | 1604 private void genArrayLength() { |
1632 FrameState stateBefore = curState.immutableCopy(bci()); | 1605 FrameState stateBefore = frameState.create(bci()); |
1633 ipush(append(new ArrayLength(apop(), stateBefore, graph))); | 1606 ipush(append(new ArrayLength(apop(), stateBefore, graph))); |
1634 } | 1607 } |
1635 | 1608 |
1636 void killMemoryMap() { | 1609 void killMemoryMap() { |
1637 if (localValueMap != null) { | 1610 if (localValueMap != null) { |