# HG changeset patch # User Doug Simon # Date 1347527137 -7200 # Node ID 9b6b8626983a27989ca91d94f1556a8b6ea128ab # Parent e957c9ff0bda4b51c5240b23494d52b194477d04 factored out access to LIRGenerator lock scope for external use in LIR lowering diff -r e957c9ff0bda -r 9b6b8626983a graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Thu Sep 13 10:53:41 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Thu Sep 13 11:05:37 2012 +0200 @@ -120,9 +120,9 @@ for (int i = numLocks - 1; i >= 0; i--) { assert locks != null && nextLock.inliningIdentifier == state.inliningIdentifier() && nextLock.stateDepth == i; - Value owner = toValue(nextLock.monitor.object()); - Value lockData = nextLock.lockData; - boolean eliminated = nextLock.monitor.eliminated(); + Value owner = toValue(nextLock.object); + StackSlot lockData = nextLock.lockData; + boolean eliminated = nextLock.eliminated; values[numLocals + numStack + nextLock.stateDepth] = new MonitorValue(owner, lockData, eliminated); nextLock = nextLock.outer; diff -r e957c9ff0bda -r 9b6b8626983a graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Thu Sep 13 10:53:41 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Thu Sep 13 11:05:37 2012 +0200 @@ -107,19 +107,25 @@ public final int stateDepth; /** - * The monitor enter node, with information about the object that is locked and the elimination status. + * The object that is locked. */ - public final MonitorEnterNode monitor; + public final ValueNode object; + + /** + * Whether or not the lock is eliminated. + */ + public final boolean eliminated; /** * Space in the stack frame needed by the VM to perform the locking. */ public final StackSlot lockData; - public LockScope(LockScope outer, InliningIdentifier inliningIdentifier, MonitorEnterNode monitor, StackSlot lockData) { + public LockScope(LockScope outer, InliningIdentifier inliningIdentifier, ValueNode object, boolean eliminated, StackSlot lockData) { this.outer = outer; this.inliningIdentifier = inliningIdentifier; - this.monitor = monitor; + this.object = object; + this.eliminated = eliminated; this.lockData = lockData; if (outer != null && outer.inliningIdentifier == inliningIdentifier) { this.stateDepth = outer.stateDepth + 1; @@ -127,6 +133,23 @@ this.stateDepth = 0; } } + + @Override + public String toString() { + InliningIdentifier identifier = inliningIdentifier; + StringBuilder sb = new StringBuilder().append(identifier).append(": "); + for (LockScope scope = this; scope != null; scope = scope.outer) { + if (scope.inliningIdentifier != identifier) { + identifier = scope.inliningIdentifier; + sb.append('\n').append(identifier).append(": "); + } + if (scope.eliminated) { + sb.append('!'); + } + sb.append(scope.object).append(' '); + } + return sb.toString(); + } } /** @@ -526,13 +549,30 @@ setResult(x, operand(x.object())); } + public void lock(ValueNode object, boolean eliminated, StackSlot lock, InliningIdentifier inliningIdentifier) { + assert lastState != null : "must have state before instruction"; + curLocks = new LockScope(curLocks, inliningIdentifier, object, eliminated, lock); + } + + public StackSlot peekLock() { + assert curLocks.lockData != null; + return curLocks.lockData; + } + + public void unlock(ValueNode object, boolean eliminated) { + if (curLocks == null || curLocks.object != object || curLocks.eliminated != eliminated) { + throw new BailoutException("unbalanced monitors: attempting to unlock an object that is not on top of the locking stack"); + } + curLocks = curLocks.outer; + } + @Override public void visitMonitorEnter(MonitorEnterNode x) { StackSlot lockData = frameMap.allocateStackBlock(runtime.sizeOfLockData(), false); if (x.eliminated()) { // No code is emitted for eliminated locks, but for proper debug information generation we need to // register the monitor and its lock data. - curLocks = new LockScope(curLocks, x.stateAfter().inliningIdentifier(), x, lockData); + lock(x.object(), true, lockData, x.stateAfter().inliningIdentifier()); return; } @@ -541,7 +581,7 @@ LIRFrameState stateBefore = state(); // The state before the monitor enter is used for null checks, so it must not contain the newly locked object. - curLocks = new LockScope(curLocks, x.stateAfter().inliningIdentifier(), x, lockData); + lock(x.object(), false, lockData, x.stateAfter().inliningIdentifier()); // The state after the monitor enter is used for deoptimization, after the monitor has blocked, so it must contain the newly locked object. LIRFrameState stateAfter = stateFor(x.stateAfter(), -1); @@ -551,20 +591,17 @@ @Override public void visitMonitorExit(MonitorExitNode x) { - if (curLocks == null || curLocks.monitor.object() != x.object() || curLocks.monitor.eliminated() != x.eliminated()) { - throw new BailoutException("unbalanced monitors: attempting to unlock an object that is not on top of the locking stack"); - } if (x.eliminated()) { - curLocks = curLocks.outer; + unlock(x.object(), true); return; } - StackSlot lockData = curLocks.lockData; + Value lockData = peekLock(); XirArgument obj = toXirArgument(x.object()); XirArgument lockAddress = lockData == null ? null : toXirArgument(emitLea(lockData)); LIRFrameState stateBefore = state(); - curLocks = curLocks.outer; + unlock(x.object(), false); XirSnippet snippet = xir.genMonitorExit(site(x, x.object()), obj, lockAddress); emitXir(snippet, x, stateBefore, true);