# HG changeset patch # User Chris Seaton # Date 1389205232 0 # Node ID 06c13c9bb4b6678c243eabc52d67a9942e1ace9e # Parent b63357fbe40c2ac9208758f212378424c503fe9c# Parent 83fd2094ff66b71b477f8a8b91be686b539d27e8 Merge. diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Wed Jan 08 18:20:32 2014 +0000 @@ -482,8 +482,8 @@ graph.addBeforeFixed(commit, anchor); } for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) { - for (int lockDepth : commit.getLocks().get(objIndex)) { - MonitorEnterNode enter = graph.add(new MonitorEnterNode(allocations[objIndex], lockDepth)); + for (MonitorIdNode monitorId : commit.getLocks(objIndex)) { + MonitorEnterNode enter = graph.add(new MonitorEnterNode(allocations[objIndex], monitorId)); graph.addBeforeFixed(commit, enter); enter.lower(tool); } diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Wed Jan 08 18:20:32 2014 +0000 @@ -434,7 +434,7 @@ args = new Arguments(monitorenterStub, graph.getGuardsStage(), tool.getLoweringStage()); } args.add("object", monitorenterNode.object()); - args.addConst("lockDepth", monitorenterNode.getLockDepth()); + args.addConst("lockDepth", monitorenterNode.getMonitorId().getLockDepth()); boolean tracingEnabledForMethod = stateAfter != null && (isTracingEnabledForMethod(stateAfter.method()) || isTracingEnabledForMethod(graph.method())); args.addConst("threadRegister", registers.getThreadRegister()); args.addConst("stackPointerRegister", registers.getStackPointerRegister()); @@ -461,7 +461,7 @@ args = new Arguments(monitorexitStub, graph.getGuardsStage(), tool.getLoweringStage()); } args.add("object", monitorexitNode.object()); - args.addConst("lockDepth", monitorexitNode.getLockDepth()); + args.addConst("lockDepth", monitorexitNode.getMonitorId().getLockDepth()); args.addConst("trace", isTracingEnabledForType(monitorexitNode.object()) || isTracingEnabledForMethod(stateAfter.method()) || isTracingEnabledForMethod(graph.method())); Map nodes = template(args).instantiate(providers.getMetaAccess(), monitorexitNode, DEFAULT_REPLACER, args); @@ -529,7 +529,7 @@ callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, checkCounter.getMethod(), new ValueNode[]{errMsg}, returnType)); invoke = graph.add(new InvokeNode(callTarget, 0)); List stack = Collections.emptyList(); - FrameState stateAfter = new FrameState(graph.method(), FrameState.AFTER_BCI, new ValueNode[0], stack, new ValueNode[0], false, false); + FrameState stateAfter = new FrameState(graph.method(), FrameState.AFTER_BCI, new ValueNode[0], stack, new ValueNode[0], new MonitorIdNode[0], false, false); invoke.setStateAfter(graph.add(stateAfter)); graph.addBeforeFixed(ret, invoke); diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Wed Jan 08 18:20:32 2014 +0000 @@ -25,6 +25,7 @@ import static com.oracle.graal.compiler.GraalCompiler.*; import java.lang.reflect.*; +import java.util.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; @@ -138,7 +139,7 @@ newEntryState[i] = originalState.getEntry(i); } VirtualObjectNode newVirtual = originalVirtual.duplicate(); - tool.createVirtualObject(newVirtual, newEntryState, null); + tool.createVirtualObject(newVirtual, newEntryState, Collections. emptyList()); tool.replaceWithVirtual(newVirtual); } } else { @@ -159,7 +160,7 @@ state[i] = loads[i] = new LoadFieldNode(obj, fields[i]); tool.addNode(loads[i]); } - tool.createVirtualObject(newVirtual, state, null); + tool.createVirtualObject(newVirtual, state, Collections. emptyList()); tool.replaceWithVirtual(newVirtual); } } diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Wed Jan 08 18:20:32 2014 +0000 @@ -34,19 +34,22 @@ import com.oracle.graal.graph.Node.Verbosity; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; public class FrameStateBuilder { private static final ValueNode[] EMPTY_ARRAY = new ValueNode[0]; + private static final MonitorIdNode[] EMPTY_MONITOR_ARRAY = new MonitorIdNode[0]; private final ResolvedJavaMethod method; private final StructuredGraph graph; private final ValueNode[] locals; private final ValueNode[] stack; - private ValueNode[] locks; + private ValueNode[] lockedObjects; + private MonitorIdNode[] monitorIds; private int stackSize; @@ -62,7 +65,8 @@ this.locals = new ValueNode[method.getMaxLocals()]; // we always need at least one stack slot (for exceptions) this.stack = new ValueNode[Math.max(1, method.getMaxStackSize())]; - this.locks = EMPTY_ARRAY; + this.lockedObjects = EMPTY_ARRAY; + this.monitorIds = EMPTY_MONITOR_ARRAY; int javaIndex = 0; int index = 0; @@ -100,12 +104,14 @@ graph = other.graph; locals = other.locals.clone(); stack = other.stack.clone(); - locks = other.locks == EMPTY_ARRAY ? EMPTY_ARRAY : other.locks.clone(); + lockedObjects = other.lockedObjects == EMPTY_ARRAY ? EMPTY_ARRAY : other.lockedObjects.clone(); + monitorIds = other.monitorIds == EMPTY_MONITOR_ARRAY ? EMPTY_MONITOR_ARRAY : other.monitorIds.clone(); stackSize = other.stackSize; rethrowException = other.rethrowException; assert locals.length == method.getMaxLocals(); assert stack.length == Math.max(1, method.getMaxStackSize()); + assert lockedObjects.length == monitorIds.length; } @Override @@ -120,8 +126,8 @@ sb.append(i == 0 ? "" : ",").append(stack[i] == null ? "_" : stack[i].toString(Verbosity.Id)); } sb.append("] locks: ["); - for (int i = 0; i < locks.length; i++) { - sb.append(i == 0 ? "" : ",").append(locks[i] == null ? "_" : locks[i].toString(Verbosity.Id)); + for (int i = 0; i < lockedObjects.length; i++) { + sb.append(i == 0 ? "" : ",").append(lockedObjects[i].toString(Verbosity.Id)).append(" / ").append(monitorIds[i].toString(Verbosity.Id)); } sb.append("]"); if (rethrowException) { @@ -132,7 +138,7 @@ } public FrameState create(int bci) { - return graph.add(new FrameState(method, bci, locals, Arrays.asList(stack).subList(0, stackSize), locks, rethrowException, false)); + return graph.add(new FrameState(method, bci, locals, Arrays.asList(stack).subList(0, stackSize), lockedObjects, monitorIds, rethrowException, false)); } public FrameStateBuilder copy() { @@ -141,6 +147,7 @@ public boolean isCompatibleWith(FrameStateBuilder other) { assert method == other.method && graph == other.graph && localsSize() == other.localsSize() : "Can only compare frame states of the same method"; + assert lockedObjects.length == monitorIds.length && other.lockedObjects.length == other.monitorIds.length : "mismatch between lockedObjects and monitorIds"; if (stackSize() != other.stackSize()) { return false; @@ -152,11 +159,11 @@ return false; } } - if (locks.length != other.locks.length) { + if (lockedObjects.length != other.lockedObjects.length) { return false; } - for (int i = 0; i < locks.length; i++) { - if (GraphUtil.originalValue(locks[i]) != GraphUtil.originalValue(other.locks[i])) { + for (int i = 0; i < lockedObjects.length; i++) { + if (GraphUtil.originalValue(lockedObjects[i]) != GraphUtil.originalValue(other.lockedObjects[i]) || monitorIds[i] != other.monitorIds[i]) { throw new BailoutException("unbalanced monitors"); } } @@ -172,8 +179,9 @@ for (int i = 0; i < stackSize(); i++) { storeStack(i, merge(stackAt(i), other.stackAt(i), block)); } - for (int i = 0; i < locks.length; i++) { - locks[i] = merge(locks[i], other.locks[i], block); + for (int i = 0; i < lockedObjects.length; i++) { + lockedObjects[i] = merge(lockedObjects[i], other.lockedObjects[i], block); + assert monitorIds[i] == other.monitorIds[i]; } } @@ -234,8 +242,8 @@ for (int i = 0; i < stackSize(); i++) { storeStack(i, createLoopPhi(loopBegin, stackAt(i))); } - for (int i = 0; i < locks.length; i++) { - locks[i] = createLoopPhi(loopBegin, locks[i]); + for (int i = 0; i < lockedObjects.length; i++) { + lockedObjects[i] = createLoopPhi(loopBegin, lockedObjects[i]); } } @@ -254,11 +262,11 @@ storeStack(i, ProxyNode.forValue(value, loopExit, graph)); } } - for (int i = 0; i < locks.length; i++) { - ValueNode value = locks[i]; + for (int i = 0; i < lockedObjects.length; i++) { + ValueNode value = lockedObjects[i]; if (value != null && (!loopEntryState.contains(value) || loopExit.loopBegin().isPhiAtMerge(value))) { Debug.log(" inserting proxy for %s", value); - locks[i] = ProxyNode.forValue(value, loopExit, graph); + lockedObjects[i] = ProxyNode.forValue(value, loopExit, graph); } } } @@ -278,11 +286,11 @@ storeStack(i, ProxyNode.forValue(value, begin, graph)); } } - for (int i = 0; i < locks.length; i++) { - ValueNode value = locks[i]; + for (int i = 0; i < lockedObjects.length; i++) { + ValueNode value = lockedObjects[i]; if (value != null) { Debug.log(" inserting proxy for %s", value); - locks[i] = ProxyNode.forValue(value, begin, graph); + lockedObjects[i] = ProxyNode.forValue(value, begin, graph); } } } @@ -373,10 +381,13 @@ * * @param object the object whose monitor will be locked. */ - public void pushLock(ValueNode object) { + public void pushLock(ValueNode object, MonitorIdNode monitorId) { assert object.isAlive() && object.kind() == Kind.Object : "unexpected value: " + object; - locks = Arrays.copyOf(locks, locks.length + 1); - locks[locks.length - 1] = object; + lockedObjects = Arrays.copyOf(lockedObjects, lockedObjects.length + 1); + monitorIds = Arrays.copyOf(monitorIds, monitorIds.length + 1); + lockedObjects[lockedObjects.length - 1] = object; + monitorIds[monitorIds.length - 1] = monitorId; + assert lockedObjects.length == monitorIds.length; } /** @@ -386,17 +397,23 @@ */ public ValueNode popLock() { try { - return locks[locks.length - 1]; + return lockedObjects[lockedObjects.length - 1]; } finally { - locks = locks.length == 1 ? EMPTY_ARRAY : Arrays.copyOf(locks, locks.length - 1); + lockedObjects = lockedObjects.length == 1 ? EMPTY_ARRAY : Arrays.copyOf(lockedObjects, lockedObjects.length - 1); + monitorIds = monitorIds.length == 1 ? EMPTY_MONITOR_ARRAY : Arrays.copyOf(monitorIds, monitorIds.length - 1); } } + public MonitorIdNode peekMonitorId() { + return monitorIds[monitorIds.length - 1]; + } + /** * @return the current lock depth */ public int lockDepth() { - return locks.length; + assert lockedObjects.length == monitorIds.length; + return lockedObjects.length; } /** @@ -660,8 +677,9 @@ return true; } } - for (int i = 0; i < locks.length; i++) { - if (locks[i] == value) { + assert lockedObjects.length == monitorIds.length; + for (int i = 0; i < lockedObjects.length; i++) { + if (lockedObjects[i] == value || monitorIds[i] == value) { return true; } } diff -r b63357fbe40c -r 06c13c9bb4b6 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 Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Jan 08 18:20:32 2014 +0000 @@ -1247,17 +1247,19 @@ } private MonitorEnterNode genMonitorEnter(ValueNode x) { - MonitorEnterNode monitorEnter = append(new MonitorEnterNode(x, frameState.lockDepth())); - frameState.pushLock(x); + MonitorIdNode monitorId = currentGraph.add(new MonitorIdNode(frameState.lockDepth())); + MonitorEnterNode monitorEnter = append(new MonitorEnterNode(x, monitorId)); + frameState.pushLock(x, monitorId); return monitorEnter; } private MonitorExitNode genMonitorExit(ValueNode x, ValueNode returnValue) { + MonitorIdNode monitorId = frameState.peekMonitorId(); 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, returnValue, frameState.lockDepth())); + MonitorExitNode monitorExit = append(new MonitorExitNode(x, monitorId, returnValue)); return monitorExit; } diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Wed Jan 08 18:20:32 2014 +0000 @@ -31,6 +31,7 @@ import com.oracle.graal.nodes.VirtualState.NodeClosure; import com.oracle.graal.nodes.VirtualState.VirtualClosure; import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.virtual.*; public abstract class LoopFragment { @@ -198,11 +199,13 @@ markFloating(obj, nodes, notloopNodes); } } + if (n instanceof MonitorEnterNode) { + markFloating(((MonitorEnterNode) n).getMonitorId(), nodes, notloopNodes); + } for (Node usage : n.usages()) { markFloating(usage, nodes, notloopNodes); } } - } return nodes; diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Wed Jan 08 18:20:32 2014 +0000 @@ -28,6 +28,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.virtual.*; /** @@ -81,8 +82,13 @@ @Input private FrameState outerFrameState; + /** + * Contains the locals, the expressions and the locked objects, in this order. + */ @Input private final NodeInputList values; + @Input private final NodeInputList monitorIds; + @Input private final NodeInputList virtualObjectMappings; /** @@ -93,16 +99,20 @@ private final ResolvedJavaMethod method; /** - * Creates a {@code FrameState} for the given scope and maximum number of stack and local - * variables. + * Creates a {@code FrameState} with the given locals, stack expressions and locked monitors. * * @param method the method for this frame state * @param bci the bytecode index of the frame state - * @param stackSize size of the stack - * @param rethrowException if true the VM should re-throw the exception on top of the stack when - * deopt'ing using this framestate + * @param values the locals, stack expressions and locked objects, in this order + * @param localsSize the number of locals in the values list + * @param stackSize the number of stack expressions in the values list + * @param rethrowException if true, this FrameState will throw an exception (taken from the top + * of the expression stack) during deoptimization + * @param duringCall true if this FrameState describes the state during a call + * @param monitorIds one MonitorIdNode for each locked object + * @param virtualObjectMappings a description of the current state for every virtual object */ - public FrameState(ResolvedJavaMethod method, int bci, List values, int localsSize, int stackSize, boolean rethrowException, boolean duringCall, + public FrameState(ResolvedJavaMethod method, int bci, List values, int localsSize, int stackSize, boolean rethrowException, boolean duringCall, List monitorIds, List virtualObjectMappings) { assert stackSize >= 0; this.method = method; @@ -110,10 +120,12 @@ this.localsSize = localsSize; this.stackSize = stackSize; this.values = new NodeInputList<>(this, values); + this.monitorIds = new NodeInputList<>(this, monitorIds); this.virtualObjectMappings = new NodeInputList<>(this, virtualObjectMappings); this.rethrowException = rethrowException; this.duringCall = duringCall; assert !rethrowException || stackSize == 1 : "must have exception on top of the stack"; + assert values.size() - localsSize - stackSize == monitorIds.size(); } /** @@ -122,11 +134,12 @@ * @param bci marker bci, needs to be < 0 */ public FrameState(int bci) { - this(null, bci, Collections. emptyList(), 0, 0, false, false, Collections. emptyList()); + this(null, bci, Collections. emptyList(), 0, 0, false, false, Collections. emptyList(), Collections. emptyList()); + assert bci == BEFORE_BCI || bci == AFTER_BCI || bci == AFTER_EXCEPTION_BCI || bci == UNKNOWN_BCI || bci == INVALID_FRAMESTATE_BCI; } - public FrameState(ResolvedJavaMethod method, int bci, ValueNode[] locals, List stack, ValueNode[] locks, boolean rethrowException, boolean duringCall) { - this(method, bci, createValues(locals, stack, locks), locals.length, stack.size(), rethrowException, duringCall, Collections. emptyList()); + public FrameState(ResolvedJavaMethod method, int bci, ValueNode[] locals, List stack, ValueNode[] locks, MonitorIdNode[] monitorIds, boolean rethrowException, boolean duringCall) { + this(method, bci, createValues(locals, stack, locks), locals.length, stack.size(), rethrowException, duringCall, Arrays.asList(monitorIds), Collections. emptyList()); } private static List createValues(ValueNode[] locals, List stack, ValueNode[] locks) { @@ -198,7 +211,7 @@ * Gets a copy of this frame state. */ public FrameState duplicate(int newBci) { - FrameState other = graph().add(new FrameState(method, newBci, values, localsSize, stackSize, rethrowException, duringCall, virtualObjectMappings)); + FrameState other = graph().add(new FrameState(method, newBci, values, localsSize, stackSize, rethrowException, duringCall, monitorIds, virtualObjectMappings)); other.setOuterFrameState(outerFrameState()); return other; } @@ -224,7 +237,7 @@ for (EscapeObjectState state : virtualObjectMappings) { newVirtualMappings.add(state.duplicateWithVirtualState()); } - FrameState other = graph().add(new FrameState(method, bci, values, localsSize, stackSize, rethrowException, duringCall, newVirtualMappings)); + FrameState other = graph().add(new FrameState(method, bci, values, localsSize, stackSize, rethrowException, duringCall, monitorIds, newVirtualMappings)); other.setOuterFrameState(newOuterFrameState); return other; } @@ -248,7 +261,7 @@ int newStackSize = copy.size() - localsSize; copy.addAll(values.subList(localsSize + stackSize, values.size())); - FrameState other = graph().add(new FrameState(method, newBci, copy, localsSize, newStackSize, newRethrowException, false, virtualObjectMappings)); + FrameState other = graph().add(new FrameState(method, newBci, copy, localsSize, newStackSize, newRethrowException, false, monitorIds, virtualObjectMappings)); other.setOuterFrameState(outerFrameState()); return other; } @@ -319,6 +332,14 @@ return values.get(localsSize + stackSize + i); } + /** + * Get the MonitorIdNode that corresponds to the locked object at the specified index. + */ + public MonitorIdNode monitorIdAt(int i) { + assert i >= 0 && i < locksSize(); + return monitorIds.get(i); + } + public NodeIterable innerFrameStates() { return usages().filter(FrameState.class); } @@ -375,9 +396,10 @@ @Override public boolean verify() { + assertTrue(values.size() - localsSize - stackSize == monitorIds.size(), "mismatch in number of locks"); for (ValueNode value : values) { - assert assertTrue(value == null || !value.isDeleted(), "frame state must not contain deleted nodes"); - assert assertTrue(value == null || value instanceof VirtualObjectNode || (value.kind() != Kind.Void), "unexpected value: %s", value); + assertTrue(value == null || !value.isDeleted(), "frame state must not contain deleted nodes"); + assertTrue(value == null || value instanceof VirtualObjectNode || (value.kind() != Kind.Void), "unexpected value: %s", value); } return super.verify(); } @@ -387,6 +409,9 @@ for (ValueNode value : values.nonNull()) { closure.apply(this, value); } + for (MonitorIdNode monitorId : monitorIds) { + closure.apply(this, monitorId); + } for (EscapeObjectState state : virtualObjectMappings) { state.applyToNonVirtual(closure); } diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Wed Jan 08 18:20:32 2014 +0000 @@ -22,11 +22,14 @@ */ package com.oracle.graal.nodes.extended; +import java.util.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.virtual.*; @@ -79,7 +82,7 @@ VirtualBoxingNode newVirtual = new VirtualBoxingNode(type, boxingKind); assert newVirtual.getFields().length == 1; - tool.createVirtualObject(newVirtual, new ValueNode[]{v}, null); + tool.createVirtualObject(newVirtual, new ValueNode[]{v}, Collections. emptyList()); tool.replaceWithVirtual(newVirtual); } diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MonitorReference.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MonitorReference.java Wed Jan 08 17:44:56 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.nodes.extended; - -/** - * Denotes an instruction that references a monitor and wants to know its lock nesting depth. - */ -public interface MonitorReference { - - /** - * Sets the depth of the lock referenced by this operation. - */ - void setLockDepth(int lockDepth); - - /** - * Gets the depth of the lock referenced by this operation. - */ - int getLockDepth(); -} diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java Wed Jan 08 18:20:32 2014 +0000 @@ -36,18 +36,24 @@ public abstract class AccessMonitorNode extends AbstractMemoryCheckpoint implements MemoryCheckpoint { @Input private ValueNode object; + @Input private MonitorIdNode monitorId; public ValueNode object() { return object; } + public MonitorIdNode getMonitorId() { + return monitorId; + } + /** * Creates a new AccessMonitor instruction. * * @param object the instruction producing the object */ - public AccessMonitorNode(ValueNode object) { + public AccessMonitorNode(ValueNode object, MonitorIdNode monitorId) { super(StampFactory.forVoid()); this.object = object; + this.monitorId = monitorId; } } diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java Wed Jan 08 18:20:32 2014 +0000 @@ -30,18 +30,15 @@ /** * The {@code MonitorEnterNode} represents the acquisition of a monitor. */ -public final class MonitorEnterNode extends AccessMonitorNode implements Virtualizable, Lowerable, MonitorEnter, MemoryCheckpoint.Single, MonitorReference { - - private int lockDepth; +public final class MonitorEnterNode extends AccessMonitorNode implements Virtualizable, Lowerable, MonitorEnter, MemoryCheckpoint.Single { /** * Creates a new MonitorEnterNode. * * @param object the instruction producing the object */ - public MonitorEnterNode(ValueNode object, int lockDepth) { - super(object); - this.lockDepth = lockDepth; + public MonitorEnterNode(ValueNode object, MonitorIdNode monitorId) { + super(object, monitorId); } @Override @@ -54,19 +51,11 @@ tool.getLowerer().lower(this, tool); } - public int getLockDepth() { - return lockDepth; - } - - public void setLockDepth(int lockDepth) { - this.lockDepth = lockDepth; - } - @Override public void virtualize(VirtualizerTool tool) { State state = tool.getObjectState(object()); if (state != null && state.getState() == EscapeState.Virtual && state.getVirtualObject().hasIdentity()) { - state.addLock(getLockDepth()); + state.addLock(getMonitorId()); tool.delete(); } } diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Wed Jan 08 18:20:32 2014 +0000 @@ -34,19 +34,16 @@ * a synchronized method, then the return value of the method will be referenced, so that it will be * materialized before releasing the monitor. */ -public final class MonitorExitNode extends AccessMonitorNode implements Virtualizable, Simplifiable, Lowerable, IterableNodeType, MonitorExit, MemoryCheckpoint.Single, MonitorReference { +public final class MonitorExitNode extends AccessMonitorNode implements Virtualizable, Simplifiable, Lowerable, IterableNodeType, MonitorExit, MemoryCheckpoint.Single { @Input private ValueNode escapedReturnValue; - private int lockDepth; - /** * Creates a new MonitorExitNode. */ - public MonitorExitNode(ValueNode object, ValueNode escapedReturnValue, int lockDepth) { - super(object); + public MonitorExitNode(ValueNode object, MonitorIdNode monitorId, ValueNode escapedReturnValue) { + super(object, monitorId); this.escapedReturnValue = escapedReturnValue; - this.lockDepth = lockDepth; } public void setEscapedReturnValue(ValueNode x) { @@ -73,22 +70,17 @@ tool.getLowerer().lower(this, tool); } - public int getLockDepth() { - return lockDepth; - } - - public void setLockDepth(int lockDepth) { - this.lockDepth = lockDepth; - } - @Override public void virtualize(VirtualizerTool tool) { State state = tool.getObjectState(object()); // the monitor exit for a synchronized method should never be virtualized assert stateAfter().bci != FrameState.AFTER_BCI || state == null; if (state != null && state.getState() == EscapeState.Virtual && state.getVirtualObject().hasIdentity()) { - int removedLock = state.removeLock(); - assert removedLock == getLockDepth(); + MonitorIdNode removedLock = state.removeLock(); + if (removedLock != getMonitorId()) { + throw new GraalInternalError("mismatch at %s: %s vs. %s", this, removedLock, getMonitorId()); + } + assert removedLock == getMonitorId() : "mismatch at " + this + ": " + removedLock + " vs. " + getMonitorId(); tool.delete(); } } diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorIdNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorIdNode.java Wed Jan 08 18:20:32 2014 +0000 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes.java; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * This node describes one locking scope; it ties the monitor enter, monitor exit and the frame + * states together. It is thus referenced from the {@link MonitorEnterNode}, from the + * {@link MonitorExitNode} and from the {@link FrameState}. + */ +public final class MonitorIdNode extends ValueNode implements IterableNodeType, LIRLowerable { + + private int lockDepth; + + public MonitorIdNode(int lockDepth) { + super(StampFactory.dependency()); + this.lockDepth = lockDepth; + } + + public int getLockDepth() { + return lockDepth; + } + + public void setLockDepth(int lockDepth) { + this.lockDepth = lockDepth; + } + + public void generate(LIRGeneratorTool generator) { + // nothing to do + } +} diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java Wed Jan 08 18:20:32 2014 +0000 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes.java; +import java.util.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -66,7 +68,7 @@ state[i] = defaultForKind; } VirtualObjectNode virtualObject = new VirtualArrayNode(elementType(), constantLength); - tool.createVirtualObject(virtualObject, state, null); + tool.createVirtualObject(virtualObject, state, Collections. emptyList()); tool.replaceWithVirtual(virtualObject); } } diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Wed Jan 08 18:20:32 2014 +0000 @@ -23,6 +23,7 @@ package com.oracle.graal.nodes.java; import java.lang.ref.*; +import java.util.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; @@ -74,7 +75,7 @@ for (int i = 0; i < state.length; i++) { state[i] = defaultFieldValue(fields[i]); } - tool.createVirtualObject(virtualObject, state, null); + tool.createVirtualObject(virtualObject, state, Collections. emptyList()); tool.replaceWithVirtual(virtualObject); } } diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Virtualizable.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Virtualizable.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Virtualizable.java Wed Jan 08 18:20:32 2014 +0000 @@ -23,6 +23,7 @@ package com.oracle.graal.nodes.spi; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.virtual.*; /** @@ -45,9 +46,9 @@ public abstract ValueNode getEntry(int index); - public abstract void addLock(int depth); + public abstract void addLock(MonitorIdNode monitorId); - public abstract int removeLock(); + public abstract MonitorIdNode removeLock(); public abstract ValueNode getMaterializedValue(); } diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java Wed Jan 08 18:20:32 2014 +0000 @@ -22,10 +22,13 @@ */ package com.oracle.graal.nodes.spi; +import java.util.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.Virtualizable.State; import com.oracle.graal.nodes.virtual.*; @@ -66,7 +69,7 @@ * @param entryState the initial state of the virtual object's fields. * @param locks the initial locking depths. */ - void createVirtualObject(VirtualObjectNode virtualObject, ValueNode[] entryState, int[] locks); + void createVirtualObject(VirtualObjectNode virtualObject, ValueNode[] entryState, List locks); /** * Queries the current state of the given value: if it is virtualized (thread-local and the diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java Wed Jan 08 18:20:32 2014 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -36,7 +37,8 @@ @Input private final NodeInputList virtualObjects = new NodeInputList<>(this); @Input private final NodeInputList values = new NodeInputList<>(this); - private List locks = new ArrayList<>(); + @Input private final NodeInputList locks = new NodeInputList<>(this); + private ArrayList lockIndexes = new ArrayList<>(Arrays.asList(0)); public CommitAllocationNode() { super(StampFactory.forVoid()); @@ -50,13 +52,14 @@ return values; } - public List getLocks() { - return locks; + public List getLocks(int objIndex) { + return locks.subList(lockIndexes.get(objIndex), lockIndexes.get(objIndex + 1)); } @Override public boolean verify() { - assertTrue(virtualObjects.size() == locks.size(), "lockCounts size doesn't match " + virtualObjects + ", " + locks); + assertTrue(virtualObjects.size() + 1 == lockIndexes.size(), "lockIndexes size doesn't match " + virtualObjects + ", " + lockIndexes); + assertTrue(lockIndexes.get(lockIndexes.size() - 1) == locks.size(), "locks size doesn't match " + lockIndexes + ", " + locks); int valueCount = 0; for (VirtualObjectNode virtual : virtualObjects) { valueCount += virtual.entryCount(); @@ -72,7 +75,12 @@ @Override public void afterClone(Node other) { - locks = new ArrayList<>(((CommitAllocationNode) other).locks); + lockIndexes = new ArrayList<>(lockIndexes); + } + + public void addLocks(List monitorIds) { + locks.addAll(monitorIds); + lockIndexes.add(locks.size()); } @Override @@ -81,7 +89,7 @@ for (int i = 0; i < virtualObjects.size(); i++) { VirtualObjectNode virtualObject = virtualObjects.get(i); int entryCount = virtualObject.entryCount(); - tool.createVirtualObject(virtualObject, values.subList(pos, pos + entryCount).toArray(new ValueNode[entryCount]), locks.get(i)); + tool.createVirtualObject(virtualObject, values.subList(pos, pos + entryCount).toArray(new ValueNode[entryCount]), getLocks(i)); pos += entryCount; } tool.delete(); @@ -100,8 +108,8 @@ s.append(i == 0 ? "" : ",").append(value == null ? "_" : value.toString(Verbosity.Id)); } s.append("]"); - if (locks.get(objIndex).length > 0) { - s.append(" locked(").append(Arrays.toString(locks.get(objIndex))).append(")"); + if (!getLocks(objIndex).isEmpty()) { + s.append(" locked(").append(locks.get(objIndex)).append(")"); } properties.put("object(" + virtual.toString(Verbosity.Id) + ")", s.toString()); } @@ -150,14 +158,17 @@ if (usedCount < virtualObjects.size()) { List newVirtualObjects = new ArrayList<>(usedCount); - List newLocks = new ArrayList<>(usedCount); + List newLocks = new ArrayList<>(usedCount); + ArrayList newLockIndexes = new ArrayList<>(usedCount + 1); + newLockIndexes.add(0); List newValues = new ArrayList<>(); int valuePos = 0; for (int objIndex = 0; objIndex < virtualObjects.size(); objIndex++) { VirtualObjectNode virtualObject = virtualObjects.get(objIndex); if (used[objIndex]) { newVirtualObjects.add(virtualObject); - newLocks.add(locks.get(objIndex)); + newLocks.addAll(getLocks(objIndex)); + newLockIndexes.add(newLocks.size()); newValues.addAll(values.subList(valuePos, valuePos + virtualObject.entryCount())); } valuePos += virtualObject.entryCount(); @@ -168,6 +179,7 @@ locks.addAll(newLocks); values.clear(); values.addAll(newValues); + lockIndexes = newLockIndexes; } } diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/LockState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/LockState.java Wed Jan 08 18:20:32 2014 +0000 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes.virtual; + +import java.util.*; + +import com.oracle.graal.nodes.java.*; + +/** + * The class implements a simple linked list of MonitorIdNodes, which can be used to describe the + * current lock state of an object. + */ +public final class LockState { + + public final MonitorIdNode monitorId; + public final LockState next; + + public LockState(MonitorIdNode monitorId, LockState next) { + this.monitorId = monitorId; + this.next = next; + } + + @Override + public String toString() { + return monitorId.getLockDepth() + (next == null ? "" : "," + next); + } + + public static List asList(LockState state) { + if (state == null) { + return Collections.emptyList(); + } else { + ArrayList result = new ArrayList<>(); + LockState a = state; + do { + result.add(a.monitorId); + a = a.next; + } while (a != null); + return result; + } + } +} diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java Wed Jan 08 18:20:32 2014 +0000 @@ -141,7 +141,7 @@ } @Override - public ValueNode getMaterializedRepresentation(FixedNode fixed, ValueNode[] entries, int[] locks) { + public ValueNode getMaterializedRepresentation(FixedNode fixed, ValueNode[] entries, LockState locks) { return new AllocatedObjectNode(this); } } diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualBoxingNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualBoxingNode.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualBoxingNode.java Wed Jan 08 18:20:32 2014 +0000 @@ -41,9 +41,9 @@ } @Override - public ValueNode getMaterializedRepresentation(FixedNode fixed, ValueNode[] entries, int[] locks) { + public ValueNode getMaterializedRepresentation(FixedNode fixed, ValueNode[] entries, LockState locks) { assert entries.length == 1; - assert locks.length == 0; + assert locks == null; return new BoxNode(entries[0], type(), boxingKind); } } diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java Wed Jan 08 18:20:32 2014 +0000 @@ -101,7 +101,7 @@ } @Override - public ValueNode getMaterializedRepresentation(FixedNode fixed, ValueNode[] entries, int[] locks) { + public ValueNode getMaterializedRepresentation(FixedNode fixed, ValueNode[] entries, LockState locks) { return new AllocatedObjectNode(this); } } diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java Wed Jan 08 18:20:32 2014 +0000 @@ -88,7 +88,7 @@ * {@link AllocatedObjectNode} then this node will be attached to a {@link CommitAllocationNode} * , otherwise the node will just be added to the graph. */ - public abstract ValueNode getMaterializedRepresentation(FixedNode fixed, ValueNode[] entries, int[] locks); + public abstract ValueNode getMaterializedRepresentation(FixedNode fixed, ValueNode[] entries, LockState locks); @Override public void generate(LIRGeneratorTool gen) { diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Wed Jan 08 18:20:32 2014 +0000 @@ -1395,10 +1395,9 @@ if (stateAfter != null) { FrameState outerFrameState = null; int callerLockDepth = stateAfter.nestedLockDepth(); - for (Node inlinedNode : inlineGraph.getNodes()) { - Node node = duplicates.get(inlinedNode); - if (node instanceof FrameState) { - FrameState frameState = (FrameState) node; + for (FrameState original : inlineGraph.getNodes(FrameState.class)) { + FrameState frameState = (FrameState) duplicates.get(original); + if (frameState != null) { assert frameState.bci != FrameState.BEFORE_BCI : frameState; if (frameState.bci == FrameState.AFTER_BCI) { frameState.replaceAndDelete(stateAfter); @@ -1421,8 +1420,10 @@ } } } - if (callerLockDepth != 0 && node instanceof MonitorReference) { - MonitorReference monitor = (MonitorReference) node; + } + if (callerLockDepth != 0) { + for (MonitorIdNode original : inlineGraph.getNodes(MonitorIdNode.class)) { + MonitorIdNode monitor = (MonitorIdNode) duplicates.get(original); monitor.setLockDepth(monitor.getLockDepth() + callerLockDepth); } } diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Wed Jan 08 18:20:32 2014 +0000 @@ -102,7 +102,7 @@ } @Override - public ValueNode getMaterializedRepresentation(FixedNode fixed, ValueNode[] entries, int[] locks) { + public ValueNode getMaterializedRepresentation(FixedNode fixed, ValueNode[] entries, LockState locks) { if (allowMaterialization) { return super.getMaterializedRepresentation(fixed, entries, locks); } @@ -173,9 +173,9 @@ tool.getAssumptions().record(new AssumptionValidAssumption((OptimizedAssumption) frameDescriptor.getVersion())); } - tool.createVirtualObject(virtualFrameObjectArray, objectArrayEntryState, null); - tool.createVirtualObject(virtualFramePrimitiveArray, primitiveArrayEntryState, null); - tool.createVirtualObject(virtualFrameTagArray, tagArrayEntryState, null); + tool.createVirtualObject(virtualFrameObjectArray, objectArrayEntryState, Collections. emptyList()); + tool.createVirtualObject(virtualFramePrimitiveArray, primitiveArrayEntryState, Collections. emptyList()); + tool.createVirtualObject(virtualFrameTagArray, tagArrayEntryState, Collections. emptyList()); assert frameFields.length == 6; ValueNode[] frameEntryState = new ValueNode[frameFields.length]; diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Wed Jan 08 18:20:32 2014 +0000 @@ -28,6 +28,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.debug.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.common.*; @@ -308,7 +309,7 @@ * @param otherAllocations A list of allocations that need to be added before the rest (used for * boxing allocations). */ - public void addMaterializationBefore(final FixedNode position, final List objects, final List locks, final List values, + public void addMaterializationBefore(final FixedNode position, final List objects, final List> locks, final List values, final List otherAllocations) { add(new Effect() { @@ -341,7 +342,9 @@ obj.setCommit(commit); } commit.getValues().addAll(values); - commit.getLocks().addAll(locks); + for (List monitorIds : locks) { + commit.addLocks(monitorIds); + } assert commit.usages().filter(AllocatedObjectNode.class).count() == commit.usages().count(); List materializedValues = commit.usages().filter(AllocatedObjectNode.class).snapshot(); diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java Wed Jan 08 18:20:32 2014 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ import java.util.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.spi.Virtualizable.EscapeState; import com.oracle.graal.nodes.virtual.*; @@ -36,37 +37,6 @@ */ public class ObjectState extends Virtualizable.State { - private static final int[] EMPTY_INT_ARRAY = new int[0]; - - public static final class LockState { - - public final int depth; - public final LockState next; - - private LockState(int depth, LockState next) { - this.depth = depth; - this.next = next; - } - - @Override - public String toString() { - return next == null ? String.valueOf(depth) : depth + "," + next; - } - - public static boolean equals(LockState a, LockState b) { - if ((a == null) != (b == null)) { - return false; - } - if (a != null) { - if (a.depth != b.depth) { - return false; - } - return equals(a.next, b.next); - } - return true; - } - } - final VirtualObjectNode virtual; private EscapeState state; @@ -74,17 +44,18 @@ private ValueNode materializedValue; private LockState locks; - public ObjectState(VirtualObjectNode virtual, ValueNode[] entries, EscapeState state, int[] locks) { + public ObjectState(VirtualObjectNode virtual, ValueNode[] entries, EscapeState state, List locks) { + this(virtual, entries, state, (LockState) null); + for (int i = locks.size() - 1; i >= 0; i--) { + this.locks = new LockState(locks.get(i), this.locks); + } + } + + public ObjectState(VirtualObjectNode virtual, ValueNode[] entries, EscapeState state, LockState locks) { this.virtual = virtual; this.entries = entries; this.state = state; - if (locks == null) { - this.locks = null; - } else { - for (int i = locks.length - 1; i >= 0; i--) { - this.locks = new LockState(locks[i], this.locks); - } - } + this.locks = locks; } public ObjectState(VirtualObjectNode virtual, ValueNode materializedValue, EscapeState state, LockState locks) { @@ -156,37 +127,21 @@ } @Override - public void addLock(int depth) { - locks = new LockState(depth, locks); + public void addLock(MonitorIdNode monitorId) { + locks = new LockState(monitorId, locks); } @Override - public int removeLock() { + public MonitorIdNode removeLock() { try { - return locks.depth; + return locks.monitorId; } finally { locks = locks.next; } } - public int[] getLocks() { - if (locks == null) { - return EMPTY_INT_ARRAY; - } - int cnt = 0; - LockState current = locks; - while (current != null) { - cnt++; - current = current.next; - } - int[] result = new int[cnt]; - current = locks; - cnt = 0; - while (current != null) { - result[cnt++] = current.depth; - current = current.next; - } - return result; + public LockState getLocks() { + return locks; } public boolean hasLocks() { @@ -194,7 +149,13 @@ } public boolean locksEqual(ObjectState other) { - return LockState.equals(locks, other.locks); + LockState a = locks; + LockState b = other.locks; + while (a != null && b != null && a.monitorId == b.monitorId) { + a = a.next; + b = b.next; + } + return a == null && b == null; } @Override @@ -220,7 +181,7 @@ final int prime = 31; int result = 1; result = prime * result + Arrays.hashCode(entries); - result = prime * result + (locks != null ? locks.depth : 0); + result = prime * result + (locks != null ? locks.monitorId.getLockDepth() : 0); result = prime * result + ((materializedValue == null) ? 0 : materializedValue.hashCode()); result = prime * result + ((state == null) ? 0 : state.hashCode()); result = prime * result + ((virtual == null) ? 0 : virtual.hashCode()); @@ -239,7 +200,7 @@ if (!Arrays.equals(entries, other.entries)) { return false; } - if (!LockState.equals(locks, other.locks)) { + if (!locksEqual(other)) { return false; } if (materializedValue == null) { diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java Wed Jan 08 18:20:32 2014 +0000 @@ -25,6 +25,7 @@ import java.util.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.Virtualizable.EscapeState; import com.oracle.graal.nodes.virtual.*; @@ -68,15 +69,15 @@ PartialEscapeClosure.METRIC_MATERIALIZATIONS.increment(); List objects = new ArrayList<>(2); List values = new ArrayList<>(8); - List locks = new ArrayList<>(2); + List> locks = new ArrayList<>(2); List otherAllocations = new ArrayList<>(2); materializeWithCommit(fixed, virtual, objects, locks, values, otherAllocations, state); materializeEffects.addMaterializationBefore(fixed, objects, locks, values, otherAllocations); } - private void materializeWithCommit(FixedNode fixed, VirtualObjectNode virtual, List objects, List locks, List values, List otherAllocations, - EscapeState state) { + private void materializeWithCommit(FixedNode fixed, VirtualObjectNode virtual, List objects, List> locks, List values, + List otherAllocations, EscapeState state) { ObjectState obj = getObjectState(virtual); ValueNode[] entries = obj.getEntries(); @@ -84,7 +85,7 @@ obj.escape(representation, state); if (representation instanceof AllocatedObjectNode) { objects.add((AllocatedObjectNode) representation); - locks.add(obj.getLocks()); + locks.add(LockState.asList(obj.getLocks())); int pos = values.size(); while (values.size() < pos + entries.length) { values.add(null); @@ -104,7 +105,7 @@ } else { VirtualUtil.trace("materialized %s as %s", virtual, representation); otherAllocations.add(representation); - assert obj.getLocks().length == 0; + assert obj.getLocks() == null; } } diff -r b63357fbe40c -r 06c13c9bb4b6 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Wed Jan 08 17:44:56 2014 +0000 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Wed Jan 08 18:20:32 2014 +0000 @@ -24,11 +24,14 @@ import static com.oracle.graal.phases.GraalOptions.*; +import java.util.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.Virtualizable.EscapeState; import com.oracle.graal.nodes.spi.Virtualizable.State; import com.oracle.graal.nodes.spi.*; @@ -150,7 +153,7 @@ } @Override - public void createVirtualObject(VirtualObjectNode virtualObject, ValueNode[] entryState, int[] locks) { + public void createVirtualObject(VirtualObjectNode virtualObject, ValueNode[] entryState, List locks) { VirtualUtil.trace("{{%s}} ", current); if (!virtualObject.isAlive()) { effects.addFloatingNode(virtualObject, "newVirtualObject");