comparison graal/GraalCompiler/src/com/sun/c1x/graph/BlockMap.java @ 2773:27512ea6bbcb

exception dispatch simplification: * BlockMap creates exception dispatch blocks (so they're iterated in the right order) * GraphBuilder uses exception dispatch blocks, simplified handleException, removed updateDispatchChain * simplified mergeOrClone * removed successor & predecessor methods from BlockBegin
author Lukas Stadler <lukas.stadler@jku.at>
date Tue, 24 May 2011 12:07:17 +0200
parents 49a8790b85a2
children 706047ee5f2e
comparison
equal deleted inserted replaced
2772:3e3338a1abb9 2773:27512ea6bbcb
120 public boolean isLoopHeader; 120 public boolean isLoopHeader;
121 public int blockID; 121 public int blockID;
122 122
123 public Instruction firstInstruction; 123 public Instruction firstInstruction;
124 124
125 private Block[] successors; 125 final HashSet<Block> successors = new HashSet<Block>();
126 private boolean visited; 126 private boolean visited;
127 private boolean active; 127 private boolean active;
128 private int loops; 128 private int loops;
129 }
130
131 public static class ExceptionBlock extends Block {
132 public RiExceptionHandler handler;
133 public Block next;
134 public Block handlerBlock;
129 } 135 }
130 136
131 private static final Block[] NO_SUCCESSORS = new Block[0]; 137 private static final Block[] NO_SUCCESSORS = new Block[0];
132 138
133 /** 139 /**
344 private Block makeBlock(int startBci) { 350 private Block makeBlock(int startBci) {
345 Block oldBlock = blockMap[startBci]; 351 Block oldBlock = blockMap[startBci];
346 if (oldBlock == null) { 352 if (oldBlock == null) {
347 Block newBlock = new Block(); 353 Block newBlock = new Block();
348 newBlock.startBci = startBci; 354 newBlock.startBci = startBci;
349 newBlock.successors = NO_SUCCESSORS;
350 blockMap[startBci] = newBlock; 355 blockMap[startBci] = newBlock;
351 return newBlock; 356 return newBlock;
352 357
353 } else if (oldBlock.startBci != startBci) { 358 } else if (oldBlock.startBci != startBci) {
354 // Backward branch into the middle of an already processed block. 359 // Backward branch into the middle of an already processed block.
355 // Add the correct fall-through successor. 360 // Add the correct fall-through successor.
356 Block newBlock = new Block(); 361 Block newBlock = new Block();
357 newBlock.startBci = startBci; 362 newBlock.startBci = startBci;
358 newBlock.endBci = oldBlock.endBci; 363 newBlock.endBci = oldBlock.endBci;
359 newBlock.successors = oldBlock.successors; 364 newBlock.successors.addAll(oldBlock.successors);
360 365
361 oldBlock.endBci = startBci - 1; 366 oldBlock.endBci = startBci - 1;
362 oldBlock.successors = new Block[] {newBlock }; 367 oldBlock.successors.clear();
368 oldBlock.successors.add(newBlock);
363 369
364 for (int i = startBci; i <= newBlock.endBci; i++) { 370 for (int i = startBci; i <= newBlock.endBci; i++) {
365 blockMap[i] = newBlock; 371 blockMap[i] = newBlock;
366 } 372 }
367 return newBlock; 373 return newBlock;
386 if (sux.isExceptionEntry) { 392 if (sux.isExceptionEntry) {
387 throw new CiBailout("Exception handler can be reached by both normal and exceptional control flow"); 393 throw new CiBailout("Exception handler can be reached by both normal and exceptional control flow");
388 } 394 }
389 } 395 }
390 Block predecessor = blockMap[predBci]; 396 Block predecessor = blockMap[predBci];
391 assert predecessor.successors.length == 0; 397 assert predecessor.successors.size() == 0;
392 predecessor.successors = successors; 398 predecessor.successors.addAll(Arrays.asList(successors));
399 }
400
401 private HashMap<RiExceptionHandler, ExceptionBlock> exceptionDispatch = new HashMap<RiExceptionHandler, ExceptionBlock>();
402
403 private ExceptionBlock unwindBlock;
404
405 private ExceptionBlock makeUnwind() {
406 if (unwindBlock == null) {
407 unwindBlock = new ExceptionBlock();
408 unwindBlock.startBci = -1;
409 unwindBlock.endBci = -1;
410 }
411 return unwindBlock;
412 }
413
414 private Block makeExceptionDispatch(List<RiExceptionHandler> handlers, int index) {
415 RiExceptionHandler handler = handlers.get(index);
416 if (handler.isCatchAll()) {
417 return blockMap[handler.handlerBCI()];
418 }
419 ExceptionBlock block = exceptionDispatch.get(handler);
420 if (block == null) {
421 block = new ExceptionBlock();
422 block.startBci = -1;
423 block.endBci = -1;
424 block.handler = handler;
425 block.successors.add(blockMap[handler.handlerBCI()]);
426 block.handlerBlock = blockMap[handler.handlerBCI()];
427 Block next;
428 if (index < handlers.size() - 1) {
429 next = makeExceptionDispatch(handlers, index + 1);
430 } else {
431 next = makeUnwind();
432 }
433 block.successors.add(next);
434 block.next = next;
435 exceptionDispatch.put(handler, block);
436 }
437 return block;
393 } 438 }
394 439
395 private void addExceptionEdges() { 440 private void addExceptionEdges() {
396 if (canTrap == null) { 441 if (canTrap == null) {
397 return; 442 return;
398 } 443 }
399 444
400 Block block = null;
401 HashSet<Block> newSuccessorsOfBlock = new HashSet<Block>();
402
403 for (int bci = canTrap.nextSetBit(0); bci >= 0; bci = canTrap.nextSetBit(bci + 1)) { 445 for (int bci = canTrap.nextSetBit(0); bci >= 0; bci = canTrap.nextSetBit(bci + 1)) {
404 Block newBlock = blockMap[bci]; 446 Block block = blockMap[bci];
405 if (newBlock != block) { 447
406 if (block != null) { 448 ArrayList<RiExceptionHandler> handlers = null;
407 block.successors = newSuccessorsOfBlock.toArray(new Block[newSuccessorsOfBlock.size()]);
408 newSuccessorsOfBlock.clear();
409 }
410 Collections.addAll(newSuccessorsOfBlock, newBlock.successors);
411 }
412 block = newBlock;
413
414 for (RiExceptionHandler h : method.exceptionHandlers()) { 449 for (RiExceptionHandler h : method.exceptionHandlers()) {
415 if (h.startBCI() <= bci && bci < h.endBCI()) { 450 if (h.startBCI() <= bci && bci < h.endBCI()) {
416 newSuccessorsOfBlock.add(blockMap[h.handlerBCI()]); 451 if (handlers == null) {
452 handlers = new ArrayList<RiExceptionHandler>();
453 }
454 handlers.add(h);
417 if (h.isCatchAll()) { 455 if (h.isCatchAll()) {
418 break; 456 break;
419 } 457 }
420 } 458 }
421 } 459 }
422 } 460 if (handlers != null) {
423 if (block != null) { 461 Block dispatch = makeExceptionDispatch(handlers, 0);
424 block.successors = newSuccessorsOfBlock.toArray(new Block[newSuccessorsOfBlock.size()]); 462 block.successors.add(dispatch);
463 }
425 } 464 }
426 } 465 }
427 466
428 private void computeBlockOrder() { 467 private void computeBlockOrder() {
429 int loop = computeBlockOrder(blockMap[0]); 468 int loop = computeBlockOrder(blockMap[0]);
511 550
512 private void processLoopBlock(Block block) { 551 private void processLoopBlock(Block block) {
513 // process all the stores in this block 552 // process all the stores in this block
514 byte[] code = method.code(); 553 byte[] code = method.code();
515 int bci = block.startBci; 554 int bci = block.startBci;
516 while (bci <= block.endBci) { 555 if (bci >= 0) {
517 int opcode = Bytes.beU1(code, bci); 556 while (bci <= block.endBci) {
518 if (isStore(opcode)) { 557 int opcode = Bytes.beU1(code, bci);
519 processStore(opcode, Bytes.beU1(code, bci + 1));
520
521 } else if (opcode == WIDE) {
522 opcode = Bytes.beU1(code, bci + 1);
523 if (isStore(opcode)) { 558 if (isStore(opcode)) {
524 processStore(opcode, Bytes.beU2(code, bci + 2)); 559 processStore(opcode, Bytes.beU1(code, bci + 1));
525 } 560
526 } 561 } else if (opcode == WIDE) {
527 bci += lengthOf(code, bci); 562 opcode = Bytes.beU1(code, bci + 1);
563 if (isStore(opcode)) {
564 processStore(opcode, Bytes.beU2(code, bci + 2));
565 }
566 }
567 bci += lengthOf(code, bci);
568 }
528 } 569 }
529 } 570 }
530 571
531 private void processStore(int opcode, int local) { 572 private void processStore(int opcode, int local) {
532 switch (opcode) { 573 switch (opcode) {