# HG changeset patch # User Thomas Wuerthinger # Date 1330029839 -3600 # Node ID a03f3fd16b22cef04a84d3aecb2d8d7389855dd0 # Parent 74c0b866fe8dd413eec5ac4dab1bce2996e91be3 Fix reexecute boolean in HotSpot debug information. Introduce "duringCall" flag in FrameState that indicates that the bci of the frame state denotes an invoke that should *not* be reexecuted. diff -r 74c0b866fe8d -r a03f3fd16b22 graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiFrame.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiFrame.java Thu Feb 23 12:06:39 2012 +0100 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiFrame.java Thu Feb 23 21:43:59 2012 +0100 @@ -67,6 +67,8 @@ public final boolean rethrowException; + public final boolean duringCall; + /** * Creates a new frame object. * @@ -79,7 +81,7 @@ * @param numStack the depth of the stack * @param numLocks the number of locked objects */ - public CiFrame(CiFrame caller, RiResolvedMethod method, int bci, boolean rethrowException, CiValue[] values, int numLocals, int numStack, int numLocks) { + public CiFrame(CiFrame caller, RiResolvedMethod method, int bci, boolean rethrowException, boolean duringCall, CiValue[] values, int numLocals, int numStack, int numLocks) { super(caller, method, bci); assert values != null; this.rethrowException = rethrowException; @@ -87,6 +89,7 @@ this.numLocks = numLocks; this.numLocals = numLocals; this.numStack = numStack; + this.duringCall = duringCall; assert !rethrowException || numStack == 1 : "must have exception on top of the stack"; } diff -r 74c0b866fe8d -r a03f3fd16b22 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/DebugInfoBuilder.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/DebugInfoBuilder.java Thu Feb 23 12:06:39 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/DebugInfoBuilder.java Thu Feb 23 21:43:59 2012 +0100 @@ -135,7 +135,7 @@ throw new CiBailout("unbalanced monitors: found monitor for unknown frame"); } } - CiFrame frame = new CiFrame(caller, state.method(), state.bci, state.rethrowException(), values, state.localsSize(), state.stackSize(), numLocks); + CiFrame frame = new CiFrame(caller, state.method(), state.bci, state.rethrowException(), state.duringCall(), values, state.localsSize(), state.stackSize(), numLocks); return frame; } diff -r 74c0b866fe8d -r a03f3fd16b22 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InsertStateAfterPlaceholderPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InsertStateAfterPlaceholderPhase.java Thu Feb 23 12:06:39 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InsertStateAfterPlaceholderPhase.java Thu Feb 23 21:43:59 2012 +0100 @@ -30,7 +30,7 @@ protected void run(StructuredGraph graph) { for (ReturnNode ret : graph.getNodes(ReturnNode.class)) { PlaceholderNode p = graph.add(new PlaceholderNode()); - p.setStateAfter(graph.add(new FrameState(null, FrameState.AFTER_BCI, 0, 0, false))); + p.setStateAfter(graph.add(new FrameState(null, FrameState.AFTER_BCI, 0, 0, false, false))); graph.addBeforeFixed(ret, p); } } diff -r 74c0b866fe8d -r a03f3fd16b22 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java Thu Feb 23 12:06:39 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java Thu Feb 23 21:43:59 2012 +0100 @@ -859,6 +859,7 @@ } else { if (outerFrameState == null) { outerFrameState = stateAfter.duplicateModified(invoke.bci(), stateAfter.rethrowException(), invoke.node().kind()); + outerFrameState.setDuringCall(true); } frameState.setOuterFrameState(outerFrameState); } diff -r 74c0b866fe8d -r a03f3fd16b22 graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/FrameStateBuilder.java --- a/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/FrameStateBuilder.java Thu Feb 23 12:06:39 2012 +0100 +++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/FrameStateBuilder.java Thu Feb 23 21:43:59 2012 +0100 @@ -108,11 +108,11 @@ } public FrameState create(int bci) { - return graph.add(new FrameState(method, bci, locals, stack, stackIndex, rethrowException)); + return graph.add(new FrameState(method, bci, locals, stack, stackIndex, rethrowException, false)); } public FrameState duplicateWithException(int bci, ValueNode exceptionObject) { - FrameState frameState = graph.add(new FrameState(method, bci, locals, new ValueNode[]{exceptionObject}, 1, true)); + FrameState frameState = graph.add(new FrameState(method, bci, locals, new ValueNode[]{exceptionObject}, 1, true, false)); frameState.setOuterFrameState(outerFrameState()); return frameState; } @@ -464,7 +464,7 @@ } public FrameState duplicateWithoutStack(int bci) { - FrameState frameState = graph.add(new FrameState(method, bci, locals, new ValueNode[0], 0, false)); + FrameState frameState = graph.add(new FrameState(method, bci, locals, new ValueNode[0], 0, false, false)); frameState.setOuterFrameState(outerFrameState()); return frameState; } diff -r 74c0b866fe8d -r a03f3fd16b22 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FrameState.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FrameState.java Thu Feb 23 12:06:39 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FrameState.java Thu Feb 23 21:43:59 2012 +0100 @@ -44,6 +44,8 @@ private boolean rethrowException; + private boolean duringCall; + /** * This BCI should be used for frame states that are built for code with no meaningful BCI. */ @@ -92,7 +94,7 @@ * @param stackSize size of the stack * @param rethrowException if true the VM should re-throw the exception on top of the stack when deopt'ing using this framestate */ - public FrameState(RiResolvedMethod method, int bci, int localsSize, int stackSize, boolean rethrowException) { + public FrameState(RiResolvedMethod method, int bci, int localsSize, int stackSize, boolean rethrowException, boolean duringCall) { assert stackSize >= 0; this.method = method; this.bci = bci; @@ -101,10 +103,11 @@ this.values = new NodeInputList<>(this, localsSize + stackSize); this.virtualObjectMappings = new NodeInputList<>(this); this.rethrowException = rethrowException; + this.duringCall = duringCall; assert !rethrowException || stackSize == 1 : "must have exception on top of the stack"; } - public FrameState(RiResolvedMethod method, int bci, ValueNode[] locals, ValueNode[] stack, int stackSize, boolean rethrowException) { + public FrameState(RiResolvedMethod method, int bci, ValueNode[] locals, ValueNode[] stack, int stackSize, boolean rethrowException, boolean duringCall) { this.method = method; this.bci = bci; this.localsSize = locals.length; @@ -119,6 +122,7 @@ this.values = new NodeInputList<>(this, newValues); this.virtualObjectMappings = new NodeInputList<>(this); this.rethrowException = rethrowException; + this.duringCall = duringCall; assert !rethrowException || stackSize == 1 : "must have exception on top of the stack"; } @@ -147,6 +151,14 @@ return rethrowException; } + public boolean duringCall() { + return duringCall; + } + + public void setDuringCall(boolean b) { + this.duringCall = b; + } + public RiResolvedMethod method() { return method; } @@ -176,7 +188,7 @@ } public FrameState duplicate(int newBci, boolean duplicateOuter) { - FrameState other = graph().add(new FrameState(method, newBci, localsSize, stackSize, rethrowException)); + FrameState other = graph().add(new FrameState(method, newBci, localsSize, stackSize, rethrowException, duringCall)); other.values.setAll(values); other.virtualObjectMappings.setAll(virtualObjectMappings); FrameState newOuterFrameState = outerFrameState(); @@ -200,7 +212,7 @@ public FrameState duplicateModified(int newBci, boolean newRethrowException, CiKind popKind, ValueNode... pushedValues) { int popSlots = popKind == CiKind.Void ? 0 : isTwoSlot(popKind) ? 2 : 1; int pushSlots = pushedValues.length; - FrameState other = graph().add(new FrameState(method, newBci, localsSize, stackSize - popSlots + pushSlots, newRethrowException)); + FrameState other = graph().add(new FrameState(method, newBci, localsSize, stackSize - popSlots + pushSlots, newRethrowException, false)); for (int i = 0; i < localsSize; i++) { other.setValueAt(i, localAt(i)); } @@ -599,6 +611,7 @@ } properties.put("stack", str.toString()); properties.put("rethrowException", rethrowException); + properties.put("duringCall", duringCall); return properties; } diff -r 74c0b866fe8d -r a03f3fd16b22 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/InvokeNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/InvokeNode.java Thu Feb 23 12:06:39 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/InvokeNode.java Thu Feb 23 21:43:59 2012 +0100 @@ -108,7 +108,9 @@ @Override public FrameState stateDuring() { FrameState stateAfter = stateAfter(); - return stateAfter.duplicateModified(bci(), stateAfter.rethrowException(), this.callTarget.targetMethod().signature().returnKind(false)); + FrameState stateDuring = stateAfter.duplicateModified(bci(), stateAfter.rethrowException(), this.callTarget.targetMethod().signature().returnKind(false)); + stateDuring.setDuringCall(true); + return stateDuring; } @Override diff -r 74c0b866fe8d -r a03f3fd16b22 graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/InvokeWithExceptionNode.java --- a/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/InvokeWithExceptionNode.java Thu Feb 23 12:06:39 2012 +0100 +++ b/graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/InvokeWithExceptionNode.java Thu Feb 23 21:43:59 2012 +0100 @@ -126,7 +126,10 @@ } public FrameState stateDuring() { - return stateAfter().duplicateModified(bci(), stateAfter().rethrowException(), this.callTarget.targetMethod().signature().returnKind(false)); + FrameState stateAfter = stateAfter(); + FrameState stateDuring = stateAfter.duplicateModified(bci(), stateAfter.rethrowException(), this.callTarget.targetMethod().signature().returnKind(false)); + stateDuring.setDuringCall(true); + return stateDuring; } @Override diff -r 74c0b866fe8d -r a03f3fd16b22 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Thu Feb 23 12:06:39 2012 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Thu Feb 23 21:43:59 2012 +0100 @@ -486,6 +486,9 @@ } else { Bytecodes::Code code = Bytecodes::java_code_at(method, method->bcp_from(bci)); reexecute = Interpreter::bytecode_should_reexecute(code); + if (frame != NULL) { + reexecute = (CiFrame::duringCall(frame) == 0); + } } if (TraceGraal >= 2) { diff -r 74c0b866fe8d -r a03f3fd16b22 src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Thu Feb 23 12:06:39 2012 +0100 +++ b/src/share/vm/graal/graalJavaAccess.hpp Thu Feb 23 21:43:59 2012 +0100 @@ -168,6 +168,7 @@ int_field(CiFrame, numStack) \ int_field(CiFrame, numLocks) \ boolean_field(CiFrame, rethrowException) \ + boolean_field(CiFrame, duringCall) \ end_class \ start_class(CiCodePos) \ oop_field(CiCodePos, caller, "Lcom/oracle/max/cri/ci/CiCodePos;") \ diff -r 74c0b866fe8d -r a03f3fd16b22 src/share/vm/interpreter/interpreter.cpp --- a/src/share/vm/interpreter/interpreter.cpp Thu Feb 23 12:06:39 2012 +0100 +++ b/src/share/vm/interpreter/interpreter.cpp Thu Feb 23 21:43:59 2012 +0100 @@ -367,6 +367,26 @@ return Interpreter::deopt_entry(vtos, 0); } +#ifdef GRAAL + + +// If deoptimization happens, the interpreter should reexecute these bytecodes. +// This function mainly helps the compilers to set up the reexecute bit. +bool AbstractInterpreter::bytecode_should_reexecute(Bytecodes::Code code) { + switch (code) { + case Bytecodes::_invokedynamic: + case Bytecodes::_invokevirtual: + case Bytecodes::_invokeinterface: + case Bytecodes::_invokespecial: + case Bytecodes::_invokestatic: + return false; + default: + return true; + } + return true; +} +#else + // If deoptimization happens, the interpreter should reexecute these bytecodes. // This function mainly helps the compilers to set up the reexecute bit. bool AbstractInterpreter::bytecode_should_reexecute(Bytecodes::Code code) { @@ -415,6 +435,7 @@ return false; } } +#endif void AbstractInterpreterGenerator::bang_stack_shadow_pages(bool native_call) { // Quick & dirty stack overflow checking: bang the stack & handle trap. diff -r 74c0b866fe8d -r a03f3fd16b22 src/share/vm/runtime/vframeArray.cpp --- a/src/share/vm/runtime/vframeArray.cpp Thu Feb 23 12:06:39 2012 +0100 +++ b/src/share/vm/runtime/vframeArray.cpp Thu Feb 23 21:43:59 2012 +0100 @@ -130,6 +130,7 @@ bool rethrow_exception = vf->scope()->rethrow_exception(); if (rethrow_exception) { // (tw) Make sure there are only null pointers on the stack, because the stack values do not correspond to the GC map at the bytecode at which the exception is rethrown. + // TODO: Fix this! Locals map might be wrong too. _expressions = new StackValueCollection(vf->method()->max_stack()); assert(Thread::current()->has_pending_exception(), "just checking"); for (int i=0; imethod()->max_stack(); ++i) { @@ -261,6 +262,7 @@ case Deoptimization::Unpack_uncommon_trap: case Deoptimization::Unpack_reexecute: // redo last byte code + assert(should_reexecute(), ""); pc = Interpreter::deopt_entry(vtos, 0); use_next_mdp = false; break;