# HG changeset patch # User Christian Humer # Date 1381325616 -7200 # Node ID df3af5e007ad60aa6d3b48f40d845c05c22769f2 # Parent 7cce548b0b60f69fe536a37d7f64ca4030141eb8# Parent dfaac94659aaf900eafdf1a05eee587ac6c5ca0e Merge. diff -r 7cce548b0b60 -r df3af5e007ad 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 Wed Oct 09 15:33:36 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 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java Wed Oct 09 15:33:36 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 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/AbstractHSAILAssembler.java --- a/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/AbstractHSAILAssembler.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/AbstractHSAILAssembler.java Wed Oct 09 15:33:36 2013 +0200 @@ -57,6 +57,7 @@ @Override protected String createLabelName(Label l, int id) { - return "@L" + id; + int blockId = l.getBlockId(); + return "@L" + (blockId == -1 ? id : blockId); } } diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ import static com.oracle.graal.api.code.ValueUtil.*; +import com.oracle.graal.asm.Label; import com.oracle.graal.api.code.Register; import com.oracle.graal.api.code.RegisterConfig; import com.oracle.graal.api.code.TargetDescription; @@ -32,6 +33,7 @@ import com.oracle.graal.api.meta.Value; import com.oracle.graal.nodes.calc.Condition; import com.oracle.graal.graph.GraalInternalError; +import com.oracle.graal.lir.LabelRef; import com.oracle.graal.lir.Variable; public class PTXAssembler extends AbstractPTXAssembler { @@ -185,7 +187,7 @@ assert v != null; if (isConstant(v)) { - return (emitConstant(v)); + return (emitConstant(v, comma)); } else { return (emitRegister((Variable) v, comma)); } @@ -195,28 +197,38 @@ return (" %r" + v.index + (comma ? "," : "")); } - public String emitConstant(Value v) { + public String emitConstant(Value v, boolean comma) { Constant constant = (Constant) v; + String str = null; switch (v.getKind().getTypeChar()) { case 'i': - return (String.valueOf((int) constant.asLong())); + str = String.valueOf((int) constant.asLong()); + break; case 'f': - return (String.valueOf(constant.asFloat())); + str = String.valueOf(constant.asFloat()); + break; case 'j': - return (String.valueOf(constant.asLong())); + str = String.valueOf(constant.asLong()); + break; case 'd': - return (String.valueOf(constant.asDouble())); + str = String.valueOf(constant.asDouble()); + break; default: throw GraalInternalError.shouldNotReachHere(); } + if (comma) { + return (str + ","); + } else { + return str; + } } } public static class SingleOperandFormat { protected Variable dest; - protected Value source; + protected Value source; public SingleOperandFormat(Variable dst, Value src) { setDestination(dst); @@ -298,6 +310,27 @@ } } + public static class BinarySingleOperandFormat extends SingleOperandFormat { + + public BinarySingleOperandFormat(Variable dst, Value src) { + super(dst, src); + } + + @Override + public String typeForKind(Kind k) { + switch (k.getTypeChar()) { + case 's': + return "b16"; + case 'i': + return "b32"; + case 'j': + return "b64"; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } + public static class ConversionFormat extends SingleOperandFormat { public ConversionFormat(Variable dst, Value src) { @@ -306,8 +339,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) + ";"); } } @@ -333,21 +365,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) + ";"); } } } @@ -480,7 +509,16 @@ // Checkstyle: stop method name check public final void bra(String tgt, int pred) { - emitString((pred >= 0) ? "" : ("@%p" + pred + " ") + "bra" + " " + tgt + ";" + ""); + assert pred >= 0; + + if (tgt.equals("?")) { + Thread.dumpStack(); + } + emitString("@%p" + pred + " " + "bra" + " " + tgt + ";"); + } + + public final void bra(String src) { + emitString("bra " + src + ";"); } public final void bra_uni(String tgt) { @@ -494,27 +532,42 @@ } public void emit(PTXAssembler asm) { - asm.emitString("cvt." + super.emit()); + if (dest.getKind() == Kind.Float || dest.getKind() == Kind.Double) { + // round-to-zero - might not be right + asm.emitString("cvt.rz." + super.emit()); + } else { + asm.emitString("cvt." + super.emit()); + } } } - + public static class Mov extends SingleOperandFormat { + private int predicateRegisterNumber = -1; + public Mov(Variable dst, Value src) { super(dst, src); } - /* - public Mov(Variable dst, AbstractAddress src) { - throw GraalInternalError.unimplemented("AbstractAddress Mov"); + public Mov(Variable dst, Value src, int predicate) { + super(dst, src); + this.predicateRegisterNumber = predicate; } - */ - + + /* + * public Mov(Variable dst, AbstractAddress src) { throw + * GraalInternalError.unimplemented("AbstractAddress Mov"); } + */ + public void emit(PTXAssembler asm) { - asm.emitString("mov." + super.emit()); + if (predicateRegisterNumber >= 0) { + asm.emitString("@%p" + String.valueOf(predicateRegisterNumber) + " mov." + super.emit()); + } else { + asm.emitString("mov." + super.emit()); + } } } - + public static class Neg extends SingleOperandFormat { public Neg(Variable dst, Variable src) { @@ -525,8 +578,8 @@ asm.emitString("neg." + super.emit()); } } - - public static class Not extends SingleOperandFormat { + + public static class Not extends BinarySingleOperandFormat { public Not(Variable dst, Variable src) { super(dst, src); @@ -536,7 +589,7 @@ asm.emitString("not." + super.emit()); } } - + public static class Ld extends LoadStoreFormat { public Ld(PTXStateSpace space, Variable dst, Variable src1, Value src2) { @@ -563,6 +616,47 @@ emitString("exit;" + " " + ""); } + public static class Global { + + private Kind kind; + private String name; + private LabelRef[] targets; + + public Global(Value val, String name, LabelRef[] targets) { + this.kind = val.getKind(); + this.name = name; + this.targets = targets; + } + + private static String valueForKind(Kind k) { + switch (k.getTypeChar()) { + case 'i': + return "s32"; + case 'j': + return "s64"; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + private static String emitTargets(PTXAssembler asm, LabelRef[] refs) { + StringBuffer sb = new StringBuffer(); + + for (int i = 0; i < refs.length; i++) { + sb.append(asm.nameOf(refs[i].label())); + if (i < (refs.length - 1)) { + sb.append(", "); + } + } + + return sb.toString(); + } + + public void emit(PTXAssembler asm) { + asm.emitString(".global ." + valueForKind(kind) + " " + name + "[" + targets.length + "] = " + "{ " + emitTargets(asm, targets) + " };"); + } + } + public static class Param extends SingleOperandFormat { private boolean lastParameter; @@ -581,8 +675,33 @@ } public void emit(PTXAssembler asm) { - asm.emitString(".param ." + typeForKind(dest.getKind()) + emitParameter(dest) + (lastParameter ? "" : ",")); + asm.emitString(".param ." + paramForKind(dest.getKind()) + emitParameter(dest) + (lastParameter ? "" : ",")); } + + public String paramForKind(Kind k) { + switch (k.getTypeChar()) { + case 'z': + case 'f': + return "s32"; + case 'b': + return "s8"; + case 's': + return "s16"; + case 'c': + return "u16"; + case 'i': + return "s32"; + case 'j': + return "s64"; + case 'd': + return "f64"; + case 'a': + return "u64"; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } public final void popc_b32(Register d, Register a) { @@ -601,9 +720,24 @@ emitString("ret.uni;" + " " + ""); } - public static class Setp { + public enum BooleanOperator { + AND("and"), OR("or"), XOR("xor"); + + private final String output; + + private BooleanOperator(String out) { + this.output = out; + } - private ConditionOperator operator; + public String getOperator() { + return output + "."; + } + } + + public static class Setp { + + private BooleanOperator booleanOperator; + private ConditionOperator operator; private Value first, second; private Kind kind; private int predicate; @@ -616,6 +750,15 @@ setConditionOperator(operatorForConditon(condition)); } + public Setp(Condition condition, BooleanOperator operator, Value first, Value second, int predicateRegisterNumber) { + setFirst(first); + setSecond(second); + setPredicate(predicateRegisterNumber); + setKind(); + setConditionOperator(operatorForConditon(condition)); + setBooleanOperator(operator); + } + public void setFirst(Value v) { first = v; } @@ -632,6 +775,10 @@ operator = co; } + public void setBooleanOperator(BooleanOperator bo) { + booleanOperator = bo; + } + private ConditionOperator operatorForConditon(Condition condition) { char typeChar = kind.getTypeChar(); @@ -641,12 +788,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(); } @@ -656,11 +809,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; @@ -671,12 +829,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(); } @@ -694,7 +858,7 @@ kind = first.getKind(); } } - + public String emitValue(Value v) { assert v != null; @@ -746,16 +910,23 @@ throw GraalInternalError.shouldNotReachHere(); } } - + public String emitVariable(Variable v) { return ("%r" + v.index); } public void emit(PTXAssembler asm) { - asm.emitString("setp." + operator.getOperator() + "." + typeForKind(kind) + - " %p" + predicate + emitValue(first) + emitValue(second) + ";"); + + if (booleanOperator != null) { + 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) + ";"); + } } } + @Override public PTXAddress makeAddress(Register base, int displacement) { throw GraalInternalError.shouldNotReachHere(); @@ -765,4 +936,14 @@ public PTXAddress getPlaceholder() { return null; } + + @Override + public void jmp(Label l) { + String str = nameOf(l); + if (l.equals("?")) { + Thread.dumpStack(); + } + bra(str); + } + } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Label.java --- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Label.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Label.java Wed Oct 09 15:33:36 2013 +0200 @@ -30,6 +30,7 @@ public final class Label { private int position = -1; + private int blockId = -1; /** * References to instructions that jump to this unresolved label. These instructions need to be @@ -51,6 +52,14 @@ public Label() { } + public Label(int id) { + blockId = id; + } + + public int getBlockId() { + return blockId; + } + /** * Binds the label to the specified position. * diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayPTXTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayPTXTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -71,12 +71,6 @@ } - public static void printReport(String message) { - // CheckStyle: stop system..print check - System.out.println(message); - // CheckStyle: resume system..print check - } - public static void main(String[] args) { ArrayPTXTest test = new ArrayPTXTest(); for (Method m : ArrayPTXTest.class.getMethods()) { diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,13 +24,11 @@ import java.lang.reflect.Method; -import org.junit.Ignore; import org.junit.Test; /** * Test class for small Java methods compiled to PTX kernels. */ -@Ignore public class BasicPTXTest extends PTXTestBase { @Test diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -28,14 +28,54 @@ public class ControlPTXTest extends PTXTestBase { - @Ignore @Test public void testControl() { - compile("testLoop"); - // compile("testSwitch1I"); - // compile("testStatic"); - // compile("testCall"); - // compile("testLookupSwitch1I"); + Integer ret = (Integer) invoke(compile("testLoop"), 42); + if (ret != null) { + printReport("testLoop: " + ret); + } else { + printReport("testLoop: no VALUE"); + } + ret = (Integer) invoke(compile("testSwitchDefault1I"), 3); + if (ret != null) { + printReport("testSwitchDefault1I: " + ret); + } else { + printReport("testSwitchDefault1I: no VALUE"); + } + ret = (Integer) invoke(compile("testSwitch1I"), 2); + if (ret != null) { + printReport("testSwitch1I: " + ret); + } else { + printReport("testSwitch1I: no VALUE"); + } + ret = (Integer) invoke(compile("testIfElse1I"), 222); + if (ret != null) { + printReport("testIfElse1I: " + ret); + } else { + printReport("testIfElse1I: no VALUE"); + } + ret = (Integer) invoke(compile("testIfElse2I"), 19, 64); + if (ret != null) { + printReport("testIfElse2I: " + (char) ret.intValue()); + } else { + printReport("testIfElse2I: no VALUE"); + } + Boolean bret = (Boolean) invoke(compile("testIntegerTestBranch2I"), + 0xff00, 0x00ff); + if (bret != null) { + printReport("testIntegerTestBranch2I: " + bret); + printReport("testIntegerTestBranch2I: actual: " + + testIntegerTestBranch2I(0xff00, 0x00ff)); + } else { + printReport("testIntegerTestBranch2I: no VALUE"); + } + compile("testStatic"); + compile("testCall"); + compile("testLookupSwitch1I"); + } + + public static boolean testIntegerTestBranch2I(int x, int y) { + return (x & y) == 0; } public static int testLoop(int n) { @@ -47,6 +87,31 @@ return sum; } + public static int testIfElse1I(int n) { + if (n > 22) { + return 42; + } else { + return -42; + } + } + + public static int testIfElse2I(int c, int y) { + if (c > 19) { + return 'M'; // millenial + } else if (y > 84) { + return 'Y'; // young + } else { + return 'O'; // old + } + } + + public static int testSwitchDefault1I(int a) { + switch (a) { + default: + return 4; + } + } + public static int testSwitch1I(int a) { switch (a) { case 1: @@ -61,31 +126,31 @@ public static int testLookupSwitch1I(int a) { switch (a) { case 0: - return 1; + return 10; case 1: - return 2; + return 11; case 2: - return 3; + return 12; case 3: - return 1; + return 13; case 4: - return 2; + return 14; case 5: - return 3; + return 15; case 6: - return 1; + return 16; case 7: - return 2; + return 17; case 8: - return 3; + return 18; case 9: - return 1; + return 19; case 10: - return 2; + return 20; case 11: - return 3; + return 21; default: - return -1; + return 42; } } @@ -100,7 +165,7 @@ return a + b; } - public static int testCall(@SuppressWarnings("unused") Object o, int a, int b) { + public static int testCall(int a, int b) { return method(a, b); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/FloatPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/FloatPTXTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/FloatPTXTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -29,44 +29,46 @@ import com.oracle.graal.api.code.CompilationResult; /* PTX ISA 3.1 - 8.7.3 Floating-Point Instructions */ -@Ignore public class FloatPTXTest extends PTXTestBase { - @Ignore @Test public void testAdd() { - CompilationResult r = compile("testAdd2F"); - if (r.getTargetCode() == null) { - printReport("Compilation of testAdd2F FAILED"); + Float ret = (Float) invoke(compile("testAdd2I"), 42, 43); + if (ret != null) { + printReport("testAdd2I: " + ret); + } else { + printReport("testAdd2I: no VALUE"); } - /* - r = compile("testAdd2D"); - if (r.getTargetCode() == null) { - printReport("Compilation of testAdd2D FAILED"); + ret = (Float) invoke(compile("testAdd2F"), 42.1F, 43.5F); + if (ret != null) { + printReport("testAdd2F: " + ret); + } else { + printReport("testAdd2F: no VALUE"); } - r = compile("testAddFConst"); - if (r.getTargetCode() == null) { - printReport("Compilation of testAddFConst FAILED"); - } - r = compile("testAddConstF"); - if (r.getTargetCode() == null) { - printReport("Compilation of testConstF FAILED"); + ret = (Float) invoke(compile("testAddFConst"), 42.1F); + if (ret != null) { + printReport("testAddFConst: " + ret); + } else { + printReport("testAddFConst: no VALUE"); } - r = compile("testAddDConst"); - if (r.getTargetCode() == null) { - printReport("Compilation of testAddDConst FAILED"); + + Double dret = (Double) invoke(compile("testAdd2D"), 42.1, 43.5); + if (dret != null) { + printReport("testAdd2D: " + dret); + } else { + printReport("testAdd2D: no VALUE"); } - r = compile("testAddConstD"); - if (r.getTargetCode() == null) { - printReport("Compilation of testConstD FAILED"); - } - */ + + } + + public static float testAdd2I(int a, int b) { + return a + b; } public static float testAdd2F(float a, float b) { - return a + b; + return (a + b); } public static double testAdd2D(double a, double b) { @@ -359,13 +361,6 @@ return (float) a; } - public static void printReport(String message) { - // CheckStyle: stop system..print check - System.out.println(message); - // CheckStyle: resume system..print check - - } - public static void main(String[] args) { FloatPTXTest test = new FloatPTXTest(); for (Method m : FloatPTXTest.class.getMethods()) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -30,8 +30,8 @@ @Test public void testAdd() { - /* - Integer r4 = (Integer) invoke(compile("testAdd2B"), (byte) 6, (byte) 4); + + /* Integer r4 = (Integer) invoke(compile("testAdd2B"), (byte) 6, (byte) 4); if (r4 == null) { printReport("testAdd2B FAILED"); } else if (r4.intValue() == testAdd2B((byte) 6, (byte) 4)) { @@ -49,14 +49,14 @@ printReport("testAdd2I FAILED"); } - /* Long r2 = (Long) invoke(compile("testAdd2L"), (long) 12, (long) 6); + Long r2 = (Long) invoke(compile("testAdd2L"), (long) 12, (long) 6); if (r2 == null) { printReport("testAdd2L FAILED"); } else if (r2.longValue() == testAdd2L(12, 6)) { printReport("testAdd2L PASSED"); } else { printReport("testAdd2L FAILED"); - } + } r4 = (Integer) invoke(compile("testAddIConst"), 5); if (r4 == null) { @@ -74,7 +74,7 @@ printReport("testAddConstI PASSED"); } else { printReport("testAddConstI FAILED"); - } */ + } } public static int testAdd2I(int a, int b) { @@ -97,7 +97,6 @@ return 32 + a; } - @Ignore @Test public void testSub() { @@ -155,7 +154,6 @@ return 32 - a; } - @Ignore @Test public void testMul() { @@ -348,12 +346,6 @@ return (int) a; } - public static void printReport(String message) { - // CheckStyle: stop system..print check - System.out.println(message); - // CheckStyle: resume system..print check - - } public static void main(String[] args) { IntegerPTXTest test = new IntegerPTXTest(); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/LogicPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/LogicPTXTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/LogicPTXTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,11 +24,9 @@ import java.lang.reflect.Method; -import org.junit.Ignore; import org.junit.Test; /* PTX ISA 3.1 - 8.7.5 Logic and Shift Instructions */ -@Ignore public class LogicPTXTest extends PTXTestBase { @Test diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java Wed Oct 09 15:33:36 2013 +0200 @@ -55,6 +55,13 @@ private StructuredGraph sg; + public void printReport(String message) { + // CheckStyle: stop system..print check + System.out.println(message); + // CheckStyle: resume system..print check + + } + protected CompilationResult compile(String test) { if (runtime instanceof PTXHotSpotRuntime) { StructuredGraph graph = parse(test); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java Wed Oct 09 15:33:36 2013 +0200 @@ -85,7 +85,8 @@ } @Override - public TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult) { + public TargetMethodAssembler newAssembler(LIRGenerator lirGen, + CompilationResult compilationResult) { // Omit the frame of the method: // - has no spill slots or other slots allocated during register allocation // - has no callee-saved registers @@ -99,7 +100,9 @@ return tasm; } - private static void emitKernelEntry(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) { + private static void emitKernelEntry(TargetMethodAssembler tasm, + LIRGenerator lirGen, + ResolvedJavaMethod codeCacheOwner) { // Emit PTX kernel entry text based on PTXParameterOp // instructions in the start block. Remove the instructions // once kernel entry text and directives are emitted to @@ -109,8 +112,8 @@ Buffer codeBuffer = tasm.asm.codeBuffer; // Emit initial boiler-plate directives. - codeBuffer.emitString(".version 1.4"); - codeBuffer.emitString(".target sm_10"); + codeBuffer.emitString(".version 3.0"); + codeBuffer.emitString(".target sm_30"); codeBuffer.emitString0(".entry " + name + " ("); codeBuffer.emitString(""); @@ -140,9 +143,13 @@ } // Emit .reg space declarations - private static void emitRegisterDecl(TargetMethodAssembler tasm, LIRGenerator lirGen, + private static void emitRegisterDecl(TargetMethodAssembler tasm, + LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) { - assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method"; + + assert codeCacheOwner != null : + lirGen.getGraph() + " is not associated with a method"; + Buffer codeBuffer = tasm.asm.codeBuffer; final SortedSet signed32 = new TreeSet<>(); @@ -231,6 +238,7 @@ if (maxPredRegNum > 0) { codeBuffer.emitString(".reg .pred %p<" + maxPredRegNum + ">;"); } + codeBuffer.emitString(".reg .pred %r;"); // used for setp bool } @Override diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Wed Oct 09 15:33:36 2013 +0200 @@ -46,6 +46,8 @@ import com.oracle.graal.lir.ptx.PTXArithmetic.Unary2Op; import com.oracle.graal.lir.ptx.PTXCompare.CompareOp; import com.oracle.graal.lir.ptx.PTXControlFlow.BranchOp; +import com.oracle.graal.lir.ptx.PTXControlFlow.CondMoveOp; +import com.oracle.graal.lir.ptx.PTXControlFlow.FloatCondMoveOp; import com.oracle.graal.lir.ptx.PTXControlFlow.ReturnOp; import com.oracle.graal.lir.ptx.PTXControlFlow.ReturnNoValOp; import com.oracle.graal.lir.ptx.PTXControlFlow.SequentialSwitchOp; @@ -64,7 +66,6 @@ import java.lang.annotation.*; - /** * This class implements the PTX specific portion of the LIR generator. */ @@ -123,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(); } @@ -329,21 +328,105 @@ @Override public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label) { - throw GraalInternalError.unimplemented("PTXLIRGenerator.emitIntegerTestBranch()"); + /// emitIntegerTest(left, right); + // append(new BranchOp(negated ? Condition.NE : Condition.EQ, label)); + throw GraalInternalError.unimplemented("emitIntegerTestBranch()"); } @Override public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) { - // TODO: There is no conventional conditional move instruction in PTX. - // So, this method is changed to throw NYI exception. - // To be revisited if this needs to be really implemented. - throw GraalInternalError.unimplemented("PTXLIRGenerator.emitConditionalMove()"); + + Condition finalCondition = LIRValueUtil.isVariable(right) ? cond.mirror() : cond; + + emitCompare(finalCondition, left, right); + + Variable result = newVariable(trueValue.getKind()); + switch (left.getKind().getStackKind()) { + case Int: + case Long: + case Object: + 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)); + nextPredRegNum++; + break; + default: + throw GraalInternalError.shouldNotReachHere("" + left.getKind()); + } + return result; + } + + /** + * 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 + */ + private boolean emitCompare(Condition cond, Value a, Value b) { + Variable left; + Value right; + boolean mirrored; + if (LIRValueUtil.isVariable(b)) { + left = load(b); + right = loadNonConst(a); + mirrored = true; + } else { + left = load(a); + right = loadNonConst(b); + mirrored = false; + } + switch (left.getKind().getStackKind()) { + case Int: + append(new CompareOp(ICMP, cond, left, right, nextPredRegNum)); + break; + case Long: + append(new CompareOp(LCMP, cond, left, right, nextPredRegNum)); + break; + case Object: + append(new CompareOp(ACMP, cond, left, right, nextPredRegNum)); + break; + case Float: + append(new CompareOp(FCMP, cond, left, right, nextPredRegNum)); + break; + case Double: + append(new CompareOp(DCMP, cond, left, right, nextPredRegNum)); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return mirrored; + } + + @Override + public Variable emitIntegerTestMove(Value left, Value right, + Value trueValue, Value falseValue) { + + emitIntegerTest(left, right); + Variable result = newVariable(trueValue.getKind()); + append(new CondMoveOp(result, Condition.EQ, + load(trueValue), loadNonConst(falseValue), + nextPredRegNum)); + nextPredRegNum++; + + return result; } - @Override - public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) { - throw new InternalError("NYI"); + private void emitIntegerTest(Value a, Value b) { + + assert a.getKind().getStackKind() == Kind.Int || + a.getKind() == Kind.Long; + + if (LIRValueUtil.isVariable(b)) { + append(new PTXTestOp(load(b), loadNonConst(a), nextPredRegNum)); + } else { + append(new PTXTestOp(load(a), loadNonConst(b), nextPredRegNum)); + } } @Override @@ -765,10 +848,10 @@ // Making a copy of the switch value is necessary because jump table destroys the input // value if (key.getKind() == Kind.Int || key.getKind() == Kind.Long) { - append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, Value.ILLEGAL, nextPredRegNum)); + append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, Value.ILLEGAL, nextPredRegNum++)); } else { assert key.getKind() == Kind.Object : key.getKind(); - append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, newVariable(Kind.Object), nextPredRegNum)); + append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, newVariable(Kind.Object), nextPredRegNum++)); } } @@ -817,24 +900,46 @@ throw GraalInternalError.unimplemented("PTXLIRGenerator.visitInfopointNode()"); } - public Variable emitLoadParam(Kind kind, Value address, DeoptimizingNode deopting) { + public Variable emitLoadParam(Kind kind, Value address, + DeoptimizingNode deopting) { + PTXAddressValue loadAddress = asAddress(address); Variable result = newVariable(kind); - append(new LoadParamOp(kind, result, loadAddress, deopting != null ? state(deopting) : null)); + append(new LoadParamOp(kind, result, loadAddress, + deopting != null ? state(deopting) : null)); + return result; } - public Variable emitLoadReturnAddress(Kind kind, Value address, DeoptimizingNode deopting) { + public Variable emitLoadReturnAddress(Kind kind, Value address, + DeoptimizingNode deopting) { + PTXAddressValue loadAddress = asAddress(address); - Variable result = newVariable(kind); - append(new LoadReturnAddrOp(kind, result, loadAddress, deopting != null ? state(deopting) : null)); + Variable result; + switch (kind) { + case Float: + result = newVariable(Kind.Int); + break; + case Double: + result = newVariable(Kind.Long); + break; + default: + result = newVariable(kind); + + } + append(new LoadReturnAddrOp(kind, result, loadAddress, + deopting != null ? state(deopting) : null)); + return result; } - public void emitStoreReturnValue(Kind kind, Value address, Value inputVal, DeoptimizingNode deopting) { + public void emitStoreReturnValue(Kind kind, Value address, Value inputVal, + DeoptimizingNode deopting) { + PTXAddressValue storeAddress = asAddress(address); Variable input = load(inputVal); - append(new StoreReturnValOp(kind, storeAddress, input, deopting != null ? state(deopting) : null)); + append(new StoreReturnValOp(kind, storeAddress, input, + deopting != null ? state(deopting) : null)); } @Override diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXTargetMethodAssembler.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXTargetMethodAssembler.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXTargetMethodAssembler.java Wed Oct 09 15:33:36 2013 +0200 @@ -33,10 +33,13 @@ public class PTXTargetMethodAssembler extends TargetMethodAssembler { - private static CompilerToGPU toGPU = HotSpotGraalRuntime.graalRuntime().getCompilerToGPU(); + private static CompilerToGPU toGPU = + HotSpotGraalRuntime.graalRuntime().getCompilerToGPU(); + private static boolean validDevice = toGPU.deviceInit(); - private static final int totalProcessors = (validDevice ? toGPU.availableProcessors() : 0); + private static final int totalProcessors = + (validDevice ? toGPU.availableProcessors() : 0); public static int getAvailableProcessors() { return totalProcessors; @@ -44,8 +47,12 @@ // detach ?? - public PTXTargetMethodAssembler(TargetDescription target, CodeCacheProvider runtime, FrameMap frameMap, - AbstractAssembler asm, FrameContext frameContext, CompilationResult compilationResult) { + public PTXTargetMethodAssembler(TargetDescription target, + CodeCacheProvider runtime, + FrameMap frameMap, + AbstractAssembler asm, + FrameContext frameContext, + CompilationResult compilationResult) { super(target, runtime, frameMap, asm, frameContext, compilationResult); } @@ -53,11 +60,14 @@ public CompilationResult finishTargetMethod(StructuredGraph graph) { ResolvedJavaMethod method = graph.method(); assert method != null : graph + " is not associated wth a method"; - ExternalCompilationResult graalCompile = (ExternalCompilationResult) super.finishTargetMethod(graph); + + ExternalCompilationResult graalCompile = + (ExternalCompilationResult) super.finishTargetMethod(graph); try { if ((validDevice) && (graalCompile.getTargetCode() != null)) { - long kernel = toGPU.generateKernel(graalCompile.getTargetCode(), method.getName()); + long kernel = toGPU.generateKernel(graalCompile.getTargetCode(), + method.getName()); graalCompile.setEntryPoint(kernel); } } catch (Throwable th) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -94,7 +94,7 @@ /** * In this case the read should be scheduled in the first block. */ - public static int testSplitSnippet1(int a) { + public static int testSplit1Snippet(int a) { try { return container.a; } finally { @@ -109,7 +109,7 @@ @Test public void testSplit1() { for (TestMode mode : TestMode.values()) { - SchedulePhase schedule = getFinalSchedule("testSplitSnippet1", mode, MemoryScheduling.OPTIMAL); + SchedulePhase schedule = getFinalSchedule("testSplit1Snippet", mode, MemoryScheduling.OPTIMAL); assertReadWithinStartBlock(schedule, true); assertReadWithinReturnBlock(schedule, false); } @@ -209,6 +209,42 @@ assertReadWithinReturnBlock(schedule, false); } + public String testStringReplaceSnippet(String input) { + return input.replace('a', 'b'); + } + + @Test + public void testStringReplace() { + getFinalSchedule("testStringReplaceSnippet", TestMode.INLINED_WITHOUT_FRAMESTATES, MemoryScheduling.OPTIMAL); + test("testStringReplaceSnippet", "acbaaa"); + } + + /** + * Here the read should float out of the loop. + */ + public static int testLoop5Snippet(int a, int b, MemoryScheduleTest obj) { + int ret = 0; + int bb = b; + for (int i = 0; i < a; i++) { + ret = obj.hash; + if (a > 10) { + bb++; + } else { + bb--; + } + ret = ret / 10; + } + return ret + bb; + } + + @Test + public void testLoop5() { + SchedulePhase schedule = getFinalSchedule("testLoop5Snippet", TestMode.WITHOUT_FRAMESTATES, MemoryScheduling.OPTIMAL); + assertEquals(7, schedule.getCFG().getBlocks().length); + assertReadWithinStartBlock(schedule, false); + assertReadWithinReturnBlock(schedule, false); + } + /** * Here the read should float to the end (into the same block as the return). */ @@ -312,6 +348,25 @@ } /** + * Here the read should float to the end. + */ + public static int testIfRead5Snippet(int a) { + if (a < 0) { + container.a = 10; + } + return container.a; + } + + @Test + public void testIfRead5() { + SchedulePhase schedule = getFinalSchedule("testIfRead5Snippet", TestMode.WITHOUT_FRAMESTATES, MemoryScheduling.OPTIMAL); + assertEquals(4, schedule.getCFG().getBlocks().length); + assertReadWithinStartBlock(schedule, false); + assertReadWithinReturnBlock(schedule, true); + assertReadAndWriteInSameBlock(schedule, false); + } + + /** * testing scheduling within a block. */ public static int testBlockScheduleSnippet() { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PhiCreationTests.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PhiCreationTests.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PhiCreationTests.java Wed Oct 09 15:33:36 2013 +0200 @@ -41,7 +41,7 @@ @Test public void test1() { StructuredGraph graph = parse("test1Snippet"); - Assert.assertFalse(graph.getNodes(PhiNode.class).iterator().hasNext()); + Assert.assertFalse(graph.getNodes().filter(PhiNode.class).iterator().hasNext()); } public static int test1Snippet(int a) { @@ -54,7 +54,7 @@ @Test public void test2() { StructuredGraph graph = parse("test2Snippet"); - Assert.assertFalse(graph.getNodes(PhiNode.class).iterator().hasNext()); + Assert.assertFalse(graph.getNodes().filter(PhiNode.class).iterator().hasNext()); } public static int test2Snippet(int a) { @@ -68,7 +68,7 @@ public void test3() { StructuredGraph graph = parse("test3Snippet"); Debug.dump(graph, "Graph"); - Assert.assertFalse(graph.getNodes(PhiNode.class).iterator().hasNext()); + Assert.assertFalse(graph.getNodes().filter(PhiNode.class).iterator().hasNext()); } public static int test3Snippet(int a) { @@ -84,7 +84,7 @@ public void test4() { StructuredGraph graph = parse("test4Snippet"); Debug.dump(graph, "Graph"); - Assert.assertFalse(graph.getNodes(PhiNode.class).iterator().hasNext()); + Assert.assertFalse(graph.getNodes().filter(PhiNode.class).iterator().hasNext()); } public static int test4Snippet(int a) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -76,7 +76,7 @@ @Test public void testSimple() { ValueNode result = getReturn("testSimpleSnippet").result(); - assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); + assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty()); assertEquals(graph.getLocal(0), result); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -83,7 +83,7 @@ @Test public void testSimple() { ValueNode result = getReturn("testSimpleSnippet").result(); - assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); + assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty()); assertTrue(result.isConstant()); assertEquals(2, result.asConstant().asInt()); } @@ -112,7 +112,7 @@ @Test public void testParam() { ValueNode result = getReturn("testParamSnippet").result(); - assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); + assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty()); assertEquals(graph.getLocal(1), result); } @@ -126,7 +126,7 @@ @Test public void testMaterialized() { ValueNode result = getReturn("testMaterializedSnippet").result(); - assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); + assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty()); assertEquals(graph.getLocal(0), result); } @@ -142,7 +142,7 @@ @Test public void testSimpleLoop() { ValueNode result = getReturn("testSimpleLoopSnippet").result(); - assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); + assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty()); assertEquals(graph.getLocal(1), result); } @@ -160,7 +160,7 @@ @Test public void testBadLoop() { ValueNode result = getReturn("testBadLoopSnippet").result(); - assertEquals(0, graph.getNodes(LoadFieldNode.class).count()); + assertEquals(0, graph.getNodes().filter(LoadFieldNode.class).count()); assertTrue(result instanceof ProxyNode); assertTrue(((ProxyNode) result).value() instanceof PhiNode); } @@ -178,7 +178,7 @@ @Test public void testBadLoop2() { ValueNode result = getReturn("testBadLoop2Snippet").result(); - assertEquals(1, graph.getNodes(LoadFieldNode.class).count()); + assertEquals(1, graph.getNodes().filter(LoadFieldNode.class).count()); assertTrue(result instanceof LoadFieldNode); } @@ -195,7 +195,7 @@ @Test public void testPhi() { ValueNode result = getReturn("testPhiSnippet").result(); - assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); + assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty()); assertTrue(result instanceof PhiNode); PhiNode phi = (PhiNode) result; assertTrue(phi.valueAt(0).isConstant()); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Wed Oct 09 15:33:36 2013 +0200 @@ -86,7 +86,7 @@ */ @Option(help = "Pattern for method(s) to which intrinsification will not be applied. " + "See MethodFilter class for pattern syntax.") - public static final OptionValue IntrinsificationsDisabled = new OptionValue<>("Object.clone"); + public static final OptionValue IntrinsificationsDisabled = new OptionValue<>(null); // @formatter:on } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Wed Oct 09 15:33:36 2013 +0200 @@ -288,7 +288,7 @@ assert lir.lir(block) == null : "LIR list already computed for this block"; lir.setLir(block, new ArrayList()); - append(new LabelOp(new Label(), block.isAligned())); + append(new LabelOp(new Label(block.getId()), block.isAligned())); if (TraceLIRGeneratorLevel.getValue() >= 1) { TTY.println("BEGIN Generating LIR for block B" + block.getId()); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Wed Oct 09 15:33:36 2013 +0200 @@ -31,6 +31,7 @@ import com.oracle.graal.graph.NodeClass.NodeClassIterator; import com.oracle.graal.graph.NodeClass.Position; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.graph.spi.*; /** * This class is the base class for all nodes, it represent a node which can be inserted in a @@ -594,12 +595,32 @@ return newNode; } - static int count = 0; - public final Node clone(Graph into) { return clone(into, true); } + /** + * Must be overridden buy subclasses that implement {@link Canonicalizable}. The implementation + * in {@link Node} exists to obviate the need to cast a node before invoking + * {@link Canonicalizable#canonical(CanonicalizerTool)}. + * + * @param tool + */ + public Node canonical(CanonicalizerTool tool) { + throw new UnsupportedOperationException(); + } + + /** + * Must be overridden buy subclasses that implement {@link Simplifiable}. The implementation in + * {@link Node} exists to obviate the need to cast a node before invoking + * {@link Simplifiable#simplify(SimplifierTool)}. + * + * @param tool + */ + public void simplify(SimplifierTool tool) { + throw new UnsupportedOperationException(); + } + final Node clone(Graph into, boolean clearInputsAndSuccessors) { NodeClass nodeClass = getNodeClass(); if (nodeClass.valueNumberable() && nodeClass.isLeafNode()) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Wed Oct 09 15:33:36 2013 +0200 @@ -33,6 +33,7 @@ import com.oracle.graal.graph.Node.Input; import com.oracle.graal.graph.Node.Successor; import com.oracle.graal.graph.Node.Verbosity; +import com.oracle.graal.graph.spi.*; /** * Lazily associated metadata for every {@link Node} type. The metadata includes: @@ -148,9 +149,21 @@ private static final DebugMetric ITERABLE_NODE_TYPES = Debug.metric("IterableNodeTypes"); private final DebugMetric nodeIterableCount; + /** + * Determines if this node type implements {@link Canonicalizable}. + */ + private final boolean isCanonicalizable; + + /** + * Determines if this node type implements {@link Simplifiable}. + */ + private final boolean isSimplifiable; + private NodeClass(Class clazz) { super(clazz); assert NODE_CLASS.isAssignableFrom(clazz); + this.isCanonicalizable = Canonicalizable.class.isAssignableFrom(clazz); + this.isSimplifiable = Simplifiable.class.isAssignableFrom(clazz); FieldScanner scanner = new FieldScanner(new DefaultCalcOffset()); scanner.scan(clazz); @@ -259,6 +272,20 @@ return isLeafNode; } + /** + * Determines if this node type implements {@link Canonicalizable}. + */ + public boolean isCanonicalizable() { + return isCanonicalizable; + } + + /** + * Determines if this node type implements {@link Simplifiable}. + */ + public boolean isSimplifiable() { + return isSimplifiable; + } + public static int cacheSize() { return nextIterableId; } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Canonicalizable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Canonicalizable.java Wed Oct 09 15:33:36 2013 +0200 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011, 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.graph.spi; + +import com.oracle.graal.graph.*; + +public interface Canonicalizable { + + Node canonical(CanonicalizerTool tool); +} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/CanonicalizerTool.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/CanonicalizerTool.java Wed Oct 09 15:33:36 2013 +0200 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011, 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.graph.spi; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; + +public interface CanonicalizerTool { + + Assumptions assumptions(); + + MetaAccessProvider runtime(); + + boolean canonicalizeReads(); + + void removeIfUnused(Node node); +} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Simplifiable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Simplifiable.java Wed Oct 09 15:33:36 2013 +0200 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graph.spi; + +/** + * This interface allows nodes to perform more complicated simplifications, in contrast to + * {@link Canonicalizable}, which supports only replacing the current node. + * + * Implementors of this interface need to be aware that they need to call + * {@link SimplifierTool#addToWorkList(com.oracle.graal.graph.Node)} for each node that might be + * influenced (in terms of simplification and canonicalization) by the actions performed in + * simplify. + */ +public interface Simplifiable { + + void simplify(SimplifierTool tool); +} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/SimplifierTool.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/SimplifierTool.java Wed Oct 09 15:33:36 2013 +0200 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.graph.spi; + +import com.oracle.graal.graph.*; + +/** + * @see Simplifiable + */ +public interface SimplifierTool extends CanonicalizerTool { + + void deleteBranch(Node branch); + + /** + * Adds a node to the worklist independent of whether it has already been on the worklist. + */ + void addToWorkList(Node node); +} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java Wed Oct 09 15:33:36 2013 +0200 @@ -104,7 +104,14 @@ int currentStackOffset = 0; Kind returnKind = returnType == null ? Kind.Void : returnType.getKind(); - AllocatableValue returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : new Variable(returnKind, currentGeneral++); + + AllocatableValue returnLocation; + if (returnKind == Kind.Void) { + returnLocation = Value.ILLEGAL; + } else { + returnLocation = new Variable(returnKind, currentGeneral++); + } + AllocatableValue[] locations = new AllocatableValue[parameterTypes.length]; for (int i = 0; i < parameterTypes.length; i++) { diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Wed Oct 09 15:33:36 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 { @@ -258,9 +258,10 @@ int barriers = 0; if (useG1GC()) { - barriers = graph.getNodes(G1ReferentFieldReadBarrier.class).count() + graph.getNodes(G1PreWriteBarrier.class).count() + graph.getNodes(G1PostWriteBarrier.class).count(); + barriers = graph.getNodes().filter(G1ReferentFieldReadBarrier.class).count() + graph.getNodes().filter(G1PreWriteBarrier.class).count() + + graph.getNodes().filter(G1PostWriteBarrier.class).count(); } else { - barriers = graph.getNodes(SerialWriteBarrier.class).count(); + barriers = graph.getNodes().filter(SerialWriteBarrier.class).count(); } Assert.assertEquals(expectedBarriers, barriers); for (WriteNode write : graph.getNodes().filter(WriteNode.class)) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -647,11 +647,11 @@ int barriers = 0; // First, the total number of expected barriers is checked. if (((HotSpotRuntime) runtime()).config.useG1GC) { - barriers = graph.getNodes(G1PreWriteBarrier.class).count() + graph.getNodes(G1PostWriteBarrier.class).count() + graph.getNodes(G1ArrayRangePreWriteBarrier.class).count() + - graph.getNodes(G1ArrayRangePostWriteBarrier.class).count(); + barriers = graph.getNodes().filter(G1PreWriteBarrier.class).count() + graph.getNodes().filter(G1PostWriteBarrier.class).count() + + graph.getNodes().filter(G1ArrayRangePreWriteBarrier.class).count() + graph.getNodes().filter(G1ArrayRangePostWriteBarrier.class).count(); Assert.assertTrue(expectedBarriers * 2 == barriers); } else { - barriers = graph.getNodes(SerialWriteBarrier.class).count() + graph.getNodes(SerialArrayRangeWriteBarrier.class).count(); + barriers = graph.getNodes().filter(SerialWriteBarrier.class).count() + graph.getNodes().filter(SerialArrayRangeWriteBarrier.class).count(); Assert.assertTrue(expectedBarriers == barriers); } // Iterate over all write nodes and remove barriers according to input indices. diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Wed Oct 09 15:33:36 2013 +0200 @@ -131,6 +131,14 @@ OptionDescriptor desc = options.get(optionName); if (desc == null) { Logger.info("Could not find option " + optionName + " (use -G:+PrintFlags to see Graal options)"); + List matches = fuzzyMatch(optionName); + if (!matches.isEmpty()) { + Logger.info("Did you mean one of the following?"); + for (OptionDescriptor match : matches) { + boolean isBoolean = match.getType() == boolean.class; + Logger.info(String.format(" %s%s%s", isBoolean ? "(+/-)" : "", match.getName(), isBoolean ? "" : "=")); + } + } return false; } @@ -210,7 +218,7 @@ if (line.length() != 0) { line.append(' '); } - String[] embeddedLines = chunk.split("%n"); + String[] embeddedLines = chunk.split("%n", -2); if (embeddedLines.length == 1) { line.append(chunk); } else { @@ -246,4 +254,38 @@ System.exit(0); } + + /** + * Compute string similarity based on Dice's coefficient. + * + * Ported from str_similar() in globals.cpp. + */ + static float stringSimiliarity(String str1, String str2) { + int hit = 0; + for (int i = 0; i < str1.length() - 1; ++i) { + for (int j = 0; j < str2.length() - 1; ++j) { + if ((str1.charAt(i) == str2.charAt(j)) && (str1.charAt(i + 1) == str2.charAt(j + 1))) { + ++hit; + break; + } + } + } + return 2.0f * hit / (str1.length() + str2.length()); + } + + private static final float FUZZY_MATCH_THRESHOLD = 0.7F; + + /** + * Returns the set of options that fuzzy match a given option name. + */ + private static List fuzzyMatch(String optionName) { + List matches = new ArrayList<>(); + for (Map.Entry e : options.entrySet()) { + float score = stringSimiliarity(e.getKey(), optionName); + if (score >= FUZZY_MATCH_THRESHOLD) { + matches.add(e.getValue()); + } + } + return matches; + } } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Wed Oct 09 15:33:36 2013 +0200 @@ -35,6 +35,7 @@ import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.HeapAccess.*; import com.oracle.graal.nodes.calc.*; @@ -44,6 +45,39 @@ import com.oracle.graal.options.*; import com.oracle.graal.replacements.nodes.*; +/** + * This class contains infrastructure to maintain counters based on {@link DynamicCounterNode}s. The + * infrastructure is enabled by specifying either the GenericDynamicCounters or + * BenchmarkDynamicCounters option.
+ * + * The counters are kept in a special area in the native JavaThread object, and the number of + * counters is configured in {@code thread.hpp (GRAAL_COUNTERS_SIZE)}. This file also contains an + * option to exclude compiler threads ({@code GRAAL_COUNTERS_EXCLUDE_COMPILER_THREADS}, which + * defaults to true). + * + * The subsystems that use the logging need to have their own options to turn on the counters, and + * insert DynamicCounterNodes when they're enabled. + * + * Counters will be displayed as a rate (per second) if their group name starts with "~", otherwise + * they will be displayed as a total number. + * + *

