Mercurial > hg > graal-jvmci-8
changeset 12417:0b71e8b6418c
preliminary fix for MonitorExitNodes with AFTER_BCI
author | Lukas Stadler <lukas.stadler@jku.at> |
---|---|
date | Tue, 15 Oct 2013 11:31:23 +0200 |
parents | 9ad59f7fd57e |
children | 8c53ba3efbc9 |
files | graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java |
diffstat | 2 files changed, 29 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Mon Oct 14 19:46:29 2013 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Oct 15 11:31:23 2013 +0200 @@ -1218,12 +1218,12 @@ return monitorEnter; } - private MonitorExitNode genMonitorExit(ValueNode x) { + private MonitorExitNode genMonitorExit(ValueNode x, ValueNode returnValue) { ValueNode lockedObject = frameState.popLock(); 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 = append(new MonitorExitNode(x, frameState.lockDepth())); + MonitorExitNode monitorExit = append(new MonitorExitNode(x, returnValue, frameState.lockDepth())); return monitorExit; } @@ -1619,7 +1619,7 @@ assert frameState.stackSize() == 1 : frameState; ValueNode exception = frameState.apop(); append(new FixedGuardNode(currentGraph.unique(new IsNullNode(exception)), NullCheckException, InvalidateReprofile, true)); - synchronizedEpilogue(FrameState.AFTER_EXCEPTION_BCI); + synchronizedEpilogue(FrameState.AFTER_EXCEPTION_BCI, null); append(new UnwindNode(exception)); } @@ -1628,7 +1628,7 @@ ValueNode x = returnKind == Kind.Void ? null : frameState.pop(returnKind); assert frameState.stackSize() == 0; - synchronizedEpilogue(FrameState.AFTER_BCI); + synchronizedEpilogue(FrameState.AFTER_BCI, x); if (frameState.lockDepth() != 0) { throw new BailoutException("unbalanced monitors"); } @@ -1640,9 +1640,9 @@ append(new ReturnNode(x)); } - private void synchronizedEpilogue(int bci) { + private void synchronizedEpilogue(int bci, ValueNode returnValue) { if (Modifier.isSynchronized(method.getModifiers())) { - MonitorExitNode monitorExit = genMonitorExit(methodSynchronizedObject); + MonitorExitNode monitorExit = genMonitorExit(methodSynchronizedObject, returnValue); monitorExit.setStateAfter(frameState.create(bci)); assert !frameState.rethrowException(); } @@ -2002,7 +2002,7 @@ case CHECKCAST : genCheckCast(); break; case INSTANCEOF : genInstanceOf(); break; case MONITORENTER : genMonitorEnter(frameState.apop()); break; - case MONITOREXIT : genMonitorExit(frameState.apop()); break; + case MONITOREXIT : genMonitorExit(frameState.apop(), null); break; case MULTIANEWARRAY : genNewMultiArray(stream.readCPI()); break; case IFNULL : genIfNull(Condition.EQ); break; case IFNONNULL : genIfNull(Condition.NE); break;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Mon Oct 14 19:46:29 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Tue Oct 15 11:31:23 2013 +0200 @@ -34,17 +34,24 @@ public final class MonitorExitNode extends AccessMonitorNode implements Virtualizable, Lowerable, IterableNodeType, MonitorExit, MemoryCheckpoint.Single, MonitorReference { private int lockDepth; + @Input private ValueNode escapedReturnValue; /** * Creates a new MonitorExitNode. * * @param object the instruction produces the object value */ - public MonitorExitNode(ValueNode object, int lockDepth) { + public MonitorExitNode(ValueNode object, ValueNode escapedReturnValue, int lockDepth) { super(object); + this.escapedReturnValue = escapedReturnValue; this.lockDepth = lockDepth; } + public void setEscapedReturnValue(ValueNode x) { + updateUsages(escapedReturnValue, x); + this.escapedReturnValue = x; + } + @Override public LocationIdentity getLocationIdentity() { return LocationIdentity.ANY_LOCATION; @@ -65,11 +72,20 @@ @Override public void virtualize(VirtualizerTool tool) { - State state = tool.getObjectState(object()); - if (state != null && state.getState() == EscapeState.Virtual && state.getVirtualObject().hasIdentity()) { - int removedLock = state.removeLock(); - assert removedLock == getLockDepth(); - tool.delete(); + /* + * The last MonitorExitNode of a synchronized method cannot be removed anyway, and we need + * it to materialize the return value. + * + * TODO: replace this with correct handling of AFTER_BCI frame states in the runtime. + */ + if (stateAfter().bci != FrameState.AFTER_BCI) { + setEscapedReturnValue(null); + State state = tool.getObjectState(object()); + if (state != null && state.getState() == EscapeState.Virtual && state.getVirtualObject().hasIdentity()) { + int removedLock = state.removeLock(); + assert removedLock == getLockDepth(); + tool.delete(); + } } } }