# HG changeset patch # User Thomas Wuerthinger # Date 1308417235 -7200 # Node ID 5857923e563cf7ea62f7faa3268fbaaf5d8cda90 # Parent b4ba003eb11df3f04874dfa02f7f91577c79dd17 Fixed an issue with frame states in exception dispatch chains (now we are correctly rethrowing the exception immediately at entering the interpreter). diff -r b4ba003eb11d -r 5857923e563c graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java Sat Jun 18 14:51:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompilation.java Sat Jun 18 19:13:55 2011 +0200 @@ -95,7 +95,7 @@ this.method = method; this.stats = stats == null ? new CiStatistics() : stats; this.registerConfig = method == null ? compiler.globalStubRegisterConfig : runtime.getRegisterConfig(method); - this.placeholderState = method != null && method.minimalDebugInfo() ? new FrameState(method, 0, 0, 0, 0, graph) : null; + this.placeholderState = method != null && method.minimalDebugInfo() ? new FrameState(method, 0, 0, 0, 0, false, graph) : null; if (compiler.isObserved()) { compiler.fireCompilationStarted(new CompilationEvent(this)); diff -r b4ba003eb11d -r 5857923e563c graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java Sat Jun 18 14:51:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java Sat Jun 18 19:13:55 2011 +0200 @@ -1914,7 +1914,7 @@ if (state.outerFrameState() != null) { caller = computeFrameForState(state.outerFrameState(), opId, frameRefMap); } - return new CiFrame(caller, state.method, state.bci, values, state.localsSize(), state.stackSize(), state.locksSize()); + return new CiFrame(caller, state.method, state.bci, state.rethrowException(), values, state.localsSize(), state.stackSize(), state.locksSize()); } private void computeDebugInfo(IntervalWalker iw, LIRInstruction op) { diff -r b4ba003eb11d -r 5857923e563c graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Sat Jun 18 14:51:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Sat Jun 18 19:13:55 2011 +0200 @@ -300,7 +300,7 @@ slot += arguments[arg].sizeInSlots(); } - FrameState fs = new FrameState(compilation.method, bci, compilation.method.maxLocals(), 0, 0, compilation.graph); + FrameState fs = new FrameState(compilation.method, bci, compilation.method.maxLocals(), 0, 0, false, compilation.graph); for (Node node : compilation.graph.start().usages()) { if (node instanceof Local) { Local local = (Local) node; @@ -534,7 +534,7 @@ } protected FrameState stateBeforeInvokeReturn(Invoke invoke) { - return invoke.stateAfter().duplicateModified(getBeforeInvokeBci(invoke), invoke.kind); + return invoke.stateAfter().duplicateModified(getBeforeInvokeBci(invoke), invoke.stateAfter().rethrowException(), invoke.kind); } protected FrameState stateBeforeInvokeWithArguments(Invoke invoke) { @@ -542,7 +542,7 @@ for (int i = 0; i < invoke.argumentCount(); i++) { args[i] = invoke.argument(i); } - return invoke.stateAfter().duplicateModified(getBeforeInvokeBci(invoke), invoke.kind, args); + return invoke.stateAfter().duplicateModified(getBeforeInvokeBci(invoke), invoke.stateAfter().rethrowException(), invoke.kind, args); } private int getBeforeInvokeBci(Invoke invoke) { diff -r b4ba003eb11d -r 5857923e563c graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java Sat Jun 18 14:51:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/BlockMap.java Sat Jun 18 19:13:55 2011 +0200 @@ -132,6 +132,7 @@ public static class ExceptionBlock extends Block { public RiExceptionHandler handler; public Block next; + public int deoptBci; } public static class DeoptBlock extends Block { @@ -157,6 +158,8 @@ private final RiMethod method; + private final RiExceptionHandler[] exceptionHandlers; + public final HashMap branchOverride; private Block[] blockMap; @@ -169,6 +172,7 @@ */ public BlockMap(RiMethod method) { this.method = method; + exceptionHandlers = method.exceptionHandlers(); this.blockMap = new Block[method.codeSize()]; if (method.exceptionHandlers().length != 0) { this.canTrap = new BitSet(blockMap.length); @@ -178,6 +182,10 @@ branchOverride = new HashMap(); } + public RiExceptionHandler[] exceptionHandlers() { + return exceptionHandlers; + } + /** * Builds the block map and conservative CFG and numbers blocks. */ @@ -202,7 +210,7 @@ private void makeExceptionEntries() { // start basic blocks at all exception handler blocks and mark them as exception entries - for (RiExceptionHandler h : method.exceptionHandlers()) { + for (RiExceptionHandler h : this.exceptionHandlers) { Block xhandler = makeBlock(h.handlerBCI()); xhandler.isExceptionEntry = true; } @@ -427,7 +435,7 @@ private ExceptionBlock unwindBlock; - private Block makeExceptionDispatch(List handlers, int index) { + private Block makeExceptionDispatch(List handlers, int index, int bci) { RiExceptionHandler handler = handlers.get(index); if (handler.isCatchAll()) { return blockMap[handler.handlerBCI()]; @@ -437,10 +445,11 @@ block = new ExceptionBlock(); block.startBci = -1; block.endBci = -1; + block.deoptBci = bci; block.handler = handler; block.successors.add(blockMap[handler.handlerBCI()]); if (index < handlers.size() - 1) { - block.next = makeExceptionDispatch(handlers, index + 1); + block.next = makeExceptionDispatch(handlers, index + 1, bci); block.successors.add(block.next); } exceptionDispatch.put(handler, block); @@ -457,7 +466,7 @@ Block block = blockMap[bci]; ArrayList handlers = null; - for (RiExceptionHandler h : method.exceptionHandlers()) { + for (RiExceptionHandler h : this.exceptionHandlers) { if (h.startBCI() <= bci && bci < h.endBCI()) { if (handlers == null) { handlers = new ArrayList(); @@ -469,7 +478,7 @@ } } if (handlers != null) { - Block dispatch = makeExceptionDispatch(handlers, 0); + Block dispatch = makeExceptionDispatch(handlers, 0, bci); block.successors.add(dispatch); } } diff -r b4ba003eb11d -r 5857923e563c graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Deoptimize.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Deoptimize.java Sat Jun 18 14:51:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Deoptimize.java Sat Jun 18 19:13:55 2011 +0200 @@ -39,6 +39,7 @@ InvalidateReprofile, // invalidate the nmethod, reset IC, maybe recompile InvalidateRecompile, // invalidate the nmethod, recompile (probably) InvalidateStopCompiling, // invalidate the nmethod and do not compile + RethrowExceptionInInterpreter, } private String message; diff -r b4ba003eb11d -r 5857923e563c graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java Sat Jun 18 14:51:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/DeadCodeEliminationPhase.java Sat Jun 18 19:13:55 2011 +0200 @@ -29,7 +29,6 @@ import com.oracle.max.graal.compiler.gen.*; import com.oracle.max.graal.compiler.ir.*; import com.oracle.max.graal.graph.*; -import com.sun.cri.ci.*; public class DeadCodeEliminationPhase extends Phase { diff -r b4ba003eb11d -r 5857923e563c graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Sat Jun 18 14:51:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/GraphBuilderPhase.java Sat Jun 18 19:13:55 2011 +0200 @@ -70,6 +70,7 @@ private final RiRuntime runtime; private final RiMethod method; private final RiConstantPool constantPool; + private RiExceptionHandler[] exceptionHandlers; private final BytecodeStream stream; // the bytecode stream private final LogStream log; @@ -152,6 +153,7 @@ BlockMap blockMap = compilation.getBlockMap(method); this.branchOverride = blockMap.branchOverride; + exceptionHandlers = blockMap.exceptionHandlers(); blockList = new ArrayList(blockMap.blocks); blockFromBci = new Block[method.codeSize()]; for (int i = 0; i < blockList.size(); i++) { @@ -285,6 +287,9 @@ assert first instanceof StateSplit; int bci = target.startBci; + if (target instanceof ExceptionBlock) { + bci = ((ExceptionBlock) target).deoptBci; + } FrameState existingState = ((StateSplit) first).stateAfter(); @@ -379,7 +384,6 @@ assert bci == Instruction.SYNCHRONIZATION_ENTRY_BCI || bci == bci() : "invalid bci"; RiExceptionHandler firstHandler = null; - RiExceptionHandler[] exceptionHandlers = method.exceptionHandlers(); // join with all potential exception handlers if (exceptionHandlers != null) { for (RiExceptionHandler handler : exceptionHandlers) { @@ -431,7 +435,7 @@ currentNext = exception; currentExceptionObject = exception; } - FrameState stateWithException = entryState.duplicateModified(bci, CiKind.Void, currentExceptionObject); + FrameState stateWithException = entryState.duplicateWithException(bci, currentExceptionObject); currentNext.setNext(createTarget(dispatchBlock, stateWithException)); return entry; @@ -1281,7 +1285,7 @@ assert frameState.stackSize() == 1 : "only exception object expected on stack, actual size: " + frameState.stackSize(); createUnwindBlock(block); } else { - assert frameState.stackSize() == 1; + assert frameState.stackSize() == 1 : frameState; Block nextBlock = block.next == null ? unwindBlock() : block.next; if (block.handler.catchType().isResolved()) { @@ -1289,7 +1293,7 @@ FixedNode nextDispatch = createTarget(nextBlock, frameState); append(new ExceptionDispatch(frameState.stackAt(0), catchSuccessor, nextDispatch, block.handler.catchType(), graph)); } else { - Deoptimize deopt = new Deoptimize(DeoptAction.InvalidateRecompile, graph); + Deoptimize deopt = new Deoptimize(DeoptAction.RethrowExceptionInInterpreter, graph); deopt.setMessage("unresolved " + block.handler.catchType().name()); append(deopt); // FixedNode nextDispatch = createTarget(nextBlock, frameState); diff -r b4ba003eb11d -r 5857923e563c graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Sat Jun 18 14:51:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Sat Jun 18 19:13:55 2011 +0200 @@ -411,7 +411,7 @@ // adjust all frame states that were copied if (frameStates.size() > 0) { - FrameState outerFrameState = stateAfter.duplicateModified(invoke.bci, invoke.kind); + FrameState outerFrameState = stateAfter.duplicateModified(invoke.bci, stateAfter.rethrowException(), invoke.kind); for (Node node : frameStates) { FrameState frameState = (FrameState) duplicates.get(node); if (!frameState.isDeleted()) { diff -r b4ba003eb11d -r 5857923e563c graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java Sat Jun 18 14:51:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java Sat Jun 18 19:13:55 2011 +0200 @@ -2087,6 +2087,9 @@ case InvalidateStopCompiling: code = 4; break; + case RethrowExceptionInInterpreter: + code = 5; + break; default: throw Util.shouldNotReachHere(); } diff -r b4ba003eb11d -r 5857923e563c graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java Sat Jun 18 14:51:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameState.java Sat Jun 18 19:13:55 2011 +0200 @@ -49,6 +49,8 @@ protected final int locksSize; + private final boolean rethrowException; + private static final int SUCCESSOR_COUNT = 0; @Override @@ -90,19 +92,20 @@ * @param stackSize size of the stack * @param lockSize number of locks */ - public FrameState(RiMethod method, int bci, int localsSize, int stackSize, int locksSize, Graph graph) { + public FrameState(RiMethod method, int bci, int localsSize, int stackSize, int locksSize, boolean rethrowException, Graph graph) { super(CiKind.Illegal, localsSize + stackSize + locksSize + INPUT_COUNT, SUCCESSOR_COUNT, graph); this.method = method; this.bci = bci; this.localsSize = localsSize; this.stackSize = stackSize; this.locksSize = locksSize; + this.rethrowException = rethrowException; GraalMetrics.FrameStatesCreated++; GraalMetrics.FrameStateValuesCreated += localsSize + stackSize + locksSize; } - FrameState(RiMethod method, int bci, Value[] locals, Value[] stack, int stackSize, ArrayList locks, Graph graph) { - this(method, bci, locals.length, stackSize, locks.size(), graph); + FrameState(RiMethod method, int bci, Value[] locals, Value[] stack, int stackSize, ArrayList locks, boolean rethrowException, Graph graph) { + this(method, bci, locals.length, stackSize, locks.size(), rethrowException, graph); for (int i = 0; i < locals.length; i++) { setValueAt(i, locals[i]); } @@ -114,6 +117,10 @@ } } + public boolean rethrowException() { + return rethrowException; + } + /** * Gets a copy of this frame state. */ @@ -128,7 +135,7 @@ */ @Override public FrameState duplicateWithEmptyStack(int bci) { - FrameState other = new FrameState(method, bci, localsSize, 0, locksSize(), graph()); + FrameState other = new FrameState(method, bci, localsSize, 0, locksSize(), rethrowException, graph()); for (int i = 0; i < localsSize; i++) { other.setValueAt(i, localAt(i)); } @@ -139,15 +146,19 @@ return other; } + public FrameState duplicateWithException(int bci, Value exceptionObject) { + return duplicateModified(bci, true, CiKind.Void, exceptionObject); + } + /** * Creates a copy of this frame state with one stack element of type popKind popped from the stack and the * values in pushedValues pushed on the stack. The pushedValues are expected to be in slot encoding: a long * or double is followed by a null slot. */ - public FrameState duplicateModified(int bci, CiKind popKind, Value... pushedValues) { + public FrameState duplicateModified(int bci, boolean rethrowException, CiKind popKind, Value... pushedValues) { int popSlots = popKind.sizeInSlots(); int pushSlots = pushedValues.length; - FrameState other = new FrameState(method, bci, localsSize, stackSize - popSlots + pushSlots, locksSize(), graph()); + FrameState other = new FrameState(method, bci, localsSize, stackSize - popSlots + pushSlots, locksSize(), rethrowException, graph()); for (int i = 0; i < localsSize; i++) { other.setValueAt(i, localAt(i)); } @@ -481,14 +492,9 @@ out.print("FrameState"); } - @Override - public FrameState copy() { - return new FrameState(method, bci, localsSize, stackSize, locksSize, graph()); - } - private FrameState copy(int newBci) { - return new FrameState(method, newBci, localsSize, stackSize, locksSize, graph()); + return new FrameState(method, newBci, localsSize, stackSize, locksSize, rethrowException, graph()); } @Override @@ -520,12 +526,12 @@ str.append(i == 0 ? "" : ", ").append(lockAt(i) == null ? "_" : lockAt(i).id()); } properties.put("locks", str.toString()); + properties.put("rethrowException", rethrowException); return properties; } @Override public Node copy(Graph into) { - FrameState x = new FrameState(method, bci, localsSize, stackSize, locksSize, into); - return x; + return new FrameState(method, bci, localsSize, stackSize, locksSize, rethrowException, into); } } diff -r b4ba003eb11d -r 5857923e563c graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java Sat Jun 18 14:51:18 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/value/FrameStateBuilder.java Sat Jun 18 19:13:55 2011 +0200 @@ -81,6 +81,11 @@ this.locks = new ArrayList(); } + @Override + public String toString() { + return String.format("FrameStateBuilder[stackSize=%d]", stackIndex); + } + public void initializeFrom(FrameState other) { assert locals.length == other.localsSize() : "expected: " + locals.length + ", actual: " + other.localsSize(); assert stack.length >= other.stackSize() : "expected: <=" + stack.length + ", actual: " + other.stackSize(); @@ -99,12 +104,12 @@ } public FrameState create(int bci) { - return new FrameState(method, bci, locals, stack, stackIndex, locks, graph); + return new FrameState(method, bci, locals, stack, stackIndex, locks, false, graph); } @Override public FrameState duplicateWithEmptyStack(int bci) { - FrameState frameState = new FrameState(method, bci, locals, new Value[0], 0, locks, graph); + FrameState frameState = new FrameState(method, bci, locals, new Value[0], 0, locks, false, graph); frameState.setOuterFrameState(outerFrameState()); return frameState; } diff -r b4ba003eb11d -r 5857923e563c graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java --- a/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java Sat Jun 18 14:51:18 2011 +0200 +++ b/graal/com.oracle.max.graal.graph/src/com/oracle/max/graal/graph/Node.java Sat Jun 18 19:13:55 2011 +0200 @@ -160,7 +160,7 @@ return true; } - public Node copy() { + public final Node copy() { return copy(graph); } diff -r b4ba003eb11d -r 5857923e563c graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotConstantPool.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotConstantPool.java Sat Jun 18 14:51:18 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotConstantPool.java Sat Jun 18 19:13:55 2011 +0200 @@ -128,7 +128,9 @@ RiType result = typeCache.get(cpi); if (result == null) { result = compiler.getVMEntries().RiConstantPool_lookupType(vmId, cpi); - typeCache.add(cpi, result); + if (result.isResolved()) { + typeCache.add(cpi, result); + } } return result; } diff -r b4ba003eb11d -r 5857923e563c graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java Sat Jun 18 14:51:18 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotMethodResolvedImpl.java Sat Jun 18 19:13:55 2011 +0200 @@ -80,10 +80,7 @@ @Override public RiExceptionHandler[] exceptionHandlers() { - if (exceptionHandlers == null) { - exceptionHandlers = compiler.getVMEntries().RiMethod_exceptionHandlers(this); - } - return exceptionHandlers; + return compiler.getVMEntries().RiMethod_exceptionHandlers(this); } @Override diff -r b4ba003eb11d -r 5857923e563c src/share/vm/c1/c1_IR.hpp --- a/src/share/vm/c1/c1_IR.hpp Sat Jun 18 14:51:18 2011 +0200 +++ b/src/share/vm/c1/c1_IR.hpp Sat Jun 18 19:13:55 2011 +0200 @@ -237,7 +237,7 @@ // reexecute allowed only for the topmost frame bool reexecute = topmost ? should_reexecute() : false; bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis. - recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, is_method_handle_invoke, return_oop, locvals, expvals, monvals); + recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, false, is_method_handle_invoke, return_oop, locvals, expvals, monvals); } }; diff -r b4ba003eb11d -r 5857923e563c src/share/vm/c1/c1_LIRAssembler.cpp --- a/src/share/vm/c1/c1_LIRAssembler.cpp Sat Jun 18 14:51:18 2011 +0200 +++ b/src/share/vm/c1/c1_LIRAssembler.cpp Sat Jun 18 19:13:55 2011 +0200 @@ -405,7 +405,7 @@ if (s == NULL) break; IRScope* scope = s->scope(); //Always pass false for reexecute since these ScopeDescs are never used for deopt - debug_info->describe_scope(pc_offset, scope->method(), s->bci(), false/*reexecute*/); + debug_info->describe_scope(pc_offset, scope->method(), s->bci(), false/*reexecute*/, false/*rethrow_exception*/); } debug_info->end_non_safepoint(pc_offset); diff -r b4ba003eb11d -r 5857923e563c src/share/vm/code/debugInfoRec.cpp --- a/src/share/vm/code/debugInfoRec.cpp Sat Jun 18 14:51:18 2011 +0200 +++ b/src/share/vm/code/debugInfoRec.cpp Sat Jun 18 19:13:55 2011 +0200 @@ -283,6 +283,7 @@ ciMethod* method, int bci, bool reexecute, + bool rethrow_exception, bool is_method_handle_invoke, bool return_oop, DebugToken* locals, @@ -298,6 +299,7 @@ // Record flags into pcDesc. last_pd->set_should_reexecute(reexecute); + last_pd->set_rethrow_exception(rethrow_exception); last_pd->set_is_method_handle_invoke(is_method_handle_invoke); last_pd->set_return_oop(return_oop); diff -r b4ba003eb11d -r 5857923e563c src/share/vm/code/debugInfoRec.hpp --- a/src/share/vm/code/debugInfoRec.hpp Sat Jun 18 14:51:18 2011 +0200 +++ b/src/share/vm/code/debugInfoRec.hpp Sat Jun 18 19:13:55 2011 +0200 @@ -101,6 +101,7 @@ ciMethod* method, int bci, bool reexecute, + bool rethrow_exception, bool is_method_handle_invoke = false, bool return_oop = false, DebugToken* locals = NULL, diff -r b4ba003eb11d -r 5857923e563c src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Sat Jun 18 14:51:18 2011 +0200 +++ b/src/share/vm/code/nmethod.cpp Sat Jun 18 19:13:55 2011 +0200 @@ -1079,7 +1079,7 @@ PcDesc* pd = pc_desc_at(pc); guarantee(pd != NULL, "scope must be present"); return new ScopeDesc(this, pd->scope_decode_offset(), - pd->obj_decode_offset(), pd->should_reexecute(), + pd->obj_decode_offset(), pd->should_reexecute(), pd->rethrow_exception(), pd->return_oop()); } @@ -2267,7 +2267,7 @@ PcDesc* pd = pc_desc_at(ic->end_of_call()); assert(pd != NULL, "PcDesc must exist"); for (ScopeDesc* sd = new ScopeDesc(this, pd->scope_decode_offset(), - pd->obj_decode_offset(), pd->should_reexecute(), + pd->obj_decode_offset(), pd->should_reexecute(), pd->rethrow_exception(), pd->return_oop()); !sd->is_top(); sd = sd->sender()) { sd->verify(); @@ -2533,7 +2533,7 @@ PcDesc* p = pc_desc_near(begin+1); if (p != NULL && p->real_pc(this) <= end) { return new ScopeDesc(this, p->scope_decode_offset(), - p->obj_decode_offset(), p->should_reexecute(), + p->obj_decode_offset(), p->should_reexecute(), p->rethrow_exception(), p->return_oop()); } return NULL; diff -r b4ba003eb11d -r 5857923e563c src/share/vm/code/pcDesc.hpp --- a/src/share/vm/code/pcDesc.hpp Sat Jun 18 14:51:18 2011 +0200 +++ b/src/share/vm/code/pcDesc.hpp Sat Jun 18 19:13:55 2011 +0200 @@ -43,6 +43,7 @@ int word; struct { unsigned int reexecute: 1; + unsigned int rethrow_exception: 1; unsigned int is_method_handle_invoke: 1; unsigned int return_oop: 1; } bits; @@ -71,6 +72,8 @@ // Flags bool should_reexecute() const { return _flags.bits.reexecute; } void set_should_reexecute(bool z) { _flags.bits.reexecute = z; } + bool rethrow_exception() const { return _flags.bits.rethrow_exception; } + void set_rethrow_exception(bool z) { _flags.bits.rethrow_exception = z; } // Does pd refer to the same information as pd? bool is_same_info(const PcDesc* pd) { diff -r b4ba003eb11d -r 5857923e563c src/share/vm/code/scopeDesc.cpp --- a/src/share/vm/code/scopeDesc.cpp Sat Jun 18 14:51:18 2011 +0200 +++ b/src/share/vm/code/scopeDesc.cpp Sat Jun 18 19:13:55 2011 +0200 @@ -31,21 +31,23 @@ #include "runtime/handles.inline.hpp" -ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop) { +ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool rethrow_exception, bool return_oop) { _code = code; _decode_offset = decode_offset; _objects = decode_object_values(obj_decode_offset); _reexecute = reexecute; _return_oop = return_oop; + _rethrow_exception = rethrow_exception; decode_body(); } -ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool return_oop) { +ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool rethrow_exception, bool return_oop) { _code = code; _decode_offset = decode_offset; _objects = decode_object_values(DebugInformationRecorder::serialized_null); _reexecute = reexecute; _return_oop = return_oop; + _rethrow_exception = rethrow_exception; decode_body(); } @@ -55,6 +57,7 @@ _decode_offset = parent->_sender_decode_offset; _objects = parent->_objects; _reexecute = false; //reexecute only applies to the first scope + _rethrow_exception = false; _return_oop = false; decode_body(); } diff -r b4ba003eb11d -r 5857923e563c src/share/vm/code/scopeDesc.hpp --- a/src/share/vm/code/scopeDesc.hpp Sat Jun 18 14:51:18 2011 +0200 +++ b/src/share/vm/code/scopeDesc.hpp Sat Jun 18 19:13:55 2011 +0200 @@ -60,17 +60,18 @@ class ScopeDesc : public ResourceObj { public: // Constructor - ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop); + ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool rethrow_exception, bool return_oop); // Calls above, giving default value of "serialized_null" to the // "obj_decode_offset" argument. (We don't use a default argument to // avoid a .hpp-.hpp dependency.) - ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool return_oop); + ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool rethrow_exception, bool return_oop); // JVM state methodHandle method() const { return _method; } int bci() const { return _bci; } bool should_reexecute() const { return _reexecute; } + bool rethrow_exception() const { return _rethrow_exception; } bool return_oop() const { return _return_oop; } GrowableArray* locals(); @@ -97,6 +98,7 @@ methodHandle _method; int _bci; bool _reexecute; + bool _rethrow_exception; bool _return_oop; // Decoding offsets diff -r b4ba003eb11d -r 5857923e563c src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Sat Jun 18 14:51:18 2011 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Sat Jun 18 19:13:55 2011 +0200 @@ -496,9 +496,14 @@ DebugToken* expressions_token = _debug_recorder->create_scope_values(expressions); DebugToken* monitors_token = _debug_recorder->create_monitor_values(monitors); - _debug_recorder->describe_scope(pc_offset, cimethod, bci, reexecute, false, false, locals_token, expressions_token, monitors_token); + bool throw_exception = false; + if (CiFrame::rethrowException(frame)) { + throw_exception = true; + } + + _debug_recorder->describe_scope(pc_offset, cimethod, bci, reexecute, throw_exception, false, false, locals_token, expressions_token, monitors_token); } else { - _debug_recorder->describe_scope(pc_offset, cimethod, bci, reexecute, false, false, NULL, NULL, NULL); + _debug_recorder->describe_scope(pc_offset, cimethod, bci, reexecute, false, false, false, NULL, NULL, NULL); } } diff -r b4ba003eb11d -r 5857923e563c src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Sat Jun 18 14:51:18 2011 +0200 +++ b/src/share/vm/graal/graalJavaAccess.hpp Sat Jun 18 19:13:55 2011 +0200 @@ -153,6 +153,7 @@ int_field(CiFrame, numLocals) \ int_field(CiFrame, numStack) \ int_field(CiFrame, numLocks) \ + boolean_field(CiFrame, rethrowException) \ end_class \ start_class(CiCodePos) \ oop_field(CiCodePos, caller, "Lcom/sun/cri/ci/CiCodePos;") \ diff -r b4ba003eb11d -r 5857923e563c src/share/vm/prims/jvmtiCodeBlobEvents.cpp --- a/src/share/vm/prims/jvmtiCodeBlobEvents.cpp Sat Jun 18 14:51:18 2011 +0200 +++ b/src/share/vm/prims/jvmtiCodeBlobEvents.cpp Sat Jun 18 19:13:55 2011 +0200 @@ -251,7 +251,7 @@ address scopes_data = nm->scopes_data_begin(); for( pcd = nm->scopes_pcs_begin(); pcd < nm->scopes_pcs_end(); ++pcd ) { - ScopeDesc sc0(nm, pcd->scope_decode_offset(), pcd->should_reexecute(), pcd->return_oop()); + ScopeDesc sc0(nm, pcd->scope_decode_offset(), pcd->should_reexecute(), pcd->rethrow_exception(), pcd->return_oop()); ScopeDesc *sd = &sc0; while( !sd->is_top() ) { sd = sd->sender(); } int bci = sd->bci(); diff -r b4ba003eb11d -r 5857923e563c src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Sat Jun 18 14:51:18 2011 +0200 +++ b/src/share/vm/runtime/deoptimization.cpp Sat Jun 18 19:13:55 2011 +0200 @@ -1239,6 +1239,15 @@ int trap_bci = trap_scope->bci(); Bytecodes::Code trap_bc = trap_method->java_code_at(trap_bci); + if (trap_scope->rethrow_exception()) { + tty->print_cr("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Exception to be rethrown in the interpreter"); + GrowableArray* expressions = trap_scope->expressions(); + ScopeValue* topOfStack = expressions->top(); + Handle topOfStackObj = cvf->create_stack_value(topOfStack)->get_obj(); + topOfStackObj->print(); + THREAD->set_pending_exception(topOfStackObj(), NULL, 0); + } + // Record this event in the histogram. gather_statistics(reason, action, trap_bc); @@ -1407,6 +1416,7 @@ reprofile = true; break; case Action_make_not_entrant: + case Action_rethrow_exception_in_interpreter: // Request immediate recompilation, and get rid of the old code. // Make them not entrant, so next time they are called they get // recompiled. Unloaded classes are loaded now so recompile before next diff -r b4ba003eb11d -r 5857923e563c src/share/vm/runtime/deoptimization.hpp --- a/src/share/vm/runtime/deoptimization.hpp Sat Jun 18 14:51:18 2011 +0200 +++ b/src/share/vm/runtime/deoptimization.hpp Sat Jun 18 19:13:55 2011 +0200 @@ -72,6 +72,7 @@ Action_reinterpret, // invalidate the nmethod, reset IC, maybe recompile Action_make_not_entrant, // invalidate the nmethod, recompile (probably) Action_make_not_compilable, // invalidate the nmethod and do not compile + Action_rethrow_exception_in_interpreter, Action_LIMIT // Note: Keep this enum in sync. with _trap_action_name. }; diff -r b4ba003eb11d -r 5857923e563c src/share/vm/runtime/vframe_hp.hpp --- a/src/share/vm/runtime/vframe_hp.hpp Sat Jun 18 14:51:18 2011 +0200 +++ b/src/share/vm/runtime/vframe_hp.hpp Sat Jun 18 19:13:55 2011 +0200 @@ -66,7 +66,7 @@ // Returns SynchronizationEntryBCI or bci() (used for synchronization) int raw_bci() const; - protected: + //protected: ScopeDesc* _scope;