# HG changeset patch # User Lukas Stadler # Date 1306841865 -7200 # Node ID c1c8a0291771049bb06094878c27aea432b790c3 # Parent bfce42cd9c076c67e5db2ad94046131f392e406b# Parent 1cd59ca9ac862b9272cfe9e901d2508c19b3df4c merge diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/oracle/max/graal/schedule/Block.java --- a/graal/GraalCompiler/src/com/oracle/max/graal/schedule/Block.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/oracle/max/graal/schedule/Block.java Tue May 31 13:37:45 2011 +0200 @@ -34,7 +34,6 @@ private final List successors = new ArrayList(); private final List predecessors = new ArrayList(); private List instructions = new ArrayList(); - private boolean exceptionEntry; private Block dominator; private final List dominators = new ArrayList(); @@ -93,14 +92,6 @@ return blockID; } - public void setExceptionEntry(boolean b) { - exceptionEntry = b; - } - - public boolean isExceptionEntry() { - return exceptionEntry; - } - /** * Iterate over this block, its exception handlers, and its successors, in that order. * diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/oracle/max/graal/schedule/Schedule.java --- a/graal/GraalCompiler/src/com/oracle/max/graal/schedule/Schedule.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/oracle/max/graal/schedule/Schedule.java Tue May 31 13:37:45 2011 +0200 @@ -86,7 +86,7 @@ } public static boolean isBlockEnd(Node n) { - return trueSuccessorCount(n) > 1 || n instanceof Anchor || n instanceof Return || n instanceof Throw; + return trueSuccessorCount(n) > 1 || n instanceof Anchor || n instanceof Return || n instanceof Unwind; } private void identifyBlocks() { @@ -128,7 +128,6 @@ // We have a single predecessor => check its successor count. if (isBlockEnd(singlePred)) { Block b = assignBlock(n); - b.setExceptionEntry(singlePred instanceof Throw); blockBeginNodes.add(n); } else { assignBlock(n, nodeToBlock.get(singlePred)); @@ -395,9 +394,6 @@ for (Block b : blocks) { TTY.println(); TTY.print(b.toString()); - if (b.isExceptionEntry()) { - TTY.print(" (ex)"); - } TTY.print(" succs="); for (Block succ : b.getSuccessors()) { diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/alloc/LinearScan.java --- a/graal/GraalCompiler/src/com/sun/c1x/alloc/LinearScan.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/alloc/LinearScan.java Tue May 31 13:37:45 2011 +0200 @@ -746,8 +746,6 @@ // Perform a backward dataflow analysis to compute liveOut and liveIn for each block. // The loop is executed until a fixpoint is reached (no changes in an iteration) - // Exception handlers must be processed because not all live values are - // present in the state array, e.g. because of global value numbering do { changeOccurred = false; @@ -1181,14 +1179,6 @@ final int blockFrom = block.firstLirInstructionId(); int blockTo = block.lastLirInstructionId(); - // (tw) Destroy all registers on exception handler entry. - if (block.isExceptionEntry()) { - for (CiRegister r : callerSaveRegs) { - if (attributes(r).isAllocatable) { - addTemp(r.asValue(), block.firstLirInstructionId(), RegisterPriority.None, CiKind.Illegal); - } - } - } assert blockFrom == instructions.get(0).id; assert blockTo == instructions.get(instructions.size() - 1).id; @@ -1292,23 +1282,6 @@ addRegisterHints(op); } // end of instruction iteration - - - // (tw) TODO: Check if this matters.. - // (tw) Make sure that no spill store optimization is applied for phi instructions that flow into exception handlers. -// if (block.isExceptionEntry()) { -// Instruction firstInstruction = block.getInstructions().get(0); -// for (Node n : firstInstruction.usages()) { -// if (n instanceof Phi) { -// Phi phi = (Phi) n; -// Interval interval = intervalFor(phi.operand()); -// if (interval != null) { -// interval.setSpillState(SpillState.NoOptimization); -// } -// } -// } -// } - } // end of block iteration // add the range [0, 1] to all fixed intervals. @@ -1999,13 +1972,6 @@ } if (op.info != null) { - // exception handling -// if (compilation.hasExceptionHandlers()) { -// if (op.exceptionEdge() != null && op.exceptionEdge().lir() != null) { -// assignLocations(op.exceptionEdge().lir().instructionsList(), iw); -// } -// } - // compute reference map and debug information computeDebugInfo(iw, op); } diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/alloc/RegisterVerifier.java --- a/graal/GraalCompiler/src/com/sun/c1x/alloc/RegisterVerifier.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/alloc/RegisterVerifier.java Tue May 31 13:37:45 2011 +0200 @@ -101,7 +101,7 @@ } while (!workList.isEmpty()); } - void processBlock(LIRBlock block) { + private void processBlock(LIRBlock block) { if (C1XOptions.TraceLinearScanLevel >= 2) { TTY.println(); TTY.println("processBlock B%d", block.blockID()); @@ -133,21 +133,7 @@ } } - void processXhandler(LIRBlock xhandler, Interval[] inputState) { - if (C1XOptions.TraceLinearScanLevel >= 2) { - TTY.println("processXhandler B%d", xhandler.blockID()); - } - - // must copy state because it is modified - inputState = copy(inputState); - - if (xhandler.lir() != null) { - processOperations(xhandler.lir(), inputState); - } - processSuccessor(xhandler, inputState); - } - - void processSuccessor(LIRBlock block, Interval[] inputState) { + private void processSuccessor(LIRBlock block, Interval[] inputState) { Interval[] savedState = stateForBlock(block); if (savedState != null) { @@ -258,11 +244,6 @@ } } - // process xhandler before output and temp operands - if (op.exceptionEdge() != null) { - processXhandler(op.exceptionEdge(), inputState); - } - // set temp operands (some operations use temp operands also as output operands, so can't set them null) n = op.operandCount(LIRInstruction.OperandMode.Temp); for (int j = 0; j < n; j++) { diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/asm/TargetMethodAssembler.java --- a/graal/GraalCompiler/src/com/sun/c1x/asm/TargetMethodAssembler.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/asm/TargetMethodAssembler.java Tue May 31 13:37:45 2011 +0200 @@ -140,11 +140,11 @@ public void recordExceptionHandlers(int pcOffset, LIRDebugInfo info) { if (info != null) { - if (info.exceptionEdge != null) { + if (info.exceptionEdge() != null) { if (exceptionInfoList == null) { exceptionInfoList = new ArrayList(4); } - exceptionInfoList.add(new ExceptionInfo(pcOffset, info.exceptionEdge, info.state.bci)); + exceptionInfoList.add(new ExceptionInfo(pcOffset, info.exceptionEdge(), info.state.bci)); } } } @@ -155,7 +155,7 @@ assert lastSafepointPos < pcOffset; lastSafepointPos = pcOffset; targetMethod.recordSafepoint(pcOffset, info.debugInfo()); - recordExceptionHandlers(pcOffset, info); + assert info.exceptionEdge() == null; } } diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java --- a/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java Tue May 31 13:37:45 2011 +0200 @@ -216,7 +216,7 @@ public final LIRDebugInfo info; public DeoptimizationStub(FrameState state) { - info = new LIRDebugInfo(state, null); + info = new LIRDebugInfo(state); } } @@ -477,6 +477,9 @@ RiMethod target = x.target(); LIRDebugInfo info = stateFor(x, stateBeforeInvokeWithArguments(x)); LIRDebugInfo info2 = stateFor(x, stateBeforeInvokeReturn(x)); + if (x.exceptionEdge() != null) { + info2.setExceptionEdge(getLIRBlock(x.exceptionEdge())); + } XirSnippet snippet = null; @@ -880,20 +883,6 @@ } @Override - public void visitThrow(Throw x) { - setNoResult(x); - CiValue exceptionOpr = load(x.exception()); - LIRDebugInfo info = stateFor(x, x.stateBefore()); - - // move exception oop into fixed register - CiCallingConvention callingConvention = compilation.frameMap().getCallingConvention(new CiKind[]{CiKind.Object}, RuntimeCall); - CiValue argumentOperand = callingConvention.locations[0]; - lir.move(exceptionOpr, argumentOperand); - - lir.throwException(CiValue.IllegalValue, argumentOperand, info); - } - - @Override public void visitDeoptimize(Deoptimize deoptimize) { DeoptimizationStub stub = new DeoptimizationStub(lastState); addDeoptimizationStub(stub); @@ -1488,16 +1477,7 @@ if (compilation.placeholderState != null) { state = compilation.placeholderState; } - - assert state != null; - LIRBlock exceptionEdge = null; - if (x instanceof ExceptionEdgeInstruction) { - Instruction begin = ((ExceptionEdgeInstruction) x).exceptionEdge(); - if (begin != null) { - exceptionEdge = getLIRBlock(begin); - } - } - return new LIRDebugInfo(state, exceptionEdge); + return new LIRDebugInfo(state); } List visitInvokeArguments(CiCallingConvention cc, Invoke x, List pointerSlots) { diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/graph/BlockMap.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/BlockMap.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/BlockMap.java Tue May 31 13:37:45 2011 +0200 @@ -131,7 +131,6 @@ public static class ExceptionBlock extends Block { public RiExceptionHandler handler; public Block next; - public Block handlerBlock; } private static final Block[] NO_SUCCESSORS = new Block[0]; @@ -423,7 +422,6 @@ 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); diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java --- 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 blockList; + private Block syncBlock; + private CiExceptionHandler syncHandler; + // the constant pool private final RiConstantPool constantPool; @@ -79,9 +82,6 @@ } }); - // Exception handler list - private List 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(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(); - } - 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); - } } diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/graph/IR.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java Tue May 31 13:37:45 2011 +0200 @@ -96,7 +96,6 @@ Map map = new HashMap(); for (Block b : blocks) { LIRBlock block = new LIRBlock(b.blockID()); - block.setExceptionEntry(b.isExceptionEntry()); map.put(b, block); block.setInstructions(b.getInstructions()); block.setLinearScanNumber(b.blockID()); @@ -108,11 +107,7 @@ for (Block b : blocks) { for (Block succ : b.getSuccessors()) { - if (succ.isExceptionEntry()) { - map.get(b).getExceptionHandlerSuccessors().add(map.get(succ)); - } else { - map.get(b).blockSuccessors().add(map.get(succ)); - } + map.get(b).blockSuccessors().add(map.get(succ)); } for (Block pred : b.getPredecessors()) { @@ -120,16 +115,10 @@ } } - - // TODO(tw): Schedule nodes within a block. - - CriticalEdgeFinder finder = new CriticalEdgeFinder(lirBlocks, compilation.graph); finder.splitCriticalEdges(); - orderedBlocks = lirBlocks; - valueToBlock = new HashMap(); for (LIRBlock b : orderedBlocks) { for (Node i : b.getInstructions()) { diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/ir/ComputeLinearScanOrder.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/ComputeLinearScanOrder.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ComputeLinearScanOrder.java Tue May 31 13:37:45 2011 +0200 @@ -162,16 +162,6 @@ cur.setBackwardBranchTarget(true); parent.setLinearScanLoopEnd(); - // When a loop header is also the start of an exception handler, then the backward branch is - // an exception edge. Because such edges are usually critical edges which cannot be split, the - // loop must be excluded here from processing. - if (cur.isExceptionEntry()) { - // Make sure that dominators are correct in this weird situation - iterativeDominators = true; - return; - } -// assert parent.numberOfSux() == 1 && parent.suxAt(0) == cur : "loop end blocks must have one successor (critical edges are split)"; - loopEndBlocks.add(parent); return; } @@ -195,9 +185,6 @@ for (i = cur.numberOfSux() - 1; i >= 0; i--) { countEdges(cur.suxAt(i), cur); } - for (LIRBlock ex : cur.getExceptionHandlerSuccessors()) { - countEdges(ex, cur); - } clearActive(cur); @@ -328,9 +315,6 @@ for (i = cur.numberOfSux() - 1; i >= 0; i--) { workList.add(cur.suxAt(i)); } - for (LIRBlock ex : cur.getExceptionHandlerSuccessors()) { - workList.add(ex); - } } } while (!workList.isEmpty()); } @@ -380,10 +364,10 @@ // curBit--; // exceptions handlers are added as late as possible - if (!cur.isExceptionEntry()) { - weight |= 1 << curBit; - } - curBit--; +// if (!cur.isExceptionEntry()) { +// weight |= 1 << curBit; +// } +// curBit--; // guarantee that weight is > 0 weight |= 1; @@ -488,11 +472,6 @@ sortIntoWorkList(sux); } } - for (LIRBlock ex : cur.getExceptionHandlerSuccessors()) { - if (readyForProcessing(ex)) { - sortIntoWorkList(ex); - } - } } while (workList.size() > 0); } @@ -513,7 +492,6 @@ for (LIRBlock cur : linearScanOrder) { TTY.print(String.format("%4d: B%02d loop: %2d depth: %2d", cur.linearScanNumber(), cur.blockID(), cur.loopIndex(), cur.loopDepth())); - TTY.print(cur.isExceptionEntry() ? " ex" : " "); TTY.print(cur.isLinearScanLoopHeader() ? " lh" : " "); TTY.print(cur.isLinearScanLoopEnd() ? " le" : " "); diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionHandler.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/ExceptionHandler.java Tue May 31 13:34:52 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.sun.c1x.ir; - -import java.util.*; - -import com.sun.c1x.graph.*; -import com.sun.c1x.lir.*; -import com.sun.cri.ri.*; - -/** - * The {@code ExceptionHandler} class represents an exception handler for a Java bytecode method. - * There is exactly one instance of this class for every exception handler without any specific - * reference to an exception-throwing instruction covered by the handler. Then there is one - * instance per exception-throwing instruction that is used to record the frame state before - * execution of the instruction. The latter is used to generate exception adapter blocks - * (see section 3.4 of the paper - * Optimized Interval Splitting in a Linear Scan Register Allocator) where necessary. - */ -public final class ExceptionHandler { - - public static final List ZERO_HANDLERS = Collections.emptyList(); - - public final RiExceptionHandler handler; - private BlockMap.Block entryBlock; - private LIRList entryCode; - private int entryCodeOffset; - private int phiOperand; - private int lirOpId; - - public ExceptionHandler(RiExceptionHandler handler) { - this.handler = handler; - this.entryCodeOffset = -1; - this.phiOperand = -1; - this.lirOpId = -1; - } - - public ExceptionHandler(ExceptionHandler other) { - this.handler = other.handler; - this.entryBlock = other.entryBlock; - this.entryCode = other.entryCode; - this.entryCodeOffset = other.entryCodeOffset; - this.phiOperand = other.phiOperand; - this.lirOpId = other.lirOpId; - } - - @Override - public String toString() { - return "XHandler(Block=" + entryBlock.blockID + ") " + handler; - } - - /** - * Gets the compiler interface object that describes this exception handler, - * including the bytecode ranges. - * @return the compiler interface exception handler - */ - public RiExceptionHandler handler() { - return handler; - } - - /** - * Gets the bytecode index of the handler (catch block). - * @return the bytecode index of the handler - */ - public int handlerBCI() { - return handler.handlerBCI(); - } - - /** - * Utility method to check if this exception handler covers the specified bytecode index. - * @param bci the bytecode index to check - * @return {@code true} if this exception handler covers the specified bytecode - */ - public boolean covers(int bci) { - return handler.startBCI() <= bci && bci < handler.endBCI(); - } - - /** - * Gets the entry block for this exception handler. - * @return the entry block - */ - public BlockMap.Block entryBlock() { - return entryBlock; - } - - /** - * Gets the PC offset of the handler entrypoint, which is used by - * the runtime to forward exception points to their catch sites. - * @return the pc offset of the handler entrypoint - */ - public int entryCodeOffset() { - return entryCodeOffset; - } - - public int phiOperand() { - return phiOperand; - } - - public void setEntryBlock(BlockMap.Block entry) { - entryBlock = entry; - } - - public void setEntryCodeOffset(int pco) { - entryCodeOffset = pco; - } - - public void setPhiOperand(int phi) { - phiOperand = phi; - } - - public boolean isCatchAll() { - return handler.catchTypeCPI() == 0; - } - - public static boolean couldCatch(List exceptionHandlers, RiType klass, boolean typeIsExact) { - // the type is unknown so be conservative - if (!klass.isResolved()) { - return true; - } - - for (int i = 0; i < exceptionHandlers.size(); i++) { - ExceptionHandler handler = exceptionHandlers.get(i); - if (handler.isCatchAll()) { - // catch of ANY - return true; - } - RiType handlerKlass = handler.handler.catchType(); - // if it's unknown it might be catchable - if (!handlerKlass.isResolved()) { - return true; - } - // if the throw type is definitely a subtype of the catch type - // then it can be caught. - if (klass.isSubtypeOf(handlerKlass)) { - return true; - } - if (!typeIsExact) { - // If the type isn't exactly known then it can also be caught by - // catch statements where the inexact type is a subtype of the - // catch type. - // given: foo extends bar extends Exception - // throw bar can be caught by catch foo, catch bar, and catch - // Exception, however it can't be caught by any handlers without - // bar in its type hierarchy. - if (handlerKlass.isSubtypeOf(klass)) { - return true; - } - } - } - return false; - } - - public int lirOpId() { - return lirOpId; - } - - public LIRList entryCode() { - return entryCode; - } - - public void setLirOpId(int throwingOpId) { - lirOpId = throwingOpId; - } - - public void setEntryCode(LIRList entryCode) { - this.entryCode = entryCode; - - } -} diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/ir/NullCheck.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/NullCheck.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/NullCheck.java Tue May 31 13:37:45 2011 +0200 @@ -32,7 +32,7 @@ /** * The {@code NullCheck} class represents an explicit null check instruction. */ -public final class NullCheck extends Value { +public final class NullCheck extends Instruction { private static final int INPUT_COUNT = 1; private static final int INPUT_OBJECT = 0; diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/ir/Throw.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/Throw.java Tue May 31 13:34:52 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.sun.c1x.ir; - -import com.oracle.graal.graph.*; -import com.sun.c1x.debug.*; -import com.sun.c1x.value.*; -import com.sun.cri.ci.*; - -/** - * The {@code Throw} instruction represents a throw of an exception. - */ -public final class Throw extends BlockEnd implements ExceptionEdgeInstruction { - - private static final int INPUT_COUNT = 2; - private static final int INPUT_EXCEPTION = 0; - private static final int INPUT_STATE_BEFORE = 1; - - private static final int SUCCESSOR_COUNT = 1; - private static final int SUCCESSOR_EXCEPTION_EDGE = 0; - - @Override - protected int inputCount() { - return super.inputCount() + INPUT_COUNT; - } - - @Override - protected int successorCount() { - return super.successorCount() + SUCCESSOR_COUNT; - } - - /** - * The instruction which produces the exception to throw. - */ - public Value exception() { - return (Value) inputs().get(super.inputCount() + INPUT_EXCEPTION); - } - - public Value setException(Value n) { - return (Value) inputs().set(super.inputCount() + INPUT_EXCEPTION, n); - } - - /** - * The state for this instruction. - */ - public FrameState stateBefore() { - return (FrameState) inputs().get(super.inputCount() + INPUT_STATE_BEFORE); - } - - public FrameState setStateBefore(FrameState n) { - return (FrameState) inputs().set(super.inputCount() + INPUT_STATE_BEFORE, n); - } - - /** - * The entry to the exception dispatch chain for this throw. - * TODO ls: this needs more cleanup - throw should either unwind or jump to the exception dispatch chain - */ - @Override - public Instruction exceptionEdge() { - return (Instruction) successors().get(super.successorCount() + SUCCESSOR_EXCEPTION_EDGE); - } - - public Instruction setExceptionEdge(Instruction n) { - return (Instruction) successors().set(super.successorCount() + SUCCESSOR_EXCEPTION_EDGE, n); - } - - /** - * Creates a new Throw instruction. - * @param exception the instruction that generates the exception to throw - * @param stateAfter the state before the exception is thrown but after the exception object has been popped - * @param graph - */ - public Throw(Value exception, Graph graph) { - super(CiKind.Illegal, 0, INPUT_COUNT, SUCCESSOR_COUNT, graph); - setException(exception); - } - - @Override - public void accept(ValueVisitor v) { - v.visitThrow(this); - } - - @Override - public void print(LogStream out) { - out.print("throw ").print(exception()); - } - - @Override - public Node copy(Graph into) { - Throw x = new Throw(null, into); - x.setNonNull(isNonNull()); - return x; - } -} diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/ir/ValueVisitor.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/ValueVisitor.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ValueVisitor.java Tue May 31 13:37:45 2011 +0200 @@ -66,7 +66,6 @@ public abstract void visitStoreField(StoreField i); public abstract void visitStoreIndexed(StoreIndexed i); public abstract void visitTableSwitch(TableSwitch i); - public abstract void visitThrow(Throw i); public abstract void visitDeoptimize(Deoptimize deoptimize); public abstract void visitExceptionDispatch(ExceptionDispatch exceptionDispatch); public abstract void visitUnwind(Unwind unwind); diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/lir/LIRAssembler.java --- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRAssembler.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRAssembler.java Tue May 31 13:37:45 2011 +0200 @@ -311,10 +311,6 @@ emitLogicOp(op.code, op.operand1(), op.operand2(), op.result()); break; - case Throw: - emitThrow(op.operand1(), op.operand2(), op.info); - break; - default: throw Util.shouldNotReachHere(); } @@ -407,8 +403,6 @@ protected abstract void emitVolatileMove(CiValue inOpr, CiValue result, CiKind kind, LIRDebugInfo info); - protected abstract void emitThrow(CiValue inOpr1, CiValue inOpr2, LIRDebugInfo info); - protected abstract void emitLogicOp(LIROpcode code, CiValue inOpr1, CiValue inOpr2, CiValue dst); protected abstract void emitIntrinsicOp(LIROpcode code, CiValue inOpr1, CiValue inOpr2, CiValue dst, LIROp2 op); diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java --- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRBlock.java Tue May 31 13:37:45 2011 +0200 @@ -44,7 +44,6 @@ private List instructions = new ArrayList(4); private List predecessors = new ArrayList(4); private List successors = new ArrayList(4); - private List exceptionHandlerSuccessors = new ArrayList(4); /** * Bit map specifying which {@linkplain OperandPool operands} are live upon entry to this block. @@ -79,10 +78,6 @@ private int lastLirInstructionID; public int blockEntryPco; - public List getExceptionHandlerSuccessors() { - return exceptionHandlerSuccessors; - } - public LIRBlock(int blockID) { this.blockID = blockID; loopIndex = -1; @@ -190,18 +185,8 @@ private int linearScanNumber = -1; private boolean linearScanLoopEnd; private boolean linearScanLoopHeader; - private boolean exceptionEntry; private boolean backwardBranchTarget; - - public void setExceptionEntry(boolean b) { - this.exceptionEntry = b; - } - - public boolean isExceptionEntry() { - return exceptionEntry; - } - public void setBackwardBranchTarget(boolean b) { this.backwardBranchTarget = b; } diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/lir/LIRDebugInfo.java --- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRDebugInfo.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRDebugInfo.java Tue May 31 13:37:45 2011 +0200 @@ -37,12 +37,19 @@ } public final FrameState state; - public final LIRBlock exceptionEdge; + private LIRBlock exceptionEdge; public CiDebugInfo debugInfo; - public LIRDebugInfo(FrameState state, LIRBlock exceptionEdge) { + public LIRDebugInfo(FrameState state) { assert state != null; this.state = state; + } + + public LIRBlock exceptionEdge() { + return exceptionEdge; + } + + public void setExceptionEdge(LIRBlock exceptionEdge) { this.exceptionEdge = exceptionEdge; } diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/lir/LIRInstruction.java --- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRInstruction.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRInstruction.java Tue May 31 13:37:45 2011 +0200 @@ -482,7 +482,7 @@ } public final LIRBlock exceptionEdge() { - return (info == null) ? null : info.exceptionEdge; + return (info == null) ? null : info.exceptionEdge(); } @Override diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/lir/LIRList.java --- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIRList.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIRList.java Tue May 31 13:37:45 2011 +0200 @@ -172,10 +172,6 @@ append(new LIROp1(LIROpcode.NullCheck, opr, info)); } - public void throwException(CiValue exceptionPC, CiValue exceptionOop, LIRDebugInfo info) { - append(new LIROp2(LIROpcode.Throw, exceptionPC, exceptionOop, CiValue.IllegalValue, info, CiKind.Illegal, true)); - } - public void compareTo(CiValue left, CiValue right, CiValue dst) { append(new LIROp2(LIROpcode.CompareTo, left, right, dst)); } diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/lir/LIROpcode.java --- a/graal/GraalCompiler/src/com/sun/c1x/lir/LIROpcode.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/lir/LIROpcode.java Tue May 31 13:37:45 2011 +0200 @@ -77,7 +77,6 @@ Shl, Shr, Ushr, - Throw, CompareTo, EndOp2, BeginOp3, diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRAssembler.java --- a/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRAssembler.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRAssembler.java Tue May 31 13:37:45 2011 +0200 @@ -1397,16 +1397,6 @@ indirectCall(reg, null, null); } - @Override - protected void emitThrow(CiValue exceptionPC, CiValue exceptionOop, LIRDebugInfo info) { - // exception object is not added to oop map by LinearScan - // (LinearScan assumes that no oops are in fixed registers) - // info.addRegisterOop(exceptionOop); - directCall(CiRuntimeCall.HandleException, info); - // enough room for two byte trap - shouldNotReachHere(); - } - private void emitXIRShiftOp(LIROpcode code, CiValue left, CiValue count, CiValue dest) { if (count.isConstant()) { emitShiftOp(code, left, ((CiConstant) count).asInt(), dest); diff -r bfce42cd9c07 -r c1c8a0291771 graal/GraalGraph/src/com/oracle/graal/graph/Node.java --- a/graal/GraalGraph/src/com/oracle/graal/graph/Node.java Tue May 31 13:34:52 2011 +0200 +++ b/graal/GraalGraph/src/com/oracle/graal/graph/Node.java Tue May 31 13:37:45 2011 +0200 @@ -80,6 +80,10 @@ return graph; } + public T lookup(Class clazz) { + return null; + } + public String shortName() { return getClass().getSimpleName(); }