diff graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java @ 5645:f53a347eae93

add inliningIdentifier to FrameState (fixes problem with duplicated FrameStates and locking)
author Lukas Stadler <lukas.stadler@jku.at>
date Mon, 18 Jun 2012 17:58:36 +0200
parents a9b615da0cba
children a65b2a11bf34
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Mon Jun 18 10:07:33 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java	Mon Jun 18 17:58:36 2012 +0200
@@ -37,6 +37,25 @@
  */
 public final class FrameState extends VirtualState implements Node.IterableNodeType, LIRLowerable {
 
+    /**
+     * An instance of this class is an identifier for all nodes that were generated by one specific inlining operation.
+     * It is used to generate the correct debug information for nested locks.
+     */
+    public static final class InliningIdentifier {
+        private final ResolvedJavaMethod method;
+        private final String context;
+
+        public InliningIdentifier(ResolvedJavaMethod method, String context) {
+            this.method = method;
+            this.context = context;
+        }
+
+        @Override
+        public String toString() {
+            return method + "@" + context;
+        }
+    }
+
     protected final int localsSize;
 
     protected final int stackSize;
@@ -46,6 +65,12 @@
     private boolean duringCall;
 
     /**
+     * This object identifies the concrete inlining operation that produced this frame state.
+     * It is set during inlining, therefore for the outermost frame states of a graph this field is null.
+     */
+    private InliningIdentifier inliningIdentifier;
+
+    /**
      * This BCI should be used for frame states that are built for code with no meaningful BCI.
      */
     public static final int UNKNOWN_BCI = -4;
@@ -92,7 +117,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(ResolvedJavaMethod method, int bci, List<ValueNode> values, int stackSize, boolean rethrowException, boolean duringCall, List<VirtualObjectState> virtualObjectMappings) {
+    public FrameState(ResolvedJavaMethod method, int bci, List<ValueNode> values, int stackSize, boolean rethrowException, boolean duringCall, InliningIdentifier inliningIdentifier, List<VirtualObjectState> virtualObjectMappings) {
         assert stackSize >= 0;
         assert (bci >= 0 && method != null) || (bci < 0 && method == null && values.isEmpty());
         this.method = method;
@@ -103,6 +128,7 @@
         this.virtualObjectMappings = new NodeInputList<>(this, virtualObjectMappings);
         this.rethrowException = rethrowException;
         this.duringCall = duringCall;
+        this.inliningIdentifier = inliningIdentifier;
         assert !rethrowException || stackSize == 1 : "must have exception on top of the stack";
     }
 
@@ -111,10 +137,10 @@
      * @param bci marker bci, needs to be < 0
      */
     public FrameState(int bci) {
-        this(null, bci, Collections.<ValueNode>emptyList(), 0, false, false, Collections.<VirtualObjectState>emptyList());
+        this(null, bci, Collections.<ValueNode>emptyList(), 0, false, false, null, Collections.<VirtualObjectState>emptyList());
     }
 
-    public FrameState(ResolvedJavaMethod method, int bci, ValueNode[] locals, ValueNode[] stack, int stackSize, boolean rethrowException, boolean duringCall) {
+    public FrameState(ResolvedJavaMethod method, int bci, ValueNode[] locals, ValueNode[] stack, int stackSize, boolean rethrowException, boolean duringCall, InliningIdentifier inliningIdentifier) {
         this.method = method;
         this.bci = bci;
         this.localsSize = locals.length;
@@ -132,6 +158,7 @@
         this.virtualObjectMappings = new NodeInputList<>(this);
         this.rethrowException = rethrowException;
         this.duringCall = duringCall;
+        this.inliningIdentifier = inliningIdentifier;
         assert !rethrowException || stackSize == 1 : "must have exception on top of the stack";
     }
 
@@ -148,6 +175,14 @@
         this.outerFrameState = x;
     }
 
+    public InliningIdentifier inliningIdentifier() {
+        return inliningIdentifier;
+    }
+
+    public void setInliningIdentifier(InliningIdentifier inliningIdentifier) {
+        this.inliningIdentifier = inliningIdentifier;
+    }
+
     public boolean rethrowException() {
         return rethrowException;
     }
@@ -176,7 +211,7 @@
         return virtualObjectMappings.get(i);
     }
 
-    public Iterable<VirtualObjectState> virtualObjectMappings() {
+    public NodeInputList<VirtualObjectState> virtualObjectMappings() {
         return virtualObjectMappings;
     }
 
@@ -184,7 +219,9 @@
      * Gets a copy of this frame state.
      */
     public FrameState duplicate(int newBci) {
-        return duplicate(newBci, false);
+        FrameState other = graph().add(new FrameState(method, newBci, values, stackSize, rethrowException, duringCall, inliningIdentifier, virtualObjectMappings));
+        other.setOuterFrameState(outerFrameState());
+        return other;
     }
 
     /**
@@ -194,12 +231,21 @@
         return duplicate(bci);
     }
 
-    public FrameState duplicate(int newBci, boolean duplicateOuter) {
-        FrameState other = graph().add(new FrameState(method, newBci, values, stackSize, rethrowException, duringCall, virtualObjectMappings));
+    /**
+     * Duplicates a FrameState, along with a deep copy of all connected VirtualState (outer FrameStates,
+     * VirtualObjectStates, ...).
+     */
+    @Override
+    public FrameState duplicateWithVirtualState() {
         FrameState newOuterFrameState = outerFrameState();
-        if (duplicateOuter && newOuterFrameState != null) {
-            newOuterFrameState = newOuterFrameState.duplicate(newOuterFrameState.bci, duplicateOuter);
+        if (newOuterFrameState != null) {
+            newOuterFrameState = newOuterFrameState.duplicateWithVirtualState();
         }
+        ArrayList<VirtualObjectState> newVirtualMappings = new ArrayList<>(virtualObjectMappings.size());
+        for (VirtualObjectState state : virtualObjectMappings) {
+            newVirtualMappings.add(state.duplicateWithVirtualState());
+        }
+        FrameState other = graph().add(new FrameState(method, bci, values, stackSize, rethrowException, duringCall, inliningIdentifier, newVirtualMappings));
         other.setOuterFrameState(newOuterFrameState);
         return other;
     }
@@ -221,7 +267,7 @@
         }
         Collections.addAll(copy, pushedValues);
 
-        FrameState other = graph().add(new FrameState(method, newBci, copy, copy.size() - localsSize, newRethrowException, false, virtualObjectMappings));
+        FrameState other = graph().add(new FrameState(method, newBci, copy, copy.size() - localsSize, newRethrowException, false, inliningIdentifier, virtualObjectMappings));
         other.setOuterFrameState(outerFrameState());
         return other;
     }
@@ -342,4 +388,14 @@
         }
         return super.verify();
     }
+
+    @Override
+    public void applyToNonVirtual(NodeClosure< ? super ValueNode> closure) {
+        for (ValueNode value : values.nonNull()) {
+            closure.apply(value);
+        }
+        for (VirtualObjectState state : virtualObjectMappings) {
+            state.applyToNonVirtual(closure);
+        }
+    }
 }