changeset 4678:a03f3fd16b22

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.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Thu, 23 Feb 2012 21:43:59 +0100
parents 74c0b866fe8d
children 7406229b269f
files graal/com.oracle.max.cri/src/com/oracle/max/cri/ci/CiFrame.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/DebugInfoBuilder.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InsertStateAfterPlaceholderPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/InliningUtil.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/FrameStateBuilder.java graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/FrameState.java graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/InvokeNode.java graal/com.oracle.max.graal.nodes/src/com/oracle/max/graal/nodes/InvokeWithExceptionNode.java src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalJavaAccess.hpp src/share/vm/interpreter/interpreter.cpp src/share/vm/runtime/vframeArray.cpp
diffstat 12 files changed, 61 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- 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";
     }
 
--- 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;
     }
 
--- 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);
         }
     }
--- 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);
                 }
--- 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;
     }
--- 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;
     }
 
--- 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
--- 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
--- 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) {
--- 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;")                   \
--- 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.
--- 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; i<vf->method()->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;