# HG changeset patch # User Christian Haeubl # Date 1370846665 -7200 # Node ID 8ad4e90fc5d730a548b1a9172216638a774725b3 # Parent de73bbbde021431f9a2f63e8dbcf905fa60403bc# Parent 60648c97cdd0f7b61793556dd5b135cc148e716c Merge. diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Mon Jun 10 08:44:25 2013 +0200 @@ -90,6 +90,20 @@ } } + public static class Fmt2e { + public Fmt2e(SPARCAssembler asm, int op, int c4lo, int cc2, int rs1, int d10lo, int regOrImmediate) { + assert op == 0; + assert (cc2 & 0xFFFFFFFE) == 0; + assert c4lo >= 0 && rs1 < 0x10; + assert rs1 >= 0 && rs1 < 0x20; + assert (regOrImmediate & 0x1F) < 0x20; + assert (regOrImmediate & 0xFFFFC000) == 0; + assert (d10lo & 0xFFFFFC00) == 0; + + asm.emitInt(op << 30 | 1 << 28 | 3 << 22 | cc2 << 21 | (d10lo >> 8) << 19 | rs1 << 14 | (d10lo & 0xff) << 5 | regOrImmediate); + } + } + public static class Fmt3a { public Fmt3a(SPARCAssembler masm, int op, int rd, int op3, int rs1, int rs2) { assert op == 2 || op == 3; @@ -158,6 +172,18 @@ } } + public static class Fmt3n { + public Fmt3n(SPARCAssembler masm, int op, int op3, int opf, int rs2, int rd) { + assert op == 2 || op == 3; + assert op3 >= 0 && op3 < 0x40; + assert opf >= 0 && opf < 0x200; + assert rs2 >= 0 && rs2 < 0x20; + assert rd >= 0 && rd < 0x20; + + masm.emitInt(op << 30 | rd << 25 | op3 << 19 | opf << 5 | rs2); + } + } + public static class Fmt3p { public Fmt3p(SPARCAssembler masm, int op, int op3, int opf, int rs1, int rs2, int rd) { assert op == 2 || op == 3; @@ -171,18 +197,6 @@ } } - public static class Fmt3n { - public Fmt3n(SPARCAssembler masm, int op, int op3, int opf, int rs2, int rd) { - assert op == 2 || op == 3; - assert op3 >= 0 && op3 < 0x40; - assert opf >= 0 && opf < 0x200; - assert rs2 >= 0 && rs2 < 0x20; - assert rd >= 0 && rd < 0x20; - - masm.emitInt(op << 30 | rd << 25 | op3 << 19 | opf << 5 | rs2); - } - } - public static class Fmt3q { public Fmt3q(SPARCAssembler masm, int op, int op3, int rs1, int rd) { assert op == 2 || op == 3; @@ -239,6 +253,20 @@ } } + public static class Fmt5a { + public Fmt5a(SPARCAssembler masm, int op, int op3, int op5, int rs1, int rs2, int rs3, int rd) { + assert op == 2; + assert op3 >= 0 && op3 < 0x40; + assert op5 >= 0 && op5 < 0x10; + assert rs1 >= 0 && rs1 < 0x20; + assert rs2 >= 0 && rs2 < 0x20; + assert rs3 >= 0 && rs3 < 0x20; + assert rd >= 0 && rd < 0x20; + + masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | rs3 << 9 | op5 << 5 | rs2); + } + } + public static final int ImmedTrue = 0x00002000; public enum Ops { @@ -389,6 +417,27 @@ } } + public enum Op5s { + Fmadds(0x1), + Fmaddd(0x2), + Fmsubs(0x5), + Fmsubd(0x6), + Fnmsubs(0x9), + Fnmsubd(0xA), + Fnmadds(0xD), + Fnmaddd(0xE); + + private final int value; + + private Op5s(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } + public enum Opfs { Fmovs(0x01, "fmovs"), Fmovd(0x02, "fmovd"), @@ -399,6 +448,62 @@ Fabss(0x09, "fabss"), Fabsd(0x0A, "fabsd"), Fabsq(0x0B, "fabsq"), + + // start VIS1 + Edge8cc(0x0, "edge8cc"), + Edge8n(0x1, "edge8n"), + Edge8lcc(0x2, "edge8lcc"), + Edge8ln(0x3, "edge8ln"), + Edge16cc(0x4, "edge16cc"), + Edge16n(0x5, "edge16n"), + Edge16lcc(0x6, "edge16lcc"), + Edge16ln(0x7, "edge16ln"), + Edge32cc(0x8, "edge32cc"), + Edge32n(0x9, "edge32n"), + Edge32lcc(0xA, "edge32lcc"), + Edge32ln(0xB, "edge32ln"), + Array8(0x10, "array8"), + Array16(0x12, "array16"), + Array32(0x14, "array32"), + AlignAddress(0x18, "alignaddress"), + AlignAddressLittle(0x1A, "alignaddress_little"), + Fmul8x16(0x31, "fmul8x16"), + Fmul8x16au(0x33, "fmul8x16au"), + Fmul8x16al(0x35, "fmul8x16al"), + Fmul8sux16(0x36, "fmul8sux16"), + Fmul8ulx16(0x37, "fmul8ulx16"), + Fmuld8sux16(0x38, "fmuld8sux16"), + Fmuld8ulx16(0x39, "fmuld8ulx16"), + Faligndatag(0x48, "faligndata"), + Fnhadds(0x71, "fnhadds"), + Fnhaddd(0x72, "fnhaddd"), + // end VIS1 + + // start VIS2 + Bmask(0x19, "bmask"), + Bshuffle(0x4c, "bshuffle"), + // end VIS2 only + + // start VIS3 + Addxc(0x11, "addxc"), + Addxccc(0x13, "addxccc"), + Cmask8(0x1B, "cmask8"), + Cmask16(0x1D, "cmask16"), + Cmask32(0x1F, "cmask32"), + Fmean16(0x40, "fmean16"), + Fnadds(0x51, "fnadds"), + Fnaddd(0x52, "fnaddd"), + // end VIS3 + + // start CAMMELLIA + CammelliaFl(0x13C, "cammelia_fl"), + CammelliaFli(0x13D, "cammellia_fli"), + // end CAMMELLIA + + // start CRYPTO + Crc32c(0x147, "crc32c"), + // end CRYPTO + Fadds(0x41, "fadds"), Faddd(0x42, "faddd"), Faddq(0x43, "faddq"), @@ -663,6 +768,38 @@ } } + public static class Addxc extends Fmt3p { + public Addxc(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS3 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Addxc.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Addxccc extends Fmt3p { + public Addxccc(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS3 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Addxccc.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Alignaddr extends Fmt3p { + public Alignaddr(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS1 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.AlignAddress.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Alignaddrl extends Fmt3p { + public Alignaddrl(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS1 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.AlignAddressLittle.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + public static class And extends Fmt3b { public And(SPARCAssembler masm, Register src1, int simm13, Register dst) { super(masm, Ops.ArithOp.getValue(), Op3s.And.getValue(), src1.encoding(), simm13, dst.encoding()); @@ -699,6 +836,38 @@ } } + public static class Array8 extends Fmt3p { + public Array8(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS1 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Array8.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Array16 extends Fmt3p { + public Array16(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS1 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Array16.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Array32 extends Fmt3p { + public Array32(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS1 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Array32.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Bmask extends Fmt3p { + public Bmask(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS2 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Bmask.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + public static class Bpa extends Fmt2c { public Bpa(SPARCAssembler masm, int simmm19) { super(masm, Ops.BranchOp.getValue(), 0, ConditionFlag.Always.getValue(), @@ -891,11 +1060,456 @@ } } + public static class Bshuffle extends Fmt3p { + public Bshuffle(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS2 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Bshuffle.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class CammelliaFl extends Fmt3p { + public CammelliaFl(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* CAMELLIA only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.CammelliaFl.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class CammelliaFli extends Fmt3p { + public CammelliaFli(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* CAMELLIA only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.CammelliaFli.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + private static int patchUnbound(SPARCAssembler masm, Label label) { label.addPatchAt(masm.codeBuffer.position()); return 0; } + public static class Cmask8 extends Fmt3n { + public Cmask8(SPARCAssembler asm, Register src2) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Cmask8.getValue(), + src2.encoding(), 0); + } + } + + public static class Cmask16 extends Fmt3n { + public Cmask16(SPARCAssembler asm, Register src2) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Cmask16.getValue(), + src2.encoding(), 0); + } + } + + public static class Cmask32 extends Fmt3n { + public Cmask32(SPARCAssembler asm, Register src2) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Cmask32.getValue(), + src2.encoding(), 0); + } + } + + public static class Crc32c extends Fmt3p { + public Crc32c(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* CRYPTO only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Crc32c.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Cwbcc extends Fmt2e { + public Cwbcc(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarryClear.getValue(), 0, + src1.encoding(), simm10, src2.encoding()); + } + public Cwbcc(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Equal.getValue(), 0, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cwbcs extends Fmt2e { + public Cwbcs(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarrySet.getValue(), 0, + src1.encoding(), simm10, src2.encoding()); + } + public Cwbcs(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarrySet.getValue(), 0, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cwbe extends Fmt2e { + public Cwbe(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarryClear.getValue(), 0, + src1.encoding(), simm10, src2.encoding()); + } + public Cwbe(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Equal.getValue(), 0, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cwbg extends Fmt2e { + public Cwbg(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Greater.getValue(), 0, + src1.encoding(), simm10, src2.encoding()); + } + public Cwbg(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Greater.getValue(), 0, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cwbge extends Fmt2e { + public Cwbge(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterEqual.getValue(), 0, + src1.encoding(), simm10, src2.encoding()); + } + public Cwbge(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterEqual.getValue(), 0, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cwbgu extends Fmt2e { + public Cwbgu(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterUnsigned.getValue(), 0, + src1.encoding(), simm10, src2.encoding()); + } + public Cwbgu(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterUnsigned.getValue(), 0, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cwbl extends Fmt2e { + public Cwbl(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Less.getValue(), 0, + src1.encoding(), simm10, src2.encoding()); + } + public Cwbl(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Less.getValue(), 0, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cwble extends Fmt2e { + public Cwble(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqual.getValue(), 0, + src1.encoding(), simm10, src2.encoding()); + } + public Cwble(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqual.getValue(), 0, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cwbleu extends Fmt2e { + public Cwbleu(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqualUnsigned.getValue(), 0, + src1.encoding(), simm10, src2.encoding()); + } + public Cwbleu(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqualUnsigned.getValue(), 0, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cwbne extends Fmt2e { + public Cwbne(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.NotEqual.getValue(), 0, + src1.encoding(), simm10, src2.encoding()); + } + public Cwbne(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.NotEqual.getValue(), 0, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cwbneg extends Fmt2e { + public Cwbneg(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Negative.getValue(), 0, + src1.encoding(), simm10, src2.encoding()); + } + public Cwbneg(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Negative.getValue(), 0, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cwbpos extends Fmt2e { + public Cwbpos(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Positive.getValue(), 0, + src1.encoding(), simm10, src2.encoding()); + } + public Cwbpos(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Positive.getValue(), 0, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cwbvc extends Fmt2e { + public Cwbvc(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowClear.getValue(), 0, + src1.encoding(), simm10, src2.encoding()); + } + public Cwbvc(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowClear.getValue(), 0, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cwbvs extends Fmt2e { + public Cwbvs(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowSet.getValue(), 0, + src1.encoding(), simm10, src2.encoding()); + } + public Cwbvs(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowSet.getValue(), 0, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cxbcc extends Fmt2e { + public Cxbcc(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarryClear.getValue(), 1, + src1.encoding(), simm10, src2.encoding()); + } + public Cxbcc(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Equal.getValue(), 1, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cxbcs extends Fmt2e { + public Cxbcs(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarrySet.getValue(), 1, + src1.encoding(), simm10, src2.encoding()); + } + public Cxbcs(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarrySet.getValue(), 1, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cxbe extends Fmt2e { + public Cxbe(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarryClear.getValue(), 1, + src1.encoding(), simm10, src2.encoding()); + } + public Cxbe(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Equal.getValue(), 1, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cxbg extends Fmt2e { + public Cxbg(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Greater.getValue(), 1, + src1.encoding(), simm10, src2.encoding()); + } + public Cxbg(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Greater.getValue(), 1, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cxbge extends Fmt2e { + public Cxbge(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterEqual.getValue(), 1, + src1.encoding(), simm10, src2.encoding()); + } + public Cxbge(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterEqual.getValue(), 1, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cxbgu extends Fmt2e { + public Cxbgu(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterUnsigned.getValue(), 1, + src1.encoding(), simm10, src2.encoding()); + } + public Cxbgu(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterUnsigned.getValue(), 1, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cxbl extends Fmt2e { + public Cxbl(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Less.getValue(), 1, + src1.encoding(), simm10, src2.encoding()); + } + public Cxbl(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Less.getValue(), 1, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cxble extends Fmt2e { + public Cxble(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqual.getValue(), 1, + src1.encoding(), simm10, src2.encoding()); + } + public Cxble(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqual.getValue(), 1, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cxbleu extends Fmt2e { + public Cxbleu(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqualUnsigned.getValue(), 1, + src1.encoding(), simm10, src2.encoding()); + } + public Cxbleu(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqualUnsigned.getValue(), 1, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cxbne extends Fmt2e { + public Cxbne(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.NotEqual.getValue(), 1, + src1.encoding(), simm10, src2.encoding()); + } + public Cxbne(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.NotEqual.getValue(), 1, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cxbneg extends Fmt2e { + public Cxbneg(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Negative.getValue(), 1, + src1.encoding(), simm10, src2.encoding()); + } + public Cxbneg(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Negative.getValue(), 1, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cxbpos extends Fmt2e { + public Cxbpos(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Positive.getValue(), 1, + src1.encoding(), simm10, src2.encoding()); + } + public Cxbpos(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.Positive.getValue(), 1, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cxbvc extends Fmt2e { + public Cxbvc(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowClear.getValue(), 1, + src1.encoding(), simm10, src2.encoding()); + } + public Cxbvc(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowClear.getValue(), 1, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Cxbvs extends Fmt2e { + public Cxbvs(SPARCAssembler asm, Register src1, Register src2, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowSet.getValue(), 1, + src1.encoding(), simm10, src2.encoding()); + } + public Cxbvs(SPARCAssembler asm, Register src1, int immed5, int simm10) { + super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowSet.getValue(), 1, + src1.encoding(), simm10, immed5 | ImmedTrue); + } + } + + public static class Edge8cc extends Fmt3p { + public Edge8cc(SPARCAssembler asm, Register src1, Register src2, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge8cc.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Edge8n extends Fmt3p { + public Edge8n(SPARCAssembler asm, Register src1, Register src2, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge8n.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Edge8lcc extends Fmt3p { + public Edge8lcc(SPARCAssembler asm, Register src1, Register src2, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge8lcc.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Edge8ln extends Fmt3p { + public Edge8ln(SPARCAssembler asm, Register src1, Register src2, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge8ln.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Edge16cc extends Fmt3p { + public Edge16cc(SPARCAssembler asm, Register src1, Register src2, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge16cc.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Edge16n extends Fmt3p { + public Edge16n(SPARCAssembler asm, Register src1, Register src2, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge16n.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Edge16lcc extends Fmt3p { + public Edge16lcc(SPARCAssembler asm, Register src1, Register src2, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge16lcc.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Edge16ln extends Fmt3p { + public Edge16ln(SPARCAssembler asm, Register src1, Register src2, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge16ln.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Edge32cc extends Fmt3p { + public Edge32cc(SPARCAssembler asm, Register src1, Register src2, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge32cc.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Edge32n extends Fmt3p { + public Edge32n(SPARCAssembler asm, Register src1, Register src2, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge32n.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Edge32lcc extends Fmt3p { + public Edge32lcc(SPARCAssembler asm, Register src1, Register src2, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge32lcc.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Edge32ln extends Fmt3p { + public Edge32ln(SPARCAssembler asm, Register src1, Register src2, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Edge32ln.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + public static class Fadds extends Fmt3p { public Fadds(SPARCAssembler masm, Register src1, Register src2, Register dst) { super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fadds.getValue(), @@ -917,6 +1531,13 @@ } } + public static class Faligndata extends Fmt3p { + public Faligndata(SPARCAssembler asm, Register src1, Register src2, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Faligndatag.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + public static class Fdivs extends Fmt3p { public Fdivs(SPARCAssembler masm, Register src1, Register src2, Register dst) { super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fdivs.getValue(), @@ -931,6 +1552,86 @@ } } + public static class Fmadds extends Fmt5a { + public Fmadds(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fmadds.getValue(), + src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding()); + } + } + + public static class Fmaddd extends Fmt5a { + public Fmaddd(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fmaddd.getValue(), + src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding()); + } + } + + public static class Fmean16 extends Fmt3p { + public Fmean16(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS3 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fmean16.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Fmsubs extends Fmt5a { + public Fmsubs(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fmsubs.getValue(), + src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding()); + } + } + + public static class Fmsubd extends Fmt5a { + public Fmsubd(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fmsubd.getValue(), + src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding()); + } + } + + public static class Fnadds extends Fmt3p { + public Fnadds(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS3 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fnadds.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Fnaddd extends Fmt3p { + public Fnaddd(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS3 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fnaddd.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Fnmadds extends Fmt5a { + public Fnmadds(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fnmadds.getValue(), + src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding()); + } + } + + public static class Fnmaddd extends Fmt5a { + public Fnmaddd(SPARCAssembler asm, Register src1, Register src2, Register src3, Register dst) { + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fnmaddd.getValue(), + src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding()); + } + } + + public static class Fnmsubs extends Fmt5a { + public Fnmsubs(SPARCAssembler masm, Register src1, Register src2, Register src3, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fnmsubs.getValue(), + src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding()); + } + } + + public static class Fnmsubd extends Fmt5a { + public Fnmsubd(SPARCAssembler masm, Register src1, Register src2, Register src3, Register dst) { + super(masm, Ops.ArithOp.getValue(), Op3s.Impdep2.getValue(), Op5s.Fnmsubd.getValue(), + src1.encoding(), src2.encoding(), src3.encoding(), dst.encoding()); + } + } + public static class Fmuls extends Fmt3p { public Fmuls(SPARCAssembler masm, Register src1, Register src2, Register dst) { super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fmuls.getValue(), @@ -945,6 +1646,62 @@ } } + public static class Fmul8x16 extends Fmt3p { + public Fmul8x16(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS1 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fmul8x16.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Fmul8x16au extends Fmt3p { + public Fmul8x16au(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS1 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fmul8x16.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Fmul8x16al extends Fmt3p { + public Fmul8x16al(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS1 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fmul8x16al.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Fmul8sux16 extends Fmt3p { + public Fmul8sux16(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS1 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fmul8sux16.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Fmul8ulx16 extends Fmt3p { + public Fmul8ulx16(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS1 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fmul8ulx16.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Fmuld8sux16 extends Fmt3p { + public Fmuld8sux16(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS1 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fmuld8sux16.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + + public static class Fmuld8ulx16 extends Fmt3p { + public Fmuld8ulx16(SPARCAssembler asm, Register src1, Register src2, Register dst) { + /* VIS1 only */ + super(asm, Ops.ArithOp.getValue(), Op3s.Impdep1.getValue(), Opfs.Fmuld8ulx16.getValue(), + src1.encoding(), src2.encoding(), dst.encoding()); + } + } + public static class Fnegs extends Fmt3n { public Fnegs(SPARCAssembler masm, Register src2, Register dst) { super(masm, Ops.ArithOp.getValue(), Op3s.Fpop1.getValue(), Opfs.Fnegs.getValue(), @@ -1463,6 +2220,127 @@ } } + public static class Tcc extends Fmt4a { + public Tcc(SPARCAssembler asm, CC cc, Register src1, int trap) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), trap, ConditionFlag.CarryClear.getValue()); + } + public Tcc(SPARCAssembler asm, CC cc, Register src1, Register src2) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), src2.encoding(), ConditionFlag.CarryClear.getValue()); + } + } + + public static class Tcs extends Fmt4a { + public Tcs(SPARCAssembler asm, CC cc, Register src1, int trap) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), trap, ConditionFlag.CarrySet.getValue()); + } + public Tcs(SPARCAssembler asm, CC cc, Register src1, Register src2) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), src2.encoding(), ConditionFlag.CarrySet.getValue()); + } + } + + public static class Te extends Fmt4a { + public Te(SPARCAssembler asm, CC cc, Register src1, int trap) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), trap, ConditionFlag.Equal.getValue()); + } + public Te(SPARCAssembler asm, CC cc, Register src1, Register src2) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), src2.encoding(), ConditionFlag.Equal.getValue()); + } + } + + public static class Tg extends Fmt4a { + public Tg(SPARCAssembler asm, CC cc, Register src1, int trap) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), trap, ConditionFlag.Greater.getValue()); + } + public Tg(SPARCAssembler asm, CC cc, Register src1, Register src2) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), src2.encoding(), ConditionFlag.Greater.getValue()); + } + } + + public static class Tge extends Fmt4a { + public Tge(SPARCAssembler asm, CC cc, Register src1, int trap) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), trap, ConditionFlag.GreaterEqual.getValue()); + } + public Tge(SPARCAssembler asm, CC cc, Register src1, Register src2) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), src2.encoding(), ConditionFlag.GreaterEqual.getValue()); + } + } + + public static class Tle extends Fmt4a { + public Tle(SPARCAssembler asm, CC cc, Register src1, int trap) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), trap, ConditionFlag.LessEqual.getValue()); + } + public Tle(SPARCAssembler asm, CC cc, Register src1, Register src2) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), src2.encoding(), ConditionFlag.LessEqual.getValue()); + } + } + + public static class Tleu extends Fmt4a { + public Tleu(SPARCAssembler asm, CC cc, Register src1, int trap) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), trap, ConditionFlag.LessEqualUnsigned.getValue()); + } + public Tleu(SPARCAssembler asm, CC cc, Register src1, Register src2) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), src2.encoding(), ConditionFlag.LessEqualUnsigned.getValue()); + } + } + + public static class Tn extends Fmt4a { + public Tn(SPARCAssembler asm, CC cc, Register src1, int trap) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), trap, ConditionFlag.Never.getValue()); + } + public Tn(SPARCAssembler asm, CC cc, Register src1, Register src2) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), src2.encoding(), ConditionFlag.Never.getValue()); + } + } + + public static class Tne extends Fmt4a { + public Tne(SPARCAssembler asm, CC cc, Register src1, int trap) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), trap, ConditionFlag.NotEqual.getValue()); + } + public Tne(SPARCAssembler asm, CC cc, Register src1, Register src2) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), src2.encoding(), ConditionFlag.NotEqual.getValue()); + } + } + + public static class Tneg extends Fmt4a { + public Tneg(SPARCAssembler asm, CC cc, Register src1, int trap) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), trap, ConditionFlag.Negative.getValue()); + } + public Tneg(SPARCAssembler asm, CC cc, Register src1, Register src2) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), src2.encoding(), ConditionFlag.Negative.getValue()); + } + } + + public static class Tpos extends Fmt4a { + public Tpos(SPARCAssembler asm, CC cc, Register src1, int trap) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), trap, ConditionFlag.Positive.getValue()); + } + public Tpos(SPARCAssembler asm, CC cc, Register src1, Register src2) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), src2.encoding(), ConditionFlag.Positive.getValue()); + } + } + public static class Tsubcc extends Fmt3b { public Tsubcc(SPARCAssembler masm, Register src1, int simm13, Register dst) { super(masm, Ops.ArithOp.getValue(), Op3s.Tsubcc.getValue(), src1.encoding(), simm13, dst.encoding()); @@ -1484,6 +2362,28 @@ } } + public static class Tvc extends Fmt4a { + public Tvc(SPARCAssembler asm, CC cc, Register src1, int trap) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), trap, ConditionFlag.OverflowClear.getValue()); + } + public Tvc(SPARCAssembler asm, CC cc, Register src1, Register src2) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), src2.encoding(), ConditionFlag.OverflowClear.getValue()); + } + } + + public static class Tvs extends Fmt4a { + public Tvs(SPARCAssembler asm, CC cc, Register src1, int trap) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), trap, ConditionFlag.OverflowSet.getValue()); + } + public Tvs(SPARCAssembler asm, CC cc, Register src1, Register src2) { + super(asm, Ops.ArithOp.getValue(), Op3s.Trap.getValue(), cc.getValue(), + src1.encoding(), src2.encoding(), ConditionFlag.OverflowSet.getValue()); + } + } + @Deprecated public static class Udiv extends Fmt3b { @Deprecated diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Mon Jun 10 08:44:25 2013 +0200 @@ -212,6 +212,19 @@ } @SuppressWarnings("unused") + public static class Mov { + + public Mov(SPARCAssembler asm, Register src1, Register dst) { + assert src1.encoding() != dst.encoding(); + new Or(asm, SPARC.g0, src1, dst); + } + + public Mov(SPARCAssembler asm, int simm13, Register dst) { + new Or(asm, SPARC.g0, simm13, dst); + } + } + + @SuppressWarnings("unused") public static class Not { public Not(SPARCAssembler asm, Register src1, Register dst) { diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Mon Jun 10 08:44:25 2013 +0200 @@ -119,6 +119,13 @@ @Override public void emitMove(AllocatableValue dst, Value src) { + // XXX SPARCAddress loads + /* + * if (src instanceof SPARCAddressValue) { public LoadOp(Kind kind, AllocatableValue result, + * SPARCAddressValue address, LIRFrameState state) { + * + * return new LoadOp(result.getKind(), result, (SPARCAddressValue) src); } + */ if (isRegister(src) || isStackSlot(dst)) { append(new MoveFromRegOp(dst, src)); } else { diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Mon Jun 10 08:44:25 2013 +0200 @@ -309,7 +309,7 @@ Assumptions assumptions = new Assumptions(false); HighTierContext context = new HighTierContext(runtime(), assumptions, replacements); new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); - new PartialEscapeAnalysisPhase(false, false, new CanonicalizerPhase(true)).apply(graph, context); + new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context); new CullFrameStatesPhase().apply(graph); } @@ -333,7 +333,7 @@ } new DeadCodeEliminationPhase().apply(graph); canonicalizer.apply(graph, context); - new PartialEscapeAnalysisPhase(false, false, canonicalizer).apply(graph, context); + new PartialEscapePhase(false, canonicalizer).apply(graph, context); new CullFrameStatesPhase().apply(graph); new DeadCodeEliminationPhase().apply(graph); diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Mon Jun 10 08:44:25 2013 +0200 @@ -222,7 +222,7 @@ HighTierContext context = new HighTierContext(runtime(), assumptions, replacements); new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); new DeadCodeEliminationPhase().apply(graph); - new PartialEscapeAnalysisPhase(iterativeEscapeAnalysis, false, new CanonicalizerPhase(true)).apply(graph, context); + new PartialEscapePhase(iterativeEscapeAnalysis, new CanonicalizerPhase(true)).apply(graph, context); Assert.assertEquals(1, graph.getNodes(ReturnNode.class).count()); ReturnNode returnNode = graph.getNodes(ReturnNode.class).first(); if (expectedConstantResult != null) { diff -r de73bbbde021 -r 8ad4e90fc5d7 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 Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java Mon Jun 10 08:44:25 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.compiler.test.ea; -import static com.oracle.graal.phases.GraalOptions.*; import static org.junit.Assert.*; import java.util.concurrent.*; @@ -81,19 +80,6 @@ assertEquals(graph.getLocal(0), result); } - @SuppressWarnings("all") - public static int testSimpleReadSnippet(TestObject a, int b) throws Exception { - a.callable = new TestInt(b, 9); - return a.callable.call(); - } - - @Test - public void testSimpleRead() { - ValueNode result = getReturn("testSimpleReadSnippet").result(); - assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); - assertEquals(graph.getLocal(1), result); - } - final ReturnNode getReturn(String snippet) { processMethod(snippet); assertEquals(1, graph.getNodes(ReturnNode.class).count()); @@ -102,8 +88,7 @@ private void processMethod(final String snippet) { graph = parse(snippet); - OptEarlyReadElimination.setValue(true); HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements); - new IterativeInliningPhase(replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL, false, new CanonicalizerPhase(true)).apply(graph, context); + new IterativeInliningPhase(replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL, new CanonicalizerPhase(true)).apply(graph, context); } } diff -r de73bbbde021 -r 8ad4e90fc5d7 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 Mon Jun 10 08:44:03 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,229 +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.compiler.test.ea; - -import static org.junit.Assert.*; - -import java.util.concurrent.*; - -import org.junit.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.compiler.test.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.phases.*; -import com.oracle.graal.phases.common.*; -import com.oracle.graal.phases.tiers.*; -import com.oracle.graal.virtual.phases.ea.*; - -public class PEAReadEliminationTest extends GraalCompilerTest { - - private StructuredGraph graph; - - public static Object staticField; - - public static class TestObject implements Callable { - - public int x; - public int y; - - public TestObject(int x, int y) { - this.x = x; - this.y = y; - } - - @Override - public Integer call() throws Exception { - return x; - } - } - - public static class TestObject2 { - - public Object x; - public Object y; - - public TestObject2(Object x, Object y) { - this.x = x; - this.y = y; - } - } - - @SuppressWarnings("all") - public static int testSimpleSnippet(TestObject a) { - a.x = 2; - staticField = a; - return a.x; - } - - @Test - public void testSimple() { - ValueNode result = getReturn("testSimpleSnippet").result(); - assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); - assertTrue(result.isConstant()); - assertEquals(2, result.asConstant().asInt()); - } - - @SuppressWarnings("all") - public static int testSimpleConflictSnippet(TestObject a, TestObject b) { - a.x = 2; - b.x = 3; - staticField = a; - return a.x; - } - - @Test - public void testSimpleConflict() { - ValueNode result = getReturn("testSimpleConflictSnippet").result(); - assertFalse(result.isConstant()); - assertTrue(result instanceof LoadFieldNode); - } - - @SuppressWarnings("all") - public static int testParamSnippet(TestObject a, int b) { - a.x = b; - return a.x; - } - - @Test - public void testParam() { - ValueNode result = getReturn("testParamSnippet").result(); - assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); - assertEquals(graph.getLocal(1), result); - } - - @SuppressWarnings("all") - public static int testMaterializedSnippet(int a) { - TestObject obj = new TestObject(a, 0); - staticField = obj; - return obj.x; - } - - @Test - public void testMaterialized() { - ValueNode result = getReturn("testMaterializedSnippet").result(); - assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); - assertEquals(graph.getLocal(0), result); - } - - @SuppressWarnings("all") - public static int testSimpleLoopSnippet(TestObject obj, int a, int b) { - obj.x = a; - for (int i = 0; i < 10; i++) { - staticField = obj; - } - return obj.x; - } - - @Test - public void testSimpleLoop() { - ValueNode result = getReturn("testSimpleLoopSnippet").result(); - assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); - assertEquals(graph.getLocal(1), result); - } - - @SuppressWarnings("all") - public static int testBadLoopSnippet(TestObject obj, TestObject obj2, int a, int b) { - obj.x = a; - for (int i = 0; i < 10; i++) { - staticField = obj; - obj2.x = 10; - obj.x = 0; - } - return obj.x; - } - - @Test - public void testBadLoop() { - ValueNode result = getReturn("testBadLoopSnippet").result(); - assertEquals(0, graph.getNodes(LoadFieldNode.class).count()); - assertTrue(result instanceof ProxyNode); - assertTrue(((ProxyNode) result).value() instanceof PhiNode); - } - - @SuppressWarnings("all") - public static int testBadLoop2Snippet(TestObject obj, TestObject obj2, int a, int b) { - obj.x = a; - for (int i = 0; i < 10; i++) { - obj.x = 0; - obj2.x = 10; - } - return obj.x; - } - - @Test - public void testBadLoop2() { - ValueNode result = getReturn("testBadLoop2Snippet").result(); - assertEquals(1, graph.getNodes(LoadFieldNode.class).count()); - assertTrue(result instanceof LoadFieldNode); - } - - @SuppressWarnings("all") - public static int testPhiSnippet(TestObject a, int b) { - if (b < 0) { - a.x = 1; - } else { - a.x = 2; - } - return a.x; - } - - @Test - public void testPhi() { - ValueNode result = getReturn("testPhiSnippet").result(); - assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty()); - assertTrue(result instanceof PhiNode); - PhiNode phi = (PhiNode) result; - assertTrue(phi.valueAt(0).isConstant()); - assertTrue(phi.valueAt(1).isConstant()); - assertEquals(1, phi.valueAt(0).asConstant().asInt()); - assertEquals(2, phi.valueAt(1).asConstant().asInt()); - } - - @SuppressWarnings("all") - public static void testSimpleStoreSnippet(TestObject a, int b) { - a.x = b; - a.x = b; - } - - @Test - public void testSimpleStore() { - processMethod("testSimpleStoreSnippet"); - assertEquals(1, graph.getNodes().filter(StoreFieldNode.class).count()); - } - - final ReturnNode getReturn(String snippet) { - processMethod(snippet); - assertEquals(1, graph.getNodes(ReturnNode.class).count()); - return graph.getNodes(ReturnNode.class).first(); - } - - private void processMethod(final String snippet) { - graph = parse(snippet); - Assumptions assumptions = new Assumptions(false); - HighTierContext context = new HighTierContext(runtime(), assumptions, replacements); - new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); - new PartialEscapeAnalysisPhase(false, true, new CanonicalizerPhase(true)).apply(graph, context); - } -} diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Mon Jun 10 08:44:25 2013 +0200 @@ -166,7 +166,7 @@ new DeadCodeEliminationPhase().apply(graph); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); canonicalizer.apply(graph, context); - new PartialEscapeAnalysisPhase(false, false, canonicalizer).apply(graph, context); + new PartialEscapePhase(false, canonicalizer).apply(graph, context); new CullFrameStatesPhase().apply(graph); new DeadCodeEliminationPhase().apply(graph); diff -r de73bbbde021 -r 8ad4e90fc5d7 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 Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Mon Jun 10 08:44:25 2013 +0200 @@ -150,7 +150,7 @@ if (Inline.getValue() && !plan.isPhaseDisabled(InliningPhase.class)) { if (IterativeInlining.getValue()) { - new IterativeInliningPhase(replacements, cache, plan, optimisticOpts, OptEarlyReadElimination.getValue(), canonicalizer).apply(graph, highTierContext); + new IterativeInliningPhase(replacements, cache, plan, optimisticOpts, canonicalizer).apply(graph, highTierContext); } else { new InliningPhase(runtime, null, replacements, assumptions, cache, plan, optimisticOpts).apply(graph); new DeadCodeEliminationPhase().apply(graph); diff -r de73bbbde021 -r 8ad4e90fc5d7 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 Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Mon Jun 10 08:44:25 2013 +0200 @@ -68,12 +68,6 @@ protected Block currentBlock; private ValueNode currentInstruction; private ValueNode lastInstructionPrinted; // Debugging only - private FrameState lastState; - - /** - * Mapping from blocks to the last encountered frame state at the end of the block. - */ - private final BlockMap blockLastState; /** * Checks whether the supplied constant can be used without loading it into a register for store @@ -100,7 +94,6 @@ this.nodeOperands = graph.createNodeMap(); this.lir = lir; this.debugInfoBuilder = createDebugInfoBuilder(nodeOperands); - this.blockLastState = new BlockMap<>(lir.cfg); } @SuppressWarnings("hiding") @@ -291,41 +284,8 @@ if (block == lir.cfg.getStartBlock()) { assert block.getPredecessorCount() == 0; emitPrologue(); - } else { assert block.getPredecessorCount() > 0; - FrameState fs = null; - - for (Block pred : block.getPredecessors()) { - if (fs == null) { - fs = blockLastState.get(pred); - } else { - if (blockLastState.get(pred) == null) { - // Only a back edge can have a null state for its enclosing block. - assert pred.getEndNode() instanceof LoopEndNode; - - if (block.getBeginNode().stateAfter() == null) { - // We'll assert later that the begin and end of a framestate-less loop - // share the frame state that flowed into the loop - blockLastState.put(pred, fs); - } - } else if (fs != blockLastState.get(pred)) { - fs = null; - break; - } - } - } - if (TraceLIRGeneratorLevel.getValue() >= 2) { - if (fs == null) { - TTY.println("STATE RESET"); - } else { - TTY.println("STATE CHANGE (singlePred)"); - if (TraceLIRGeneratorLevel.getValue() >= 3) { - TTY.println(fs.toString(Node.Verbosity.Debugger)); - } - } - } - lastState = fs; } List nodes = lir.nodesFor(block); @@ -334,10 +294,6 @@ if (TraceLIRGeneratorLevel.getValue() >= 3) { TTY.println("LIRGen for " + instr); } - FrameState stateAfter = null; - if (instr instanceof StateSplit && !(instr instanceof InfopointNode)) { - stateAfter = ((StateSplit) instr).stateAfter(); - } if (instr instanceof ValueNode) { ValueNode valueNode = (ValueNode) instr; if (operand(valueNode) == null) { @@ -355,16 +311,6 @@ // before by other instructions. } } - if (stateAfter != null) { - lastState = stateAfter; - assert checkStateReady(lastState); - if (TraceLIRGeneratorLevel.getValue() >= 2) { - TTY.println("STATE CHANGE"); - if (TraceLIRGeneratorLevel.getValue() >= 3) { - TTY.println(stateAfter.toString(Node.Verbosity.Debugger)); - } - } - } } if (block.getSuccessorCount() >= 1 && !endsWithJump(block)) { NodeClassIterable successors = block.getEndNode().successors(); @@ -377,11 +323,6 @@ TTY.println("END Generating LIR for block B" + block.getId()); } - // Check that the begin and end of a framestate-less loop - // share the frame state that flowed into the loop - assert blockLastState.get(block) == null || blockLastState.get(block) == lastState; - - blockLastState.put(block, lastState); currentBlock = null; if (PrintIRWithLIR.getValue()) { @@ -391,19 +332,6 @@ protected abstract boolean peephole(ValueNode valueNode); - private boolean checkStateReady(FrameState state) { - FrameState fs = state; - while (fs != null) { - for (ValueNode v : fs.values()) { - if (v != null && !(v instanceof VirtualObjectNode)) { - assert operand(v) != null : "Value " + v + " in " + fs + " is not ready!"; - } - } - fs = fs.outerFrameState(); - } - return true; - } - private boolean endsWithJump(Block block) { List instructions = lir.lir(block); if (instructions.size() == 0) { diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Mon Jun 10 08:44:25 2013 +0200 @@ -45,7 +45,7 @@ } if (PartialEscapeAnalysis.getValue()) { - addPhase(new PartialEscapeAnalysisPhase(true, OptEarlyReadElimination.getValue(), canonicalizer)); + addPhase(new PartialEscapePhase(true, canonicalizer)); } if (OptConvertDeoptsToGuards.getValue()) { diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java Mon Jun 10 08:44:25 2013 +0200 @@ -25,6 +25,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.sparc.*; /** * SPARC specific implementation of {@link HotSpotGraalRuntime}. @@ -44,10 +45,15 @@ return graalRuntime(); } + protected static Architecture createArchitecture() { + return new SPARC(); + } + @Override protected TargetDescription createTarget() { - // SPARC: Create target description. - throw new InternalError("NYI"); + final int stackFrameAlignment = 16; + final int implicitNullCheckLimit = 4096; + return new TargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, true); } @Override diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Mon Jun 10 08:44:25 2013 +0200 @@ -31,6 +31,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.target.*; +import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.logging.*; import com.oracle.graal.hotspot.meta.*; @@ -87,9 +88,11 @@ runtime.compilerToVm = toVM; } + private static final String DEFAULT_GRAAL_RUNTIME = "basic"; + // @formatter:off @Option(help = "The runtime configuration to use") - private static final OptionValue GraalRuntime = new OptionValue<>("basic"); + private static final OptionValue GraalRuntime = new OptionValue<>(DEFAULT_GRAAL_RUNTIME); // @formatter:on protected static HotSpotGraalRuntimeFactory findFactory(String architecture) { @@ -98,6 +101,11 @@ return factory; } } + if (!DEFAULT_GRAAL_RUNTIME.equals(GraalRuntime.getValue())) { + // Fail fast if a non-default value for GraalRuntime was specified + // and the corresponding factory is not available + throw new GraalInternalError("Specified runtime \"%s\" not available for the %s architecture", GraalRuntime.getValue(), architecture); + } return null; } diff -r de73bbbde021 -r 8ad4e90fc5d7 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 Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Mon Jun 10 08:44:25 2013 +0200 @@ -23,16 +23,28 @@ package com.oracle.graal.hotspot; +import static java.nio.file.Files.*; + +import java.io.*; +import java.nio.charset.*; +import java.nio.file.*; import java.util.*; import com.oracle.graal.hotspot.logging.*; import com.oracle.graal.options.*; +/** + * Called from {@code graalCompiler.cpp} to parse any Graal specific options. Such options are + * (currently) distinguished by a {@code "-G:"} prefix. + */ public class HotSpotOptions { private static final Map options = new HashMap<>(); - static { + /** + * Initializes {@link #options} from {@link Options} services. + */ + private static void initializeOptions() { ServiceLoader sl = ServiceLoader.loadInstalled(Options.class); for (Options opts : sl) { for (OptionDescriptor desc : opts) { @@ -45,6 +57,38 @@ } } + /** + * Loads default option value overrides from a {@code graal.options} file if it exists. Each + * line in this file starts with {@code "#"} and is ignored or must have the format of a Graal + * command line option without the leading {@code "-G:"} prefix. These option value are set + * prior to processing of any Graal options present on the command line. + */ + private static void loadOptionOverrides() throws InternalError { + String javaHome = System.getProperty("java.home"); + Path graalDotOptions = Paths.get(javaHome, "lib", "graal.options"); + if (!exists(graalDotOptions)) { + graalDotOptions = Paths.get(javaHome, "jre", "lib", "graal.options"); + } + if (exists(graalDotOptions)) { + try { + for (String line : Files.readAllLines(graalDotOptions, Charset.defaultCharset())) { + if (!line.startsWith("#")) { + if (!setOption(line)) { + throw new InternalError("Invalid option \"" + line + "\" specified in " + graalDotOptions); + } + } + } + } catch (IOException e) { + throw (InternalError) new InternalError().initCause(e); + } + } + } + + static { + initializeOptions(); + loadOptionOverrides(); + } + // Called from VM code public static boolean setOption(String option) { if (option.length() == 0) { diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java Mon Jun 10 08:44:25 2013 +0200 @@ -373,6 +373,12 @@ } } else { switch (opcode) { + // case A: new Add(Int, dst, src1, src2); + // case S: new Sub(Int, dst, src1, src2); + // case U: new Shl(UnsignedInt, dst, src1, src2); + // case L: new Shl(UnsignedLong, dst, src1, src2); + // case F: new Add(Float, dst, src1, src2); + // case D: new Mul(Double, dst, src1, src2); case IADD: masm.add_s32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break; case ISUB: masm.sub_s32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break; case IMUL: masm.mul_s32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break; diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Mon Jun 10 08:44:25 2013 +0200 @@ -22,9 +22,16 @@ */ package com.oracle.graal.lir.sparc; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Andn; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Ldsw; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Ldx; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Or; import static com.oracle.graal.asm.sparc.SPARCAssembler.Popc; import static com.oracle.graal.asm.sparc.SPARCAssembler.Srl; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Srlx; +import static com.oracle.graal.asm.sparc.SPARCAssembler.Sub; import static com.oracle.graal.asm.sparc.SPARCAssembler.isSimm13; +import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; @@ -54,6 +61,7 @@ @SuppressWarnings("unused") public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) { Register dst = ValueUtil.asIntReg(result); + Register tmp = null; // ?? if (ValueUtil.isRegister(input)) { Register src = ValueUtil.asRegister(input); switch (opcode) { @@ -65,9 +73,64 @@ case LPOPCNT: new Popc(masm, src, dst); break; - case BSF: // masm.bsfq(dst, src); - case IBSR: // masm.bsrl(dst, src); - case LBSR: // masm.bsrq(dst, src); + case BSF: + // countTrailingZerosI - bsfl + // countTrailingZerosL - masm.bsfq(dst, src); + Kind tkind = input.getKind(); + if (tkind == Kind.Int) { + new Sub(masm, src, 1, dst); + new Andn(masm, dst, src, dst); + new Srl(masm, dst, SPARC.g0, dst); + new Popc(masm, dst, dst); + } else if (tkind == Kind.Long) { + new Sub(masm, src, 1, dst); + new Andn(masm, dst, src, dst); + new Popc(masm, dst, dst); + } else { + throw GraalInternalError.shouldNotReachHere("missing: " + tkind); + } + break; + case IBSR: + // countLeadingZerosI_bsr masm.bsrq(dst, src); + // masm.bsrl(dst, src); + Kind ikind = input.getKind(); + assert ikind == Kind.Int; + new Srl(masm, src, 1, tmp); + new Srl(masm, src, 0, dst); + new Or(masm, src, tmp, dst); + new Srl(masm, dst, 2, tmp); + new Or(masm, dst, tmp, dst); + new Srl(masm, dst, 4, tmp); + new Or(masm, dst, tmp, dst); + new Srl(masm, dst, 8, tmp); + new Or(masm, dst, tmp, dst); + new Srl(masm, dst, 16, tmp); + new Or(masm, dst, tmp, dst); + new Popc(masm, dst, dst); + new Mov(masm, ikind.getBitCount(), tmp); + new Sub(masm, tmp, dst, dst); + break; + case LBSR: + // countLeadingZerosL_bsr masm.bsrq(dst, src); + // masm.bsrq(dst, src); + Kind lkind = input.getKind(); + assert lkind == Kind.Int; + new Srlx(masm, src, 1, tmp); + new Or(masm, src, tmp, dst); + new Srlx(masm, dst, 2, tmp); + new Or(masm, dst, tmp, dst); + new Srlx(masm, dst, 4, tmp); + new Or(masm, dst, tmp, dst); + new Srlx(masm, dst, 8, tmp); + new Or(masm, dst, tmp, dst); + new Srlx(masm, dst, 16, tmp); + new Or(masm, dst, tmp, dst); + new Srlx(masm, dst, 32, tmp); + new Or(masm, dst, tmp, dst); + new Popc(masm, dst, dst); + new Mov(masm, lkind.getBitCount(), tmp); + new Sub(masm, tmp, dst, dst); + break; default: throw GraalInternalError.shouldNotReachHere("missing: " + opcode); @@ -87,20 +150,41 @@ SPARCAddress src = (SPARCAddress) tasm.asAddress(input); switch (opcode) { case IPOPCNT: - // masm.popcntl(dst, src); + new Ldsw(masm, src, tmp); + // clear upper word for 64 bit POPC + new Srl(masm, tmp, SPARC.g0, dst); + new Popc(masm, tmp, dst); break; case LPOPCNT: - // masm.popcntq(dst, src); + new Ldx(masm, src, tmp); + new Popc(masm, tmp, dst); break; case BSF: - // masm.bsfq(dst, src); + assert input.getKind() == Kind.Int; + new Ldsw(masm, src, tmp); + new Srl(masm, tmp, 1, tmp); + new Srl(masm, tmp, 0, dst); + new Or(masm, tmp, tmp, dst); + new Srl(masm, dst, 2, tmp); + new Or(masm, dst, tmp, dst); + new Srl(masm, dst, 4, tmp); + new Or(masm, dst, tmp, dst); + new Srl(masm, dst, 8, tmp); + new Or(masm, dst, tmp, dst); + new Srl(masm, dst, 16, tmp); + new Or(masm, dst, tmp, dst); + new Popc(masm, dst, dst); + new Mov(masm, Kind.Int.getBitCount(), tmp); + new Sub(masm, tmp, dst, dst); break; case IBSR: // masm.bsrl(dst, src); - break; + // countLeadingZerosI_bsr masm.bsrq(dst, src); + // masm.bsrl(dst, src); case LBSR: // masm.bsrq(dst, src); - break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + opcode); } } } diff -r de73bbbde021 -r 8ad4e90fc5d7 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 Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java Mon Jun 10 08:44:25 2013 +0200 @@ -29,7 +29,7 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "*") -public final class IntegerMulNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable { +public class IntegerMulNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable { public IntegerMulNode(Kind kind, ValueNode x, ValueNode y) { super(kind, x, y); diff -r de73bbbde021 -r 8ad4e90fc5d7 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 Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java Mon Jun 10 08:44:25 2013 +0200 @@ -29,7 +29,7 @@ import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "-") -public final class IntegerSubNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable { +public class IntegerSubNode extends IntegerArithmeticNode implements Canonicalizable, LIRLowerable { public IntegerSubNode(Kind kind, ValueNode x, ValueNode y) { super(kind, x, y); diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Mon Jun 10 08:44:25 2013 +0200 @@ -105,10 +105,15 @@ @Override public void setDeoptimizationState(FrameState f) { updateUsages(deoptState, f); - if (deoptState != null) { - throw new IllegalStateException(toString(Verbosity.Debugger)); + assert deoptState == null && canDeoptimize() : "shouldn't assign deoptState to " + this; + deoptState = f; + } + + @Override + public void setStateAfter(FrameState x) { + if (hasSideEffect() || canDeoptimize()) { + super.setStateAfter(x); } - deoptState = f; } @Override diff -r de73bbbde021 -r 8ad4e90fc5d7 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 Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Mon Jun 10 08:44:25 2013 +0200 @@ -79,13 +79,6 @@ if (fieldIndex != -1) { tool.replaceWith(state.getEntry(fieldIndex)); } - } else { - ValueNode cachedValue = tool.getReadCache(object(), field()); - if (cachedValue != null) { - tool.replaceWithValue(cachedValue); - } else { - tool.addReadCache(object(), field(), this); - } } } } diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java Mon Jun 10 08:44:25 2013 +0200 @@ -77,12 +77,6 @@ tool.setVirtualEntry(state, fieldIndex, value()); tool.delete(); } - } else { - if (value() == tool.getReadCache(object(), field())) { - tool.delete(); - } - tool.killReadCache(field()); - tool.addReadCache(object(), field(), value()); } } } diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Virtualizable.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Virtualizable.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Virtualizable.java Mon Jun 10 08:44:25 2013 +0200 @@ -43,8 +43,6 @@ public abstract VirtualObjectNode getVirtualObject(); - public abstract void setEntry(int index, ValueNode value); - public abstract ValueNode getEntry(int index); public abstract void addLock(int depth); diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java Mon Jun 10 08:44:25 2013 +0200 @@ -153,10 +153,4 @@ */ void replaceWith(ValueNode value); - void addReadCache(ValueNode object, ResolvedJavaField identity, ValueNode value); - - ValueNode getReadCache(ValueNode object, ResolvedJavaField identity); - - void killReadCache(ResolvedJavaField identity); - } diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java Mon Jun 10 08:44:25 2013 +0200 @@ -37,6 +37,11 @@ this.fields = type.getInstanceFields(true); } + public VirtualInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields) { + this.type = type; + this.fields = fields; + } + @Override public ResolvedJavaType type() { return type; diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java --- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java Mon Jun 10 08:44:25 2013 +0200 @@ -159,7 +159,7 @@ String help = option.help; String location = pkg + "." + option.declaringClass + "." + option.field.getSimpleName(); String comma = i == info.options.size() - 1 ? "" : ","; - out.printf(" new %s(\"%s\", %s.class, \"%s\", \"%s\", %s)%s%n", OptionDescriptor.class.getSimpleName(), name, type, help, location, optionValue, comma); + out.printf(" new %s(\"%s\", %s.class, \"%s\", \"%s\", %s)%s\n", OptionDescriptor.class.getSimpleName(), name, type, help, location, optionValue, comma); i++; } out.println(" );"); diff -r de73bbbde021 -r 8ad4e90fc5d7 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 Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Mon Jun 10 08:44:25 2013 +0200 @@ -257,8 +257,6 @@ @Option(help = "") public static final OptionValue OptReadElimination = new OptionValue<>(true); @Option(help = "") - public static final OptionValue OptEarlyReadElimination = new OptionValue<>(true); - @Option(help = "") public static final OptionValue OptCanonicalizer = new OptionValue<>(true); @Option(help = "") public static final OptionValue OptCanonicalizeReads = new OptionValue<>(true); diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MonitorTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MonitorTest.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MonitorTest.java Mon Jun 10 08:44:25 2013 +0200 @@ -63,7 +63,7 @@ } /** - * Tests monitor operations on {@link PartialEscapeAnalysisPhase virtual objects}. + * Tests monitor operations on {@link PartialEscapePhase virtual objects}. */ @Test public void test3() { diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Mon Jun 10 08:44:25 2013 +0200 @@ -22,17 +22,20 @@ */ package com.oracle.graal.replacements.nodes; +import static com.oracle.graal.api.meta.LocationIdentity.*; + import java.lang.reflect.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +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.phases.common.*; -public class MacroNode extends AbstractStateSplit implements Lowerable { +public class MacroNode extends AbstractStateSplit implements Lowerable, MemoryCheckpoint { @Input protected final NodeInputList arguments; @@ -106,4 +109,9 @@ } } } + + @Override + public LocationIdentity[] getLocationIdentities() { + return new LocationIdentity[]{ANY_LOCATION}; + } } diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java Mon Jun 10 08:44:03 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,306 +0,0 @@ -/* - * 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.virtual.phases.ea; - -import java.util.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.Virtualizable.EscapeState; -import com.oracle.graal.nodes.virtual.*; - -public class BlockState { - - protected final IdentityHashMap objectStates = new IdentityHashMap<>(); - protected final IdentityHashMap objectAliases; - protected final IdentityHashMap scalarAliases; - final HashMap readCache; - - static class ReadCacheEntry { - - public final ResolvedJavaField identity; - public final ValueNode object; - - public ReadCacheEntry(ResolvedJavaField identity, ValueNode object) { - this.identity = identity; - this.object = object; - } - - @Override - public int hashCode() { - int result = 31 + ((identity == null) ? 0 : identity.hashCode()); - return 31 * result + ((object == null) ? 0 : object.hashCode()); - } - - @Override - public boolean equals(Object obj) { - ReadCacheEntry other = (ReadCacheEntry) obj; - return identity == other.identity && object == other.object; - } - - @Override - public String toString() { - return object + ":" + identity; - } - } - - public BlockState() { - objectAliases = new IdentityHashMap<>(); - scalarAliases = new IdentityHashMap<>(); - readCache = new HashMap<>(); - } - - public BlockState(BlockState other) { - for (Map.Entry entry : other.objectStates.entrySet()) { - objectStates.put(entry.getKey(), entry.getValue().cloneState()); - } - objectAliases = new IdentityHashMap<>(other.objectAliases); - scalarAliases = new IdentityHashMap<>(other.scalarAliases); - readCache = new HashMap<>(other.readCache); - } - - public void addReadCache(ValueNode object, ResolvedJavaField identity, ValueNode value) { - ValueNode cacheObject; - ObjectState obj = getObjectState(object); - if (obj != null) { - assert !obj.isVirtual(); - cacheObject = obj.getMaterializedValue(); - } else { - cacheObject = object; - } - readCache.put(new ReadCacheEntry(identity, cacheObject), value); - } - - public ValueNode getReadCache(ValueNode object, ResolvedJavaField identity) { - ValueNode cacheObject; - ObjectState obj = getObjectState(object); - if (obj != null) { - assert !obj.isVirtual(); - cacheObject = obj.getMaterializedValue(); - } else { - cacheObject = object; - } - ValueNode cacheValue = readCache.get(new ReadCacheEntry(identity, cacheObject)); - obj = getObjectState(cacheValue); - if (obj != null) { - assert !obj.isVirtual(); - cacheValue = obj.getMaterializedValue(); - } else { - cacheValue = getScalarAlias(cacheValue); - } - return cacheValue; - } - - public void killReadCache() { - readCache.clear(); - } - - public void killReadCache(ResolvedJavaField identity) { - Iterator> iter = readCache.entrySet().iterator(); - while (iter.hasNext()) { - Map.Entry entry = iter.next(); - if (entry.getKey().identity == identity) { - iter.remove(); - } - } - } - - public ObjectState getObjectState(VirtualObjectNode object) { - assert objectStates.containsKey(object); - return objectStates.get(object); - } - - public ObjectState getObjectStateOptional(VirtualObjectNode object) { - return objectStates.get(object); - } - - public ObjectState getObjectState(ValueNode value) { - VirtualObjectNode object = objectAliases.get(value); - return object == null ? null : getObjectState(object); - } - - public BlockState cloneState() { - return new BlockState(this); - } - - public BlockState cloneEmptyState() { - return new BlockState(); - } - - public void materializeBefore(FixedNode fixed, VirtualObjectNode virtual, EscapeState state, GraphEffectList materializeEffects) { - PartialEscapeClosure.METRIC_MATERIALIZATIONS.increment(); - List objects = new ArrayList<>(2); - List values = new ArrayList<>(8); - List locks = new ArrayList<>(2); - List otherAllocations = new ArrayList<>(2); - materializeWithCommit(fixed, virtual, objects, locks, values, otherAllocations, state); - - materializeEffects.addMaterializationBefore(fixed, objects, locks, values, otherAllocations); - } - - private void materializeWithCommit(FixedNode fixed, VirtualObjectNode virtual, List objects, List locks, List values, List otherAllocations, - EscapeState state) { - VirtualUtil.trace("materializing %s", virtual); - ObjectState obj = getObjectState(virtual); - - ValueNode[] entries = obj.getEntries(); - ValueNode representation = virtual.getMaterializedRepresentation(fixed, entries, obj.getLocks()); - obj.escape(representation, state); - if (representation instanceof AllocatedObjectNode) { - objects.add((AllocatedObjectNode) representation); - locks.add(obj.getLocks()); - int pos = values.size(); - while (values.size() < pos + entries.length) { - values.add(null); - } - for (int i = 0; i < entries.length; i++) { - ObjectState entryObj = getObjectState(entries[i]); - if (entryObj != null) { - if (entryObj.isVirtual()) { - materializeWithCommit(fixed, entryObj.getVirtualObject(), objects, locks, values, otherAllocations, state); - } - values.set(pos + i, entryObj.getMaterializedValue()); - } else { - values.set(pos + i, entries[i]); - } - } - if (virtual instanceof VirtualInstanceNode) { - VirtualInstanceNode instance = (VirtualInstanceNode) virtual; - for (int i = 0; i < entries.length; i++) { - readCache.put(new ReadCacheEntry(instance.field(i), representation), values.get(pos + i)); - } - } - } else { - otherAllocations.add(representation); - assert obj.getLocks().length == 0; - } - } - - void addAndMarkAlias(VirtualObjectNode virtual, ValueNode node, NodeBitMap usages) { - objectAliases.put(node, virtual); - if (node.isAlive()) { - for (Node usage : node.usages()) { - markVirtualUsages(usage, usages); - } - } - } - - private void markVirtualUsages(Node node, NodeBitMap usages) { - if (!usages.isNew(node)) { - usages.mark(node); - } - if (node instanceof VirtualState) { - for (Node usage : node.usages()) { - markVirtualUsages(usage, usages); - } - } - } - - public void addObject(VirtualObjectNode virtual, ObjectState state) { - objectStates.put(virtual, state); - } - - public void addScalarAlias(ValueNode alias, ValueNode value) { - scalarAliases.put(alias, value); - } - - public ValueNode getScalarAlias(ValueNode alias) { - ValueNode result = scalarAliases.get(alias); - return result == null ? alias : result; - } - - public Iterable getStates() { - return objectStates.values(); - } - - public Collection getVirtualObjects() { - return objectAliases.values(); - } - - @Override - public String toString() { - return objectStates + " " + readCache; - } - - public void meetAliases(List states) { - objectAliases.putAll(states.get(0).objectAliases); - scalarAliases.putAll(states.get(0).scalarAliases); - for (int i = 1; i < states.size(); i++) { - BlockState state = states.get(i); - meetMaps(objectAliases, state.objectAliases); - meetMaps(scalarAliases, state.scalarAliases); - } - } - - public Map getReadCache() { - return readCache; - } - - public boolean equivalentTo(BlockState other) { - if (this == other) { - return true; - } - boolean objectAliasesEqual = compareMaps(objectAliases, other.objectAliases); - boolean objectStatesEqual = compareMaps(objectStates, other.objectStates); - boolean readCacheEqual = compareMapsNoSize(readCache, other.readCache); - boolean scalarAliasesEqual = scalarAliases.equals(other.scalarAliases); - return objectAliasesEqual && objectStatesEqual && readCacheEqual && scalarAliasesEqual; - } - - protected static boolean compareMaps(Map left, Map right) { - if (left.size() != right.size()) { - return false; - } - return compareMapsNoSize(left, right); - } - - protected static boolean compareMapsNoSize(Map left, Map right) { - if (left == right) { - return true; - } - for (Map.Entry entry : right.entrySet()) { - K key = entry.getKey(); - V value = entry.getValue(); - assert value != null; - V otherValue = left.get(key); - if (otherValue != value && !value.equals(otherValue)) { - return false; - } - } - return true; - } - - protected static void meetMaps(Map target, Map source) { - Iterator> iter = target.entrySet().iterator(); - while (iter.hasNext()) { - Map.Entry entry = iter.next(); - if (source.containsKey(entry.getKey())) { - assert source.get(entry.getKey()) == entry.getValue(); - } else { - iter.remove(); - } - } - } - -} diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsBlockState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsBlockState.java Mon Jun 10 08:44:25 2013 +0200 @@ -0,0 +1,105 @@ +/* + * 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.virtual.phases.ea; + +import java.util.*; + +import com.oracle.graal.nodes.*; + +public abstract class EffectsBlockState> { + + protected final IdentityHashMap scalarAliases; + + protected EffectsBlockState() { + scalarAliases = new IdentityHashMap<>(); + } + + protected EffectsBlockState(EffectsBlockState other) { + scalarAliases = new IdentityHashMap<>(other.scalarAliases); + } + + public void addScalarAlias(ValueNode alias, ValueNode value) { + scalarAliases.put(alias, value); + } + + public ValueNode getScalarAlias(ValueNode alias) { + ValueNode result = scalarAliases.get(alias); + return result == null ? alias : result; + } + + @Override + public String toString() { + return "Scalar Aliases: " + scalarAliases.toString(); + } + + public void meetAliases(List states) { + scalarAliases.putAll(states.get(0).scalarAliases); + for (int i = 1; i < states.size(); i++) { + EffectsBlockState state = states.get(i); + meetMaps(scalarAliases, state.scalarAliases); + } + } + + public boolean equivalentTo(T other) { + if (this == other) { + return true; + } + return scalarAliases.equals(other.scalarAliases); + } + + protected static boolean compareMaps(Map left, Map right) { + if (left.size() != right.size()) { + return false; + } + return compareMapsNoSize(left, right); + } + + protected static boolean compareMapsNoSize(Map left, Map right) { + if (left == right) { + return true; + } + for (Map.Entry entry : right.entrySet()) { + K key = entry.getKey(); + V value = entry.getValue(); + assert value != null; + V otherValue = left.get(key); + if (otherValue != value && !value.equals(otherValue)) { + return false; + } + } + return true; + } + + protected static void meetMaps(Map target, Map source) { + Iterator> iter = target.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + if (source.containsKey(entry.getKey())) { + assert source.get(entry.getKey()) == entry.getValue(); + } else { + iter.remove(); + } + } + } + +} diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Mon Jun 10 08:44:25 2013 +0200 @@ -0,0 +1,203 @@ +/* + * 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.virtual.phases.ea; + +import java.util.*; + +import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.phases.graph.*; +import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure; +import com.oracle.graal.phases.graph.ReentrantBlockIterator.LoopInfo; +import com.oracle.graal.phases.schedule.*; +import com.oracle.graal.virtual.phases.ea.EffectList.Effect; + +public abstract class EffectsClosure> extends EffectsPhase.Closure { + + private final SchedulePhase schedule; + + protected final BlockMap blockEffects; + private final IdentityHashMap loopMergeEffects = new IdentityHashMap<>(); + + private boolean changed; + + public EffectsClosure(SchedulePhase schedule) { + this.schedule = schedule; + this.blockEffects = new BlockMap<>(schedule.getCFG()); + for (Block block : schedule.getCFG().getBlocks()) { + blockEffects.put(block, new GraphEffectList()); + } + } + + @Override + public boolean hasChanged() { + return changed; + } + + @Override + public void applyEffects() { + final StructuredGraph graph = schedule.getCFG().graph; + final ArrayList obsoleteNodes = new ArrayList<>(0); + BlockIteratorClosure closure = new BlockIteratorClosure() { + + @Override + protected Void getInitialState() { + return null; + } + + private void apply(GraphEffectList effects, Object context) { + if (!effects.isEmpty()) { + Debug.log(" ==== effects for %s", context); + for (Effect effect : effects) { + effect.apply(graph, obsoleteNodes); + if (effect.isVisible()) { + Debug.log(" %s", effect); + } + } + } + } + + @Override + protected Void processBlock(Block block, Void currentState) { + apply(blockEffects.get(block), block); + Debug.dump(graph, "after processing block %s", block); + return currentState; + } + + @Override + protected Void merge(Block merge, List states) { + return null; + } + + @Override + protected Void cloneState(Void oldState) { + return oldState; + } + + @Override + protected List processLoop(Loop loop, Void initialState) { + LoopInfo info = ReentrantBlockIterator.processLoop(this, loop, initialState); + apply(loopMergeEffects.get(loop), loop); + return info.exitStates; + } + }; + ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock()); + assert VirtualUtil.assertNonReachable(graph, obsoleteNodes); + } + + @Override + protected BlockT processBlock(Block block, BlockT state) { + VirtualUtil.trace("\nBlock: %s (", block); + + GraphEffectList effects = blockEffects.get(block); + FixedWithNextNode lastFixedNode = null; + for (Node node : schedule.getBlockToNodesMap().get(block)) { + changed |= processNode(node, state, effects, lastFixedNode); + if (node instanceof FixedWithNextNode) { + lastFixedNode = (FixedWithNextNode) node; + } + } + VirtualUtil.trace(")\n end state: %s\n", state); + return state; + } + + protected abstract boolean processNode(Node node, BlockT state, GraphEffectList effects, FixedWithNextNode lastFixedNode); + + @Override + protected BlockT merge(Block merge, List states) { + assert blockEffects.get(merge).isEmpty(); + MergeProcessor processor = createMergeProcessor(merge); + processor.merge(states); + blockEffects.get(merge).addAll(processor.mergeEffects); + blockEffects.get(merge).addAll(processor.afterMergeEffects); + return processor.newState; + } + + @Override + protected final List processLoop(Loop loop, BlockT initialState) { + BlockT loopEntryState = initialState; + BlockT lastMergedState = initialState; + MergeProcessor mergeProcessor = createMergeProcessor(loop.header); + for (int iteration = 0; iteration < 10; iteration++) { + LoopInfo info = ReentrantBlockIterator.processLoop(this, loop, cloneState(lastMergedState)); + + List states = new ArrayList<>(); + states.add(initialState); + states.addAll(info.endStates); + mergeProcessor.merge(states); + + Debug.log("================== %s", loop.header); + Debug.log("%s", mergeProcessor.newState); + Debug.log("===== vs."); + Debug.log("%s", lastMergedState); + + if (mergeProcessor.newState.equivalentTo(lastMergedState)) { + blockEffects.get(loop.header).insertAll(mergeProcessor.mergeEffects, 0); + loopMergeEffects.put(loop, mergeProcessor.afterMergeEffects); + + assert info.exitStates.size() == loop.exits.size(); + for (int i = 0; i < loop.exits.size(); i++) { + BlockT exitState = info.exitStates.get(i); + assert exitState != null : "no loop exit state at " + loop.exits.get(i) + " / " + loop.header; + processLoopExit((LoopExitNode) loop.exits.get(i).getBeginNode(), loopEntryState, exitState, blockEffects.get(loop.exits.get(i))); + } + + return info.exitStates; + } else { + lastMergedState = mergeProcessor.newState; + for (Block block : loop.blocks) { + blockEffects.get(block).clear(); + } + } + } + throw new GraalInternalError("too many iterations at %s", loop); + } + + protected abstract void processLoopExit(LoopExitNode exitNode, BlockT initialState, BlockT exitState, GraphEffectList effects); + + protected abstract MergeProcessor createMergeProcessor(Block merge); + + protected class MergeProcessor { + + protected final Block mergeBlock; + protected final MergeNode merge; + + protected final GraphEffectList mergeEffects; + protected final GraphEffectList afterMergeEffects; + protected BlockT newState; + + public MergeProcessor(Block mergeBlock) { + this.mergeBlock = mergeBlock; + this.merge = (MergeNode) mergeBlock.getBeginNode(); + this.mergeEffects = new GraphEffectList(); + this.afterMergeEffects = new GraphEffectList(); + } + + protected void merge(List states) { + newState = getInitialState(); + newState.meetAliases(states); + } + } +} diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java Mon Jun 10 08:44:25 2013 +0200 @@ -0,0 +1,98 @@ +/* + * 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.virtual.phases.ea; + +import static com.oracle.graal.phases.GraalOptions.*; + +import java.util.concurrent.*; + +import com.oracle.graal.debug.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.graph.*; +import com.oracle.graal.phases.schedule.*; +import com.oracle.graal.phases.tiers.*; + +public abstract class EffectsPhase extends BasePhase { + + public abstract static class Closure extends ReentrantBlockIterator.BlockIteratorClosure { + + public abstract boolean hasChanged(); + + public abstract void applyEffects(); + } + + private final int maxIterations; + private CanonicalizerPhase canonicalizer; + + public EffectsPhase(int maxIterations, CanonicalizerPhase canonicalizer) { + this.maxIterations = maxIterations; + this.canonicalizer = canonicalizer; + } + + @Override + protected void run(StructuredGraph graph, PhaseContextT context) { + runAnalysis(graph, context); + } + + public boolean runAnalysis(final StructuredGraph graph, final PhaseContextT context) { + boolean changed = false; + for (int iteration = 0; iteration < maxIterations; iteration++) { + boolean currentChanged = Debug.scope("iteration " + iteration, new Callable() { + + @Override + public Boolean call() { + SchedulePhase schedule = new SchedulePhase(); + schedule.apply(graph, false); + Closure closure = createEffectsClosure(context, schedule); + ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock()); + + if (!closure.hasChanged()) { + return false; + } + + // apply the effects collected during this iteration + closure.applyEffects(); + + Debug.dump(graph, "after " + getName() + " iteration"); + + new DeadCodeEliminationPhase().apply(graph); + + if (OptCanonicalizer.getValue()) { + canonicalizer.apply(graph, context); + } + + return true; + } + }); + if (!currentChanged) { + break; + } + changed |= currentChanged; + } + return changed; + } + + protected abstract Closure createEffectsClosure(PhaseContextT context, SchedulePhase schedule); +} diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Mon Jun 10 08:44:25 2013 +0200 @@ -41,15 +41,13 @@ private final Replacements replacements; private final GraphCache cache; private final OptimisticOptimizations optimisticOpts; - private final boolean readElimination; private final CanonicalizerPhase canonicalizer; - public IterativeInliningPhase(Replacements replacements, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts, boolean readElimination, CanonicalizerPhase canonicalizer) { + public IterativeInliningPhase(Replacements replacements, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts, CanonicalizerPhase canonicalizer) { this.replacements = replacements; this.cache = cache; this.plan = plan; this.optimisticOpts = optimisticOpts; - this.readElimination = readElimination; this.canonicalizer = canonicalizer; } @@ -73,11 +71,11 @@ @Override public Boolean call() { boolean progress = false; - PartialEscapeAnalysisPhase ea = new PartialEscapeAnalysisPhase(false, readElimination, canonicalizer); + PartialEscapePhase ea = new PartialEscapePhase(false, canonicalizer); boolean eaResult = ea.runAnalysis(graph, context); progress |= eaResult; - Map hints = PEAInliningHints.getValue() ? PartialEscapeAnalysisPhase.getHints(graph) : null; + Map hints = PEAInliningHints.getValue() ? PartialEscapePhase.getHints(graph) : null; InliningPhase inlining = new InliningPhase(context.getRuntime(), hints, replacements, context.getAssumptions(), cache, plan, optimisticOpts); inlining.setMaxMethodsPerInlining(simple ? 1 : Integer.MAX_VALUE); diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java Mon Jun 10 08:44:25 2013 +0200 @@ -34,7 +34,7 @@ * the fields or array elements (called "entries") and the lock count if the object is still * virtual. If the object was materialized, it contains the current materialized value. */ -class ObjectState extends Virtualizable.State { +public class ObjectState extends Virtualizable.State { private static final int[] EMPTY_INT_ARRAY = new int[0]; @@ -131,7 +131,6 @@ return entries[index]; } - @Override public void setEntry(int index, ValueNode value) { assert isVirtual(); entries[index] = value; diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java Mon Jun 10 08:44:03 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,166 +0,0 @@ -/* - * 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.virtual.phases.ea; - -import static com.oracle.graal.phases.GraalOptions.*; - -import java.util.*; -import java.util.concurrent.*; - -import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.util.*; -import com.oracle.graal.nodes.virtual.*; -import com.oracle.graal.phases.*; -import com.oracle.graal.phases.common.*; -import com.oracle.graal.phases.graph.*; -import com.oracle.graal.phases.schedule.*; -import com.oracle.graal.phases.tiers.*; - -public class PartialEscapeAnalysisPhase extends BasePhase { - - public abstract static class Closure extends ReentrantBlockIterator.BlockIteratorClosure { - - public abstract boolean hasChanged(); - - public abstract void applyEffects(); - } - - private final boolean iterative; - private final boolean readElimination; - private final CanonicalizerPhase canonicalizer; - - public PartialEscapeAnalysisPhase(boolean iterative, boolean readElimination, CanonicalizerPhase canonicalizer) { - this.iterative = iterative; - this.readElimination = readElimination; - this.canonicalizer = canonicalizer; - } - - @Override - protected void run(StructuredGraph graph, PhaseContext context) { - runAnalysis(graph, context); - } - - public boolean runAnalysis(final StructuredGraph graph, final PhaseContext context) { - if (!VirtualUtil.matches(graph, EscapeAnalyzeOnly.getValue())) { - return false; - } - - if (!readElimination) { - boolean analyzableNodes = false; - for (Node node : graph.getNodes()) { - if (node instanceof VirtualizableAllocation) { - analyzableNodes = true; - break; - } - } - if (!analyzableNodes) { - return false; - } - } - - boolean continueIteration = true; - boolean changed = false; - for (int iteration = 0; iteration < EscapeAnalysisIterations.getValue() && continueIteration; iteration++) { - boolean currentChanged = Debug.scope("iteration " + iteration, new Callable() { - - @Override - public Boolean call() { - - SchedulePhase schedule = new SchedulePhase(); - schedule.apply(graph, false); - Closure closure = createAnalysisClosure(context, schedule); - ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock()); - - if (!closure.hasChanged()) { - return false; - } - - // apply the effects collected during the escape analysis iteration - closure.applyEffects(); - - Debug.dump(graph, "after PartialEscapeAnalysis iteration"); - - new DeadCodeEliminationPhase().apply(graph); - - if (OptCanonicalizer.getValue()) { - canonicalizer.apply(graph, context); - } - - return true; - } - }); - continueIteration = currentChanged && iterative; - changed |= currentChanged; - } - - return changed; - } - - protected Closure createAnalysisClosure(PhaseContext context, SchedulePhase schedule) { - return new PartialEscapeClosure<>(schedule, context.getRuntime(), context.getAssumptions()); - } - - public static Map getHints(StructuredGraph graph) { - NodesToDoubles probabilities = new ComputeProbabilityClosure(graph).apply(); - Map hints = null; - for (CommitAllocationNode commit : graph.getNodes(CommitAllocationNode.class)) { - double sum = 0; - double invokeSum = 0; - for (Node commitUsage : commit.usages()) { - for (Node usage : commitUsage.usages()) { - if (usage instanceof FixedNode) { - sum += probabilities.get((FixedNode) usage); - } else { - if (usage instanceof MethodCallTargetNode) { - invokeSum += probabilities.get(((MethodCallTargetNode) usage).invoke().asNode()); - } - for (Node secondLevelUage : usage.usages()) { - if (secondLevelUage instanceof FixedNode) { - sum += probabilities.get(((FixedNode) secondLevelUage)); - } - } - } - } - } - // TODO(lstadler) get rid of this magic number - if (sum > 100 && invokeSum > 0) { - for (Node commitUsage : commit.usages()) { - for (Node usage : commitUsage.usages()) { - if (usage instanceof MethodCallTargetNode) { - if (hints == null) { - hints = new HashMap<>(); - } - Invoke invoke = ((MethodCallTargetNode) usage).invoke(); - hints.put(invoke, sum / invokeSum); - } - } - } - } - } - return hints; - } -} diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java Mon Jun 10 08:44:25 2013 +0200 @@ -0,0 +1,214 @@ +/* + * 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.virtual.phases.ea; + +import java.util.*; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.Virtualizable.EscapeState; +import com.oracle.graal.nodes.virtual.*; + +public abstract class PartialEscapeBlockState> extends EffectsBlockState { + + protected final IdentityHashMap objectStates = new IdentityHashMap<>(); + protected final IdentityHashMap objectAliases; + + /** + * Final subclass of PartialEscapeBlockState, for performance and to make everything behave + * nicely with generics. + */ + public static final class Final extends PartialEscapeBlockState { + + public Final() { + } + + public Final(Final other) { + super(other); + } + } + + protected PartialEscapeBlockState() { + objectAliases = new IdentityHashMap<>(); + } + + protected PartialEscapeBlockState(PartialEscapeBlockState other) { + super(other); + for (Map.Entry entry : other.objectStates.entrySet()) { + objectStates.put(entry.getKey(), entry.getValue().cloneState()); + } + objectAliases = new IdentityHashMap<>(other.objectAliases); + } + + public ObjectState getObjectState(VirtualObjectNode object) { + assert objectStates.containsKey(object); + return objectStates.get(object); + } + + public ObjectState getObjectStateOptional(VirtualObjectNode object) { + return objectStates.get(object); + } + + public ObjectState getObjectState(ValueNode value) { + VirtualObjectNode object = objectAliases.get(value); + return object == null ? null : getObjectState(object); + } + + public void materializeBefore(FixedNode fixed, VirtualObjectNode virtual, EscapeState state, GraphEffectList materializeEffects) { + PartialEscapeClosure.METRIC_MATERIALIZATIONS.increment(); + List objects = new ArrayList<>(2); + List values = new ArrayList<>(8); + List locks = new ArrayList<>(2); + List otherAllocations = new ArrayList<>(2); + materializeWithCommit(fixed, virtual, objects, locks, values, otherAllocations, state); + + materializeEffects.addMaterializationBefore(fixed, objects, locks, values, otherAllocations); + } + + private void materializeWithCommit(FixedNode fixed, VirtualObjectNode virtual, List objects, List locks, List values, List otherAllocations, + EscapeState state) { + ObjectState obj = getObjectState(virtual); + + ValueNode[] entries = obj.getEntries(); + ValueNode representation = virtual.getMaterializedRepresentation(fixed, entries, obj.getLocks()); + obj.escape(representation, state); + if (representation instanceof AllocatedObjectNode) { + objects.add((AllocatedObjectNode) representation); + locks.add(obj.getLocks()); + int pos = values.size(); + while (values.size() < pos + entries.length) { + values.add(null); + } + for (int i = 0; i < entries.length; i++) { + ObjectState entryObj = getObjectState(entries[i]); + if (entryObj != null) { + if (entryObj.isVirtual()) { + materializeWithCommit(fixed, entryObj.getVirtualObject(), objects, locks, values, otherAllocations, state); + } + values.set(pos + i, entryObj.getMaterializedValue()); + } else { + values.set(pos + i, entries[i]); + } + } + objectMaterialized(virtual, (AllocatedObjectNode) representation, values.subList(pos, pos + entries.length)); + } else { + VirtualUtil.trace("materialized %s as %s", virtual, representation); + otherAllocations.add(representation); + assert obj.getLocks().length == 0; + } + } + + protected void objectMaterialized(VirtualObjectNode virtual, AllocatedObjectNode representation, List values) { + VirtualUtil.trace("materialized %s as %s with values %s", virtual, representation, values); + } + + void addAndMarkAlias(VirtualObjectNode virtual, ValueNode node, NodeBitMap usages) { + objectAliases.put(node, virtual); + if (node.isAlive()) { + for (Node usage : node.usages()) { + markVirtualUsages(usage, usages); + } + } + } + + private void markVirtualUsages(Node node, NodeBitMap usages) { + if (!usages.isNew(node)) { + usages.mark(node); + } + if (node instanceof VirtualState) { + for (Node usage : node.usages()) { + markVirtualUsages(usage, usages); + } + } + } + + public void addObject(VirtualObjectNode virtual, ObjectState state) { + objectStates.put(virtual, state); + } + + public Iterable getStates() { + return objectStates.values(); + } + + public Collection getVirtualObjects() { + return objectAliases.values(); + } + + @Override + public String toString() { + return super.toString() + ", Object Aliases: " + objectAliases + ", Object States: " + objectStates; + } + + @Override + public void meetAliases(List states) { + super.meetAliases(states); + objectAliases.putAll(states.get(0).objectAliases); + for (int i = 1; i < states.size(); i++) { + meetMaps(objectAliases, states.get(i).objectAliases); + } + } + + @Override + public boolean equivalentTo(T other) { + if (!compareMaps(objectAliases, other.objectAliases) || !compareMaps(objectStates, other.objectStates)) { + return false; + } + return super.equivalentTo(other); + } + + protected static boolean compareMaps(Map left, Map right) { + if (left.size() != right.size()) { + return false; + } + return compareMapsNoSize(left, right); + } + + protected static boolean compareMapsNoSize(Map left, Map right) { + if (left == right) { + return true; + } + for (Map.Entry entry : right.entrySet()) { + K key = entry.getKey(); + V value = entry.getValue(); + assert value != null; + V otherValue = left.get(key); + if (otherValue != value && !value.equals(otherValue)) { + return false; + } + } + return true; + } + + protected static void meetMaps(Map target, Map source) { + Iterator> iter = target.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + if (source.containsKey(entry.getKey())) { + assert source.get(entry.getKey()) == entry.getValue(); + } else { + iter.remove(); + } + } + } + +} diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Mon Jun 10 08:44:25 2013 +0200 @@ -22,9 +22,6 @@ */ package com.oracle.graal.virtual.phases.ea; -import static com.oracle.graal.api.meta.LocationIdentity.*; -import static com.oracle.graal.phases.GraalOptions.*; - import java.util.*; import com.oracle.graal.api.code.*; @@ -35,20 +32,14 @@ import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.VirtualState.NodeClosure; import com.oracle.graal.nodes.cfg.*; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.spi.Virtualizable.EscapeState; import com.oracle.graal.nodes.virtual.*; -import com.oracle.graal.phases.graph.*; -import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure; -import com.oracle.graal.phases.graph.ReentrantBlockIterator.LoopInfo; import com.oracle.graal.phases.schedule.*; import com.oracle.graal.virtual.nodes.*; -import com.oracle.graal.virtual.phases.ea.BlockState.ReadCacheEntry; -import com.oracle.graal.virtual.phases.ea.EffectList.Effect; -public class PartialEscapeClosure extends PartialEscapeAnalysisPhase.Closure { +public abstract class PartialEscapeClosure> extends EffectsClosure { public static final DebugMetric METRIC_MATERIALIZATIONS = Debug.metric("Materializations"); public static final DebugMetric METRIC_MATERIALIZATIONS_PHI = Debug.metric("MaterializationsPhi"); @@ -61,143 +52,63 @@ public static final DebugMetric METRIC_MEMORYCHECKOINT = Debug.metric("MemoryCheckpoint"); private final NodeBitMap usages; - private final SchedulePhase schedule; - - private final BlockMap blockEffects; - private final IdentityHashMap loopMergeEffects = new IdentityHashMap<>(); - private final VirtualizerToolImpl tool; - private final Map hints = new IdentityHashMap<>(); - private boolean changed; + /** + * Final subclass of PartialEscapeClosure, for performance and to make everything behave nicely + * with generics. + */ + public static final class Final extends PartialEscapeClosure { - public PartialEscapeClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) { - this.usages = schedule.getCFG().graph.createNodeBitMap(); - this.schedule = schedule; - this.tool = new VirtualizerToolImpl(usages, metaAccess, assumptions); - this.blockEffects = new BlockMap<>(schedule.getCFG()); - for (Block block : schedule.getCFG().getBlocks()) { - blockEffects.put(block, new GraphEffectList()); + public Final(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) { + super(schedule, metaAccess, assumptions); + } + + @Override + protected PartialEscapeBlockState.Final getInitialState() { + return new PartialEscapeBlockState.Final(); + } + + @Override + protected PartialEscapeBlockState.Final cloneState(PartialEscapeBlockState.Final oldState) { + return new PartialEscapeBlockState.Final(oldState); } } - @SuppressWarnings("unchecked") - @Override - protected BlockT getInitialState() { - return (BlockT) new BlockState(); - } - - @Override - public boolean hasChanged() { - return changed; - } - - @Override - public void applyEffects() { - final StructuredGraph graph = schedule.getCFG().graph; - final ArrayList obsoleteNodes = new ArrayList<>(0); - BlockIteratorClosure closure = new BlockIteratorClosure() { - - @Override - protected Void getInitialState() { - return null; - } - - private void apply(GraphEffectList effects, Object context) { - if (!effects.isEmpty()) { - Debug.log(" ==== effects for %s", context); - for (Effect effect : effects) { - effect.apply(graph, obsoleteNodes); - if (effect.isVisible()) { - Debug.log(" %s", effect); - } - } - } - } - - @Override - protected Void processBlock(Block block, Void currentState) { - apply(blockEffects.get(block), block); - return currentState; - } - - @Override - protected Void merge(Block merge, List states) { - return null; - } - - @Override - protected Void cloneState(Void oldState) { - return oldState; - } - - @Override - protected List processLoop(Loop loop, Void initialState) { - LoopInfo info = ReentrantBlockIterator.processLoop(this, loop, initialState); - apply(loopMergeEffects.get(loop), loop); - return info.exitStates; - } - }; - ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock()); - assert VirtualUtil.assertNonReachable(graph, obsoleteNodes); + public PartialEscapeClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) { + super(schedule); + this.usages = schedule.getCFG().graph.createNodeBitMap(); + this.tool = new VirtualizerToolImpl(usages, metaAccess, assumptions); } public Map getHints() { return hints; } + /** + * @return true if the node was deleted, false otherwise + */ @Override - protected BlockT processBlock(Block block, BlockT state) { - GraphEffectList effects = blockEffects.get(block); - tool.setEffects(effects); - - VirtualUtil.trace("\nBlock: %s (", block); - List nodeList = schedule.getBlockToNodesMap().get(block); - - FixedWithNextNode lastFixedNode = null; - for (Node node : nodeList) { - boolean deleted; - boolean isMarked = usages.isMarked(node); - if (isMarked || node instanceof VirtualizableRoot) { - VirtualUtil.trace("[[%s]] ", node); - FixedNode nextFixedNode = lastFixedNode == null ? null : lastFixedNode.next(); - deleted = processNode((ValueNode) node, nextFixedNode, state, effects, isMarked); - } else { - VirtualUtil.trace("%s ", node); - deleted = false; - } - if (OptEarlyReadElimination.getValue()) { - if (!deleted && node instanceof MemoryCheckpoint) { - METRIC_MEMORYCHECKOINT.increment(); - MemoryCheckpoint checkpoint = (MemoryCheckpoint) node; - for (LocationIdentity identity : checkpoint.getLocationIdentities()) { - if (identity instanceof ResolvedJavaField) { - state.killReadCache((ResolvedJavaField) identity); - } else if (identity == ANY_LOCATION) { - state.killReadCache(); - } - } - } - } - if (node instanceof FixedWithNextNode) { - lastFixedNode = (FixedWithNextNode) node; - } + protected boolean processNode(Node node, BlockT state, GraphEffectList effects, FixedWithNextNode lastFixedNode) { + boolean isMarked = usages.isMarked(node); + if (isMarked || node instanceof VirtualizableRoot) { + VirtualUtil.trace("[[%s]] ", node); + FixedNode nextFixedNode = lastFixedNode == null ? null : lastFixedNode.next(); + return processNode((ValueNode) node, nextFixedNode, state, effects, isMarked); + } else { + VirtualUtil.trace("%s ", node); + return false; } - VirtualUtil.trace(")\n end state: %s\n", state); - return state; } private boolean processNode(final ValueNode node, FixedNode insertBefore, final BlockT state, final GraphEffectList effects, boolean isMarked) { - tool.reset(state, node, insertBefore); + tool.reset(state, node, insertBefore, effects); if (node instanceof Virtualizable) { ((Virtualizable) node).virtualize(tool); } if (tool.isDeleted()) { - if (!(node instanceof CommitAllocationNode || node instanceof AllocatedObjectNode)) { - changed = true; - } - return true; + return !(node instanceof CommitAllocationNode || node instanceof AllocatedObjectNode); } if (isMarked) { if (node instanceof StateSplit) { @@ -289,7 +200,7 @@ return false; } - private static void ensureMaterialized(BlockState state, ObjectState obj, FixedNode materializeBefore, GraphEffectList effects, DebugMetric metric) { + private static void ensureMaterialized(PartialEscapeBlockState state, ObjectState obj, FixedNode materializeBefore, GraphEffectList effects, DebugMetric metric) { assert obj != null; if (obj.getState() == EscapeState.Virtual) { metric.increment(); @@ -300,70 +211,13 @@ assert !obj.isVirtual(); } - private static void replaceWithMaterialized(ValueNode value, Node usage, FixedNode materializeBefore, BlockState state, ObjectState obj, GraphEffectList effects, DebugMetric metric) { + private static void replaceWithMaterialized(ValueNode value, Node usage, FixedNode materializeBefore, PartialEscapeBlockState state, ObjectState obj, GraphEffectList effects, DebugMetric metric) { ensureMaterialized(state, obj, materializeBefore, effects, metric); effects.replaceFirstInput(usage, value, obj.getMaterializedValue()); } @Override - protected BlockT merge(Block merge, List states) { - assert blockEffects.get(merge).isEmpty(); - MergeProcessor processor = new MergeProcessor<>(merge, usages, blockEffects); - processor.merge(states); - blockEffects.get(merge).addAll(processor.mergeEffects); - blockEffects.get(merge).addAll(processor.afterMergeEffects); - return processor.newState; - - } - - @SuppressWarnings("unchecked") - @Override - protected BlockT cloneState(BlockState oldState) { - return (BlockT) oldState.cloneState(); - } - - @SuppressWarnings("unchecked") - @Override - protected List processLoop(Loop loop, BlockT initialState) { - BlockState loopEntryState = initialState; - BlockState lastMergedState = initialState; - MergeProcessor mergeProcessor = new MergeProcessor<>(loop.header, usages, blockEffects); - for (int iteration = 0; iteration < 10; iteration++) { - LoopInfo info = ReentrantBlockIterator.processLoop(this, loop, (BlockT) lastMergedState.cloneState()); - - List states = new ArrayList<>(); - states.add(initialState); - states.addAll(info.endStates); - mergeProcessor.merge(states); - - Debug.log("================== %s", loop.header); - Debug.log("%s", mergeProcessor.newState); - Debug.log("===== vs."); - Debug.log("%s", lastMergedState); - - if (mergeProcessor.newState.equivalentTo(lastMergedState)) { - blockEffects.get(loop.header).insertAll(mergeProcessor.mergeEffects, 0); - loopMergeEffects.put(loop, mergeProcessor.afterMergeEffects); - - assert info.exitStates.size() == loop.exits.size(); - for (int i = 0; i < loop.exits.size(); i++) { - BlockState exitState = info.exitStates.get(i); - assert exitState != null : "no loop exit state at " + loop.exits.get(i) + " / " + loop.header; - processLoopExit((LoopExitNode) loop.exits.get(i).getBeginNode(), loopEntryState, exitState, blockEffects.get(loop.exits.get(i))); - } - - return info.exitStates; - } else { - lastMergedState = mergeProcessor.newState; - for (Block block : loop.blocks) { - blockEffects.get(block).clear(); - } - } - } - throw new GraalInternalError("too many iterations at %s", loop); - } - - private static void processLoopExit(LoopExitNode exitNode, BlockState initialState, BlockState exitState, GraphEffectList effects) { + protected void processLoopExit(LoopExitNode exitNode, BlockT initialState, BlockT exitState, GraphEffectList effects) { HashMap proxies = new HashMap<>(); for (ProxyNode proxy : exitNode.proxies()) { @@ -404,41 +258,25 @@ } } } - - for (Map.Entry entry : exitState.getReadCache().entrySet()) { - if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) { - ProxyNode proxy = new ProxyNode(exitState.getReadCache(entry.getKey().object, entry.getKey().identity), exitNode, PhiType.Value, null); - effects.addFloatingNode(proxy, "readCacheProxy"); - entry.setValue(proxy); - } - } } - private static class MergeProcessor { + @Override + protected MergeProcessor createMergeProcessor(Block merge) { + return new MergeProcessor(merge); + } - private final Block mergeBlock; - private final MergeNode merge; - private final NodeBitMap usages; - private final BlockMap blockEffects; - private final GraphEffectList mergeEffects; - private final GraphEffectList afterMergeEffects; + protected class MergeProcessor extends EffectsClosure.MergeProcessor { private final HashMap materializedPhis = new HashMap<>(); private final IdentityHashMap valuePhis = new IdentityHashMap<>(); private final IdentityHashMap valueObjectMergePhis = new IdentityHashMap<>(); private final IdentityHashMap valueObjectVirtuals = new IdentityHashMap<>(); - private BlockT newState; - public MergeProcessor(Block mergeBlock, NodeBitMap usages, BlockMap blockEffects) { - this.usages = usages; - this.mergeBlock = mergeBlock; - this.blockEffects = blockEffects; - this.merge = (MergeNode) mergeBlock.getBeginNode(); - this.mergeEffects = new GraphEffectList(); - this.afterMergeEffects = new GraphEffectList(); + public MergeProcessor(Block mergeBlock) { + super(mergeBlock); } - private PhiNode getCachedPhi(T virtual, Kind kind) { + protected PhiNode getCachedPhi(T virtual, Kind kind) { PhiNode result = materializedPhis.get(virtual); if (result == null) { result = new PhiNode(kind, merge); @@ -474,10 +312,9 @@ return result; } - @SuppressWarnings("unchecked") - private void merge(List states) { - newState = (BlockT) states.get(0).cloneEmptyState(); - newState.meetAliases(states); + @Override + protected void merge(List states) { + super.merge(states); /* * Iterative processing: Merging the materialized/virtual state of virtual objects can @@ -519,7 +356,7 @@ PhiNode materializedValuePhi = getCachedPhi(object, Kind.Object); mergeEffects.addFloatingNode(materializedValuePhi, "materializedPhi"); for (int i = 0; i < states.size(); i++) { - BlockState state = states.get(i); + PartialEscapeBlockState state = states.get(i); ObjectState obj = objStates[i]; materialized |= obj.isVirtual(); Block predecessor = mergeBlock.getPredecessors().get(i); @@ -578,8 +415,6 @@ } } } while (materialized); - - mergeReadCache(states); } private boolean processPhi(PhiNode phi, List states) { @@ -665,62 +500,5 @@ } return materialized; } - - private void mergeReadCache(List states) { - for (Map.Entry entry : states.get(0).readCache.entrySet()) { - ReadCacheEntry key = entry.getKey(); - ValueNode value = entry.getValue(); - boolean phi = false; - for (int i = 1; i < states.size(); i++) { - ValueNode otherValue = states.get(i).readCache.get(key); - if (otherValue == null) { - value = null; - phi = false; - break; - } - if (!phi && otherValue != value) { - phi = true; - } - } - if (phi) { - PhiNode phiNode = getCachedPhi(entry, value.kind()); - mergeEffects.addFloatingNode(phiNode, "mergeReadCache"); - for (int i = 0; i < states.size(); i++) { - afterMergeEffects.addPhiInput(phiNode, states.get(i).getReadCache(key.object, key.identity)); - } - newState.readCache.put(key, phiNode); - } else if (value != null) { - newState.readCache.put(key, value); - } - } - for (PhiNode phi : merge.phis()) { - if (phi.kind() == Kind.Object) { - for (Map.Entry entry : states.get(0).readCache.entrySet()) { - if (entry.getKey().object == phi.valueAt(0)) { - mergeReadCachePhi(phi, entry.getKey().identity, states); - } - } - - } - } - } - - private void mergeReadCachePhi(PhiNode phi, ResolvedJavaField identity, List states) { - ValueNode[] values = new ValueNode[phi.valueCount()]; - for (int i = 0; i < phi.valueCount(); i++) { - ValueNode value = states.get(i).getReadCache(phi.valueAt(i), identity); - if (value == null) { - return; - } - values[i] = value; - } - - PhiNode phiNode = getCachedPhi(new ReadCacheEntry(identity, phi), values[0].kind()); - mergeEffects.addFloatingNode(phiNode, "mergeReadCachePhi"); - for (int i = 0; i < values.length; i++) { - afterMergeEffects.addPhiInput(phiNode, values[i]); - } - newState.readCache.put(new ReadCacheEntry(identity, phi), phiNode); - } } } diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java Mon Jun 10 08:44:25 2013 +0200 @@ -0,0 +1,106 @@ +/* + * 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.virtual.phases.ea; + +import static com.oracle.graal.phases.GraalOptions.*; + +import java.util.*; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.util.*; +import com.oracle.graal.nodes.virtual.*; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.graph.*; +import com.oracle.graal.phases.schedule.*; +import com.oracle.graal.phases.tiers.*; + +public class PartialEscapePhase extends EffectsPhase { + + public PartialEscapePhase(boolean iterative, CanonicalizerPhase canonicalizer) { + super(iterative ? EscapeAnalysisIterations.getValue() : 1, canonicalizer); + } + + @Override + protected void run(StructuredGraph graph, PhaseContext context) { + if (VirtualUtil.matches(graph, EscapeAnalyzeOnly.getValue())) { + boolean analyzableNodes = false; + for (Node node : graph.getNodes()) { + if (node instanceof VirtualizableAllocation) { + analyzableNodes = true; + break; + } + } + if (analyzableNodes) { + runAnalysis(graph, context); + } + } + } + + @Override + protected Closure createEffectsClosure(PhaseContext context, SchedulePhase schedule) { + return new PartialEscapeClosure.Final(schedule, context.getRuntime(), context.getAssumptions()); + } + + public static Map getHints(StructuredGraph graph) { + NodesToDoubles probabilities = new ComputeProbabilityClosure(graph).apply(); + Map hints = null; + for (CommitAllocationNode commit : graph.getNodes(CommitAllocationNode.class)) { + double sum = 0; + double invokeSum = 0; + for (Node commitUsage : commit.usages()) { + for (Node usage : commitUsage.usages()) { + if (usage instanceof FixedNode) { + sum += probabilities.get((FixedNode) usage); + } else { + if (usage instanceof MethodCallTargetNode) { + invokeSum += probabilities.get(((MethodCallTargetNode) usage).invoke().asNode()); + } + for (Node secondLevelUage : usage.usages()) { + if (secondLevelUage instanceof FixedNode) { + sum += probabilities.get(((FixedNode) secondLevelUage)); + } + } + } + } + } + // TODO(lstadler) get rid of this magic number + if (sum > 100 && invokeSum > 0) { + for (Node commitUsage : commit.usages()) { + for (Node usage : commitUsage.usages()) { + if (usage instanceof MethodCallTargetNode) { + if (hints == null) { + hints = new HashMap<>(); + } + Invoke invoke = ((MethodCallTargetNode) usage).invoke(); + hints.put(invoke, sum / invokeSum); + } + } + } + } + } + return hints; + } +} diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java Mon Jun 10 08:44:25 2013 +0200 @@ -111,7 +111,7 @@ } } - static boolean matches(StructuredGraph graph, String filter) { + public static boolean matches(StructuredGraph graph, String filter) { if (filter != null) { if (filter.startsWith("~")) { ResolvedJavaMethod method = graph.method(); diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Mon Jun 10 08:44:25 2013 +0200 @@ -39,7 +39,6 @@ private final NodeBitMap usages; private final MetaAccessProvider metaAccess; private final Assumptions assumptions; - private GraphEffectList effects; VirtualizerToolImpl(NodeBitMap usages, MetaAccessProvider metaAccess, Assumptions assumptions) { this.usages = usages; @@ -48,9 +47,10 @@ } private boolean deleted; - private BlockState state; + private PartialEscapeBlockState state; private ValueNode current; private FixedNode position; + private GraphEffectList effects; @Override public MetaAccessProvider getMetaAccessProvider() { @@ -62,15 +62,12 @@ return assumptions; } - public void setEffects(GraphEffectList effects) { - this.effects = effects; - } - - public void reset(BlockState newState, ValueNode newCurrent, FixedNode newPosition) { + public void reset(PartialEscapeBlockState newState, ValueNode newCurrent, FixedNode newPosition, GraphEffectList newEffects) { deleted = false; state = newState; current = newCurrent; position = newPosition; + effects = newEffects; } public boolean isDeleted() { @@ -87,16 +84,24 @@ ObjectState obj = (ObjectState) objectState; assert obj != null && obj.isVirtual() : "not virtual: " + obj; ObjectState valueState = state.getObjectState(value); + ValueNode newValue = value; if (valueState == null) { - obj.setEntry(index, getReplacedValue(value)); + newValue = getReplacedValue(value); + assert obj.getEntry(index) == null || obj.getEntry(index).kind() == newValue.kind() || (isObjectEntry(obj.getEntry(index)) && isObjectEntry(newValue)); } else { - ValueNode newValue = value; if (valueState.getState() != EscapeState.Virtual) { newValue = valueState.getMaterializedValue(); + assert newValue.kind() == Kind.Object; + } else { + newValue = valueState.getVirtualObject(); } - assert obj.getEntry(index) == null || obj.getEntry(index).kind() == newValue.kind(); - obj.setEntry(index, newValue); + assert obj.getEntry(index) == null || isObjectEntry(obj.getEntry(index)); } + obj.setEntry(index, newValue); + } + + private static boolean isObjectEntry(ValueNode value) { + return value.kind() == Kind.Object || value instanceof VirtualObjectNode; } @Override @@ -128,7 +133,6 @@ @Override public void delete() { - assert current instanceof FixedWithNextNode; effects.deleteFixedNode((FixedWithNextNode) current); deleted = true; } @@ -181,26 +185,4 @@ } } } - - @Override - public void addReadCache(ValueNode object, ResolvedJavaField identity, ValueNode value) { - if (OptEarlyReadElimination.getValue()) { - state.addReadCache(object, identity, value); - } - } - - @Override - public ValueNode getReadCache(ValueNode object, ResolvedJavaField identity) { - if (OptEarlyReadElimination.getValue()) { - return state.getReadCache(object, identity); - } - return null; - } - - @Override - public void killReadCache(ResolvedJavaField identity) { - if (OptEarlyReadElimination.getValue()) { - state.killReadCache(identity); - } - } } diff -r de73bbbde021 -r 8ad4e90fc5d7 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 Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java Mon Jun 10 08:44:25 2013 +0200 @@ -170,4 +170,13 @@ * @return the new materialized frame */ MaterializedFrame materialize(); + + /** + * To check whether the given {@link FrameSlot} has been initialized or not. An initialized slot + * has previously been read or modified. + * + * @param slot the slot + * @return true if the slot is uninitialized. + */ + boolean isInitialized(FrameSlot slot); } diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java Mon Jun 10 08:44:25 2013 +0200 @@ -112,6 +112,13 @@ return clonedFrameDescriptor; } + public FrameDescriptor shallowCopy() { + FrameDescriptor clonedFrameDescriptor = new FrameDescriptor(this.typeConversion); + clonedFrameDescriptor.slots.addAll(slots); + clonedFrameDescriptor.identifierToSlotMap.putAll(identifierToSlotMap); + return clonedFrameDescriptor; + } + void updateVersion() { version.invalidate(); version = createVersion(); diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotImpl.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotImpl.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotImpl.java Mon Jun 10 08:44:25 2013 +0200 @@ -29,7 +29,7 @@ private final int index; private FrameSlotKind kind; - protected FrameSlotImpl(FrameDescriptor descriptor, Object identifier, int index, FrameSlotKind kind) { + public FrameSlotImpl(FrameDescriptor descriptor, Object identifier, int index, FrameSlotKind kind) { this.descriptor = descriptor; this.identifier = identifier; this.index = index; diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/NativeFrame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/NativeFrame.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/NativeFrame.java Mon Jun 10 08:44:25 2013 +0200 @@ -133,4 +133,9 @@ public FrameDescriptor getFrameDescriptor() { throw new UnsupportedOperationException("native frame"); } + + @Override + public boolean isInitialized(FrameSlot slot) { + throw new UnsupportedOperationException("native frame"); + } } diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java Mon Jun 10 08:44:25 2013 +0200 @@ -122,4 +122,9 @@ public FrameDescriptor getFrameDescriptor() { return wrapped.getFrameDescriptor(); } + + @Override + public boolean isInitialized(FrameSlot slot) { + return wrapped.isInitialized(slot); + } } diff -r de73bbbde021 -r 8ad4e90fc5d7 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java Mon Jun 10 08:44:03 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java Mon Jun 10 08:44:25 2013 +0200 @@ -201,4 +201,9 @@ tags = Arrays.copyOf(tags, newSize); } } + + @Override + public boolean isInitialized(FrameSlot slot) { + return (this.tags[slot.getIndex()] != FrameSlotKind.Illegal.ordinal()); + } } diff -r de73bbbde021 -r 8ad4e90fc5d7 make/Makefile --- a/make/Makefile Mon Jun 10 08:44:03 2013 +0200 +++ b/make/Makefile Mon Jun 10 08:44:25 2013 +0200 @@ -516,6 +516,10 @@ $(EXPORT_JRE_LIB_DIR)/%.jar: $(SHARED_DIR)/%.jar $(install-file) +# Shared options files +$(EXPORT_JRE_LIB_DIR)/%.options: $(SHARED_DIR)/%.options + $(install-file) + # Include files (jvmti.h, jvmticmlr.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h, jfr.h) $(EXPORT_INCLUDE_DIR)/%: $(GEN_DIR)/jvmtifiles/% $(install-file) diff -r de73bbbde021 -r 8ad4e90fc5d7 make/build-graal.xml --- a/make/build-graal.xml Mon Jun 10 08:44:03 2013 +0200 +++ b/make/build-graal.xml Mon Jun 10 08:44:25 2013 +0200 @@ -28,7 +28,7 @@ - + @@ -101,6 +101,14 @@ + + + + + + + + diff -r de73bbbde021 -r 8ad4e90fc5d7 make/solaris/makefiles/buildtree.make --- a/make/solaris/makefiles/buildtree.make Mon Jun 10 08:44:03 2013 +0200 +++ b/make/solaris/makefiles/buildtree.make Mon Jun 10 08:44:25 2013 +0200 @@ -229,7 +229,9 @@ echo "$(call gamma-path,altsrc,os/$(OS_FAMILY)/vm) \\"; \ echo "$(call gamma-path,commonsrc,os/$(OS_FAMILY)/vm) \\"; \ echo "$(call gamma-path,altsrc,os/posix/vm) \\"; \ - echo "$(call gamma-path,commonsrc,os/posix/vm)"; \ + echo "$(call gamma-path,commonsrc,os/posix/vm) \\"; \ + echo "$(call gamma-path,altsrc,gpu/ptx) \\"; \ + echo "$(call gamma-path,commonsrc,gpu/ptx)"; \ echo; \ echo "Src_Dirs_I = \\"; \ echo "$(call gamma-path,altsrc,share/vm/prims) \\"; \ @@ -244,8 +246,9 @@ echo "$(call gamma-path,commonsrc,os_cpu/$(OS_FAMILY)_$(ARCH)/vm) \\"; \ echo "$(call gamma-path,altsrc,os/$(OS_FAMILY)/vm) \\"; \ echo "$(call gamma-path,commonsrc,os/$(OS_FAMILY)/vm) \\"; \ - echo "$(call gamma-path,altsrc,os/posix/vm) \\"; \ - echo "$(call gamma-path,commonsrc,os/posix/vm)"; \ + echo "$(call gamma-path,commonsrc,os/posix/vm) \\"; \ + echo "$(call gamma-path,altsrc,gpu) \\"; \ + echo "$(call gamma-path,commonsrc,gpu)"; \ [ -n "$(CFLAGS_BROWSE)" ] && \ echo && echo "CFLAGS_BROWSE = $(CFLAGS_BROWSE)"; \ [ -n "$(ENABLE_FULL_DEBUG_SYMBOLS)" ] && \ diff -r de73bbbde021 -r 8ad4e90fc5d7 make/solaris/makefiles/vm.make --- a/make/solaris/makefiles/vm.make Mon Jun 10 08:44:03 2013 +0200 +++ b/make/solaris/makefiles/vm.make Mon Jun 10 08:44:25 2013 +0200 @@ -194,7 +194,9 @@ COMPILER2_PATHS += $(GENERATED)/adfiles GRAAL_PATHS += $(call altsrc,$(HS_COMMON_SRC)/share/vm/graal) +GRAAL_PATHS += $(call altsrc,$(HS_COMMON_SRC)/gpu/ptx) GRAAL_PATHS += $(HS_COMMON_SRC)/share/vm/graal +GRAAL_PATHS += $(HS_COMMON_SRC)/gpu/ptx # Include dirs per type. Src_Dirs/CORE := $(CORE_PATHS) diff -r de73bbbde021 -r 8ad4e90fc5d7 mx/commands.py --- a/mx/commands.py Mon Jun 10 08:44:03 2013 +0200 +++ b/mx/commands.py Mon Jun 10 08:44:25 2013 +0200 @@ -232,6 +232,8 @@ machine = platform.uname()[4] if machine in ['amd64', 'AMD64', 'x86_64', 'i86pc']: return 'amd64' + if machine in ['sun4v']: + return 'sparc' if machine == 'i386' and mx.get_os() == 'darwin': try: # Support for Snow Leopard and earlier version of MacOSX @@ -343,6 +345,7 @@ def _installGraalJarInJdks(graalDist): graalJar = graalDist.path + graalOptions = join(_graal_home, 'graal.options') jdks = join(_graal_home, 'jdk' + str(mx.java().version)) if exists(jdks): for e in os.listdir(jdks): @@ -353,6 +356,9 @@ shutil.copyfile(graalJar, tmp) 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={}): @@ -458,7 +464,7 @@ out.element('property', {'name' : 'jar.dir', 'value' : '${shared.dir}'}) out.element('property', {'name' : 'jar.file', 'value' : '${jar.dir}/graal.jar'}) - out.element('target', {'name' : 'main', 'depends' : 'jar'}) + out.element('target', {'name' : 'main', 'depends' : 'options,jar'}) serviceMap = {}; def addService(service, provider): @@ -513,6 +519,16 @@ out.element('delete', {'dir' : '${classes.dir}'}) out.close('target') + out.open('target', {'name' : 'options', 'if' : 'graal.options.exists'}) + out.open('copy', {'todir' : '${jar.dir}'}) + out.element('filelist', {'dir' : '${gamma.dir}', 'files' : 'graal.options'}) + out.close('copy') + out.close('target') + + out.open('target', {'name' : 'check-graal-options-exists'}) + out.element('available', {'property' : 'graal.options.exists', 'file' : '${gamma.dir}/graal.options'}) + out.close('target') + out.open('target', {'name' : 'clean', 'depends' : 'cleanclasses'}) out.element('delete', {'file' : '${jar.file}'}) out.close('target') diff -r de73bbbde021 -r 8ad4e90fc5d7 src/cpu/sparc/vm/codeInstaller_sparc.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/sparc/vm/codeInstaller_sparc.hpp Mon Jun 10 08:44:25 2013 +0200 @@ -0,0 +1,53 @@ +/* + * 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. + */ +#ifndef CPU_SPARC_VM_CODEINSTALLER_SPARC_HPP +#define CPU_SPARC_VM_CODEINSTALLER_SPARC_HPP + +inline jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) { + fatal("CodeInstaller::pd_next_offset - sparc unimp"); + return 0; +} + +inline void CodeInstaller::pd_site_DataPatch(oop constant, oop kind, bool inlined, + address instruction, int alignment, char typeChar) { + fatal("CodeInstaller::pd_site_DataPatch - sparc unimp"); +} + +inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) { + fatal("CodeInstaller::pd_relocate_CodeBlob - sparc unimp"); +} + +inline void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) { + fatal("CodeInstaller::pd_relocate_ForeignCall - sparc unimp"); +} + +inline void CodeInstaller::pd_relocate_JavaMethod(oop method, jint pc_offset) { + fatal("CodeInstaller::pd_relocate_JavaMethod - sparc unimp"); +} + +inline int32_t* CodeInstaller::pd_locate_operand(address instruction) { + fatal("CodeInstaller::pd_locate_operand - sparc unimp"); + return (int32_t*)0; +} + +#endif // CPU_SPARC_VM_CODEINSTALLER_SPARC_HPP diff -r de73bbbde021 -r 8ad4e90fc5d7 src/cpu/sparc/vm/graalGlobals_sparc.hpp --- a/src/cpu/sparc/vm/graalGlobals_sparc.hpp Mon Jun 10 08:44:03 2013 +0200 +++ b/src/cpu/sparc/vm/graalGlobals_sparc.hpp Mon Jun 10 08:44:25 2013 +0200 @@ -31,6 +31,32 @@ // Sets the default values for platform dependent flags used by the Graal compiler. // (see graalGlobals.hpp) -define_pd_global(intx, GraalSafepointPollOffset, 0 ); +#if !defined(COMPILER1) && !defined(COMPILER2) +define_pd_global(bool, BackgroundCompilation, true ); +define_pd_global(bool, UseTLAB, true ); +define_pd_global(bool, ResizeTLAB, true ); +define_pd_global(bool, InlineIntrinsics, true ); +define_pd_global(bool, PreferInterpreterNativeStubs, false); +define_pd_global(bool, TieredCompilation, false); +define_pd_global(intx, BackEdgeThreshold, 100000); + +define_pd_global(intx, OnStackReplacePercentage, 933 ); +define_pd_global(intx, FreqInlineSize, 325 ); +define_pd_global(intx, NewSizeThreadIncrease, 4*K ); +define_pd_global(uintx,MetaspaceSize, 12*M ); +define_pd_global(bool, NeverActAsServerClassMachine, false); +define_pd_global(uint64_t,MaxRAM, 1ULL*G); +define_pd_global(bool, CICompileOSR, true ); +define_pd_global(bool, ProfileTraps, true ); +define_pd_global(bool, UseOnStackReplacement, true ); +define_pd_global(intx, CompileThreshold, 10000); +define_pd_global(intx, InitialCodeCacheSize, 16*M ); +define_pd_global(intx, ReservedCodeCacheSize, 64*M ); +define_pd_global(bool, ProfileInterpreter, true ); +define_pd_global(intx, CodeCacheExpansionSize, 64*K ); +define_pd_global(uintx,CodeCacheMinBlockLength, 4); +define_pd_global(intx, TypeProfileWidth, 8); +define_pd_global(intx, MethodProfileWidth, 4); +#endif #endif // CPU_SPARC_VM_GRAALGLOBALS_SPARC_HPP diff -r de73bbbde021 -r 8ad4e90fc5d7 src/cpu/sparc/vm/interpreterGenerator_sparc.hpp --- a/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp Mon Jun 10 08:44:03 2013 +0200 +++ b/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp Mon Jun 10 08:44:25 2013 +0200 @@ -27,11 +27,16 @@ friend class AbstractInterpreterGenerator; + address generate_deopt_entry_for(TosState state, int step); + private: address generate_normal_entry(bool synchronized); address generate_native_entry(bool synchronized); - address generate_abstract_entry(void); +#ifdef GRAAL + address generate_execute_compiled_method_entry(); +#endif + address generate_abstract_entry(void); address generate_math_entry(AbstractInterpreter::MethodKind kind); address generate_empty_entry(void); address generate_accessor_entry(void); diff -r de73bbbde021 -r 8ad4e90fc5d7 src/cpu/sparc/vm/nativeInst_sparc.cpp --- a/src/cpu/sparc/vm/nativeInst_sparc.cpp Mon Jun 10 08:44:03 2013 +0200 +++ b/src/cpu/sparc/vm/nativeInst_sparc.cpp Mon Jun 10 08:44:25 2013 +0200 @@ -24,6 +24,8 @@ #include "precompiled.hpp" #include "asm/macroAssembler.hpp" +#include "asm/macroAssembler.inline.hpp" +#include "code/codeCache.hpp" #include "memory/resourceArea.hpp" #include "nativeInst_sparc.hpp" #include "oops/oop.inline.hpp" diff -r de73bbbde021 -r 8ad4e90fc5d7 src/cpu/sparc/vm/sharedRuntime_sparc.cpp --- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Mon Jun 10 08:44:03 2013 +0200 +++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Mon Jun 10 08:44:25 2013 +0200 @@ -1826,6 +1826,20 @@ verify_oop_args(masm, method, sig_bt, regs); vmIntrinsics::ID iid = method->intrinsic_id(); + +#ifdef GRAAL + if (iid == vmIntrinsics::_CompilerToVMImpl_executeCompiledMethod) { + // We are called from compiled code here. The three object arguments + // are already in the correct registers (j_rarg0, jrarg1, jrarg2). The + // fourth argument (j_rarg3) is a raw pointer to the nmethod. Make a tail + // call to its verified entry point. + __ set(nmethod::verified_entry_point_offset(), O0); + __ JMP(O0, 0); + __ delayed()->nop(); + return; + } +#endif + // Now write the args into the outgoing interpreter space bool has_receiver = false; Register receiver_reg = noreg; diff -r de73bbbde021 -r 8ad4e90fc5d7 src/cpu/sparc/vm/templateInterpreter_sparc.cpp --- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Mon Jun 10 08:44:03 2013 +0200 +++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Mon Jun 10 08:44:25 2013 +0200 @@ -213,7 +213,7 @@ } -address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) { +address InterpreterGenerator::generate_deopt_entry_for(TosState state, int step) { address entry = __ pc(); __ get_constant_pool_cache(LcpoolCache); // load LcpoolCache { Label L; @@ -813,6 +813,19 @@ return generate_accessor_entry(); } +#ifdef GRAAL + +// Interpreter stub for calling a compiled method with 3 object arguments +address InterpreterGenerator::generate_execute_compiled_method_entry() { + address entry_point = __ pc(); + + __ stop("graal-sparc unimp"); + + return entry_point; +} + +#endif + // // Interpreter stub for calling a native method. (asm interpreter) // This sets up a somewhat different looking stack for calling the native method diff -r de73bbbde021 -r 8ad4e90fc5d7 src/cpu/x86/vm/codeInstaller_x86.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/x86/vm/codeInstaller_x86.hpp Mon Jun 10 08:44:25 2013 +0200 @@ -0,0 +1,192 @@ +/* + * 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. + */ +#ifndef CPU_SPARC_VM_CODEINSTALLER_X86_HPP +#define CPU_SPARC_VM_CODEINSTALLER_X86_HPP + +#include "compiler/disassembler.hpp" +#include "runtime/javaCalls.hpp" +#include "graal/graalEnv.hpp" +#include "graal/graalCompiler.hpp" +#include "graal/graalCodeInstaller.hpp" +#include "graal/graalJavaAccess.hpp" +#include "graal/graalCompilerToVM.hpp" +#include "graal/graalRuntime.hpp" +#include "asm/register.hpp" +#include "classfile/vmSymbols.hpp" +#include "code/vmreg.hpp" + +inline jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method) { + if (inst->is_call() || inst->is_jump()) { + assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size"); + return (pc_offset + NativeCall::instruction_size); + } else if (inst->is_mov_literal64()) { + // mov+call instruction pair + jint offset = pc_offset + NativeMovConstReg::instruction_size; + u_char* call = (u_char*) (_instructions->start() + offset); + assert((call[0] == 0x40 || call[0] == 0x41) && call[1] == 0xFF, "expected call with rex/rexb prefix byte"); + offset += 3; /* prefix byte + opcode byte + modrm byte */ + return (offset); + } else if (inst->is_call_reg()) { + // the inlined vtable stub contains a "call register" instruction + assert(method != NULL, "only valid for virtual calls"); + return (pc_offset + ((NativeCallReg *) inst)->next_instruction_offset()); + } else { + fatal("unsupported type of instruction for call site"); + return 0; + } +} + +inline void CodeInstaller::pd_site_DataPatch(oop constant, oop kind, bool inlined, + address instruction, int alignment, char typeChar) { + switch (typeChar) { + case 'z': + case 'b': + case 's': + case 'c': + case 'i': + fatal("int-sized values not expected in DataPatch"); + break; + case 'f': + case 'j': + case 'd': { + if (inlined) { + address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); + *((jlong*) operand) = Constant::primitive(constant); + } else { + address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand); + address next_instruction = Assembler::locate_next_instruction(instruction); + int size = _constants->size(); + if (alignment > 0) { + guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); + size = align_size_up(size, alignment); + } + // we don't care if this is a long/double/etc., the primitive field contains the right bits + address dest = _constants->start() + size; + _constants->set_end(dest + BytesPerLong); + *(jlong*) dest = Constant::primitive(constant); + + long disp = dest - next_instruction; + assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); + *((jint*) operand) = (jint) disp; + + _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); + TRACE_graal_3("relocating (%c) at %p/%p with destination at %p (%d)", typeChar, instruction, operand, dest, size); + } + break; + } + case 'a': { + address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); + Handle obj = Constant::object(constant); + + jobject value = JNIHandles::make_local(obj()); + *((jobject*) operand) = value; + _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); + TRACE_graal_3("relocating (oop constant) at %p/%p", instruction, operand); + break; + } + default: + fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar)); + break; + } +} + +inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) { + if (cb->is_nmethod()) { + nmethod* nm = (nmethod*) cb; + nativeJump_at((address)inst)->set_jump_destination(nm->verified_entry_point()); + } else { + nativeJump_at((address)inst)->set_jump_destination(cb->code_begin()); + } + _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand); +} + +inline void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) { + if (inst->is_call()) { + // NOTE: for call without a mov, the offset must fit a 32-bit immediate + // see also CompilerToVM.getMaxCallTargetOffset() + NativeCall* call = nativeCall_at((address) (inst)); + call->set_destination((address) foreign_call_destination); + _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); + } else if (inst->is_mov_literal64()) { + NativeMovConstReg* mov = nativeMovConstReg_at((address) (inst)); + mov->set_data((intptr_t) foreign_call_destination); + _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand); + } else { + NativeJump* jump = nativeJump_at((address) (inst)); + jump->set_jump_destination((address) foreign_call_destination); + _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand); + } + TRACE_graal_3("relocating (foreign call) at %p", inst); +} + +inline void CodeInstaller::pd_relocate_JavaMethod(oop hotspot_method, jint pc_offset) { +#ifdef ASSERT + Method* method = NULL; + // we need to check, this might also be an unresolved method + if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) { + method = getMethodFromHotSpotMethod(hotspot_method); + } +#endif + switch (_next_call_type) { + case MARK_INLINE_INVOKE: + break; + case MARK_INVOKEVIRTUAL: + case MARK_INVOKEINTERFACE: { + assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); + + NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + call->set_destination(SharedRuntime::get_resolve_virtual_call_stub()); + _instructions->relocate(call->instruction_address(), + virtual_call_Relocation::spec(_invoke_mark_pc), + Assembler::call32_operand); + break; + } + case MARK_INVOKESTATIC: { + assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic"); + + NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + call->set_destination(SharedRuntime::get_resolve_static_call_stub()); + _instructions->relocate(call->instruction_address(), + relocInfo::static_call_type, Assembler::call32_operand); + break; + } + case MARK_INVOKESPECIAL: { + assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial"); + NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); + call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub()); + _instructions->relocate(call->instruction_address(), + relocInfo::opt_virtual_call_type, Assembler::call32_operand); + break; + } + default: + fatal("invalid _next_call_type value"); + break; + } +} + +inline int32_t* CodeInstaller::pd_locate_operand(address instruction) { + return (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand); +} + +#endif // CPU_SPARC_VM_CODEINSTALLER_X86_HPP + diff -r de73bbbde021 -r 8ad4e90fc5d7 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Mon Jun 10 08:44:03 2013 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Mon Jun 10 08:44:25 2013 +0200 @@ -314,6 +314,7 @@ template(com_oracle_graal_hotspot_meta_HotSpotMonitorValue, "com/oracle/graal/hotspot/meta/HotSpotMonitorValue") \ template(com_oracle_graal_hotspot_debug_LocalImpl, "com/oracle/graal/hotspot/debug/LocalImpl") \ AMD64_ONLY(template(com_oracle_graal_hotspot_amd64_AMD64HotSpotGraalRuntime,"com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime"))\ + SPARC_ONLY(template(com_oracle_graal_hotspot_sparc_SPARCHotSpotGraalRuntime,"com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime"))\ /* graal.api.meta */ \ template(com_oracle_graal_api_meta_Constant, "com/oracle/graal/api/meta/Constant") \ template(com_oracle_graal_api_meta_ConstantPool, "com/oracle/graal/api/meta/ConstantPool") \ diff -r de73bbbde021 -r 8ad4e90fc5d7 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Mon Jun 10 08:44:03 2013 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Mon Jun 10 08:44:25 2013 +0200 @@ -35,18 +35,23 @@ #include "code/vmreg.hpp" #ifdef TARGET_ARCH_x86 +# include "codeInstaller_x86.hpp" # include "vmreg_x86.inline.hpp" #endif #ifdef TARGET_ARCH_sparc +# include "codeInstaller_sparc.hpp" # include "vmreg_sparc.inline.hpp" #endif #ifdef TARGET_ARCH_zero +# include "codeInstaller_zero.hpp" # include "vmreg_zero.inline.hpp" #endif #ifdef TARGET_ARCH_arm +# include "codeInstaller_arm.hpp" # include "vmreg_arm.inline.hpp" #endif #ifdef TARGET_ARCH_ppc +# include "codeInstaller_ppc.hpp" # include "vmreg_ppc.inline.hpp" #endif @@ -199,8 +204,16 @@ } return value; #else +#ifdef TARGET_ARCH_sparc + ScopeValue* value = new LocationValue(Location::new_reg_loc(locationType, as_FloatRegister(number)->as_VMReg())); + if (type == T_DOUBLE) { + second = value; + } + return value; +#else ShouldNotReachHere("Platform currently does not support floating point values."); #endif +#endif } } else if (value->is_a(StackSlot::klass())) { if (type == T_DOUBLE) { @@ -704,36 +717,15 @@ assert((hotspot_method ? 1 : 0) + (foreign_call ? 1 : 0) == 1, "Call site needs exactly one type"); NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset); - jint next_pc_offset = 0x0; - if (inst->is_call() || inst->is_jump()) { - assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size"); - next_pc_offset = pc_offset + NativeCall::instruction_size; - } else if (inst->is_mov_literal64()) { - // mov+call instruction pair - next_pc_offset = pc_offset + NativeMovConstReg::instruction_size; - u_char* call = (u_char*) (_instructions->start() + next_pc_offset); - assert((call[0] == 0x40 || call[0] == 0x41) && call[1] == 0xFF, "expected call with rex/rexb prefix byte"); - next_pc_offset += 3; /* prefix byte + opcode byte + modrm byte */ - } else if (inst->is_call_reg()) { - // the inlined vtable stub contains a "call register" instruction - assert(hotspot_method != NULL, "only valid for virtual calls"); - next_pc_offset = pc_offset + ((NativeCallReg *) inst)->next_instruction_offset(); - } else { - fatal("unsupported type of instruction for call site"); - } - + jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method); + if (target->is_a(SystemDictionary::HotSpotInstalledCode_klass())) { assert(inst->is_jump(), "jump expected"); CodeBlob* cb = (CodeBlob*) (address) HotSpotInstalledCode::codeBlob(target); assert(cb != NULL, "npe"); - if (cb->is_nmethod()) { - nmethod* nm = (nmethod*) cb; - nativeJump_at((address)inst)->set_jump_destination(nm->verified_entry_point()); - } else { - nativeJump_at((address)inst)->set_jump_destination(cb->code_begin()); - } - _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand); + + CodeInstaller::pd_relocate_CodeBlob(cb, inst); return; } @@ -750,65 +742,14 @@ if (foreign_call != NULL) { jlong foreign_call_destination = HotSpotForeignCallLinkage::address(foreign_call); - if (inst->is_call()) { - // NOTE: for call without a mov, the offset must fit a 32-bit immediate - // see also CompilerToVM.getMaxCallTargetOffset() - NativeCall* call = nativeCall_at((address) (inst)); - call->set_destination((address) foreign_call_destination); - _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand); - } else if (inst->is_mov_literal64()) { - NativeMovConstReg* mov = nativeMovConstReg_at((address) (inst)); - mov->set_data((intptr_t) foreign_call_destination); - _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand); - } else { - NativeJump* jump = nativeJump_at((address) (inst)); - jump->set_jump_destination((address) foreign_call_destination); - _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand); - } - TRACE_graal_3("relocating (foreign call) at %p", inst); + + CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination); } else { // method != NULL assert(hotspot_method != NULL, "unexpected JavaMethod"); -#ifdef ASSERT - Method* method = NULL; - // we need to check, this might also be an unresolved method - if (hotspot_method->is_a(HotSpotResolvedJavaMethod::klass())) { - method = getMethodFromHotSpotMethod(hotspot_method); - } -#endif assert(debug_info != NULL, "debug info expected"); TRACE_graal_3("method call"); - switch (_next_call_type) { - case MARK_INLINE_INVOKE: - break; - case MARK_INVOKEVIRTUAL: - case MARK_INVOKEINTERFACE: { - assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); - - NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); - call->set_destination(SharedRuntime::get_resolve_virtual_call_stub()); - _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc), Assembler::call32_operand); - break; - } - case MARK_INVOKESTATIC: { - assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic"); - - NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); - call->set_destination(SharedRuntime::get_resolve_static_call_stub()); - _instructions->relocate(call->instruction_address(), relocInfo::static_call_type, Assembler::call32_operand); - break; - } - case MARK_INVOKESPECIAL: { - assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial"); - NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); - call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub()); - _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type, Assembler::call32_operand); - break; - } - default: - fatal("invalid _next_call_type value"); - break; - } + CodeInstaller::pd_relocate_JavaMethod(hotspot_method, pc_offset); } _next_call_type = MARK_INVOKE_INVALID; if (debug_info != NULL) { @@ -823,59 +764,15 @@ oop kind = Constant::kind(constant); address instruction = _instructions->start() + pc_offset; - char typeChar = Kind::typeChar(kind); switch (typeChar) { - case 'z': - case 'b': - case 's': - case 'c': - case 'i': - fatal("int-sized values not expected in DataPatch"); - break; case 'f': case 'j': - case 'd': { + case 'd': record_metadata_in_constant(constant, _oop_recorder); - if (inlined) { - address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); - *((jlong*) operand) = Constant::primitive(constant); - } else { - address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand); - address next_instruction = Assembler::locate_next_instruction(instruction); - int size = _constants->size(); - if (alignment > 0) { - guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); - size = align_size_up(size, alignment); - } - // we don't care if this is a long/double/etc., the primitive field contains the right bits - address dest = _constants->start() + size; - _constants->set_end(dest + BytesPerLong); - *(jlong*) dest = Constant::primitive(constant); - - long disp = dest - next_instruction; - assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); - *((jint*) operand) = (jint) disp; - - _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); - TRACE_graal_3("relocating (%c) at %p/%p with destination at %p (%d)", typeChar, instruction, operand, dest, size); - } - break; - } - case 'a': { - address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); - Handle obj = Constant::object(constant); - - jobject value = JNIHandles::make_local(obj()); - *((jobject*) operand) = value; - _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); - TRACE_graal_3("relocating (oop constant) at %p/%p", instruction, operand); - break; - } - default: - fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar)); break; } + CodeInstaller::pd_site_DataPatch(constant, kind, inlined, instruction, alignment, typeChar); } void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) { @@ -920,7 +817,8 @@ break; case MARK_POLL_NEAR: { NativeInstruction* ni = nativeInstruction_at(instruction); - int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand); + int32_t* disp = (int32_t*) pd_locate_operand(instruction); + // int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand); int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni; *disp = (int32_t)new_disp; @@ -930,7 +828,8 @@ break; case MARK_POLL_RETURN_NEAR: { NativeInstruction* ni = nativeInstruction_at(instruction); - int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand); + int32_t* disp = (int32_t*) pd_locate_operand(instruction); + // int32_t* disp = (int32_t*) Assembler::locate_operand(instruction, Assembler::disp32_operand); int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni; *disp = (int32_t)new_disp; diff -r de73bbbde021 -r 8ad4e90fc5d7 src/share/vm/graal/graalCodeInstaller.hpp --- a/src/share/vm/graal/graalCodeInstaller.hpp Mon Jun 10 08:44:03 2013 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Mon Jun 10 08:44:25 2013 +0200 @@ -75,6 +75,13 @@ Dependencies* _dependencies; ExceptionHandlerTable _exception_handler_table; + jint pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method); + void pd_site_DataPatch(oop constant, oop kind, bool inlined, address instruction, int alignment, char typeChar); + void pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst); + void pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination); + void pd_relocate_JavaMethod(oop method, jint pc_offset); + int32_t* pd_locate_operand(address instruction); + public: CodeInstaller(Handle& comp_result, GraalEnv::CodeInstallResult& result, CodeBlob*& cb, Handle installed_code, Handle triggered_deoptimizations); @@ -106,4 +113,20 @@ }; +#ifdef TARGET_ARCH_x86 +# include "codeInstaller_x86.hpp" +#endif +#ifdef TARGET_ARCH_sparc +# include "codeInstaller_sparc.hpp" +#endif +#ifdef TARGET_ARCH_zero +# error +#endif +#ifdef TARGET_ARCH_arm +# error +#endif +#ifdef TARGET_ARCH_ppc +# error +#endif + #endif // SHARE_VM_GRAAL_GRAAL_CODE_INSTALLER_HPP diff -r de73bbbde021 -r 8ad4e90fc5d7 src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Mon Jun 10 08:44:03 2013 +0200 +++ b/src/share/vm/graal/graalCompiler.cpp Mon Jun 10 08:44:25 2013 +0200 @@ -51,7 +51,7 @@ uintptr_t heap_end = (uintptr_t) Universe::heap()->reserved_region().end(); uintptr_t allocation_end = heap_end + ((uintptr_t)16) * 1024 * 1024 * 1024; - guarantee(heap_end < allocation_end, "heap end too close to end of address space (might lead to erroneous TLAB allocations)"); + AMD64_ONLY(guarantee(heap_end < allocation_end, "heap end too close to end of address space (might lead to erroneous TLAB allocations)")); NOT_LP64(error("check TLAB allocation code for address space conflicts")); _deopted_leaf_graph_count = 0; diff -r de73bbbde021 -r 8ad4e90fc5d7 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Mon Jun 10 08:44:03 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Mon Jun 10 08:44:25 2013 +0200 @@ -658,8 +658,10 @@ set_boolean("useAESIntrinsics", UseAESIntrinsics); set_boolean("useTLAB", UseTLAB); set_boolean("useG1GC", UseG1GC); +#ifdef TARGET_ARCH_x86 set_int("useSSE", UseSSE); set_int("useAVX", UseAVX); +#endif set_int("codeEntryAlignment", CodeEntryAlignment); set_int("stackShadowPages", StackShadowPages); set_int("hubOffset", oopDesc::klass_offset_in_bytes()); @@ -695,9 +697,11 @@ set_int("klassHasFinalizerFlag", JVM_ACC_HAS_FINALIZER); set_int("threadExceptionOopOffset", in_bytes(JavaThread::exception_oop_offset())); set_int("threadExceptionPcOffset", in_bytes(JavaThread::exception_pc_offset())); +#ifdef TARGET_ARCH_x86 set_boolean("isPollingPageFar", Assembler::is_polling_page_far()); + set_int("runtimeCallStackSize", (jint)frame::arg_reg_save_area_bytes); +#endif set_int("classMirrorOffset", in_bytes(Klass::java_mirror_offset())); - set_int("runtimeCallStackSize", (jint)frame::arg_reg_save_area_bytes); set_int("klassModifierFlagsOffset", in_bytes(Klass::modifier_flags_offset())); set_int("klassAccessFlagsOffset", in_bytes(Klass::access_flags_offset())); set_int("klassOffset", java_lang_Class::klass_offset_in_bytes()); @@ -744,7 +748,9 @@ set_int("threadTlabSizeOffset", in_bytes(JavaThread::tlab_size_offset())); set_int("threadAllocatedBytesOffset", in_bytes(JavaThread::allocated_bytes_offset())); set_int("threadLastJavaSpOffset", in_bytes(JavaThread::last_Java_sp_offset())); +#ifdef TARGET_ARCH_x86 set_int("threadLastJavaFpOffset", in_bytes(JavaThread::last_Java_fp_offset())); +#endif set_int("threadLastJavaPcOffset", in_bytes(JavaThread::last_Java_pc_offset())); set_int("threadObjectResultOffset", in_bytes(JavaThread::vm_result_offset())); set_int("tlabSlowAllocationsOffset", in_bytes(JavaThread::tlab_slow_allocations_offset())); diff -r de73bbbde021 -r 8ad4e90fc5d7 src/share/vm/graal/graalVMToCompiler.cpp --- a/src/share/vm/graal/graalVMToCompiler.cpp Mon Jun 10 08:44:03 2013 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.cpp Mon Jun 10 08:44:25 2013 +0200 @@ -51,6 +51,9 @@ #ifdef AMD64 Symbol* name = vmSymbols::com_oracle_graal_hotspot_amd64_AMD64HotSpotGraalRuntime(); #endif +#ifdef SPARC + Symbol* name = vmSymbols::com_oracle_graal_hotspot_sparc_SPARCHotSpotGraalRuntime(); +#endif KlassHandle klass = loadClass(name); JavaValue result(T_OBJECT); diff -r de73bbbde021 -r 8ad4e90fc5d7 src/share/vm/runtime/fieldDescriptor.cpp --- a/src/share/vm/runtime/fieldDescriptor.cpp Mon Jun 10 08:44:03 2013 +0200 +++ b/src/share/vm/runtime/fieldDescriptor.cpp Mon Jun 10 08:44:25 2013 +0200 @@ -27,9 +27,6 @@ #include "classfile/vmSymbols.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.inline.hpp" -#include "oops/annotations.hpp" -#include "oops/instanceKlass.hpp" -#include "oops/fieldStreams.hpp" #include "runtime/fieldDescriptor.hpp" #include "runtime/handles.inline.hpp" #include "runtime/signature.hpp" diff -r de73bbbde021 -r 8ad4e90fc5d7 src/share/vm/runtime/fieldDescriptor.hpp --- a/src/share/vm/runtime/fieldDescriptor.hpp Mon Jun 10 08:44:03 2013 +0200 +++ b/src/share/vm/runtime/fieldDescriptor.hpp Mon Jun 10 08:44:25 2013 +0200 @@ -25,7 +25,10 @@ #ifndef SHARE_VM_RUNTIME_FIELDDESCRIPTOR_HPP #define SHARE_VM_RUNTIME_FIELDDESCRIPTOR_HPP +#include "oops/annotations.hpp" #include "oops/constantPool.hpp" +#include "oops/fieldStreams.hpp" +#include "oops/instanceKlass.hpp" #include "oops/symbol.hpp" #include "runtime/fieldType.hpp" #include "utilities/accessFlags.hpp"