Mercurial > hg > graal-jvmci-8
diff graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java @ 2835:c1c8a0291771
merge
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Tue, 31 May 2011 13:37:45 +0200 |
parents | bfce42cd9c07 1cd59ca9ac86 |
children | 7b5831f0e913 |
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Tue May 31 13:37:45 2011 +0200 @@ -69,6 +69,9 @@ private Block[] blockFromBci; private ArrayList<Block> blockList; + private Block syncBlock; + private CiExceptionHandler syncHandler; + // the constant pool private final RiConstantPool constantPool; @@ -79,9 +82,6 @@ } }); - // Exception handler list - private List<ExceptionHandler> exceptionHandlers; - private FrameStateBuilder frameState; // the current execution state private Instruction lastInstr; // the last instruction added @@ -133,21 +133,6 @@ if (block.startBci >= 0) { blockFromBci[block.startBci] = block; } -// System.out.println("block " + blockID + " @ " + block.startBci); - } - - RiExceptionHandler[] handlers = rootMethod.exceptionHandlers(); - if (handlers != null && handlers.length > 0) { - exceptionHandlers = new ArrayList<ExceptionHandler>(handlers.length); - for (RiExceptionHandler ch : handlers) { - 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); - h.setEntryBlock(entry); - exceptionHandlers.add(h); - } - } } // 1. create the start block @@ -156,7 +141,6 @@ lastInstr = createTarget(startBlock, frameState); graph.start().setStart(lastInstr); - Block syncBlock = null; if (isSynchronized(rootMethod.accessFlags())) { // 4A.1 add a monitor enter to the start block rootMethodSynchronizedObject = synchronizedObject(frameState, compilation.method); @@ -168,9 +152,7 @@ syncBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI); markOnWorkList(syncBlock); - ExceptionHandler h = new ExceptionHandler(new CiExceptionHandler(0, rootMethod.code().length, -1, 0, null)); - h.setEntryBlock(syncBlock); - addExceptionHandler(h); + syncHandler = new CiExceptionHandler(0, rootMethod.code().length, Instruction.SYNCHRONIZATION_ENTRY_BCI, 0, null); } else { // 4B.1 simply finish the start block finishStartBlock(startBlock); @@ -347,25 +329,34 @@ frameState.storeLocal(index, frameState.pop(kind)); } - private void handleException(Instruction x, int bci) { - if (!hasHandler()) { - return; - } + public boolean covers(RiExceptionHandler handler, int bci) { + return handler.startBCI() <= bci && bci < handler.endBCI(); + } + public boolean isCatchAll(RiExceptionHandler handler) { + return handler.catchTypeCPI() == 0; + } + + private Instruction handleException(Value exceptionObject, int bci) { assert bci == Instruction.SYNCHRONIZATION_ENTRY_BCI || bci == bci() : "invalid bci"; - ExceptionHandler firstHandler = null; + RiExceptionHandler firstHandler = null; + RiExceptionHandler[] exceptionHandlers = compilation.method.exceptionHandlers(); // join with all potential exception handlers - if (this.exceptionHandlers != null) { - for (ExceptionHandler handler : this.exceptionHandlers) { + if (exceptionHandlers != null) { + for (RiExceptionHandler handler : exceptionHandlers) { // if the handler covers this bytecode index, add it to the list - if (handler.covers(bci)) { - firstHandler = new ExceptionHandler(handler); + if (covers(handler, bci)) { + firstHandler = handler; break; } } } + if (firstHandler == null) { + firstHandler = syncHandler; + } + if (firstHandler != null) { compilation.setHasExceptionHandlers(); @@ -373,7 +364,7 @@ for (Block block : blockList) { if (block instanceof ExceptionBlock) { ExceptionBlock excBlock = (ExceptionBlock) block; - if (excBlock.handler == firstHandler.handler) { + if (excBlock.handler == firstHandler) { dispatchBlock = block; break; } @@ -381,26 +372,35 @@ } // 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(); + assert isCatchAll(firstHandler); + int handlerBCI = firstHandler.handlerBCI(); + if (handlerBCI == Instruction.SYNCHRONIZATION_ENTRY_BCI) { + dispatchBlock = syncBlock; + } else { + dispatchBlock = blockFromBci[handlerBCI]; + } } FrameState entryState = frameState.duplicateWithEmptyStack(bci); StateSplit entry = new Placeholder(graph); entry.setStateBefore(entryState); - ExceptionObject exception = new ExceptionObject(graph); - entry.setNext(exception); - FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, exception); + + Instruction currentNext = entry; + Value currentExceptionObject = exceptionObject; + if (currentExceptionObject == null) { + ExceptionObject exception = new ExceptionObject(graph); + entry.setNext(exception); + currentNext = exception; + currentExceptionObject = exception; + } + FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, currentExceptionObject); Instruction successor = createTarget(dispatchBlock, stateWithException); Anchor end = new Anchor(successor, graph); - exception.setNext(end); - if (x instanceof Invoke) { - ((Invoke) x).setExceptionEdge(entry); - } else { - ((Throw) x).setExceptionEdge(entry); - } + currentNext.setNext(end); + return entry; } + return null; } private void genLoadConstant(int cpi) { @@ -608,11 +608,13 @@ } private void genThrow(int bci) { - FrameState stateBefore = frameState.create(bci); - Throw t = new Throw(frameState.apop(), graph); - t.setStateBefore(stateBefore); - appendWithBCI(t); - handleException(t, bci); + Value exception = frameState.apop(); + append(new NullCheck(exception, graph)); + Instruction entry = handleException(exception, bci); + if (entry == null) { + entry = new Unwind(exception, graph.end(), graph); + } + append(entry); } private void genCheckCast() { @@ -831,7 +833,7 @@ CiKind resultType = returnKind(target); Invoke invoke = new Invoke(bci(), opcode, resultType.stackKind(), args, target, target.signature().returnType(compilation.method.holder()), graph); Value result = appendWithBCI(invoke); - handleException(invoke, bci()); + invoke.setExceptionEdge(handleException(null, bci())); frameState.pushReturn(resultType, result); } @@ -1009,7 +1011,7 @@ } private Value appendWithBCI(Instruction x) { - assert x.next() == null && x.predecessors().size() == 0 : "instruction should not have been appended yet"; + assert x.predecessors().size() == 0 : "instruction should not have been appended yet"; assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; lastInstr.setNext(x); @@ -1153,7 +1155,7 @@ assert frameState.stackSize() == 1; if (block.handler.catchType().isResolved()) { - Instruction catchSuccessor = createTarget(block.handlerBlock, frameState); + Instruction catchSuccessor = createTarget(blockFromBci[block.handler.handlerBCI()], frameState); Instruction nextDispatch = createTarget(block.next, frameState); append(new ExceptionDispatch(frameState.stackAt(0), catchSuccessor, nextDispatch, block.handler.catchType(), graph)); } else { @@ -1468,17 +1470,6 @@ } /** - * Adds an exception handler. - * @param handler the handler to add - */ - private void addExceptionHandler(ExceptionHandler handler) { - if (exceptionHandlers == null) { - exceptionHandlers = new ArrayList<ExceptionHandler>(); - } - exceptionHandlers.add(handler); - } - - /** * Adds a block to the worklist, if it is not already in the worklist. * This method will keep the worklist topologically stored (i.e. the lower * DFNs are earlier in the list). @@ -1504,12 +1495,4 @@ private Block removeFromWorkList() { return workList.poll(); } - - /** - * Checks whether this graph has any handlers. - * @return {@code true} if there are any exception handlers - */ - private boolean hasHandler() { - return Modifier.isSynchronized(compilation.method.accessFlags()) || (compilation.method.exceptionHandlers() != null && compilation.method.exceptionHandlers().length > 0); - } }