# HG changeset patch # User Lukas Stadler # Date 1348654552 -7200 # Node ID 5ebe3e5a892bfc00335d1ee6592c91a60554751c # Parent 5b419d76b406c0e02ffa377015b554a792c3ed62 fix bailouts due to insufficient balanced monitor checks diff -r 5b419d76b406 -r 5ebe3e5a892b graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- 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); diff -r 5b419d76b406 -r 5ebe3e5a892b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java --- 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; } + }