# HG changeset patch # User Doug Simon # Date 1366994336 -7200 # Node ID bdf4604fec2ebfc8058a54f8405f85735d0a666d # Parent 0266549ff6e04b46c5e361b146a5ae69bb55efab# Parent d9b3221c577d8432564fa9e54b0d3f93ad0403de Merge. diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/AllocatableValue.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/AllocatableValue.java Fri Apr 26 18:36:41 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2013, 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 com.oracle.graal.api.meta.*; - -/** - * Common base class for values that can be manipulated by the register allocator. - */ -public abstract class AllocatableValue extends Value { - - private static final long serialVersionUID = 153019506717492133L; - - /** - * Marker to tell the register allocator that no storage location needs to be allocated for this - * value. - */ - @SuppressWarnings("serial") public static final AllocatableValue UNUSED = new AllocatableValue(Kind.Illegal) { - - @Override - public String toString() { - return "-"; - } - }; - - public AllocatableValue(Kind kind) { - super(kind); - } - -} diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CallingConvention.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CallingConvention.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CallingConvention.java Fri Apr 26 18:38:56 2013 +0200 @@ -76,17 +76,17 @@ */ private final int stackSize; - private final Value returnLocation; + private final AllocatableValue returnLocation; /** * The ordered locations in which the arguments are placed. */ - private final Value[] argumentLocations; + private final AllocatableValue[] argumentLocations; /** * The locations used (and killed) by the call in addition to the arguments. */ - private final Value[] temporaryLocations; + private final AllocatableValue[] temporaryLocations; /** * Creates a description of the registers and stack locations used by a call. @@ -97,8 +97,8 @@ * call * @param argumentLocations the ordered locations in which the arguments are placed */ - public CallingConvention(int stackSize, Value returnLocation, Value... argumentLocations) { - this(Value.NONE, stackSize, returnLocation, argumentLocations); + public CallingConvention(int stackSize, AllocatableValue returnLocation, AllocatableValue... argumentLocations) { + this(AllocatableValue.NONE, stackSize, returnLocation, argumentLocations); } /** @@ -112,7 +112,7 @@ * call * @param argumentLocations the ordered locations in which the arguments are placed */ - public CallingConvention(Value[] temporaryLocations, int stackSize, Value returnLocation, Value... argumentLocations) { + public CallingConvention(AllocatableValue[] temporaryLocations, int stackSize, AllocatableValue returnLocation, AllocatableValue... argumentLocations) { assert argumentLocations != null; assert temporaryLocations != null; assert returnLocation != null; @@ -126,14 +126,14 @@ /** * Gets the location for the return value or {@link Value#ILLEGAL} if a void call. */ - public Value getReturn() { + public AllocatableValue getReturn() { return returnLocation; } /** * Gets the location for the {@code index}'th argument. */ - public Value getArgument(int index) { + public AllocatableValue getArgument(int index) { return argumentLocations[index]; } @@ -155,7 +155,7 @@ * Gets the locations used (and killed) by the call apart from the * {@linkplain #getArgument(int) arguments}. */ - public Value[] getTemporaries() { + public AllocatableValue[] getTemporaries() { if (temporaryLocations.length == 0) { return temporaryLocations; } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/AllocatableValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/AllocatableValue.java Fri Apr 26 18:38:56 2013 +0200 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013, 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.meta; + +/** + * Common base class for values that are stored in some location that's managed by the register + * allocator (e.g. register, stack slot). + */ +public abstract class AllocatableValue extends Value { + + private static final long serialVersionUID = 153019506717492133L; + + public static final AllocatableValue[] NONE = {}; + + public AllocatableValue(Kind kind) { + super(kind); + } + +} diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Value.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Value.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Value.java Fri Apr 26 18:38:56 2013 +0200 @@ -32,9 +32,7 @@ private static final long serialVersionUID = -6909397188697766469L; - public static final Value[] NONE = {}; - - @SuppressWarnings("serial") public static final Value ILLEGAL = new Value(Kind.Illegal) { + @SuppressWarnings("serial") public static final AllocatableValue ILLEGAL = new AllocatableValue(Kind.Illegal) { @Override public String toString() { diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Apr 26 18:38:56 2013 +0200 @@ -90,7 +90,7 @@ public static class AMD64SpillMoveFactory implements LIR.SpillMoveFactory { @Override - public LIRInstruction createMove(Value result, Value input) { + public LIRInstruction createMove(AllocatableValue result, Value input) { return AMD64LIRGenerator.createMove(result, input); } } @@ -143,8 +143,10 @@ return result; } - private static AMD64LIRInstruction createMove(Value dst, Value src) { - if (isRegister(src) || isStackSlot(dst)) { + private static AMD64LIRInstruction createMove(AllocatableValue dst, Value src) { + if (src instanceof AMD64AddressValue) { + return new LeaOp(dst, (AMD64AddressValue) src); + } else if (isRegister(src) || isStackSlot(dst)) { return new MoveFromRegOp(dst, src); } else { return new MoveToRegOp(dst, src); @@ -152,24 +154,23 @@ } @Override - public void emitMove(Value dst, Value src) { + public void emitMove(AllocatableValue dst, Value src) { append(createMove(dst, src)); } - private AMD64AddressValue prepareAddress(Kind kind, Value base, long displacement, Value index, int scale) { + @Override + public AMD64AddressValue emitAddress(Value base, long displacement, Value index, int scale) { AllocatableValue baseRegister; long finalDisp = displacement; if (isConstant(base)) { if (asConstant(base).isNull()) { - baseRegister = AllocatableValue.UNUSED; + baseRegister = Value.ILLEGAL; } else if (asConstant(base).getKind() != Kind.Object && !runtime.needsDataPatch(asConstant(base))) { finalDisp += asConstant(base).asLong(); - baseRegister = AllocatableValue.UNUSED; + baseRegister = Value.ILLEGAL; } else { baseRegister = load(base); } - } else if (base == Value.ILLEGAL) { - baseRegister = AllocatableValue.UNUSED; } else { baseRegister = asAllocatable(base); } @@ -180,12 +181,12 @@ scaleEnum = Scale.fromInt(scale); if (isConstant(index)) { finalDisp += asConstant(index).asLong() * scale; - indexRegister = AllocatableValue.UNUSED; + indexRegister = Value.ILLEGAL; } else { indexRegister = asAllocatable(index); } } else { - indexRegister = AllocatableValue.UNUSED; + indexRegister = Value.ILLEGAL; scaleEnum = Scale.Times1; } @@ -195,9 +196,9 @@ } else { displacementInt = 0; AllocatableValue displacementRegister = load(Constant.forLong(finalDisp)); - if (baseRegister == AllocatableValue.UNUSED) { + if (baseRegister == Value.ILLEGAL) { baseRegister = displacementRegister; - } else if (indexRegister == AllocatableValue.UNUSED) { + } else if (indexRegister == Value.ILLEGAL) { indexRegister = displacementRegister; scaleEnum = Scale.Times1; } else { @@ -205,44 +206,44 @@ } } - return new AMD64AddressValue(kind, baseRegister, indexRegister, scaleEnum, displacementInt); + return new AMD64AddressValue(target().wordKind, baseRegister, indexRegister, scaleEnum, displacementInt); + } + + private AMD64AddressValue asAddress(Value address) { + if (address instanceof AMD64AddressValue) { + return (AMD64AddressValue) address; + } else { + return emitAddress(address, 0, Value.ILLEGAL, 0); + } } @Override - public Variable emitLoad(Kind kind, Value base, long displacement, Value index, int scale, DeoptimizingNode deopting) { - AMD64AddressValue loadAddress = prepareAddress(kind, base, displacement, index, scale); - Variable result = newVariable(loadAddress.getKind()); - append(new LoadOp(result, loadAddress, deopting != null ? state(deopting) : null)); + public Variable emitLoad(Kind kind, Value address, DeoptimizingNode deopting) { + AMD64AddressValue loadAddress = asAddress(address); + Variable result = newVariable(kind); + append(new LoadOp(kind, result, loadAddress, deopting != null ? state(deopting) : null)); return result; } @Override - public void emitStore(Kind kind, Value base, long displacement, Value index, int scale, Value inputVal, DeoptimizingNode deopting) { - AMD64AddressValue storeAddress = prepareAddress(kind, base, displacement, index, scale); + public void emitStore(Kind kind, Value address, Value inputVal, DeoptimizingNode deopting) { + AMD64AddressValue storeAddress = asAddress(address); LIRFrameState state = deopting != null ? state(deopting) : null; if (isConstant(inputVal)) { Constant c = asConstant(inputVal); if (canStoreConstant(c)) { - append(new StoreConstantOp(storeAddress, c, state)); + append(new StoreConstantOp(kind, storeAddress, c, state)); return; } } Variable input = load(inputVal); - append(new StoreOp(storeAddress, input, state)); + append(new StoreOp(kind, storeAddress, input, state)); } @Override - public Variable emitLea(Value base, long displacement, Value index, int scale) { - Variable result = newVariable(target().wordKind); - AMD64AddressValue address = prepareAddress(result.getKind(), base, displacement, index, scale); - append(new LeaOp(result, address)); - return result; - } - - @Override - public Variable emitLea(StackSlot address) { + public Variable emitAddress(StackSlot address) { Variable result = newVariable(target().wordKind); append(new StackLeaOp(result, address)); return result; diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Fri Apr 26 18:38:56 2013 +0200 @@ -28,17 +28,13 @@ import static com.oracle.graal.lir.ptx.PTXBitManipulationOp.IntrinsicOpcode.*; import static com.oracle.graal.lir.ptx.PTXCompare.*; -import com.oracle.graal.api.code.AllocatableValue; import com.oracle.graal.api.code.CodeCacheProvider; import com.oracle.graal.api.code.DeoptimizationAction; import com.oracle.graal.api.code.RuntimeCallTarget; import com.oracle.graal.api.code.StackSlot; import com.oracle.graal.api.code.TargetDescription; import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; -import com.oracle.graal.api.meta.Constant; -import com.oracle.graal.api.meta.Kind; -import com.oracle.graal.api.meta.ResolvedJavaMethod; -import com.oracle.graal.api.meta.Value; +import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.NumUtil; import com.oracle.graal.compiler.gen.LIRGenerator; import com.oracle.graal.compiler.target.LIRGenLowerable; @@ -84,7 +80,7 @@ public static class PTXSpillMoveFactory implements LIR.SpillMoveFactory { @Override - public LIRInstruction createMove(Value result, Value input) { + public LIRInstruction createMove(AllocatableValue result, Value input) { throw new InternalError("NYI"); } } @@ -129,7 +125,7 @@ } @Override - public void emitMove(Value dst, Value src) { + public void emitMove(AllocatableValue dst, Value src) { if (isRegister(src) || isStackSlot(dst)) { append(new MoveFromRegOp(dst, src)); } else { @@ -137,20 +133,19 @@ } } - private PTXAddressValue prepareAddress(Kind kind, Value base, long displacement, Value index, int scale) { + @Override + public PTXAddressValue emitAddress(Value base, long displacement, Value index, int scale) { AllocatableValue baseRegister; long finalDisp = displacement; if (isConstant(base)) { if (asConstant(base).isNull()) { - baseRegister = AllocatableValue.UNUSED; + baseRegister = Value.ILLEGAL; } else if (asConstant(base).getKind() != Kind.Object) { finalDisp += asConstant(base).asLong(); - baseRegister = AllocatableValue.UNUSED; + baseRegister = Value.ILLEGAL; } else { baseRegister = load(base); } - } else if (base == Value.ILLEGAL) { - baseRegister = AllocatableValue.UNUSED; } else { baseRegister = asAllocatable(base); } @@ -166,7 +161,7 @@ indexRegister = index; } - if (baseRegister == AllocatableValue.UNUSED) { + if (baseRegister == Value.ILLEGAL) { baseRegister = asAllocatable(indexRegister); } else { Variable newBase = newVariable(Kind.Int); @@ -177,31 +172,34 @@ } } - return new PTXAddressValue(kind, baseRegister, finalDisp); + return new PTXAddressValue(target().wordKind, baseRegister, finalDisp); + } + + private PTXAddressValue asAddress(Value address) { + if (address instanceof PTXAddressValue) { + return (PTXAddressValue) address; + } else { + return emitAddress(address, 0, Value.ILLEGAL, 0); + } } @Override - public Variable emitLoad(Kind kind, Value base, long displacement, Value index, int scale, DeoptimizingNode deopting) { - PTXAddressValue loadAddress = prepareAddress(kind, base, displacement, index, scale); - Variable result = newVariable(loadAddress.getKind()); - append(new LoadOp(result, loadAddress, deopting != null ? state(deopting) : null)); + public Variable emitLoad(Kind kind, Value address, DeoptimizingNode deopting) { + PTXAddressValue loadAddress = asAddress(address); + Variable result = newVariable(kind); + append(new LoadOp(kind, result, loadAddress, deopting != null ? state(deopting) : null)); return result; } @Override - public void emitStore(Kind kind, Value base, long displacement, Value index, int scale, Value inputVal, DeoptimizingNode deopting) { - PTXAddressValue storeAddress = prepareAddress(kind, base, displacement, index, scale); + public void emitStore(Kind kind, Value address, Value inputVal, DeoptimizingNode deopting) { + PTXAddressValue storeAddress = asAddress(address); Variable input = load(inputVal); - append(new StoreOp(storeAddress, input, deopting != null ? state(deopting) : null)); + append(new StoreOp(kind, storeAddress, input, deopting != null ? state(deopting) : null)); } @Override - public Variable emitLea(Value base, long displacement, Value index, int scale) { - throw new InternalError("NYI"); - } - - @Override - public Variable emitLea(StackSlot address) { + public Variable emitAddress(StackSlot address) { throw new InternalError("NYI"); } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Fri Apr 26 18:38:56 2013 +0200 @@ -208,31 +208,31 @@ } @Override - public void emitMove(Value dst, Value src) { + public void emitMove(AllocatableValue dst, Value src) { // SPARC: Auto-generated method stub } @Override - public Value emitLoad(Kind kind, Value base, long displacement, Value index, int scale, DeoptimizingNode canTrap) { + public Value emitAddress(Value base, long displacement, Value index, int scale) { // SPARC: Auto-generated method stub return null; } @Override - public void emitStore(Kind kind, Value base, long displacement, Value index, int scale, Value input, DeoptimizingNode canTrap) { + public Value emitLoad(Kind kind, Value address, DeoptimizingNode canTrap) { + // SPARC: Auto-generated method stub + return null; + } + + @Override + public void emitStore(Kind kind, Value address, Value input, DeoptimizingNode canTrap) { // SPARC: Auto-generated method stub } @Override - public Value emitLea(Value base, long displacement, Value index, int scale) { - // SPARC: Auto-generated method stub - return null; - } - - @Override - public Value emitLea(StackSlot address) { + public Value emitAddress(StackSlot address) { // SPARC: Auto-generated method stub return null; } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Fri Apr 26 18:38:56 2013 +0200 @@ -22,15 +22,11 @@ */ package com.oracle.graal.compiler.test; -import java.util.*; - import org.junit.*; import com.oracle.graal.api.code.*; import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.Lowerable.*; import com.oracle.graal.phases.common.*; @@ -96,36 +92,10 @@ Debug.dump(graph, "After lowering"); - ArrayList merges = new ArrayList<>(); - ArrayList reads = new ArrayList<>(); - for (Node n : graph.getNodes()) { - if (n instanceof MergeNode) { - // check shape - MergeNode merge = (MergeNode) n; - - if (merge.inputs().count() == 2) { - for (EndNode m : merge.forwardEnds()) { - if (m.predecessor() != null && m.predecessor() instanceof BeginNode && m.predecessor().predecessor() instanceof IfNode) { - IfNode o = (IfNode) m.predecessor().predecessor(); - if (o.falseSuccessor().next() instanceof DeoptimizeNode) { - merges.add(merge); - } - } - } - } - } - if (n instanceof IntegerAddNode) { - IntegerAddNode ian = (IntegerAddNode) n; - - Assert.assertTrue(ian.y() instanceof ConstantNode); - Assert.assertTrue(ian.x() instanceof FloatingReadNode); - reads.add((FloatingReadNode) ian.x()); - } - } - - Assert.assertTrue(merges.size() >= reads.size()); - for (int i = 0; i < reads.size(); i++) { - assertOrderedAfterSchedule(graph, merges.get(i), reads.get(i)); + for (FloatingReadNode node : graph.getNodes(LocalNode.class).first().usages().filter(FloatingReadNode.class)) { + // Checking that the parameter a is not directly used for the access to field + // x10 (because x10 must be guarded by the checkcast). + Assert.assertTrue(node.location().locationIdentity() == LocationNode.FINAL_LOCATION); } } }); diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java Fri Apr 26 18:38:56 2013 +0200 @@ -409,7 +409,7 @@ * The {@linkplain RegisterValue register} or {@linkplain Variable variable} for this interval * prior to register allocation. */ - public final Value operand; + public final AllocatableValue operand; /** * The operand number for this interval's {@linkplain #operand operand}. @@ -420,7 +420,7 @@ * The {@linkplain RegisterValue register} or {@linkplain StackSlot spill slot} assigned to this * interval. */ - private Value location; + private AllocatableValue location; /** * The stack slot to which all splits of this interval are spilled if necessary. @@ -498,7 +498,7 @@ */ private Interval locationHint; - void assignLocation(Value newLocation) { + void assignLocation(AllocatableValue newLocation) { if (isRegister(newLocation)) { assert this.location == null : "cannot re-assign location for " + this; if (newLocation.getKind() == Kind.Illegal && kind != Kind.Illegal) { @@ -518,7 +518,7 @@ * Gets the {@linkplain RegisterValue register} or {@linkplain StackSlot spill slot} assigned to * this interval. */ - public Value location() { + public AllocatableValue location() { return location; } @@ -673,7 +673,7 @@ */ static final Interval EndMarker = new Interval(Value.ILLEGAL, -1); - Interval(Value operand, int operandNumber) { + Interval(AllocatableValue operand, int operandNumber) { assert operand != null; this.operand = operand; this.operandNumber = operandNumber; diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Fri Apr 26 18:38:56 2013 +0200 @@ -206,7 +206,7 @@ /** * Gets the operand denoted by a given operand number. */ - private Value operandFor(int operandNumber) { + private AllocatableValue operandFor(int operandNumber) { if (operandNumber < firstVariableNumber) { assert operandNumber >= 0; return registers[operandNumber].asValue(); @@ -281,7 +281,7 @@ * @param operand the operand for the interval * @return the created interval */ - Interval createInterval(Value operand) { + Interval createInterval(AllocatableValue operand) { assert isLegal(operand); int operandNumber = operandNumber(operand); Interval interval = new Interval(operand, operandNumber); @@ -346,7 +346,7 @@ return intervals[operandNumber]; } - Interval getOrCreateInterval(Value operand) { + Interval getOrCreateInterval(AllocatableValue operand) { Interval ret = intervalFor(operand); if (ret == null) { return createInterval(operand); @@ -555,8 +555,8 @@ insertionBuffer.init(instructions); } - Value fromLocation = interval.location(); - Value toLocation = canonicalSpillOpr(interval); + AllocatableValue fromLocation = interval.location(); + AllocatableValue toLocation = canonicalSpillOpr(interval); assert isRegister(fromLocation) : "from operand must be a register but is: " + fromLocation + " toLocation=" + toLocation + " spillState=" + interval.spillState(); assert isStackSlot(toLocation) : "to operand must be a stack slot"; @@ -968,7 +968,7 @@ TTY.println(blockData.get(block).liveOut.toString()); } - void addUse(Value operand, int from, int to, RegisterPriority registerPriority, Kind kind) { + void addUse(AllocatableValue operand, int from, int to, RegisterPriority registerPriority, Kind kind) { if (!isProcessed(operand)) { return; } @@ -987,7 +987,7 @@ interval.addUsePos(to & ~1, registerPriority); } - void addTemp(Value operand, int tempPos, RegisterPriority registerPriority, Kind kind) { + void addTemp(AllocatableValue operand, int tempPos, RegisterPriority registerPriority, Kind kind) { if (!isProcessed(operand)) { return; } @@ -1008,7 +1008,7 @@ return !isRegister(operand) || attributes(asRegister(operand)).isAllocatable(); } - void addDef(Value operand, int defPos, RegisterPriority registerPriority, Kind kind) { + void addDef(AllocatableValue operand, int defPos, RegisterPriority registerPriority, Kind kind) { if (!isProcessed(operand)) { return; } @@ -1114,8 +1114,8 @@ @Override protected Value doValue(Value registerHint) { if (isVariableOrRegister(registerHint)) { - Interval from = getOrCreateInterval(registerHint); - Interval to = getOrCreateInterval(targetValue); + Interval from = getOrCreateInterval((AllocatableValue) registerHint); + Interval to = getOrCreateInterval((AllocatableValue) targetValue); // hints always point from def to use if (hintAtDef) { @@ -1156,7 +1156,7 @@ BitSet live = blockData.get(block).liveOut; for (int operandNum = live.nextSetBit(0); operandNum >= 0; operandNum = live.nextSetBit(operandNum + 1)) { assert live.get(operandNum) : "should not stop here otherwise"; - Value operand = operandFor(operandNum); + AllocatableValue operand = operandFor(operandNum); if (GraalOptions.TraceLinearScanLevel >= 2) { TTY.println("live in %s to %d", operand, blockTo + 2); } @@ -1197,7 +1197,7 @@ @Override public Value doValue(Value operand, OperandMode mode, EnumSet flags) { if (isVariableOrRegister(operand)) { - addDef(operand, opId, registerPriorityOfOutputOperand(op), operand.getKind().getStackKind()); + addDef((AllocatableValue) operand, opId, registerPriorityOfOutputOperand(op), operand.getKind().getStackKind()); addRegisterHint(op, operand, mode, flags, true); } return operand; @@ -1208,7 +1208,7 @@ @Override public Value doValue(Value operand, OperandMode mode, EnumSet flags) { if (isVariableOrRegister(operand)) { - addTemp(operand, opId, RegisterPriority.MustHaveRegister, operand.getKind().getStackKind()); + addTemp((AllocatableValue) operand, opId, RegisterPriority.MustHaveRegister, operand.getKind().getStackKind()); addRegisterHint(op, operand, mode, flags, false); } return operand; @@ -1220,7 +1220,7 @@ public Value doValue(Value operand, OperandMode mode, EnumSet flags) { if (isVariableOrRegister(operand)) { RegisterPriority p = registerPriorityOfInputOperand(flags); - addUse(operand, blockFrom, opId + 1, p, operand.getKind().getStackKind()); + addUse((AllocatableValue) operand, blockFrom, opId + 1, p, operand.getKind().getStackKind()); addRegisterHint(op, operand, mode, flags, false); } return operand; @@ -1232,7 +1232,7 @@ public Value doValue(Value operand, OperandMode mode, EnumSet flags) { if (isVariableOrRegister(operand)) { RegisterPriority p = registerPriorityOfInputOperand(flags); - addUse(operand, blockFrom, opId, p, operand.getKind().getStackKind()); + addUse((AllocatableValue) operand, blockFrom, opId, p, operand.getKind().getStackKind()); addRegisterHint(op, operand, mode, flags, false); } return operand; @@ -1247,7 +1247,7 @@ @Override public Value doValue(Value operand) { - addUse(operand, blockFrom, opId + 1, RegisterPriority.None, operand.getKind().getStackKind()); + addUse((AllocatableValue) operand, blockFrom, opId + 1, RegisterPriority.None, operand.getKind().getStackKind()); return operand; } }); diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/MoveResolver.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/MoveResolver.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/MoveResolver.java Fri Apr 26 18:38:56 2013 +0200 @@ -196,8 +196,8 @@ assert fromInterval.kind() == toInterval.kind() : "move between different types"; assert insertIdx != -1 : "must setup insert position first"; - Value fromOpr = fromInterval.operand; - Value toOpr = toInterval.operand; + AllocatableValue fromOpr = fromInterval.operand; + AllocatableValue toOpr = toInterval.operand; insertionBuffer.append(insertIdx, allocator.ir.spillMoveFactory.createMove(toOpr, fromOpr)); @@ -210,7 +210,7 @@ assert fromOpr.getKind() == toInterval.kind() : "move between different types"; assert insertIdx != -1 : "must setup insert position first"; - Value toOpr = toInterval.operand; + AllocatableValue toOpr = toInterval.operand; insertionBuffer.append(insertIdx, allocator.ir.spillMoveFactory.createMove(toOpr, fromOpr)); if (GraalOptions.TraceLinearScanLevel >= 4) { diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri Apr 26 18:38:56 2013 +0200 @@ -52,7 +52,7 @@ /** * This class traverses the HIR instructions and generates LIR instructions from them. */ -public abstract class LIRGenerator extends LIRGeneratorTool { +public abstract class LIRGenerator implements LIRGeneratorTool { public final FrameMap frameMap; public final NodeMap nodeOperands; @@ -168,8 +168,8 @@ @Override public Value setResult(ValueNode x, Value operand) { - assert (isVariable(operand) && x.kind() == operand.getKind()) || (isRegister(operand) && !attributes(asRegister(operand)).isAllocatable()) || - (isConstant(operand) && x.kind() == operand.getKind().getStackKind()) : operand.getKind() + " for node " + x; + assert (!isVariable(operand) || x.kind() == operand.getKind()) : operand.getKind() + " for node " + x; + assert (!isRegister(operand) || !attributes(asRegister(operand)).isAllocatable()); assert operand(x) == null : "operand cannot be set twice"; assert operand != null && isLegal(operand) : "operand must be legal"; assert operand.getKind().getStackKind() == x.kind() : operand.getKind().getStackKind() + " must match " + x.kind(); @@ -251,7 +251,7 @@ * @return the operand representing the ABI defined location used return a value of kind * {@code kind} */ - public Value resultOperandFor(Kind kind) { + public AllocatableValue resultOperandFor(Kind kind) { if (kind == Kind.Void) { return ILLEGAL; } @@ -461,7 +461,7 @@ @Override public void visitReturn(ReturnNode x) { - Value operand = Value.ILLEGAL; + AllocatableValue operand = ILLEGAL; if (x.result() != null) { operand = resultOperandFor(x.result().kind()); emitMove(operand, operand(x.result())); @@ -630,7 +630,7 @@ protected abstract void emitCall(RuntimeCallTarget callTarget, Value result, Value[] arguments, Value[] temps, LIRFrameState info); - protected static Value toStackKind(Value value) { + protected static AllocatableValue toStackKind(AllocatableValue value) { if (value.getKind().getStackKind() != value.getKind()) { // We only have stack-kinds in the LIR, so convert the operand kind for values from the // calling convention. @@ -651,7 +651,7 @@ int j = 0; for (ValueNode arg : arguments) { if (arg != null) { - Value operand = toStackKind(cc.getArgument(j)); + AllocatableValue operand = toStackKind(cc.getArgument(j)); emitMove(operand, operand(arg)); result[j] = operand; j++; @@ -672,7 +672,7 @@ Value[] argLocations = new Value[args.length]; for (int i = 0; i < args.length; i++) { Value arg = args[i]; - Value loc = cc.getArgument(i); + AllocatableValue loc = cc.getArgument(i); emitMove(loc, arg); argLocations[i] = loc; } @@ -826,6 +826,10 @@ return frameMap; } + @Override + public void beforeRegisterAllocation() { + } + public abstract void emitBitCount(Variable result, Value operand); public abstract void emitBitScanForward(Variable result, Value operand); diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/PhiResolver.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/PhiResolver.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/PhiResolver.java Fri Apr 26 18:38:56 2013 +0200 @@ -22,9 +22,9 @@ */ package com.oracle.graal.compiler.gen; +import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.api.meta.Value.*; import static com.oracle.graal.lir.LIRValueUtil.*; -import static com.oracle.graal.api.code.ValueUtil.*; import java.util.*; @@ -187,7 +187,7 @@ private void emitMove(Value dest, Value src) { assert isLegal(src); assert isLegal(dest); - gen.emitMove(dest, src); + gen.emitMove((AllocatableValue) dest, src); } // Traverse assignment graph in depth first order and generate moves in post order diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.graph/src/com/oracle/graal/graph/GraalInternalError.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/GraalInternalError.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/GraalInternalError.java Fri Apr 26 18:38:56 2013 +0200 @@ -51,6 +51,23 @@ } /** + * Checks a given condition and throws a {@link GraalInternalError} if it is false. Guarantees + * are stronger than assertions in that they are always checked. Error messages for guarantee + * violations should clearly indicate the nature of the problem as well as a suggested solution + * if possible. + * + * @param condition the condition to check + * @param msg the message that will be associated with the error, in + * {@link String#format(String, Object...)} syntax + * @param args arguments to the format string + */ + public static void guarantee(boolean condition, String msg, Object... args) { + if (!condition) { + throw new GraalInternalError("failed guarantee: " + msg, args); + } + } + + /** * This constructor creates a {@link GraalInternalError} with a message assembled via * {@link String#format(String, Object...)}. It always uses the ENGLISH locale in order to * always generate the same output. diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Fri Apr 26 18:38:56 2013 +0200 @@ -27,6 +27,7 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.hotspot.amd64.AMD64HotSpotUnwindOp.*; +import java.lang.reflect.*; import java.util.*; import com.oracle.graal.amd64.*; @@ -301,6 +302,7 @@ } else { assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special; HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) callTarget.target(); + assert !Modifier.isAbstract(resolvedMethod.getModifiers()) : "Cannot make direct call to abstract method."; Constant metaspaceMethod = resolvedMethod.getMetaspaceMethodConstant(); append(new AMD64HotspotDirectStaticCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind, metaspaceMethod)); } @@ -308,9 +310,9 @@ @Override protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { - Value metaspaceMethod = AMD64.rbx.asValue(); + AllocatableValue metaspaceMethod = AMD64.rbx.asValue(); emitMove(metaspaceMethod, operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod())); - Value targetAddress = AMD64.rax.asValue(); + AllocatableValue targetAddress = AMD64.rax.asValue(); emitMove(targetAddress, operand(callTarget.computedAddress())); append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, temps, metaspaceMethod, targetAddress, callState)); } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Fri Apr 26 18:38:56 2013 +0200 @@ -143,7 +143,7 @@ } private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, TargetDescription target, boolean stackOnly) { - Value[] locations = new Value[parameterTypes.length]; + AllocatableValue[] locations = new AllocatableValue[parameterTypes.length]; int currentGeneral = 0; int currentXMM = 0; @@ -183,7 +183,7 @@ } Kind returnKind = returnType == null ? Kind.Void : returnType.getKind(); - Value returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(returnKind); + AllocatableValue returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(returnKind); return new CallingConvention(currentStackOffset, returnLocation, locations); } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Fri Apr 26 18:38:56 2013 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.amd64.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; +import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.lir.LIRInstruction.Opcode; import com.oracle.graal.lir.amd64.*; diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64SafepointOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64SafepointOp.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64SafepointOp.java Fri Apr 26 18:38:56 2013 +0200 @@ -27,6 +27,7 @@ import sun.misc.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java Fri Apr 26 18:38:56 2013 +0200 @@ -91,13 +91,13 @@ assert stub != null : "linkage without an address must be a stub"; InstalledCode code = stub.getCode(backend); - Value[] argumentLocations = new Value[cc.getArgumentCount()]; + AllocatableValue[] argumentLocations = new AllocatableValue[cc.getArgumentCount()]; for (int i = 0; i < argumentLocations.length; i++) { argumentLocations[i] = cc.getArgument(i); } Set definedRegisters = stub.getDefinedRegisters(); - Value[] temporaryLocations = new Value[definedRegisters.size()]; + AllocatableValue[] temporaryLocations = new AllocatableValue[definedRegisters.size()]; int i = 0; for (Register reg : definedRegisters) { temporaryLocations[i++] = reg.asValue(); diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri Apr 26 18:38:56 2013 +0200 @@ -48,8 +48,8 @@ import com.oracle.graal.api.code.CodeUtil.RefMapFormatter; import com.oracle.graal.api.code.CompilationResult.Call; import com.oracle.graal.api.code.CompilationResult.DataPatch; +import com.oracle.graal.api.code.CompilationResult.Infopoint; import com.oracle.graal.api.code.CompilationResult.Mark; -import com.oracle.graal.api.code.CompilationResult.Infopoint; import com.oracle.graal.api.code.Register.RegisterFlag; import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; import com.oracle.graal.api.meta.*; @@ -164,23 +164,23 @@ } } - protected Value ret(Kind kind) { + protected AllocatableValue ret(Kind kind) { if (kind == Kind.Void) { return ILLEGAL; } return globalStubRegConfig.getReturnRegister(kind).asValue(kind); } - protected Value[] javaCallingConvention(Kind... arguments) { + protected AllocatableValue[] javaCallingConvention(Kind... arguments) { return callingConvention(arguments, RuntimeCall); } - protected Value[] nativeCallingConvention(Kind... arguments) { + protected AllocatableValue[] nativeCallingConvention(Kind... arguments) { return callingConvention(arguments, NativeCall); } - private Value[] callingConvention(Kind[] arguments, CallingConvention.Type type) { - Value[] result = new Value[arguments.length]; + private AllocatableValue[] callingConvention(Kind[] arguments, CallingConvention.Type type) { + AllocatableValue[] result = new AllocatableValue[arguments.length]; TargetDescription target = graalRuntime.getTarget(); int currentStackOffset = 0; @@ -286,7 +286,7 @@ * @param ret where the call returns its result * @param args where arguments are passed to the call */ - protected RuntimeCallTarget addStubCall(Descriptor descriptor, Value ret, Value... args) { + protected RuntimeCallTarget addStubCall(Descriptor descriptor, AllocatableValue ret, AllocatableValue... args) { return addRuntimeCall(descriptor, 0L, null, ret, args); } @@ -299,8 +299,8 @@ * @param ret where the call returns its result * @param args where arguments are passed to the call */ - protected RuntimeCallTarget addRuntimeCall(Descriptor descriptor, long address, Register[] tempRegs, Value ret, Value... args) { - Value[] temps = tempRegs == null || tempRegs.length == 0 ? Value.NONE : new Value[tempRegs.length]; + protected RuntimeCallTarget addRuntimeCall(Descriptor descriptor, long address, Register[] tempRegs, AllocatableValue ret, AllocatableValue... args) { + AllocatableValue[] temps = tempRegs == null || tempRegs.length == 0 ? AllocatableValue.NONE : new AllocatableValue[tempRegs.length]; for (int i = 0; i < temps.length; i++) { temps[i] = tempRegs[i].asValue(); } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -73,7 +73,7 @@ HotSpotLIRGenerator hsGen = (HotSpotLIRGenerator) gen; StackSlot slot = hsGen.getLockSlot(lockDepth); if (!eliminated) { - Value result = gen.emitLea(slot); + Value result = gen.emitAddress(slot); gen.setResult(this, result); } } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentLockNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentLockNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentLockNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -57,7 +57,7 @@ HotSpotLIRGenerator hsGen = (HotSpotLIRGenerator) gen; StackSlot slot = hsGen.getLockSlot(lockDepth); // The register allocator cannot handle stack -> register moves so we use an LEA here - Value result = gen.emitMove(gen.emitLea(slot)); + Value result = gen.emitMove(gen.emitAddress(slot)); gen.setResult(this, result); } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -47,7 +47,7 @@ public void generate(LIRGenerator gen) { int size = rank * 4; StackSlot array = gen.frameMap().allocateStackBlock(size, false); - Value result = gen.emitLea(array); + Value result = gen.emitAddress(array); gen.setResult(this, result); } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/GetObjectAddressNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/GetObjectAddressNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/GetObjectAddressNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -46,7 +46,7 @@ @Override public void generate(LIRGeneratorTool gen) { - Value obj = gen.newVariable(gen.target().wordKind); + AllocatableValue obj = gen.newVariable(gen.target().wordKind); gen.emitMove(obj, gen.operand(object)); gen.setResult(this, obj); } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorCounterNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorCounterNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorCounterNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -43,7 +43,7 @@ public void generate(LIRGenerator gen) { assert graph().getNodes().filter(MonitorCounterNode.class).count() == 1 : "monitor counters not canonicalized to single instance"; StackSlot counter = gen.frameMap().allocateStackBlock(gen.target().wordSize, false); - Value result = gen.emitLea(counter); + Value result = gen.emitAddress(counter); gen.setResult(this, result); } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorExitStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorExitStubCall.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorExitStubCall.java Fri Apr 26 18:38:56 2013 +0200 @@ -60,7 +60,7 @@ HotSpotLIRGenerator hsGen = (HotSpotLIRGenerator) gen; StackSlot slot = hsGen.getLockSlot(lockDepth); RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(MonitorExitStubCall.MONITOREXIT); - gen.emitCall(stub, stub.getCallingConvention(), this, gen.operand(object), gen.emitLea(slot)); + gen.emitCall(stub, stub.getCallingConvention(), this, gen.operand(object), gen.emitAddress(slot)); } @NodeIntrinsic diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -71,7 +71,8 @@ parameters.add(frameState.localAt(slot)); } Value[] args = gen.visitInvokeArguments(cc, parameters); - Value entry = gen.emitLoad(Kind.Long, gen.operand(target), config.nmethodEntryOffset, Value.ILLEGAL, 0, null); + Value address = gen.emitAddress(gen.operand(target), config.nmethodEntryOffset, Value.ILLEGAL, 0); + Value entry = gen.emitLoad(Kind.Long, address, null); HotSpotLIRGenerator hsgen = (HotSpotLIRGenerator) gen; hsgen.emitTailcall(args, entry); } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java Fri Apr 26 18:38:56 2013 +0200 @@ -84,8 +84,8 @@ long nonVectorBytes = byteLength % VECTOR_SIZE; long srcOffset = (long) srcPos * elementSize; long destOffset = (long) destPos * elementSize; - if (src == dest && srcPos < destPos) { // bad aliased case - probability(NOT_FREQUENT_PROBABILITY); + if (probability(NOT_FREQUENT_PROBABILITY, src == dest) && probability(NOT_FREQUENT_PROBABILITY, srcPos < destPos)) { + // bad aliased case for (long i = byteLength - elementSize; i >= byteLength - nonVectorBytes; i -= elementSize) { UnsafeStoreNode.store(dest, header, i + destOffset, UnsafeLoadNode.load(src, header, i + srcOffset, baseKind), baseKind); } @@ -107,7 +107,6 @@ public static void checkNonNull(Object obj) { if (obj == null) { - probability(DEOPT_PATH_PROBABILITY); checkNPECounter.inc(); DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } @@ -116,7 +115,6 @@ public static int checkArrayType(Word hub) { int layoutHelper = readLayoutHelper(hub); if (layoutHelper >= 0) { - probability(DEOPT_PATH_PROBABILITY); DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } return layoutHelper; @@ -124,27 +122,22 @@ public static void checkLimits(Object src, int srcPos, Object dest, int destPos, int length) { if (srcPos < 0) { - probability(DEOPT_PATH_PROBABILITY); checkAIOOBECounter.inc(); DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } if (destPos < 0) { - probability(DEOPT_PATH_PROBABILITY); checkAIOOBECounter.inc(); DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } if (length < 0) { - probability(DEOPT_PATH_PROBABILITY); checkAIOOBECounter.inc(); DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } if (srcPos + length > ArrayLengthNode.arrayLength(src)) { - probability(DEOPT_PATH_PROBABILITY); checkAIOOBECounter.inc(); DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } if (destPos + length > ArrayLengthNode.arrayLength(dest)) { - probability(DEOPT_PATH_PROBABILITY); checkAIOOBECounter.inc(); DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } @@ -278,13 +271,10 @@ int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask(); final boolean isObjectArray = ((layoutHelper & layoutHelperElementTypePrimitiveInPlace()) == 0); - if (srcHub.equal(destHub) && src != dest) { - probability(FAST_PATH_PROBABILITY); - + if (probability(FAST_PATH_PROBABILITY, srcHub.equal(destHub)) && probability(FAST_PATH_PROBABILITY, src != dest)) { checkLimits(src, srcPos, dest, destPos, length); - if (isObjectArray) { + if (probability(FAST_PATH_PROBABILITY, isObjectArray)) { genericObjectExactCallCounter.inc(); - probability(FAST_PATH_PROBABILITY); arrayObjectCopy(src, srcPos, dest, destPos, length); } else { genericPrimitiveCallCounter.inc(); diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java Fri Apr 26 18:38:56 2013 +0200 @@ -65,13 +65,11 @@ */ @Snippet public static Object checkcastExact(Object object, Word exactHub, @ConstantParameter boolean checkNull) { - if (checkNull && object == null) { - probability(NOT_FREQUENT_PROBABILITY); + if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) { isNull.inc(); } else { Word objectHub = loadHub(object); if (objectHub.notEqual(exactHub)) { - probability(DEOPT_PATH_PROBABILITY); exactMiss.inc(); DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException); } @@ -92,13 +90,11 @@ */ @Snippet public static Object checkcastPrimary(Word hub, Object object, @ConstantParameter int superCheckOffset, @ConstantParameter boolean checkNull) { - if (checkNull && object == null) { - probability(NOT_FREQUENT_PROBABILITY); + if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) { isNull.inc(); } else { Word objectHub = loadHub(object); if (objectHub.readWord(superCheckOffset, FINAL_LOCATION).notEqual(hub)) { - probability(DEOPT_PATH_PROBABILITY); displayMiss.inc(); DeoptimizeNode.deopt(InvalidateReprofile, ClassCastException); } @@ -113,8 +109,7 @@ */ @Snippet public static Object checkcastSecondary(Word hub, Object object, @VarargsParameter Word[] hints, @ConstantParameter boolean checkNull) { - if (checkNull && object == null) { - probability(NOT_FREQUENT_PROBABILITY); + if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) { isNull.inc(); } else { Word objectHub = loadHub(object); @@ -142,8 +137,7 @@ */ @Snippet public static Object checkcastDynamic(Word hub, Object object, @ConstantParameter boolean checkNull) { - if (checkNull && object == null) { - probability(NOT_FREQUENT_PROBABILITY); + if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) { isNull.inc(); } else { Word objectHub = loadHub(object); diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSnippetUtils.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSnippetUtils.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSnippetUtils.java Fri Apr 26 18:38:56 2013 +0200 @@ -644,11 +644,9 @@ // this code is independent from biased locking (although it does not look that way) final Word biasedLock = mark.and(biasedLockMaskInPlace()); - if (biasedLock.equal(Word.unsigned(unlockedMask()))) { - probability(FAST_PATH_PROBABILITY); + if (probability(FAST_PATH_PROBABILITY, biasedLock.equal(Word.unsigned(unlockedMask())))) { int hash = (int) mark.unsignedShiftRight(identityHashCodeShift()).rawValue(); - if (hash != uninitializedIdentityHashCodeValue()) { - probability(FAST_PATH_PROBABILITY); + if (probability(FAST_PATH_PROBABILITY, hash != uninitializedIdentityHashCodeValue())) { return hash; } } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Fri Apr 26 18:38:56 2013 +0200 @@ -58,14 +58,12 @@ */ @Snippet public static Object instanceofExact(Object object, Word exactHub, Object trueValue, Object falseValue, @ConstantParameter boolean checkNull) { - if (checkNull && object == null) { - probability(NOT_FREQUENT_PROBABILITY); + if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) { isNull.inc(); return falseValue; } Word objectHub = loadHub(object); - if (objectHub.notEqual(exactHub)) { - probability(LIKELY_PROBABILITY); + if (probability(LIKELY_PROBABILITY, objectHub.notEqual(exactHub))) { exactMiss.inc(); return falseValue; } @@ -78,14 +76,12 @@ */ @Snippet public static Object instanceofPrimary(Word hub, Object object, @ConstantParameter int superCheckOffset, Object trueValue, Object falseValue, @ConstantParameter boolean checkNull) { - if (checkNull && object == null) { - probability(NOT_FREQUENT_PROBABILITY); + if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) { isNull.inc(); return falseValue; } Word objectHub = loadHub(object); - if (objectHub.readWord(superCheckOffset, FINAL_LOCATION).notEqual(hub)) { - probability(NOT_LIKELY_PROBABILITY); + if (probability(NOT_LIKELY_PROBABILITY, objectHub.readWord(superCheckOffset, FINAL_LOCATION).notEqual(hub))) { displayMiss.inc(); return falseValue; } @@ -99,8 +95,7 @@ @Snippet public static Object instanceofSecondary(Word hub, Object object, @VarargsParameter Word[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue, Object falseValue, @ConstantParameter boolean checkNull) { - if (checkNull && object == null) { - probability(NOT_FREQUENT_PROBABILITY); + if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) { isNull.inc(); return falseValue; } @@ -110,8 +105,7 @@ for (int i = 0; i < hints.length; i++) { Word hintHub = hints[i]; boolean positive = hintIsPositive[i]; - if (hintHub.equal(objectHub)) { - probability(NOT_FREQUENT_PROBABILITY); + if (probability(NOT_FREQUENT_PROBABILITY, hintHub.equal(objectHub))) { hintsHit.inc(); return positive ? trueValue : falseValue; } @@ -127,8 +121,7 @@ */ @Snippet public static Object instanceofDynamic(Class mirror, Object object, Object trueValue, Object falseValue, @ConstantParameter boolean checkNull) { - if (checkNull && object == null) { - probability(NOT_FREQUENT_PROBABILITY); + if (checkNull && probability(NOT_FREQUENT_PROBABILITY, object == null)) { isNull.inc(); return falseValue; } diff -r 0266549ff6e0 -r bdf4604fec2e 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 Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Fri Apr 26 18:38:56 2013 +0200 @@ -102,10 +102,9 @@ final Word biasableLockBits = mark.and(biasedLockMaskInPlace()); // First check to see whether biasing is enabled for this object - if (biasableLockBits.notEqual(Word.unsigned(biasedLockPattern()))) { + if (probability(NOT_FREQUENT_PROBABILITY, biasableLockBits.notEqual(Word.unsigned(biasedLockPattern())))) { // Biasing not enabled -> fall through to lightweight locking } else { - probability(FREQUENT_PROBABILITY); // The bias pattern is present in the object's mark word. Need to check // whether the bias owner and the epoch are both still current. Word hub = loadHub(object); @@ -115,9 +114,8 @@ trace(trace, "prototypeMarkWord: 0x%016lx\n", prototypeMarkWord); trace(trace, " thread: 0x%016lx\n", thread); trace(trace, " tmp: 0x%016lx\n", tmp); - if (tmp.equal(0)) { + if (probability(FREQUENT_PROBABILITY, tmp.equal(0))) { // Object is already biased to current thread -> done - probability(FREQUENT_PROBABILITY); traceObject(trace, "+lock{bias:existing}", object); return; } @@ -131,8 +129,7 @@ // If the low three bits in the xor result aren't clear, that means // the prototype header is no longer biasable and we have to revoke // the bias on this object. - if (tmp.and(biasedLockMaskInPlace()).equal(0)) { - probability(FREQUENT_PROBABILITY); + if (probability(FREQUENT_PROBABILITY, tmp.and(biasedLockMaskInPlace()).equal(0))) { // Biasing is still enabled for object's type. See whether the // epoch of the current bias is still valid, meaning that the epoch // bits of the mark word are equal to the epoch bits of the @@ -142,8 +139,7 @@ // that the current epoch is invalid in order to do this because // otherwise the manipulations it performs on the mark word are // illegal. - if (tmp.and(epochMaskInPlace()).equal(0)) { - probability(FREQUENT_PROBABILITY); + if (probability(FREQUENT_PROBABILITY, tmp.and(epochMaskInPlace()).equal(0))) { // The epoch of the current bias is still valid but we know nothing // about the owner; it might be set or it might be clear. Try to // acquire the bias of the object using an atomic operation. If this @@ -154,7 +150,7 @@ Word biasedMark = unbiasedMark.or(thread); trace(trace, " unbiasedMark: 0x%016lx\n", unbiasedMark); trace(trace, " biasedMark: 0x%016lx\n", biasedMark); - if (compareAndSwap(object, markOffset(), unbiasedMark, biasedMark, MARK_WORD_LOCATION).equal(unbiasedMark)) { + if (probability(VERY_FAST_DEOPT_PATH_PROBABILITY, compareAndSwap(object, markOffset(), unbiasedMark, biasedMark, MARK_WORD_LOCATION).equal(unbiasedMark))) { // Object is now biased to current thread -> done traceObject(trace, "+lock{bias:acquired}", object); return; @@ -162,7 +158,6 @@ // If the biasing toward our thread failed, this means that another thread // owns the bias and we need to revoke that bias. The revocation will occur // in the interpreter runtime. - probability(DEOPT_PATH_PROBABILITY); traceObject(trace, "+lock{stub:revoke}", object); MonitorEnterStubCall.call(object, lock); return; @@ -175,7 +170,7 @@ // the bias from one thread to another directly in this situation. Word biasedMark = prototypeMarkWord.or(thread); trace(trace, " biasedMark: 0x%016lx\n", biasedMark); - if (compareAndSwap(object, markOffset(), mark, biasedMark, MARK_WORD_LOCATION).equal(mark)) { + if (probability(VERY_FAST_DEOPT_PATH_PROBABILITY, compareAndSwap(object, markOffset(), mark, biasedMark, MARK_WORD_LOCATION).equal(mark))) { // Object is now biased to current thread -> done traceObject(trace, "+lock{bias:transfer}", object); return; @@ -183,7 +178,6 @@ // If the biasing toward our thread failed, then another thread // succeeded in biasing it toward itself and we need to revoke that // bias. The revocation will occur in the runtime in the slow case. - probability(DEOPT_PATH_PROBABILITY); traceObject(trace, "+lock{stub:epoch-expired}", object); MonitorEnterStubCall.call(object, lock); return; @@ -239,9 +233,8 @@ // significant 2 bits cleared and page_size is a power of 2 final Word alignedMask = Word.unsigned(wordSize() - 1); final Word stackPointer = stackPointer(); - if (currentMark.subtract(stackPointer).and(alignedMask.subtract(pageSize())).notEqual(0)) { + if (probability(VERY_SLOW_PATH_PROBABILITY, currentMark.subtract(stackPointer).and(alignedMask.subtract(pageSize())).notEqual(0))) { // Most likely not a recursive lock, go into a slow runtime call - probability(DEOPT_PATH_PROBABILITY); traceObject(trace, "+lock{stub:failed-cas}", object); MonitorEnterStubCall.call(object, lock); return; @@ -290,8 +283,7 @@ // the bias bit would be clear. final Word mark = loadWordFromObject(object, markOffset()); trace(trace, " mark: 0x%016lx\n", mark); - if (mark.and(biasedLockMaskInPlace()).equal(Word.unsigned(biasedLockPattern()))) { - probability(FREQUENT_PROBABILITY); + if (probability(FREQUENT_PROBABILITY, mark.and(biasedLockMaskInPlace()).equal(Word.unsigned(biasedLockPattern())))) { endLockScope(); decCounter(); traceObject(trace, "-lock{bias}", object); @@ -313,10 +305,9 @@ // Test if object's mark word is pointing to the displaced mark word, and if so, restore // the displaced mark in the object - if the object's mark word is not pointing to // the displaced mark word, do unlocking via runtime call. - if (DirectCompareAndSwapNode.compareAndSwap(object, markOffset(), lock, displacedMark, MARK_WORD_LOCATION).notEqual(lock)) { + if (probability(VERY_SLOW_PATH_PROBABILITY, DirectCompareAndSwapNode.compareAndSwap(object, markOffset(), lock, displacedMark, MARK_WORD_LOCATION).notEqual(lock))) { // The object's mark word was not pointing to the displaced header, // we do unlocking via runtime call. - probability(DEOPT_PATH_PROBABILITY); traceObject(trace, "-lock{stub}", object); MonitorExitStubCall.call(object); } else { diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Fri Apr 26 18:38:56 2013 +0200 @@ -64,8 +64,7 @@ * this check might lead to problems if the TLAB is within 16GB of the address space end * (checked in c++ code) */ - if (newTop.belowOrEqual(end)) { - probability(FAST_PATH_PROBABILITY); + if (probability(FAST_PATH_PROBABILITY, newTop.belowOrEqual(end))) { writeTlabTop(thread, newTop); return top; } @@ -76,11 +75,10 @@ public static Object initializeObject(Word memory, Word hub, Word prototypeMarkWord, @ConstantParameter int size, @ConstantParameter boolean fillContents, @ConstantParameter boolean locked) { Object result; - if (memory.equal(0)) { + if (probability(SLOW_PATH_PROBABILITY, memory.equal(0))) { new_stub.inc(); result = NewInstanceStubCall.call(hub); } else { - probability(FAST_PATH_PROBABILITY); if (locked) { formatObject(hub, size, memory, thread().or(biasedLockPattern()), fillContents); } else { @@ -108,11 +106,10 @@ private static Object initializeArray(Word memory, Word hub, int length, int allocationSize, Word prototypeMarkWord, int headerSize, boolean fillContents) { Object result; - if (memory.equal(0)) { + if (probability(SLOW_PATH_PROBABILITY, memory.equal(0))) { newarray_stub.inc(); result = NewArrayStubCall.call(hub, length); } else { - probability(FAST_PATH_PROBABILITY); newarray_loopInit.inc(); formatArray(hub, allocationSize, length, headerSize, memory, prototypeMarkWord, fillContents); result = memory.toObject(); @@ -130,7 +127,6 @@ public static Object allocateArrayAndInitialize(int length, @ConstantParameter int alignment, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize, @ConstantParameter boolean fillContents, @ConstantParameter ResolvedJavaType type) { if (!belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) { - probability(DEOPT_PATH_PROBABILITY); // This handles both negative array sizes and very large array sizes DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java Fri Apr 26 18:38:56 2013 +0200 @@ -84,7 +84,6 @@ private static Word getAndCheckHub(Object src) { Word hub = loadHub(src); if (!(src instanceof Cloneable)) { - probability(DEOPT_PATH_PROBABILITY); DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } return hub; @@ -110,8 +109,7 @@ genericCloneCounter.inc(); Word hub = getAndCheckHub(src); int layoutHelper = hub.readInt(layoutHelperOffset(), FINAL_LOCATION); - if (layoutHelper < 0) { - probability(LIKELY_PROBABILITY); + if (probability(LIKELY_PROBABILITY, layoutHelper < 0)) { genericArrayCloneCounter.inc(); return arrayClone(src, hub, layoutHelper); } else { diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/SystemSubstitutions.java Fri Apr 26 18:38:56 2013 +0200 @@ -56,8 +56,7 @@ @MethodSubstitution public static int identityHashCode(Object x) { - if (x == null) { - probability(NOT_FREQUENT_PROBABILITY); + if (probability(NOT_FREQUENT_PROBABILITY, x == null)) { return 0; } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java Fri Apr 26 18:38:56 2013 +0200 @@ -89,8 +89,7 @@ Word secondarySupers = s.readWord(secondarySupersOffset(), SECONDARY_SUPERS_LOCATION); int length = secondarySupers.readInt(metaspaceArrayLengthOffset(), FINAL_LOCATION); for (int i = 0; i < length; i++) { - if (t.equal(loadSecondarySupersElement(secondarySupers, i))) { - probability(NOT_LIKELY_PROBABILITY); + if (probability(NOT_LIKELY_PROBABILITY, t.equal(loadSecondarySupersElement(secondarySupers, i)))) { s.writeWord(secondarySuperCacheOffset(), t, SECONDARY_SUPER_CACHE_LOCATION); secondariesHit.inc(); return true; diff -r 0266549ff6e0 -r bdf4604fec2e 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 Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Apr 26 18:38:56 2013 +0200 @@ -34,7 +34,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType; import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.api.meta.ResolvedJavaType.Representation; import com.oracle.graal.bytecode.*; @@ -798,12 +797,7 @@ if (!optimisticOpts.useTypeCheckHints() || !canHaveSubtype(type)) { return null; } else { - ResolvedJavaType uniqueSubtype = type.findUniqueConcreteSubtype(); - if (uniqueSubtype != null) { - return new JavaTypeProfile(profilingInfo.getNullSeen(bci()), 0.0D, new ProfiledType(uniqueSubtype, 1.0D)); - } else { - return profilingInfo.getTypeProfile(bci()); - } + return profilingInfo.getTypeProfile(bci()); } } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java Fri Apr 26 18:38:56 2013 +0200 @@ -30,18 +30,19 @@ import com.oracle.graal.asm.amd64.*; import com.oracle.graal.asm.amd64.AMD64Address.Scale; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.OperandFlag; public class AMD64AddressValue extends CompositeValue { private static final long serialVersionUID = -4444600052487578694L; - @Component({REG, UNUSED}) protected AllocatableValue base; - @Component({REG, UNUSED}) protected AllocatableValue index; + @Component({REG, OperandFlag.ILLEGAL}) protected AllocatableValue base; + @Component({REG, OperandFlag.ILLEGAL}) protected AllocatableValue index; protected final Scale scale; protected final int displacement; public AMD64AddressValue(Kind kind, AllocatableValue base, int displacement) { - this(kind, base, AllocatableValue.UNUSED, Scale.Times1, displacement); + this(kind, base, Value.ILLEGAL, Scale.Times1, displacement); } public AMD64AddressValue(Kind kind, AllocatableValue base, AllocatableValue index, Scale scale, int displacement) { @@ -53,7 +54,7 @@ } private static Register toRegister(AllocatableValue value) { - if (value == AllocatableValue.UNUSED) { + if (value == Value.ILLEGAL) { return Register.None; } else { RegisterValue reg = (RegisterValue) value; @@ -67,8 +68,7 @@ @Override public String toString() { - StringBuilder s = new StringBuilder(); - s.append(getKind().getJavaName()).append("["); + StringBuilder s = new StringBuilder("["); String sep = ""; if (isLegal(base)) { s.append(base); diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Arithmetic.java Fri Apr 26 18:38:56 2013 +0200 @@ -26,7 +26,6 @@ import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import com.oracle.graal.amd64.*; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.graph.*; diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BitManipulationOp.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BitManipulationOp.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64BitManipulationOp.java Fri Apr 26 18:38:56 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.lir.amd64; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.lir.asm.*; diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Fri Apr 26 18:38:56 2013 +0200 @@ -44,10 +44,10 @@ @Opcode("MOVE") public static class MoveToRegOp extends AMD64LIRInstruction implements MoveOp { - @Def({REG, HINT}) protected Value result; + @Def({REG, HINT}) protected AllocatableValue result; @Use({REG, STACK, CONST}) protected Value input; - public MoveToRegOp(Value result, Value input) { + public MoveToRegOp(AllocatableValue result, Value input) { this.result = result; this.input = input; } @@ -63,7 +63,7 @@ } @Override - public Value getResult() { + public AllocatableValue getResult() { return result; } } @@ -71,10 +71,10 @@ @Opcode("MOVE") public static class MoveFromRegOp extends AMD64LIRInstruction implements MoveOp { - @Def({REG, STACK}) protected Value result; + @Def({REG, STACK}) protected AllocatableValue result; @Use({REG, CONST, HINT}) protected Value input; - public MoveFromRegOp(Value result, Value input) { + public MoveFromRegOp(AllocatableValue result, Value input) { this.result = result; this.input = input; } @@ -90,17 +90,19 @@ } @Override - public Value getResult() { + public AllocatableValue getResult() { return result; } } public abstract static class MemOp extends AMD64LIRInstruction { + protected final Kind kind; @Use({COMPOSITE}) protected AMD64AddressValue address; @State protected LIRFrameState state; - public MemOp(AMD64AddressValue address, LIRFrameState state) { + public MemOp(Kind kind, AMD64AddressValue address, LIRFrameState state) { + this.kind = kind; this.address = address; this.state = state; } @@ -120,14 +122,14 @@ @Def({REG}) protected AllocatableValue result; - public LoadOp(AllocatableValue result, AMD64AddressValue address, LIRFrameState state) { - super(address, state); + public LoadOp(Kind kind, AllocatableValue result, AMD64AddressValue address, LIRFrameState state) { + super(kind, address, state); this.result = result; } @Override public void emitMemAccess(AMD64MacroAssembler masm) { - switch (address.getKind()) { + switch (kind) { case Boolean: case Byte: masm.movsxb(asRegister(result), address.toAddress()); @@ -163,15 +165,15 @@ @Use({REG}) protected AllocatableValue input; - public StoreOp(AMD64AddressValue address, AllocatableValue input, LIRFrameState state) { - super(address, state); + public StoreOp(Kind kind, AMD64AddressValue address, AllocatableValue input, LIRFrameState state) { + super(kind, address, state); this.input = input; } @Override public void emitMemAccess(AMD64MacroAssembler masm) { assert isRegister(input); - switch (address.getKind()) { + switch (kind) { case Boolean: case Byte: masm.movb(address.toAddress(), asRegister(input)); @@ -205,14 +207,14 @@ protected final Constant input; - public StoreConstantOp(AMD64AddressValue address, Constant input, LIRFrameState state) { - super(address, state); + public StoreConstantOp(Kind kind, AMD64AddressValue address, Constant input, LIRFrameState state) { + super(kind, address, state); this.input = input; } @Override public void emitMemAccess(AMD64MacroAssembler masm) { - switch (address.getKind()) { + switch (kind) { case Boolean: case Byte: masm.movb(address.toAddress(), input.asInt() & 0xFF); diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXAddressValue.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXAddressValue.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXAddressValue.java Fri Apr 26 18:38:56 2013 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.ptx.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.OperandFlag; /** * Represents an address in target machine memory, specified via some combination of a base register @@ -38,7 +39,7 @@ private static final long serialVersionUID = 1802222435353022623L; - @Component({REG, UNUSED}) private AllocatableValue base; + @Component({REG, OperandFlag.ILLEGAL}) private AllocatableValue base; private final long displacement; /** @@ -68,7 +69,7 @@ } public PTXAddress toAddress() { - Register baseReg = base == AllocatableValue.UNUSED ? Register.None : asRegister(base); + Register baseReg = base == Value.ILLEGAL ? Register.None : asRegister(base); return new PTXAddress(baseReg, displacement); } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java Fri Apr 26 18:38:56 2013 +0200 @@ -25,7 +25,6 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.ptx.*; import com.oracle.graal.graph.*; diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java Fri Apr 26 18:38:56 2013 +0200 @@ -97,6 +97,7 @@ @SuppressWarnings("unused") public static class CondMoveOp extends PTXLIRInstruction { + @Def({REG, HINT}) protected Value result; @Alive({REG}) protected Value trueValue; @Use({REG, STACK, CONST}) protected Value falseValue; @@ -119,6 +120,7 @@ @SuppressWarnings("unused") public static class FloatCondMoveOp extends PTXLIRInstruction { + @Def({REG}) protected Value result; @Alive({REG}) protected Value trueValue; @Alive({REG}) protected Value falseValue; @@ -142,14 +144,14 @@ } public static class SequentialSwitchOp extends PTXLIRInstruction implements FallThroughOp { + @Use({CONST}) protected Constant[] keyConstants; private final LabelRef[] keyTargets; private LabelRef defaultTarget; @Alive({REG}) protected Value key; @Temp({REG, ILLEGAL}) protected Value scratch; - public SequentialSwitchOp(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, - Value key, Value scratch) { + public SequentialSwitchOp(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value scratch) { assert keyConstants.length == keyTargets.length; this.keyConstants = keyConstants; this.keyTargets = keyTargets; @@ -216,14 +218,14 @@ } public static class TableSwitchOp extends PTXLIRInstruction { + private final int lowKey; private final LabelRef defaultTarget; private final LabelRef[] targets; @Alive protected Value index; @Temp protected Value scratch; - public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, final LabelRef[] targets, - Variable index, Variable scratch) { + public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, final LabelRef[] targets, Variable index, Variable scratch) { this.lowKey = lowKey; this.defaultTarget = defaultTarget; this.targets = targets; @@ -238,9 +240,7 @@ } @SuppressWarnings("unused") - private static void tableswitch(TargetMethodAssembler tasm, PTXAssembler masm, int lowKey, - LabelRef defaultTarget, LabelRef[] targets, - Register value, Register scratch) { + private static void tableswitch(TargetMethodAssembler tasm, PTXAssembler masm, int lowKey, LabelRef defaultTarget, LabelRef[] targets, Register value, Register scratch) { Buffer buf = masm.codeBuffer; // Compare index against jump table bounds int highKey = lowKey + targets.length - 1; diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java Fri Apr 26 18:38:56 2013 +0200 @@ -39,10 +39,10 @@ @Opcode("MOVE") public static class SpillMoveOp extends PTXLIRInstruction implements MoveOp { - @Def({REG, STACK}) protected Value result; + @Def({REG, STACK}) protected AllocatableValue result; @Use({REG, STACK, CONST}) protected Value input; - public SpillMoveOp(Value result, Value input) { + public SpillMoveOp(AllocatableValue result, Value input) { this.result = result; this.input = input; } @@ -58,7 +58,7 @@ } @Override - public Value getResult() { + public AllocatableValue getResult() { return result; } } @@ -66,10 +66,10 @@ @Opcode("MOVE") public static class MoveToRegOp extends PTXLIRInstruction implements MoveOp { - @Def({REG, HINT}) protected Value result; + @Def({REG, HINT}) protected AllocatableValue result; @Use({REG, STACK, CONST}) protected Value input; - public MoveToRegOp(Value result, Value input) { + public MoveToRegOp(AllocatableValue result, Value input) { this.result = result; this.input = input; } @@ -85,7 +85,7 @@ } @Override - public Value getResult() { + public AllocatableValue getResult() { return result; } } @@ -93,10 +93,10 @@ @Opcode("MOVE") public static class MoveFromRegOp extends PTXLIRInstruction implements MoveOp { - @Def({REG, STACK}) protected Value result; + @Def({REG, STACK}) protected AllocatableValue result; @Use({REG, CONST, HINT}) protected Value input; - public MoveFromRegOp(Value result, Value input) { + public MoveFromRegOp(AllocatableValue result, Value input) { this.result = result; this.input = input; } @@ -112,18 +112,20 @@ } @Override - public Value getResult() { + public AllocatableValue getResult() { return result; } } public static class LoadOp extends PTXLIRInstruction { + private final Kind kind; @Def({REG}) protected AllocatableValue result; @Use({COMPOSITE}) protected PTXAddressValue address; @State protected LIRFrameState state; - public LoadOp(AllocatableValue result, PTXAddressValue address, LIRFrameState state) { + public LoadOp(Kind kind, AllocatableValue result, PTXAddressValue address, LIRFrameState state) { + this.kind = kind; this.result = result; this.address = address; this.state = state; @@ -132,7 +134,7 @@ @Override public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { PTXAddress addr = address.toAddress(); - switch (address.getKind()) { + switch (kind) { case Byte: masm.ld_global_s8(asRegister(result), addr.getBase(), addr.getDisplacement()); break; @@ -165,11 +167,13 @@ public static class StoreOp extends PTXLIRInstruction { + private final Kind kind; @Use({COMPOSITE}) protected PTXAddressValue address; @Use({REG}) protected AllocatableValue input; @State protected LIRFrameState state; - public StoreOp(PTXAddressValue address, AllocatableValue input, LIRFrameState state) { + public StoreOp(Kind kind, PTXAddressValue address, AllocatableValue input, LIRFrameState state) { + this.kind = kind; this.address = address; this.input = input; this.state = state; @@ -179,7 +183,7 @@ public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { assert isRegister(input); PTXAddress addr = address.toAddress(); - switch (address.getKind()) { + switch (kind) { case Byte: masm.st_global_s8(addr.getBase(), addr.getDisplacement(), asRegister(input)); break; diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java Fri Apr 26 18:38:56 2013 +0200 @@ -64,7 +64,7 @@ public interface SpillMoveFactory { - LIRInstruction createMove(Value result, Value input); + LIRInstruction createMove(AllocatableValue result, Value input); } private boolean hasArgInCallerFrame; diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Fri Apr 26 18:38:56 2013 +0200 @@ -181,11 +181,6 @@ ILLEGAL, /** - * The value can be {@link AllocatableValue#UNUSED}. - */ - UNUSED, - - /** * The register allocator should try to assign a certain register to improve code quality. * Use {@link LIRInstruction#forEachRegisterHint} to access the register hints. */ @@ -205,10 +200,10 @@ static { ALLOWED_FLAGS = new EnumMap<>(OperandMode.class); - ALLOWED_FLAGS.put(USE, EnumSet.of(REG, STACK, COMPOSITE, CONST, ILLEGAL, HINT, UNUSED, UNINITIALIZED)); - ALLOWED_FLAGS.put(ALIVE, EnumSet.of(REG, STACK, COMPOSITE, CONST, ILLEGAL, HINT, UNUSED, UNINITIALIZED)); - ALLOWED_FLAGS.put(TEMP, EnumSet.of(REG, COMPOSITE, CONST, ILLEGAL, UNUSED, HINT)); - ALLOWED_FLAGS.put(DEF, EnumSet.of(REG, STACK, COMPOSITE, ILLEGAL, UNUSED, HINT)); + ALLOWED_FLAGS.put(USE, EnumSet.of(REG, STACK, COMPOSITE, CONST, ILLEGAL, HINT, UNINITIALIZED)); + ALLOWED_FLAGS.put(ALIVE, EnumSet.of(REG, STACK, COMPOSITE, CONST, ILLEGAL, HINT, UNINITIALIZED)); + ALLOWED_FLAGS.put(TEMP, EnumSet.of(REG, COMPOSITE, CONST, ILLEGAL, HINT)); + ALLOWED_FLAGS.put(DEF, EnumSet.of(REG, STACK, COMPOSITE, ILLEGAL, HINT)); } /** diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java Fri Apr 26 18:38:56 2013 +0200 @@ -232,8 +232,7 @@ private static Value allowed(Object op, Value value, OperandMode mode, EnumSet flags) { if ((isVariable(value) && flags.contains(OperandFlag.REG)) || (isRegister(value) && flags.contains(OperandFlag.REG)) || (isStackSlot(value) && flags.contains(OperandFlag.STACK)) || - (isConstant(value) && flags.contains(OperandFlag.CONST) && mode != OperandMode.DEF) || (isIllegal(value) && flags.contains(OperandFlag.ILLEGAL)) || - (value == AllocatableValue.UNUSED && flags.contains(OperandFlag.UNUSED))) { + (isConstant(value) && flags.contains(OperandFlag.CONST) && mode != OperandMode.DEF) || (isIllegal(value) && flags.contains(OperandFlag.ILLEGAL))) { return value; } TTY.println("instruction %s", op); diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Fri Apr 26 18:38:56 2013 +0200 @@ -117,7 +117,7 @@ Value getInput(); - Value getResult(); + AllocatableValue getResult(); } /** diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -91,18 +91,6 @@ return getY().generateAddress(gen, xAddr); } - @Override - public Value generateLoad(LIRGeneratorTool gen, Value base, DeoptimizingNode deopting) { - Value xAddr = getX().generateAddress(gen, base); - return getY().generateLoad(gen, xAddr, deopting); - } - - @Override - public void generateStore(LIRGeneratorTool gen, Value base, Value value, DeoptimizingNode deopting) { - Value xAddr = getX().generateAddress(gen, base); - getY().generateStore(gen, xAddr, value, deopting); - } - @NodeIntrinsic public static native Location addLocation(@ConstantNodeParameter Object identity, @ConstantNodeParameter Kind kind, Location x, Location y); } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -24,7 +24,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; /** @@ -56,16 +55,6 @@ @Override public Value generateAddress(LIRGeneratorTool gen, Value base) { - return gen.emitLea(base, displacement(), Value.ILLEGAL, 0); - } - - @Override - public Value generateLoad(LIRGeneratorTool gen, Value base, DeoptimizingNode deopting) { - return gen.emitLoad(getValueKind(), base, displacement(), Value.ILLEGAL, 0, deopting); - } - - @Override - public void generateStore(LIRGeneratorTool gen, Value base, Value value, DeoptimizingNode deopting) { - gen.emitStore(getValueKind(), base, displacement(), Value.ILLEGAL, 0, value, deopting); + return gen.emitAddress(base, displacement(), Value.ILLEGAL, 0); } } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -24,6 +24,7 @@ import java.util.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -53,7 +54,8 @@ @Override public void generate(LIRGeneratorTool gen) { - gen.setResult(this, location().generateLoad(gen, gen.operand(object()), this)); + Value address = location().generateAddress(gen, gen.operand(object())); + gen.setResult(this, gen.emitLoad(location().getValueKind(), address, this)); } @Override diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -91,17 +91,7 @@ @Override public Value generateAddress(LIRGeneratorTool gen, Value base) { - return gen.emitLea(base, displacement, gen.operand(index()), indexScaling()); - } - - @Override - public Value generateLoad(LIRGeneratorTool gen, Value base, DeoptimizingNode deopting) { - return gen.emitLoad(getValueKind(), base, displacement, gen.operand(index()), indexScaling(), deopting); - } - - @Override - public void generateStore(LIRGeneratorTool gen, Value base, Value value, DeoptimizingNode deopting) { - gen.emitStore(getValueKind(), base, displacement, gen.operand(index()), indexScaling(), value, deopting); + return gen.emitAddress(base, displacement, gen.operand(index()), indexScaling()); } @NodeIntrinsic diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -24,7 +24,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.Node.ValueNumberable; -import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -100,8 +99,4 @@ } public abstract Value generateAddress(LIRGeneratorTool gen, Value base); - - public abstract Value generateLoad(LIRGeneratorTool gen, Value base, DeoptimizingNode deopting); - - public abstract void generateStore(LIRGeneratorTool gen, Value base, Value value, DeoptimizingNode deopting); } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -57,7 +57,8 @@ @Override public void generate(LIRGeneratorTool gen) { - gen.setResult(this, location().generateLoad(gen, gen.operand(object()), this)); + Value address = location().generateAddress(gen, gen.operand(object())); + gen.setResult(this, gen.emitLoad(location().getValueKind(), address, this)); } @Override diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -91,7 +91,7 @@ public void generate(LIRGeneratorTool generator) { if (kind() != object().kind()) { assert generator.target().sizeInBytes(kind()) == generator.target().sizeInBytes(object().kind()) : "unsafe cast cannot be used to change the size of a value"; - Value result = generator.newVariable(kind()); + AllocatableValue result = generator.newVariable(kind()); generator.emitMove(result, generator.operand(object())); generator.setResult(this, result); } else { diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -22,10 +22,11 @@ */ package com.oracle.graal.nodes.extended; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -import com.oracle.graal.graph.*; /** * Writes a given {@linkplain #value() value} a {@linkplain AccessNode memory location}. @@ -84,7 +85,8 @@ @Override public void generate(LIRGeneratorTool gen) { - location().generateStore(gen, gen.operand(object()), gen.operand(value()), this); + Value address = location().generateAddress(gen, gen.operand(object())); + gen.emitStore(location().getValueKind(), address, gen.operand(value()), this); } @NodeIntrinsic diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes.java; +import java.lang.reflect.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -102,6 +104,14 @@ for (Node n : usages()) { assertTrue(n instanceof Invoke, "call target can only be used from an invoke (%s)", n); } + if (invokeKind == InvokeKind.Special || invokeKind == InvokeKind.Static) { + assertFalse(Modifier.isAbstract(targetMethod.getModifiers()), "special calls or static calls are only allowed for concrete methods (%s)", targetMethod); + } + if (invokeKind == InvokeKind.Static) { + assertTrue(Modifier.isStatic(targetMethod.getModifiers()), "static calls are only allowed for static methods (%s)", targetMethod); + } else { + assertFalse(Modifier.isStatic(targetMethod.getModifiers()), "static calls are only allowed for non-static methods (%s)", targetMethod); + } return super.verify(); } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Fri Apr 26 18:38:56 2013 +0200 @@ -29,11 +29,11 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; -public abstract class LIRGeneratorTool { +public interface LIRGeneratorTool { - public abstract TargetDescription target(); + TargetDescription target(); - public abstract CodeCacheProvider getRuntime(); + CodeCacheProvider getRuntime(); /** * Checks whether the supplied constant can be used without loading it into a register for most @@ -43,100 +43,99 @@ * @return True if the constant can be used directly, false if the constant needs to be in a * register. */ - public abstract boolean canInlineConstant(Constant c); + boolean canInlineConstant(Constant c); - public abstract RegisterAttributes attributes(Register register); + RegisterAttributes attributes(Register register); - public abstract Value operand(ValueNode object); + Value operand(ValueNode object); - public abstract AllocatableValue newVariable(Kind kind); + AllocatableValue newVariable(Kind kind); - public abstract Value setResult(ValueNode x, Value operand); + Value setResult(ValueNode x, Value operand); - public abstract Value emitMove(Value input); + AllocatableValue emitMove(Value input); - public abstract void emitMove(Value dst, Value src); + void emitMove(AllocatableValue dst, Value src); - public abstract Value emitLoad(Kind kind, Value base, long displacement, Value index, int scale, DeoptimizingNode deopting); + Value emitAddress(Value base, long displacement, Value index, int scale); - public abstract void emitStore(Kind kind, Value base, long displacement, Value index, int scale, Value input, DeoptimizingNode deopting); + Value emitAddress(StackSlot slot); - public abstract Value emitLea(Value base, long displacement, Value index, int scale); + Value emitLoad(Kind kind, Value address, DeoptimizingNode deopting); - public abstract Value emitLea(StackSlot slot); + void emitStore(Kind kind, Value address, Value input, DeoptimizingNode deopting); - public abstract Value emitNegate(Value input); + Value emitNegate(Value input); - public abstract Value emitAdd(Value a, Value b); + Value emitAdd(Value a, Value b); - public abstract Value emitSub(Value a, Value b); + Value emitSub(Value a, Value b); - public abstract Value emitMul(Value a, Value b); + Value emitMul(Value a, Value b); - public abstract Value emitDiv(Value a, Value b, DeoptimizingNode deopting); + Value emitDiv(Value a, Value b, DeoptimizingNode deopting); - public abstract Value emitRem(Value a, Value b, DeoptimizingNode deopting); + Value emitRem(Value a, Value b, DeoptimizingNode deopting); - public abstract Value emitUDiv(Value a, Value b, DeoptimizingNode deopting); + Value emitUDiv(Value a, Value b, DeoptimizingNode deopting); - public abstract Value emitURem(Value a, Value b, DeoptimizingNode deopting); + Value emitURem(Value a, Value b, DeoptimizingNode deopting); - public abstract Value emitAnd(Value a, Value b); + Value emitAnd(Value a, Value b); - public abstract Value emitOr(Value a, Value b); + Value emitOr(Value a, Value b); - public abstract Value emitXor(Value a, Value b); + Value emitXor(Value a, Value b); - public abstract Value emitShl(Value a, Value b); + Value emitShl(Value a, Value b); - public abstract Value emitShr(Value a, Value b); + Value emitShr(Value a, Value b); - public abstract Value emitUShr(Value a, Value b); + Value emitUShr(Value a, Value b); - public abstract Value emitConvert(ConvertNode.Op opcode, Value inputVal); + Value emitConvert(ConvertNode.Op opcode, Value inputVal); - public abstract void emitMembar(int barriers); + void emitMembar(int barriers); - public abstract void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting); + void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting); - public abstract void emitNullCheck(ValueNode v, DeoptimizingNode deopting); + void emitNullCheck(ValueNode v, DeoptimizingNode deopting); - public abstract Value emitCall(RuntimeCallTarget callTarget, CallingConvention cc, DeoptimizingNode info, Value... args); + Value emitCall(RuntimeCallTarget callTarget, CallingConvention cc, DeoptimizingNode info, Value... args); - public abstract void emitIf(IfNode i); + void emitIf(IfNode i); - public abstract void emitConditional(ConditionalNode i); + void emitConditional(ConditionalNode i); - public abstract void emitSwitch(SwitchNode i); + void emitSwitch(SwitchNode i); - public abstract void emitInvoke(Invoke i); + void emitInvoke(Invoke i); - public abstract void visitRuntimeCall(RuntimeCallNode i); + void visitRuntimeCall(RuntimeCallNode i); // Handling of block-end nodes still needs to be unified in the LIRGenerator. - public abstract void visitMerge(MergeNode i); + void visitMerge(MergeNode i); - public abstract void visitEndNode(EndNode i); + void visitEndNode(EndNode i); - public abstract void visitLoopEnd(LoopEndNode i); + void visitLoopEnd(LoopEndNode i); - public abstract void visitCompareAndSwap(CompareAndSwapNode i); + void visitCompareAndSwap(CompareAndSwapNode i); // These methods define the contract a runtime specific backend must provide. - public abstract void visitReturn(ReturnNode i); + void visitReturn(ReturnNode i); - public abstract void visitSafepointNode(SafepointNode i); + void visitSafepointNode(SafepointNode i); - public abstract void visitBreakpointNode(BreakpointNode i); + void visitBreakpointNode(BreakpointNode i); - public abstract void emitUnwind(Value operand); + void emitUnwind(Value operand); /** * Called just before register allocation is performed on the LIR owned by this generator. */ - public void beforeRegisterAllocation() { - } + void beforeRegisterAllocation(); - public abstract void visitInfopointNode(InfopointNode i); + void visitInfopointNode(InfopointNode i); } diff -r 0266549ff6e0 -r bdf4604fec2e 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 Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Fri Apr 26 18:38:56 2013 +0200 @@ -254,6 +254,10 @@ Class macroNodeClass = getMacroNodeClass(replacements, concrete); StructuredGraph graph = (StructuredGraph) invoke.asNode().graph(); if (macroNodeClass != null) { + if (((MethodCallTargetNode) invoke.callTarget()).targetMethod() != concrete) { + assert ((MethodCallTargetNode) invoke.callTarget()).invokeKind() != InvokeKind.Static; + InliningUtil.replaceInvokeCallTarget(invoke, graph, InvokeKind.Special, concrete); + } FixedWithNextNode macroNode; try { macroNode = macroNodeClass.getConstructor(Invoke.class).newInstance(invoke); @@ -294,12 +298,12 @@ } }); } + } - protected void replaceInvokeCallTarget(StructuredGraph graph, InvokeKind invokeKind, ResolvedJavaMethod targetMethod) { - MethodCallTargetNode oldCallTarget = (MethodCallTargetNode) invoke.callTarget(); - MethodCallTargetNode newCallTarget = graph.add(new MethodCallTargetNode(invokeKind, targetMethod, oldCallTarget.arguments().toArray(new ValueNode[0]), oldCallTarget.returnType())); - invoke.asNode().replaceFirstInput(oldCallTarget, newCallTarget); - } + public static void replaceInvokeCallTarget(Invoke invoke, StructuredGraph graph, InvokeKind invokeKind, ResolvedJavaMethod targetMethod) { + MethodCallTargetNode oldCallTarget = (MethodCallTargetNode) invoke.callTarget(); + MethodCallTargetNode newCallTarget = graph.add(new MethodCallTargetNode(invokeKind, targetMethod, oldCallTarget.arguments().toArray(new ValueNode[0]), oldCallTarget.returnType())); + invoke.asNode().replaceFirstInput(oldCallTarget, newCallTarget); } /** @@ -378,7 +382,7 @@ @Override public void tryToDevirtualizeInvoke(StructuredGraph graph, MetaAccessProvider runtime, Assumptions assumptions) { createGuard(graph, runtime); - replaceInvokeCallTarget(graph, InvokeKind.Special, concrete); + replaceInvokeCallTarget(invoke, graph, InvokeKind.Special, concrete); } private void createGuard(StructuredGraph graph, MetaAccessProvider runtime) { @@ -730,7 +734,7 @@ ValueNode receiver = ((MethodCallTargetNode) invoke.callTarget()).receiver(); PiNode anchoredReceiver = createAnchoredReceiver(graph, invocationEntry, target.getDeclaringClass(), receiver, false); invoke.callTarget().replaceFirstInput(receiver, anchoredReceiver); - replaceInvokeCallTarget(graph, kind, target); + replaceInvokeCallTarget(invoke, graph, kind, target); } private static BeginNode createUnknownTypeSuccessor(StructuredGraph graph) { @@ -775,15 +779,13 @@ @Override public void inline(StructuredGraph graph, MetaAccessProvider runtime, Replacements replacements, InliningCallback callback, Assumptions assumptions) { assumptions.record(takenAssumption); - Debug.log("recording assumption: %s", takenAssumption); - super.inline(graph, runtime, replacements, callback, assumptions); } @Override public void tryToDevirtualizeInvoke(StructuredGraph graph, MetaAccessProvider runtime, Assumptions assumptions) { assumptions.record(takenAssumption); - replaceInvokeCallTarget(graph, InvokeKind.Special, concrete); + replaceInvokeCallTarget(invoke, graph, InvokeKind.Special, concrete); } @Override diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java Fri Apr 26 18:38:56 2013 +0200 @@ -57,8 +57,7 @@ */ @Snippet public static int f2i(float input, int result) { - if (result == Integer.MIN_VALUE) { - probability(NOT_FREQUENT_PROBABILITY); + if (probability(SLOW_PATH_PROBABILITY, result == Integer.MIN_VALUE)) { if (Float.isNaN(input)) { // input is NaN -> return 0 return 0; @@ -83,8 +82,7 @@ */ @Snippet public static long f2l(float input, long result) { - if (result == Long.MIN_VALUE) { - probability(NOT_FREQUENT_PROBABILITY); + if (probability(SLOW_PATH_PROBABILITY, result == Long.MIN_VALUE)) { if (Float.isNaN(input)) { // input is NaN -> return 0 return 0; @@ -109,8 +107,7 @@ */ @Snippet public static int d2i(double input, int result) { - if (result == Integer.MIN_VALUE) { - probability(NOT_FREQUENT_PROBABILITY); + if (probability(SLOW_PATH_PROBABILITY, result == Integer.MIN_VALUE)) { if (Double.isNaN(input)) { // input is NaN -> return 0 return 0; @@ -135,8 +132,7 @@ */ @Snippet public static long d2l(double input, long result) { - if (result == Long.MIN_VALUE) { - probability(NOT_FREQUENT_PROBABILITY); + if (probability(SLOW_PATH_PROBABILITY, result == Long.MIN_VALUE)) { if (Double.isNaN(input)) { // input is NaN -> return 0 return 0; diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationVerificationPhase.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationVerificationPhase.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationVerificationPhase.java Fri Apr 26 18:38:56 2013 +0200 @@ -24,20 +24,20 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.*; -import com.oracle.graal.replacements.Snippet.*; +import com.oracle.graal.replacements.Snippet.Fold; /** * Checks that a graph contains no calls to {@link NodeIntrinsic} or {@link Fold} methods. */ public class NodeIntrinsificationVerificationPhase extends Phase { - public static boolean verify(StructuredGraph graph) { + public static void verify(StructuredGraph graph) { new NodeIntrinsificationVerificationPhase().apply(graph); - return true; } @Override @@ -49,11 +49,17 @@ private static void checkInvoke(MethodCallTargetNode n) { ResolvedJavaMethod target = n.targetMethod(); - NodeIntrinsic intrinsic = target.getAnnotation(Node.NodeIntrinsic.class); - if (intrinsic != null) { - throw new GraalInternalError("Illegal call to node intrinsic in " + n.graph() + ": " + n.invoke()); + if (target.getAnnotation(Node.NodeIntrinsic.class) != null) { + error(n, "Intrinsification"); } else if (target.getAnnotation(Fold.class) != null) { - throw new GraalInternalError("Illegal call to foldable method in " + n.graph() + ": " + n.invoke()); + error(n, "Folding"); } } + + private static void error(MethodCallTargetNode n, String failedAction) throws GraalInternalError { + String context = MetaUtil.format("%H.%n", ((StructuredGraph) n.graph()).method()); + String target = n.invoke().callTarget().targetName(); + throw new GraalInternalError(failedAction + " of call to '" + target + "' in '" + context + "' failed, most likely due to a parameter annotated with @" + + ConstantNodeParameter.class.getSimpleName() + " not being resolvable to a constant during compilation"); + } } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Fri Apr 26 18:38:56 2013 +0200 @@ -279,7 +279,10 @@ */ protected void finalizeGraph(StructuredGraph graph) { new NodeIntrinsificationPhase(runtime).apply(graph); - assert SnippetTemplate.hasConstantParameter(method) || NodeIntrinsificationVerificationPhase.verify(graph); + if (!SnippetTemplate.hasConstantParameter(method)) { + NodeIntrinsificationVerificationPhase.verify(graph); + } + new ConvertDeoptimizeToGuardPhase().apply(graph); if (original == null) { new SnippetFrameStateCleanupPhase().apply(graph); diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Fri Apr 26 18:38:56 2013 +0200 @@ -378,7 +378,7 @@ new CanonicalizerPhase.Instance(runtime, replacements.getAssumptions(), 0, null).apply(snippetCopy); } - assert NodeIntrinsificationVerificationPhase.verify(snippetCopy); + NodeIntrinsificationVerificationPhase.verify(snippetCopy); // Gather the template parameters parameters = new Object[parameterCount]; diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BranchProbabilityNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -22,17 +22,17 @@ */ package com.oracle.graal.replacements.nodes; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.nodes.util.*; /** * Instances of this node class will look for a preceding if node and put the given probability into * the if node's taken probability. Then the branch probability node will be removed. This node is * intended primarily for snippets, so that they can define their fast and slow paths. */ -public class BranchProbabilityNode extends FixedWithNextNode implements Simplifiable { +public class BranchProbabilityNode extends FloatingNode implements Canonicalizable, Lowerable { public static final double LIKELY_PROBABILITY = 0.6; public static final double NOT_LIKELY_PROBABILITY = 1 - LIKELY_PROBABILITY; @@ -43,41 +43,80 @@ public static final double FAST_PATH_PROBABILITY = 0.99; public static final double SLOW_PATH_PROBABILITY = 1 - FAST_PATH_PROBABILITY; - public static final double NOT_DEOPT_PATH_PROBABILITY = 0.999; - public static final double DEOPT_PATH_PROBABILITY = 1 - NOT_DEOPT_PATH_PROBABILITY; + public static final double VERY_FAST_DEOPT_PATH_PROBABILITY = 0.999; + public static final double VERY_SLOW_PATH_PROBABILITY = 1 - VERY_FAST_DEOPT_PATH_PROBABILITY; - private final double probability; + @Input private ValueNode probability; + @Input private ValueNode condition; - public BranchProbabilityNode(double probability) { - super(StampFactory.forVoid()); - assert probability >= 0 && probability <= 1; + public BranchProbabilityNode(ValueNode probability, ValueNode condition) { + super(condition.stamp()); this.probability = probability; + this.condition = condition; + } + + public ValueNode getProbability() { + return probability; + } + + public ValueNode getCondition() { + return condition; } @Override - public void simplify(SimplifierTool tool) { - FixedNode current = this; - while (!(current instanceof BeginNode)) { - current = (FixedNode) current.predecessor(); + public ValueNode canonical(CanonicalizerTool tool) { + if (probability.isConstant()) { + double probabilityValue = probability.asConstant().asDouble(); + if (probabilityValue < 0.0) { + throw new GraalInternalError("A negative probability of " + probabilityValue + " is not allowed!"); + } else if (probabilityValue > 1.0) { + throw new GraalInternalError("A probability of more than 1.0 (" + probabilityValue + ") is not allowed!"); + } + boolean couldSet = false; + for (IntegerEqualsNode node : this.usages().filter(IntegerEqualsNode.class)) { + if (node.condition() == Condition.EQ) { + ValueNode other = node.x(); + if (node.x() == this) { + other = node.y(); + } + if (other.isConstant()) { + double probabilityToSet = probabilityValue; + if (other.asConstant().asInt() == 0) { + probabilityToSet = 1.0 - probabilityToSet; + } + for (IfNode ifNodeUsages : node.usages().filter(IfNode.class)) { + couldSet = true; + ifNodeUsages.setTrueSuccessorProbability(probabilityToSet); + } + } + } + } + if (!couldSet) { + throw new GraalInternalError("Wrong usage of branch probability injection!"); + } + return condition; } - BeginNode begin = (BeginNode) current; - assert begin.predecessor() instanceof IfNode : "explicit branch probability cannot follow a merge, only if nodes"; - IfNode ifNode = (IfNode) begin.predecessor(); - if (ifNode.trueSuccessor() == begin) { - ifNode.setTrueSuccessorProbability(probability); - } else { - ifNode.setTrueSuccessorProbability(1 - probability); - } - - FixedNode next = next(); - setNext(null); - ((FixedWithNextNode) predecessor()).setNext(next); - GraphUtil.killCFG(this); + return this; } - @SuppressWarnings("unused") + /** + * This intrinsic should only be used for the condition of an if statement. The parameter + * condition should also only denote a simple condition and not a combined condition involving + * && or || operators. It injects the probability of the condition into the if statement. + * + * @param probability the probability that the given condition is true as a double value between + * 0.0 and 1.0. + * @param condition the simple condition without any && or || operators + * @return the condition + */ @NodeIntrinsic - public static void probability(@ConstantNodeParameter double probability) { + public static boolean probability(double probability, boolean condition) { + assert probability >= 0.0 && probability <= 1.0; + return condition; } + @Override + public void lower(LoweringTool tool, LoweringType loweringType) { + throw new GraalInternalError("Branch probability could not be injected, because the probability value did not reduce to a constant value."); + } } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectReadNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -47,7 +47,7 @@ @Override public void generate(LIRGeneratorTool gen) { - gen.setResult(this, gen.emitLoad(readKind, gen.operand(address), 0, Value.ILLEGAL, 0, null)); + gen.setResult(this, gen.emitLoad(readKind, gen.operand(address), null)); } @SuppressWarnings("unchecked") diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectStoreNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -50,7 +50,7 @@ @Override public void generate(LIRGeneratorTool gen) { Value v = gen.operand(value); - gen.emitStore(kind, gen.operand(address), 0, Value.ILLEGAL, 0, v, null); + gen.emitStore(kind, gen.operand(address), v, null); } /* diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -71,6 +71,7 @@ StructuredGraph snippetGraph = getSnippetGraph(tool); InvokeNode invoke = replaceWithInvoke(); + assert invoke.verify(); if (snippetGraph != null) { InliningUtil.inline(invoke, snippetGraph, false); diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/WriteRegisterNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/WriteRegisterNode.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/WriteRegisterNode.java Fri Apr 26 18:38:56 2013 +0200 @@ -54,7 +54,7 @@ @Override public void generate(LIRGeneratorTool generator) { Value val = generator.operand(value); - generator.emitMove(val, register.asValue(val.getKind())); + generator.emitMove(register.asValue(val.getKind()), val); } @Override diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java Fri Apr 26 18:38:56 2013 +0200 @@ -34,7 +34,7 @@ *

