Mercurial > hg > graal-compiler
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; } + }