Example

In order to create statistics about allocations within the DaCapo pmd benchmark + * the following steps are necessary: + *
    + *
  • Modify {@code thread.hpp}: increase GRAAL_COUNTER_SIZE. The actual required value depends on + * the granularity of the profiling, 10000 should be enough for most cases. This will increase the + * JavaThread structure by 80kb.
  • + *
  • Also in {@code thread.hpp}: GRAAL_COUNTERS_EXCLUDE_COMPILER_THREADS specifies whether the + * numbers generated by compiler threads should be excluded (default: true).
  • + *
  • Build the Graal VM.
  • + *
  • Start the DaCapo pmd benchmark with + * {@code "-G:BenchmarkDynamicCounters=err, starting ====, PASSED in "} and + * {@code -G:+ProfileAllocations}.
  • + *
  • The numbers will only include allocation from compiled code!
  • + *
  • The counters can be further configured by modifying the + * {@link NewObjectSnippets#PROFILE_MODE} field.
  • + *
+ */ public class BenchmarkCounters { static class Options { @@ -98,7 +132,7 @@ } public static synchronized void dump(PrintStream out, double seconds, long[] counters) { - if (!staticCounters.isEmpty()) { + if (!groups.isEmpty()) { out.println("====== dynamic counters (" + staticCounters.size() + " in total) ======"); for (String group : new TreeSet<>(groups)) { if (group != null) { @@ -146,7 +180,7 @@ NumberFormat format = NumberFormat.getInstance(Locale.US); long cutoff = sorted.size() < 10 ? 1 : Math.max(1, sum / 100); if (staticCounter) { - out.println("=========== " + group + " static counters: "); + out.println("=========== " + group + " (static counters):"); for (Map.Entry entry : sorted.entrySet()) { long counter = entry.getKey() / array.length; if (counter >= cutoff) { @@ -156,7 +190,16 @@ out.println(sum + ": total"); } else { if (group.startsWith("~")) { - out.println("=========== " + group + " dynamic counters"); + out.println("=========== " + group + " (dynamic counters), time = " + seconds + " s:"); + for (Map.Entry entry : sorted.entrySet()) { + long counter = entry.getKey() / array.length; + if (counter >= cutoff) { + out.println(format.format((long) (counter / seconds)) + "/s \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue()); + } + } + out.println(format.format((long) (sum / seconds)) + "/s: total"); + } else { + out.println("=========== " + group + " (dynamic counters):"); for (Map.Entry entry : sorted.entrySet()) { long counter = entry.getKey() / array.length; if (counter >= cutoff) { @@ -164,15 +207,6 @@ } } out.println(format.format(sum) + ": total"); - } else { - out.println("=========== " + group + " dynamic counters, time = " + seconds + " s"); - for (Map.Entry entry : sorted.entrySet()) { - long counter = entry.getKey() / array.length; - if (counter >= cutoff) { - out.println(format.format((long) (counter / seconds)) + "/s \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue()); - } - } - out.println(format.format((long) (sum / seconds)) + "/s: total"); } } } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Wed Oct 09 15:33:36 2013 +0200 @@ -99,7 +99,7 @@ ResolvedJavaMethod initMethod = null; try { Class rjm = ResolvedJavaMethod.class; - makeGraphMethod = runtime.lookupJavaMethod(ReplacementsImpl.class.getDeclaredMethod("makeGraph", rjm, rjm, SnippetInliningPolicy.class)); + makeGraphMethod = runtime.lookupJavaMethod(ReplacementsImpl.class.getDeclaredMethod("makeGraph", rjm, rjm, SnippetInliningPolicy.class, boolean.class)); initMethod = runtime.lookupJavaMethod(SnippetTemplate.AbstractTemplates.class.getDeclaredMethod("template", Arguments.class)); } catch (NoSuchMethodException | SecurityException e) { throw new GraalInternalError(e); diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Wed Oct 09 15:33:36 2013 +0200 @@ -556,7 +556,7 @@ ValueNode object = loadField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : loadField.object(); assert loadField.kind() != Kind.Illegal; BarrierType barrierType = getFieldLoadBarrierType(field); - ReadNode memoryRead = graph.add(new ReadNode(object, createFieldLocation(graph, field), loadField.stamp(), barrierType, (loadField.kind() == Kind.Object))); + ReadNode memoryRead = graph.add(new ReadNode(object, createFieldLocation(graph, field, false), loadField.stamp(), barrierType, (loadField.kind() == Kind.Object))); graph.replaceFixedWithFixed(loadField, memoryRead); tool.createNullCheckGuard(memoryRead, object); @@ -571,7 +571,7 @@ HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field(); ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : storeField.object(); BarrierType barrierType = getFieldStoreBarrierType(storeField); - WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), createFieldLocation(graph, field), barrierType, storeField.field().getKind() == Kind.Object)); + WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), createFieldLocation(graph, field, false), barrierType, storeField.field().getKind() == Kind.Object)); tool.createNullCheckGuard(memoryWrite, object); memoryWrite.setStateAfter(storeField.stateAfter()); graph.replaceFixedWithFixed(storeField, memoryWrite); @@ -596,7 +596,7 @@ LoadIndexedNode loadIndexed = (LoadIndexedNode) n; GuardingNode boundsCheck = createBoundsCheck(loadIndexed, tool); Kind elementKind = loadIndexed.elementKind(); - LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index()); + LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index(), false); ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), arrayLocation, loadIndexed.stamp(), BarrierType.NONE, elementKind == Kind.Object)); memoryRead.setGuard(boundsCheck); graph.replaceFixedWithFixed(loadIndexed, memoryRead); @@ -604,7 +604,7 @@ StoreIndexedNode storeIndexed = (StoreIndexedNode) n; GuardingNode boundsCheck = createBoundsCheck(storeIndexed, tool); Kind elementKind = storeIndexed.elementKind(); - LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index()); + LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index(), false); ValueNode value = storeIndexed.value(); ValueNode array = storeIndexed.array(); @@ -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)); @@ -719,7 +719,7 @@ value = allocations[commit.getVirtualObjects().indexOf(value)]; } if (!(value.isConstant() && value.asConstant().isDefaultForKind())) { - WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) virtualInstance.field(i)), + WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) virtualInstance.field(i), true), virtualInstance.field(i).getKind() == Kind.Object ? BarrierType.IMPRECISE : BarrierType.NONE, virtualInstance.field(i).getKind() == Kind.Object); graph.addBeforeFixed(commit, graph.add(write)); @@ -737,7 +737,7 @@ value = allocations[indexOf]; } if (!(value.isConstant() && value.asConstant().isDefaultForKind())) { - WriteNode write = new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph)), + WriteNode write = new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph), true), value.kind() == Kind.Object ? BarrierType.PRECISE : BarrierType.NONE, value.kind() == Kind.Object); graph.addBeforeFixed(commit, graph.add(write)); } @@ -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())) { @@ -943,8 +980,9 @@ return barrierType; } - protected static ConstantLocationNode createFieldLocation(StructuredGraph graph, HotSpotResolvedJavaField field) { - return ConstantLocationNode.create(field, field.getKind(), field.offset(), graph); + protected static ConstantLocationNode createFieldLocation(StructuredGraph graph, HotSpotResolvedJavaField field, boolean initialization) { + LocationIdentity loc = initialization ? INIT_LOCATION : field; + return ConstantLocationNode.create(loc, field.getKind(), field.offset(), graph); } public int getScalingFactor(Kind kind) { @@ -955,9 +993,10 @@ } } - protected IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index) { + protected IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index, boolean initialization) { + LocationIdentity loc = initialization ? INIT_LOCATION : NamedLocationIdentity.getArrayLocation(elementKind); int scale = getScalingFactor(elementKind); - return IndexedLocationNode.create(NamedLocationIdentity.getArrayLocation(elementKind), elementKind, getArrayBaseOffset(elementKind), index, graph, scale); + return IndexedLocationNode.create(loc, elementKind, getArrayBaseOffset(elementKind), index, graph, scale); } @Override @@ -1014,6 +1053,9 @@ } public ResolvedJavaType lookupJavaType(Class clazz) { + if (clazz == null) { + throw new IllegalArgumentException("Class parameter was null"); + } return HotSpotResolvedObjectType.fromClass(clazz); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -22,11 +22,12 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; /** @@ -48,7 +49,8 @@ return arguments.get(1); } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { ValueNode object = getObject(); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -22,9 +22,10 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; /** @@ -42,7 +43,8 @@ return arguments.get(0); } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { Class c = (Class) javaClass.asConstant().asObject(); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -22,9 +22,10 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; /** @@ -42,7 +43,8 @@ return arguments.get(0); } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { Class c = (Class) javaClass.asConstant().asObject(); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -22,9 +22,10 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; /** @@ -42,7 +43,8 @@ return arguments.get(0); } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { Class c = (Class) javaClass.asConstant().asObject(); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -22,9 +22,10 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; /** @@ -42,7 +43,8 @@ return arguments.get(0); } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { Class c = (Class) javaClass.asConstant().asObject(); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -22,12 +22,13 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; /** @@ -49,7 +50,8 @@ return arguments.get(1); } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { ValueNode object = getObject(); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -22,9 +22,10 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; /** @@ -42,7 +43,8 @@ return arguments.get(0); } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { Class c = (Class) javaClass.asConstant().asObject(); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -22,9 +22,10 @@ */ package com.oracle.graal.hotspot.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; /** @@ -42,7 +43,8 @@ return arguments.get(0); } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { ValueNode javaClass = getJavaClass(); if (javaClass.isConstant()) { Class c = (Class) javaClass.asConstant().asObject(); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java Wed Oct 09 15:33:36 2013 +0200 @@ -22,13 +22,12 @@ */ package com.oracle.graal.hotspot.nodes; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -public abstract class WriteBarrier extends FixedWithNextNode implements Lowerable, IterableNodeType { +public abstract class WriteBarrier extends FixedWithNextNode implements Lowerable { @Input private ValueNode object; @Input private ValueNode value; diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java Wed Oct 09 15:33:36 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 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -32,6 +32,7 @@ import com.oracle.graal.api.meta.ResolvedJavaType; import com.oracle.graal.graph.GraalInternalError; import com.oracle.graal.graph.NodeInputList; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.meta.HotSpotResolvedJavaMethod; import com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType; import com.oracle.graal.hotspot.meta.HotSpotSignature; @@ -43,7 +44,6 @@ import com.oracle.graal.nodes.java.MethodCallTargetNode; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.nodes.java.SelfReplacingMethodCallTargetNode; -import com.oracle.graal.nodes.spi.Canonicalizable; import com.oracle.graal.nodes.type.*; import com.oracle.graal.replacements.nodes.MacroNode; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -26,6 +26,8 @@ import com.oracle.graal.api.code.*; 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.spi.*; import com.oracle.graal.replacements.nodes.*; @@ -56,7 +58,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { ConstantNode target = getConstantCallTarget(tool.runtime(), tool.assumptions()); if (target != null) { return target; diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java Wed Oct 09 15:33:36 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 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Wed Oct 09 15:33:36 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 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleInvokeBasicNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleInvokeBasicNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleInvokeBasicNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,10 +24,9 @@ import java.lang.invoke.MethodHandle; -import com.oracle.graal.nodes.Invoke; -import com.oracle.graal.nodes.InvokeNode; -import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.CanonicalizerTool; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.*; /** * Macro node for {@link MethodHandle}{@code .invokeBasic(Object...)}. @@ -39,7 +38,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { InvokeNode invoke = getInvokeBasicTarget(); if (invoke != null) { return invoke; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToInterfaceNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToInterfaceNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToInterfaceNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,10 +24,9 @@ import java.lang.invoke.MethodHandle; -import com.oracle.graal.nodes.Invoke; -import com.oracle.graal.nodes.InvokeNode; -import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.CanonicalizerTool; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.*; /** * Macro node for {@link MethodHandle}{@code .linkToInterface(Object...)}. @@ -39,7 +38,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { InvokeNode invoke = getLinkToTarget(); if (invoke != null) { return invoke; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToSpecialNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToSpecialNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToSpecialNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,10 +24,9 @@ import java.lang.invoke.MethodHandle; -import com.oracle.graal.nodes.Invoke; -import com.oracle.graal.nodes.InvokeNode; -import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.CanonicalizerTool; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.*; /** * Macro node for {@link MethodHandle}{@code .linkToSpecial(Object...)}. @@ -39,7 +38,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { InvokeNode invoke = getLinkToTarget(); if (invoke != null) { return invoke; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToStaticNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToStaticNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToStaticNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,10 +24,9 @@ import java.lang.invoke.MethodHandle; -import com.oracle.graal.nodes.Invoke; -import com.oracle.graal.nodes.InvokeNode; -import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.CanonicalizerTool; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.*; /** * Macro node for {@link MethodHandle}{@code .linkToStatic(Object...)}. @@ -39,7 +38,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { InvokeNode invoke = getLinkToTarget(); if (invoke != null) { return invoke; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToVirtualNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToVirtualNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToVirtualNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,10 +24,9 @@ import java.lang.invoke.MethodHandle; -import com.oracle.graal.nodes.Invoke; -import com.oracle.graal.nodes.InvokeNode; -import com.oracle.graal.nodes.ValueNode; -import com.oracle.graal.nodes.spi.CanonicalizerTool; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.*; /** * Macro node for {@link MethodHandle}{@code .linkToVirtual(Object...)}. @@ -39,7 +38,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { InvokeNode invoke = getLinkToTarget(); if (invoke != null) { return invoke; diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Wed Oct 09 15:33:36 2013 +0200 @@ -40,14 +40,17 @@ import com.oracle.graal.graph.iterators.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.debug.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.options.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; +import com.oracle.graal.replacements.Snippet.Fold; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo; @@ -63,6 +66,22 @@ */ public class MonitorSnippets implements Snippets { + public static class Options { + + //@formatter:off + @Option(help = "") + private static final OptionValue ProfileMonitors = new OptionValue<>(false); + //@formatter:on + } + + private static final boolean PROFILE_CONTEXT = false; + + @Fold + @SuppressWarnings("unused") + private static boolean doProfile(String path) { + return Options.ProfileMonitors.getValue(); + } + /** * Monitor operations on objects whose type contains this substring will be traced. */ @@ -118,7 +137,7 @@ trace(trace, " tmp: 0x%016lx\n", tmp); if (probability(FREQUENT_PROBABILITY, tmp.equal(0))) { // Object is already biased to current thread -> done - traceObject(trace, "+lock{bias:existing}", object); + traceObject(trace, "+lock{bias:existing}", object, true); return; } @@ -154,13 +173,13 @@ trace(trace, " biasedMark: 0x%016lx\n", biasedMark); if (probability(VERY_FAST_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); + traceObject(trace, "+lock{bias:acquired}", object, true); return; } // 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. - traceObject(trace, "+lock{stub:revoke}", object); + traceObject(trace, "+lock{stub:revoke}", object, true); monitorenterStub(MONITORENTER, object, lock); return; } else { @@ -174,13 +193,13 @@ trace(trace, " biasedMark: 0x%016lx\n", biasedMark); if (probability(VERY_FAST_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); + traceObject(trace, "+lock{bias:transfer}", object, true); return; } // 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. - traceObject(trace, "+lock{stub:epoch-expired}", object); + traceObject(trace, "+lock{stub:epoch-expired}", object, true); monitorenterStub(MONITORENTER, object, lock); return; } @@ -237,16 +256,16 @@ final Word stackPointer = stackPointer(); 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 - traceObject(trace, "+lock{stub:failed-cas}", object); + traceObject(trace, "+lock{stub:failed-cas}", object, true); monitorenterStub(MONITORENTER, object, lock); return; } else { // Recursively locked => write 0 to the lock slot lock.writeWord(lockDisplacedMarkOffset(), Word.zero(), DISPLACED_MARK_WORD_LOCATION); - traceObject(trace, "+lock{recursive}", object); + traceObject(trace, "+lock{recursive}", object, true); } } else { - traceObject(trace, "+lock{cas}", object); + traceObject(trace, "+lock{cas}", object, true); } } @@ -263,7 +282,7 @@ // BeginLockScope nodes do not read from object so a use of object // cannot float about the null check above final Word lock = beginLockScope(lockDepth); - traceObject(trace, "+lock{stub}", object); + traceObject(trace, "+lock{stub}", object, true); monitorenterStub(MONITORENTER, object, lock); } @@ -282,7 +301,7 @@ if (probability(FREQUENT_PROBABILITY, mark.and(biasedLockMaskInPlace()).equal(Word.unsigned(biasedLockPattern())))) { endLockScope(); decCounter(); - traceObject(trace, "-lock{bias}", object); + traceObject(trace, "-lock{bias}", object, false); return; } } @@ -295,7 +314,7 @@ if (displacedMark.equal(0)) { // Recursive locking => done - traceObject(trace, "-lock{recursive}", object); + traceObject(trace, "-lock{recursive}", object, false); } else { verifyOop(object); // Test if object's mark word is pointing to the displaced mark word, and if so, restore @@ -304,10 +323,10 @@ 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. - traceObject(trace, "-lock{stub}", object); + traceObject(trace, "-lock{stub}", object, false); MonitorExitStubCall.call(object, lockDepth); } else { - traceObject(trace, "-lock{cas}", object); + traceObject(trace, "-lock{cas}", object, false); } } endLockScope(); @@ -320,13 +339,16 @@ @Snippet public static void monitorexitStub(Object object, @ConstantParameter int lockDepth, @ConstantParameter boolean trace) { verifyOop(object); - traceObject(trace, "-lock{stub}", object); + traceObject(trace, "-lock{stub}", object, false); MonitorExitStubCall.call(object, lockDepth); endLockScope(); decCounter(); } - private static void traceObject(boolean enabled, String action, Object object) { + private static void traceObject(boolean enabled, String action, Object object, boolean enter) { + if (doProfile(action)) { + DynamicCounterNode.counter(action, enter ? "number of monitor enters" : "number of monitor exits", 1, PROFILE_CONTEXT); + } if (enabled) { Log.print(action); Log.print(' '); diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Wed Oct 09 15:33:36 2013 +0200 @@ -34,17 +34,21 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.debug.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.options.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; +import com.oracle.graal.replacements.Snippet.Fold; import com.oracle.graal.replacements.Snippet.VarargsParameter; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; @@ -59,6 +63,20 @@ public static final LocationIdentity INIT_LOCATION = new NamedLocationIdentity("Initialization"); + public static class Options { + + //@formatter:off + @Option(help = "") + private static final OptionValue ProfileAllocations = new OptionValue<>(false); + //@formatter:on + } + + static enum ProfileMode { + AllocatingMethods, InstanceOrArray, AllocatedTypes, AllocatedTypesInMethods, Total + } + + public static final ProfileMode PROFILE_MODE = ProfileMode.Total; + @Snippet public static Word allocate(int size) { Word thread = thread(); @@ -76,8 +94,41 @@ return Word.zero(); } + @Fold + private static String createName(String path, String typeContext) { + switch (PROFILE_MODE) { + case AllocatingMethods: + return ""; + case InstanceOrArray: + return path; + case AllocatedTypes: + case AllocatedTypesInMethods: + return typeContext; + case Total: + return "bytes"; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + @Fold + @SuppressWarnings("unused") + private static boolean doProfile(String path, String typeContext) { + return Options.ProfileAllocations.getValue(); + } + + private static void profileAllocation(String path, long size, String typeContext) { + if (doProfile(path, typeContext)) { + String name = createName(path, typeContext); + + boolean context = PROFILE_MODE == ProfileMode.AllocatingMethods || PROFILE_MODE == ProfileMode.AllocatedTypesInMethods; + DynamicCounterNode.counter(name, "number of bytes allocated", size, context); + DynamicCounterNode.counter(name, "number of allocations", 1, context); + } + } + @Snippet - public static Object allocateInstance(@ConstantParameter int size, Word hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents) { + public static Object allocateInstance(@ConstantParameter int size, Word hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents, @ConstantParameter String typeContext) { Object result; Word thread = thread(); Word top = readTlabTop(thread); @@ -90,6 +141,7 @@ new_stub.inc(); result = NewInstanceStubCall.call(hub); } + profileAllocation("instance", size, typeContext); return piCast(verifyOop(result), StampFactory.forNodeIntrinsic()); } @@ -99,15 +151,16 @@ public static final int MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH = 0x00FFFFFF; @Snippet - public static Object allocateArray(Word hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize, @ConstantParameter boolean fillContents) { + public static Object allocateArray(Word hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize, + @ConstantParameter boolean fillContents, @ConstantParameter String typeContext) { if (!belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) { // This handles both negative array sizes and very large array sizes DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } - return allocateArrayImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents); + return allocateArrayImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, typeContext); } - private static Object allocateArrayImpl(Word hub, int length, Word prototypeMarkWord, int headerSize, int log2ElementSize, boolean fillContents) { + private static Object allocateArrayImpl(Word hub, int length, Word prototypeMarkWord, int headerSize, int log2ElementSize, boolean fillContents, String typeContext) { Object result; int alignment = wordSize(); int allocationSize = computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize); @@ -123,6 +176,7 @@ newarray_stub.inc(); result = NewArrayStubCall.call(hub, length); } + profileAllocation("array", allocationSize, typeContext); return piArrayCast(verifyOop(result), length, StampFactory.forNodeIntrinsic()); } @@ -156,7 +210,7 @@ int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask(); Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION); - return allocateArrayImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents); + return allocateArrayImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, "dynamic type"); } /** @@ -261,6 +315,7 @@ args.add("hub", hub); args.add("prototypeMarkWord", type.prototypeMarkWord()); args.addConst("fillContents", newInstanceNode.fillContents()); + args.addConst("typeContext", MetaUtil.toJavaName(type, false)); SnippetTemplate template = template(args); Debug.log("Lowering allocateInstance in %s: node=%s, template=%s, arguments=%s", graph, newInstanceNode, template, args); @@ -286,6 +341,7 @@ args.addConst("headerSize", headerSize); args.addConst("log2ElementSize", log2ElementSize); args.addConst("fillContents", newArrayNode.fillContents()); + args.addConst("typeContext", MetaUtil.toJavaName(arrayType, false)); SnippetTemplate template = template(args); Debug.log("Lowering allocateArray in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, args); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -59,49 +59,72 @@ } ResolvedJavaType type = ObjectStamp.typeOrNull(getObject()); - Method method; - /* - * The first condition tests if the parameter is an array, the second condition tests if the - * parameter can be an array. Otherwise, the parameter is known to be a non-array object. - */ - if (type.isArray()) { - method = ObjectCloneSnippets.arrayCloneMethod; - } else if (type == null || type.isAssignableFrom(tool.getRuntime().lookupJavaType(Object[].class))) { - method = ObjectCloneSnippets.genericCloneMethod; - } else { - method = ObjectCloneSnippets.instanceCloneMethod; + if (type != null) { + if (type.isArray()) { + Method method = ObjectCloneSnippets.arrayCloneMethods.get(type.getComponentType().getKind()); + if (method != null) { + final ResolvedJavaMethod snippetMethod = tool.getRuntime().lookupJavaMethod(method); + final Replacements replacements = tool.getReplacements(); + StructuredGraph snippetGraph = Debug.scope("ArrayCopySnippet", snippetMethod, new Callable() { + + @Override + public StructuredGraph call() throws Exception { + return replacements.getSnippet(snippetMethod); + } + }); + + assert snippetGraph != null : "ObjectCloneSnippets should be installed"; + return lowerReplacement(snippetGraph.copy(), tool); + } + } else { + type = getConcreteType(getObject().stamp(), tool.assumptions(), tool.getRuntime()); + if (type != null) { + StructuredGraph newGraph = new StructuredGraph(); + LocalNode local = newGraph.add(new LocalNode(0, getObject().stamp())); + NewInstanceNode newInstance = newGraph.add(new NewInstanceNode(type, true)); + newGraph.addAfterFixed(newGraph.start(), newInstance); + ReturnNode returnNode = newGraph.add(new ReturnNode(newInstance)); + newGraph.addAfterFixed(newInstance, returnNode); + + for (ResolvedJavaField field : type.getInstanceFields(true)) { + LoadFieldNode load = newGraph.add(new LoadFieldNode(local, field)); + newGraph.addBeforeFixed(returnNode, load); + newGraph.addBeforeFixed(returnNode, newGraph.add(new StoreFieldNode(newInstance, field, load))); + } + return lowerReplacement(newGraph, tool); + } + } } - final ResolvedJavaMethod snippetMethod = tool.getRuntime().lookupJavaMethod(method); - final Replacements replacements = tool.getReplacements(); - StructuredGraph snippetGraph = Debug.scope("ArrayCopySnippet", snippetMethod, new Callable() { - - @Override - public StructuredGraph call() throws Exception { - return replacements.getSnippet(snippetMethod); - } - }); - - assert snippetGraph != null : "ObjectCloneSnippets should be installed"; - return lowerReplacement(snippetGraph.copy(), tool); + return null; } private static boolean isCloneableType(ResolvedJavaType type, MetaAccessProvider metaAccess) { - return type != null && metaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(type); + return metaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(type); } - private static ResolvedJavaType getConcreteType(Stamp stamp, Assumptions assumptions) { + /* + * Looks at the given stamp and determines if it is an exact type (or can be assumed to be an + * exact type) and if it is a cloneable type. + * + * If yes, then the exact type is returned, otherwise it returns null. + */ + private static ResolvedJavaType getConcreteType(Stamp stamp, Assumptions assumptions, MetaAccessProvider metaAccess) { if (!(stamp instanceof ObjectStamp)) { return null; } ObjectStamp objectStamp = (ObjectStamp) stamp; - if (objectStamp.isExactType() || objectStamp.type() == null) { - return objectStamp.type(); + if (objectStamp.type() == null) { + return null; + } else if (objectStamp.isExactType()) { + return isCloneableType(objectStamp.type(), metaAccess) ? objectStamp.type() : null; } else { ResolvedJavaType type = objectStamp.type().findUniqueConcreteSubtype(); - if (type != null) { + if (type != null && isCloneableType(type, metaAccess)) { assumptions.recordConcreteSubtype(objectStamp.type(), type); + return type; + } else { + return null; } - return type; } } @@ -126,21 +149,19 @@ } else { obj = tool.getReplacedValue(getObject()); } - ResolvedJavaType type = getConcreteType(obj.stamp(), tool.getAssumptions()); - if (isCloneableType(type, tool.getMetaAccessProvider())) { - if (!type.isArray()) { - VirtualInstanceNode newVirtual = new VirtualInstanceNode(type, true); - ResolvedJavaField[] fields = newVirtual.getFields(); + ResolvedJavaType type = getConcreteType(obj.stamp(), tool.getAssumptions(), tool.getMetaAccessProvider()); + if (type != null && !type.isArray()) { + VirtualInstanceNode newVirtual = new VirtualInstanceNode(type, true); + ResolvedJavaField[] fields = newVirtual.getFields(); - ValueNode[] state = new ValueNode[fields.length]; - final LoadFieldNode[] loads = new LoadFieldNode[fields.length]; - for (int i = 0; i < fields.length; i++) { - state[i] = loads[i] = new LoadFieldNode(obj, fields[i]); - tool.addNode(loads[i]); - } - tool.createVirtualObject(newVirtual, state, null); - tool.replaceWithVirtual(newVirtual); + ValueNode[] state = new ValueNode[fields.length]; + final LoadFieldNode[] loads = new LoadFieldNode[fields.length]; + for (int i = 0; i < fields.length; i++) { + state[i] = loads[i] = new LoadFieldNode(obj, fields[i]); + tool.addNode(loads[i]); } + tool.createVirtualObject(newVirtual, state, null); + tool.replaceWithVirtual(newVirtual); } } } diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java Wed Oct 09 15:33:36 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -22,113 +22,77 @@ */ package com.oracle.graal.hotspot.replacements; -import static com.oracle.graal.api.meta.LocationIdentity.*; -import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; -import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; -import static com.oracle.graal.phases.GraalOptions.*; - import java.lang.reflect.*; +import java.util.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.replacements.*; -import com.oracle.graal.word.*; public class ObjectCloneSnippets implements Snippets { - public static final Method instanceCloneMethod = getCloneMethod("instanceClone"); - public static final Method arrayCloneMethod = getCloneMethod("arrayClone"); - public static final Method genericCloneMethod = getCloneMethod("genericClone"); + public static final EnumMap arrayCloneMethods = new EnumMap<>(Kind.class); - private static Method getCloneMethod(String name) { + static { + arrayCloneMethods.put(Kind.Byte, getCloneMethod("byteArrayClone", byte[].class)); + arrayCloneMethods.put(Kind.Char, getCloneMethod("charArrayClone", char[].class)); + arrayCloneMethods.put(Kind.Int, getCloneMethod("intArrayClone", int[].class)); + arrayCloneMethods.put(Kind.Long, getCloneMethod("longArrayClone", long[].class)); + arrayCloneMethods.put(Kind.Object, getCloneMethod("objectArrayClone", Object[].class)); + } + + private static Method getCloneMethod(String name, Class param) { try { - return ObjectCloneSnippets.class.getDeclaredMethod(name, Object.class); + return ObjectCloneSnippets.class.getDeclaredMethod(name, param); } catch (SecurityException | NoSuchMethodException e) { throw new GraalInternalError(e); } } - private static Object instanceClone(Object src, Word hub, int layoutHelper) { - int instanceSize = layoutHelper; - Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION); - Object result = NewObjectSnippets.allocateInstance(instanceSize, hub, prototypeMarkWord, false); - - for (int offset = instanceHeaderSize(); offset < instanceSize; offset += wordSize()) { - /* - * TODO atomicity problem on 32-bit architectures: The JVM spec requires double values - * to be copied atomically, but here they are copied as two 4-byte word values. - */ - ObjectAccess.writeWord(result, offset, ObjectAccess.readWord(src, offset, ANY_LOCATION), ANY_LOCATION); + @Snippet(removeAllFrameStates = true) + public static byte[] byteArrayClone(byte[] src) { + byte[] result = new byte[src.length]; + for (int i = 0; i < result.length; i++) { + result[i] = src[i]; } - return result; } - private static Object arrayClone(Object src, Word hub, int layoutHelper) { - int arrayLength = ArrayLengthNode.arrayLength(src); - int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask(); - int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask(); - int sizeInBytes = NewObjectSnippets.computeArrayAllocationSize(arrayLength, wordSize(), headerSize, log2ElementSize); - - Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION); - Object result = NewObjectSnippets.allocateArray(hub, arrayLength, prototypeMarkWord, headerSize, log2ElementSize, false); - - for (int offset = headerSize; offset < sizeInBytes; offset += wordSize()) { - /* - * TODO atomicity problem on 32-bit architectures: The JVM spec requires double values - * to be copied atomically, but here they are copied as two 4-byte word values. - */ - ObjectAccess.writeWord(result, offset, ObjectAccess.readWord(src, offset, ANY_LOCATION), ANY_LOCATION); + @Snippet(removeAllFrameStates = true) + public static char[] charArrayClone(char[] src) { + char[] result = new char[src.length]; + for (int i = 0; i < result.length; i++) { + result[i] = src[i]; } return result; } - private static Word getAndCheckHub(Object src) { - Word hub = loadHub(src); - if (!(src instanceof Cloneable)) { - DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); + @Snippet(removeAllFrameStates = true) + public static int[] intArrayClone(int[] src) { + int[] result = new int[src.length]; + for (int i = 0; i < result.length; i++) { + result[i] = src[i]; } - return hub; - } - - @Snippet - public static Object instanceClone(Object src) { - instanceCloneCounter.inc(); - Word hub = getAndCheckHub(src); - return instanceClone(src, hub, hub.readInt(layoutHelperOffset(), FINAL_LOCATION)); - } - - @Snippet - public static Object arrayClone(Object src) { - arrayCloneCounter.inc(); - Word hub = getAndCheckHub(src); - int layoutHelper = hub.readInt(layoutHelperOffset(), FINAL_LOCATION); - return arrayClone(src, hub, layoutHelper); + return result; } - @Snippet - public static Object genericClone(Object src) { - genericCloneCounter.inc(); - Word hub = getAndCheckHub(src); - int layoutHelper = hub.readInt(layoutHelperOffset(), FINAL_LOCATION); - if (probability(LIKELY_PROBABILITY, layoutHelper < 0)) { - genericArrayCloneCounter.inc(); - return arrayClone(src, hub, layoutHelper); - } else { - genericInstanceCloneCounter.inc(); - return instanceClone(src, hub, layoutHelper); + @Snippet(removeAllFrameStates = true) + public static long[] longArrayClone(long[] src) { + long[] result = new long[src.length]; + for (int i = 0; i < result.length; i++) { + result[i] = src[i]; } + return result; } - private static final SnippetCounter.Group cloneCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("Object.clone") : null; - private static final SnippetCounter instanceCloneCounter = new SnippetCounter(cloneCounters, "instanceClone", "clone snippet for instances"); - private static final SnippetCounter arrayCloneCounter = new SnippetCounter(cloneCounters, "arrayClone", "clone snippet for arrays"); - private static final SnippetCounter genericCloneCounter = new SnippetCounter(cloneCounters, "genericClone", "clone snippet for arrays and instances"); - - private static final SnippetCounter.Group genericCloneCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("Object.clone generic snippet") : null; - private static final SnippetCounter genericInstanceCloneCounter = new SnippetCounter(genericCloneCounters, "genericInstanceClone", "generic clone implementation took instance path"); - private static final SnippetCounter genericArrayCloneCounter = new SnippetCounter(genericCloneCounters, "genericArrayClone", "generic clone implementation took array path"); - + @Snippet(removeAllFrameStates = true) + public static Object[] objectArrayClone(Object[] src) { + Object[] result = (Object[]) DynamicNewArrayNode.newArray(GuardingPiNode.guardingNonNull(src.getClass().getComponentType()), src.length); + for (int i = 0; i < result.length; i++) { + result[i] = src[i]; + } + return result; + } } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectGetClassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectGetClassNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectGetClassNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -26,6 +26,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ResolvedJavaType.Representation; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -57,7 +59,8 @@ } } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { if (AOTCompilation.getValue()) { return this; } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -38,7 +39,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { ConstantNode callerClassNode = getCallerClassNode(tool.runtime()); if (callerClassNode != null) { return callerClassNode; diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Wed Oct 09 15:33:36 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 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java Wed Oct 09 15:33:36 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 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Wed Oct 09 15:33:36 2013 +0200 @@ -305,7 +305,7 @@ private void inline(InvokeNode invoke) { ResolvedJavaMethod method = ((MethodCallTargetNode) invoke.callTarget()).targetMethod(); ReplacementsImpl repl = new ReplacementsImpl(runtime, new Assumptions(false), runtime.getTarget()); - StructuredGraph calleeGraph = repl.makeGraph(method, null, null); + StructuredGraph calleeGraph = repl.makeGraph(method, null, null, false); InliningUtil.inline(invoke, calleeGraph, false); } } diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ import static com.oracle.graal.asm.ptx.PTXAssembler.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; +import static com.oracle.graal.lir.LIRValueUtil.*; import static com.oracle.graal.nodes.calc.Condition.*; import com.oracle.graal.api.code.CompilationResult.JumpTable; @@ -57,7 +58,8 @@ public static class ReturnNoValOp extends PTXLIRInstruction { - public ReturnNoValOp() { } + public ReturnNoValOp() { + } @Override public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { @@ -97,30 +99,28 @@ } } - @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; private final Condition condition; + private final int predicate; - public CondMoveOp(Variable result, Condition condition, Variable trueValue, Value falseValue) { + public CondMoveOp(Variable result, Condition condition, Variable trueValue, Value falseValue, int predicateRegister) { this.result = result; this.condition = condition; this.trueValue = trueValue; this.falseValue = falseValue; + this.predicate = predicateRegister; } @Override public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { - // cmove(tasm, masm, result, false, condition, false, trueValue, falseValue); - // see 8.3 Predicated Execution p. 61 of PTX ISA 3.1 - throw new InternalError("NYI"); + cmove(tasm, masm, result, false, condition, false, trueValue, falseValue, predicate); } } - @SuppressWarnings("unused") public static class FloatCondMoveOp extends PTXLIRInstruction { @Def({REG}) protected Value result; @@ -128,20 +128,71 @@ @Alive({REG}) protected Value falseValue; private final Condition condition; private final boolean unorderedIsTrue; + private final int predicate; - public FloatCondMoveOp(Variable result, Condition condition, boolean unorderedIsTrue, Variable trueValue, Variable falseValue) { + public FloatCondMoveOp(Variable result, Condition condition, boolean unorderedIsTrue, Variable trueValue, Variable falseValue, int predicateRegister) { this.result = result; this.condition = condition; this.unorderedIsTrue = unorderedIsTrue; this.trueValue = trueValue; this.falseValue = falseValue; + this.predicate = predicateRegister; } @Override public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { - // cmove(tasm, masm, result, true, condition, unorderedIsTrue, trueValue, falseValue); - // see 8.3 Predicated Execution p. 61 of PTX ISA 3.1 - throw new InternalError("NYI"); + 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) { + // check that we don't overwrite an input operand before it is used. + assert !result.equals(trueValue); + + PTXMove.move(tasm, asm, result, falseValue); + cmove(asm, result, trueValue, predicateRegister); + + if (isFloat) { + if (unorderedIsTrue && !trueOnUnordered(condition)) { + // cmove(tasm, masm, result, ConditionFlag.Parity, trueValue); + throw GraalInternalError.unimplemented(); + } else if (!unorderedIsTrue && trueOnUnordered(condition)) { + // cmove(tasm, masm, result, ConditionFlag.Parity, falseValue); + throw GraalInternalError.unimplemented(); + } + } + } + + private static boolean trueOnUnordered(Condition condition) { + switch (condition) { + case NE: + case EQ: + return false; + case LT: + case GE: + return true; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + 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"; + + switch (other.getKind()) { + case Int: + new Mov(asVariable(result), other, predicateRegister).emit(asm); + break; + case Long: + new Mov(asVariable(result), other, predicateRegister).emit(asm); + break; + default: + throw new InternalError("unhandled: " + other.getKind()); + } + } else { + throw GraalInternalError.shouldNotReachHere("cmove: not register"); } } @@ -232,7 +283,9 @@ @SuppressWarnings("unused") 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 + int highKey = lowKey + targets.length - 1; if (lowKey != 0) { // subtract the low value from the switch value @@ -244,15 +297,20 @@ // Jump to default target if index is not within the jump table if (defaultTarget != null) { - masm.bra(defaultTarget.label().toString(), predNum); + masm.bra(masm.nameOf(defaultTarget.label()), predNum); } // address of jump table int tablePos = buf.position(); JumpTable jt = new JumpTable(tablePos, lowKey, highKey, 4); + String name = "jumptable" + jt.position; + + new Global(value, name, targets).emit(masm); + + // bra(Value, name); + tasm.compilationResult.addAnnotation(jt); - // PTX: unimp: tableswitch extract } } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java Wed Oct 09 15:33:36 2013 +0200 @@ -43,7 +43,8 @@ @Use({COMPOSITE}) protected PTXAddressValue address; @State protected LIRFrameState state; - public LoadOp(Kind kind, Variable result, PTXAddressValue address, LIRFrameState state) { + public LoadOp(Kind kind, Variable result, PTXAddressValue address, + LIRFrameState state) { this.kind = kind; this.result = result; this.address = address; @@ -62,7 +63,8 @@ case Float: case Double: case Object: - new Ld(Global, result, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm); + new Ld(Global, result, addr.getBase(), + Constant.forLong(addr.getDisplacement())).emit(masm); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -97,7 +99,8 @@ case Float: case Double: case Object: - new St(Global, input, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm); + new St(Global, input, addr.getBase(), + Constant.forLong(addr.getDisplacement())).emit(masm); break; default: throw GraalInternalError.shouldNotReachHere("missing: " + address.getKind()); @@ -114,7 +117,8 @@ @Use({COMPOSITE}) protected PTXAddressValue address; @State protected LIRFrameState state; - public LoadParamOp(Kind kind, Variable result, PTXAddressValue address, LIRFrameState state) { + public LoadParamOp(Kind kind, Variable result, PTXAddressValue address, + LIRFrameState state) { this.kind = kind; this.result = result; this.address = address; @@ -133,7 +137,8 @@ case Float: case Double: case Object: - new Ld(Parameter, result, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm); + new Ld(Parameter, result, addr.getBase(), + Constant.forLong(addr.getDisplacement())).emit(masm); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -151,7 +156,8 @@ @Use({COMPOSITE}) protected PTXAddressValue address; @State protected LIRFrameState state; - public LoadReturnAddrOp(Kind kind, Variable result, PTXAddressValue address, LIRFrameState state) { + public LoadReturnAddrOp(Kind kind, Variable result, + PTXAddressValue address, LIRFrameState state) { this.kind = kind; this.result = result; this.address = address; @@ -166,7 +172,8 @@ case Long: case Float: case Double: - new Ld(Parameter, result, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm); + new Ld(Parameter, result, addr.getBase(), + Constant.forLong(addr.getDisplacement())).emit(masm); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -183,7 +190,8 @@ @Use({REG}) protected Variable input; @State protected LIRFrameState state; - public StoreReturnValOp(Kind kind, PTXAddressValue address, Variable input, LIRFrameState state) { + public StoreReturnValOp(Kind kind, PTXAddressValue address, + Variable input, LIRFrameState state) { this.kind = kind; this.address = address; this.input = input; @@ -202,7 +210,8 @@ case Float: case Double: case Object: - new St(Global, input, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm); + new St(Global, input, addr.getBase(), + Constant.forLong(addr.getDisplacement())).emit(masm); break; default: throw GraalInternalError.shouldNotReachHere("missing: " + address.getKind()); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXTestOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXTestOp.java Wed Oct 09 15:33:36 2013 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.lir.ptx; + +import static com.oracle.graal.asm.ptx.PTXAssembler.BooleanOperator.*; +import static com.oracle.graal.asm.ptx.PTXAssembler.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.ptx.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.nodes.calc.Condition; + +public class PTXTestOp extends PTXLIRInstruction { + + @Use({REG}) protected Value x; + @Use({REG, STACK, CONST}) protected Value y; + int predicate; + + public PTXTestOp(Value x, Value y, int predicate) { + this.x = x; + this.y = y; + this.predicate = predicate; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { + 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; + } + + 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. + */ + new Setp(Condition.EQ, AND, x, y, predicate).emit(masm); + } +} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes; + +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +@NodeInfo(nameTemplate = "ConditionGuard(!={p#negated})") +public final class ConditionAnchorNode extends FixedWithNextNode implements Canonicalizable, Lowerable, GuardingNode { + + @Input private LogicNode condition; + private boolean negated; + + public ConditionAnchorNode(LogicNode condition) { + this(condition, false); + } + + public ConditionAnchorNode(LogicNode condition, boolean negated) { + super(StampFactory.dependency()); + this.negated = negated; + this.condition = condition; + } + + public LogicNode condition() { + return condition; + } + + private void setCondition(LogicNode x) { + updateUsages(condition, x); + condition = x; + } + + public boolean isNegated() { + return negated; + } + + @Override + public String toString(Verbosity verbosity) { + if (verbosity == Verbosity.Name && negated) { + return "!" + super.toString(verbosity); + } else { + return super.toString(verbosity); + } + } + + @Override + public Node canonical(CanonicalizerTool tool) { + if (condition instanceof LogicNegationNode) { + LogicNegationNode negation = (LogicNegationNode) condition; + setCondition(negation.getInput()); + negated = !negated; + } + + if (condition instanceof LogicConstantNode) { + LogicConstantNode c = (LogicConstantNode) condition; + if (c.getValue() != negated) { + this.replaceAtUsages(null); + return null; + } else { + return graph().add(new ValueAnchorNode(null)); + } + } + + return this; + } + + @Override + public void lower(LoweringTool tool) { + if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { + ValueAnchorNode newAnchor = graph().add(new ValueAnchorNode(null)); + graph().replaceFixedWithFixed(this, newAnchor); + } + } +} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.nodes; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.spi.*; /** diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,8 +24,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; /** @@ -90,7 +90,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (condition() instanceof LogicNegationNode) { LogicNegationNode negation = (LogicNegationNode) condition(); return graph().unique(new GuardNode(negation.getInput(), getGuard(), reason, action, !negated)); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -74,7 +75,8 @@ } } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { if (getGuard() == graph().start()) { if (stamp().equals(object().stamp())) { return object(); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; @@ -92,7 +93,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (stamp() == StampFactory.illegal(object.kind())) { // The guard always fails return graph().add(new DeoptimizeNode(action, reason)); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -30,6 +30,7 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -121,7 +121,7 @@ @Override public void setNext(FixedNode x) { if (x != null) { - this.setNext(AbstractBeginNode.begin(x)); + this.setNext(KillingBeginNode.begin(x, getLocationIdentity())); } else { this.setNext(null); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -0,0 +1,49 @@ +/* + * 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.nodes; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.extended.*; + +public class KillingBeginNode extends AbstractBeginNode implements MemoryCheckpoint.Single { + + private LocationIdentity locationIdentity; + + public KillingBeginNode(LocationIdentity locationIdentity) { + this.locationIdentity = locationIdentity; + } + + public static KillingBeginNode begin(FixedNode with, LocationIdentity locationIdentity) { + if (with instanceof KillingBeginNode) { + return (KillingBeginNode) with; + } + KillingBeginNode begin = with.graph().add(new KillingBeginNode(locationIdentity)); + begin.setNext(with); + return begin; + } + + @Override + public LocationIdentity getLocationIdentity() { + return locationIdentity; + } +} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNegationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNegationNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNegationNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,12 +23,12 @@ package com.oracle.graal.nodes; import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.graph.spi.*; /** * Logic node that negates its argument. */ -public class LogicNegationNode extends LogicNode implements Canonicalizable, IterableNodeType { +public class LogicNegationNode extends LogicNode implements Canonicalizable { @Input private LogicNode input; @@ -40,7 +40,8 @@ return input; } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { if (input instanceof LogicNegationNode) { return ((LogicNegationNode) input).getInput(); } else { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,7 +23,7 @@ package com.oracle.graal.nodes; import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.graph.spi.*; public class LoopExitNode extends BeginStateSplitNode implements IterableNodeType { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.util.*; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,9 +24,9 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; /** @@ -34,7 +34,7 @@ * variable. */ @NodeInfo(nameTemplate = "{p#type/s}Phi({i#values})") -public class PhiNode extends FloatingNode implements Canonicalizable, IterableNodeType, GuardingNode { +public class PhiNode extends FloatingNode implements Canonicalizable, GuardingNode { public static enum PhiType { Value(null), // normal value phis @@ -231,7 +231,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { ValueNode singleValue = singleValue(); if (singleValue != null) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiArrayNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiArrayNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -45,7 +47,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (!(object() instanceof ArrayLengthProvider) || length() != ((ArrayLengthProvider) object()).length()) { return this; } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -83,7 +84,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { inferStamp(); if (stamp().equals(object().stamp())) { return object(); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.ValueNumberable; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; @@ -87,7 +88,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (type == PhiType.Value && value.isConstant()) { return value; } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,7 +23,7 @@ package com.oracle.graal.nodes; import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.graph.spi.*; public class ShortCircuitOrNode extends LogicNode implements IterableNodeType, Canonicalizable { @@ -88,7 +88,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { ShortCircuitOrNode ret = canonicalizeNegation(); if (ret != null) { return ret; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Wed Oct 09 15:33:36 2013 +0200 @@ -250,7 +250,7 @@ node.safeDelete(); } - public void replaceFloating(FloatingNode node, ValueNode replacement) { + public void replaceFloating(FloatingNode node, Node replacement) { assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement; node.replaceAtUsages(replacement); node.safeDelete(); @@ -324,7 +324,7 @@ for (Node successor : snapshot) { if (successor != null && successor.isAlive()) { if (successor != survivingSuccessor) { - GraphUtil.killCFG((AbstractBeginNode) successor); + GraphUtil.killCFG(successor); } } } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -25,6 +25,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -71,7 +72,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (ObjectStamp.isExactType(object)) { // The profile is useless - we know the type! return object; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -26,7 +26,6 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.nodes.type.*; -import com.oracle.graal.nodes.util.*; /** * This class represents a value within the graph, including local variables, phis, and all other @@ -127,13 +126,6 @@ return null; } - public boolean verifyStamp(Class stampClass) { - assert stamp() != null; - assert stampClass.isInstance(stamp()) : this + " (" + GraphUtil.approxSourceLocation(this) + ") has unexpected stamp type: expected " + stampClass.getName() + ", got " + - stamp().getClass().getName() + ", usages=" + usages(); - return true; - } - @Override public boolean verify() { assertTrue(kind() != null, "Should have a valid kind"); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -47,7 +48,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return x(); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; @@ -115,7 +116,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant() && tool.runtime() != null) { return LogicConstantNode.forBoolean(condition().foldCondition(x().asConstant(), y().asConstant(), tool.runtime(), unorderedIsTrue()), graph()); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -25,6 +25,8 @@ import static com.oracle.graal.nodes.calc.CompareNode.*; 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.java.*; import com.oracle.graal.nodes.spi.*; @@ -66,7 +68,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (condition instanceof LogicNegationNode) { LogicNegationNode negated = (LogicNegationNode) condition; return graph().unique(new ConditionalNode(negated.getInput(), falseValue(), trueValue())); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -26,6 +26,7 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -200,7 +201,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (value.isConstant()) { return ConstantNode.forPrimitive(evalConst(value.asConstant()), graph()); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; @@ -37,15 +38,15 @@ public Constant evalConst(Constant... inputs) { assert inputs.length == 2; if (kind() == Kind.Float) { - return Constant.forFloat(x().asConstant().asFloat() + y().asConstant().asFloat()); + return Constant.forFloat(inputs[0].asFloat() + inputs[1].asFloat()); } else { assert kind() == Kind.Double; - return Constant.forDouble(x().asConstant().asDouble() + y().asConstant().asDouble()); + return Constant.forDouble(inputs[0].asDouble() + inputs[1].asDouble()); } } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && !y().isConstant()) { return graph().unique(new FloatAddNode(kind(), y(), x(), isStrictFP())); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; @@ -37,15 +38,15 @@ public Constant evalConst(Constant... inputs) { assert inputs.length == 2; if (kind() == Kind.Float) { - return Constant.forFloat(x().asConstant().asFloat() / y().asConstant().asFloat()); + return Constant.forFloat(inputs[0].asFloat() / inputs[1].asFloat()); } else { assert kind() == Kind.Double; - return Constant.forDouble(x().asConstant().asDouble() / y().asConstant().asDouble()); + return Constant.forDouble(inputs[0].asDouble() / inputs[1].asDouble()); } } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,8 +24,8 @@ 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.spi.*; @NodeInfo(shortName = "<") public final class FloatLessThanNode extends CompareNode { @@ -58,7 +58,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x() == y() && !unorderedIsTrue()) { return LogicConstantNode.contradiction(graph()); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; @@ -37,15 +38,15 @@ public Constant evalConst(Constant... inputs) { assert inputs.length == 2; if (kind() == Kind.Float) { - return Constant.forFloat(x().asConstant().asFloat() * y().asConstant().asFloat()); + return Constant.forFloat(inputs[0].asFloat() * inputs[1].asFloat()); } else { assert kind() == Kind.Double; - return Constant.forDouble(x().asConstant().asDouble() * y().asConstant().asDouble()); + return Constant.forDouble(inputs[0].asDouble() * inputs[1].asDouble()); } } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && !y().isConstant()) { return graph().unique(new FloatMulNode(kind(), y(), x(), isStrictFP())); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; @@ -37,15 +38,15 @@ public Constant evalConst(Constant... inputs) { assert inputs.length == 2; if (kind() == Kind.Float) { - return Constant.forFloat(x().asConstant().asFloat() % y().asConstant().asFloat()); + return Constant.forFloat(inputs[0].asFloat() % inputs[1].asFloat()); } else { assert kind() == Kind.Double; - return Constant.forDouble(x().asConstant().asDouble() % y().asConstant().asDouble()); + return Constant.forDouble(inputs[0].asDouble() % inputs[1].asDouble()); } } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; @@ -37,15 +38,15 @@ public Constant evalConst(Constant... inputs) { assert inputs.length == 2; if (kind() == Kind.Float) { - return Constant.forFloat(x().asConstant().asFloat() - y().asConstant().asFloat()); + return Constant.forFloat(inputs[0].asFloat() - inputs[1].asFloat()); } else { assert kind() == Kind.Double; - return Constant.forDouble(x().asConstant().asDouble() - y().asConstant().asDouble()); + return Constant.forDouble(inputs[0].asDouble() - inputs[1].asDouble()); } } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return ConstantNode.forFloatingKind(kind(), 0.0f, graph()); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -47,7 +48,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && !y().isConstant()) { return graph().unique(new IntegerAddNode(kind(), y(), x())); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,8 +24,8 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "|<|") @@ -54,7 +54,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return LogicConstantNode.contradiction(graph()); } else { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -25,6 +25,7 @@ import com.oracle.graal.api.code.*; 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -42,7 +43,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { long yConst = y().asConstant().asLong(); if (yConst == 0) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,8 +24,8 @@ 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.spi.*; @NodeInfo(shortName = "==") public final class IntegerEqualsNode extends CompareNode { @@ -68,7 +68,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return LogicConstantNode.tautology(graph()); } else if (x().stamp().alwaysDistinct(y().stamp())) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,8 +24,8 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "<") @@ -70,7 +70,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return LogicConstantNode.contradiction(graph()); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -25,6 +25,7 @@ import com.oracle.graal.api.code.*; 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.spi.*; @@ -42,7 +43,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && !y().isConstant()) { return graph().unique(new IntegerMulNode(kind(), y(), x())); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -25,6 +25,7 @@ import com.oracle.graal.api.code.*; 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -37,7 +38,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { long yConst = y().asConstant().asLong(); if (yConst == 0) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -47,7 +48,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return ConstantNode.forIntegerKind(kind(), 0, graph()); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes.calc; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -61,7 +63,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { return LogicConstantNode.forBoolean((x().asConstant().asLong() & y().asConstant().asLong()) == 0, graph()); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.nodes.calc; 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -60,7 +62,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { Constant constant = object().asConstant(); if (constant != null) { assert constant.getKind() == Kind.Object; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -52,7 +53,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } else if (y().isConstant()) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -71,7 +72,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant()) { return ConstantNode.forPrimitive(evalConst(x.asConstant()), graph()); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.nodes.calc; 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -61,7 +63,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant()) { return ConstantNode.forPrimitive(evalConst(x().asConstant()), graph()); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -54,7 +55,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return LogicConstantNode.tautology(graph()); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -47,7 +48,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return x(); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -47,7 +48,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().stamp() instanceof IntegerStamp && ((IntegerStamp) x().stamp()).isPositive()) { return graph().unique(new UnsignedRightShiftNode(kind(), x(), y())); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -25,6 +25,7 @@ import com.oracle.graal.api.code.*; 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -37,7 +38,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { long yConst = y().asConstant().asLong(); if (yConst == 0) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -25,6 +25,7 @@ import com.oracle.graal.api.code.*; 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -37,7 +38,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { long yConst = y().asConstant().asLong(); if (yConst == 0) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -52,7 +53,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph()); } else if (y().isConstant()) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -47,7 +48,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return ConstantNode.forIntegerKind(kind(), 0, graph()); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/SurvivingCounterNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/SurvivingCounterNode.java Thu Oct 03 18:09:21 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +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.nodes.debug; - -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; - -/** - * This is a special version of the dynamic counter node that removes itself as soon as it's the - * only usage of the associated node. This way it only increments the counter if the node is - * actually executed. - */ -public class SurvivingCounterNode extends DynamicCounterNode implements Simplifiable, Virtualizable { - - @Input private ValueNode checkedValue; - - public SurvivingCounterNode(String group, String name, ValueNode increment, boolean addContext, ValueNode checkedValue) { - super(group, name, increment, addContext); - this.checkedValue = checkedValue; - } - - @Override - public void simplify(SimplifierTool tool) { - if (checkedValue instanceof FloatingNode && checkedValue.usages().count() == 1) { - tool.addToWorkList(checkedValue); - graph().removeFixed(this); - } - } - - @Override - public void virtualize(VirtualizerTool tool) { - State state = tool.getObjectState(checkedValue); - if (state != null && state.getState() == EscapeState.Virtual) { - tool.delete(); - } - } - - public static void addCounterBefore(String group, String name, long increment, boolean addContext, ValueNode checkedValue, FixedNode position) { - StructuredGraph graph = position.graph(); - SurvivingCounterNode counter = graph.add(new SurvivingCounterNode(name, group, ConstantNode.forLong(increment, graph), addContext, checkedValue)); - graph.addBeforeFixed(position, counter); - } -} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/WeakCounterNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/WeakCounterNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -0,0 +1,65 @@ +/* + * 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.nodes.debug; + +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; + +/** + * This is a special version of the dynamic counter node that removes itself as soon as it's the + * only usage of the associated node. This way it only increments the counter if the node is + * actually executed. + */ +public class WeakCounterNode extends DynamicCounterNode implements Simplifiable, Virtualizable { + + @Input private ValueNode checkedValue; + + public WeakCounterNode(String group, String name, ValueNode increment, boolean addContext, ValueNode checkedValue) { + super(group, name, increment, addContext); + this.checkedValue = checkedValue; + } + + @Override + public void simplify(SimplifierTool tool) { + if (checkedValue instanceof FloatingNode && checkedValue.usages().count() == 1) { + tool.addToWorkList(checkedValue); + graph().removeFixed(this); + } + } + + @Override + public void virtualize(VirtualizerTool tool) { + State state = tool.getObjectState(checkedValue); + if (state != null && state.getState() == EscapeState.Virtual) { + tool.delete(); + } + } + + public static void addCounterBefore(String group, String name, long increment, boolean addContext, ValueNode checkedValue, FixedNode position) { + StructuredGraph graph = position.graph(); + WeakCounterNode counter = graph.add(new WeakCounterNode(name, group, ConstantNode.forLong(increment, graph), addContext, checkedValue)); + graph.addBeforeFixed(position, counter); + } +} diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -69,7 +70,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x instanceof ConstantLocationNode) { return canonical((ConstantLocationNode) x, getY()); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.nodes.extended; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -58,7 +60,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { /* * Constant values are not canonicalized into their constant boxing objects because this * would mean that the information that they came from a valueOf is lost. diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.nodes.extended; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -64,7 +65,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (probability.isConstant()) { double probabilityValue = probability.asConstant().asDouble(); if (probabilityValue < 0.0) { diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,7 +24,9 @@ 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.PhiNode.PhiType; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -65,7 +67,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { return ReadNode.canonicalizeRead(this, location(), object(), tool, isCompressible()); } @@ -73,4 +75,25 @@ public Access asFixedNode() { return graph().add(new ReadNode(object(), nullCheckLocation(), stamp(), getGuard(), getBarrierType(), isCompressible())); } + + private static boolean isMemoryCheckPoint(Node n) { + return n instanceof MemoryCheckpoint.Single || n instanceof MemoryCheckpoint.Multi; + } + + private static boolean isMemoryPhi(Node n) { + return n instanceof PhiNode && ((PhiNode) n).type() == PhiType.Memory; + } + + private static boolean isMemoryProxy(Node n) { + return n instanceof ProxyNode && ((ProxyNode) n).type() == PhiType.Memory; + } + + @Override + public boolean verify() { + Node lla = lastLocationAccess(); + if (lla != null && !(isMemoryCheckPoint(lla) || isMemoryPhi(lla) || isMemoryProxy(lla))) { + assert false : "lastLocationAccess of " + this + " should be a MemoryCheckpoint, but is " + lla; + } + return super.verify(); + } } diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -85,7 +86,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (index == null || indexScaling == 0) { return ConstantLocationNode.create(getLocationIdentity(), getValueKind(), displacement, graph()); } else if (index.isConstant()) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -25,6 +25,7 @@ import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ResolvedJavaType.Representation; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -65,7 +67,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { MetaAccessProvider runtime = tool.runtime(); if (runtime != null && object.stamp() instanceof ObjectStamp) { ObjectStamp stamp = (ObjectStamp) object.stamp(); diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.nodes.extended; 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -41,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())); @@ -60,7 +50,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { return canonicalizeRead(this, location(), object(), tool, isCompressible()); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -26,6 +26,7 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -80,7 +81,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (valueKind.isConstant() && locationIdentity.isConstant() && displacement.isConstant() && (indexScaling == null || indexScaling.isConstant())) { Kind constKind = (Kind) valueKind.asConstant().asObject(); LocationIdentity constLocation = (LocationIdentity) locationIdentity.asConstant().asObject(); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.nodes.extended; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -61,7 +63,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (value.isConstant()) { Constant constant = value.asConstant(); Object o = constant.asObject(); diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,34 +23,35 @@ package com.oracle.graal.nodes.extended; 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.spi.*; import com.oracle.graal.nodes.type.*; public abstract class UnsafeAccessNode extends FixedWithNextNode implements Canonicalizable { @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; } @@ -60,14 +61,14 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { - if (offset().isConstant()) { + public Node canonical(CanonicalizerTool tool) { + 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. @@ -75,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 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -58,7 +59,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { assert kind() == Kind.Object && object.kind() == Kind.Object; ObjectStamp my = (ObjectStamp) stamp(); diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Wed Oct 09 15:33:36 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 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Wed Oct 09 15:33:36 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 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.nodes.extended; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -30,7 +31,7 @@ /** * The ValueAnchor instruction keeps non-CFG (floating) nodes above a certain point in the graph. */ -public final class ValueAnchorNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, IterableNodeType, Virtualizable, GuardingNode { +public final class ValueAnchorNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, Virtualizable, GuardingNode { @Input private ValueNode anchored; @@ -49,7 +50,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (anchored != null && !anchored.isConstant() && !(anchored instanceof FixedNode)) { // Found entry that needs this anchor. return this; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes.java; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -75,7 +77,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (usages().isEmpty()) { Stamp stamp = length.stamp(); if (stamp instanceof IntegerStamp && ((IntegerStamp) stamp).isPositive()) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.nodes.java; 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -44,7 +46,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { ValueNode length = readArrayLength(array(), tool.runtime()); if (length != null) { return length; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.nodes.java; 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -68,7 +70,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { assert object() != null : this; if (ObjectStamp.isObjectAlwaysNull(object())) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -135,7 +136,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { assert object() != null : this; ResolvedJavaType objectType = ObjectStamp.typeOrNull(object()); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -25,8 +25,9 @@ import java.lang.reflect.*; 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.spi.*; import com.oracle.graal.nodes.type.*; /** @@ -51,7 +52,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (elementType.isConstant()) { Class elementClass = (Class) elementType.asConstant().asObject(); if (elementClass != null && !(elementClass.equals(void.class))) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.api.code.*; 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.*; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.nodes.java; 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -55,7 +57,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { assert object() != null : this; if (mirror().isConstant()) { Class clazz = (Class) mirror().asConstant().asObject(); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.nodes.java; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -56,7 +58,7 @@ } @Override - public LogicNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { Stamp stamp = object().stamp(); if (!(stamp instanceof ObjectStamp)) { return this; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -36,7 +37,7 @@ * The {@code LoadFieldNode} represents a read of a static or instance field. */ @NodeInfo(nameTemplate = "LoadField#{p#field/s}") -public final class LoadFieldNode extends AccessFieldNode implements Canonicalizable, IterableNodeType, VirtualizableRoot { +public final class LoadFieldNode extends AccessFieldNode implements Canonicalizable, VirtualizableRoot { /** * Creates a new LoadFieldNode instance. @@ -58,7 +59,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { MetaAccessProvider runtime = tool.runtime(); if (tool.canonicalizeReads() && runtime != null) { ConstantNode constant = asConstant(runtime); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.java; 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.*; @@ -31,7 +30,7 @@ /** * The {@code LoadIndexedNode} represents a read from an element of an array. */ -public final class LoadIndexedNode extends AccessIndexedNode implements IterableNodeType, Virtualizable { +public final class LoadIndexedNode extends AccessIndexedNode implements Virtualizable { /** * Creates a new LoadIndexedNode. diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -26,8 +26,8 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; public class MethodCallTargetNode extends CallTargetNode implements IterableNodeType, Canonicalizable { @@ -125,7 +125,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (!isStatic()) { ValueNode receiver = receiver(); if (receiver != null && ObjectStamp.isExactType(receiver) && ObjectStamp.typeOrNull(receiver) != null) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -68,7 +69,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (usages().isEmpty()) { return null; } else { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,8 @@ import com.oracle.graal.api.code.*; 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -55,7 +57,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (!(object.stamp() instanceof ObjectStamp)) { return this; } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ResolvedJavaType.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Canonicalizable.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Canonicalizable.java Thu Oct 03 18:09:21 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.nodes.spi; - -import com.oracle.graal.nodes.*; - -public interface Canonicalizable { - - ValueNode canonical(CanonicalizerTool tool); -} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/CanonicalizerTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/CanonicalizerTool.java Thu Oct 03 18:09:21 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.nodes.spi; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; - -public interface CanonicalizerTool { - - Assumptions assumptions(); - - MetaAccessProvider runtime(); - - boolean canonicalizeReads(); - - void removeIfUnused(Node node); -} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Simplifiable.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Simplifiable.java Thu Oct 03 18:09:21 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.nodes.spi; - -/** - * This interface allows nodes to perform more complicated simplifications, in contrast to - * {@link Canonicalizable}, which supports only replacing the current node. - * - * Implementors of this interface need to be aware that they need to call - * {@link SimplifierTool#addToWorkList(com.oracle.graal.graph.Node)} for each node that might be - * influenced (in terms of simplification and canonicalization) by the actions performed in - * simplify. - */ -public interface Simplifiable { - - void simplify(SimplifierTool tool); -} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/SimplifierTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/SimplifierTool.java Thu Oct 03 18:09:21 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.nodes.spi; - -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; - -/** - * @see Simplifiable - */ -public interface SimplifierTool extends CanonicalizerTool { - - void deleteBranch(FixedNode branch); - - /** - * Adds a node to the worklist independent of whether it has already been on the worklist. - */ - void addToWorkList(Node node); -} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java Wed Oct 09 15:33:36 2013 +0200 @@ -92,12 +92,6 @@ } @Override - public boolean alwaysDistinct(Stamp otherStamp) { - FloatStamp other = (FloatStamp) otherStamp; - return (nonNaN || other.nonNaN) && (lowerBound > other.upperBound || upperBound < other.lowerBound); - } - - @Override public Stamp meet(Stamp otherStamp) { if (otherStamp == this) { return this; @@ -183,4 +177,16 @@ return true; } + @Override + public Constant asConstant() { + if (nonNaN && lowerBound == upperBound) { + switch (kind()) { + case Float: + return Constant.forFloat((float) lowerBound); + case Double: + return Constant.forDouble(lowerBound); + } + } + return null; + } } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java Wed Oct 09 15:33:36 2013 +0200 @@ -40,11 +40,6 @@ } @Override - public boolean alwaysDistinct(Stamp other) { - return true; - } - - @Override public Stamp meet(Stamp other) { return other; } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java Wed Oct 09 15:33:36 2013 +0200 @@ -145,21 +145,6 @@ return str.toString(); } - @Override - public boolean alwaysDistinct(Stamp otherStamp) { - IntegerStamp other = (IntegerStamp) otherStamp; - if (lowerBound > other.upperBound || upperBound < other.lowerBound) { - return true; - } else if ((upMask & other.upMask) == 0 && (lowerBound > 0 || upperBound < 0 || other.lowerBound > 0 || other.upperBound < 0)) { - /* - * Zero is the only common value if the masks don't overlap. If one of the two values is - * less than or greater than zero, they are always distinct. - */ - return true; - } - return false; - } - private Stamp createStamp(IntegerStamp other, long newUpperBound, long newLowerBound, long newDownMask, long newUpMask) { assert kind() == other.kind(); if (newLowerBound > newUpperBound || (newDownMask & (~newUpMask)) != 0) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Wed Oct 09 15:33:36 2013 +0200 @@ -43,7 +43,7 @@ } }; - public static void killCFG(FixedNode node) { + public static void killCFG(Node node) { assert node.isAlive(); if (node instanceof AbstractEndNode) { // We reached a control flow end. @@ -58,7 +58,7 @@ * while processing one branch. */ for (Node successor : node.successors()) { - killCFG((FixedNode) successor); + killCFG(successor); } } propagateKill(node); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -26,6 +26,7 @@ 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.spi.*; import com.oracle.graal.nodes.type.*; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/EscapeObjectState.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/EscapeObjectState.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/EscapeObjectState.java Wed Oct 09 15:33:36 2013 +0200 @@ -22,10 +22,9 @@ */ package com.oracle.graal.nodes.virtual; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -public abstract class EscapeObjectState extends VirtualState implements IterableNodeType { +public abstract class EscapeObjectState extends VirtualState { @Input private VirtualObjectNode object; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Wed Oct 09 15:33:36 2013 +0200 @@ -29,9 +29,9 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Graph.NodeChangedListener; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; @@ -53,7 +53,7 @@ public interface CustomCanonicalizer { - ValueNode canonicalize(ValueNode node); + Node canonicalize(Node node); } public CanonicalizerPhase(boolean canonicalizeReads) { @@ -179,13 +179,14 @@ if (node.isAlive()) { METRIC_PROCESSED_NODES.increment(); - if (tryGlobalValueNumbering(node)) { + NodeClass nodeClass = node.getNodeClass(); + if (tryGlobalValueNumbering(node, nodeClass)) { return; } StructuredGraph graph = (StructuredGraph) node.graph(); int mark = graph.getMark(); if (!tryKillUnused(node)) { - if (!tryCanonicalize(node)) { + if (!tryCanonicalize(node, nodeClass)) { if (node instanceof ValueNode) { ValueNode valueNode = (ValueNode) node; boolean improvedStamp = tryInferStamp(valueNode); @@ -194,7 +195,7 @@ performReplacement(valueNode, ConstantNode.forConstant(constant, runtime, valueNode.graph())); } else if (improvedStamp) { // the improved stamp may enable additional canonicalization - tryCanonicalize(valueNode); + tryCanonicalize(valueNode, nodeClass); } } } @@ -214,8 +215,7 @@ return false; } - public static boolean tryGlobalValueNumbering(Node node) { - NodeClass nodeClass = node.getNodeClass(); + public static boolean tryGlobalValueNumbering(Node node, NodeClass nodeClass) { if (nodeClass.valueNumberable() && !nodeClass.isLeafNode()) { Node newNode = node.graph().findDuplicate(node); if (newNode != null) { @@ -230,34 +230,33 @@ return false; } - public boolean tryCanonicalize(final Node node) { - boolean result = baseTryCanonicalize(node); - if (!result && customCanonicalizer != null && node instanceof ValueNode) { - ValueNode valueNode = (ValueNode) node; - ValueNode canonical = customCanonicalizer.canonicalize(valueNode); + public boolean tryCanonicalize(final Node node, NodeClass nodeClass) { + boolean result = baseTryCanonicalize(node, nodeClass); + if (!result && customCanonicalizer != null) { + Node canonical = customCanonicalizer.canonicalize(node); result = performReplacement(node, canonical); } return result; } - public boolean baseTryCanonicalize(final Node node) { - if (node instanceof Canonicalizable) { - assert !(node instanceof Simplifiable); + public boolean baseTryCanonicalize(final Node node, NodeClass nodeClass) { + if (nodeClass.isCanonicalizable()) { + assert !nodeClass.isSimplifiable(); METRIC_CANONICALIZATION_CONSIDERED_NODES.increment(); return Debug.scope("CanonicalizeNode", node, new Callable() { public Boolean call() { - ValueNode canonical = ((Canonicalizable) node).canonical(tool); + Node canonical = node.canonical(tool); return performReplacement(node, canonical); } }); - } else if (node instanceof Simplifiable) { + } else if (nodeClass.isSimplifiable()) { Debug.log("Canonicalizer: simplifying %s", node); METRIC_SIMPLIFICATION_CONSIDERED_NODES.increment(); Debug.scope("SimplifyNode", node, new Runnable() { public void run() { - ((Simplifiable) node).simplify(tool); + node.simplify(tool); } }); } @@ -280,7 +279,7 @@ // -------------------------------------------- // X: must not happen (checked with assertions) // @formatter:on - private boolean performReplacement(final Node node, ValueNode canonical) { + private boolean performReplacement(final Node node, Node canonical) { if (canonical == node) { Debug.log("Canonicalizer: work on %s", node); return false; @@ -362,7 +361,7 @@ private final class Tool implements SimplifierTool { @Override - public void deleteBranch(FixedNode branch) { + public void deleteBranch(Node branch) { branch.predecessor().replaceFirstSuccessor(branch, null); GraphUtil.killCFG(branch); } diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Wed Oct 09 15:33:36 2013 +0200 @@ -1363,6 +1363,13 @@ } else { invokeWithException.killExceptionEdge(); } + + // get rid of memory kill + AbstractBeginNode begin = invokeWithException.next(); + if (begin instanceof KillingBeginNode) { + graph.addAfterFixed(begin, graph.add(new BeginNode())); + graph.removeFixed(begin); + } } else { if (unwindNode != null) { UnwindNode unwindDuplicate = (UnwindNode) duplicates.get(unwindNode); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,8 +24,8 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.util.*; import com.oracle.graal.phases.tiers.*; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/PhiStampPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/PhiStampPhase.java Thu Oct 03 18:09:21 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2011, 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.phases.common; - -import com.oracle.graal.nodes.*; -import com.oracle.graal.phases.*; - -public class PhiStampPhase extends Phase { - - @Override - protected void run(StructuredGraph graph) { - // Infer phis stopping at loop phis. - for (PhiNode phi : graph.getNodes(PhiNode.class)) { - inferPhi(phi); - } - - // Start iterative inference for loop phis. - if (graph.hasLoops()) { - for (PhiNode phi : graph.getNodes(PhiNode.class)) { - if (phi.isLoopPhi()) { - iterativeInferPhi(phi); - } - } - } - } - - private void iterativeInferPhi(PhiNode phi) { - if (phi.inferPhiStamp()) { - for (PhiNode phiUsage : phi.usages().filter(PhiNode.class)) { - iterativeInferPhi(phiUsage); - } - } - } - - private void inferPhi(PhiNode phi) { - for (PhiNode phiInput : phi.values().filter(PhiNode.class)) { - if (!phiInput.isLoopPhi()) { - inferPhi(phiInput); - } - } - phi.inferPhiStamp(); - } -} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Wed Oct 09 15:33:36 2013 +0200 @@ -36,6 +36,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; +import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.tiers.*; @@ -172,6 +173,9 @@ int fixedCount = 0; while (fixed instanceof FixedWithNextNode) { fixed = ((FixedWithNextNode) fixed).next(); + if (fixed instanceof CommitAllocationNode) { + return false; + } fixedCount++; } if (fixedCount > 1) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Wed Oct 09 15:33:36 2013 +0200 @@ -70,8 +70,6 @@ @Option(help = "") public static final OptionValue PartialEscapeAnalysis = new OptionValue<>(true); @Option(help = "") - public static final OptionValue EscapeAnalysisHistogram = new OptionValue<>(false); - @Option(help = "") public static final OptionValue EscapeAnalysisIterations = new OptionValue<>(2); @Option(help = "") public static final OptionValue EscapeAnalyzeOnly = new OptionValue<>(null); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Wed Oct 09 15:33:36 2013 +0200 @@ -33,6 +33,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.Verbosity; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.extended.*; @@ -99,7 +100,7 @@ @Override protected HashSet processBlock(Block block, HashSet currentState) { - for (Node node : getBlockToNodesMap().get(block)) { + for (Node node : blockToNodesMap.get(block)) { if (node instanceof FloatingReadNode) { currentState.add((FloatingReadNode) node); } else if (node instanceof MemoryCheckpoint.Single) { @@ -183,37 +184,49 @@ @Override protected Map processBlock(Block block, Map currentState) { - Map initKillMap = getBlockToKillMap().get(block); - initKillMap.putAll(currentState); + + if (block.getBeginNode() instanceof MergeNode) { + MergeNode mergeNode = (MergeNode) block.getBeginNode(); + for (PhiNode phi : mergeNode.usages().filter(PhiNode.class)) { + if (phi.type() == PhiType.Memory) { + LocationIdentity identity = (LocationIdentity) phi.getIdentity(); + locationKilledBy(identity, phi, currentState); + } + } + } + currentState.putAll(blockToKillMapInit.get(block)); for (Node node : block.getNodes()) { if (node instanceof MemoryCheckpoint.Single) { LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity(); - initKillMap.put(identity, node); + locationKilledBy(identity, node, currentState); } else if (node instanceof MemoryCheckpoint.Multi) { for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getLocationIdentities()) { - initKillMap.put(identity, node); + locationKilledBy(identity, node, currentState); } } assert MemoryCheckpoint.TypeAssertion.correctType(node); } - return cloneState(initKillMap); + blockToKillMap.put(block, currentState); + return cloneState(currentState); + } + + private void locationKilledBy(LocationIdentity identity, Node checkpoint, Map state) { + state.put(identity, checkpoint); + if (identity == ANY_LOCATION) { + for (LocationIdentity locid : state.keySet()) { + state.put(locid, checkpoint); + } + } } @Override protected Map merge(Block merge, List> states) { - return merge(merge, states, false); - } - - protected Map merge(Block merge, List> states, boolean loopbegin) { assert merge.getBeginNode() instanceof MergeNode; MergeNode mergeNode = (MergeNode) merge.getBeginNode(); Map initKillMap = new HashMap<>(); - if (loopbegin) { - initKillMap.putAll(getBlockToKillMap().get(merge)); - } for (Map state : states) { for (LocationIdentity locid : state.keySet()) { if (initKillMap.containsKey(locid)) { @@ -226,10 +239,7 @@ } } - getMergeToKillMap().set(mergeNode, cloneState(initKillMap)); - if (!loopbegin) { - initKillMap.putAll(getBlockToKillMap().get(merge)); - } + mergeToKillMap.set(mergeNode, cloneState(initKillMap)); return initKillMap; } @@ -240,18 +250,27 @@ @Override protected List> processLoop(Loop loop, Map state) { - LoopInfo> info = ReentrantBlockIterator.processLoop(this, loop, new HashMap<>(state)); + LoopInfo> info = ReentrantBlockIterator.processLoop(this, loop, cloneState(state)); assert loop.header.getBeginNode() instanceof LoopBeginNode; - Map headerState = merge(loop.header, info.endStates, true); - getBlockToKillMap().put(loop.header, headerState); + Map headerState = merge(loop.header, info.endStates); + // second iteration, for computing information at loop exits + info = ReentrantBlockIterator.processLoop(this, loop, cloneState(headerState)); + + int i = 0; + for (Block exit : loop.exits) { + Map exitState = info.exitStates.get(i++); - for (Map exitState : info.exitStates) { - for (LocationIdentity key : headerState.keySet()) { - exitState.put(key, headerState.get(key)); + Node begin = exit.getBeginNode(); + assert begin instanceof LoopExitNode; + for (Node usage : begin.usages()) { + if (usage instanceof ProxyNode && ((ProxyNode) usage).type() == PhiType.Memory) { + ProxyNode proxy = (ProxyNode) usage; + LocationIdentity identity = (LocationIdentity) proxy.getIdentity(); + locationKilledBy(identity, proxy, exitState); + } } } - return info.exitStates; } } @@ -263,6 +282,7 @@ * Map from blocks to the nodes in each block. */ private BlockMap> blockToNodesMap; + private BlockMap> blockToKillMapInit; private BlockMap> blockToKillMap; private NodeMap> mergeToKillMap; private final Map> phantomUsages = new IdentityHashMap<>(); @@ -315,8 +335,10 @@ } else if (memsched == MemoryScheduling.OPTIMAL && selectedStrategy != SchedulingStrategy.EARLIEST && graph.getNodes(FloatingReadNode.class).isNotEmpty()) { mergeToKillMap = graph.createNodeMap(); + blockToKillMapInit = new BlockMap<>(cfg); blockToKillMap = new BlockMap<>(cfg); for (Block b : cfg.getBlocks()) { + blockToKillMapInit.put(b, new HashMap()); blockToKillMap.put(b, new HashMap()); } @@ -328,7 +350,7 @@ Node first = n.lastLocationAccess(); assert first != null; - Map killMap = blockToKillMap.get(forKillLocation(first)); + Map killMap = blockToKillMapInit.get(forKillLocation(first)); killMap.put(n.location().getLocationIdentity(), first); } @@ -357,20 +379,27 @@ private void printSchedule(String desc) { Debug.printf("=== %s / %s / %s (%s) ===\n", getCFG().getStartBlock().getBeginNode().graph(), selectedStrategy, memsched, desc); for (Block b : getCFG().getBlocks()) { - Debug.printf("==== b: %s. ", b); + Debug.printf("==== b: %s (loopDepth: %s). ", b, b.getLoopDepth()); Debug.printf("dom: %s. ", b.getDominator()); Debug.printf("post-dom: %s. ", b.getPostdominator()); Debug.printf("preds: %s. ", b.getPredecessors()); Debug.printf("succs: %s ====\n", b.getSuccessors()); - BlockMap> killMaps = getBlockToKillMap(); + BlockMap> killMaps = blockToKillMap; if (killMaps != null) { + if (b.getBeginNode() instanceof MergeNode) { + MergeNode merge = (MergeNode) b.getBeginNode(); + Debug.printf("M merge kills: \n"); + for (LocationIdentity locId : mergeToKillMap.get(merge).keySet()) { + Debug.printf("M %s killed by %s\n", locId, mergeToKillMap.get(merge).get(locId)); + } + } Debug.printf("X block kills: \n"); for (LocationIdentity locId : killMaps.get(b).keySet()) { Debug.printf("X %s killed by %s\n", locId, killMaps.get(b).get(locId)); } } - if (getBlockToNodesMap().get(b) != null) { + if (blockToNodesMap.get(b) != null) { for (Node n : nodesFor(b)) { printNode(n); } @@ -414,14 +443,6 @@ return blockToNodesMap; } - public BlockMap> getBlockToKillMap() { - return blockToKillMap; - } - - public NodeMap> getMergeToKillMap() { - return mergeToKillMap; - } - /** * Gets the nodes in a given block. */ @@ -465,10 +486,11 @@ throw new SchedulingError("%s should already have been placed in a block", node); } + Block earliestBlock = earliestBlock(node); Block block; switch (strategy) { case EARLIEST: - block = earliestBlock(node); + block = earliestBlock; break; case LATEST: case LATEST_OUT_OF_LOOPS: @@ -477,23 +499,19 @@ } else { block = latestBlock(node, strategy); if (block == null) { - block = earliestBlock(node); + block = earliestBlock; } else if (strategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS && !(node instanceof VirtualObjectNode)) { // schedule at the latest position possible in the outermost loop possible - Block earliestBlock = earliestBlock(node); - Block before = block; block = scheduleOutOfLoops(node, block, earliestBlock); - if (!earliestBlock.dominates(block)) { - throw new SchedulingError("%s: Graph cannot be scheduled : inconsistent for %s, %d usages, (%s needs to dominate %s (before %s))", node.graph(), node, - node.usages().count(), earliestBlock, block, before); - } } } break; default: throw new GraalInternalError("unknown scheduling strategy"); } - assert earliestBlock(node).dominates(block) : "node " + node + " in block " + block + " is not dominated by earliest " + earliestBlock(node); + if (!earliestBlock.dominates(block)) { + throw new SchedulingError("%s: Graph cannot be scheduled : inconsistent for %s, %d usages, (%s needs to dominate %s)", node.graph(), node, node.usages().count(), earliestBlock, block); + } cfg.getNodeToBlock().set(node, block); blockToNodesMap.get(block).add(node); } @@ -541,9 +559,8 @@ // iterate the dominator tree while (true) { iterations++; - assert earliestBlock.dominates(previousBlock) : "iterations: " + iterations; Node lastKill = blockToKillMap.get(currentBlock).get(locid); - boolean isAtEarliest = earliestBlock == previousBlock && previousBlock != currentBlock; + assert lastKill != null : "should be never null, due to init of killMaps: " + currentBlock + ", location: " + locid; if (lastKill.equals(upperBound)) { // assign node to the block which kills the location @@ -553,7 +570,6 @@ // schedule read out of the loop if possible, in terms of killMaps and earliest // schedule if (currentBlock != earliestBlock && previousBlock != earliestBlock) { - assert earliestBlock.dominates(currentBlock); Block t = currentBlock; while (t.getLoop() != null && t.getDominator() != null && earliestBlock.dominates(t)) { Block dom = t.getDominator(); @@ -568,17 +584,12 @@ if (!outOfLoop && previousBlock.getBeginNode() instanceof MergeNode) { // merges kill locations right at the beginning of a block. if a merge is the - // killing node, we assign it to the dominating node. + // killing node, we assign it to the dominating block. MergeNode merge = (MergeNode) previousBlock.getBeginNode(); - Node killer = getMergeToKillMap().get(merge).get(locid); + Node killer = mergeToKillMap.get(merge).get(locid); if (killer != null && killer == merge) { - // check if we violate earliest schedule condition - if (isAtEarliest) { - printIterations(iterations, "earliest bound in merge: " + earliestBlock); - return earliestBlock; - } printIterations(iterations, "kill by merge: " + currentBlock); return currentBlock; } @@ -590,11 +601,6 @@ return previousBlock; } - if (isAtEarliest) { - printIterations(iterations, "earliest bound: " + earliestBlock); - return earliestBlock; - } - if (upperBoundBlock == currentBlock) { printIterations(iterations, "upper bound: " + currentBlock + ", previous: " + previousBlock); return currentBlock; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -57,7 +57,7 @@ @Override protected StructuredGraph parse(Method m) { ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m); - return installer.makeGraph(resolvedMethod, null, inliningPolicy.get()); + return installer.makeGraph(resolvedMethod, null, inliningPolicy.get(), false); } @Test diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -61,7 +61,7 @@ @Override protected StructuredGraph parse(Method m) { ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m); - return installer.makeGraph(resolvedMethod, null, inliningPolicy.get()); + return installer.makeGraph(resolvedMethod, null, inliningPolicy.get(), false); } @Test diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -350,6 +350,7 @@ // Math.pow(value, 13); } + @Ignore @Test public void testIntegerSubstitutions() { assertInGraph(test("integerReverseBytes"), ReverseBytesNode.class); // Java @@ -385,6 +386,7 @@ return Integer.bitCount(value); } + @Ignore @Test public void testLongSubstitutions() { assertInGraph(test("longReverseBytes"), ReverseBytesNode.class); // Java diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -51,7 +51,7 @@ @Override protected StructuredGraph parse(Method m) { ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m); - return installer.makeGraph(resolvedMethod, null, inliningPolicy.get()); + return installer.makeGraph(resolvedMethod, null, inliningPolicy.get(), false); } @LongTest diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java Wed Oct 09 15:33:36 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 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Wed Oct 09 15:33:36 2013 +0200 @@ -84,7 +84,7 @@ StructuredGraph graph = graphs.get(method); if (graph == null) { - graphs.putIfAbsent(method, makeGraph(method, null, inliningPolicy(method))); + graphs.putIfAbsent(method, makeGraph(method, null, inliningPolicy(method), method.getAnnotation(Snippet.class).removeAllFrameStates())); graph = graphs.get(method); } return graph; @@ -97,7 +97,7 @@ } StructuredGraph graph = graphs.get(substitute); if (graph == null) { - graphs.putIfAbsent(substitute, makeGraph(substitute, original, inliningPolicy(substitute))); + graphs.putIfAbsent(substitute, makeGraph(substitute, original, inliningPolicy(substitute), false)); graph = graphs.get(substitute); } return graph; @@ -221,9 +221,10 @@ * @param original the original method if {@code method} is a {@linkplain MethodSubstitution * substitution} otherwise null * @param policy the inlining policy to use during preprocessing + * @param removeAllFrameStates removes all frame states from side effecting instructions */ - public StructuredGraph makeGraph(ResolvedJavaMethod method, ResolvedJavaMethod original, SnippetInliningPolicy policy) { - return createGraphMaker(method, original).makeGraph(policy); + public StructuredGraph makeGraph(ResolvedJavaMethod method, ResolvedJavaMethod original, SnippetInliningPolicy policy, boolean removeAllFrameStates) { + return createGraphMaker(method, original).makeGraph(policy, removeAllFrameStates); } /** @@ -261,7 +262,7 @@ this.original = original; } - public StructuredGraph makeGraph(final SnippetInliningPolicy policy) { + public StructuredGraph makeGraph(final SnippetInliningPolicy policy, final boolean removeAllFrameStates) { return Debug.scope("BuildSnippetGraph", new Object[]{method}, new Callable() { @Override @@ -271,7 +272,7 @@ // Cannot have a finalized version of a graph in the cache graph = graph.copy(); - finalizeGraph(graph); + finalizeGraph(graph, removeAllFrameStates); Debug.dump(graph, "%s: Final", method.getName()); @@ -283,7 +284,7 @@ /** * Does final processing of a snippet graph. */ - protected void finalizeGraph(StructuredGraph graph) { + protected void finalizeGraph(StructuredGraph graph, boolean removeAllFrameStates) { new NodeIntrinsificationPhase(runtime).apply(graph); if (!SnippetTemplate.hasConstantParameter(method)) { NodeIntrinsificationVerificationPhase.verify(graph); @@ -291,7 +292,15 @@ new ConvertDeoptimizeToGuardPhase().apply(graph); if (original == null) { - new SnippetFrameStateCleanupPhase().apply(graph); + if (removeAllFrameStates) { + for (Node node : graph.getNodes()) { + if (node instanceof StateSplit) { + ((StateSplit) node).setStateAfter(null); + } + } + } else { + new SnippetFrameStateCleanupPhase().apply(graph); + } } new DeadCodeEliminationPhase().apply(graph); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Snippet.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Snippet.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Snippet.java Wed Oct 09 15:33:36 2013 +0200 @@ -45,6 +45,13 @@ Class inlining() default SnippetInliningPolicy.class; /** + * Specifies whether all FrameStates within this snippet should always be removed. If this is + * false, FrameStates are only removed if there are no side-effecting instructions in the + * snippet. + */ + boolean removeAllFrameStates() default false; + + /** * Guides inlining decisions used when installing a snippet. */ public interface SnippetInliningPolicy { diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsafeSubstitutions.java Wed Oct 09 15:33:36 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 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -25,10 +25,11 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; public class BitCountNode extends FloatingNode implements LIRGenLowerable, Canonicalizable { @@ -41,7 +42,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (value.isConstant()) { long v = value.asConstant().asLong(); if (value.kind().getStackKind() == Kind.Int) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -25,10 +25,11 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; public class BitScanForwardNode extends FloatingNode implements LIRGenLowerable, Canonicalizable { @@ -41,7 +42,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (value.isConstant()) { long v = value.asConstant().asLong(); if (value.kind().getStackKind() == Kind.Int) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -25,10 +25,11 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; public class BitScanReverseNode extends FloatingNode implements LIRGenLowerable, Canonicalizable { @@ -41,7 +42,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (value.isConstant()) { long v = value.asConstant().asLong(); if (value.kind().getStackKind() == Kind.Int) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -22,8 +22,9 @@ */ package com.oracle.graal.replacements.nodes; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.replacements.Snippet.*; @@ -43,7 +44,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (index.isConstant()) { return locals[index.asConstant().asInt()]; } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -91,7 +92,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant()) { return ConstantNode.forPrimitive(evalConst(x().asConstant()), graph()); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,8 +23,9 @@ package com.oracle.graal.replacements.nodes; 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.spi.*; /** * This node class can be used to create {@link MacroNode}s for simple pure functions like @@ -42,7 +43,8 @@ */ protected abstract Constant evaluate(Constant param, MetaAccessProvider metaAccess); - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { if (usages().isEmpty()) { return null; } else { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -25,10 +25,11 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; public class ReverseBytesNode extends FloatingNode implements LIRGenLowerable, Canonicalizable { @@ -42,7 +43,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (value.isConstant()) { long v = value.asConstant().asLong(); if (kind().getStackKind() == Kind.Int) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/AbstractTestNode.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/AbstractTestNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/AbstractTestNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -27,5 +27,9 @@ public abstract class AbstractTestNode extends Node { + protected AbstractTestNode() { + super(null); + } + public abstract int execute(VirtualFrame frame); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/RootTestNode.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/RootTestNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/RootTestNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -31,6 +31,7 @@ @Child AbstractTestNode node; public RootTestNode(String name, AbstractTestNode node) { + super(null); this.name = name; this.node = node; } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java Wed Oct 09 15:33:36 2013 +0200 @@ -57,7 +57,7 @@ @Override public T getArguments(Class clazz) { - return CompilerDirectives.unsafeCast(arguments, clazz); + return CompilerDirectives.unsafeCast(arguments, clazz, true); } @Override diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Wed Oct 09 15:33:36 2013 +0200 @@ -69,6 +69,11 @@ } @Override + public VirtualFrame createVirtualFrame(PackedFrame caller, Arguments arguments, FrameDescriptor frameDescriptor) { + return OptimizedCallTarget.createFrame(frameDescriptor, caller, arguments); + } + + @Override public MaterializedFrame createMaterializedFrame(Arguments arguments) { return createMaterializedFrame(arguments); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Wed Oct 09 15:33:36 2013 +0200 @@ -166,7 +166,7 @@ return rootNode.execute(frame); } - private static FrameWithoutBoxing createFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments args) { + protected static FrameWithoutBoxing createFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments args) { return new FrameWithoutBoxing(descriptor, caller, args); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Wed Oct 09 15:33:36 2013 +0200 @@ -35,6 +35,7 @@ import com.oracle.graal.debug.internal.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.java.*; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java Wed Oct 09 15:33:36 2013 +0200 @@ -27,6 +27,7 @@ import sun.misc.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.Node; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.common.*; @@ -42,7 +43,7 @@ } @Override - public ValueNode canonicalize(ValueNode node) { + public Node canonicalize(Node node) { if (node instanceof LoadFieldNode) { LoadFieldNode loadFieldNode = (LoadFieldNode) node; if (!loadFieldNode.isStatic() && loadFieldNode.object().isConstant() && !loadFieldNode.object().isNullConstant()) { diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Wed Oct 09 15:33:36 2013 +0200 @@ -33,6 +33,7 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; @@ -172,6 +173,8 @@ // Convert deopt to guards. new ConvertDeoptimizeToGuardPhase().apply(graph); + new EarlyReadEliminationPhase(canonicalizerPhase).apply(graph, context); + if (!inliningProgress) { break; } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,8 +23,8 @@ package com.oracle.graal.truffle.nodes; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.truffle.*; @@ -39,6 +39,7 @@ return arguments.first(); } + @Override public void simplify(SimplifierTool tool) { ValueNode assumption = getAssumption(); if (tool.assumptions() != null && assumption.isConstant()) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,8 +23,9 @@ package com.oracle.graal.truffle.nodes; import com.oracle.graal.api.code.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.nodes.*; public class BailoutNode extends MacroNode implements Canonicalizable { @@ -35,7 +36,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { ValueNode arg = arguments.get(0); String message = ""; if (arg.isConstant()) { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -27,6 +27,8 @@ import sun.misc.*; 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.java.*; import com.oracle.graal.nodes.spi.*; @@ -49,7 +51,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (array().isConstant() && !array().isNullConstant() && index().isConstant()) { Object array = array().asConstant().asObject(); long index = index().asConstant().asLong(); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.truffle.nodes.arithmetic; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -47,7 +49,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && !y().isConstant()) { return graph().unique(new IntegerAddExactNode(y(), x())); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.truffle.nodes.arithmetic; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -40,7 +42,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && !y().isConstant()) { return graph().unique(new IntegerMulExactNode(y(), x())); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.truffle.nodes.arithmetic; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; @@ -47,7 +49,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (x() == y()) { return ConstantNode.forIntegerKind(kind(), 0, graph()); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/CompilationConstantNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/CompilationConstantNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/CompilationConstantNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -22,8 +22,9 @@ */ package com.oracle.graal.truffle.nodes.asserts; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; public class CompilationConstantNode extends NeverPartOfCompilationNode implements Canonicalizable { @@ -33,7 +34,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (arguments.get(0).isConstant()) { return arguments.get(0); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -26,6 +26,7 @@ import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java Wed Oct 09 15:33:36 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 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; @@ -205,7 +206,7 @@ } @Override - public ValueNode canonical(CanonicalizerTool tool) { + public Node canonical(CanonicalizerTool tool) { if (usages().isEmpty()) { return null; } else { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckMacroNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckMacroNode.java Thu Oct 03 18:09:21 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +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.truffle.nodes.typesystem; - -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.truffle.nodes.asserts.*; -import com.oracle.truffle.api.*; - -/** - * Macro node for method {@link CompilerDirectives#customTypeCheck(boolean, Object, Object)}. - */ -public class CustomTypeCheckMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { - - private static final int ARGUMENT_COUNT = 3; - private static final int CONDITION_ARGUMENT_INDEX = 0; - private static final int OBJECT_ARGUMENT_INDEX = 1; - private static final int CUSTOM_TYPE_ARGUMENT_INDEX = 2; - - public CustomTypeCheckMacroNode(Invoke invoke) { - super(invoke, "The custom type parameter could not be reduced to a compile time constant."); - assert arguments.size() == ARGUMENT_COUNT; - } - - @Override - public ValueNode canonical(CanonicalizerTool tool) { - ValueNode customTypeArgument = arguments.get(CUSTOM_TYPE_ARGUMENT_INDEX); - if (customTypeArgument.isConstant()) { - Object typeToken = customTypeArgument.asConstant().asObject(); - ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX); - ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX); - return graph().unique(new ConditionalNode(graph().unique(new CustomTypeCheckNode(conditionArgument, objectArgument, typeToken)))); - } - return this; - } -} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckNode.java Thu Oct 03 18:09:21 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +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.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; - -public final class CustomTypeCheckNode extends LogicNode implements Lowerable, Virtualizable, com.oracle.graal.graph.IterableNodeType { - - @Input private ValueNode condition; - @Input private ValueNode object; - private final Object customType; - - public CustomTypeCheckNode(ValueNode condition, ValueNode object, Object customType) { - this.condition = condition; - this.object = object; - this.customType = customType; - } - - public ValueNode getObject() { - return object; - } - - public ValueNode getCondition() { - return condition; - } - - public Object getCustomType() { - return customType; - } - - public void lower(LoweringTool tool) { - if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FLOATING_GUARDS) { - this.replaceAtUsages(graph().unique(new IntegerEqualsNode(condition, ConstantNode.forInt(1, graph())))); - this.safeDelete(); - } - } - - public void virtualize(VirtualizerTool tool) { - if (getObject() != null) { - State objectState = tool.getObjectState(getObject()); - if (objectState != null && objectState.getState() == EscapeState.Virtual) { - // The object is escape analyzed => cut the connection. - this.updateUsages(this.object, null); - this.object = null; - } - } - } -} diff -r 7cce548b0b60 -r df3af5e007ad 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 Wed Oct 09 15:33:36 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 7cce548b0b60 -r df3af5e007ad 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 Wed Oct 09 15:33:36 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 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastMacroNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastMacroNode.java Thu Oct 03 18:09:21 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +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.truffle.nodes.typesystem; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.truffle.nodes.asserts.*; -import com.oracle.truffle.api.*; - -/** - * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class)} and - * {@link CompilerDirectives#unsafeCast(Object, Class, Object, Object)}. - */ -public class TypeCastMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { - - private static final int ARGUMENT_COUNT = 4; - private static final int OBJECT_ARGUMENT_INDEX = 0; - private static final int CLASS_ARGUMENT_INDEX = 1; - private static final int RECEIVER_ARGUMENT_INDEX = 2; - private static final int CUSTOM_TYPE_ARGUMENT_INDEX = 3; - - public TypeCastMacroNode(Invoke invoke) { - super(invoke, "The class of the unsafe cast could not be reduced to a compile time constant."); - assert arguments.size() == ARGUMENT_COUNT; - } - - @Override - public ValueNode canonical(CanonicalizerTool tool) { - ValueNode classArgument = arguments.get(CLASS_ARGUMENT_INDEX); - ValueNode customTypeArgument = arguments.get(CUSTOM_TYPE_ARGUMENT_INDEX); - if (classArgument.isConstant() && customTypeArgument.isConstant()) { - Class c = (Class) classArgument.asConstant().asObject(); - ResolvedJavaType lookupJavaType = tool.runtime().lookupJavaType(c); - ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX); - ValueNode receiverArgument = arguments.get(RECEIVER_ARGUMENT_INDEX); - Object customType = customTypeArgument.asConstant().asObject(); - return graph().add(new TypeCastNode(objectArgument, lookupJavaType, receiverArgument, customType)); - } - return this; - } -} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastNode.java Thu Oct 03 18:09:21 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +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.nodes.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; - -public final class TypeCastNode extends FixedWithNextNode implements Lowerable, com.oracle.graal.graph.IterableNodeType, ValueProxy, Virtualizable { - - @Input private ValueNode receiver; - @Input private ValueNode object; - private final Object customType; - private final ResolvedJavaType castTarget; - - public TypeCastNode(ValueNode object, ResolvedJavaType castTarget, ValueNode receiver, Object customType) { - super(StampFactory.declaredNonNull(castTarget)); - this.receiver = receiver; - this.object = object; - this.customType = customType; - this.castTarget = castTarget; - } - - public ValueNode getObject() { - return object; - } - - public ValueNode getReceiver() { - return receiver; - } - - public ResolvedJavaType getCastTarget() { - return castTarget; - } - - public Object getCustomType() { - return customType; - } - - public void lower(LoweringTool tool) { - if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FLOATING_GUARDS) { - ValueAnchorNode valueAnchorNode = graph().add(new ValueAnchorNode(null)); - PiNode piCast = graph().unique(new PiNode(object, this.stamp(), valueAnchorNode)); - this.replaceAtUsages(piCast); - graph().replaceFixedWithFixed(this, valueAnchorNode); - } - } - - public ValueNode getOriginalValue() { - return object; - } - - @Override - public void virtualize(VirtualizerTool tool) { - State state = tool.getObjectState(object); - if (state != null && state.getState() == EscapeState.Virtual) { - tool.replaceWithVirtual(state.getVirtualObject()); - } - } -} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationMacroNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationMacroNode.java Thu Oct 03 18:09:21 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +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.truffle.nodes.typesystem; - -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.truffle.nodes.asserts.*; -import com.oracle.truffle.api.*; - -/** - * Macro node for method {@link CompilerDirectives#unsafeCustomization(Object, Object, Object)}. - */ -public class UnsafeCustomizationMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { - - private static final int ARGUMENT_COUNT = 3; - private static final int RECEIVER_ARGUMENT_INDEX = 0; - private static final int CUSTOM_TYPE_ARGUMENT_INDEX = 1; - private static final int LOCATION_IDENTITY_ARGUMENT_INDEX = 2; - - public UnsafeCustomizationMacroNode(Invoke invoke) { - super(invoke, "The custom type parameter and/or the location identity could not be reduced to a compile time constant."); - assert arguments.size() == ARGUMENT_COUNT; - } - - @Override - public ValueNode canonical(CanonicalizerTool tool) { - ValueNode customTypeArgument = this.arguments.get(CUSTOM_TYPE_ARGUMENT_INDEX); - ValueNode locationIdentityArgument = this.arguments.get(LOCATION_IDENTITY_ARGUMENT_INDEX); - if (customTypeArgument.isConstant() && locationIdentityArgument.isConstant()) { - Object customType = customTypeArgument.asConstant().asObject(); - Object locationIdentity = locationIdentityArgument.asConstant().asObject(); - ValueNode receiverArgument = this.arguments.get(RECEIVER_ARGUMENT_INDEX); - return graph().unique(new UnsafeCustomizationNode(receiverArgument, customType, locationIdentity)); - } - return this; - } -} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationNode.java Thu Oct 03 18:09:21 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +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.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; - -public final class UnsafeCustomizationNode extends FloatingNode implements LIRLowerable, com.oracle.graal.graph.IterableNodeType { - - @Input private ValueNode receiver; - private final Object customType; - private final Object locationIdentity; - - public UnsafeCustomizationNode(ValueNode receiver, Object customType, Object locationIdentity) { - super(StampFactory.object()); - this.receiver = receiver; - this.customType = customType; - this.locationIdentity = locationIdentity; - } - - public ValueNode getReceiver() { - return receiver; - } - - public Object getCustomType() { - return customType; - } - - public Object getLocationIdentity() { - return locationIdentity; - } - - public void generate(LIRGeneratorTool generator) { - generator.setResult(this, generator.operand(receiver)); - } -} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java Wed Oct 09 15:33:36 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.calc.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.truffle.nodes.asserts.*; +import com.oracle.truffle.api.*; + +/** + * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class, boolean)}. + */ +public class UnsafeTypeCastMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { + + private static final int ARGUMENT_COUNT = 3; + private static final int OBJECT_ARGUMENT_INDEX = 0; + private static final int CLASS_ARGUMENT_INDEX = 1; + private static final int CONDITION_ARGUMENT_INDEX = 2; + + public UnsafeTypeCastMacroNode(Invoke invoke) { + super(invoke, "The class of the unsafe cast could not be reduced to a compile time constant."); + assert arguments.size() == ARGUMENT_COUNT; + } + + @Override + public Node canonical(CanonicalizerTool tool) { + ValueNode classArgument = arguments.get(CLASS_ARGUMENT_INDEX); + if (classArgument.isConstant()) { + ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX); + ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX); + Class c = (Class) classArgument.asConstant().asObject(); + if (c == null) { + return objectArgument; + } + ResolvedJavaType lookupJavaType = tool.runtime().lookupJavaType(c); + ConditionAnchorNode valueAnchorNode = graph().add(new ConditionAnchorNode(CompareNode.createCompareNode(Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph())))); + UnsafeCastNode piCast = graph().unique(new UnsafeCastNode(objectArgument, StampFactory.declaredNonNull(lookupJavaType), valueAnchorNode)); + this.replaceAtUsages(piCast); + return valueAnchorNode; + } + return this; + } +} diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/ReplaceLoadFinalPhase.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/ReplaceLoadFinalPhase.java Thu Oct 03 18:09:21 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +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.truffle.phases; - -import java.lang.reflect.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.phases.*; -import com.oracle.graal.truffle.nodes.*; -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.nodes.Node.Children; - -public class ReplaceLoadFinalPhase extends Phase { - - @Override - protected void run(StructuredGraph graph) { - for (LoadIndexedNode loadIndexedNode : graph.getNodes(LoadIndexedNode.class)) { - if (loadIndexedNode.array() instanceof LoadFieldNode) { - LoadFieldNode loadFieldNode = (LoadFieldNode) loadIndexedNode.array(); - if (!loadFieldNode.isStatic() && isCompilationFinal(loadFieldNode.field())) { - graph.replaceFixedWithFixed(loadIndexedNode, graph.add(new LoadIndexedFinalNode(loadIndexedNode.array(), loadIndexedNode.index(), loadIndexedNode.elementKind()))); - } - } else if (loadIndexedNode.array() instanceof ConstantNode) { - graph.replaceFixedWithFixed(loadIndexedNode, graph.add(new LoadIndexedFinalNode(loadIndexedNode.array(), loadIndexedNode.index(), loadIndexedNode.elementKind()))); - } - } - } - - private static boolean isCompilationFinal(ResolvedJavaField field) { - assert (field.getAnnotation(Children.class) == null && field.getAnnotation(CompilerDirectives.CompilationFinal.class) == null) || Modifier.isFinal(field.getModifiers()) : "field needs to be declared as final"; - return Modifier.isFinal(field.getModifiers()) && (field.getAnnotation(Children.class) != null || field.getAnnotation(CompilerDirectives.CompilationFinal.class) != null); - } -} diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java Wed Oct 09 15:33:36 2013 +0200 @@ -63,12 +63,51 @@ @MacroSubstitution(macro = BailoutNode.class, isStatic = true) public static native void bailout(String reason); - @MacroSubstitution(macro = TypeCastMacroNode.class, isStatic = true) - public static native Object unsafeCast(Object value, Class clazz, Object receiver, Object customType); + @MacroSubstitution(macro = UnsafeTypeCastMacroNode.class, isStatic = true) + public static native Object unsafeCast(Object value, Class clazz, boolean condition); + + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native boolean unsafeGetBoolean(Object receiver, long offset, boolean condition, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native byte unsafeGetByte(Object receiver, long offset, boolean condition, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native short unsafeGetShort(Object receiver, long offset, boolean condition, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native int unsafeGetInt(Object receiver, long offset, boolean condition, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native float unsafeGetFloat(Object receiver, long offset, boolean condition, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native double unsafeGetDouble(Object receiver, long offset, boolean condition, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true) + public static native Object unsafeGetObject(Object receiver, long offset, boolean condition, Object locationIdentity); - @MacroSubstitution(macro = CustomTypeCheckMacroNode.class, isStatic = true) - public static native boolean customTypeCheck(boolean condition, Object value, Object customType); + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutBoolean(Object receiver, long offset, boolean value, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutByte(Object receiver, long offset, byte value, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutShort(Object receiver, long offset, short value, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutInt(Object receiver, long offset, int value, Object locationIdentity); - @MacroSubstitution(macro = UnsafeCustomizationMacroNode.class, isStatic = true) - public static native Object unsafeCustomization(Object receiver, Object customType, Object locationIdentity); + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutLong(Object receiver, long offset, long value, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutFloat(Object receiver, long offset, float value, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutDouble(Object receiver, long offset, double value, Object locationIdentity); + + @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true) + public static native void unsafePutObject(Object receiver, long offset, Object value, Object locationIdentity); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/MaterializedObjectState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/MaterializedObjectState.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/MaterializedObjectState.java Wed Oct 09 15:33:36 2013 +0200 @@ -29,7 +29,7 @@ /** * This class encapsulated the materialized state of an escape analyzed object. */ -public final class MaterializedObjectState extends EscapeObjectState implements IterableNodeType, Node.ValueNumberable { +public final class MaterializedObjectState extends EscapeObjectState implements Node.ValueNumberable { @Input private ValueNode materializedValue; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/VirtualObjectState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/VirtualObjectState.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/VirtualObjectState.java Wed Oct 09 15:33:36 2013 +0200 @@ -31,7 +31,7 @@ /** * This class encapsulated the virtual state of an escape analyzed object. */ -public final class VirtualObjectState extends EscapeObjectState implements IterableNodeType, Node.ValueNumberable { +public final class VirtualObjectState extends EscapeObjectState implements Node.ValueNumberable { @Input private final NodeInputList fieldValues; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java Wed Oct 09 15:33:36 2013 +0200 @@ -26,8 +26,8 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.util.*; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Wed Oct 09 15:33:36 2013 +0200 @@ -49,18 +49,18 @@ }); } - public void addSurvivingCounterBefore(final String group, final String name, final int increment, final boolean addContext, final ValueNode checkedValue, final FixedNode position) { + public void addWeakCounterCounterBefore(final String group, final String name, final int increment, final boolean addContext, final ValueNode checkedValue, final FixedNode position) { add(new Effect() { @Override public String name() { - return "addSurvivingCounterBefore"; + return "addWeakCounterBefore"; } @Override public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { assert position.isAlive(); - SurvivingCounterNode.addCounterBefore(group, name, increment, addContext, checkedValue, position); + WeakCounterNode.addCounterBefore(group, name, increment, addContext, checkedValue, position); } }); } diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationBlockState.java Wed Oct 09 15:33:36 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 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Wed Oct 09 15:33:36 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); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.word.nodes; 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.spi.*; import com.oracle.graal.nodes.type.*; @@ -55,7 +57,8 @@ return input; } - public ValueNode canonical(CanonicalizerTool tool) { + @Override + public Node canonical(CanonicalizerTool tool) { if (usages().count() == 0) { /* If the cast is unused, it can be eliminated. */ return input; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -58,6 +58,10 @@ @TypeSystemReference(SimpleTypes.class) public abstract static class ValueNode extends Node { + public ValueNode() { + super(null); + } + public int executeInt(VirtualFrame frame) throws UnexpectedResultException { return SimpleTypesGen.SIMPLETYPES.expectInteger(execute(frame)); } @@ -105,6 +109,7 @@ @Child private E node; public TestRootNode(E node) { + super(null); this.node = adoptChild(node); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ArgumentsTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ArgumentsTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ArgumentsTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -75,6 +75,7 @@ @Children private TestArgumentNode[] children; TestRootNode(TestArgumentNode[] children) { + super(null); this.children = adoptChildren(children); } @@ -93,6 +94,7 @@ private final int index; TestArgumentNode(int index) { + super(null); this.index = index; } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/CallTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/CallTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/CallTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -60,6 +60,7 @@ private final CallTarget secondTarget; DualCallNode(CallTarget firstTarget, CallTarget secondTarget) { + super(null); this.firstTarget = firstTarget; this.secondTarget = secondTarget; } @@ -75,6 +76,7 @@ private final int value; public ConstantRootNode(int value) { + super(null); this.value = value; } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildNodeTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildNodeTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildNodeTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -78,6 +78,7 @@ @Child private TestChildNode right; public TestRootNode(TestChildNode left, TestChildNode right) { + super(null); this.left = adoptChild(left); this.right = adoptChild(right); } @@ -90,6 +91,10 @@ class TestChildNode extends Node { + public TestChildNode() { + super(null); + } + public int execute() { return 21; } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildrenNodesTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildrenNodesTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildrenNodesTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -71,6 +71,7 @@ @Children private final TestChildNode[] children; public TestRootNode(TestChildNode[] children) { + super(null); this.children = adoptChildren(children); } @@ -86,6 +87,10 @@ class TestChildNode extends Node { + public TestChildNode() { + super(null); + } + public int execute() { return 21; } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FinalFieldTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FinalFieldTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FinalFieldTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -65,6 +65,7 @@ @Children TestChildNode[] children; public TestRootNode(TestChildNode[] children) { + super(null); this.children = adoptChildren(children); } @@ -83,6 +84,7 @@ private final int value; public TestChildNode(int value) { + super(null); this.value = value; } diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -63,6 +63,7 @@ @Child TestChildNode right; public TestRootNode(TestChildNode left, TestChildNode right) { + super(null); this.left = adoptChild(left); this.right = adoptChild(right); } @@ -76,6 +77,10 @@ abstract class TestChildNode extends Node { + protected TestChildNode() { + super(null); + } + abstract Object execute(VirtualFrame frame); } diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -77,6 +77,7 @@ @Child TestChildNode right; public TestRootNode(TestChildNode left, TestChildNode right) { + super(null); this.left = adoptChild(left); this.right = adoptChild(right); } @@ -89,6 +90,10 @@ abstract class TestChildNode extends Node { + public TestChildNode() { + super(null); + } + abstract int execute(VirtualFrame frame); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReplaceTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReplaceTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReplaceTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -84,6 +84,7 @@ @Children private final ValueNode[] children; public TestRootNode(ValueNode[] children) { + super(null); this.children = adoptChildren(children); } @@ -99,6 +100,10 @@ abstract class ValueNode extends Node { + public ValueNode() { + super(null); + } + abstract int execute(); } diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -62,6 +62,7 @@ @Child TestChildNode right; public TestRootNode(TestChildNode left, TestChildNode right) { + super(null); this.left = adoptChild(left); this.right = adoptChild(right); } @@ -75,6 +76,10 @@ abstract class TestChildNode extends Node { + public TestChildNode() { + super(null); + } + abstract Object execute(VirtualFrame frame); int executeInt(VirtualFrame frame) throws UnexpectedResultException { diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/RootNodeTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/RootNodeTest.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/RootNodeTest.java Wed Oct 09 15:33:36 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -59,6 +59,10 @@ class TestRootNode extends RootNode { + public TestRootNode() { + super(null); + } + @Override public Object execute(VirtualFrame frame) { return 42; diff -r 7cce548b0b60 -r df3af5e007ad 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 Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java Wed Oct 09 15:33:36 2013 +0200 @@ -25,13 +25,16 @@ package com.oracle.truffle.api; import java.lang.annotation.*; +import java.lang.reflect.*; import java.util.concurrent.*; +import sun.misc.*; + /** * Directives that influence the optimizations of the Truffle compiler. All of the operations have * no effect when executed in the Truffle interpreter. */ -public class CompilerDirectives { +public final class CompilerDirectives { public static final double LIKELY_PROBABILITY = 0.75; public static final double UNLIKELY_PROBABILITY = 1.0 - LIKELY_PROBABILITY; @@ -39,6 +42,22 @@ public static final double SLOWPATH_PROBABILITY = 0.0001; public static final double FASTPATH_PROBABILITY = 1.0 - SLOWPATH_PROBABILITY; + private static final Unsafe UNSAFE = getUnsafe(); + + private static Unsafe getUnsafe() { + try { + return Unsafe.getUnsafe(); + } catch (SecurityException e) { + } + try { + Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafeInstance.setAccessible(true); + return (Unsafe) theUnsafeInstance.get(Unsafe.class); + } catch (Exception e) { + throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e); + } + } + /** * Directive for the compiler to discontinue compilation at this code position and instead * insert a transfer to the interpreter. @@ -130,72 +149,275 @@ } /** - * Marks methods that are considered unsafe. Wrong usage of those methods can lead to unexpected - * behavior including a crash of the runtime. Therefore, special care should be taken. - */ - @Retention(RetentionPolicy.RUNTIME) - @Target({ElementType.METHOD}) - public @interface Unsafe { - } - - /** - * Treats the given value as a value of the given class. The class must evaluate to a constant. + * Casts the given value to the value of the given type without any checks. The class must + * evaluate to a constant. The condition parameter gives a hint to the compiler under which + * circumstances this cast can be moved to an earlier location in the program. * * @param value the value that is known to have the specified type - * @param clazz the specified type of the value - * @return the value - */ - @Unsafe - public static T unsafeCast(Object value, Class clazz) { - return unsafeCast(value, clazz, null, null); - } - - /** - * Associates the given type token with the given value for the case that condition is true. - * - * @param condition the custom type check - * @param value the value that is of the given custom type after the check - * @param customType the custom type that should be associated with the value - * @return the type check condition - */ - public static boolean customTypeCheck(boolean condition, Object value, Object customType) { - return condition; - } - - /** - * Treats the given value as a value of the given class. The class must evaluate to a constant. - * If the compiler can prove that the given value is of the given custom type, the cast is safe. - * - * @param value the value that is known to have the specified type - * @param clazz the specified type of the value - * @param receiver the receiver on which the custom type is tested - * @param customType the custom type that if present on a value makes this unsafe cast safe - * @return the value + * @param type the specified new type of the value + * @param condition the condition that makes this cast safe also at an earlier location of the + * program + * @return the value to be casted to the new type */ @SuppressWarnings("unchecked") - @Unsafe - public static T unsafeCast(Object value, Class clazz, Object receiver, Object customType) { + public static T unsafeCast(Object value, Class type, boolean condition) { return (T) value; } /** - * Proxies an object instance into an instance that adds a custom location identity on its - * accesses via sun.misc.Unsafe. This means that the accesses on these kind of location - * identities can only alias among themselves. It also allows to specify a custom type for the - * receiver values of follow-up unsafe accesses. Both the custom type and the location identity - * must evaluate to a constant. Furthermore, you should use the proxied receiver object - * immediately for one read or write access via a sun.misc.Unsafe method and not store it - * anywhere. + * Unsafe access to a boolean value within an object. The condition parameter gives a hint to + * the compiler under which circumstances this access can be moved to an earlier location in the + * program. The location identity gives a hint to the compiler for improved global value + * numbering. + * + * @param receiver the object that is accessed + * @param offset the offset at which to access the object in bytes + * @param condition the condition that makes this access safe also at an earlier location in the + * program + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + * @return the accessed value + */ + public static boolean unsafeGetBoolean(Object receiver, long offset, boolean condition, Object locationIdentity) { + return UNSAFE.getBoolean(receiver, offset); + } + + /** + * Unsafe access to a byte value within an object. The condition parameter gives a hint to the + * compiler under which circumstances this access can be moved to an earlier location in the + * program. The location identity gives a hint to the compiler for improved global value + * numbering. + * + * @param receiver the object that is accessed + * @param offset the offset at which to access the object in bytes + * @param condition the condition that makes this access safe also at an earlier location in the + * program + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + * @return the accessed value + */ + public static byte unsafeGetByte(Object receiver, long offset, boolean condition, Object locationIdentity) { + return UNSAFE.getByte(receiver, offset); + } + + /** + * Unsafe access to a short value within an object. The condition parameter gives a hint to the + * compiler under which circumstances this access can be moved to an earlier location in the + * program. The location identity gives a hint to the compiler for improved global value + * numbering. + * + * @param receiver the object that is accessed + * @param offset the offset at which to access the object in bytes + * @param condition the condition that makes this access safe also at an earlier location in the + * program + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + * @return the accessed value + */ + public static short unsafeGetShort(Object receiver, long offset, boolean condition, Object locationIdentity) { + return UNSAFE.getShort(receiver, offset); + } + + /** + * Unsafe access to a int value within an object. The condition parameter gives a hint to the + * compiler under which circumstances this access can be moved to an earlier location in the + * program. The location identity gives a hint to the compiler for improved global value + * numbering. * - * @param receiver the object that is accessed via sun.misc.Unsafe - * @param customType the expected type of the receiver object of follow-up unsafe accesses + * @param receiver the object that is accessed + * @param offset the offset at which to access the object in bytes + * @param condition the condition that makes this access safe also at an earlier location in the + * program + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + * @return the accessed value + */ + public static int unsafeGetInt(Object receiver, long offset, boolean condition, Object locationIdentity) { + return UNSAFE.getInt(receiver, offset); + } + + /** + * Unsafe access to a long value within an object. The condition parameter gives a hint to the + * compiler under which circumstances this access can be moved to an earlier location in the + * program. The location identity gives a hint to the compiler for improved global value + * numbering. + * + * @param receiver the object that is accessed + * @param offset the offset at which to access the object in bytes + * @param condition the condition that makes this access safe also at an earlier location in the + * program + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + * @return the accessed value + */ + public static long unsafeGetLong(Object receiver, long offset, boolean condition, Object locationIdentity) { + return UNSAFE.getLong(receiver, offset); + } + + /** + * Unsafe access to a float value within an object. The condition parameter gives a hint to the + * compiler under which circumstances this access can be moved to an earlier location in the + * program. The location identity gives a hint to the compiler for improved global value + * numbering. + * + * @param receiver the object that is accessed + * @param offset the offset at which to access the object in bytes + * @param condition the condition that makes this access safe also at an earlier location in the + * program + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + * @return the accessed value + */ + public static float unsafeGetFloat(Object receiver, long offset, boolean condition, Object locationIdentity) { + return UNSAFE.getFloat(receiver, offset); + } + + /** + * Unsafe access to a double value within an object. The condition parameter gives a hint to the + * compiler under which circumstances this access can be moved to an earlier location in the + * program. The location identity gives a hint to the compiler for improved global value + * numbering. + * + * @param receiver the object that is accessed + * @param offset the offset at which to access the object in bytes + * @param condition the condition that makes this access safe also at an earlier location in the + * program * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ - @Unsafe - public static Object unsafeCustomization(Object receiver, Object customType, Object locationIdentity) { - return receiver; + public static double unsafeGetDouble(Object receiver, long offset, boolean condition, Object locationIdentity) { + return UNSAFE.getDouble(receiver, offset); + } + + /** + * Unsafe access to a Object value within an object. The condition parameter gives a hint to the + * compiler under which circumstances this access can be moved to an earlier location in the + * program. The location identity gives a hint to the compiler for improved global value + * numbering. + * + * @param receiver the object that is accessed + * @param offset the offset at which to access the object in bytes + * @param condition the condition that makes this access safe also at an earlier location in the + * program + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + * @return the accessed value + */ + public static Object unsafeGetObject(Object receiver, long offset, boolean condition, Object locationIdentity) { + return UNSAFE.getObject(receiver, offset); + } + + /** + * Write a boolean value within an object. The location identity gives a hint to the compiler + * for improved global value numbering. + * + * @param receiver the object that is written to + * @param offset the offset at which to write to the object in bytes + * @param value the value to be written + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + */ + public static void unsafePutBoolean(Object receiver, long offset, boolean value, Object locationIdentity) { + UNSAFE.putBoolean(receiver, offset, value); + } + + /** + * Write a byte value within an object. The location identity gives a hint to the compiler for + * improved global value numbering. + * + * @param receiver the object that is written to + * @param offset the offset at which to write to the object in bytes + * @param value the value to be written + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + */ + public static void unsafePutByte(Object receiver, long offset, byte value, Object locationIdentity) { + UNSAFE.putByte(receiver, offset, value); + } + + /** + * Write a short value within an object. The location identity gives a hint to the compiler for + * improved global value numbering. + * + * @param receiver the object that is written to + * @param offset the offset at which to write to the object in bytes + * @param value the value to be written + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + */ + public static void unsafePutShort(Object receiver, long offset, short value, Object locationIdentity) { + UNSAFE.putShort(receiver, offset, value); + } + + /** + * Write a int value within an object. The location identity gives a hint to the compiler for + * improved global value numbering. + * + * @param receiver the object that is written to + * @param offset the offset at which to write to the object in bytes + * @param value the value to be written + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + */ + public static void unsafePutInt(Object receiver, long offset, int value, Object locationIdentity) { + UNSAFE.putInt(receiver, offset, value); + } + + /** + * Write a long value within an object. The location identity gives a hint to the compiler for + * improved global value numbering. + * + * @param receiver the object that is written to + * @param offset the offset at which to write to the object in bytes + * @param value the value to be written + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + */ + public static void unsafePutLong(Object receiver, long offset, long value, Object locationIdentity) { + UNSAFE.putLong(receiver, offset, value); + } + + /** + * Write a float value within an object. The location identity gives a hint to the compiler for + * improved global value numbering. + * + * @param receiver the object that is written to + * @param offset the offset at which to write to the object in bytes + * @param value the value to be written + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + */ + public static void unsafePutFloat(Object receiver, long offset, float value, Object locationIdentity) { + UNSAFE.putFloat(receiver, offset, value); + } + + /** + * Write a double value within an object. The location identity gives a hint to the compiler for + * improved global value numbering. + * + * @param receiver the object that is written to + * @param offset the offset at which to write to the object in bytes + * @param value the value to be written + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + */ + public static void unsafePutDouble(Object receiver, long offset, double value, Object locationIdentity) { + UNSAFE.putDouble(receiver, offset, value); + } + + /** + * Write a Object value within an object. The location identity gives a hint to the compiler for + * improved global value numbering. + * + * @param receiver the object that is written to + * @param offset the offset at which to write to the object in bytes + * @param value the value to be written + * @param locationIdentity the location identity token that can be used for improved global + * value numbering or null + */ + public static void unsafePutObject(Object receiver, long offset, Object value, Object locationIdentity) { + UNSAFE.putObject(receiver, offset, value); } /** diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java Wed Oct 09 15:33:36 2013 +0200 @@ -77,6 +77,14 @@ Assumption createAssumption(String name); /** + * Creates a new virtual frame object that can be used to store values and is potentially + * optimizable by the runtime. + * + * @return the newly created virtual frame object + */ + VirtualFrame createVirtualFrame(PackedFrame caller, Arguments arguments, FrameDescriptor frameDescriptor); + + /** * Creates a new materialized frame object that can be used to store values. * * @return the newly created materialized frame object diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java Wed Oct 09 15:33:36 2013 +0200 @@ -47,7 +47,6 @@ * @param clazz the known type of the arguments object as a compile time constant * @return the arguments used when calling this method */ - @CompilerDirectives.Unsafe T getArguments(Class clazz); /** diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Wed Oct 09 15:33:36 2013 +0200 @@ -50,6 +50,11 @@ } @Override + public VirtualFrame createVirtualFrame(PackedFrame caller, Arguments arguments, FrameDescriptor frameDescriptor) { + return new DefaultVirtualFrame(frameDescriptor, caller, arguments); + } + + @Override public MaterializedFrame createMaterializedFrame(Arguments arguments) { return createMaterializedFrame(arguments, new FrameDescriptor()); } diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Wed Oct 09 15:33:36 2013 +0200 @@ -657,7 +657,7 @@ final SourceSection sourceSection = node.getSourceSection(); if (sourceSection != null) { final String txt = sourceSection.getSource().getCode(); - p.println("Full source len=(" + txt.length() + ") txt=___" + txt + "___"); + p.println("Full source len=(" + txt.length() + ") ___" + txt + "___"); p.println("AST source attribution:"); } } @@ -793,7 +793,7 @@ final StringBuilder sb = new StringBuilder(); sb.append("source: len=" + srcText.length()); sb.append(" (" + section.getCharIndex() + "," + (section.getCharEndIndex() - 1) + ")"); - sb.append(" txt=___" + srcText + "___"); + sb.append(" ___" + srcText + "___"); return sb.toString(); } return ""; diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -28,6 +28,11 @@ @TypeSystemReference(SLTypes.class) public class SLNode extends Node { + public SLNode() { + // No source attribution + super(null); + } + @Override public String toString() { return NodeUtil.printTreeToString(this); diff -r 7cce548b0b60 -r df3af5e007ad graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionDefinitionNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionDefinitionNode.java Thu Oct 03 18:09:21 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionDefinitionNode.java Wed Oct 09 15:33:36 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -35,6 +35,7 @@ private final String name; public FunctionDefinitionNode(StatementNode body, FrameDescriptor frameDescriptor, String name, TypedNode returnValue) { + super(null); this.body = adoptChild(body); this.frameDescriptor = frameDescriptor; this.name = name; diff -r 7cce548b0b60 -r df3af5e007ad mx/commands.py --- a/mx/commands.py Thu Oct 03 18:09:21 2013 +0200 +++ b/mx/commands.py Wed Oct 09 15:33:36 2013 +0200 @@ -365,9 +365,18 @@ return jdk +def _updateInstalledGraalOptionsFile(jdk): + graalOptions = join(_graal_home, 'graal.options') + jreLibDir = join(jdk, 'jre', 'lib') + if exists(graalOptions): + shutil.copy(graalOptions, join(jreLibDir, 'graal.options')) + else: + toDelete = join(jreLibDir, 'graal.options') + if exists(toDelete): + os.unlink(toDelete) + def _installGraalJarInJdks(graalDist): graalJar = graalDist.path - graalOptions = join(_graal_home, 'graal.options') jdks = _jdksDir() if exists(jdks): for e in os.listdir(jdks): @@ -379,9 +388,6 @@ os.close(fd) shutil.move(tmp, join(jreLibDir, 'graal.jar')) - if exists(graalOptions): - shutil.copy(graalOptions, join(jreLibDir, 'graal.options')) - # run a command in the windows SDK Debug Shell def _runInDebugShell(cmd, workingDir, logFile=None, findInOutput=None, respondTo=None): if respondTo is None: @@ -692,6 +698,7 @@ build = vmbuild if vmbuild is not None else _vmbuild if _vmSourcesAvailable else 'product' jdk = _jdk(build, vmToCheck=vm, installGraalJar=False) + _updateInstalledGraalOptionsFile(jdk) mx.expand_project_in_args(args) if _make_eclipse_launch: mx.make_eclipse_launch(args, 'graal-' + build, name=None, deps=mx.project('com.oracle.graal.hotspot').all_deps([], True)) @@ -1318,6 +1325,14 @@ mx.abort('jacocoreport takes only one argument : an output directory') mx.run_java(['-jar', jacocoreport.get_path(True), '-in', 'jacoco.exec', '-g', join(_graal_home, 'graal'), out]) +def sl(args): + """run an SL program + + VM args should have a @ prefix.""" + vmArgs = [a[1:] for a in args if a[0] == '@'] + slArgs = [a for a in args if a[0] != '@'] + vm(vmArgs + ['-cp', mx.classpath("com.oracle.truffle.sl"), "com.oracle.truffle.sl.SimpleLanguage"] + slArgs) + def isGraalEnabled(vm): return vm != 'original' and not vm.endswith('nograal') @@ -1361,7 +1376,8 @@ 'vmg': [vmg, '[-options] class [args...]'], 'vmfg': [vmfg, '[-options] class [args...]'], 'deoptalot' : [deoptalot, '[n]'], - 'longtests' : [longtests, ''] + 'longtests' : [longtests, ''], + 'sl' : [sl, '[SL args|@VM options]'] } mx.add_argument('--jacoco', help='instruments com.oracle.* classes using JaCoCo', default='off', choices=['off', 'on', 'append']) diff -r 7cce548b0b60 -r df3af5e007ad mx/projects --- a/mx/projects Thu Oct 03 18:09:21 2013 +0200 +++ b/mx/projects Wed Oct 09 15:33:36 2013 +0200 @@ -186,7 +186,7 @@ # graal.graph project@com.oracle.graal.graph@subDir=graal project@com.oracle.graal.graph@sourceDirs=src -project@com.oracle.graal.graph@dependencies=com.oracle.graal.debug +project@com.oracle.graal.graph@dependencies=com.oracle.graal.debug,com.oracle.graal.api.code project@com.oracle.graal.graph@javaCompliance=1.7 project@com.oracle.graal.graph@workingSets=Graal,Graph @@ -297,7 +297,7 @@ # graal.nodes project@com.oracle.graal.nodes@subDir=graal project@com.oracle.graal.nodes@sourceDirs=src -project@com.oracle.graal.nodes@dependencies=com.oracle.graal.graph,com.oracle.graal.api.replacements,com.oracle.graal.api.code +project@com.oracle.graal.nodes@dependencies=com.oracle.graal.graph,com.oracle.graal.api.replacements project@com.oracle.graal.nodes@checkstyle=com.oracle.graal.graph project@com.oracle.graal.nodes@javaCompliance=1.7 project@com.oracle.graal.nodes@workingSets=Graal,Graph @@ -497,7 +497,7 @@ # graal.hsail project@com.oracle.graal.hsail@subDir=graal project@com.oracle.graal.hsail@sourceDirs=src -project@com.oracle.graal.hsail@dependencies=com.oracle.graal.api.code,com.oracle.graal.graph +project@com.oracle.graal.hsail@dependencies=com.oracle.graal.graph project@com.oracle.graal.hsail@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hsail@javaCompliance=1.7 diff -r 7cce548b0b60 -r df3af5e007ad src/gpu/ptx/vm/gpu_ptx.cpp --- a/src/gpu/ptx/vm/gpu_ptx.cpp Thu Oct 03 18:09:21 2013 +0200 +++ b/src/gpu/ptx/vm/gpu_ptx.cpp Wed Oct 09 15:33:36 2013 +0200 @@ -180,9 +180,58 @@ int total = nmp * ncores(major, minor); + int max_threads_per_block, warp_size, async_engines, can_map_host_memory, concurrent_kernels; + + status = _cuda_cu_device_get_attribute(&max_threads_per_block, + GRAAL_CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK, + _cu_device); + + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] Failed to get GRAAL_CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK: %d", _cu_device); + return 0; + } + + status = _cuda_cu_device_get_attribute(&warp_size, + GRAAL_CU_DEVICE_ATTRIBUTE_WARP_SIZE, + _cu_device); + + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] Failed to get GRAAL_CU_DEVICE_ATTRIBUTE_WARP_SIZE: %d", _cu_device); + return 0; + } + + status = _cuda_cu_device_get_attribute(&async_engines, + GRAAL_CU_DEVICE_ATTRIBUTE_ASYNC_ENGINE_COUNT, + _cu_device); + + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] Failed to get GRAAL_CU_DEVICE_ATTRIBUTE_WARP_SIZE: %d", _cu_device); + return 0; + } + + status = _cuda_cu_device_get_attribute(&can_map_host_memory, + GRAAL_CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY, + _cu_device); + + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] Failed to get GRAAL_CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY: %d", _cu_device); + return 0; + } + + status = _cuda_cu_device_get_attribute(&concurrent_kernels, + GRAAL_CU_DEVICE_ATTRIBUTE_CONCURRENT_KERNELS, + _cu_device); + + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] Failed to get GRAAL_CU_DEVICE_ATTRIBUTE_CONCURRENT_KERNELS: %d", _cu_device); + return 0; + } + if (TraceGPUInteraction) { tty->print_cr("[CUDA] Compatibility version of device %d: %d.%d", _cu_device, major, minor); - tty->print_cr("[CUDA] Number of cores: %d", total); + tty->print_cr("[CUDA] Number of cores: %d async engines: %d can map host mem: %d concurrent kernels: %d", + total, async_engines, can_map_host_memory, concurrent_kernels); + tty->print_cr("[CUDA] Max threads per block: %d warp size: %d", max_threads_per_block, warp_size); } return (total); @@ -344,6 +393,39 @@ ret.set_jint(return_val); } break; + case T_BOOLEAN: + { + int return_val; + status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._return_value_ptr, T_INT_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status); + return false; + } + ret.set_jint(return_val); + } + break; + case T_FLOAT: + { + float return_val; + status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._return_value_ptr, T_FLOAT_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status); + return false; + } + ret.set_jfloat(return_val); + } + break; + case T_DOUBLE: + { + double return_val; + status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._return_value_ptr, T_DOUBLE_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status); + return false; + } + ret.set_jdouble(return_val); + } + break; case T_LONG: { long return_val; diff -r 7cce548b0b60 -r df3af5e007ad src/gpu/ptx/vm/gpu_ptx.hpp --- a/src/gpu/ptx/vm/gpu_ptx.hpp Thu Oct 03 18:09:21 2013 +0200 +++ b/src/gpu/ptx/vm/gpu_ptx.hpp Wed Oct 09 15:33:36 2013 +0200 @@ -31,10 +31,15 @@ */ #define GRAAL_CUDA_SUCCESS 0 /**< Device shares a unified address space with the host */ +#define GRAAL_CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK 1 #define GRAAL_CU_DEVICE_ATTRIBUTE_UNIFIED_ADDRESSING 41 #define GRAAL_CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR 75 #define GRAAL_CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR 76 #define GRAAL_CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT 16 +#define GRAAL_CU_DEVICE_ATTRIBUTE_WARP_SIZE 10 +#define GRAAL_CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY 19 +#define GRAAL_CU_DEVICE_ATTRIBUTE_CONCURRENT_KERNELS 31 +#define GRAAL_CU_DEVICE_ATTRIBUTE_ASYNC_ENGINE_COUNT 40 #define GRAAL_CU_JIT_MAX_REGISTERS 0 #define GRAAL_CU_JIT_THREADS_PER_BLOCK 1 #define GRAAL_CU_JIT_INFO_LOG_BUFFER 3 diff -r 7cce548b0b60 -r df3af5e007ad src/gpu/ptx/vm/ptxKernelArguments.cpp --- a/src/gpu/ptx/vm/ptxKernelArguments.cpp Thu Oct 03 18:09:21 2013 +0200 +++ b/src/gpu/ptx/vm/ptxKernelArguments.cpp Wed Oct 09 15:33:36 2013 +0200 @@ -41,35 +41,100 @@ } void PTXKernelArguments::do_int() { - if (is_after_invocation()) { + if (is_after_invocation()) { + return; + } + // If the parameter is a return value, + if (is_return_type()) { + // Allocate device memory for T_INT return value pointer on device. Size in bytes + int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_INT_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; + return; + } + // Push _return_value_ptr to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; + _bufferOffset += sizeof(_return_value_ptr); + } else { + // Get the next java argument and its value which should be a T_INT + oop arg = next_arg(T_INT); + // Copy the java argument value to kernelArgBuffer + jvalue intval; + if (java_lang_boxing_object::get_value(arg, &intval) != T_INT) { + tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT"); + _success = false; + return; + } + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = intval.i; + _bufferOffset += sizeof(intval.i); + } return; - } - // If the parameter is a return value, - if (is_return_type()) { - // Allocate device memory for T_INT return value pointer on device. Size in bytes - int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_INT_BYTE_SIZE); - if (status != GRAAL_CUDA_SUCCESS) { - tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); - _success = false; - return; +} + +void PTXKernelArguments::do_float() { + if (is_after_invocation()) { + return; } - // Push _return_value_ptr to _kernelBuffer - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; - _bufferOffset += sizeof(_return_value_ptr); - } else { - // Get the next java argument and its value which should be a T_INT - oop arg = next_arg(T_INT); - // Copy the java argument value to kernelArgBuffer - jvalue intval; - if (java_lang_boxing_object::get_value(arg, &intval) != T_INT) { - tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT"); - _success = false; - return; + // If the parameter is a return value, + if (is_return_type()) { + // Allocate device memory for T_INT return value pointer on device. Size in bytes + int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_FLOAT_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; + return; + } + // Push _return_value_ptr to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; + _bufferOffset += sizeof(_return_value_ptr); + } else { + // Get the next java argument and its value which should be a T_INT + oop arg = next_arg(T_FLOAT); + // Copy the java argument value to kernelArgBuffer + jvalue floatval; + if (java_lang_boxing_object::get_value(arg, &floatval) != T_FLOAT) { + tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT"); + _success = false; + return; + } + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = floatval.f; + _bufferOffset += sizeof(floatval.f); } - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = intval.i; - _bufferOffset += sizeof(intval.i); - } - return; + return; +} + +void PTXKernelArguments::do_double() { + if (is_after_invocation()) { + return; + } + // If the parameter is a return value, + jvalue doubleval; + if (is_return_type()) { + // Allocate device memory for T_INT return value pointer on device. Size in bytes + int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_DOUBLE_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; + return; + } + // Push _return_value_ptr to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; + // _bufferOffset += sizeof(_return_value_ptr); + _bufferOffset += sizeof(doubleval.d); + } else { + // Get the next java argument and its value which should be a T_INT + oop arg = next_arg(T_FLOAT); + // Copy the java argument value to kernelArgBuffer + if (java_lang_boxing_object::get_value(arg, &doubleval) != T_DOUBLE) { + tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT"); + _success = false; + return; + } + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = doubleval.d; + _bufferOffset += sizeof(doubleval.d); + } + return; } void PTXKernelArguments::do_long() { @@ -136,6 +201,38 @@ return; } +void PTXKernelArguments::do_bool() { + if (is_after_invocation()) { + return; + } + // If the parameter is a return value, + if (is_return_type()) { + // Allocate device memory for T_BYTE return value pointer on device. Size in bytes + int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_BOOLEAN_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; + return; + } + // Push _return_value_ptr to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; + _bufferOffset += sizeof(_return_value_ptr); + } else { + // Get the next java argument and its value which should be a T_BYTE + oop arg = next_arg(T_BYTE); + // Copy the java argument value to kernelArgBuffer + jvalue val; + if (java_lang_boxing_object::get_value(arg, &val) != T_BOOLEAN) { + tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_BYTE"); + _success = false; + return; + } + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.z; + _bufferOffset += sizeof(val.z); + } + return; +} + void PTXKernelArguments::do_array(int begin, int end) { gpu::Ptx::CUdeviceptr _array_ptr; int status; diff -r 7cce548b0b60 -r df3af5e007ad src/gpu/ptx/vm/ptxKernelArguments.hpp --- a/src/gpu/ptx/vm/ptxKernelArguments.hpp Thu Oct 03 18:09:21 2013 +0200 +++ b/src/gpu/ptx/vm/ptxKernelArguments.hpp Wed Oct 09 15:33:36 2013 +0200 @@ -28,10 +28,13 @@ #include "runtime/gpu.hpp" #include "runtime/signature.hpp" -#define T_BYTE_SIZE 1 -#define T_INT_BYTE_SIZE 4 -#define T_LONG_BYTE_SIZE 8 -#define T_ARRAY_BYTE_SIZE 8 +#define T_BYTE_SIZE 1 +#define T_BOOLEAN_SIZE 4 +#define T_INT_BYTE_SIZE 4 +#define T_FLOAT_BYTE_SIZE 4 +#define T_DOUBLE_BYTE_SIZE 8 +#define T_LONG_BYTE_SIZE 8 +#define T_ARRAY_BYTE_SIZE 8 class PTXKernelArguments : public SignatureIterator { public: @@ -98,15 +101,14 @@ void do_byte(); + void do_bool(); void do_int(); + void do_float(); + void do_double(); void do_long(); void do_array(int begin, int end); void do_void(); - inline void do_bool() { - /* TODO : To be implemented */ - guarantee(false, "do_bool:NYI"); - } inline void do_char() { /* TODO : To be implemented */ guarantee(false, "do_char:NYI"); @@ -115,15 +117,6 @@ /* TODO : To be implemented */ guarantee(false, "do_short:NYI"); } - inline void do_float() { - /* TODO : To be implemented */ - guarantee(false, "do_float:NYI"); - } - inline void do_double() { - /* TODO : To be implemented */ - guarantee(false, "do_double:NYI"); - } - inline void do_object() { /* TODO : To be implemented */ guarantee(false, "do_object:NYI"); diff -r 7cce548b0b60 -r df3af5e007ad src/share/vm/graal/graalCompilerToGPU.cpp --- a/src/share/vm/graal/graalCompilerToGPU.cpp Thu Oct 03 18:09:21 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToGPU.cpp Wed Oct 09 15:33:36 2013 +0200 @@ -96,7 +96,20 @@ } else { oop o = java_lang_boxing_object::create(ptxka.get_ret_type(), (jvalue *) result.get_value_addr(), CHECK_NULL); if (TraceGPUInteraction) { - tty->print_cr("GPU execution returned %d", result.get_jint()); + switch (ptxka.get_ret_type()) { + case T_INT: + tty->print_cr("GPU execution returned %d", result.get_jint()); + break; + case T_FLOAT: + tty->print_cr("GPU execution returned %f", result.get_jfloat()); + break; + case T_DOUBLE: + tty->print_cr("GPU execution returned %f", result.get_jdouble()); + break; + default: + tty->print_cr("GPU returned unhandled"); + break; + } } return JNIHandles::make_local(o); } @@ -135,7 +148,20 @@ } else { oop o = java_lang_boxing_object::create(ptxka.get_ret_type(), (jvalue *) result.get_value_addr(), CHECK_NULL); if (TraceGPUInteraction) { - tty->print_cr("GPU execution returned %d", result.get_jint()); + switch (ptxka.get_ret_type()) { + case T_INT: + tty->print_cr("GPU execution returned %d", result.get_jint()); + break; + case T_FLOAT: + tty->print_cr("GPU execution returned %f", result.get_jfloat()); + break; + case T_DOUBLE: + tty->print_cr("GPU execution returned %g", result.get_jdouble()); + break; + default: + tty->print_cr("GPU returned unhandled"); + break; + } } return JNIHandles::make_local(o); } diff -r 7cce548b0b60 -r df3af5e007ad src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp Thu Oct 03 18:09:21 2013 +0200 +++ b/src/share/vm/runtime/thread.cpp Wed Oct 09 15:33:36 2013 +0200 @@ -1414,7 +1414,7 @@ #ifdef GRAAL #if GRAAL_COUNTERS_SIZE > 0 -jlong JavaThread::_graal_old_counters[GRAAL_COUNTERS_SIZE]; +jlong JavaThread::_graal_old_thread_counters[GRAAL_COUNTERS_SIZE]; bool graal_counters_include(oop threadObj) { return !GRAAL_COUNTERS_EXCLUDE_COMPILER_THREADS || threadObj == NULL || threadObj->klass() != SystemDictionary::CompilerThread_klass(); @@ -1423,7 +1423,7 @@ void JavaThread::collect_counters(typeArrayOop array) { MutexLocker tl(Threads_lock); for (int i = 0; i < array->length(); i++) { - array->long_at_put(i, _graal_old_counters[i]); + array->long_at_put(i, _graal_old_thread_counters[i]); } for (JavaThread* tp = Threads::first(); tp != NULL; tp = tp->next()) { if (graal_counters_include(tp->threadObj())) { @@ -1479,10 +1479,12 @@ _stack_guard_state = stack_guard_unused; #ifdef GRAAL _graal_alternate_call_target = NULL; +#if GRAAL_COUNTERS_SIZE > 0 for (int i = 0; i < GRAAL_COUNTERS_SIZE; i++) { _graal_counters[i] = 0; } -#endif +#endif // GRAAL_COUNTER_SIZE > 0 +#endif // GRAAL _exception_oop = NULL; _exception_pc = 0; _exception_handler_pc = 0; @@ -1675,7 +1677,7 @@ #if defined(GRAAL) && (GRAAL_COUNTERS_SIZE > 0) if (graal_counters_include(threadObj())) { for (int i = 0; i < GRAAL_COUNTERS_SIZE; i++) { - _graal_old_counters[i] += _graal_counters[i]; + _graal_old_thread_counters[i] += _graal_counters[i]; } } #endif diff -r 7cce548b0b60 -r df3af5e007ad src/share/vm/runtime/thread.hpp --- a/src/share/vm/runtime/thread.hpp Thu Oct 03 18:09:21 2013 +0200 +++ b/src/share/vm/runtime/thread.hpp Wed Oct 09 15:33:36 2013 +0200 @@ -924,13 +924,15 @@ #define GRAAL_COUNTERS_SIZE (0) #define GRAAL_COUNTERS_EXCLUDE_COMPILER_THREADS (true) +#if GRAAL_COUNTERS_SIZE > 0 jlong _graal_counters[GRAAL_COUNTERS_SIZE]; - static jlong _graal_old_counters[GRAAL_COUNTERS_SIZE]; + static jlong _graal_old_thread_counters[GRAAL_COUNTERS_SIZE]; +#endif // GRAAL_COUNTERS_SIZE > 0 public: static void collect_counters(typeArrayOop array); private: -#endif +#endif // GRAAL StackGuardState _stack_guard_state; nmethod* _scanned_nmethod; // nmethod being scanned by the sweeper @@ -1390,8 +1392,12 @@ #ifdef GRAAL static ByteSize graal_alternate_call_target_offset() { return byte_offset_of(JavaThread, _graal_alternate_call_target); } static ByteSize graal_implicit_exception_pc_offset() { return byte_offset_of(JavaThread, _graal_implicit_exception_pc); } - static ByteSize graal_counters_offset() { return byte_offset_of(JavaThread, _graal_counters ); } -#endif +#if GRAAL_COUNTERS_SIZE > 0 + static ByteSize graal_counters_offset() { return byte_offset_of(JavaThread, _graal_counters ); } +#else + static ByteSize graal_counters_offset() { return in_ByteSize(0); } +#endif // GRAAL_COUNTERS_SIZE > 0 +#endif // GRAAL static ByteSize exception_oop_offset() { return byte_offset_of(JavaThread, _exception_oop ); } static ByteSize exception_pc_offset() { return byte_offset_of(JavaThread, _exception_pc ); } static ByteSize exception_handler_pc_offset() { return byte_offset_of(JavaThread, _exception_handler_pc); }