# HG changeset patch # User Thomas Wuerthinger # Date 1381180560 -7200 # Node ID 60bf1372d1a00b9da0420cfabfc6d74420b57adb # Parent 66909d05531457a6a6b3dc0a9997b84e24f6871f# Parent b7ce25d81ef3c3ecb8acaea11e27e065ba6d103a Merge. diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ObjectLocationIdentity.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ObjectLocationIdentity.java Mon Oct 07 23:16:00 2013 +0200 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013, 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; + +import java.util.*; + +/** + * A {@link LocationIdentity} warpping an object. + */ +public final class ObjectLocationIdentity implements LocationIdentity { + + private static IdentityHashMap map = new IdentityHashMap<>(); + + private Object object; + + public static LocationIdentity create(Object object) { + synchronized (map) { + if (map.containsKey(object)) { + return map.get(object); + } else { + ObjectLocationIdentity locationIdentity = new ObjectLocationIdentity(object); + map.put(object, locationIdentity); + return locationIdentity; + } + } + } + + private ObjectLocationIdentity(Object object) { + this.object = object; + } + + @Override + public String toString() { + return "Identity(" + object + ")"; + } +} diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java Mon Oct 07 23:16:00 2013 +0200 @@ -29,7 +29,7 @@ * Represents a reference to a resolved Java field. Fields, like methods and types, are resolved * through {@link ConstantPool constant pools}. */ -public interface ResolvedJavaField extends JavaField { +public interface ResolvedJavaField extends JavaField, LocationIdentity { /** * Returns the Java language modifiers for this field, as an integer. The {@link Modifier} class diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java --- a/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Mon Oct 07 23:16:00 2013 +0200 @@ -229,7 +229,7 @@ public static class SingleOperandFormat { protected Variable dest; - protected Value source; + protected Value source; public SingleOperandFormat(Variable dst, Value src) { setDestination(dst); @@ -340,8 +340,7 @@ @Override public String emit() { - return (typeForKind(dest.getKind()) + "." + typeForKind(source.getKind()) + " " + - emitVariable(dest) + ", " + emitValue(source) + ";"); + return (typeForKind(dest.getKind()) + "." + typeForKind(source.getKind()) + " " + emitVariable(dest) + ", " + emitValue(source) + ";"); } } @@ -367,21 +366,18 @@ @Override public String emitRegister(Variable var, boolean comma) { - /* if (space == Parameter) { - return ("param" + var.index); - } else { - return ("%r" + var.index); - } */ + /* + * if (space == Parameter) { return ("param" + var.index); } else { return ("%r" + + * var.index); } + */ return ("%r" + var.index); } public String emit(boolean isLoad) { if (isLoad) { - return (space.getStateName() + "." + typeForKind(valueKind) + " " + - emitRegister(dest, false) + ", " + emitAddress(source1, source2) + ";"); + return (space.getStateName() + "." + typeForKind(valueKind) + " " + emitRegister(dest, false) + ", " + emitAddress(source1, source2) + ";"); } else { - return (space.getStateName() + "." + typeForKind(valueKind) + " " + - emitAddress(source1, source2) + ", " + emitRegister(dest, false) + ";"); + return (space.getStateName() + "." + typeForKind(valueKind) + " " + emitAddress(source1, source2) + ", " + emitRegister(dest, false) + ";"); } } } @@ -546,7 +542,7 @@ } } } - + public static class Mov extends SingleOperandFormat { private int predicateRegisterNumber = -1; @@ -559,16 +555,15 @@ super(dst, src); this.predicateRegisterNumber = predicate; } + /* - public Mov(Variable dst, AbstractAddress src) { - throw GraalInternalError.unimplemented("AbstractAddress Mov"); - } - */ - + * public Mov(Variable dst, AbstractAddress src) { throw + * GraalInternalError.unimplemented("AbstractAddress Mov"); } + */ + public void emit(PTXAssembler asm) { if (predicateRegisterNumber >= 0) { - asm.emitString("@%p" + String.valueOf(predicateRegisterNumber) - + " mov." + super.emit()); + asm.emitString("@%p" + String.valueOf(predicateRegisterNumber) + " mov." + super.emit()); } else { asm.emitString("mov." + super.emit()); } @@ -585,7 +580,7 @@ asm.emitString("neg." + super.emit()); } } - + public static class Not extends BinarySingleOperandFormat { public Not(Variable dst, Variable src) { @@ -596,7 +591,7 @@ asm.emitString("not." + super.emit()); } } - + public static class Ld extends LoadStoreFormat { public Ld(PTXStateSpace space, Variable dst, Variable src1, Value src2) { @@ -651,7 +646,7 @@ for (int i = 0; i < refs.length; i++) { sb.append(asm.nameOf(refs[i].label())); - if (i < (refs.length -1)) { + if (i < (refs.length - 1)) { sb.append(", "); } } @@ -660,9 +655,7 @@ } public void emit(PTXAssembler asm) { - asm.emitString(".global ." + valueForKind(kind) + - " " + name + "[" + targets.length + "] = " + - "{ " + emitTargets(asm, targets) + " };"); + asm.emitString(".global ." + valueForKind(kind) + " " + name + "[" + targets.length + "] = " + "{ " + emitTargets(asm, targets) + " };"); } } @@ -684,7 +677,7 @@ } public void emit(PTXAssembler asm) { - asm.emitString(".param ." + paramForKind(dest.getKind()) + emitParameter(dest) + (lastParameter ? "" : ",")); + asm.emitString(".param ." + paramForKind(dest.getKind()) + emitParameter(dest) + (lastParameter ? "" : ",")); } public String paramForKind(Kind k) { @@ -730,9 +723,7 @@ } public enum BooleanOperator { - AND("and"), - OR("or"), - XOR("xor"); + AND("and"), OR("or"), XOR("xor"); private final String output; @@ -745,18 +736,15 @@ } } - public static class Setp { - + public static class Setp { - private BooleanOperator booleanOperator; - private ConditionOperator operator; + private BooleanOperator booleanOperator; + private ConditionOperator operator; private Value first, second; private Kind kind; private int predicate; - public Setp(Condition condition, - Value first, Value second, - int predicateRegisterNumber) { + public Setp(Condition condition, Value first, Value second, int predicateRegisterNumber) { setFirst(first); setSecond(second); setPredicate(predicateRegisterNumber); @@ -764,9 +752,7 @@ setConditionOperator(operatorForConditon(condition)); } - public Setp(Condition condition, BooleanOperator operator, - Value first, Value second, - int predicateRegisterNumber) { + public Setp(Condition condition, BooleanOperator operator, Value first, Value second, int predicateRegisterNumber) { setFirst(first); setSecond(second); setPredicate(predicateRegisterNumber); @@ -804,12 +790,18 @@ case 'a': // unsigned switch (condition) { - case EQ: return ConditionOperator.U_EQ; - case NE: return ConditionOperator.U_NE; - case LT: return ConditionOperator.U_LO; - case LE: return ConditionOperator.U_LS; - case GT: return ConditionOperator.U_HI; - case GE: return ConditionOperator.U_HS; + case EQ: + return ConditionOperator.U_EQ; + case NE: + return ConditionOperator.U_NE; + case LT: + return ConditionOperator.U_LO; + case LE: + return ConditionOperator.U_LS; + case GT: + return ConditionOperator.U_HI; + case GE: + return ConditionOperator.U_HS; default: throw GraalInternalError.shouldNotReachHere(); } @@ -819,11 +811,16 @@ case 'j': // signed switch (condition) { - case EQ: return ConditionOperator.S_EQ; - case NE: return ConditionOperator.S_NE; - case LT: return ConditionOperator.S_LT; - case LE: return ConditionOperator.S_LE; - case GT: return ConditionOperator.S_GT; + case EQ: + return ConditionOperator.S_EQ; + case NE: + return ConditionOperator.S_NE; + case LT: + return ConditionOperator.S_LT; + case LE: + return ConditionOperator.S_LE; + case GT: + return ConditionOperator.S_GT; case GE: case AE: return ConditionOperator.S_GE; @@ -834,12 +831,18 @@ case 'd': // floating point - do these need to accept NaN?? switch (condition) { - case EQ: return ConditionOperator.F_EQ; - case NE: return ConditionOperator.F_NE; - case LT: return ConditionOperator.F_LT; - case LE: return ConditionOperator.F_LE; - case GT: return ConditionOperator.F_GT; - case GE: return ConditionOperator.F_GE; + case EQ: + return ConditionOperator.F_EQ; + case NE: + return ConditionOperator.F_NE; + case LT: + return ConditionOperator.F_LT; + case LE: + return ConditionOperator.F_LE; + case GT: + return ConditionOperator.F_GT; + case GE: + return ConditionOperator.F_GE; default: throw GraalInternalError.shouldNotReachHere(); } @@ -857,7 +860,7 @@ kind = first.getKind(); } } - + public String emitValue(Value v) { assert v != null; @@ -909,7 +912,7 @@ throw GraalInternalError.shouldNotReachHere(); } } - + public String emitVariable(Variable v) { return ("%r" + v.index); } @@ -917,21 +920,15 @@ public void emit(PTXAssembler asm) { if (booleanOperator != null) { - asm.emitString("setp." + - operator.getOperator() + "." + - booleanOperator.getOperator() + - typeForKind(kind) + " %p" + predicate + - emitValue(first) + emitValue(second) + - ", %r;"); // Predicates need to be objects + asm.emitString("setp." + operator.getOperator() + "." + booleanOperator.getOperator() + typeForKind(kind) + " %p" + predicate + emitValue(first) + emitValue(second) + ", %r;"); // Predicates +// need to be objects } else { - asm.emitString("setp." + - operator.getOperator() + "." + - typeForKind(kind) + " %p" + predicate + - emitValue(first) + emitValue(second) + ";"); + asm.emitString("setp." + operator.getOperator() + "." + typeForKind(kind) + " %p" + predicate + emitValue(first) + emitValue(second) + ";"); } } } + @Override public PTXAddress makeAddress(Register base, int displacement) { throw GraalInternalError.shouldNotReachHere(); @@ -951,5 +948,4 @@ bra(str); } - } diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java Mon Oct 07 23:16:00 2013 +0200 @@ -24,7 +24,6 @@ import java.lang.reflect.Method; -import org.junit.Ignore; import org.junit.Test; /** diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java Mon Oct 07 23:16:00 2013 +0200 @@ -36,7 +36,7 @@ } else { printReport("testLoop: no VALUE"); } - ret = (Integer) invoke(compile("testSwitchDefault1I"), 3); + ret = (Integer) invoke(compile("testSwitchDefault1I"), 3); if (ret != null) { printReport("testSwitchDefault1I: " + ret); } else { @@ -96,7 +96,7 @@ } public static int testIfElse2I(int c, int y) { - if (c > 19) { + if (c > 19) { return 'M'; // millenial } else if (y > 84) { return 'Y'; // young diff -r b7ce25d81ef3 -r 60bf1372d1a0 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 Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Mon Oct 07 23:16:00 2013 +0200 @@ -66,7 +66,6 @@ import java.lang.annotation.*; - /** * This class implements the PTX specific portion of the LIR generator. */ @@ -88,9 +87,7 @@ } } - public PTXLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, - TargetDescription target, FrameMap frameMap, - CallingConvention cc, LIR lir) { + public PTXLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) { super(graph, runtime, target, frameMap, cc, lir); lir.spillMoveFactory = new PTXSpillMoveFactory(); int callVariables = cc.getArgumentCount() + (cc.getReturn() == Value.ILLEGAL ? 0 : 1); @@ -127,9 +124,7 @@ if (isRegister(value)) { return asRegister(value).asValue(value.getKind().getStackKind()); } else if (isStackSlot(value)) { - return StackSlot.get(value.getKind().getStackKind(), - asStackSlot(value).getRawOffset(), - asStackSlot(value).getRawAddFrameSize()); + return StackSlot.get(value.getKind().getStackKind(), asStackSlot(value).getRawOffset(), asStackSlot(value).getRawAddFrameSize()); } else { throw GraalInternalError.shouldNotReachHere(); } @@ -339,9 +334,7 @@ } @Override - public Variable emitConditionalMove(Value left, Value right, - Condition cond, boolean unorderedIsTrue, - Value trueValue, Value falseValue) { + public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) { Condition finalCondition = LIRValueUtil.isVariable(right) ? cond.mirror() : cond; @@ -352,16 +345,12 @@ case Int: case Long: case Object: - append(new CondMoveOp(result, finalCondition, - load(trueValue), loadNonConst(falseValue), - nextPredRegNum)); + append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue), nextPredRegNum)); nextPredRegNum++; break; case Float: case Double: - append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, - load(trueValue), load(falseValue), - nextPredRegNum)); + append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue), nextPredRegNum)); nextPredRegNum++; break; default: @@ -371,9 +360,9 @@ } /** - * This method emits the compare instruction, and may reorder the operands. - * It returns true if it did so. - * + * This method emits the compare instruction, and may reorder the operands. It returns true if + * it did so. + * * @param a the left operand of the comparison * @param b the right operand of the comparison * @return true if the left and right operands were switched, false otherwise @@ -413,7 +402,6 @@ return mirrored; } - @Override public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) { diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Mon Oct 07 23:16:00 2013 +0200 @@ -157,7 +157,7 @@ } public static Object test5Snippet() throws Exception { - return UnsafeLoadNode.load(wr, 0, useCompressedOops() ? 12 : 16, Kind.Object); + return UnsafeLoadNode.load(wr, useCompressedOops() ? 12 : 16, Kind.Object); } /** @@ -232,7 +232,7 @@ public static Object testUnsafeLoad(Object a, Object b, Object c) throws Exception { final int offset = (c == null ? 0 : ((Integer) c).intValue()); final long displacement = (b == null ? 0 : ((Long) b).longValue()); - return UnsafeLoadNode.load(a, offset, displacement, Kind.Object); + return UnsafeLoadNode.load(a, offset + displacement, Kind.Object); } private HotSpotInstalledCode getInstalledCode(String name) throws Exception { diff -r b7ce25d81ef3 -r 60bf1372d1a0 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 Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Mon Oct 07 23:16:00 2013 +0200 @@ -654,7 +654,7 @@ if (addReadBarrier(load)) { unsafeLoadSnippets.lower(load, tool); } else { - IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, load.accessKind(), load.displacement(), load.offset(), graph, 1); + LocationNode location = createLocation(load); ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp(), BarrierType.NONE, compressible)); // An unsafe read must not float outside its block otherwise // it may float above an explicit null check on its object. @@ -664,7 +664,7 @@ } } else if (n instanceof UnsafeStoreNode) { UnsafeStoreNode store = (UnsafeStoreNode) n; - IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, store.accessKind(), store.displacement(), store.offset(), graph, 1); + LocationNode location = createLocation(store); ValueNode object = store.object(); BarrierType barrierType = getUnsafeStoreBarrierType(store); WriteNode write = graph.add(new WriteNode(object, store.value(), location, barrierType, store.value().kind() == Kind.Object)); @@ -857,6 +857,43 @@ } } + private static LocationNode createLocation(UnsafeAccessNode access) { + ValueNode offset = access.offset(); + if (offset.isConstant()) { + long offsetValue = offset.asConstant().asLong(); + return ConstantLocationNode.create(access.getLocationIdentity(), access.accessKind(), offsetValue, access.graph()); + } + + long displacement = 0; + int indexScaling = 1; + if (offset instanceof IntegerAddNode) { + IntegerAddNode integerAddNode = (IntegerAddNode) offset; + if (integerAddNode.y() instanceof ConstantNode) { + displacement = integerAddNode.y().asConstant().asLong(); + offset = integerAddNode.x(); + } + } + + if (offset instanceof LeftShiftNode) { + LeftShiftNode leftShiftNode = (LeftShiftNode) offset; + if (leftShiftNode.y() instanceof ConstantNode) { + long shift = leftShiftNode.y().asConstant().asLong(); + if (shift >= 1 && shift <= 3) { + if (shift == 1) { + indexScaling = 2; + } else if (shift == 2) { + indexScaling = 4; + } else { + indexScaling = 8; + } + offset = leftShiftNode.x(); + } + } + } + + return IndexedLocationNode.create(access.getLocationIdentity(), access.accessKind(), displacement, offset, access.graph(), indexScaling); + } + private static boolean addReadBarrier(UnsafeLoadNode load) { if (useG1GC() && load.graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS && load.object().kind() == Kind.Object && load.accessKind() == Kind.Object && !ObjectStamp.isObjectAlwaysNull(load.object())) { diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java Mon Oct 07 23:16:00 2013 +0200 @@ -66,7 +66,7 @@ } private static void crypt(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset, boolean encrypt) { - Object kObject = UnsafeLoadNode.load(rcvr, 0, kOffset, Kind.Object); + Object kObject = UnsafeLoadNode.load(rcvr, kOffset, Kind.Object); Word kAddr = (Word) Word.fromObject(kObject).add(arrayBaseOffset(Kind.Byte)); Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset); Word outAddr = Word.unsigned(GetObjectAddressNode.get(out) + arrayBaseOffset(Kind.Byte) + outOffset); diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java Mon Oct 07 23:16:00 2013 +0200 @@ -62,7 +62,7 @@ @MethodSubstitution(isStatic = false) static void encrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { - Object embeddedCipher = UnsafeLoadNode.load(rcvr, 0, embeddedCipherOffset, Kind.Object); + Object embeddedCipher = UnsafeLoadNode.load(rcvr, embeddedCipherOffset, Kind.Object); if (getAESCryptClass().isInstance(embeddedCipher)) { crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, true); } else { @@ -72,7 +72,7 @@ @MethodSubstitution(isStatic = false) static void decrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { - Object embeddedCipher = UnsafeLoadNode.load(rcvr, 0, embeddedCipherOffset, Kind.Object); + Object embeddedCipher = UnsafeLoadNode.load(rcvr, embeddedCipherOffset, Kind.Object); if (in != out && getAESCryptClass().isInstance(embeddedCipher)) { crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, false); } else { @@ -81,8 +81,8 @@ } private static void crypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset, Object embeddedCipher, boolean encrypt) { - Object kObject = UnsafeLoadNode.load(embeddedCipher, 0, AESCryptSubstitutions.kOffset, Kind.Object); - Object rObject = UnsafeLoadNode.load(rcvr, 0, rOffset, Kind.Object); + Object kObject = UnsafeLoadNode.load(embeddedCipher, AESCryptSubstitutions.kOffset, Kind.Object); + Object rObject = UnsafeLoadNode.load(rcvr, rOffset, Kind.Object); Word kAddr = (Word) Word.fromObject(kObject).add(arrayBaseOffset(Kind.Byte)); Word rAddr = (Word) Word.fromObject(rObject).add(arrayBaseOffset(Kind.Byte)); Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset); diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Mon Oct 07 23:16:00 2013 +0200 @@ -481,7 +481,7 @@ public static Word loadWordFromObject(Object object, int offset) { assert offset != hubOffset() : "Use loadHubIntrinsic instead"; - return loadWordFromObjectIntrinsic(object, 0, offset, getWordKind()); + return loadWordFromObjectIntrinsic(object, offset, getWordKind()); } @NodeIntrinsic(value = ReadRegisterNode.class, setStampFromReturnType = true) @@ -489,8 +489,8 @@ @SuppressWarnings("unused") @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true) - private static Word loadWordFromObjectIntrinsic(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind wordKind) { - return Word.unsigned(unsafeReadWord(object, offset + displacement)); + private static Word loadWordFromObjectIntrinsic(Object object, long offset, @ConstantNodeParameter Kind wordKind) { + return Word.unsigned(unsafeReadWord(object, offset)); } @SuppressWarnings("unused") diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Mon Oct 07 23:16:00 2013 +0200 @@ -86,42 +86,42 @@ for (long i = 0; i < postLoopBytes; i += elementSize) { srcOffset -= elementSize; destOffset -= elementSize; - Object a = UnsafeLoadNode.load(src, arrayBaseOffset, srcOffset, baseKind); - UnsafeStoreNode.store(dest, arrayBaseOffset, destOffset, a, baseKind); + Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind); + UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind); } // Main-loop for (long i = 0; i < mainLoopBytes; i += VECTOR_SIZE) { srcOffset -= VECTOR_SIZE; destOffset -= VECTOR_SIZE; - Long a = UnsafeLoadNode.load(src, arrayBaseOffset, srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, arrayBaseOffset, destOffset, a.longValue(), VECTOR_KIND); + Long a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, VECTOR_KIND); + UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a.longValue(), VECTOR_KIND); } // Pre-loop for (long i = 0; i < preLoopBytes; i += elementSize) { srcOffset -= elementSize; destOffset -= elementSize; - Object a = UnsafeLoadNode.load(src, arrayBaseOffset, srcOffset, baseKind); - UnsafeStoreNode.store(dest, arrayBaseOffset, destOffset, a, baseKind); + Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind); + UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind); } } else { // Pre-loop for (long i = 0; i < preLoopBytes; i += elementSize) { - Object a = UnsafeLoadNode.load(src, arrayBaseOffset, srcOffset, baseKind); - UnsafeStoreNode.store(dest, arrayBaseOffset, destOffset, a, baseKind); + Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind); + UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind); srcOffset += elementSize; destOffset += elementSize; } // Main-loop for (long i = 0; i < mainLoopBytes; i += VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, arrayBaseOffset, srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, arrayBaseOffset, destOffset, a.longValue(), VECTOR_KIND); + Long a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, VECTOR_KIND); + UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a.longValue(), VECTOR_KIND); srcOffset += VECTOR_SIZE; destOffset += VECTOR_SIZE; } // Post-loop for (long i = 0; i < postLoopBytes; i += elementSize) { - Object a = UnsafeLoadNode.load(src, arrayBaseOffset, srcOffset, baseKind); - UnsafeStoreNode.store(dest, arrayBaseOffset, destOffset, a, baseKind); + Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind); + UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind); srcOffset += elementSize; destOffset += elementSize; } @@ -167,13 +167,13 @@ long destOffset = (long) destPos * arrayIndexScale(baseKind); if (src == dest && srcPos < destPos) { // bad aliased case for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, arrayBaseOffset, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, arrayBaseOffset, i + destOffset, a.longValue(), VECTOR_KIND); + Long a = UnsafeLoadNode.load(src, arrayBaseOffset + i + srcOffset, VECTOR_KIND); + UnsafeStoreNode.store(dest, arrayBaseOffset + i + destOffset, a.longValue(), VECTOR_KIND); } } else { for (long i = 0; i < byteLength; i += VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, arrayBaseOffset, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, arrayBaseOffset, i + destOffset, a.longValue(), VECTOR_KIND); + Long a = UnsafeLoadNode.load(src, arrayBaseOffset + i + srcOffset, VECTOR_KIND); + UnsafeStoreNode.store(dest, arrayBaseOffset + i + destOffset, a.longValue(), VECTOR_KIND); } } } @@ -187,8 +187,8 @@ long destOffset = (long) destPos * arrayIndexScale(baseKind); if (src == dest && srcPos < destPos) { // bad aliased case for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, arrayBaseOffset, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, arrayBaseOffset, i + destOffset, a.longValue(), VECTOR_KIND); + Long a = UnsafeLoadNode.load(src, arrayBaseOffset + i + srcOffset, VECTOR_KIND); + UnsafeStoreNode.store(dest, arrayBaseOffset + i + destOffset, a.longValue(), VECTOR_KIND); } } else { for (long i = 0; i < byteLength; i += VECTOR_SIZE) { @@ -197,8 +197,8 @@ * values to be copied atomically, but not long values. For example, on Intel 32-bit * this code is not atomic as long as the vector kind remains Kind.Long. */ - Long a = UnsafeLoadNode.load(src, arrayBaseOffset, i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, arrayBaseOffset, i + destOffset, a.longValue(), VECTOR_KIND); + Long a = UnsafeLoadNode.load(src, arrayBaseOffset + i + srcOffset, VECTOR_KIND); + UnsafeStoreNode.store(dest, arrayBaseOffset + i + destOffset, a.longValue(), VECTOR_KIND); } } } @@ -213,13 +213,13 @@ if (src == dest && srcPos < destPos) { // bad aliased case long start = (long) (length - 1) * scale; for (long i = start; i >= 0; i -= scale) { - Object a = UnsafeLoadNode.load(src, arrayBaseOffset, i + (long) srcPos * scale, Kind.Object); + Object a = UnsafeLoadNode.load(src, arrayBaseOffset + i + (long) srcPos * scale, Kind.Object); DirectObjectStoreNode.storeObject(dest, arrayBaseOffset, i + (long) destPos * scale, a); } } else { long end = (long) length * scale; for (long i = 0; i < end; i += scale) { - Object a = UnsafeLoadNode.load(src, arrayBaseOffset, i + (long) srcPos * scale, Kind.Object); + Object a = UnsafeLoadNode.load(src, arrayBaseOffset + i + (long) srcPos * scale, Kind.Object); DirectObjectStoreNode.storeObject(dest, arrayBaseOffset, i + (long) destPos * scale, a); } } diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java Mon Oct 07 23:16:00 2013 +0200 @@ -39,9 +39,8 @@ public class UnsafeLoadSnippets implements Snippets { @Snippet - public static Object lowerUnsafeLoad(Object object, long offset, int disp) { + public static Object lowerUnsafeLoad(Object object, long displacement) { Object fixedObject = FixedValueAnchorNode.getObject(object); - long displacement = disp + offset; if (object instanceof java.lang.ref.Reference && referentOffset() == displacement) { return Word.fromObject(fixedObject).readObject((int) displacement, BarrierType.PRECISE, true); } else { @@ -61,7 +60,6 @@ Arguments args = new Arguments(unsafeLoad, load.graph().getGuardsStage()); args.add("object", load.object()); args.add("offset", load.offset()); - args.add("disp", load.displacement()); template(args).instantiate(runtime, load, DEFAULT_REPLACER, args); } } diff -r b7ce25d81ef3 -r 60bf1372d1a0 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 Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java Mon Oct 07 23:16:00 2013 +0200 @@ -58,7 +58,8 @@ public static class ReturnNoValOp extends PTXLIRInstruction { - public ReturnNoValOp() { } + public ReturnNoValOp() { + } @Override public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { @@ -106,9 +107,7 @@ private final Condition condition; private final int predicate; - public CondMoveOp(Variable result, Condition condition, - Variable trueValue, Value falseValue, - int predicateRegister) { + public CondMoveOp(Variable result, Condition condition, Variable trueValue, Value falseValue, int predicateRegister) { this.result = result; this.condition = condition; this.trueValue = trueValue; @@ -118,8 +117,7 @@ @Override public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { - cmove(tasm, masm, result, false, condition, false, - trueValue, falseValue, predicate); + cmove(tasm, masm, result, false, condition, false, trueValue, falseValue, predicate); } } @@ -132,10 +130,7 @@ private final boolean unorderedIsTrue; private final int predicate; - public FloatCondMoveOp(Variable result, Condition condition, - boolean unorderedIsTrue, - Variable trueValue, Variable falseValue, - int predicateRegister) { + public FloatCondMoveOp(Variable result, Condition condition, boolean unorderedIsTrue, Variable trueValue, Variable falseValue, int predicateRegister) { this.result = result; this.condition = condition; this.unorderedIsTrue = unorderedIsTrue; @@ -146,16 +141,12 @@ @Override public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { - cmove(tasm, masm, result, true, condition, unorderedIsTrue, - trueValue, falseValue, predicate); + cmove(tasm, masm, result, true, condition, unorderedIsTrue, trueValue, falseValue, predicate); } } - private static void cmove(TargetMethodAssembler tasm, PTXAssembler asm, - Value result, boolean isFloat, Condition condition, - boolean unorderedIsTrue, - Value trueValue, Value falseValue, - int predicateRegister) { + private static void cmove(TargetMethodAssembler tasm, PTXAssembler asm, Value result, boolean isFloat, Condition condition, boolean unorderedIsTrue, Value trueValue, Value falseValue, + int predicateRegister) { // check that we don't overwrite an input operand before it is used. assert !result.equals(trueValue); @@ -186,12 +177,9 @@ } } - private static void cmove(PTXAssembler asm, - Value result, Value other, - int predicateRegister) { + private static void cmove(PTXAssembler asm, Value result, Value other, int predicateRegister) { if (isVariable(other)) { - assert !asVariable(other).equals(asVariable(result)) : - "other already overwritten by previous move"; + assert !asVariable(other).equals(asVariable(result)) : "other already overwritten by previous move"; switch (other.getKind()) { case Int: @@ -218,9 +206,7 @@ // Number of predicate register that would be set by this instruction. protected int predRegNum; - public SequentialSwitchOp(Constant[] keyConstants, - LabelRef[] keyTargets, LabelRef defaultTarget, - Value key, Value scratch, int predReg) { + public SequentialSwitchOp(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key, Value scratch, int predReg) { assert keyConstants.length == keyTargets.length; this.keyConstants = keyConstants; this.keyTargets = keyTargets; @@ -279,9 +265,7 @@ // Number of predicate register that would be set by this instruction. protected int predRegNum; - public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, - final LabelRef[] targets, - Variable index, Variable scratch, int predReg) { + public TableSwitchOp(final int lowKey, final LabelRef defaultTarget, final LabelRef[] targets, Variable index, Variable scratch, int predReg) { this.lowKey = lowKey; this.defaultTarget = defaultTarget; this.targets = targets; @@ -292,15 +276,12 @@ @Override public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { - tableswitch(tasm, masm, lowKey, defaultTarget, targets, - index, scratch, predRegNum); + tableswitch(tasm, masm, lowKey, defaultTarget, targets, index, scratch, predRegNum); } } @SuppressWarnings("unused") - private static void tableswitch(TargetMethodAssembler tasm, PTXAssembler masm, int lowKey, - LabelRef defaultTarget, LabelRef[] targets, - Value value, Value scratch, int predNum) { + private static void tableswitch(TargetMethodAssembler tasm, PTXAssembler masm, int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value value, Value scratch, int predNum) { Buffer buf = masm.codeBuffer; // Compare index against jump table bounds @@ -322,7 +303,6 @@ // address of jump table int tablePos = buf.position(); - JumpTable jt = new JumpTable(tablePos, lowKey, highKey, 4); String name = "jumptable" + jt.position; diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXTestOp.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXTestOp.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXTestOp.java Mon Oct 07 23:16:00 2013 +0200 @@ -24,12 +24,10 @@ import static com.oracle.graal.asm.ptx.PTXAssembler.BooleanOperator.*; import static com.oracle.graal.asm.ptx.PTXAssembler.*; -import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.ptx.*; -import com.oracle.graal.graph.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.calc.Condition; @@ -47,20 +45,16 @@ @Override public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { - emit(tasm, masm, x, y, predicate); + emit(masm, x, y, predicate); } @Override protected void verify() { super.verify(); - assert (x.getKind() == Kind.Int && - y.getKind().getStackKind() == Kind.Int) || - (x.getKind() == Kind.Long && y.getKind() == Kind.Long) : - x + " " + y; + assert (x.getKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) || (x.getKind() == Kind.Long && y.getKind() == Kind.Long) : x + " " + y; } - public static void emit(TargetMethodAssembler tasm, PTXAssembler masm, - Value x, Value y, int predicate) { + public static void emit(PTXAssembler masm, Value x, Value y, int predicate) { /* * This is not yet quite right - as the result for the equivalent in * ControlPTXText.testIntegerTestBranch2I is wrong. diff -r b7ce25d81ef3 -r 60bf1372d1a0 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 Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Mon Oct 07 23:16:00 2013 +0200 @@ -43,18 +43,6 @@ super(object, location, stamp, guard, barrierType, compressible); } - public ReadNode(ValueNode object, int displacement, LocationIdentity locationIdentity, Kind kind) { - super(object, ConstantLocationNode.create(locationIdentity, kind, displacement, object.graph()), StampFactory.forKind(kind)); - } - - private ReadNode(ValueNode object, ValueNode location, ValueNode guard) { - /* - * Used by node intrinsics. Since the initial value for location is a parameter, i.e., a - * LocalNode, the constructor cannot use the declared type LocationNode. - */ - super(object, location, StampFactory.forNodeIntrinsic(), (GuardingNode) guard, BarrierType.NONE, false); - } - @Override public void generate(LIRGeneratorTool gen) { Value address = location().generateAddress(gen, gen.operand(object())); diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java Mon Oct 07 23:16:00 2013 +0200 @@ -32,26 +32,26 @@ @Input private ValueNode object; @Input private ValueNode offset; - private final int displacement; private final Kind accessKind; + private final LocationIdentity locationIdentity; - public UnsafeAccessNode(Stamp stamp, ValueNode object, int displacement, ValueNode offset, Kind accessKind) { + public UnsafeAccessNode(Stamp stamp, ValueNode object, ValueNode offset, Kind accessKind, LocationIdentity locationIdentity) { super(stamp); assert accessKind != null; this.object = object; - this.displacement = displacement; this.offset = offset; this.accessKind = accessKind; + this.locationIdentity = locationIdentity; + } + + public LocationIdentity getLocationIdentity() { + return locationIdentity; } public ValueNode object() { return object; } - public int displacement() { - return displacement; - } - public ValueNode offset() { return offset; } @@ -62,13 +62,13 @@ @Override public Node canonical(CanonicalizerTool tool) { - if (offset().isConstant()) { + if (this.getLocationIdentity() == LocationIdentity.ANY_LOCATION && offset().isConstant()) { long constantOffset = offset().asConstant().asLong(); // Try to canonicalize to a field access. ResolvedJavaType receiverType = ObjectStamp.typeOrNull(object()); if (receiverType != null) { - ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement() + constantOffset); + ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(constantOffset); // No need for checking that the receiver is non-null. The field access includes // the null check and if a field is found, the offset is so small that this is // never a valid access of an arbitrary address. @@ -76,18 +76,9 @@ return cloneAsFieldAccess(field); } } - - if (constantOffset != 0 && Integer.MAX_VALUE - displacement() >= constantOffset) { - int intDisplacement = (int) (constantOffset + displacement()); - if (constantOffset == intDisplacement) { - return cloneWithZeroOffset(intDisplacement); - } - } } return this; } protected abstract ValueNode cloneAsFieldAccess(ResolvedJavaField field); - - protected abstract ValueNode cloneWithZeroOffset(int intDisplacement); } diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Mon Oct 07 23:16:00 2013 +0200 @@ -36,16 +36,12 @@ */ public class UnsafeLoadNode extends UnsafeAccessNode implements Lowerable, Virtualizable { - public UnsafeLoadNode(ValueNode object, int displacement, ValueNode offset, boolean nonNull) { - this(nonNull ? StampFactory.objectNonNull() : StampFactory.object(), object, displacement, offset, Kind.Object); + public UnsafeLoadNode(ValueNode object, ValueNode offset, Kind accessKind) { + this(object, offset, accessKind, LocationIdentity.ANY_LOCATION); } - public UnsafeLoadNode(ValueNode object, int displacement, ValueNode offset, Kind accessKind) { - this(StampFactory.forKind(accessKind.getStackKind()), object, displacement, offset, accessKind); - } - - public UnsafeLoadNode(Stamp stamp, ValueNode object, int displacement, ValueNode offset, Kind accessKind) { - super(stamp, object, displacement, offset, accessKind); + public UnsafeLoadNode(ValueNode object, ValueNode offset, Kind accessKind, LocationIdentity locationIdentity) { + super(StampFactory.forKind(accessKind.getStackKind()), object, offset, accessKind, locationIdentity); } @Override @@ -57,9 +53,9 @@ public void virtualize(VirtualizerTool tool) { State state = tool.getObjectState(object()); if (state != null && state.getState() == EscapeState.Virtual) { - ValueNode indexValue = tool.getReplacedValue(offset()); - if (indexValue.isConstant()) { - long offset = indexValue.asConstant().asLong() + displacement(); + ValueNode offsetValue = tool.getReplacedValue(offset()); + if (offsetValue.isConstant()) { + long offset = offsetValue.asConstant().asLong(); int entryIndex = state.getVirtualObject().entryIndexForOffset(offset); if (entryIndex != -1 && state.getVirtualObject().entryKind(entryIndex) == accessKind()) { tool.replaceWith(state.getEntry(entryIndex)); @@ -73,39 +69,34 @@ return this.graph().add(new LoadFieldNode(object(), field)); } - @Override - protected ValueNode cloneWithZeroOffset(int intDisplacement) { - return graph().add(new UnsafeLoadNode(this.stamp(), object(), intDisplacement, graph().unique(ConstantNode.forInt(0, graph())), accessKind())); - } - @SuppressWarnings("unchecked") @NodeIntrinsic - public static T load(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind kind) { + public static T load(Object object, long offset, @ConstantNodeParameter Kind kind) { if (kind == Kind.Boolean) { - return (T) (Boolean) unsafe.getBoolean(object, displacement + offset); + return (T) (Boolean) unsafe.getBoolean(object, offset); } if (kind == Kind.Byte) { - return (T) (Byte) unsafe.getByte(object, displacement + offset); + return (T) (Byte) unsafe.getByte(object, offset); } if (kind == Kind.Short) { - return (T) (Short) unsafe.getShort(object, displacement + offset); + return (T) (Short) unsafe.getShort(object, offset); } if (kind == Kind.Char) { - return (T) (Character) unsafe.getChar(object, displacement + offset); + return (T) (Character) unsafe.getChar(object, offset); } if (kind == Kind.Int) { - return (T) (Integer) unsafe.getInt(object, displacement + offset); + return (T) (Integer) unsafe.getInt(object, offset); } if (kind == Kind.Float) { - return (T) (Float) unsafe.getFloat(object, displacement + offset); + return (T) (Float) unsafe.getFloat(object, offset); } if (kind == Kind.Long) { - return (T) (Long) unsafe.getLong(object, displacement + offset); + return (T) (Long) unsafe.getLong(object, offset); } if (kind == Kind.Double) { - return (T) (Double) unsafe.getDouble(object, displacement + offset); + return (T) (Double) unsafe.getDouble(object, offset); } assert kind == Kind.Object; - return (T) unsafe.getObject(object, displacement + offset); + return (T) unsafe.getObject(object, offset); } } diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Mon Oct 07 23:16:00 2013 +0200 @@ -39,12 +39,12 @@ @Input private ValueNode value; @Input(notDataflow = true) private FrameState stateAfter; - public UnsafeStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value, Kind accessKind) { - this(StampFactory.forVoid(), object, displacement, offset, value, accessKind); + public UnsafeStoreNode(ValueNode object, ValueNode offset, ValueNode value, Kind accessKind) { + this(object, offset, value, accessKind, LocationIdentity.ANY_LOCATION); } - public UnsafeStoreNode(Stamp stamp, ValueNode object, int displacement, ValueNode offset, ValueNode value, Kind accessKind) { - super(stamp, object, displacement, offset, accessKind); + public UnsafeStoreNode(ValueNode object, ValueNode offset, ValueNode value, Kind accessKind, LocationIdentity locationIdentity) { + super(StampFactory.forVoid(), object, offset, accessKind, locationIdentity); assert accessKind != Kind.Void && accessKind != Kind.Illegal; this.value = value; } @@ -73,17 +73,12 @@ } @Override - public LocationIdentity getLocationIdentity() { - return LocationIdentity.ANY_LOCATION; - } - - @Override public void virtualize(VirtualizerTool tool) { State state = tool.getObjectState(object()); if (state != null && state.getState() == EscapeState.Virtual) { ValueNode indexValue = tool.getReplacedValue(offset()); if (indexValue.isConstant()) { - long offset = indexValue.asConstant().asLong() + displacement(); + long offset = indexValue.asConstant().asLong(); int entryIndex = state.getVirtualObject().entryIndexForOffset(offset); if (entryIndex != -1 && state.getVirtualObject().entryKind(entryIndex) == accessKind()) { tool.setVirtualEntry(state, entryIndex, value()); @@ -100,13 +95,6 @@ return storeFieldNode; } - @Override - protected ValueNode cloneWithZeroOffset(int intDisplacement) { - UnsafeStoreNode unsafeStoreNode = graph().add(new UnsafeStoreNode(stamp(), object(), intDisplacement, ConstantNode.forInt(0, graph()), value(), accessKind())); - unsafeStoreNode.setStateAfter(stateAfter()); - return unsafeStoreNode; - } - public FrameState getState() { return stateAfter; } @@ -115,55 +103,55 @@ @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, @ConstantNodeParameter int displacement, long offset, Object value, @ConstantNodeParameter Kind kind) { - unsafe.putObject(object, offset + displacement, value); + public static void store(Object object, long offset, Object value, @ConstantNodeParameter Kind kind) { + unsafe.putObject(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, @ConstantNodeParameter int displacement, long offset, boolean value, @ConstantNodeParameter Kind kind) { - unsafe.putBoolean(object, offset + displacement, value); + public static void store(Object object, long offset, boolean value, @ConstantNodeParameter Kind kind) { + unsafe.putBoolean(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, @ConstantNodeParameter int displacement, long offset, byte value, @ConstantNodeParameter Kind kind) { - unsafe.putByte(object, offset + displacement, value); + public static void store(Object object, long offset, byte value, @ConstantNodeParameter Kind kind) { + unsafe.putByte(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, @ConstantNodeParameter int displacement, long offset, char value, @ConstantNodeParameter Kind kind) { - unsafe.putChar(object, offset + displacement, value); + public static void store(Object object, long offset, char value, @ConstantNodeParameter Kind kind) { + unsafe.putChar(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, @ConstantNodeParameter int displacement, long offset, double value, @ConstantNodeParameter Kind kind) { - unsafe.putDouble(object, offset + displacement, value); + public static void store(Object object, long offset, double value, @ConstantNodeParameter Kind kind) { + unsafe.putDouble(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, @ConstantNodeParameter int displacement, long offset, float value, @ConstantNodeParameter Kind kind) { - unsafe.putFloat(object, offset + displacement, value); + public static void store(Object object, long offset, float value, @ConstantNodeParameter Kind kind) { + unsafe.putFloat(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, @ConstantNodeParameter int displacement, long offset, int value, @ConstantNodeParameter Kind kind) { - unsafe.putInt(object, offset + displacement, value); + public static void store(Object object, long offset, int value, @ConstantNodeParameter Kind kind) { + unsafe.putInt(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, @ConstantNodeParameter int displacement, long offset, long value, @ConstantNodeParameter Kind kind) { - unsafe.putLong(object, offset + displacement, value); + public static void store(Object object, long offset, long value, @ConstantNodeParameter Kind kind) { + unsafe.putLong(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, @ConstantNodeParameter int displacement, long offset, short value, @ConstantNodeParameter Kind kind) { - unsafe.putShort(object, offset + displacement, value); + public static void store(Object object, long offset, short value, @ConstantNodeParameter Kind kind) { + unsafe.putShort(object, offset, value); } } diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java Mon Oct 07 23:16:00 2013 +0200 @@ -64,22 +64,22 @@ @MethodSubstitution private static Node getNode(Node node, long offset) { - return PiNode.piCast(UnsafeLoadNode.load(node, 0, offset, Kind.Object), Node.class, false, false); + return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object), Node.class, false, false); } @MethodSubstitution private static NodeList getNodeList(Node node, long offset) { - return PiNode.piCast(UnsafeLoadNode.load(node, 0, offset, Kind.Object), NodeList.class, false, false); + return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object), NodeList.class, false, false); } @MethodSubstitution private static void putNode(Node node, long offset, Node value) { - UnsafeStoreNode.store(node, 0, offset, value, Kind.Object); + UnsafeStoreNode.store(node, offset, value, Kind.Object); } @MethodSubstitution private static void putNodeList(Node node, long offset, NodeList value) { - UnsafeStoreNode.store(node, 0, offset, value, Kind.Object); + UnsafeStoreNode.store(node, offset, value, Kind.Object); } } diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsafeSubstitutions.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsafeSubstitutions.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsafeSubstitutions.java Mon Oct 07 23:16:00 2013 +0200 @@ -53,7 +53,7 @@ @MethodSubstitution(isStatic = false) public static Object getObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { - return UnsafeLoadNode.load(o, 0, offset, Kind.Object); + return UnsafeLoadNode.load(o, offset, Kind.Object); } @MethodSubstitution(isStatic = false) @@ -66,7 +66,7 @@ @MethodSubstitution(isStatic = false) public static void putObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, Object x) { - UnsafeStoreNode.store(o, 0, offset, x, Kind.Object); + UnsafeStoreNode.store(o, offset, x, Kind.Object); } @MethodSubstitution(isStatic = false) @@ -85,7 +85,7 @@ @MethodSubstitution(isStatic = false) public static int getInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { - Integer value = UnsafeLoadNode.load(o, 0, offset, Kind.Int); + Integer value = UnsafeLoadNode.load(o, offset, Kind.Int); return value; } @@ -99,7 +99,7 @@ @MethodSubstitution(isStatic = false) public static void putInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, int x) { - UnsafeStoreNode.store(o, 0, offset, x, Kind.Int); + UnsafeStoreNode.store(o, offset, x, Kind.Int); } @MethodSubstitution(isStatic = false) @@ -119,7 +119,7 @@ @MethodSubstitution(isStatic = false) public static boolean getBoolean(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Boolean result = UnsafeLoadNode.load(o, 0, offset, Kind.Boolean); + Boolean result = UnsafeLoadNode.load(o, offset, Kind.Boolean); return result; } @@ -133,7 +133,7 @@ @MethodSubstitution(isStatic = false) public static void putBoolean(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, boolean x) { - UnsafeStoreNode.store(o, 0, offset, x, Kind.Boolean); + UnsafeStoreNode.store(o, offset, x, Kind.Boolean); } @MethodSubstitution(isStatic = false) @@ -146,7 +146,7 @@ @MethodSubstitution(isStatic = false) public static byte getByte(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Byte result = UnsafeLoadNode.load(o, 0, offset, Kind.Byte); + Byte result = UnsafeLoadNode.load(o, offset, Kind.Byte); return result; } @@ -160,7 +160,7 @@ @MethodSubstitution(isStatic = false) public static void putByte(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, byte x) { - UnsafeStoreNode.store(o, 0, offset, x, Kind.Byte); + UnsafeStoreNode.store(o, offset, x, Kind.Byte); } @MethodSubstitution(isStatic = false) @@ -173,7 +173,7 @@ @MethodSubstitution(isStatic = false) public static short getShort(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Short result = UnsafeLoadNode.load(o, 0, offset, Kind.Short); + Short result = UnsafeLoadNode.load(o, offset, Kind.Short); return result; } @@ -187,7 +187,7 @@ @MethodSubstitution(isStatic = false) public static void putShort(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, short x) { - UnsafeStoreNode.store(o, 0, offset, x, Kind.Short); + UnsafeStoreNode.store(o, offset, x, Kind.Short); } @MethodSubstitution(isStatic = false) @@ -200,7 +200,7 @@ @MethodSubstitution(isStatic = false) public static char getChar(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Character result = UnsafeLoadNode.load(o, 0, offset, Kind.Char); + Character result = UnsafeLoadNode.load(o, offset, Kind.Char); return result; } @@ -214,7 +214,7 @@ @MethodSubstitution(isStatic = false) public static void putChar(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, char x) { - UnsafeStoreNode.store(o, 0, offset, x, Kind.Char); + UnsafeStoreNode.store(o, offset, x, Kind.Char); } @MethodSubstitution(isStatic = false) @@ -227,7 +227,7 @@ @MethodSubstitution(isStatic = false) public static long getLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Long result = UnsafeLoadNode.load(o, 0, offset, Kind.Long); + Long result = UnsafeLoadNode.load(o, offset, Kind.Long); return result; } @@ -241,7 +241,7 @@ @MethodSubstitution(isStatic = false) public static void putLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, long x) { - UnsafeStoreNode.store(o, 0, offset, x, Kind.Long); + UnsafeStoreNode.store(o, offset, x, Kind.Long); } @MethodSubstitution(isStatic = false) @@ -261,7 +261,7 @@ @MethodSubstitution(isStatic = false) public static float getFloat(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Float result = UnsafeLoadNode.load(o, 0, offset, Kind.Float); + Float result = UnsafeLoadNode.load(o, offset, Kind.Float); return result; } @@ -275,7 +275,7 @@ @MethodSubstitution(isStatic = false) public static void putFloat(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, float x) { - UnsafeStoreNode.store(o, 0, offset, x, Kind.Float); + UnsafeStoreNode.store(o, offset, x, Kind.Float); } @MethodSubstitution(isStatic = false) @@ -288,7 +288,7 @@ @MethodSubstitution(isStatic = false) public static double getDouble(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Double result = UnsafeLoadNode.load(o, 0, offset, Kind.Double); + Double result = UnsafeLoadNode.load(o, offset, Kind.Double); return result; } @@ -302,7 +302,7 @@ @MethodSubstitution(isStatic = false) public static void putDouble(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, double x) { - UnsafeStoreNode.store(o, 0, offset, x, Kind.Double); + UnsafeStoreNode.store(o, offset, x, Kind.Double); } @MethodSubstitution(isStatic = false) diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Mon Oct 07 23:16:00 2013 +0200 @@ -173,6 +173,8 @@ // Convert deopt to guards. new ConvertDeoptimizeToGuardPhase().apply(graph); + new EarlyReadEliminationPhase(canonicalizerPhase).apply(graph, context); + if (!inliningProgress) { break; } diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java Mon Oct 07 23:16:00 2013 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; @@ -84,8 +85,9 @@ ValueNode slotIndex = getSlotOffset(1, tool.getRuntime()); loadNode = graph().add(new LoadIndexedNode(loadFieldNode, slotIndex, Kind.Object)); } else { - ValueNode slotOffset = getSlotOffset(Unsafe.ARRAY_LONG_INDEX_SCALE, tool.getRuntime()); - loadNode = graph().add(new UnsafeLoadNode(loadFieldNode, Unsafe.ARRAY_LONG_BASE_OFFSET, slotOffset, getSlotKind())); + ValueNode slotOffset = graph().unique( + new IntegerAddNode(Kind.Long, getSlotOffset(Unsafe.ARRAY_LONG_INDEX_SCALE, tool.getRuntime()), ConstantNode.forLong(Unsafe.ARRAY_LONG_BASE_OFFSET, graph()))); + loadNode = graph().add(new UnsafeLoadNode(loadFieldNode, slotOffset, getSlotKind())); } structuredGraph.replaceFixedWithFixed(this, loadNode); loadFieldNode.lower(tool); diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java Mon Oct 07 23:16:00 2013 +0200 @@ -0,0 +1,68 @@ +/* + * 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.truffle.nodes.typesystem; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.truffle.nodes.asserts.*; +import com.oracle.truffle.api.*; + +/** + * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class, boolean)}. + */ +public class CustomizedUnsafeLoadMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { + + private static final int ARGUMENT_COUNT = 4; + private static final int OBJECT_ARGUMENT_INDEX = 0; + private static final int OFFSET_ARGUMENT_INDEX = 1; + private static final int CONDITION_ARGUMENT_INDEX = 2; + private static final int LOCATION_ARGUMENT_INDEX = 3; + + public CustomizedUnsafeLoadMacroNode(Invoke invoke) { + super(invoke, "The location argument could not be resolved to a constant."); + assert arguments.size() == ARGUMENT_COUNT; + } + + @SuppressWarnings("unused") + @Override + public Node canonical(CanonicalizerTool tool) { + ValueNode locationArgument = arguments.get(LOCATION_ARGUMENT_INDEX); + if (locationArgument.isConstant()) { + ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX); + ValueNode offsetArgument = arguments.get(OFFSET_ARGUMENT_INDEX); + ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX); + Object locationIdentityObject = locationArgument.asConstant().asObject(); + LocationIdentity locationIdentity; + if (locationIdentityObject == null) { + locationIdentity = LocationIdentity.ANY_LOCATION; + } else { + locationIdentity = ObjectLocationIdentity.create(locationIdentityObject); + } + return graph().add(new UnsafeLoadNode(objectArgument, offsetArgument, this.stamp().kind(), locationIdentity)); + } + return this; + } +} diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadNode.java Mon Oct 07 14:47:18 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2012, 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.truffle.nodes.typesystem; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.spi.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; - -public final class CustomizedUnsafeLoadNode extends UnsafeLoadNode { - - @Input private ValueNode condition; - @Input private ValueNode locationIdentity; - - public CustomizedUnsafeLoadNode(ValueNode object, ValueNode offset, Kind accessKind, ValueNode condition, ValueNode locationIdentity) { - super(object, 0, offset, accessKind); - this.condition = condition; - this.locationIdentity = locationIdentity; - } - - public ValueNode getCondition() { - return condition; - } - - public ValueNode getLocationIdentity() { - return locationIdentity; - } - - @Override - public Node canonical(CanonicalizerTool tool) { - return this; - } - - @Override - public void virtualize(VirtualizerTool tool) { - super.virtualize(tool); - } - - @SuppressWarnings("unused") - public static T load(Object object, long offset, @ConstantNodeParameter Kind kind, boolean condition, Object locationIdentity) { - return UnsafeLoadNode.load(object, 0, offset, kind); - } -} diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java Mon Oct 07 23:16:00 2013 +0200 @@ -0,0 +1,70 @@ +/* + * 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.truffle.nodes.typesystem; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.truffle.nodes.asserts.*; +import com.oracle.truffle.api.*; + +/** + * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class, boolean)}. + */ +public class CustomizedUnsafeStoreMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { + + private static final int ARGUMENT_COUNT = 4; + private static final int OBJECT_ARGUMENT_INDEX = 0; + private static final int OFFSET_ARGUMENT_INDEX = 1; + private static final int VALUE_ARGUMENT_INDEX = 2; + private static final int LOCATION_ARGUMENT_INDEX = 3; + + public CustomizedUnsafeStoreMacroNode(Invoke invoke) { + super(invoke, "The location argument could not be resolved to a constant."); + assert arguments.size() == ARGUMENT_COUNT; + } + + @Override + public Node canonical(CanonicalizerTool tool) { + ValueNode locationArgument = arguments.get(LOCATION_ARGUMENT_INDEX); + if (locationArgument.isConstant()) { + ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX); + ValueNode offsetArgument = arguments.get(OFFSET_ARGUMENT_INDEX); + ValueNode valueArgument = arguments.get(VALUE_ARGUMENT_INDEX); + Object locationIdentityObject = locationArgument.asConstant().asObject(); + LocationIdentity locationIdentity; + if (locationIdentityObject == null) { + locationIdentity = LocationIdentity.ANY_LOCATION; + } else { + locationIdentity = ObjectLocationIdentity.create(locationIdentityObject); + } + + UnsafeStoreNode unsafeStoreNode = graph().add(new UnsafeStoreNode(objectArgument, offsetArgument, valueArgument, valueArgument.kind(), locationIdentity)); + unsafeStoreNode.setStateAfter(this.stateAfter()); + return unsafeStoreNode; + } + return this; + } +} diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreNode.java Mon Oct 07 14:47:18 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2012, 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.truffle.nodes.typesystem; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.spi.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; - -public final class CustomizedUnsafeStoreNode extends UnsafeStoreNode { - - @Input private ValueNode customLocationIdentity; - - public CustomizedUnsafeStoreNode(ValueNode object, ValueNode offset, ValueNode value, Kind accessKind, ValueNode customLocationIdentity) { - super(object, 0, offset, value, accessKind); - this.customLocationIdentity = customLocationIdentity; - } - - public ValueNode getCustomLocationIdentity() { - return customLocationIdentity; - } - - @Override - public Node canonical(CanonicalizerTool tool) { - return this; - } - - @Override - public void virtualize(VirtualizerTool tool) { - super.virtualize(tool); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object object, long offset, Object value, @ConstantNodeParameter Kind kind, Object customLocationIdentity) { - UnsafeStoreNode.store(object, 0, offset, value, kind); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object object, long offset, boolean value, @ConstantNodeParameter Kind kind, Object customLocationIdentity) { - UnsafeStoreNode.store(object, 0, offset, value, kind); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object object, long offset, byte value, @ConstantNodeParameter Kind kind, Object customLocationIdentity) { - UnsafeStoreNode.store(object, 0, offset, value, kind); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object object, long offset, char value, @ConstantNodeParameter Kind kind, Object customLocationIdentity) { - UnsafeStoreNode.store(object, 0, offset, value, kind); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object object, long offset, double value, @ConstantNodeParameter Kind kind, Object customLocationIdentity) { - UnsafeStoreNode.store(object, 0, offset, value, kind); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object object, long offset, float value, @ConstantNodeParameter Kind kind, Object customLocationIdentity) { - UnsafeStoreNode.store(object, 0, offset, value, kind); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object object, long offset, int value, @ConstantNodeParameter Kind kind, Object customLocationIdentity) { - UnsafeStoreNode.store(object, 0, offset, value, kind); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object object, long offset, long value, @ConstantNodeParameter Kind kind, Object customLocationIdentity) { - UnsafeStoreNode.store(object, 0, offset, value, kind); - } - - @SuppressWarnings("unused") - @NodeIntrinsic - public static void store(Object object, long offset, short value, @ConstantNodeParameter Kind kind, Object customLocationIdentity) { - UnsafeStoreNode.store(object, 0, offset, value, kind); - } -} diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java Mon Oct 07 23:16:00 2013 +0200 @@ -66,78 +66,48 @@ @MacroSubstitution(macro = UnsafeTypeCastMacroNode.class, isStatic = true) public static native Object unsafeCast(Object value, Class clazz, boolean condition); - @MethodSubstitution - public static boolean unsafeGetBoolean(Object receiver, long offset, boolean condition, Object locationIdentity) { - return CustomizedUnsafeLoadNode.load(receiver, offset, Kind.Boolean, condition, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native boolean unsafeGetBoolean(Object receiver, long offset, boolean condition, Object locationIdentity); - @MethodSubstitution - public static byte unsafeGetByte(Object receiver, long offset, boolean condition, Object locationIdentity) { - return CustomizedUnsafeLoadNode.load(receiver, offset, Kind.Byte, condition, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native byte unsafeGetByte(Object receiver, long offset, boolean condition, Object locationIdentity); - @MethodSubstitution - public static short unsafeGetShort(Object receiver, long offset, boolean condition, Object locationIdentity) { - return CustomizedUnsafeLoadNode.load(receiver, offset, Kind.Short, condition, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native short unsafeGetShort(Object receiver, long offset, boolean condition, Object locationIdentity); - @MethodSubstitution - public static int unsafeGetInt(Object receiver, long offset, boolean condition, Object locationIdentity) { - return CustomizedUnsafeLoadNode.load(receiver, offset, Kind.Int, condition, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native int unsafeGetInt(Object receiver, long offset, boolean condition, Object locationIdentity); - @MethodSubstitution - public static float unsafeGetFloat(Object receiver, long offset, boolean condition, Object locationIdentity) { - return CustomizedUnsafeLoadNode.load(receiver, offset, Kind.Float, condition, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native float unsafeGetFloat(Object receiver, long offset, boolean condition, Object locationIdentity); - @MethodSubstitution - public static double unsafeGetDouble(Object receiver, long offset, boolean condition, Object locationIdentity) { - return CustomizedUnsafeLoadNode.load(receiver, offset, Kind.Double, condition, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native double unsafeGetDouble(Object receiver, long offset, boolean condition, Object locationIdentity); - @MethodSubstitution - public static Object unsafeGetObject(Object receiver, long offset, boolean condition, Object locationIdentity) { - return CustomizedUnsafeLoadNode.load(receiver, offset, Kind.Object, condition, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native Object unsafeGetObject(Object receiver, long offset, boolean condition, Object locationIdentity); - @MethodSubstitution - public static void unsafePutBoolean(Object receiver, long offset, boolean value, Object locationIdentity) { - CustomizedUnsafeStoreNode.store(receiver, offset, value, Kind.Boolean, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutBoolean(Object receiver, long offset, boolean value, Object locationIdentity); - @MethodSubstitution - public static void unsafePutByte(Object receiver, long offset, byte value, Object locationIdentity) { - CustomizedUnsafeStoreNode.store(receiver, offset, value, Kind.Byte, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutByte(Object receiver, long offset, byte value, Object locationIdentity); - @MethodSubstitution - public static void unsafePutShort(Object receiver, long offset, short value, Object locationIdentity) { - CustomizedUnsafeStoreNode.store(receiver, offset, value, Kind.Short, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutShort(Object receiver, long offset, short value, Object locationIdentity); - @MethodSubstitution - public static void unsafePutInt(Object receiver, long offset, int value, Object locationIdentity) { - CustomizedUnsafeStoreNode.store(receiver, offset, value, Kind.Int, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutInt(Object receiver, long offset, int value, Object locationIdentity); - @MethodSubstitution - public static void unsafePutLong(Object receiver, long offset, long value, Object locationIdentity) { - CustomizedUnsafeStoreNode.store(receiver, offset, value, Kind.Long, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutLong(Object receiver, long offset, long value, Object locationIdentity); - @MethodSubstitution - public static void unsafePutFloat(Object receiver, long offset, float value, Object locationIdentity) { - CustomizedUnsafeStoreNode.store(receiver, offset, value, Kind.Float, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutFloat(Object receiver, long offset, float value, Object locationIdentity); - @MethodSubstitution - public static void unsafePutDouble(Object receiver, long offset, double value, Object locationIdentity) { - CustomizedUnsafeStoreNode.store(receiver, offset, value, Kind.Double, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutDouble(Object receiver, long offset, double value, Object locationIdentity); - @MethodSubstitution - public static void unsafePutObject(Object receiver, long offset, Object value, Object locationIdentity) { - CustomizedUnsafeStoreNode.store(receiver, offset, value, Kind.Object, locationIdentity); - } + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutObject(Object receiver, long offset, Object value, Object locationIdentity); } diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationBlockState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationBlockState.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationBlockState.java Mon Oct 07 23:16:00 2013 +0200 @@ -64,14 +64,14 @@ public abstract boolean conflicts(LocationIdentity other); } - static class LoadCacheEntry extends CacheEntry { + static class LoadCacheEntry extends CacheEntry { - public LoadCacheEntry(ValueNode object, ResolvedJavaField identity) { + public LoadCacheEntry(ValueNode object, LocationIdentity identity) { super(object, identity); } @Override - public CacheEntry duplicateWithObject(ValueNode newObject) { + public CacheEntry duplicateWithObject(ValueNode newObject) { return new LoadCacheEntry(newObject, identity); } diff -r b7ce25d81ef3 -r 60bf1372d1a0 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Mon Oct 07 14:47:18 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Mon Oct 07 23:16:00 2013 +0200 @@ -81,7 +81,7 @@ effects.deleteFixedNode(store); deleted = true; } - state.killReadCache((LocationIdentity) store.field()); + state.killReadCache(store.field()); state.addCacheEntry(identifier, value); } else { processIdentity(state, ANY_LOCATION); @@ -100,6 +100,20 @@ state.addCacheEntry(identifier, read); } } + } else if (node instanceof UnsafeLoadNode) { + UnsafeLoadNode load = (UnsafeLoadNode) node; + if (load.offset().isConstant() && load.getLocationIdentity() != LocationIdentity.ANY_LOCATION) { + ValueNode object = GraphUtil.unproxify(load.object()); + LoadCacheEntry identifier = new LoadCacheEntry(object, load.getLocationIdentity()); + ValueNode cachedValue = state.getCacheEntry(identifier); + if (cachedValue != null) { + effects.replaceAtUsages(load, cachedValue); + addScalarAlias(load, cachedValue); + deleted = true; + } else { + state.addCacheEntry(identifier, load); + } + } } else if (node instanceof WriteNode) { WriteNode write = (WriteNode) node; if (write.location() instanceof ConstantLocationNode) { @@ -117,6 +131,23 @@ } else { processIdentity(state, write.location().getLocationIdentity()); } + } else if (node instanceof UnsafeStoreNode) { + UnsafeStoreNode write = (UnsafeStoreNode) node; + if (write.offset().isConstant() && write.getLocationIdentity() != LocationIdentity.ANY_LOCATION) { + ValueNode object = GraphUtil.unproxify(write.object()); + LoadCacheEntry identifier = new LoadCacheEntry(object, write.getLocationIdentity()); + ValueNode cachedValue = state.getCacheEntry(identifier); + + ValueNode value = getScalarAlias(write.value()); + if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) { + effects.deleteFixedNode(write); + deleted = true; + } + processIdentity(state, write.getLocationIdentity()); + state.addCacheEntry(identifier, value); + } else { + processIdentity(state, write.getLocationIdentity()); + } } else if (node instanceof MemoryCheckpoint.Single) { LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity(); processIdentity(state, identity);