# HG changeset patch # User Thomas Wuerthinger # Date 1425051398 -3600 # Node ID cb701331de392844b1018fd4de34686531af33e2 # Parent afad10e79e1369f73e3452528bd26154c4f6551c# Parent 73811d1b4cd0d89423462f10c05afa8b384dd88f Merge. diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackLockValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/StackLockValue.java Fri Feb 27 16:36:38 2015 +0100 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2011, 2015, 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.api.code; + +import static com.oracle.graal.api.code.ValueUtil.*; + +import com.oracle.graal.api.meta.*; + +/** + * Represents lock information in the debug information. + */ +public final class StackLockValue extends AbstractValue implements JavaValue { + + private static final long serialVersionUID = 8241681800464483691L; + + private JavaValue owner; + private StackSlotValue slot; + private final boolean eliminated; + + public StackLockValue(JavaValue owner, StackSlotValue slot, boolean eliminated) { + super(LIRKind.Illegal); + this.owner = owner; + this.slot = slot; + this.eliminated = eliminated; + } + + public JavaValue getOwner() { + return owner; + } + + public void setOwner(JavaValue newOwner) { + this.owner = newOwner; + } + + public Value getSlot() { + return slot; + } + + public boolean isEliminated() { + return eliminated; + } + + @Override + public String toString() { + return "monitor[" + owner + (slot != null ? ", " + slot : "") + (eliminated ? ", eliminated" : "") + "]"; + } + + @Override + public int hashCode() { + final int prime = 43; + int result = super.hashCode(); + result = prime * result + (eliminated ? 1231 : 1237); + result = prime * result + owner.hashCode(); + result = prime * result + slot.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof StackLockValue) { + StackLockValue other = (StackLockValue) obj; + return super.equals(obj) && eliminated == other.eliminated && owner.equals(other.owner) && slot.equals(other.slot); + } + return false; + } + + public void setSlot(StackSlotValue stackSlot) { + assert slot == null || (isVirtualStackSlot(slot) && (slot.equals(stackSlot) || isStackSlot(stackSlot))) : String.format("Can not set slot for %s to %s", this, stackSlot); + slot = stackSlot; + } +} diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Feb 27 16:36:38 2015 +0100 @@ -41,6 +41,7 @@ import com.oracle.graal.graph.Node.OptionalInput; import com.oracle.graal.graph.Node.Successor; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.nodeinfo.*; /** @@ -118,6 +119,11 @@ private final boolean isCanonicalizable; /** + * Determines if this node type implements {@link BinaryCommutative}. + */ + private final boolean isCommutative; + + /** * Determines if this node type implements {@link Simplifiable}. */ private final boolean isSimplifiable; @@ -133,6 +139,7 @@ assert NODE_CLASS.isAssignableFrom(clazz); this.isCanonicalizable = Canonicalizable.class.isAssignableFrom(clazz); + this.isCommutative = BinaryCommutative.class.isAssignableFrom(clazz); if (Canonicalizable.Unary.class.isAssignableFrom(clazz) || Canonicalizable.Binary.class.isAssignableFrom(clazz)) { assert Canonicalizable.Unary.class.isAssignableFrom(clazz) ^ Canonicalizable.Binary.class.isAssignableFrom(clazz) : clazz + " should implement either Unary or Binary, not both"; } @@ -238,6 +245,13 @@ } /** + * Determines if this node type implements {@link BinaryCommutative}. + */ + public boolean isCommutative() { + return isCommutative; + } + + /** * Determines if this node type implements {@link Simplifiable}. */ public boolean isSimplifiable() { diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Canonicalizable.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Canonicalizable.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Canonicalizable.java Fri Feb 27 16:36:38 2015 +0100 @@ -128,4 +128,22 @@ return canonical(tool, getX(), getY()); } } + + /** + * This sub-interface of {@link Canonicalizable.Binary} is for nodes with two inputs where the + * operation is commutative. It is used to improve GVN by trying to merge nodes with the same + * inputs in different order. + */ + public interface BinaryCommutative extends Binary { + + /** + * Ensure a canonical ordering of inputs for commutative nodes to improve GVN results. Order + * the inputs by increasing {@link Node#id} and call {@link Graph#findDuplicate(Node)} on + * the node if it's currently in a graph. It's assumed that if there was a constant on the + * left it's been moved to the right by other code and that ordering is left alone. + * + * @return the original node or another node with the same input ordering + */ + Node maybeCommuteInputs(); + } } diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Fri Feb 27 16:36:38 2015 +0100 @@ -93,14 +93,14 @@ @SuppressWarnings("unused") private static Value[] createNativeABICallerSaveRegisters(HotSpotVMConfig config, RegisterConfig regConfig) { - List callerSaveRegisters = new ArrayList<>(); - Collections.addAll(callerSaveRegisters, regConfig.getCallerSaveRegisters()); - // TODO: Saving callee saved registers as well seems unneccessary, however as of now it does - // not work without; needs further investigation - Collections.addAll(callerSaveRegisters, regConfig.getCalleeSaveLayout().registers); - Value[] nativeABICallerSaveRegisters = new Value[callerSaveRegisters.size()]; - for (int i = 0; i < callerSaveRegisters.size(); i++) { - nativeABICallerSaveRegisters[i] = callerSaveRegisters.get(i).asValue(); + Set callerSavedRegisters = new HashSet<>(); + Collections.addAll(callerSavedRegisters, regConfig.getCalleeSaveLayout().registers); + Collections.addAll(callerSavedRegisters, SPARC.fpuRegisters); + Value[] nativeABICallerSaveRegisters = new Value[callerSavedRegisters.size()]; + int i = 0; + for (Register reg : callerSavedRegisters) { + nativeABICallerSaveRegisters[i] = reg.asValue(); + i++; } return nativeABICallerSaveRegisters; } diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMonitorValueTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMonitorValueTest.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMonitorValueTest.java Fri Feb 27 16:36:38 2015 +0100 @@ -35,7 +35,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.test.*; -import com.oracle.graal.hotspot.meta.*; public class HotSpotMonitorValueTest extends GraalCompilerTest { @@ -53,14 +52,14 @@ assertNull(caller.caller()); assertDeepEquals(2, frame.numLocks); assertDeepEquals(2, caller.numLocks); - HotSpotMonitorValue lock1 = (HotSpotMonitorValue) frame.getLockValue(0); - HotSpotMonitorValue lock2 = (HotSpotMonitorValue) frame.getLockValue(1); - HotSpotMonitorValue lock3 = (HotSpotMonitorValue) caller.getLockValue(0); - HotSpotMonitorValue lock4 = (HotSpotMonitorValue) caller.getLockValue(1); + StackLockValue lock1 = (StackLockValue) frame.getLockValue(0); + StackLockValue lock2 = (StackLockValue) frame.getLockValue(1); + StackLockValue lock3 = (StackLockValue) caller.getLockValue(0); + StackLockValue lock4 = (StackLockValue) caller.getLockValue(1); - List locks = Arrays.asList(lock1, lock2, lock3, lock4); - for (HotSpotMonitorValue lock : locks) { - for (HotSpotMonitorValue other : locks) { + List locks = Arrays.asList(lock1, lock2, lock3, lock4); + for (StackLockValue lock : locks) { + for (StackLockValue other : locks) { if (other != lock) { // Every lock must have a different stack slot assertThat(lock.getSlot(), not(other.getSlot())); diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java Fri Feb 27 16:36:38 2015 +0100 @@ -26,7 +26,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.graph.*; -import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; @@ -57,7 +56,7 @@ JavaValue object = toValue(lock); boolean eliminated = object instanceof VirtualObject && state.monitorIdAt(lockIndex) != null; assert state.monitorIdAt(lockIndex) == null || state.monitorIdAt(lockIndex).getLockDepth() == lockDepth; - return new HotSpotMonitorValue(object, slot, eliminated); + return new StackLockValue(object, slot, eliminated); } @Override diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java Fri Feb 27 16:36:38 2015 +0100 @@ -26,12 +26,11 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.LIRInstruction.OperandMode; /** - * Extends {@link LIRFrameState} to handle {@link HotSpotMonitorValue}s correctly. + * Extends {@link LIRFrameState} to handle {@link StackLockValue}s correctly. */ class HotSpotLIRFrameState extends LIRFrameState { @@ -41,8 +40,8 @@ @Override protected Value processValue(LIRInstruction inst, InstructionValueProcedure proc, Value value) { - if (value instanceof HotSpotMonitorValue) { - HotSpotMonitorValue monitor = (HotSpotMonitorValue) value; + if (value instanceof StackLockValue) { + StackLockValue monitor = (StackLockValue) value; if (monitor.getOwner() instanceof Value) { Value owner = (Value) monitor.getOwner(); if (processed(owner)) { diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMonitorValue.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMonitorValue.java Fri Feb 27 16:35:54 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -/* - * 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.hotspot.meta; - -import static com.oracle.graal.api.code.ValueUtil.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; - -/** - * Represents lock information in the debug information. - */ -public final class HotSpotMonitorValue extends AbstractValue implements JavaValue { - - private static final long serialVersionUID = 8241681800464483691L; - - private JavaValue owner; - private StackSlotValue slot; - private final boolean eliminated; - - public HotSpotMonitorValue(JavaValue owner, StackSlotValue slot, boolean eliminated) { - super(LIRKind.Illegal); - this.owner = owner; - this.slot = slot; - this.eliminated = eliminated; - } - - public JavaValue getOwner() { - return owner; - } - - public void setOwner(JavaValue newOwner) { - this.owner = newOwner; - } - - public Value getSlot() { - return slot; - } - - public boolean isEliminated() { - return eliminated; - } - - @Override - public String toString() { - return "monitor[" + owner + (slot != null ? ", " + slot : "") + (eliminated ? ", eliminated" : "") + "]"; - } - - @Override - public int hashCode() { - final int prime = 43; - int result = super.hashCode(); - result = prime * result + (eliminated ? 1231 : 1237); - result = prime * result + owner.hashCode(); - result = prime * result + slot.hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof HotSpotMonitorValue) { - HotSpotMonitorValue other = (HotSpotMonitorValue) obj; - return super.equals(obj) && eliminated == other.eliminated && owner.equals(other.owner) && slot.equals(other.slot); - } - return false; - } - - public void setSlot(StackSlotValue stackSlot) { - assert slot == null || (isVirtualStackSlot(slot) && (slot.equals(stackSlot) || isStackSlot(stackSlot))) : String.format("Can not set slot for %s to %s", this, stackSlot); - slot = stackSlot; - } -} diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java Fri Feb 27 16:36:38 2015 +0100 @@ -195,14 +195,13 @@ } }; - ValuePositionProcedure useProcedure = (instruction, position) -> { - Value value = position.get(instruction); + InstructionValueConsumer useConsumer = (instruction, value, mode, flags) -> { if (isVariable(value)) { Variable var = (Variable) value; if (!phiConstants.get(var.index)) { DefUseTree tree = map.get(var); if (tree != null) { - tree.addUsage(block, instruction, position); + tree.addUsage(block, instruction, value); Debug.log("usage of %s : %s", var, instruction); } } @@ -214,8 +213,8 @@ // set instruction id to the index in the lir instruction list inst.setId(opId++); inst.visitEachOutput(loadConsumer); - inst.forEachInputPos(useProcedure); - inst.forEachAlivePos(useProcedure); + inst.forEachInput(useConsumer); + inst.forEachAlive(useConsumer); } } @@ -297,7 +296,7 @@ Debug.log("new move (%s) and inserted in block %s", move, block); // update usages for (UseEntry u : usages) { - u.getPosition().set(u.getInstruction(), variable); + u.setValue(variable); Debug.log("patched instruction %s", u.getInstruction()); } } diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/DefUseTree.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/DefUseTree.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/DefUseTree.java Fri Feb 27 16:36:38 2015 +0100 @@ -66,8 +66,8 @@ return "DefUseTree [" + instruction + "|" + block + "," + uses + "]"; } - public void addUsage(AbstractBlockBase b, LIRInstruction inst, ValuePosition position) { - uses.add(new UseEntry(b, inst, position)); + public void addUsage(AbstractBlockBase b, LIRInstruction inst, Value value) { + uses.add(new UseEntry(b, inst, value)); } public int usageCount() { diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/UseEntry.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/UseEntry.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/UseEntry.java Fri Feb 27 16:36:38 2015 +0100 @@ -33,12 +33,12 @@ private final AbstractBlockBase block; private final LIRInstruction instruction; - private final ValuePosition position; + private final Value value; - public UseEntry(AbstractBlockBase block, LIRInstruction instruction, ValuePosition position) { + public UseEntry(AbstractBlockBase block, LIRInstruction instruction, Value value) { this.block = block; this.instruction = instruction; - this.position = position; + this.value = value; } public LIRInstruction getInstruction() { @@ -49,16 +49,26 @@ return block; } - public ValuePosition getPosition() { - return position; + public void setValue(Value newValue) { + replaceValue(instruction, value, newValue); + } + + private static void replaceValue(LIRInstruction op, Value oldValue, Value newValue) { + ValueProcedure proc = (value, mode, flags) -> value.identityEquals(oldValue) ? newValue : value; + op.forEachAlive(proc); + op.forEachInput(proc); + op.forEachOutput(proc); + op.forEachTemp(proc); + op.forEachState(proc); } public Value getValue() { - return position.get(instruction); + return value; } @Override public String toString() { return "Use[" + getValue() + ":" + instruction + ":" + block + "]"; } + } diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/LIRPhase.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/LIRPhase.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/phases/LIRPhase.java Fri Feb 27 16:36:38 2015 +0100 @@ -78,10 +78,12 @@ } public final > void apply(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List linearScanOrder, C context, boolean dumpLIR) { - try (TimerCloseable a = timer.start(); Scope s = Debug.scope(getName(), this); Closeable c = memUseTracker.start()) { - run(target, lirGenRes, codeEmittingOrder, linearScanOrder, context); - if (dumpLIR && Debug.isDumpEnabled(PHASE_DUMP_LEVEL)) { - Debug.dump(PHASE_DUMP_LEVEL, lirGenRes.getLIR(), "After phase %s", getName()); + try (Scope s = Debug.scope(getName(), this)) { + try (TimerCloseable a = timer.start(); Closeable c = memUseTracker.start()) { + run(target, lirGenRes, codeEmittingOrder, linearScanOrder, context); + if (dumpLIR && Debug.isDumpEnabled(PHASE_DUMP_LEVEL)) { + Debug.dump(PHASE_DUMP_LEVEL, lirGenRes.getLIR(), "After phase %s", getName()); + } } } catch (Throwable e) { throw Debug.handle(e); diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java Fri Feb 27 16:36:38 2015 +0100 @@ -64,10 +64,11 @@ * inputs by increasing {@link Node#id} and call {@link Graph#findDuplicate(Node)} on the node * if it's currently in a graph. * - * @return the original node or another node with the same input ordering + * @return the original node or another node with the same inputs, ignoring ordering. */ @SuppressWarnings("deprecation") public LogicNode maybeCommuteInputs() { + assert this instanceof BinaryCommutative; if (x.getId() > y.getId()) { ValueNode tmp = x; x = y; diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AddNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AddNode.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AddNode.java Fri Feb 27 16:36:38 2015 +0100 @@ -27,6 +27,7 @@ import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp; import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.Add; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodeinfo.*; @@ -34,7 +35,7 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "+") -public class AddNode extends BinaryArithmeticNode implements NarrowableArithmeticNode { +public class AddNode extends BinaryArithmeticNode implements NarrowableArithmeticNode, BinaryCommutative { public static final NodeClass TYPE = NodeClass.create(AddNode.class); @@ -103,7 +104,7 @@ } else if (forY instanceof NegateNode) { return BinaryArithmeticNode.sub(forX, ((NegateNode) forY).getValue()); } - return this.maybeCommuteInputs(); + return this; } @Override diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Fri Feb 27 16:36:38 2015 +0100 @@ -25,9 +25,10 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.compiler.common.type.ArithmeticOpTable.*; -import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.*; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.And; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodeinfo.*; @@ -36,7 +37,7 @@ import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "&") -public final class AndNode extends BinaryArithmeticNode implements NarrowableArithmeticNode { +public final class AndNode extends BinaryArithmeticNode implements NarrowableArithmeticNode, BinaryCommutative { public static final NodeClass TYPE = NodeClass.create(AndNode.class); @@ -95,7 +96,7 @@ return reassociate(this, ValueNode.isConstantPredicate(), forX, forY); } - return this.maybeCommuteInputs(); + return this; } @Override diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryArithmeticNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryArithmeticNode.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryArithmeticNode.java Fri Feb 27 16:36:38 2015 +0100 @@ -37,7 +37,7 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo -public abstract class BinaryArithmeticNode extends BinaryNode implements ArithmeticLIRLowerable { +public abstract class BinaryArithmeticNode extends BinaryNode implements ArithmeticLIRLowerable, Canonicalizable.Binary { @SuppressWarnings("rawtypes") public static final NodeClass TYPE = NodeClass.create(BinaryArithmeticNode.class); @@ -252,4 +252,30 @@ } return false; } + + /** + * Ensure a canonical ordering of inputs for commutative nodes to improve GVN results. Order the + * inputs by increasing {@link Node#id} and call {@link Graph#findDuplicate(Node)} on the node + * if it's currently in a graph. It's assumed that if there was a constant on the left it's been + * moved to the right by other code and that ordering is left alone. + * + * @return the original node or another node with the same input ordering + */ + @SuppressWarnings("deprecation") + public BinaryNode maybeCommuteInputs() { + assert this instanceof BinaryCommutative; + if (!y.isConstant() && x.getId() > y.getId()) { + ValueNode tmp = x; + x = y; + y = tmp; + if (graph() != null) { + // See if this node already exists + BinaryNode duplicate = graph().findDuplicate(this); + if (duplicate != null) { + return duplicate; + } + } + } + return this; + } } diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java Fri Feb 27 16:36:38 2015 +0100 @@ -68,29 +68,4 @@ this.x = x; this.y = y; } - - /** - * Ensure a canonical ordering of inputs for commutative nodes to improve GVN results. Order the - * inputs by increasing {@link Node#id} and call {@link Graph#findDuplicate(Node)} on the node - * if it's currently in a graph. It's assumed that if there was a constant on the left it's been - * moved to the right by other code and that ordering is left alone. - * - * @return the original node or another node with the same input ordering - */ - @SuppressWarnings("deprecation") - public BinaryNode maybeCommuteInputs() { - if (!y.isConstant() && x.getId() > y.getId()) { - ValueNode tmp = x; - x = y; - y = tmp; - if (graph() != null) { - // See if this node already exists - BinaryNode duplicate = graph().findDuplicate(this); - if (duplicate != null) { - return duplicate; - } - } - } - return this; - } } diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Fri Feb 27 16:36:38 2015 +0100 @@ -38,7 +38,7 @@ * into variants that do not materialize the value (CompareIf, CompareGuard...) */ @NodeInfo -public abstract class CompareNode extends BinaryOpLogicNode { +public abstract class CompareNode extends BinaryOpLogicNode implements Canonicalizable.Binary { public static final NodeClass TYPE = NodeClass.create(CompareNode.class); protected final Condition condition; @@ -125,9 +125,6 @@ return duplicateModified(convertX.getValue(), convertY.getValue()); } } - if (condition.isCommutative()) { - return this.maybeCommuteInputs(); - } return this; } diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java Fri Feb 27 16:36:38 2015 +0100 @@ -27,13 +27,14 @@ import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "==") -public final class FloatEqualsNode extends CompareNode { +public final class FloatEqualsNode extends CompareNode implements BinaryCommutative { public static final NodeClass TYPE = NodeClass.create(FloatEqualsNode.class); public FloatEqualsNode(ValueNode x, ValueNode y) { diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Fri Feb 27 16:36:38 2015 +0100 @@ -27,13 +27,14 @@ import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "==") -public final class IntegerEqualsNode extends CompareNode { +public final class IntegerEqualsNode extends CompareNode implements BinaryCommutative { public static final NodeClass TYPE = NodeClass.create(IntegerEqualsNode.class); public IntegerEqualsNode(ValueNode x, ValueNode y) { diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Fri Feb 27 16:36:38 2015 +0100 @@ -24,6 +24,7 @@ import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; @@ -34,7 +35,7 @@ * both x and y. */ @NodeInfo -public final class IntegerTestNode extends BinaryOpLogicNode { +public final class IntegerTestNode extends BinaryOpLogicNode implements BinaryCommutative { public static final NodeClass TYPE = NodeClass.create(IntegerTestNode.class); public IntegerTestNode(ValueNode x, ValueNode y) { @@ -55,6 +56,6 @@ return LogicConstantNode.contradiction(); } } - return this.maybeCommuteInputs(); + return this; } } diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java Fri Feb 27 16:36:38 2015 +0100 @@ -26,8 +26,9 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp; -import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.*; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.Mul; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodeinfo.*; @@ -35,7 +36,7 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "*") -public class MulNode extends BinaryArithmeticNode implements NarrowableArithmeticNode { +public class MulNode extends BinaryArithmeticNode implements NarrowableArithmeticNode, BinaryCommutative { public static final NodeClass TYPE = NodeClass.create(MulNode.class); diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Fri Feb 27 16:36:38 2015 +0100 @@ -25,9 +25,10 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.compiler.common.type.ArithmeticOpTable.*; -import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.*; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.Or; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodeinfo.*; @@ -36,7 +37,7 @@ import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "|") -public final class OrNode extends BinaryArithmeticNode { +public final class OrNode extends BinaryArithmeticNode implements BinaryCommutative { public static final NodeClass TYPE = NodeClass.create(OrNode.class); @@ -83,7 +84,7 @@ } return reassociate(this, ValueNode.isConstantPredicate(), forX, forY); } - return this.maybeCommuteInputs(); + return this; } @Override diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/PointerEqualsNode.java Fri Feb 27 16:36:38 2015 +0100 @@ -25,13 +25,14 @@ import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "==") -public class PointerEqualsNode extends CompareNode { +public class PointerEqualsNode extends CompareNode implements BinaryCommutative { public static final NodeClass TYPE = NodeClass.create(PointerEqualsNode.class); diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Fri Feb 27 16:36:38 2015 +0100 @@ -25,9 +25,10 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.compiler.common.type.ArithmeticOpTable.*; -import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.*; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp.Xor; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodeinfo.*; @@ -36,7 +37,7 @@ import com.oracle.graal.nodes.util.*; @NodeInfo(shortName = "^") -public final class XorNode extends BinaryArithmeticNode { +public final class XorNode extends BinaryArithmeticNode implements BinaryCommutative { public static final NodeClass TYPE = NodeClass.create(XorNode.class); @@ -84,7 +85,7 @@ } return reassociate(this, ValueNode.isConstantPredicate(), forX, forY); } - return this.maybeCommuteInputs(); + return this; } @Override diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryAccess.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryAccess.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryAccess.java Fri Feb 27 16:36:38 2015 +0100 @@ -32,14 +32,10 @@ LocationIdentity getLocationIdentity(); - default MemoryNode getLastLocationAccess() { - return null; - } + MemoryNode getLastLocationAccess(); /** * @param lla the {@link MemoryNode} that represents the last kill of the location */ - default void setLastLocationAccess(MemoryNode lla) { - // empty - } + void setLastLocationAccess(MemoryNode lla); } diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Fri Feb 27 16:36:38 2015 +0100 @@ -30,6 +30,7 @@ import com.oracle.graal.graph.Graph.NodeEventListener; import com.oracle.graal.graph.Graph.NodeEventScope; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.graph.spi.Canonicalizable.BinaryCommutative; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -261,6 +262,9 @@ Node canonical; try (AutoCloseable verify = getCanonicalizeableContractAssertion(node)) { canonical = ((Canonicalizable) node).canonical(tool); + if (canonical == node && nodeClass.isCommutative()) { + canonical = ((BinaryCommutative) node).maybeCommuteInputs(); + } } if (performReplacement(node, canonical)) { return true; diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Fri Feb 27 16:36:38 2015 +0100 @@ -251,7 +251,9 @@ @Override protected NodeBitMap getInitialState() { - return graph.createNodeBitMap(); + NodeBitMap ret = graph.createNodeBitMap(); + ret.markAll(graph.getNodes().filter(ConstantNode.class)); + return ret; } @Override diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java Fri Feb 27 16:36:38 2015 +0100 @@ -51,6 +51,8 @@ /** Length of both arrays. */ @Input ValueNode length; + @OptionalInput(InputType.Memory) MemoryNode lastLocationAccess; + public ArrayEqualsNode(ValueNode array1, ValueNode array2, ValueNode length) { super(TYPE, StampFactory.forKind(Kind.Boolean)); // Ignore nullness in stamp equality test @@ -139,4 +141,13 @@ public LocationIdentity getLocationIdentity() { return NamedLocationIdentity.getArrayLocation(kind); } + + public MemoryNode getLastLocationAccess() { + return lastLocationAccess; + } + + public void setLastLocationAccess(MemoryNode lla) { + updateUsages(ValueNodeUtil.asNode(lastLocationAccess), ValueNodeUtil.asNode(lla)); + lastLocationAccess = lla; + } } diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/TruffleGraphBuilderPlugins.java Fri Feb 27 16:36:38 2015 +0100 @@ -86,42 +86,38 @@ public static void registerExactMathPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { Registration r = new Registration(plugins, metaAccess, ExactMath.class); - r.register2("addExact", Integer.TYPE, Integer.TYPE, new InvocationPlugin() { - public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { - builder.push(Kind.Int.getStackKind(), builder.append(new IntegerAddExactNode(x, y))); - return true; - } - }); - r.register2("addExact", Long.TYPE, Long.TYPE, new InvocationPlugin() { - public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { - builder.push(Kind.Long, builder.append(new IntegerAddExactNode(x, y))); - return true; - } - }); - r.register2("subtractExact", Integer.TYPE, Integer.TYPE, new InvocationPlugin() { - public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { - builder.push(Kind.Int.getStackKind(), builder.append(new IntegerSubExactNode(x, y))); - return true; - } - }); - r.register2("subtractExact", Long.TYPE, Long.TYPE, new InvocationPlugin() { - public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { - builder.push(Kind.Long, builder.append(new IntegerSubExactNode(x, y))); - return true; - } - }); - r.register2("multiplyExact", Integer.TYPE, Integer.TYPE, new InvocationPlugin() { - public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { - builder.push(Kind.Int.getStackKind(), builder.append(new IntegerMulExactNode(x, y))); - return true; - } - }); - r.register2("multiplyExact", Long.TYPE, Long.TYPE, new InvocationPlugin() { - public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { - builder.push(Kind.Long, builder.append(new IntegerMulExactNode(x, y))); - return true; - } - }); + for (Kind kind : new Kind[]{Kind.Int, Kind.Long}) { + r.register2("addExact", kind.toJavaClass(), kind.toJavaClass(), new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { + builder.push(kind.getStackKind(), builder.append(new IntegerAddExactNode(x, y))); + return true; + } + }); + r.register2("subtractExact", kind.toJavaClass(), kind.toJavaClass(), new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { + builder.push(kind.getStackKind(), builder.append(new IntegerSubExactNode(x, y))); + return true; + } + }); + r.register2("multiplyExact", kind.toJavaClass(), kind.toJavaClass(), new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { + builder.push(kind.getStackKind(), builder.append(new IntegerMulExactNode(x, y))); + return true; + } + }); + r.register2("multiplyHigh", kind.toJavaClass(), kind.toJavaClass(), new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { + builder.push(kind.getStackKind(), builder.append(new IntegerMulHighNode(x, y))); + return true; + } + }); + r.register2("multiplyHighUnsigned", kind.toJavaClass(), kind.toJavaClass(), new InvocationPlugin() { + public boolean apply(GraphBuilderContext builder, ValueNode x, ValueNode y) { + builder.push(kind.getStackKind(), builder.append(new UnsignedMulHighNode(x, y))); + return true; + } + }); + } } public static void registerCompilerDirectivesPlugins(MetaAccessProvider metaAccess, InvocationPlugins plugins) { diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Fri Feb 27 16:36:38 2015 +0100 @@ -41,7 +41,6 @@ public abstract class Node implements NodeInterface, Cloneable { @CompilationFinal private Node parent; - @CompilationFinal private SourceSection sourceSection; /** @@ -573,11 +572,7 @@ public final void atomic(Runnable closure) { RootNode rootNode = getRootNode(); - if (rootNode != null) { - synchronized (rootNode) { - closure.run(); - } - } else { + synchronized (rootNode != null ? rootNode : GIL) { closure.run(); } } @@ -585,14 +580,10 @@ public final T atomic(Callable closure) { try { RootNode rootNode = getRootNode(); - if (rootNode != null) { - synchronized (rootNode) { - return closure.call(); - } - } else { + synchronized (rootNode != null ? rootNode : GIL) { return closure.call(); } - } catch (RuntimeException e) { + } catch (RuntimeException | Error e) { throw e; } catch (Exception e) { throw new RuntimeException(e); @@ -625,4 +616,6 @@ } return ""; } + + private static final Object GIL = new Object(); } diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Fri Feb 27 16:36:38 2015 +0100 @@ -696,6 +696,42 @@ return false; } + /** + * Executes a closure for every non-null child of the parent node. + * + * @return {@code true} if all children were visited, {@code false} otherwise + */ + public static boolean forEachChild(Node parent, NodeVisitor visitor) { + Objects.requireNonNull(visitor); + NodeClass parentNodeClass = NodeClass.get(parent.getClass()); + + for (NodeField field : parentNodeClass.getChildFields()) { + Object child = field.getObject(parent); + if (child != null) { + if (!visitor.visit((Node) child)) { + return false; + } + } + } + + for (NodeField field : parentNodeClass.getChildrenFields()) { + Object arrayObject = field.getObject(parent); + if (arrayObject != null) { + Object[] array = (Object[]) arrayObject; + for (int i = 0; i < array.length; i++) { + Object child = array[i]; + if (child != null) { + if (!visitor.visit((Node) child)) { + return false; + } + } + } + } + } + + return true; + } + /** Returns all declared fields in the class hierarchy. */ private static Field[] getAllFields(Class clazz) { Field[] declaredFields = clazz.getDeclaredFields(); diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/tools/CoverageTracker.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/tools/CoverageTracker.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/tools/CoverageTracker.java Fri Feb 27 16:36:38 2015 +0100 @@ -27,13 +27,11 @@ import java.io.*; import java.util.*; import java.util.Map.Entry; -import java.util.concurrent.atomic.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.instrument.*; import com.oracle.truffle.api.instrument.impl.*; import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.api.source.*; /** @@ -160,7 +158,7 @@ curSource = source; curLineTable = new Long[source.getLineCount()]; } - curLineTable[lineNo - 1] = entry.getValue().count.longValue(); + curLineTable[lineNo - 1] = entry.getValue().count; } if (curSource != null) { result.put(curSource, curLineTable); @@ -206,7 +204,7 @@ while (curLineNo < lineNo) { displayLine(out, null, curSource, curLineNo++); } - displayLine(out, entry.getValue().count, curSource, curLineNo++); + displayLine(out, entry.getValue(), curSource, curLineNo++); } if (curSource != null) { while (curLineNo <= curSource.getLineCount()) { @@ -215,11 +213,11 @@ } } - private static void displayLine(PrintStream out, AtomicLong value, Source source, int lineNo) { - if (value == null) { + private static void displayLine(PrintStream out, CoverageRecord record, Source source, int lineNo) { + if (record == null) { out.format("%14s", " "); } else { - out.format("(%12d)", value.longValue()); + out.format("(%12d)", record.count); } out.format(" %3d: ", lineNo); out.println(source.getCode(lineNo)); @@ -227,33 +225,25 @@ /** * A listener for events at each instrumented AST location. This listener counts - * "execution calls" to the instrumented node and is stateful. State in listeners must - * be considered carefully since ASTs, along with all instrumentation (including event listener - * such as this) are routinely cloned by the Truffle runtime. AST cloning is shallow - * (for non- {@link Child} nodes), so in this case the actual count is shared among all - * the clones; the count is also held in a table indexed by source line. - *

