# HG changeset patch # User Lukas Stadler # Date 1306231637 -7200 # Node ID 27512ea6bbcb10d44e6329f026617ea3c93cf51b # Parent 3e3338a1abb9eb30eb9767b6af3fb7c713fca410 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 diff -r 3e3338a1abb9 -r 27512ea6bbcb graal/GraalCompiler/src/com/sun/c1x/graph/BlockMap.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/BlockMap.java Tue May 24 10:27:15 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/BlockMap.java Tue May 24 12:07:17 2011 +0200 @@ -122,12 +122,18 @@ public Instruction firstInstruction; - private Block[] successors; + final HashSet successors = new HashSet(); private boolean visited; private boolean active; private int loops; } + public static class ExceptionBlock extends Block { + public RiExceptionHandler handler; + public Block next; + public Block handlerBlock; + } + private static final Block[] NO_SUCCESSORS = new Block[0]; /** @@ -346,7 +352,6 @@ if (oldBlock == null) { Block newBlock = new Block(); newBlock.startBci = startBci; - newBlock.successors = NO_SUCCESSORS; blockMap[startBci] = newBlock; return newBlock; @@ -356,10 +361,11 @@ Block newBlock = new Block(); newBlock.startBci = startBci; newBlock.endBci = oldBlock.endBci; - newBlock.successors = oldBlock.successors; + newBlock.successors.addAll(oldBlock.successors); oldBlock.endBci = startBci - 1; - oldBlock.successors = new Block[] {newBlock }; + oldBlock.successors.clear(); + oldBlock.successors.add(newBlock); for (int i = startBci; i <= newBlock.endBci; i++) { blockMap[i] = newBlock; @@ -388,8 +394,47 @@ } } Block predecessor = blockMap[predBci]; - assert predecessor.successors.length == 0; - predecessor.successors = successors; + assert predecessor.successors.size() == 0; + predecessor.successors.addAll(Arrays.asList(successors)); + } + + private HashMap exceptionDispatch = new HashMap(); + + private ExceptionBlock unwindBlock; + + private ExceptionBlock makeUnwind() { + if (unwindBlock == null) { + unwindBlock = new ExceptionBlock(); + unwindBlock.startBci = -1; + unwindBlock.endBci = -1; + } + return unwindBlock; + } + + private Block makeExceptionDispatch(List handlers, int index) { + RiExceptionHandler handler = handlers.get(index); + if (handler.isCatchAll()) { + return blockMap[handler.handlerBCI()]; + } + ExceptionBlock block = exceptionDispatch.get(handler); + if (block == null) { + block = new ExceptionBlock(); + block.startBci = -1; + block.endBci = -1; + block.handler = handler; + block.successors.add(blockMap[handler.handlerBCI()]); + block.handlerBlock = blockMap[handler.handlerBCI()]; + Block next; + if (index < handlers.size() - 1) { + next = makeExceptionDispatch(handlers, index + 1); + } else { + next = makeUnwind(); + } + block.successors.add(next); + block.next = next; + exceptionDispatch.put(handler, block); + } + return block; } private void addExceptionEdges() { @@ -397,31 +442,25 @@ return; } - Block block = null; - HashSet newSuccessorsOfBlock = new HashSet(); + for (int bci = canTrap.nextSetBit(0); bci >= 0; bci = canTrap.nextSetBit(bci + 1)) { + Block block = blockMap[bci]; - for (int bci = canTrap.nextSetBit(0); bci >= 0; bci = canTrap.nextSetBit(bci + 1)) { - Block newBlock = blockMap[bci]; - if (newBlock != block) { - if (block != null) { - block.successors = newSuccessorsOfBlock.toArray(new Block[newSuccessorsOfBlock.size()]); - newSuccessorsOfBlock.clear(); - } - Collections.addAll(newSuccessorsOfBlock, newBlock.successors); - } - block = newBlock; - + ArrayList handlers = null; for (RiExceptionHandler h : method.exceptionHandlers()) { if (h.startBCI() <= bci && bci < h.endBCI()) { - newSuccessorsOfBlock.add(blockMap[h.handlerBCI()]); + if (handlers == null) { + handlers = new ArrayList(); + } + handlers.add(h); if (h.isCatchAll()) { break; } } } - } - if (block != null) { - block.successors = newSuccessorsOfBlock.toArray(new Block[newSuccessorsOfBlock.size()]); + if (handlers != null) { + Block dispatch = makeExceptionDispatch(handlers, 0); + block.successors.add(dispatch); + } } } @@ -513,18 +552,20 @@ // process all the stores in this block byte[] code = method.code(); int bci = block.startBci; - while (bci <= block.endBci) { - int opcode = Bytes.beU1(code, bci); - if (isStore(opcode)) { - processStore(opcode, Bytes.beU1(code, bci + 1)); + if (bci >= 0) { + while (bci <= block.endBci) { + int opcode = Bytes.beU1(code, bci); + if (isStore(opcode)) { + processStore(opcode, Bytes.beU1(code, bci + 1)); - } else if (opcode == WIDE) { - opcode = Bytes.beU1(code, bci + 1); - if (isStore(opcode)) { - processStore(opcode, Bytes.beU2(code, bci + 2)); + } else if (opcode == WIDE) { + opcode = Bytes.beU1(code, bci + 1); + if (isStore(opcode)) { + processStore(opcode, Bytes.beU2(code, bci + 2)); + } } + bci += lengthOf(code, bci); } - bci += lengthOf(code, bci); } } diff -r 3e3338a1abb9 -r 27512ea6bbcb graal/GraalCompiler/src/com/sun/c1x/graph/CriticalEdgeFinder.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/CriticalEdgeFinder.java Tue May 24 10:27:15 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/CriticalEdgeFinder.java Tue May 24 12:07:17 2011 +0200 @@ -51,8 +51,9 @@ } public void apply(BlockBegin block) { - if (block.numberOfSux() >= 2) { - for (BlockBegin succ : block.end().blockSuccessors()) { + BlockEnd end = block.end(); + if (end.blockSuccessorCount() >= 2) { + for (BlockBegin succ : end.blockSuccessors()) { if (succ.numberOfPreds() >= 2) { // TODO: (tw) probably we don't have to make it a critical edge if succ only contains the _same_ predecessor multiple times. recordCriticalEdge(block, succ); diff -r 3e3338a1abb9 -r 27512ea6bbcb graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Tue May 24 10:27:15 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Tue May 24 12:07:17 2011 +0200 @@ -32,6 +32,7 @@ import com.sun.c1x.*; import com.sun.c1x.debug.*; import com.sun.c1x.graph.BlockMap.Block; +import com.sun.c1x.graph.BlockMap.ExceptionBlock; import com.sun.c1x.ir.*; import com.sun.c1x.util.*; import com.sun.c1x.value.*; @@ -84,7 +85,8 @@ private final BytecodeStream stream; // the bytecode stream // bci-to-block mapping - private Block[] blockList; + private Block[] blockFromBci; + private ArrayList blockList; // the constant pool private final RiConstantPool constantPool; @@ -152,12 +154,16 @@ // 2. compute the block map, setup exception handlers and get the entrypoint(s) BlockMap blockMap = compilation.getBlockMap(rootMethod); - blockList = new Block[rootMethod.code().length]; - for (int i = 0; i < blockMap.blocks.size(); i++) { + blockList = new ArrayList(blockMap.blocks); + blockFromBci = new Block[rootMethod.code().length]; + for (int i = 0; i < blockList.size(); i++) { int blockID = ir.nextBlockNumber(); assert blockID == i; - Block block = blockMap.blocks.get(i); - blockList[block.startBci] = block; + Block block = blockList.get(i); + if (block.startBci >= 0) { + blockFromBci[block.startBci] = block; + } +// System.out.println("block " + blockID + " @ " + block.startBci); } // 1. create the start block @@ -171,7 +177,7 @@ if (handlers != null && handlers.length > 0) { exceptionHandlers = new ArrayList(handlers.length); for (RiExceptionHandler ch : handlers) { - Block entry = blockList[ch.handlerBCI()]; + Block entry = blockFromBci[ch.handlerBCI()]; // entry == null means that the exception handler is unreachable according to the BlockMap conservative analysis if (entry != null) { ExceptionHandler h = new ExceptionHandler(ch); @@ -182,7 +188,7 @@ flags |= Flag.HasHandler.mask; } - mergeOrClone(startBlockBegin, frameState, false); + mergeOrClone(startBlock, frameState); // 3. setup internal state for appending instructions lastInstr = startBlockBegin; @@ -203,6 +209,11 @@ syncBlock.firstInstruction = syncHandler; markOnWorkList(syncBlock); + ExceptionBlock excBlock = new ExceptionBlock(); + excBlock.startBci = -1; + excBlock.endBci = -1; + excBlock.blockID = ir.nextBlockNumber(); + blockList.add(excBlock); ExceptionHandler h = new ExceptionHandler(new CiExceptionHandler(0, rootMethod.code().length, -1, 0, null)); h.setEntryBlock(syncBlock); addExceptionHandler(h); @@ -214,13 +225,30 @@ // 5. SKIPPED: look for intrinsics // 6B.1 do the normal parsing - addToWorkList(blockList[0]); + addToWorkList(blockFromBci[0]); iterateAllBlocks(); if (syncBlock != null && syncHandler.stateBefore() != null) { // generate unlocking code if the exception handler is reachable fillSyncHandler(rootMethodSynchronizedObject, syncBlock); } + +// for (Node n : graph.getNodes()) { +// if (n instanceof FrameState) { +// boolean delete = false; +// if (n.usages().size() == 0 && n.predecessors().size() == 0) { +// delete = true; +// } +// if (n.predecessors().size() == 0 && n.usages().size() == 1 && n.usages().get(0) instanceof BlockBegin) { +// n.usages().get(0).inputs().replace(n, null); +// delete = true; +// } +// if (delete) { +// n.delete(); +// System.out.println("deleted framestate"); +// } +// } +// } } private Block nextBlock(int bci) { @@ -260,51 +288,46 @@ } public void mergeOrClone(Block target, FrameStateAccess newState) { - assert target.firstInstruction instanceof BlockBegin; - if (target.isLoopHeader) { - mergeOrClone(target.firstInstruction, newState, true); - } else { - mergeOrClone(target.firstInstruction, newState, false); - } - } - + Instruction first = target.firstInstruction; + int bci = target.startBci; + boolean loopHeader = target.isLoopHeader; - private void mergeOrClone(Instruction first, FrameStateAccess stateAfter, boolean loopHeader) { - mergeOrClone(first, stateAfter, loopHeader, false); - } - - private void mergeOrClone(Instruction first, FrameStateAccess stateAfter, boolean loopHeader, boolean blockAppended) { - if (first instanceof BlockBegin) { - BlockBegin block = (BlockBegin) first; - FrameState existingState = block.stateBefore(); + FrameState existingState; + if (first instanceof Placeholder) { + existingState = ((Placeholder) first).stateBefore(); + } else { + assert first instanceof BlockBegin; + existingState = ((BlockBegin) first).stateBefore(); + } - if (existingState == null) { - // copy state because it is modified - FrameState duplicate = stateAfter.duplicate(block.bci()); - - // if the block is a loop header, insert all necessary phis - if (loopHeader) { - insertLoopPhis(block, duplicate); - } + if (existingState == null) { + // copy state because it is modified + FrameState duplicate = newState.duplicate(bci); - block.setStateBefore(duplicate); + // if the block is a loop header, insert all necessary phis + if (loopHeader) { + assert first instanceof BlockBegin; + insertLoopPhis((BlockBegin) first, duplicate); + ((BlockBegin) first).setStateBefore(duplicate); } else { - if (!C1XOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(stateAfter)) { - // stacks or locks do not match--bytecodes would not verify - throw new CiBailout("stack or locks do not match"); + if (first instanceof Placeholder) { + ((Placeholder) first).setStateBefore(duplicate); + } else { + ((BlockBegin) first).setStateBefore(duplicate); } - - assert existingState.localsSize() == stateAfter.localsSize(); - assert existingState.stackSize() == stateAfter.stackSize(); - - existingState.merge(block, stateAfter, blockAppended); } } else { - assert false; - } + + if (!C1XOptions.AssumeVerifiedBytecode && !existingState.isCompatibleWith(newState)) { + // stacks or locks do not match--bytecodes would not verify + throw new CiBailout("stack or locks do not match"); + } + assert existingState.localsSize() == newState.localsSize(); + assert existingState.stackSize() == newState.stackSize(); - + existingState.merge((BlockBegin) first, newState); + } for (int j = 0; j < frameState.localsSize() + frameState.stackSize(); ++j) { if (frameState.valueAt(j) != null) { @@ -356,79 +379,38 @@ return; } - ArrayList exceptionHandlers = new ArrayList(); - assert bci == Instruction.SYNCHRONIZATION_ENTRY_BCI || bci == bci() : "invalid bci"; + ExceptionHandler firstHandler = null; // join with all potential exception handlers if (this.exceptionHandlers != null) { for (ExceptionHandler handler : this.exceptionHandlers) { // if the handler covers this bytecode index, add it to the list if (handler.covers(bci)) { - ExceptionHandler newHandler = addExceptionHandler(handler, frameState); - exceptionHandlers.add(newHandler); - - // stop when reaching catch all - if (handler.isCatchAll()) { - break; - } + firstHandler = new ExceptionHandler(handler); + break; } } } - if (!exceptionHandlers.isEmpty()) { - Instruction successor; - - ArrayList newBlocks = new ArrayList(); + if (firstHandler != null) { + compilation.setHasExceptionHandlers(); - int current = exceptionHandlers.size() - 1; - if (exceptionHandlers.get(current).isCatchAll()) { - successor = createTarget(exceptionHandlers.get(current).entryBlock(), null); - current--; - } else { - if (unwindBlock == null) { - unwindBlock = new BlockBegin(bci, ir.nextBlockNumber(), false, graph); - Unwind unwind = new Unwind(null, graph); - unwindBlock.appendNext(unwind); - } - successor = unwindBlock; - } - - for (; current >= 0; current--) { - ExceptionHandler handler = exceptionHandlers.get(current); - - BlockBegin newSucc = null; - for (Node pred : successor.predecessors()) { - if (pred instanceof ExceptionDispatch) { - ExceptionDispatch dispatch = (ExceptionDispatch) pred; - if (dispatch.handler().handler == handler.handler) { - newSucc = dispatch.begin(); - break; - } + Block dispatchBlock = null; + for (Block block : blockList) { + if (block instanceof ExceptionBlock) { + ExceptionBlock excBlock = (ExceptionBlock) block; + if (excBlock.handler == firstHandler.handler) { + dispatchBlock = block; + break; } } - if (newSucc != null) { - successor = newSucc; - } else { - BlockBegin dispatchEntry = new BlockBegin(handler.handlerBCI(), ir.nextBlockNumber(), false, graph); - - if (handler.handler.catchType().isResolved()) { - Instruction entry = createTarget(handler.entryBlock(), null); - ExceptionDispatch end = new ExceptionDispatch(null, entry, null, handler, null, graph); - end.setBlockSuccessor(0, successor); - dispatchEntry.appendNext(end); - } else { - Deoptimize deopt = new Deoptimize(graph); - dispatchEntry.appendNext(deopt); - Goto end = new Goto(successor, null, graph); - deopt.appendNext(end); - } - - newBlocks.add(dispatchEntry); - successor = dispatchEntry; - } } - + // if there's no dispatch block then the catch block needs to be a catch all + if (dispatchBlock == null) { + assert firstHandler.isCatchAll(); + dispatchBlock = firstHandler.entryBlock(); + } FrameState entryState = frameState.duplicateWithEmptyStack(bci); BlockBegin entry = new BlockBegin(bci, ir.nextBlockNumber(), false, graph); @@ -436,6 +418,8 @@ ExceptionObject exception = new ExceptionObject(graph); entry.appendNext(exception); FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, exception); + + Instruction successor = createTarget(dispatchBlock, stateWithException); BlockEnd end = new Goto(successor, stateWithException, graph); exception.appendNext(end); @@ -444,67 +428,9 @@ } else { ((Throw) x).setExceptionEdge(entry); } - - updateDispatchChain(end.blockSuccessor(0), stateWithException, bci); } } - private void updateDispatchChain(BlockBegin dispatchEntry, FrameStateAccess state, int bci) { - FrameState oldState = dispatchEntry.stateBefore(); - if (oldState != null && dispatchEntry.predecessors().size() == 1) { - dispatchEntry.setStateBefore(null); - } - mergeOrClone(dispatchEntry, state, false, true); - FrameState mergedState = dispatchEntry.stateBefore(); - - if (dispatchEntry.next() instanceof ExceptionDispatch) { - // ordinary dispatch handler - ExceptionDispatch dispatch = (ExceptionDispatch) dispatchEntry.next(); - dispatch.setStateAfter(mergedState.duplicate(bci)); - dispatch.setException(mergedState.stackAt(0)); - dispatch.catchSuccessor().setStateBefore(mergedState.duplicate(bci)); - updateDispatchChain(dispatch.otherSuccessor(), mergedState, bci); - } else if (dispatchEntry.next() instanceof Deoptimize) { - // deoptimizing handler - dispatchEntry.end().setStateAfter(mergedState.duplicate(bci)); - updateDispatchChain(dispatchEntry.end().blockSuccessor(0), mergedState, bci); - } else if (dispatchEntry.next() instanceof Unwind) { - // unwind handler - Unwind unwind = (Unwind) dispatchEntry.next(); - unwind.setStateAfter(mergedState.duplicate(bci)); - unwind.setException(mergedState.stackAt(0)); - } else { - // synchronization or default exception handler, nothing to do - } - } - - /** - * Adds an exception handler to the {@linkplain BlockBegin#exceptionHandlerBlocks() list} - * of exception handlers for the {@link #curBlock current block}. - */ - private ExceptionHandler addExceptionHandler(ExceptionHandler handler, FrameStateAccess curState) { - compilation.setHasExceptionHandlers(); - - BlockMap.Block entry = handler.entryBlock(); - - // clone exception handler - ExceptionHandler newHandler = new ExceptionHandler(handler); - - // fill in exception handler subgraph lazily - if (!isVisited(entry)) { - if (handler.handlerBCI() != Instruction.SYNCHRONIZATION_ENTRY_BCI) { - addToWorkList(entry); - } - } else { - // This will occur for exception handlers that cover themselves. This code - // pattern is generated by javac for synchronized blocks. See the following - // for why this change to javac was made: - // - // http://www.cs.arizona.edu/projects/sumatra/hallofshame/java-async-race.html - } - return newHandler; - } - private void genLoadConstant(int cpi) { Object con = constantPool().lookupConstant(cpi); @@ -1124,28 +1050,20 @@ return x; } - private Instruction blockAtOrNull(int bci) { - return blockList[bci] != null ? blockList[bci].firstInstruction : null; - } - - private Instruction blockAt(int bci) { - Instruction result = blockAtOrNull(bci); - assert result != null : "Expected a block to begin at " + bci; - return result; - } - private Instruction createTargetAt(int bci, FrameStateAccess stateAfter) { - return createTarget(blockList[bci], stateAfter); + return createTarget(blockFromBci[bci], stateAfter); } private Instruction createTarget(Block block, FrameStateAccess stateAfter) { + assert block != null && stateAfter != null; if (block.firstInstruction == null) { - BlockBegin blockBegin = new BlockBegin(block.startBci, block.blockID, block.isLoopHeader, graph); - block.firstInstruction = blockBegin; +// if (block.isLoopHeader) { + block.firstInstruction = new BlockBegin(block.startBci, block.blockID, block.isLoopHeader, graph); +// } else { +// block.firstInstruction = new Placeholder(graph); +// } } - if (stateAfter != null) { - mergeOrClone(block, stateAfter); - } + mergeOrClone(block, stateAfter); addToWorkList(block); return block.firstInstruction; } @@ -1209,7 +1127,43 @@ lastInstr = block.firstInstruction; assert block.firstInstruction.next() == null; - iterateBytecodesForBlock(block); + if (block instanceof ExceptionBlock) { + createExceptionDispatch((ExceptionBlock) block); + } else { + iterateBytecodesForBlock(block); + } + } + } + } + + private void createExceptionDispatch(ExceptionBlock block) { + if (block.handler == null) { + assert frameState.stackSize() == 1 : "only exception object expected on stack, actual size: " + frameState.stackSize(); + if (Modifier.isSynchronized(method().accessFlags())) { + // unlock before exiting the method + int lockNumber = frameState.locksSize() - 1; + MonitorAddress lockAddress = null; + if (compilation.runtime.sizeOfBasicObjectLock() != 0) { + lockAddress = new MonitorAddress(lockNumber, graph); + append(lockAddress); + } + append(new MonitorExit(rootMethodSynchronizedObject, lockAddress, lockNumber, graph)); + frameState.unlock(); + } + append(new Unwind(frameState.apop(), graph)); + } else { + assert frameState.stackSize() == 1; + + if (block.handler.catchType().isResolved()) { + Instruction catchSuccessor = createTarget(block.handlerBlock, frameState); + Instruction nextDispatch = createTarget(block.next, frameState); + append(new ExceptionDispatch(frameState.stackAt(0), catchSuccessor, nextDispatch, block.handler.catchType(), frameState.duplicate(bci()), graph)); + } else { + Deoptimize deopt = new Deoptimize(graph); + deopt.setMessage("unresolved " + block.handler.catchType().name()); + append(deopt); + Instruction nextDispatch = createTarget(block.next, frameState); + append(new Goto(nextDispatch, frameState.duplicate(bci()), graph)); } } } @@ -1225,7 +1179,7 @@ int bci = block.startBci; while (bci < endBCI) { - Block nextBlock = blockList[bci]; + Block nextBlock = blockFromBci[bci]; if (nextBlock != null && nextBlock != block) { // we fell through to the next block, add a goto and break Instruction next = createTarget(nextBlock, frameState); @@ -1263,8 +1217,7 @@ // connect to begin and set state // NOTE that inlining may have changed the block we are parsing assert end != null : "end should exist after iterating over bytecodes"; - FrameState stateAtEnd = frameState.create(bci()); - end.setStateAfter(stateAtEnd); + end.setStateAfter(frameState.create(bci())); return end; } diff -r 3e3338a1abb9 -r 27512ea6bbcb graal/GraalCompiler/src/com/sun/c1x/graph/IR.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java Tue May 24 10:27:15 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java Tue May 24 12:07:17 2011 +0200 @@ -36,9 +36,6 @@ /** * This class implements the overall container for the HIR (high-level IR) graph * and directs its construction, optimization, and finalization. - * - * @author Thomas Wuerthinger - * @author Ben L. Titzer */ public class IR { @@ -158,8 +155,9 @@ lirBlock.blockPredecessors().add(valueToBlock.get(bb.predAt(i).block())); } - for (int i = 0; i < bb.numberOfSux(); ++i) { - lirBlock.blockSuccessors().add(valueToBlock.get(bb.suxAt(i))); + BlockEnd end = bb.end(); + for (int i = 0; i < end.blockSuccessorCount(); ++i) { + lirBlock.blockSuccessors().add(valueToBlock.get(end.blockSuccessor(i))); } Instruction first = bb; diff -r 3e3338a1abb9 -r 27512ea6bbcb graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java Tue May 24 10:27:15 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/BlockBegin.java Tue May 24 12:07:17 2011 +0200 @@ -97,19 +97,6 @@ } /** - * Gets the list of predecessors of this block. - * @return the predecessor list - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - public List blockPredecessors() { - if (predecessors().size() == 1 && predecessors().get(0) == graph().start()) { - return Collections.EMPTY_LIST; - } else { - return (List) Collections.unmodifiableList(predecessors()); - } - } - - /** * Gets the linear scan number of this block. * @return the linear scan number */ @@ -147,10 +134,8 @@ Instruction inst = this; ArrayList excBlocks = new ArrayList(); while (inst != null) { - if (inst instanceof Invoke) { - excBlocks.add(((Invoke) inst).exceptionEdge()); - } else if (inst instanceof Throw) { - excBlocks.add(((Throw) inst).exceptionEdge()); + if (inst instanceof ExceptionEdgeInstruction) { + excBlocks.add(((ExceptionEdgeInstruction) inst).exceptionEdge()); } inst = inst.next(); } @@ -202,40 +187,6 @@ return builder.toString(); } - /** - * Get the number of successors. - * @return the number of successors - */ - public int numberOfSux() { - return end().blockSuccessorCount(); - } - - /** - * Get the successor at a certain position. - * @param i the position - * @return the successor - */ - public BlockBegin suxAt(int i) { - return end().blockSuccessor(i); - } - - /** - * Get the number of predecessors. - * @return the number of predecessors - */ - public int numberOfPreds() { - // ignore the graph root - if (predecessors().size() == 1 && predecessors().get(0) == graph().start()) { - return 0; - } else { - return predecessors().size(); - } - } - - public Instruction predAt(int j) { - return (Instruction) predecessors().get(j); - } - public void printWithoutPhis(LogStream out) { // print block id BlockEnd end = end(); @@ -397,13 +348,14 @@ * Iterates over all successors of this block: successors of the end node and exception handler. */ public void allSuccessorsDo(boolean backwards, BlockClosure closure) { + BlockEnd end = end(); if (backwards) { - for (int i = numberOfSux() - 1; i >= 0; i--) { - closure.apply(suxAt(i)); + for (int i = end.blockSuccessorCount() - 1; i >= 0; i--) { + closure.apply(end.blockSuccessor(i)); } } else { - for (int i = 0; i < numberOfSux(); i++) { - closure.apply(suxAt(i)); + for (int i = 0; i < end.blockSuccessorCount(); i++) { + closure.apply(end.blockSuccessor(i)); } } for (Instruction x = next(); x != null; x = x.next()) { diff -r 3e3338a1abb9 -r 27512ea6bbcb graal/GraalCompiler/src/com/sun/c1x/ir/ComputeLinearScanOrder.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/ComputeLinearScanOrder.java Tue May 24 10:27:15 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ComputeLinearScanOrder.java Tue May 24 12:07:17 2011 +0200 @@ -177,8 +177,9 @@ private int computeWeight(BlockBegin cur) { BlockBegin singleSux = null; - if (cur.numberOfSux() == 1) { - singleSux = cur.suxAt(0); + BlockEnd end = cur.end(); + if (end.blockSuccessorCount() == 1) { + singleSux = end.blockSuccessor(0); } // limit loop-depth to 15 bit (only for security reason, it will never be so big) diff -r 3e3338a1abb9 -r 27512ea6bbcb graal/GraalCompiler/src/com/sun/c1x/ir/Deoptimize.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/Deoptimize.java Tue May 24 10:27:15 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Deoptimize.java Tue May 24 12:07:17 2011 +0200 @@ -26,25 +26,25 @@ import com.sun.c1x.debug.*; import com.sun.cri.ci.*; - -/** - * - */ public class Deoptimize extends Instruction { private static final int INPUT_COUNT = 0; private static final int SUCCESSOR_COUNT = 0; - /** - * @param kind - * @param inputCount - * @param successorCount - * @param graph - */ + private String message; + public Deoptimize(Graph graph) { super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph); } + public void setMessage(String message) { + this.message = message; + } + + public String message() { + return message; + } + @Override public void accept(ValueVisitor v) { v.visitDeoptimize(this); @@ -55,4 +55,9 @@ out.print("deoptimize"); } + @Override + public String shortName() { + return "Deopt " + message; + } + } diff -r 3e3338a1abb9 -r 27512ea6bbcb graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionDispatch.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionDispatch.java Tue May 24 10:27:15 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionDispatch.java Tue May 24 12:07:17 2011 +0200 @@ -26,6 +26,7 @@ import com.sun.c1x.debug.*; import com.sun.c1x.value.*; import com.sun.cri.ci.*; +import com.sun.cri.ri.*; /** * This instruction takes an exception object and has two successors: @@ -59,21 +60,21 @@ return (Value) inputs().set(super.inputCount() + INPUT_EXCEPTION, n); } - private final ExceptionHandler handler; + private final RiType catchType; /** * Constructs a new ExceptionDispatch instruction. */ - public ExceptionDispatch(Value exception, Instruction catchSuccessor, Instruction otherSuccessor, ExceptionHandler handler, FrameState stateAfter, Graph graph) { + public ExceptionDispatch(Value exception, Instruction catchSuccessor, Instruction otherSuccessor, RiType catchType, FrameState stateAfter, Graph graph) { super(CiKind.Int, stateAfter, 2, INPUT_COUNT, SUCCESSOR_COUNT, graph); setException(exception); setBlockSuccessor(0, otherSuccessor); setBlockSuccessor(1, catchSuccessor); - this.handler = handler; + this.catchType = catchType; } - public ExceptionHandler handler() { - return handler; + public RiType catchType() { + return catchType; } /** @@ -113,7 +114,7 @@ print(' '). print("instanceof"). print(' '). - print(handler.handler.catchType().name()). + print(catchType().name()). print(" then B"). print(blockSuccessors().get(1).blockID). print(" else B"). @@ -122,7 +123,7 @@ @Override public String shortName() { - return "Dispatch " + handler.handler.catchType().name(); + return "Dispatch " + catchType().name(); } diff -r 3e3338a1abb9 -r 27512ea6bbcb graal/GraalCompiler/src/com/sun/c1x/ir/Instruction.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/Instruction.java Tue May 24 10:27:15 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Instruction.java Tue May 24 12:07:17 2011 +0200 @@ -111,6 +111,36 @@ return next; } + /** + * Gets the list of predecessors of this block. + * @return the predecessor list + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + public List blockPredecessors() { + if (predecessors().size() == 1 && predecessors().get(0) == graph().start()) { + return Collections.EMPTY_LIST; + } else { + return (List) Collections.unmodifiableList(predecessors()); + } + } + + /** + * Get the number of predecessors. + * @return the number of predecessors + */ + public int numberOfPreds() { + // ignore the graph root + if (predecessors().size() == 1 && predecessors().get(0) == graph().start()) { + return 0; + } else { + return predecessors().size(); + } + } + + public Instruction predAt(int j) { + return (Instruction) predecessors().get(j); + } + @Override public BlockBegin block() { Instruction cur = this; diff -r 3e3338a1abb9 -r 27512ea6bbcb graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRGenerator.java --- a/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRGenerator.java Tue May 24 10:27:15 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRGenerator.java Tue May 24 12:07:17 2011 +0200 @@ -517,7 +517,7 @@ public void visitExceptionDispatch(ExceptionDispatch x) { // TODO ls: this needs some more work... - RiType riType = x.handler().handler.catchType(); + RiType riType = x.catchType(); assert riType.isResolved(); XirArgument obj = toXirArgument(x.exception()); diff -r 3e3338a1abb9 -r 27512ea6bbcb graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java --- a/graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java Tue May 24 10:27:15 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java Tue May 24 12:07:17 2011 +0200 @@ -325,7 +325,7 @@ } } - public void merge(BlockBegin block, FrameStateAccess other, boolean blockAppended) { + public void merge(BlockBegin block, FrameStateAccess other) { checkSize(other); for (int i = 0; i < valuesSize(); i++) { Value x = valueAt(i); @@ -354,9 +354,6 @@ Phi originalPhi = phi; if (phi.valueCount() == 0) { int size = block.predecessors().size(); - if (blockAppended) { - size--; - } for (int j = 0; j < size; ++j) { phi = phi.addInput(x); } @@ -372,7 +369,7 @@ } } - assert phi.valueCount() == block.predecessors().size() + (blockAppended ? 0 : 1) : "valueCount=" + phi.valueCount() + " predSize= " + block.predecessors().size(); + assert phi.valueCount() == block.predecessors().size() + 1 : "valueCount=" + phi.valueCount() + " predSize= " + block.predecessors().size(); } } }