changeset 6444:5ebe3e5a892b

fix bailouts due to insufficient balanced monitor checks
author Lukas Stadler <lukas.stadler@jku.at>
date Wed, 26 Sep 2012 12:15:52 +0200
parents 5b419d76b406
children a2299c2fc0c6
files graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java
diffstat 2 files changed, 31 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Sep 25 09:28:03 2012 -0700
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Sep 26 12:15:52 2012 +0200
@@ -1005,7 +1005,7 @@
     }
 
     private MonitorEnterNode genMonitorEnter(ValueNode x) {
-        frameState.pushLock(GraphUtil.originalValue(x));
+        frameState.pushLock(x);
         MonitorEnterNode monitorEnter = currentGraph.add(new MonitorEnterNode(x));
         appendWithBCI(monitorEnter);
         return monitorEnter;
@@ -1013,8 +1013,8 @@
 
     private MonitorExitNode genMonitorExit(ValueNode x) {
         ValueNode lockedObject = frameState.popLock();
-        if (lockedObject != GraphUtil.originalValue(x)) {
-            throw new BailoutException("unbalanced monitors: mismatch at monitorexit %s %s", GraphUtil.originalValue(x), lockedObject);
+        if (GraphUtil.originalValue(lockedObject) != GraphUtil.originalValue(x)) {
+            throw new BailoutException("unbalanced monitors: mismatch at monitorexit, %s != %s", GraphUtil.originalValue(x), GraphUtil.originalValue(lockedObject));
         }
         MonitorExitNode monitorExit = currentGraph.add(new MonitorExitNode(x));
         appendWithBCI(monitorExit);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Tue Sep 25 09:28:03 2012 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Wed Sep 26 12:15:52 2012 +0200
@@ -237,22 +237,42 @@
         return str.toString();
     }
 
+    /**
+     * Tries to find an original value of the given node by traversing through proxies and unambiguous phis.
+     *
+     * @param proxy The node whose original value should be determined.
+     */
     public static ValueNode originalValue(ValueNode proxy) {
         ValueNode v = proxy;
         do {
             if (v instanceof ValueProxyNode) {
                 v = ((ValueProxyNode) v).value();
-                continue;
+            } else if (v instanceof PhiNode) {
+                v = ((PhiNode) v).singleValue();
+            } else {
+                break;
             }
-            if (v instanceof PhiNode) {
-                ValueNode singleValue = ((PhiNode) v).singleValue();
-                if (singleValue != null) {
-                    v = singleValue;
-                    continue;
+        } while (v != null);
+
+        // if the simple check fails (this can happen for complicated phi/proxy/phi constructs), we do an exhaustive search
+        if (v == null) {
+            NodeWorkList worklist = proxy.graph().createNodeWorkList();
+            worklist.add(proxy);
+            for (Node node : worklist) {
+                if (node instanceof ValueProxyNode) {
+                    worklist.add(((ValueProxyNode) node).value());
+                } else if (node instanceof PhiNode) {
+                    worklist.addAll(((PhiNode) node).values());
+                } else {
+                    if (v == null) {
+                        v = (ValueNode) node;
+                    } else {
+                        return null;
+                    }
                 }
             }
-            break;
-        } while (true);
+        }
         return v;
     }
+
 }