- * In contrast, a primitive field would not be shared among clones and resulting counts - * would not be accurate. + * "execution calls" to the instrumented node. */ - private final class CoverageEventListener extends DefaultEventListener { + private final class CoverageRecord extends DefaultEventListener { - /** - * Shared by all clones of the associated instrument and by the table of counters for the - * line. - */ - private final AtomicLong count; + private final SourceSection srcSection; // The text of the code being counted + private Instrument instrument; // The attached Instrument, in case need to remove. + private long count = 0; - CoverageEventListener(AtomicLong count) { - this.count = count; + CoverageRecord(SourceSection srcSection) { + this.srcSection = srcSection; } @Override public void enter(Node node, VirtualFrame vFrame) { if (isEnabled()) { - count.getAndIncrement(); + count++; } } + } private static final class LineLocationEntryComparator implements Comparator> { @@ -282,35 +272,23 @@ if (record != null) { // Another node starts on same line; count only the first (textually) if (srcSection.getCharIndex() > record.srcSection.getCharIndex()) { - // Record already in place, corresponds to code earlier on line + // Existing record, corresponds to code earlier on line return; } else { - // Record already in place, corresponds to later code; replace it + // Existing record, corresponds to code at a later position; replace it record.instrument.dispose(); } } - final AtomicLong count = new AtomicLong(); - final CoverageEventListener eventListener = new CoverageEventListener(count); - final Instrument instrument = Instrument.create(eventListener, CoverageTracker.class.getSimpleName()); + + final CoverageRecord coverage = new CoverageRecord(srcSection); + final Instrument instrument = Instrument.create(coverage, CoverageTracker.class.getSimpleName()); + coverage.instrument = instrument; instruments.add(instrument); probe.attach(instrument); - coverageMap.put(lineLocation, new CoverageRecord(srcSection, instrument, count)); + coverageMap.put(lineLocation, coverage); } } } } - private class CoverageRecord { - - final SourceSection srcSection; // The text of the code being counted - final Instrument instrument; // The attached Instrument, in case need to remove. - final AtomicLong count; - - CoverageRecord(SourceSection srcSection, Instrument instrument, AtomicLong count) { - this.srcSection = srcSection; - this.instrument = instrument; - this.count = count; - } - } - } diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java Fri Feb 27 16:36:38 2015 +0100 @@ -51,25 +51,26 @@ @SuppressWarnings("unchecked") @Override public Object profile(Object value) { - if (cachedValue != GENERIC) { - if (cachedValue instanceof Byte && value instanceof Byte && (byte) cachedValue == (byte) value) { - return cachedValue; - } else if (cachedValue instanceof Short && value instanceof Short && (short) cachedValue == (short) value) { - return cachedValue; - } else if (cachedValue instanceof Integer && value instanceof Integer && (int) cachedValue == (int) value) { - return cachedValue; - } else if (cachedValue instanceof Long && value instanceof Long && (long) cachedValue == (long) value) { - return cachedValue; - } else if (cachedValue instanceof Float && value instanceof Float && exactCompare((float) cachedValue, (float) value)) { - return cachedValue; - } else if (cachedValue instanceof Double && value instanceof Double && exactCompare((double) cachedValue, (double) value)) { - return cachedValue; - } else if (cachedValue instanceof Boolean && value instanceof Boolean && (boolean) cachedValue == (boolean) value) { - return cachedValue; - } else if (cachedValue instanceof Character && value instanceof Character && (char) cachedValue == (char) value) { - return cachedValue; - } else if (cachedValue == value) { - return cachedValue; + Object snapshot = this.cachedValue; + if (snapshot != GENERIC) { + if (snapshot instanceof Byte && value instanceof Byte && (byte) snapshot == (byte) value) { + return snapshot; + } else if (snapshot instanceof Short && value instanceof Short && (short) snapshot == (short) value) { + return snapshot; + } else if (snapshot instanceof Integer && value instanceof Integer && (int) snapshot == (int) value) { + return snapshot; + } else if (snapshot instanceof Long && value instanceof Long && (long) snapshot == (long) value) { + return snapshot; + } else if (snapshot instanceof Float && value instanceof Float && exactCompare((float) snapshot, (float) value)) { + return snapshot; + } else if (snapshot instanceof Double && value instanceof Double && exactCompare((double) snapshot, (double) value)) { + return snapshot; + } else if (snapshot instanceof Boolean && value instanceof Boolean && (boolean) snapshot == (boolean) value) { + return snapshot; + } else if (snapshot instanceof Character && value instanceof Character && (char) snapshot == (char) value) { + return snapshot; + } else if (snapshot == value) { + return snapshot; } else { cacheMiss(value); } @@ -78,9 +79,10 @@ } public byte profile(byte value) { - if (cachedValue != GENERIC) { - if (cachedValue instanceof Byte && (byte) cachedValue == value) { - return (byte) cachedValue; + Object snapshot = this.cachedValue; + if (snapshot != GENERIC) { + if (snapshot instanceof Byte && (byte) snapshot == value) { + return (byte) snapshot; } else { cacheMiss(value); } @@ -89,9 +91,10 @@ } public short profile(short value) { - if (cachedValue != GENERIC) { - if (cachedValue instanceof Short && (short) cachedValue == value) { - return (short) cachedValue; + Object snapshot = this.cachedValue; + if (snapshot != GENERIC) { + if (snapshot instanceof Short && (short) snapshot == value) { + return (short) snapshot; } else { cacheMiss(value); } @@ -100,9 +103,10 @@ } public int profile(int value) { - if (cachedValue != GENERIC) { - if (cachedValue instanceof Integer && (int) cachedValue == value) { - return (int) cachedValue; + Object snapshot = this.cachedValue; + if (snapshot != GENERIC) { + if (snapshot instanceof Integer && (int) snapshot == value) { + return (int) snapshot; } else { cacheMiss(value); } @@ -111,9 +115,10 @@ } public long profile(long value) { - if (cachedValue != GENERIC) { - if (cachedValue instanceof Long && (long) cachedValue == value) { - return (long) cachedValue; + Object snapshot = this.cachedValue; + if (snapshot != GENERIC) { + if (snapshot instanceof Long && (long) snapshot == value) { + return (long) snapshot; } else { cacheMiss(value); } @@ -122,9 +127,10 @@ } public float profile(float value) { - if (cachedValue != GENERIC) { - if (cachedValue instanceof Float && exactCompare((float) cachedValue, value)) { - return (float) cachedValue; + Object snapshot = this.cachedValue; + if (snapshot != GENERIC) { + if (snapshot instanceof Float && exactCompare((float) snapshot, value)) { + return (float) snapshot; } else { cacheMiss(value); } @@ -133,9 +139,10 @@ } public double profile(double value) { - if (cachedValue != GENERIC) { - if (cachedValue instanceof Double && exactCompare((double) cachedValue, value)) { - return (double) cachedValue; + Object snapshot = this.cachedValue; + if (snapshot != GENERIC) { + if (snapshot instanceof Double && exactCompare((double) snapshot, value)) { + return (double) snapshot; } else { cacheMiss(value); } @@ -144,9 +151,10 @@ } public boolean profile(boolean value) { - if (cachedValue != GENERIC) { - if (cachedValue instanceof Boolean && (boolean) cachedValue == value) { - return (boolean) cachedValue; + Object snapshot = this.cachedValue; + if (snapshot != GENERIC) { + if (snapshot instanceof Boolean && (boolean) snapshot == value) { + return (boolean) snapshot; } else { cacheMiss(value); } @@ -155,9 +163,10 @@ } public char profile(char value) { - if (cachedValue != GENERIC) { - if (cachedValue instanceof Character && (char) cachedValue == value) { - return (char) cachedValue; + Object snapshot = this.cachedValue; + if (snapshot != GENERIC) { + if (snapshot instanceof Character && (char) snapshot == value) { + return (char) snapshot; } else { cacheMiss(value); } @@ -183,6 +192,7 @@ } private void cacheMiss(Object value) { + // TODO should we try to handle this more atomically? CompilerDirectives.transferToInterpreterAndInvalidate(); if (cachedValue == UNINITIALIZED) { cachedValue = value; @@ -208,17 +218,18 @@ } private String formatValue() { - if (cachedValue == null) { + Object snapshot = this.cachedValue; + if (snapshot == null) { return "null"; - } else if (cachedValue == UNINITIALIZED) { + } else if (snapshot == UNINITIALIZED) { return "uninitialized"; - } else if (cachedValue == GENERIC) { + } else if (snapshot == GENERIC) { return "generic"; - } else if (cachedValue instanceof Byte || cachedValue instanceof Short || cachedValue instanceof Integer || cachedValue instanceof Long || cachedValue instanceof Float || - cachedValue instanceof Double || cachedValue instanceof Boolean || cachedValue instanceof Character) { - return String.format("%s=%s", cachedValue.getClass().getSimpleName(), cachedValue); + } else if (snapshot instanceof Byte || snapshot instanceof Short || snapshot instanceof Integer || snapshot instanceof Long || snapshot instanceof Float || snapshot instanceof Double || + snapshot instanceof Boolean || snapshot instanceof Character) { + return String.format("%s=%s", snapshot.getClass().getSimpleName(), snapshot); } else { - return String.format("%s@%x", cachedValue.getClass().getSimpleName(), Objects.hash(cachedValue)); + return String.format("%s@%x", snapshot.getClass().getSimpleName(), Objects.hash(snapshot)); } } } diff -r afad10e79e13 -r cb701331de39 graal/com.oracle.truffle.object/src/com/oracle/truffle/object/ShapeImpl.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/ShapeImpl.java Fri Feb 27 16:35:54 2015 +0100 +++ b/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/ShapeImpl.java Fri Feb 27 16:36:38 2015 +0100 @@ -353,9 +353,8 @@ */ private ShapeImpl addPropertyInternal(Property prop) { CompilerAsserts.neverPartOfCompilation(); - assert prop.isShadow() || !(this.hasProperty(prop.getKey())) : "duplicate property"; + assert prop.isShadow() || !(this.hasProperty(prop.getKey())) : "duplicate property " + prop.getKey(); assert !getPropertyListInternal(false).contains(prop); - // invalidatePropertyAssumption(prop.getName()); AddPropertyTransition addTransition = new AddPropertyTransition(prop); ShapeImpl cachedShape = queryTransition(addTransition); @@ -653,7 +652,7 @@ newShape = newShape.applyTransition(previous, true); } - getTransitionMapForWrite().put(transition, newShape); + addIndirectTransition(transition, newShape); return newShape; } else { return null; @@ -899,7 +898,7 @@ private Property[] createPropertiesArray() { propertyListAllocCount.inc(); Property[] propertiesArray = new Property[getPropertyCount()]; - List ownProperties = getPropertyList(ALL); + List ownProperties = getPropertyList(); assert ownProperties.size() == getPropertyCount(); for (int i = 0; i < getPropertyCount(); i++) { propertiesArray[i] = ownProperties.get(i); @@ -1099,7 +1098,7 @@ /** * Match all filter. */ - public static final Pred ALL = new Pred() { + private static final Pred ALL = new Pred() { public boolean test(Property t) { return true; } diff -r afad10e79e13 -r cb701331de39 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Fri Feb 27 16:35:54 2015 +0100 +++ b/src/share/vm/classfile/systemDictionary.hpp Fri Feb 27 16:36:38 2015 +0100 @@ -198,7 +198,6 @@ GRAAL_ONLY(do_klass(HotSpotNmethod_klass, com_oracle_graal_hotspot_meta_HotSpotNmethod, Graal)) \ GRAAL_ONLY(do_klass(HotSpotResolvedJavaMethodImpl_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethodImpl, Graal)) \ GRAAL_ONLY(do_klass(HotSpotResolvedObjectTypeImpl_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedObjectTypeImpl, Graal)) \ - GRAAL_ONLY(do_klass(HotSpotMonitorValue_klass, com_oracle_graal_hotspot_meta_HotSpotMonitorValue, Graal)) \ GRAAL_ONLY(do_klass(HotSpotCompressedNullConstant_klass, com_oracle_graal_hotspot_meta_HotSpotCompressedNullConstant, Graal)) \ GRAAL_ONLY(do_klass(HotSpotObjectConstantImpl_klass, com_oracle_graal_hotspot_meta_HotSpotObjectConstantImpl, Graal)) \ GRAAL_ONLY(do_klass(HotSpotMetaspaceConstantImpl_klass, com_oracle_graal_hotspot_meta_HotSpotMetaspaceConstantImpl, Graal)) \ @@ -227,6 +226,7 @@ GRAAL_ONLY(do_klass(RegisterValue_klass, com_oracle_graal_api_code_RegisterValue, Graal)) \ GRAAL_ONLY(do_klass(RegisterCategory_klass, com_oracle_graal_api_code_Register_RegisterCategory, Graal)) \ GRAAL_ONLY(do_klass(StackSlot_klass, com_oracle_graal_api_code_StackSlot, Graal)) \ + GRAAL_ONLY(do_klass(StackLockValue_klass, com_oracle_graal_api_code_StackLockValue, Graal)) \ GRAAL_ONLY(do_klass(VirtualObject_klass, com_oracle_graal_api_code_VirtualObject, Graal)) \ GRAAL_ONLY(do_klass(SpeculationLog_klass, com_oracle_graal_api_code_SpeculationLog, Graal)) \ GRAAL_ONLY(do_klass(JavaConstant_klass, com_oracle_graal_api_meta_JavaConstant, Graal)) \ diff -r afad10e79e13 -r cb701331de39 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Fri Feb 27 16:35:54 2015 +0100 +++ b/src/share/vm/classfile/vmSymbols.hpp Fri Feb 27 16:36:38 2015 +0100 @@ -305,7 +305,6 @@ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotNmethod, "com/oracle/graal/hotspot/meta/HotSpotNmethod")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethodImpl, "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotResolvedObjectTypeImpl, "com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl")) \ - GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotMonitorValue, "com/oracle/graal/hotspot/meta/HotSpotMonitorValue")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotCompressedNullConstant, "com/oracle/graal/hotspot/meta/HotSpotCompressedNullConstant")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotObjectConstantImpl, "com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotMetaspaceConstantImpl,"com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstantImpl")) \ @@ -343,6 +342,7 @@ GRAAL_ONLY(template(com_oracle_graal_api_code_RegisterValue, "com/oracle/graal/api/code/RegisterValue")) \ GRAAL_ONLY(template(com_oracle_graal_api_code_Register_RegisterCategory, "com/oracle/graal/api/code/Register$RegisterCategory")) \ GRAAL_ONLY(template(com_oracle_graal_api_code_StackSlot, "com/oracle/graal/api/code/StackSlot")) \ + GRAAL_ONLY(template(com_oracle_graal_api_code_StackLockValue, "com/oracle/graal/api/code/StackLockValue")) \ GRAAL_ONLY(template(com_oracle_graal_api_code_VirtualObject, "com/oracle/graal/api/code/VirtualObject")) \ GRAAL_ONLY(template(com_oracle_graal_api_code_RegisterSaveLayout, "com/oracle/graal/api/code/RegisterSaveLayout")) \ GRAAL_ONLY(template(com_oracle_graal_api_code_InvalidInstalledCodeException, "com/oracle/graal/api/code/InvalidInstalledCodeException")) \ diff -r afad10e79e13 -r cb701331de39 src/share/vm/code/debugInfo.cpp --- a/src/share/vm/code/debugInfo.cpp Fri Feb 27 16:35:54 2015 +0100 +++ b/src/share/vm/code/debugInfo.cpp Fri Feb 27 16:36:38 2015 +0100 @@ -52,7 +52,7 @@ #ifdef ASSERT assert(_obj_pool != NULL, "object pool does not exist"); for (int i = _obj_pool->length() - 1; i >= 0; i--) { - assert(((ObjectValue*) _obj_pool->at(i))->id() != id, "should not be read twice"); + assert(_obj_pool->at(i)->as_ObjectValue()->id() != id, "should not be read twice"); } #endif ObjectValue* result = new ObjectValue(id); @@ -66,7 +66,7 @@ int id = read_int(); assert(_obj_pool != NULL, "object pool does not exist"); for (int i = _obj_pool->length() - 1; i >= 0; i--) { - ObjectValue* ov = (ObjectValue*) _obj_pool->at(i); + ObjectValue* ov = _obj_pool->at(i)->as_ObjectValue(); if (ov->id() == id) { return ov; } diff -r afad10e79e13 -r cb701331de39 src/share/vm/code/debugInfo.hpp --- a/src/share/vm/code/debugInfo.hpp Fri Feb 27 16:35:54 2015 +0100 +++ b/src/share/vm/code/debugInfo.hpp Fri Feb 27 16:36:38 2015 +0100 @@ -41,6 +41,7 @@ // - ConstantValue describes a constant class ConstantOopReadValue; +class ObjectValue; class ScopeValue: public ResourceObj { public: @@ -58,6 +59,11 @@ return (ConstantOopReadValue*) this; } + ObjectValue* as_ObjectValue() { + assert(is_object(), "must be"); + return (ObjectValue*)this; + } + // Serialization of debugging information virtual void write_on(DebugInfoWriteStream* stream) = 0; static ScopeValue* read_from(DebugInfoReadStream* stream); diff -r afad10e79e13 -r cb701331de39 src/share/vm/code/debugInfoRec.cpp --- a/src/share/vm/code/debugInfoRec.cpp Fri Feb 27 16:35:54 2015 +0100 +++ b/src/share/vm/code/debugInfoRec.cpp Fri Feb 27 16:36:38 2015 +0100 @@ -392,7 +392,7 @@ PcDesc* last_pd = &_pcs[_pcs_length-1]; if (objects != NULL) { for (int i = objects->length() - 1; i >= 0; i--) { - ((ObjectValue*) objects->at(i))->set_visited(false); + objects->at(i)->as_ObjectValue()->set_visited(false); } } int offset = serialize_scope_values(objects); diff -r afad10e79e13 -r cb701331de39 src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Fri Feb 27 16:35:54 2015 +0100 +++ b/src/share/vm/code/nmethod.cpp Fri Feb 27 16:36:38 2015 +0100 @@ -2749,7 +2749,10 @@ continue; ScopeDesc* sd = scope_desc_at(p->real_pc(this)); - sd->print_on(tty, p); + while (sd != NULL) { + sd->print_on(tty, p); + sd = sd->sender(); + } } } diff -r afad10e79e13 -r cb701331de39 src/share/vm/code/scopeDesc.cpp --- a/src/share/vm/code/scopeDesc.cpp Fri Feb 27 16:35:54 2015 +0100 +++ b/src/share/vm/code/scopeDesc.cpp Fri Feb 27 16:36:38 2015 +0100 @@ -230,7 +230,7 @@ if (NOT_GRAAL(DoEscapeAnalysis &&) is_top() && _objects != NULL) { tty->print_cr("Objects"); for (int i = 0; i < _objects->length(); i++) { - ObjectValue* sv = (ObjectValue*) _objects->at(i); + ObjectValue* sv = _objects->at(i)->as_ObjectValue(); tty->print(" - %d: ", sv->id()); sv->print_fields_on(tty); tty->cr(); diff -r afad10e79e13 -r cb701331de39 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Fri Feb 27 16:35:54 2015 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Fri Feb 27 16:36:38 2015 +0100 @@ -365,19 +365,19 @@ } MonitorValue* CodeInstaller::get_monitor_value(oop value, int total_frame_size, GrowableArray* objects, OopRecorder* oop_recorder) { - guarantee(value->is_a(HotSpotMonitorValue::klass()), "Monitors must be of type MonitorValue"); + guarantee(value->is_a(StackLockValue::klass()), "Monitors must be of type MonitorValue"); ScopeValue* second = NULL; - ScopeValue* owner_value = get_scope_value(HotSpotMonitorValue::owner(value), total_frame_size, objects, second, oop_recorder); + ScopeValue* owner_value = get_scope_value(StackLockValue::owner(value), total_frame_size, objects, second, oop_recorder); assert(second == NULL, "monitor cannot occupy two stack slots"); - ScopeValue* lock_data_value = get_scope_value(HotSpotMonitorValue::slot(value), total_frame_size, objects, second, oop_recorder); + ScopeValue* lock_data_value = get_scope_value(StackLockValue::slot(value), total_frame_size, objects, second, oop_recorder); assert(second == lock_data_value, "monitor is LONG value that occupies two stack slots"); assert(lock_data_value->is_location(), "invalid monitor location"); Location lock_data_loc = ((LocationValue*)lock_data_value)->location(); bool eliminated = false; - if (HotSpotMonitorValue::eliminated(value)) { + if (StackLockValue::eliminated(value)) { eliminated = true; } diff -r afad10e79e13 -r cb701331de39 src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Fri Feb 27 16:35:54 2015 +0100 +++ b/src/share/vm/graal/graalJavaAccess.hpp Fri Feb 27 16:36:38 2015 +0100 @@ -243,10 +243,10 @@ oop_field(VirtualObject, type, "Lcom/oracle/graal/api/meta/ResolvedJavaType;") \ objArrayOop_field(VirtualObject, values, "[Lcom/oracle/graal/api/meta/JavaValue;") \ end_class \ - start_class(HotSpotMonitorValue) \ - oop_field(HotSpotMonitorValue, owner, "Lcom/oracle/graal/api/meta/JavaValue;") \ - oop_field(HotSpotMonitorValue, slot, "Lcom/oracle/graal/api/code/StackSlotValue;") \ - boolean_field(HotSpotMonitorValue, eliminated) \ + start_class(StackLockValue) \ + oop_field(StackLockValue, owner, "Lcom/oracle/graal/api/meta/JavaValue;") \ + oop_field(StackLockValue, slot, "Lcom/oracle/graal/api/code/StackSlotValue;") \ + boolean_field(StackLockValue, eliminated) \ end_class \ start_class(SpeculationLog) \ oop_field(SpeculationLog, lastFailed, "Ljava/lang/Object;") \ diff -r afad10e79e13 -r cb701331de39 src/share/vm/runtime/vframe.cpp --- a/src/share/vm/runtime/vframe.cpp Fri Feb 27 16:35:54 2015 +0100 +++ b/src/share/vm/runtime/vframe.cpp Fri Feb 27 16:36:38 2015 +0100 @@ -274,7 +274,7 @@ // Get oopmap describing oops and int for current bci InterpreterOopMap oop_mask; if ((TraceDeoptimization && Verbose) GRAAL_ONLY( || PrintDeoptimizationDetails)) { - methodHandle m_h(thread(), method()); + methodHandle m_h(Thread::current(), method()); OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask); } else { method()->mask_for(bci(), &oop_mask);