* Dynamically typed languages can speculate on the type of a frame slot and only fall back at run * time to a more generic type if necessary. The new type of a frame slot can be set using the - * {@link FrameSlot#setType(Class)} method. + * {@link FrameSlot#setKind(FrameSlotKind)} method. *

* *

@@ -48,13 +48,13 @@ public void test() { TruffleRuntime runtime = Truffle.getRuntime(); FrameDescriptor frameDescriptor = new FrameDescriptor(); - FrameSlot slot = frameDescriptor.addFrameSlot("localVar", int.class); + FrameSlot slot = frameDescriptor.addFrameSlot("localVar", FrameSlotKind.Int); TestRootNode rootNode = new TestRootNode(new IntAssignLocal(slot, new StringTestChildNode()), new IntReadLocal(slot)); CallTarget target = runtime.createCallTarget(rootNode, frameDescriptor); - Assert.assertEquals(int.class, slot.getType()); + Assert.assertEquals(FrameSlotKind.Int, slot.getKind()); Object result = target.call(); Assert.assertEquals("42", result); - Assert.assertEquals(Object.class, slot.getType()); + Assert.assertEquals(FrameSlotKind.Object, slot.getKind()); } class TestRootNode extends RootNode { diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java Fri Apr 26 18:38:56 2013 +0200 @@ -35,9 +35,9 @@ * The frame is the preferred data structure for passing values between nodes. It can in particular * be used for storing the values of local variables of the guest language. The * {@link FrameDescriptor} represents the current structure of the frame. The method - * {@link FrameDescriptor#addFrameSlot(Object, Class)} can be used to create predefined frame slots. - * The setter and getter methods in the {@link Frame} class can be used to access the current value - * of a particular frame slot. + * {@link FrameDescriptor#addFrameSlot(Object, FrameSlotKind)} can be used to create predefined + * frame slots. The setter and getter methods in the {@link Frame} class can be used to access the + * current value of a particular frame slot. *

* *

@@ -64,7 +64,7 @@ public void test() { TruffleRuntime runtime = Truffle.getRuntime(); FrameDescriptor frameDescriptor = new FrameDescriptor(); - FrameSlot slot = frameDescriptor.addFrameSlot("localVar", int.class); + FrameSlot slot = frameDescriptor.addFrameSlot("localVar", FrameSlotKind.Int); TestRootNode rootNode = new TestRootNode(new AssignLocal(slot), new ReadLocal(slot)); CallTarget target = runtime.createCallTarget(rootNode, frameDescriptor); Object result = target.call(); diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java Fri Apr 26 18:38:56 2013 +0200 @@ -47,13 +47,13 @@ public void test() { TruffleRuntime runtime = Truffle.getRuntime(); FrameDescriptor frameDescriptor = new FrameDescriptor(); - FrameSlot slot = frameDescriptor.addFrameSlot("localVar", int.class); + FrameSlot slot = frameDescriptor.addFrameSlot("localVar", FrameSlotKind.Int); TestRootNode rootNode = new TestRootNode(new IntAssignLocal(slot, new StringTestChildNode()), new IntReadLocal(slot)); CallTarget target = runtime.createCallTarget(rootNode, frameDescriptor); - Assert.assertEquals(int.class, slot.getType()); + Assert.assertEquals(FrameSlotKind.Int, slot.getKind()); Object result = target.call(); Assert.assertEquals("42", result); - Assert.assertEquals(Object.class, slot.getType()); + Assert.assertEquals(FrameSlotKind.Object, slot.getKind()); } class TestRootNode extends RootNode { diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java Fri Apr 26 18:38:56 2013 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.truffle.api; +import java.lang.annotation.*; import java.util.concurrent.*; /** @@ -30,7 +31,11 @@ */ public class CompilerDirectives { - private static final double SLOWPATH_PROBABILITY = 0.0001; + public static final double LIKELY_PROBABILITY = 0.75; + public static final double UNLIKELY_PROBABILITY = 1.0 - LIKELY_PROBABILITY; + + public static final double SLOWPATH_PROBABILITY = 0.0001; + public static final double FASTPATH_PROBABILITY = 1.0 - SLOWPATH_PROBABILITY; /** * Directive for the compiler to discontinue compilation at this code position and instead @@ -62,20 +67,38 @@ } /** - * Directive for the compiler that the current path has a very low probability to be executed. - */ - public static void slowpath() { - injectBranchProbability(SLOWPATH_PROBABILITY); - } - - /** - * Injects a probability for the current path into the probability information of the - * immediately preceeding branch instruction. + * Injects a probability for the given condition into the probability information of the + * immediately succeeding branch instruction for the condition. The probability must be a value + * between 0.0 and 1.0 (inclusive). The condition should not be a combined condition. + * + * Example usage immediately before an if statement (it specifies that the likelihood for a to + * be greater than b is 90%): + * + * + * if (injectBranchProbability(0.9, a > b)) { + * // ... + * } + * + * + * Example usage for a combined condition (it specifies that the likelihood for a to be greater + * than b is 90% and under the assumption that this is true, the likelihood for a being 0 is + * 10%): + * + * + * if (injectBranchProbability(0.9, a > b) && injectBranchProbability(0.1, a == 0)) { + * // ... + * } + * + * + * There are predefined constants for commonly used probabilities (see + * {@link #LIKELY_PROBABILITY} , {@link #UNLIKELY_PROBABILITY}, {@link #SLOWPATH_PROBABILITY}, + * {@link #FASTPATH_PROBABILITY} ). * * @param probability the probability value between 0.0 and 1.0 that should be injected */ - public static void injectBranchProbability(double probability) { + public static boolean injectBranchProbability(double probability, boolean condition) { assert probability >= 0.0 && probability <= 1.0; + return condition; } /** @@ -85,4 +108,13 @@ */ public static void bailout(String reason) { } + + /** + * Marks fields that should be considered final for a Truffle compilation although they are not + * final while executing in the interpreter. + */ + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.FIELD}) + public @interface CompilationFinal { + } } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java Fri Apr 26 18:38:56 2013 +0200 @@ -53,9 +53,9 @@ return addFrameSlot(identifier, null); } - public FrameSlot addFrameSlot(Object identifier, Class type) { + public FrameSlot addFrameSlot(Object identifier, FrameSlotKind kind) { assert !identifierToSlotMap.containsKey(identifier); - FrameSlotImpl slot = new FrameSlotImpl(this, identifier, slots.size(), type); + FrameSlotImpl slot = new FrameSlotImpl(this, identifier, slots.size(), kind); slots.add(slot); identifierToSlotMap.put(identifier, slot); updateVersion(); @@ -74,12 +74,12 @@ return addFrameSlot(identifier); } - public FrameSlot findOrAddFrameSlot(Object identifier, Class type) { + public FrameSlot findOrAddFrameSlot(Object identifier, FrameSlotKind kind) { FrameSlot result = findFrameSlot(identifier); if (result != null) { return result; } - return addFrameSlot(identifier, type); + return addFrameSlot(identifier, kind); } public int getSize() { diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlot.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlot.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlot.java Fri Apr 26 18:38:56 2013 +0200 @@ -31,9 +31,9 @@ int getIndex(); - Class getType(); + FrameSlotKind getKind(); - void setType(Class type); + void setKind(FrameSlotKind kind); FrameDescriptor getFrameDescriptor(); } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotImpl.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotImpl.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotImpl.java Fri Apr 26 18:38:56 2013 +0200 @@ -27,13 +27,13 @@ private final FrameDescriptor descriptor; private final Object identifier; private final int index; - private Class type; + private FrameSlotKind kind; - protected FrameSlotImpl(FrameDescriptor descriptor, Object identifier, int index, Class type) { + protected FrameSlotImpl(FrameDescriptor descriptor, Object identifier, int index, FrameSlotKind kind) { this.descriptor = descriptor; this.identifier = identifier; this.index = index; - this.type = type; + this.kind = kind; } public Object getIdentifier() { @@ -44,19 +44,19 @@ return index; } - public Class getType() { - return type; + public FrameSlotKind getKind() { + return kind; } - public void setType(final Class type) { - assert this.type != type; - this.type = type; + public void setKind(final FrameSlotKind kind) { + assert this.kind != kind; + this.kind = kind; this.descriptor.updateVersion(); } @Override public String toString() { - return "[" + index + "," + identifier + "," + type + "]"; + return "[" + index + "," + identifier + "," + kind + "]"; } @Override diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotKind.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotKind.java Fri Apr 26 18:38:56 2013 +0200 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2013, 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.truffle.api.frame; + +public enum FrameSlotKind { + Illegal, Object, Long, Int, Double, Float, Boolean; +} diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameUtil.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameUtil.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameUtil.java Fri Apr 26 18:38:56 2013 +0200 @@ -33,8 +33,8 @@ * @param value the new value of the local variable */ public static void setObjectSafe(Frame frame, FrameSlot slot, Object value) { - if (slot.getType() != Object.class) { - slot.setType(Object.class); + if (slot.getKind() != FrameSlotKind.Object) { + slot.setKind(FrameSlotKind.Object); } try { frame.setObject(slot, value); @@ -52,8 +52,8 @@ * @param value the new value of the local variable */ public static void setBooleanSafe(Frame frame, FrameSlot slot, boolean value) { - if (slot.getType() != boolean.class) { - slot.setType(boolean.class); + if (slot.getKind() != FrameSlotKind.Boolean) { + slot.setKind(FrameSlotKind.Boolean); } try { frame.setBoolean(slot, value); @@ -71,8 +71,8 @@ * @param value the new value of the local variable */ public static void setIntSafe(Frame frame, FrameSlot slot, int value) { - if (slot.getType() != int.class) { - slot.setType(int.class); + if (slot.getKind() != FrameSlotKind.Int) { + slot.setKind(FrameSlotKind.Int); } try { frame.setInt(slot, value); @@ -90,8 +90,8 @@ * @param value the new value of the local variable */ public static void setLongSafe(Frame frame, FrameSlot slot, long value) { - if (slot.getType() != long.class) { - slot.setType(long.class); + if (slot.getKind() != FrameSlotKind.Long) { + slot.setKind(FrameSlotKind.Long); } try { frame.setLong(slot, value); @@ -109,8 +109,8 @@ * @param value the new value of the local variable */ public static void setFloatSafe(Frame frame, FrameSlot slot, float value) { - if (slot.getType() != float.class) { - slot.setType(float.class); + if (slot.getKind() != FrameSlotKind.Float) { + slot.setKind(FrameSlotKind.Float); } try { frame.setFloat(slot, value); @@ -128,8 +128,8 @@ * @param value the new value of the local variable */ public static void setDoubleSafe(Frame frame, FrameSlot slot, double value) { - if (slot.getType() != double.class) { - slot.setType(double.class); + if (slot.getKind() != FrameSlotKind.Double) { + slot.setKind(FrameSlotKind.Double); } try { frame.setDouble(slot, value); diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java Fri Apr 26 18:38:56 2013 +0200 @@ -33,14 +33,14 @@ private final PackedFrame caller; private final Arguments arguments; private Object[] locals; - private Class[] tags; + private byte[] tags; public DefaultVirtualFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments arguments) { this.descriptor = descriptor; this.caller = caller; this.arguments = arguments; this.locals = new Object[descriptor.getSize()]; - this.tags = new Class[descriptor.getSize()]; + this.tags = new byte[descriptor.getSize()]; } @Override @@ -65,73 +65,73 @@ @Override public Object getObject(FrameSlot slot) throws FrameSlotTypeException { - verifyGet(slot, Object.class); + verifyGet(slot, FrameSlotKind.Object); return locals[slot.getIndex()]; } @Override public void setObject(FrameSlot slot, Object value) throws FrameSlotTypeException { - verifySet(slot, Object.class); + verifySet(slot, FrameSlotKind.Object); locals[slot.getIndex()] = value; } @Override public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException { - verifyGet(slot, boolean.class); + verifyGet(slot, FrameSlotKind.Boolean); return (boolean) locals[slot.getIndex()]; } @Override public void setBoolean(FrameSlot slot, boolean value) throws FrameSlotTypeException { - verifySet(slot, boolean.class); + verifySet(slot, FrameSlotKind.Boolean); locals[slot.getIndex()] = value; } @Override public int getInt(FrameSlot slot) throws FrameSlotTypeException { - verifyGet(slot, int.class); + verifyGet(slot, FrameSlotKind.Int); return (int) locals[slot.getIndex()]; } @Override public void setInt(FrameSlot slot, int value) throws FrameSlotTypeException { - verifySet(slot, int.class); + verifySet(slot, FrameSlotKind.Int); locals[slot.getIndex()] = value; } @Override public long getLong(FrameSlot slot) throws FrameSlotTypeException { - verifyGet(slot, long.class); + verifyGet(slot, FrameSlotKind.Long); return (long) locals[slot.getIndex()]; } @Override public void setLong(FrameSlot slot, long value) throws FrameSlotTypeException { - verifySet(slot, long.class); + verifySet(slot, FrameSlotKind.Long); locals[slot.getIndex()] = value; } @Override public float getFloat(FrameSlot slot) throws FrameSlotTypeException { - verifyGet(slot, float.class); + verifyGet(slot, FrameSlotKind.Float); return (float) locals[slot.getIndex()]; } @Override public void setFloat(FrameSlot slot, float value) throws FrameSlotTypeException { - verifySet(slot, float.class); + verifySet(slot, FrameSlotKind.Float); locals[slot.getIndex()] = value; } @Override public double getDouble(FrameSlot slot) throws FrameSlotTypeException { - verifyGet(slot, double.class); + verifyGet(slot, FrameSlotKind.Double); return (double) locals[slot.getIndex()]; } @Override public void setDouble(FrameSlot slot, double value) throws FrameSlotTypeException { - verifySet(slot, double.class); + verifySet(slot, FrameSlotKind.Double); locals[slot.getIndex()] = value; } @@ -147,19 +147,19 @@ assert index >= 0 && index < descriptor.getSize(); return descriptor.getTypeConversion().getDefaultValue(); } - Class tag = tags[index]; - if (tag == null) { + byte tag = tags[index]; + if (tag == FrameSlotKind.Illegal.ordinal()) { return descriptor.getTypeConversion().getDefaultValue(); } else { return locals[index]; } } - private void verifySet(FrameSlot slot, Class accessType) throws FrameSlotTypeException { - Class slotType = slot.getType(); - if (slotType != accessType) { - if (slotType == null) { - slot.setType(accessType); + private void verifySet(FrameSlot slot, FrameSlotKind accessKind) throws FrameSlotTypeException { + FrameSlotKind slotKind = slot.getKind(); + if (slotKind != accessKind) { + if (slotKind == FrameSlotKind.Illegal) { + slot.setKind(accessKind); } else { throw new FrameSlotTypeException(); } @@ -168,14 +168,14 @@ if (slotIndex >= tags.length) { resize(); } - tags[slotIndex] = accessType; + tags[slotIndex] = (byte) accessKind.ordinal(); } - private void verifyGet(FrameSlot slot, Class accessType) throws FrameSlotTypeException { - Class slotType = slot.getType(); - if (slotType != accessType) { - if (slotType == null && accessType == Object.class) { - slot.setType(Object.class); + private void verifyGet(FrameSlot slot, FrameSlotKind accessKind) throws FrameSlotTypeException { + FrameSlotKind slotKind = slot.getKind(); + if (slotKind != accessKind) { + if (slotKind == FrameSlotKind.Illegal && accessKind == FrameSlotKind.Object) { + slot.setKind(FrameSlotKind.Object); this.setObject(slot, descriptor.getTypeConversion().getDefaultValue()); } else { throw new FrameSlotTypeException(); @@ -185,9 +185,9 @@ if (slotIndex >= tags.length) { resize(); } - if (tags[slotIndex] != accessType) { + if (tags[slotIndex] != accessKind.ordinal()) { descriptor.getTypeConversion().updateFrameSlot(this, slot, getValue(slot)); - if (tags[slotIndex] != accessType) { + if (tags[slotIndex] != accessKind.ordinal()) { throw new FrameSlotTypeException(); } } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Fri Apr 26 18:38:56 2013 +0200 @@ -96,8 +96,7 @@ } } - private static void addInternalValueParameterNames(CodeTreeBuilder builder, TemplateMethod source, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame, - boolean includeImplicit) { + private void addInternalValueParameterNames(CodeTreeBuilder builder, TemplateMethod source, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame, boolean includeImplicit) { if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) { builder.string("frameValue"); } @@ -126,12 +125,12 @@ } } - private static String valueName(ActualParameter sourceParameter, ActualParameter targetParameter) { + private String valueName(ActualParameter sourceParameter, ActualParameter targetParameter) { if (sourceParameter != null) { if (!sourceParameter.getSpecification().isSignature()) { return valueName(targetParameter); } else if (sourceParameter.getTypeSystemType() != null && targetParameter.getTypeSystemType() != null) { - if (sourceParameter.getTypeSystemType().needsCastTo(targetParameter.getTypeSystemType())) { + if (sourceParameter.getTypeSystemType().needsCastTo(getContext(), targetParameter.getTypeSystemType())) { return castValueName(targetParameter); } } @@ -324,7 +323,7 @@ } TypeData sourceType = sourceParameter.getTypeSystemType(); - if (sourceType.needsCastTo(targetType)) { + if (sourceType.needsCastTo(getContext(), targetType)) { valuesNeedsCast.add(targetParameter.getLocalName()); } } @@ -469,7 +468,7 @@ TypeData targetType = target.getTypeSystemType(); TypeData sourceType = source.getTypeSystemType(); - if (!sourceType.needsCastTo(targetType)) { + if (!sourceType.needsCastTo(getContext(), targetType)) { return null; } @@ -501,7 +500,7 @@ TypeData sourceType = source.getTypeSystemType(); TypeData targetType = target.getTypeSystemType(); - if (!sourceType.needsCastTo(targetType)) { + if (!sourceType.needsCastTo(getContext(), targetType)) { return null; } @@ -1639,7 +1638,7 @@ if (targetType == null || sourceType == null) { builder.tree(returnBuilder.getRoot()); - } else if (sourceType.needsCastTo(targetType)) { + } else if (sourceType.needsCastTo(getContext(), targetType)) { builder.tree(createCallTypeSystemMethod(context, parent, node, TypeSystemCodeGenerator.expectTypeMethodName(targetType), returnBuilder.getRoot())); } else { builder.tree(returnBuilder.getRoot()); @@ -1684,7 +1683,7 @@ CodeTree executionExpression = null; if (cast || sourceParameter != null) { TypeData sourceType = sourceParameter.getTypeSystemType(); - if (!sourceType.needsCastTo(targetType)) { + if (!sourceType.needsCastTo(getContext(), targetType)) { if (field.isShortCircuit() && sourceParameter != null) { builder.tree(createShortCircuitValue(builder, specialization, field, targetParameter.getPreviousParameter(), unexpectedParameter)); } @@ -1726,7 +1725,7 @@ CodeTreeBuilder builder = new CodeTreeBuilder(parent); boolean unexpected = targetExecutable.hasUnexpectedValue(getContext()); boolean cast = false; - if (targetExecutable.getType().needsCastTo(param.getTypeSystemType())) { + if (targetExecutable.getType().needsCastTo(getContext(), param.getTypeSystemType())) { unexpected = true; cast = true; } @@ -1750,7 +1749,7 @@ } builder.string(" = "); if (cast) { - builder.tree(createExpectType(specialization.getNode(), specialization.getReturnSignature(), body)); + builder.tree(createExpectType(specialization.getNode(), param.getTypeSystemType(), body)); } else { builder.tree(body); } @@ -1807,17 +1806,17 @@ if (index < signatureParameters.size()) { ActualParameter specializationParam = signatureParameters.get(index); + TypeData targetType = parameter.getTypeSystemType(); + TypeData sourceType = specializationParam.getTypeSystemType(); String localName = specializationParam.getLocalName(); if (unexpectedParameter != null && unexpectedParameter.getLocalName().equals(specializationParam.getLocalName())) { localName = "ex.getResult()"; + sourceType = getModel().getNode().getTypeSystem().getGenericTypeData(); } - TypeData sourceType = specializationParam.getTypeSystemType(); - TypeData targetType = parameter.getTypeSystemType(); - CodeTree value = CodeTreeBuilder.singleString(localName); - if (sourceType.needsCastTo(targetType)) { + if (sourceType.needsCastTo(getContext(), targetType)) { value = createCallTypeSystemMethod(getContext(), builder, getModel().getNode(), TypeSystemCodeGenerator.asTypeMethodName(targetType), value); } builder.tree(value); diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java Fri Apr 26 18:38:56 2013 +0200 @@ -93,6 +93,10 @@ if (type.hasUnexpectedValue(context)) { return true; } + if (type.getReturnType().getTypeSystemType().needsCastTo(context, parameter.getTypeSystemType())) { + return true; + } + } return false; } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeData.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeData.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeData.java Fri Apr 26 18:38:56 2013 +0200 @@ -110,13 +110,15 @@ return Utils.typeEquals(boxedType, actualTypeData.boxedType); } - public boolean needsCastTo(TypeData targetType) { + public boolean needsCastTo(ProcessorContext context, TypeData targetType) { if (this.equals(targetType)) { return false; } else if (targetType.isGeneric()) { return false; } else if (targetType.isVoid()) { return false; + } else if (Utils.isAssignable(context, getPrimitiveType(), targetType.getPrimitiveType())) { + return false; } return true; } diff -r 0266549ff6e0 -r bdf4604fec2e graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/NodeFactory.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/NodeFactory.java Fri Apr 26 18:36:41 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/NodeFactory.java Fri Apr 26 18:38:56 2013 +0200 @@ -59,7 +59,7 @@ } public TypedNode createLocal(String name) { - return ReadLocalNodeFactory.create(frameDescriptor.findOrAddFrameSlot(name, int.class)); + return ReadLocalNodeFactory.create(frameDescriptor.findOrAddFrameSlot(name, FrameSlotKind.Int)); } public TypedNode createStringLiteral(String value) { @@ -67,7 +67,7 @@ } public StatementNode createAssignment(String name, TypedNode right) { - return WriteLocalNodeFactory.create(frameDescriptor.findOrAddFrameSlot(name, int.class), right); + return WriteLocalNodeFactory.create(frameDescriptor.findOrAddFrameSlot(name, FrameSlotKind.Int), right); } public StatementNode createPrint(List expressions) { @@ -123,7 +123,7 @@ } public StatementNode createReturn(TypedNode value) { - FrameSlot slot = frameDescriptor.findOrAddFrameSlot("", int.class); + FrameSlot slot = frameDescriptor.findOrAddFrameSlot("", FrameSlotKind.Int); if (returnValue == null) { returnValue = ReadLocalNodeFactory.create(slot); } diff -r 0266549ff6e0 -r bdf4604fec2e mx/sanitycheck.py --- a/mx/sanitycheck.py Fri Apr 26 18:36:41 2013 +0200 +++ b/mx/sanitycheck.py Fri Apr 26 18:38:56 2013 +0200 @@ -47,7 +47,8 @@ } dacapoScalaSanityWarmup = { - 'actors': [0, 0, 2, 8, 10], +# (tw) actors sometimes fails verification; hardly reproducible + 'actors': [0, 0, 0, 0, 0], # (lstadler) apparat was disabled due to a deadlock which I think is the benchmarks fault. 'apparat': [0, 0, 0, 0, 0], 'factorie': [0, 0, 2, 5, 5], diff -r 0266549ff6e0 -r bdf4604fec2e src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Fri Apr 26 18:36:41 2013 +0200 +++ b/src/share/vm/graal/graalJavaAccess.hpp Fri Apr 26 18:38:56 2013 +0200 @@ -203,7 +203,7 @@ end_class \ start_class(Value) \ oop_field(Value, kind, "Lcom/oracle/graal/api/meta/Kind;") \ - static_oop_field(Value, ILLEGAL, "Lcom/oracle/graal/api/meta/Value;"); \ + static_oop_field(Value, ILLEGAL, "Lcom/oracle/graal/api/meta/AllocatableValue;"); \ end_class \ start_class(RegisterValue) \ oop_field(RegisterValue, reg, "Lcom/oracle/graal/api/code/Register;") \