# HG changeset patch # User Mick Jordan # Date 1378242596 25200 # Node ID 1f03076a121b1b58f6b880c27af1041d2421668c # Parent 20b6424936161ece30a930e9e38704eb7069b280# Parent dc3c8df5590565dabbc8b30a64fa09146ab6c8a0 Merge diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java Tue Sep 03 14:09:56 2013 -0700 @@ -192,7 +192,7 @@ * null if no arithmetic needs to be performed on the vector * @return a supported vector size, but at most {@code maxLength} */ - public int getSupportedVectorLength(Kind kind, int maxLength, ArithmeticOperation arithmetic) { + public int getSupportedVectorLength(Kind kind, int maxLength, Class arithmetic) { return 1; } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Tue Sep 03 14:09:56 2013 -0700 @@ -89,12 +89,4 @@ * Gets a description of the target architecture. */ TargetDescription getTarget(); - - /** - * Returns the register the runtime uses for maintaining the heap base address. This is mainly - * utilized by runtimes which support compressed pointers. - * - * @return the register that keeps the heap base address - */ - Register heapBaseRegister(); } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Tue Sep 03 14:09:56 2013 -0700 @@ -454,4 +454,102 @@ throw new IllegalArgumentException(kind.toString()); } } + + /** + * Returns the zero value for a given numeric kind. + */ + public static Constant zero(Kind kind) { + switch (kind) { + case Byte: + return forByte((byte) 0); + case Char: + return forChar((char) 0); + case Double: + return DOUBLE_0; + case Float: + return FLOAT_0; + case Int: + return INT_0; + case Long: + return LONG_0; + case Short: + return forShort((short) 0); + default: + throw new IllegalArgumentException(kind.toString()); + } + } + + /** + * Returns the one value for a given numeric kind. + */ + public static Constant one(Kind kind) { + switch (kind) { + case Byte: + return forByte((byte) 1); + case Char: + return forChar((char) 1); + case Double: + return DOUBLE_1; + case Float: + return FLOAT_1; + case Int: + return INT_1; + case Long: + return LONG_1; + case Short: + return forShort((short) 1); + default: + throw new IllegalArgumentException(kind.toString()); + } + } + + /** + * Adds two numeric constants. + */ + public static Constant add(Constant x, Constant y) { + assert x.getKind() == y.getKind(); + switch (x.getKind()) { + case Byte: + return forByte((byte) (x.asInt() + y.asInt())); + case Char: + return forChar((char) (x.asInt() + y.asInt())); + case Double: + return forDouble(x.asDouble() + y.asDouble()); + case Float: + return forFloat(x.asFloat() + y.asFloat()); + case Int: + return forInt(x.asInt() + y.asInt()); + case Long: + return forLong(x.asLong() + y.asLong()); + case Short: + return forShort((short) (x.asInt() + y.asInt())); + default: + throw new IllegalArgumentException(x.getKind().toString()); + } + } + + /** + * Multiplies two numeric constants. + */ + public static Constant mul(Constant x, Constant y) { + assert x.getKind() == y.getKind(); + switch (x.getKind()) { + case Byte: + return forByte((byte) (x.asInt() * y.asInt())); + case Char: + return forChar((char) (x.asInt() * y.asInt())); + case Double: + return forDouble(x.asDouble() * y.asDouble()); + case Float: + return forFloat(x.asFloat() * y.asFloat()); + case Int: + return forInt(x.asInt() * y.asInt()); + case Long: + return forLong(x.asLong() * y.asLong()); + case Short: + return forShort((short) (x.asInt() * y.asInt())); + default: + throw new IllegalArgumentException(x.getKind().toString()); + } + } } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java --- a/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Tue Sep 03 14:09:56 2013 -0700 @@ -272,59 +272,69 @@ } public final void ld_global_b8(Register d, Register a, long immOff) { - emitString("ld.global.b8" + " " + "%r" + d.encoding() + ", [%r" + a.encoding() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.b8" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); } public final void ld_global_b16(Register d, Register a, long immOff) { - emitString("ld.global.b16" + " " + "%r" + d.encoding() + ", [%r" + a.encoding() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.b16" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); } public final void ld_global_b32(Register d, Register a, long immOff) { - emitString("ld.global.b32" + " " + "%r" + d.encoding() + ", [%r" + a.encoding() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.b32" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); } public final void ld_global_b64(Register d, Register a, long immOff) { - emitString("ld.global.b64" + " " + "%r" + d.encoding() + ", [%r" + a.encoding() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.b64" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); } public final void ld_global_u8(Register d, Register a, long immOff) { - emitString("ld.global.u8" + " " + "%r" + d.encoding() + ", [%r" + a.encoding() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.u8" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); } public final void ld_global_u16(Register d, Register a, long immOff) { - emitString("ld.global.u16" + " " + "%r" + d.encoding() + ", [%r" + a.encoding() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.u16" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); } public final void ld_global_u32(Register d, Register a, long immOff) { - emitString("ld.global.u32" + " " + "%r" + d.encoding() + ", [%r" + a.encoding() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.u32" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); } public final void ld_global_u64(Register d, Register a, long immOff) { - emitString("ld.global.u64" + " " + "%r" + d.encoding() + ", [%r" + a.encoding() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.u64" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); } public final void ld_global_s8(Register d, Register a, long immOff) { - emitString("ld.global.s8" + " " + "%r" + d.encoding() + ", [%r" + a.encoding() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.s8" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); } public final void ld_global_s16(Register d, Register a, long immOff) { - emitString("ld.global.s16" + " " + "%r" + d.encoding() + ", [%r" + a.encoding() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.s16" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); } public final void ld_global_s32(Register d, Register a, long immOff) { - emitString("ld.global.s32" + " " + "%r" + d.encoding() + ", [%r" + a.encoding() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.s32" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); } public final void ld_global_s64(Register d, Register a, long immOff) { - emitString("ld.global.s64" + " " + "%r" + d.encoding() + ", [%r" + a.encoding() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.s64" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); } public final void ld_global_f32(Register d, Register a, long immOff) { - emitString("ld.global.f32" + " " + "%r" + d.encoding() + ", [%r" + a.encoding() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.f32" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); } public final void ld_global_f64(Register d, Register a, long immOff) { - emitString("ld.global.f64" + " " + "%r" + d.encoding() + ", [%r" + a.encoding() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.f64" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); + } + + // Load from state space to destination register + public final void ld_from_state_space(String s, Register d, Register a, long immOff) { + emitString("ld" + s + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); + } + + // Load return address from return parameter which is in .param state space + public final void ld_return_address(String s, Register d, Register a, long immOff) { + emitString("ld.param." + s + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); } public final void mov_b16(Register d, Register a) { @@ -539,6 +549,18 @@ emitString("or.b64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + b64 + ";" + ""); } + public final void param_8_decl(Register d, boolean lastParam) { + emitString(".param" + " " + ".s8" + " " + d.toString() + (lastParam ? "" : ",")); + } + + public final void param_32_decl(Register d, boolean lastParam) { + emitString(".param" + " " + ".s32" + " " + d.toString() + (lastParam ? "" : ",")); + } + + public final void param_64_decl(Register d, boolean lastParam) { + emitString(".param" + " " + ".s64" + " " + d.toString() + (lastParam ? "" : ",")); + } + public final void popc_b32(Register d, Register a) { emitString("popc.b32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ";" + ""); } @@ -923,6 +945,8 @@ emitString("shr.u64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + u64 + ";" + ""); } + // Store in global state space + public final void st_global_b8(Register a, long immOff, Register b) { emitString("st.global.b8" + " " + "[%r" + a.encoding() + " + " + immOff + "], %r" + b.encoding() + ";" + ""); } @@ -979,6 +1003,37 @@ emitString("st.global.f64" + " " + "[%r" + a.encoding() + " + " + immOff + "], %r" + b.encoding() + ";" + ""); } + // Store return value + public final void st_global_return_value_s8(Register a, long immOff, Register b) { + emitString("st.global.s8" + " " + "[%r" + a.encoding() + " + " + immOff + "], %r" + b.encoding() + ";" + ""); + } + + public final void st_global_return_value_s32(Register a, long immOff, Register b) { + emitString("st.global.s32" + " " + "[%r" + a.encoding() + " + " + immOff + "], %r" + b.encoding() + ";" + ""); + } + + public final void st_global_return_value_s64(Register a, long immOff, Register b) { + emitString("st.global.s64" + " " + "[%r" + a.encoding() + " + " + immOff + "], %r" + b.encoding() + ";" + ""); + } + + public final void st_global_return_value_f32(Register a, long immOff, Register b) { + emitString("st.global.f32" + " " + "[%r" + a.encoding() + " + " + immOff + "], %r" + b.encoding() + ";" + ""); + } + + public final void st_global_return_value_f64(Register a, long immOff, Register b) { + emitString("st.global.f64" + " " + "[%r" + a.encoding() + " + " + immOff + "], %r" + b.encoding() + ";" + ""); + } + + public final void st_global_return_value_u32(Register a, long immOff, Register b) { + emitString("st.global.u32" + " " + "[%r" + a.encoding() + " + " + immOff + "], %r" + b.encoding() + ";" + ""); + } + + public final void st_global_return_value_u64(Register a, long immOff, Register b) { + emitString("st.global.u64" + " " + "[%r" + a.encoding() + " + " + immOff + "], %r" + b.encoding() + ";" + ""); + } + + // Subtract instruction + public final void sub_f32(Register d, Register a, Register b) { emitString("sub.f32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayTest.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayTest.java Tue Sep 03 14:09:56 2013 -0700 @@ -24,10 +24,11 @@ import java.lang.reflect.Method; -import org.junit.Test; +import org.junit.*; public class ArrayTest extends PTXTestBase { + @Ignore @Test public void testArray() { compile("testArray1I"); diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java Tue Sep 03 14:09:56 2013 -0700 @@ -41,7 +41,7 @@ invoke(compile("testConstI")); } - public int testConstI() { + public static int testConstI() { return 42; } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlTest.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlTest.java Tue Sep 03 14:09:56 2013 -0700 @@ -22,12 +22,13 @@ */ package com.oracle.graal.compiler.ptx.test; -import org.junit.Test; +import org.junit.*; import java.lang.reflect.Method; public class ControlTest extends PTXTestBase { + @Ignore @Test public void testControl() { compile("testSwitch1I"); diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/FloatPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/FloatPTXTest.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/FloatPTXTest.java Tue Sep 03 14:09:56 2013 -0700 @@ -26,18 +26,38 @@ import org.junit.*; +import com.oracle.graal.api.code.CompilationResult; /* PTX ISA 3.1 - 8.7.3 Floating-Point Instructions */ public class FloatPTXTest extends PTXTestBase { @Test public void testAdd() { - compile("testAdd2F"); - compile("testAdd2D"); - compile("testAddFConst"); - compile("testAddConstF"); - compile("testAddDConst"); - compile("testAddConstD"); + CompilationResult r = compile("testAdd2F"); + if (r.getTargetCode() == null) { + printReport("Compilation of testAdd2F FAILED"); + } + r = compile("testAdd2D"); + if (r.getTargetCode() == null) { + printReport("Compilation of testAdd2D FAILED"); + } + + r = compile("testAddFConst"); + if (r.getTargetCode() == null) { + printReport("Compilation of testAddFConst FAILED"); + } + r = compile("testAddConstF"); + if (r.getTargetCode() == null) { + printReport("Compilation of testConstF FAILED"); + } + r = compile("testAddDConst"); + if (r.getTargetCode() == null) { + printReport("Compilation of testAddDConst FAILED"); + } + r = compile("testAddConstD"); + if (r.getTargetCode() == null) { + printReport("Compilation of testConstD FAILED"); + } } public static float testAdd2F(float a, float b) { @@ -66,12 +86,35 @@ @Test public void testSub() { - compile("testSub2F"); - compile("testSub2D"); - compile("testSubFConst"); - compile("testSubConstF"); - compile("testSubDConst"); - compile("testSubConstD"); + CompilationResult r = compile("testSub2F"); + if (r.getTargetCode() == null) { + printReport("Compilation of testSub2F FAILED"); + } + + r = compile("testSub2D"); + if (r.getTargetCode() == null) { + printReport("Compilation of testSub2D FAILED"); + } + + r = compile("testSubFConst"); + if (r.getTargetCode() == null) { + printReport("Compilation of testSubFConst FAILED"); + } + + r = compile("testSubConstF"); + if (r.getTargetCode() == null) { + printReport("Compilation of testSubConstF FAILED"); + } + + r = compile("testSubDConst"); + if (r.getTargetCode() == null) { + printReport("Compilation of testSubDconst FAILED"); + } + + r = compile("testSubConstD"); + if (r.getTargetCode() == null) { + printReport("Compilation of testConstD FAILED"); + } } public static float testSub2F(float a, float b) { @@ -100,12 +143,35 @@ @Test public void testMul() { - compile("testMul2F"); - compile("testMul2D"); - compile("testMulFConst"); - compile("testMulConstF"); - compile("testMulDConst"); - compile("testMulConstD"); + CompilationResult r = compile("testMul2F"); + if (r.getTargetCode() == null) { + printReport("Compilation of testAdd2F FAILED"); + } + + r = compile("testMul2D"); + if (r.getTargetCode() == null) { + printReport("Compilation of testAdd2F FAILED"); + } + + r = compile("testMulFConst"); + if (r.getTargetCode() == null) { + printReport("Compilation of testAdd2F FAILED"); + } + + r = compile("testMulConstF"); + if (r.getTargetCode() == null) { + printReport("Compilation of testAdd2F FAILED"); + } + + r = compile("testMulDConst"); + if (r.getTargetCode() == null) { + printReport("Compilation of testAdd2F FAILED"); + } + + r = compile("testMulConstD"); + if (r.getTargetCode() == null) { + printReport("Compilation of testAdd2F FAILED"); + } } public static float testMul2F(float a, float b) { @@ -134,12 +200,35 @@ @Test public void testDiv() { - compile("testDiv2F"); - compile("testDiv2D"); - compile("testDivFConst"); - compile("testDivConstF"); - compile("testDivDConst"); - compile("testDivConstD"); + CompilationResult r = compile("testDiv2F"); + if (r.getTargetCode() == null) { + printReport("Compilation of testDiv2F FAILED"); + } + + r = compile("testDiv2D"); + if (r.getTargetCode() == null) { + printReport("Compilation of testDiv2D FAILED"); + } + + r = compile("testDivFConst"); + if (r.getTargetCode() == null) { + printReport("Compilation of testDivFConst FAILED"); + } + + r = compile("testDivConstF"); + if (r.getTargetCode() == null) { + printReport("Compilation of testDivConstF FAILED"); + } + + r = compile("testDivDConst"); + if (r.getTargetCode() == null) { + printReport("Compilation of testDivDConst FAILED"); + } + + r = compile("testDivConstD"); + if (r.getTargetCode() == null) { + printReport("Compilation of testDivConstD FAILED"); + } } public static float testDiv2F(float a, float b) { @@ -168,8 +257,15 @@ @Test public void testNeg() { - compile("testNeg2F"); - compile("testNeg2D"); + CompilationResult r = compile("testNeg2F"); + if (r.getTargetCode() == null) { + printReport("Compilation of testNeg2F FAILED"); + } + + r = compile("testNeg2D"); + if (r.getTargetCode() == null) { + printReport("Compilation of testNeg2D FAILED"); + } } public static float testNeg2F(float a) { @@ -195,14 +291,38 @@ return a % b; } + @Ignore @Test public void testFloatConversion() { - compile("testF2I"); - compile("testF2L"); - compile("testF2D"); - compile("testD2I"); - compile("testD2L"); - compile("testD2F"); + CompilationResult r = compile("testF2I"); + if (r.getTargetCode() == null) { + printReport("Compilation of tesF2I FAILED"); + } + + r = compile("testF2L"); + if (r.getTargetCode() == null) { + printReport("Compilation of testF2L FAILED"); + } + + r = compile("testF2D"); + if (r.getTargetCode() == null) { + printReport("Compilation of testF2D FAILED"); + } + + r = compile("testD2I"); + if (r.getTargetCode() == null) { + printReport("Compilation of testD2I FAILED"); + } + + r = compile("testD2L"); + if (r.getTargetCode() == null) { + printReport("Compilation of testD2L FAILED"); + } + + r = compile("testD2F"); + if (r.getTargetCode() == null) { + printReport("Compilation of testD2F FAILED"); + } } public static int testF2I(float a) { @@ -229,6 +349,13 @@ return (float) a; } + public static void printReport(String message) { + // CheckStyle: stop system..print check + System.out.println(message); + // CheckStyle: resume system..print check + + } + public static void main(String[] args) { FloatPTXTest test = new FloatPTXTest(); for (Method m : FloatPTXTest.class.getMethods()) { diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java Tue Sep 03 14:09:56 2013 -0700 @@ -31,11 +31,44 @@ @Test public void testAdd() { - invoke(compile("testAdd2I"), 8, 4); - invoke(compile("testAdd2L"), 12, 6); - invoke(compile("testAdd2B"), 6, 4); - invoke(compile("testAddIConst"), 5); - invoke(compile("testAddConstI"), 7); + + Long r2 = (Long) invoke(compile("testAdd2L"), (long) 12, (long) 6); + if (r2 == null) { + printReport("testAdd2L FAILED"); + } else if (r2.longValue() == 18) { + printReport("testAdd2L PASSED"); + } else { + printReport("testAdd2L FAILED"); + } + + //invoke(compile("testAdd2B"), (byte) 6, (byte) 4); + + Integer r4 = (Integer) invoke(compile("testAddIConst"), 5); + if (r4 == null) { + printReport("testAddIConst FAILED"); + } else if (r4.intValue() == 37) { + printReport("testAddIConst PASSED"); + } else { + printReport("testAddIConst FAILED"); + } + + r4 = (Integer) invoke(compile("testAddConstI"), 7); + if (r4 == null) { + printReport("testAddConstI FAILED"); + } else if (r4.intValue() == 39) { + printReport("testAddConstI PASSED"); + } else { + printReport("testAddConstI FAILED"); + } + + r4 = (Integer) invoke(compile("testAdd2I"), 18, 24); + if (r4 == null) { + printReport("testAdd2I FAILED"); + } else if (r4.intValue() == 42) { + printReport("testAdd2I PASSED"); + } else { + printReport("testAdd2I FAILED"); + } } public static int testAdd2I(int a, int b) { @@ -60,10 +93,42 @@ @Test public void testSub() { - invoke(compile("testSub2I"), 8, 4); - invoke(compile("testSub2L"), 12, 6); - invoke(compile("testSubIConst"), 35); - invoke(compile("testSubConstI"), 12); + Long r2 = (Long) invoke(compile("testSub2L"), (long) 12, (long) 6); + if (r2 == null) { + printReport("testSub2I FAILED (null return value)"); + } else if (r2.longValue() == 6) { + printReport("testSub2I PASSED"); + } else { + printReport("testSub2I FAILED"); + } + + Integer r1 = (Integer) invoke(compile("testSub2I"), 18, 4); + + if (r1 == null) { + printReport("testSub2I FAILED"); + } else if (r1.intValue() == 14) { + printReport("testSub2I PASSED"); + } else { + printReport("testSub2I FAILED"); + } + + r1 = (Integer) invoke(compile("testSubIConst"), 35); + if (r1 == null) { + printReport("testSubIConst FAILED"); + } else if (r1.intValue() == 3) { + printReport("testSubIConst PASSED"); + } else { + printReport("testSubIConst FAILED"); + } + + r1 = (Integer) invoke(compile("testSubConstI"), 12); + if (r1 == null) { + printReport("testSubConstI FAILED"); + } else if (r1.intValue() == 20) { + printReport("testSubConstI PASSED"); + } else { + printReport("testSubConstI FAILED"); + } } public static int testSub2I(int a, int b) { @@ -85,7 +150,7 @@ @Test public void testMul() { invoke(compile("testMul2I"), 8, 4); - invoke(compile("testMul2L"), 12, 6); + invoke(compile("testMul2L"), (long) 12, (long) 6); invoke(compile("testMulIConst"), 4); invoke(compile("testMulConstI"), 5); } @@ -105,11 +170,10 @@ public static int testMulConstI(int a) { return 32 * a; } - @Test public void testDiv() { invoke(compile("testDiv2I"), 8, 4); - invoke(compile("testDiv2L"), 12, 6); + invoke(compile("testDiv2L"), (long) 12, (long) 6); invoke(compile("testDivIConst"), 64); invoke(compile("testDivConstI"), 8); } @@ -133,7 +197,7 @@ @Test public void testRem() { invoke(compile("testRem2I"), 8, 4); - invoke(compile("testRem2L"), 12, 6); + invoke(compile("testRem2L"), (long) 12, (long) 6); } public static int testRem2I(int a, int b) { @@ -147,11 +211,11 @@ @Test public void testIntConversion() { invoke(compile("testI2L"), 8); - invoke(compile("testL2I"), 12L); - invoke(compile("testI2C"), 65); - invoke(compile("testI2B"), 9); - invoke(compile("testI2F"), 17); - invoke(compile("testI2D"), 22); + invoke(compile("testL2I"), (long) 12); + // invoke(compile("testI2C"), 65); + // invoke(compile("testI2B"), 9); + // invoke(compile("testI2F"), 17); + // invoke(compile("testI2D"), 22); } public static long testI2L(int a) { @@ -178,6 +242,13 @@ return (int) a; } + public static void printReport(String message) { + // CheckStyle: stop system..print check + System.out.println(message); + // CheckStyle: resume system..print check + + } + public static void main(String[] args) { IntegerPTXTest test = new IntegerPTXTest(); for (Method m : IntegerPTXTest.class.getMethods()) { diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java Tue Sep 03 14:09:56 2013 -0700 @@ -82,11 +82,11 @@ return sg; } - protected void invoke(CompilationResult result, Object... args) { + protected Object invoke(CompilationResult result, Object... args) { try { if (((ExternalCompilationResult) result).getEntryPoint() == 0) { Debug.dump(result, "[CUDA] *** Null entry point - Not launching kernel"); - return; + return null; } /* Check if the method compiled is static */ @@ -95,9 +95,11 @@ Object[] executeArgs = argsWithReceiver((isStatic ? null : this), args); HotSpotRuntime hsr = (HotSpotRuntime) runtime; InstalledCode installedCode = hsr.addExternalMethod(sg.method(), result, sg); - installedCode.executeVarargs(executeArgs); + Object r = installedCode.executeVarargs(executeArgs); + return r; } catch (Throwable th) { th.printStackTrace(); + return null; } } } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java Tue Sep 03 14:09:56 2013 -0700 @@ -22,6 +22,10 @@ */ package com.oracle.graal.compiler.ptx; +import static com.oracle.graal.api.code.ValueUtil.*; + +import java.util.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; @@ -32,6 +36,11 @@ import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.ptx.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.cfg.Block; +import com.oracle.graal.lir.LIRInstruction.OperandFlag; +import com.oracle.graal.lir.LIRInstruction.OperandMode; +import com.oracle.graal.lir.LIRInstruction.ValueProcedure; +import com.oracle.graal.graph.GraalInternalError; /** * PTX specific backend. @@ -84,67 +93,121 @@ return tasm; } - @Override - public void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) { - // Emit the prologue + private static void emitKernelEntry(TargetMethodAssembler tasm, LIRGenerator lirGen, + ResolvedJavaMethod codeCacheOwner) { + // Emit PTX kernel entry text based on PTXParameterOp + // instructions in the start block. Remove the instructions + // once kernel entry text and directives are emitted to + // facilitate seemless PTX code generation subsequently. assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method"; final String name = codeCacheOwner.getName(); Buffer codeBuffer = tasm.asm.codeBuffer; + + // Emit initial boiler-plate directives. codeBuffer.emitString(".version 1.4"); codeBuffer.emitString(".target sm_10"); codeBuffer.emitString0(".entry " + name + " ("); codeBuffer.emitString(""); - Signature signature = codeCacheOwner.getSignature(); - int paramCount = signature.getParameterCount(false); - // TODO - Revisit this. - // Bit-size of registers to be declared and used by the kernel. - int regSize = 32; - for (int i = 0; i < paramCount; i++) { - String param; - // No unsigned types in Java. So using .s specifier - switch (signature.getParameterKind(i)) { - case Boolean: - case Byte: - param = ".param .s8 param" + i; - regSize = 8; - break; - case Char: - case Short: - param = ".param .s16 param" + i; - regSize = 16; - break; - case Int: - param = ".param .s32 param" + i; - regSize = 32; - break; - case Long: - case Float: - case Double: - case Void: - param = ".param .s64 param" + i; - regSize = 32; - break; - default: - // Not sure but specify 64-bit specifier?? - param = ".param .s64 param" + i; - break; + // Get the start block + Block startBlock = lirGen.lir.cfg.getStartBlock(); + // Keep a list of ParameterOp instructions to delete from the + // list of instructions in the block. + ArrayList deleteOps = new ArrayList<>(); + + // Emit .param arguments to kernel entry based on ParameterOp + // instruction. + for (LIRInstruction op : lirGen.lir.lir(startBlock)) { + if (op instanceof PTXParameterOp) { + op.emitCode(tasm); + deleteOps.add(op); } - if (i != (paramCount - 1)) { - param += ","; - } - codeBuffer.emitString(param); } + // Delete ParameterOp instructions. + for (LIRInstruction op : deleteOps) { + lirGen.lir.lir(startBlock).remove(op); + } + + // Start emiting body of the PTX kernel. codeBuffer.emitString0(") {"); codeBuffer.emitString(""); - // XXX For now declare one predicate and all registers - codeBuffer.emitString(" .reg .pred %p,%q;"); - codeBuffer.emitString(" .reg .s" + regSize + " %r<16>;"); + codeBuffer.emitString(".reg .u64" + " %rax;"); + } + + // Emit .reg space declarations + private static void emitRegisterDecl(TargetMethodAssembler tasm, LIRGenerator lirGen, + ResolvedJavaMethod codeCacheOwner) { + assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method"; + Buffer codeBuffer = tasm.asm.codeBuffer; + + final SortedSet signed32 = new TreeSet<>(); + final SortedSet signed64 = new TreeSet<>(); + + ValueProcedure trackRegisterKind = new ValueProcedure() { + + @Override + public Value doValue(Value value, OperandMode mode, EnumSet flags) { + if (isRegister(value)) { + RegisterValue regVal = (RegisterValue) value; + Kind regKind = regVal.getKind(); + switch (regKind) { + case Int: + signed32.add(regVal.getRegister().encoding()); + break; + case Long: + signed64.add(regVal.getRegister().encoding()); + break; + default : + throw GraalInternalError.shouldNotReachHere("unhandled register type " + value.toString()); + } + } + return value; + } + }; + for (Block b : lirGen.lir.codeEmittingOrder()) { + for (LIRInstruction op : lirGen.lir.lir(b)) { + op.forEachOutput(trackRegisterKind); + } + } + + for (Integer i : signed32) { + codeBuffer.emitString(" .reg .s32 %r" + i.intValue() + ";"); + } + for (Integer i : signed64) { + codeBuffer.emitString(".reg .s64 %r" + i.intValue() + ";"); + } + } + + @Override + public void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) { + assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method"; + Buffer codeBuffer = tasm.asm.codeBuffer; + // Emit the prologue + emitKernelEntry(tasm, lirGen, codeCacheOwner); + + // Emit register declarations + try { + emitRegisterDecl(tasm, lirGen, codeCacheOwner); + } catch (GraalInternalError e) { + // TODO : Better error handling needs to be done once + // all types of parameters are handled. + codeBuffer.setPosition(0); + codeBuffer.close(false); + return; + } // Emit code for the LIR - lirGen.lir.emitCode(tasm); + try { + lirGen.lir.emitCode(tasm); + } catch (GraalInternalError e) { + // TODO : Better error handling needs to be done once + // all types of parameters are handled. + codeBuffer.setPosition(0); + codeBuffer.close(false); + return; + } // Emit the epilogue codeBuffer.emitString0("}"); diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Tue Sep 03 14:09:56 2013 -0700 @@ -47,12 +47,16 @@ import com.oracle.graal.lir.ptx.PTXControlFlow.CondMoveOp; import com.oracle.graal.lir.ptx.PTXControlFlow.FloatCondMoveOp; import com.oracle.graal.lir.ptx.PTXControlFlow.ReturnOp; +import com.oracle.graal.lir.ptx.PTXControlFlow.ReturnNoValOp; import com.oracle.graal.lir.ptx.PTXControlFlow.SequentialSwitchOp; import com.oracle.graal.lir.ptx.PTXControlFlow.TableSwitchOp; -import com.oracle.graal.lir.ptx.PTXMove.LoadOp; import com.oracle.graal.lir.ptx.PTXMove.MoveFromRegOp; import com.oracle.graal.lir.ptx.PTXMove.MoveToRegOp; -import com.oracle.graal.lir.ptx.PTXMove.StoreOp; +import com.oracle.graal.lir.ptx.PTXMemOp.LoadOp; +import com.oracle.graal.lir.ptx.PTXMemOp.StoreOp; +import com.oracle.graal.lir.ptx.PTXMemOp.LoadParamOp; +import com.oracle.graal.lir.ptx.PTXMemOp.LoadReturnAddrOp; +import com.oracle.graal.lir.ptx.PTXMemOp.StoreReturnValOp; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; @@ -96,6 +100,42 @@ } } + protected static AllocatableValue toParamKind(AllocatableValue value) { + if (value.getKind().getStackKind() != value.getKind()) { + // We only have stack-kinds in the LIR, so convert the operand kind for values from the + // calling convention. + if (isRegister(value)) { + return asRegister(value).asValue(value.getKind().getStackKind()); + } else if (isStackSlot(value)) { + return StackSlot.get(value.getKind().getStackKind(), asStackSlot(value).getRawOffset(), asStackSlot(value).getRawAddFrameSize()); + } else { + throw GraalInternalError.shouldNotReachHere(); + } + } + return value; + } + + @Override + public void emitPrologue() { + // Need to emit .param directives based on incoming arguments and return value + CallingConvention incomingArguments = cc; + int argCount = incomingArguments.getArgumentCount(); + // Additional argument for return value. + Value[] params = new Value[argCount + 1]; + for (int i = 0; i < argCount; i++) { + params[i] = toParamKind(incomingArguments.getArgument(i)); + } + // Add the return value as the last parameter. + params[argCount] = incomingArguments.getReturn(); + + append(new PTXParameterOp(params)); + for (LocalNode local : graph.getNodes(LocalNode.class)) { + Value param = params[local.index()]; + assert param.getKind() == local.kind().getStackKind(); + setResult(local, emitLoadParam(param.getKind(), param, null)); + } + } + @Override public Variable emitMove(Value input) { Variable result = newVariable(input.getKind()); @@ -250,7 +290,8 @@ /** * This method emits the compare instruction, and may reorder the operands. It returns true if * it did so. - * + * + * * @param a the left operand of the comparison * @param b the right operand of the comparison * @return true if the left and right operands were switched, false otherwise @@ -705,6 +746,10 @@ append(new ReturnOp(input)); } + private void emitReturnNoVal() { + append(new ReturnNoValOp()); + } + @Override protected void emitSequentialSwitch(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) { // Making a copy of the switch value is necessary because jump table destroys the input @@ -761,4 +806,38 @@ public void visitInfopointNode(InfopointNode i) { throw new InternalError("NYI"); } + + public Variable emitLoadParam(Kind kind, Value address, DeoptimizingNode deopting) { + PTXAddressValue loadAddress = asAddress(address); + Variable result = newVariable(kind); + append(new LoadParamOp(kind, result, loadAddress, deopting != null ? state(deopting) : null)); + return result; + } + + public Variable emitLoadReturnAddress(Kind kind, Value address, DeoptimizingNode deopting) { + PTXAddressValue loadAddress = asAddress(address); + Variable result = newVariable(kind); + append(new LoadReturnAddrOp(kind, result, loadAddress, deopting != null ? state(deopting) : null)); + return result; + } + + public void emitStoreReturnValue(Kind kind, Value address, Value inputVal, DeoptimizingNode deopting) { + PTXAddressValue storeAddress = asAddress(address); + Variable input = load(inputVal); + append(new StoreReturnValOp(kind, storeAddress, input, deopting != null ? state(deopting) : null)); + } + + + @Override + public void visitReturn(ReturnNode x) { + AllocatableValue operand = Value.ILLEGAL; + if (x.result() != null) { + operand = resultOperandFor(x.result().kind()); + // Load the global memory address from return parameter + Variable loadVar = emitLoadReturnAddress(operand.getKind(), operand, null); + // Store result in global memory whose location is loadVar + emitStoreReturnValue(operand.getKind(), loadVar, operand(x.result()), null); + } + emitReturnNoVal(); + } } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXTargetMethodAssembler.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXTargetMethodAssembler.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXTargetMethodAssembler.java Tue Sep 03 14:09:56 2013 -0700 @@ -50,7 +50,7 @@ ExternalCompilationResult graalCompile = (ExternalCompilationResult) super.finishTargetMethod(graph); try { - if (validDevice) { + if ((validDevice) && (graalCompile.getTargetCode() != null)) { long kernel = toGPU.generateKernel(graalCompile.getTargetCode(), method.getName()); graalCompile.setEntryPoint(kernel); } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java Tue Sep 03 14:09:56 2013 -0700 @@ -145,6 +145,9 @@ } Debug.dump(graph, "Graph"); new CanonicalizerPhase.Instance(runtime(), new Assumptions(false), true).apply(graph); + for (FrameState fs : local.usages().filter(FrameState.class).snapshot()) { + fs.replaceFirstInput(local, null); + } StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); assertEquals(referenceGraph, graph); } diff -r 20b642493616 -r 1f03076a121b 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 Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Tue Sep 03 14:09:56 2013 -0700 @@ -22,6 +22,8 @@ */ package com.oracle.graal.compiler; +import static com.oracle.graal.compiler.GraalCompiler.Options.*; +import static com.oracle.graal.compiler.MethodFilter.*; import static com.oracle.graal.phases.GraalOptions.*; import java.util.*; @@ -34,12 +36,14 @@ import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.internal.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.util.*; +import com.oracle.graal.options.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.common.*; @@ -52,6 +56,71 @@ */ public class GraalCompiler { + private static final DebugTimer FrontEnd = Debug.timer("FrontEnd"); + private static final DebugTimer BackEnd = Debug.timer("BackEnd"); + + /** + * The set of positive filters specified by the {@code -G:IntrinsificationsEnabled} option. To + * enable a fast path in {@link #shouldIntrinsify(JavaMethod)}, this field is {@code null} when + * no enabling/disabling filters are specified. + */ + private static final MethodFilter[] positiveIntrinsificationFilter; + + /** + * The set of negative filters specified by the {@code -G:IntrinsificationsDisabled} option. + */ + private static final MethodFilter[] negativeIntrinsificationFilter; + + static class Options { + + // @formatter:off + /** + * @see MethodFilter + */ + @Option(help = "Pattern for method(s) to which intrinsification (if available) will be applied. " + + "By default, all available intrinsifications are applied except for methods matched " + + "by IntrinsificationsDisabled. See MethodFilter class for pattern syntax.") + public static final OptionValue IntrinsificationsEnabled = new OptionValue<>(null); + /** + * @see MethodFilter + */ + @Option(help = "Pattern for method(s) to which intrinsification will not be applied. " + + "See MethodFilter class for pattern syntax.") + public static final OptionValue IntrinsificationsDisabled = new OptionValue<>("Object.clone"); + // @formatter:on + + } + + static { + if (IntrinsificationsDisabled.getValue() != null) { + negativeIntrinsificationFilter = parse(IntrinsificationsDisabled.getValue()); + } else { + negativeIntrinsificationFilter = null; + } + + if (Options.IntrinsificationsEnabled.getValue() != null) { + positiveIntrinsificationFilter = parse(IntrinsificationsEnabled.getValue()); + } else if (negativeIntrinsificationFilter != null) { + positiveIntrinsificationFilter = new MethodFilter[0]; + } else { + positiveIntrinsificationFilter = null; + } + } + + /** + * Determines if a given method should be intrinsified based on the values of + * {@link Options#IntrinsificationsEnabled} and {@link Options#IntrinsificationsDisabled}. + */ + public static boolean shouldIntrinsify(JavaMethod method) { + if (positiveIntrinsificationFilter == null) { + return true; + } + if (positiveIntrinsificationFilter.length == 0 || matches(positiveIntrinsificationFilter, method)) { + return negativeIntrinsificationFilter == null || !matches(negativeIntrinsificationFilter, method); + } + return false; + } + /** * Requests compilation of a given graph. * @@ -62,13 +131,9 @@ * argument can be null. * @return the result of the compilation */ - public static CompilationResult compileGraph(final StructuredGraph graph, final CallingConvention cc, - final ResolvedJavaMethod installedCodeOwner, final GraalCodeCacheProvider runtime, - final Replacements replacements, final Backend backend, - final TargetDescription target, final GraphCache cache, - final PhasePlan plan, final OptimisticOptimizations optimisticOpts, - final SpeculationLog speculationLog, final Suites suites, - final CompilationResult compilationResult) { + public static CompilationResult compileGraph(final StructuredGraph graph, final CallingConvention cc, final ResolvedJavaMethod installedCodeOwner, final GraalCodeCacheProvider runtime, + final Replacements replacements, final Backend backend, final TargetDescription target, final GraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts, + final SpeculationLog speculationLog, final Suites suites, final CompilationResult compilationResult) { Debug.scope("GraalCompiler", new Object[]{graph, runtime}, new Runnable() { public void run() { @@ -76,22 +141,26 @@ final LIR lir = Debug.scope("FrontEnd", new Callable() { public LIR call() { - return emitHIR(runtime, target, graph, replacements, assumptions, cache, plan, optimisticOpts, speculationLog, suites); + try (TimerCloseable a = FrontEnd.start()) { + return emitHIR(runtime, target, graph, replacements, assumptions, cache, plan, optimisticOpts, speculationLog, suites); + } } }); - final LIRGenerator lirGen = Debug.scope("BackEnd", lir, new Callable() { + try (TimerCloseable a = BackEnd.start()) { + final LIRGenerator lirGen = Debug.scope("BackEnd", lir, new Callable() { - public LIRGenerator call() { - return emitLIR(backend, target, lir, graph, cc); - } - }); - Debug.scope("CodeGen", lirGen, new Runnable() { + public LIRGenerator call() { + return emitLIR(backend, target, lir, graph, cc); + } + }); + Debug.scope("CodeGen", lirGen, new Runnable() { - public void run() { - emitCode(backend, getLeafGraphIdArray(graph), assumptions, lirGen, compilationResult, installedCodeOwner); - } + public void run() { + emitCode(backend, getLeafGraphIdArray(graph), assumptions, lirGen, compilationResult, installedCodeOwner); + } - }); + }); + } } }); diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Tue Sep 03 14:09:56 2013 -0700 @@ -38,15 +38,15 @@ // @formatter:off @Option(help = "Enable scope-based debugging", name = "Debug") public static final OptionValue DebugEnabled = new OptionValue<>(true); - @Option(help = "Scopes to be dumped") + @Option(help = "Pattern for scope(s) to in which dumping is enabled (see DebugFilter and Debug.dump)") public static final OptionValue Dump = new OptionValue<>(null); - @Option(help = "Scopes to be metered") + @Option(help = "Pattern for scope(s) to in which metering is enabled (see DebugFilter and Debug.metric)") public static final OptionValue Meter = new OptionValue<>(null); - @Option(help = "Scopes to be timed") + @Option(help = "Pattern for scope(s) to in which timing is enabled (see DebugFilter and Debug.timer)") public static final OptionValue Time = new OptionValue<>(null); - @Option(help = "Scopes to be logged") + @Option(help = "Pattern for scope(s) to in which logging is enabled (see DebugFilter and Debug.log)") public static final OptionValue Log = new OptionValue<>(null); - @Option(help = "Filters debug scope output by method name/pattern") + @Option(help = "Pattern for filtering debug scope output based on method context (see MethodFilter)") public static final OptionValue MethodFilter = new OptionValue<>(null); @Option(help = "How to print metric and timing values:%n" + "Name - aggregate by unqualified name%n" + @@ -85,11 +85,7 @@ if (methodFilter == null || methodFilter.isEmpty()) { this.methodFilter = null; } else { - String[] filters = methodFilter.split(","); - this.methodFilter = new MethodFilter[filters.length]; - for (int i = 0; i < filters.length; i++) { - this.methodFilter[i] = new MethodFilter(filters[i]); - } + this.methodFilter = com.oracle.graal.compiler.MethodFilter.parse(methodFilter); } // Report the filters that have been configured so the user can verify it's what they expect @@ -156,10 +152,8 @@ } else if (methodFilter != null) { JavaMethod method = asJavaMethod(o); if (method != null) { - for (MethodFilter filter : methodFilter) { - if (filter.matches(method)) { - return true; - } + if (com.oracle.graal.compiler.MethodFilter.matches(methodFilter, method)) { + return true; } } } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/MethodFilter.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/MethodFilter.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/MethodFilter.java Tue Sep 03 14:09:56 2013 -0700 @@ -88,6 +88,31 @@ private final Pattern methodName; private final Pattern[] signature; + /** + * Parses a string containing list of comma separated filter patterns into an array of + * {@link MethodFilter}s. + */ + public static MethodFilter[] parse(String commaSeparatedPatterns) { + String[] filters = commaSeparatedPatterns.split(","); + MethodFilter[] methodFilters = new MethodFilter[filters.length]; + for (int i = 0; i < filters.length; i++) { + methodFilters[i] = new MethodFilter(filters[i]); + } + return methodFilters; + } + + /** + * Determines if a given method is matched by a given array of filters. + */ + public static boolean matches(MethodFilter[] filters, JavaMethod method) { + for (MethodFilter filter : filters) { + if (filter.matches(method)) { + return true; + } + } + return false; + } + public MethodFilter(String sourcePattern) { String pattern = sourcePattern.trim(); diff -r 20b642493616 -r 1f03076a121b 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 Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Tue Sep 03 14:09:56 2013 -0700 @@ -452,12 +452,16 @@ append(new JumpOp(getLIRBlock(merge))); } + protected PlatformKind getPhiKind(PhiNode phi) { + return phi.kind(); + } + private Value operandForPhi(PhiNode phi) { assert phi.type() == PhiType.Value : "wrong phi type: " + phi; Value result = operand(phi); if (result == null) { // allocate a variable for this phi - Variable newOperand = newVariable(phi.kind()); + Variable newOperand = newVariable(getPhiKind(phi)); setResult(phi, newOperand); return newOperand; } else { diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/PhiResolver.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/PhiResolver.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/PhiResolver.java Tue Sep 03 14:09:56 2013 -0700 @@ -230,7 +230,7 @@ private void moveToTemp(Value src) { assert isIllegal(temp); - temp = gen.newVariable(src.getKind()); + temp = gen.newVariable(src.getPlatformKind()); emitMove(temp, src); } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Tue Sep 03 14:09:56 2013 -0700 @@ -26,7 +26,8 @@ import java.util.*; import com.oracle.graal.graph.Graph.NodeChangedListener; -import com.oracle.graal.graph.NodeClass.*; +import com.oracle.graal.graph.NodeClass.NodeClassIterator; +import com.oracle.graal.graph.NodeClass.Position; import com.oracle.graal.graph.iterators.*; /** diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Tue Sep 03 14:09:56 2013 -0700 @@ -244,10 +244,10 @@ AMD64Address src = new AMD64Address(receiver, config.hubOffset); AMD64HotSpotLIRGenerator gen = (AMD64HotSpotLIRGenerator) lirGen; - HotSpotRuntime hr = ((HotSpotRuntime) gen.getRuntime()); - if (hr.config.useCompressedKlassPointers) { + AMD64HotSpotRuntime hr = ((AMD64HotSpotRuntime) gen.getRuntime()); + if (hr.useCompressedKlassPointers()) { Register register = r10; - AMD64Move.decodeKlassPointer(asm, register, hr.heapBaseRegister(), src, hr.config.narrowKlassBase, hr.config.narrowKlassShift, hr.config.logKlassAlignment); + AMD64HotSpotMove.decodeKlassPointer(asm, register, hr.heapBaseRegister(), src, config.narrowKlassBase, config.narrowKlassShift, config.logKlassAlignment); asm.cmpq(inlineCacheKlass, register); } else { asm.cmpq(inlineCacheKlass, src); diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Tue Sep 03 14:09:56 2013 -0700 @@ -38,6 +38,10 @@ import com.oracle.graal.compiler.gen.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.amd64.AMD64HotSpotMove.CompareAndSwapCompressedOp; +import com.oracle.graal.hotspot.amd64.AMD64HotSpotMove.LoadCompressedPointer; +import com.oracle.graal.hotspot.amd64.AMD64HotSpotMove.StoreCompressedConstantOp; +import com.oracle.graal.hotspot.amd64.AMD64HotSpotMove.StoreCompressedPointer; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.stubs.*; @@ -46,12 +50,9 @@ import com.oracle.graal.lir.StandardOp.PlaceholderOp; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp; -import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapCompressedOp; import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp; -import com.oracle.graal.lir.amd64.AMD64Move.LoadCompressedPointer; import com.oracle.graal.lir.amd64.AMD64Move.LoadOp; import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp; -import com.oracle.graal.lir.amd64.AMD64Move.StoreCompressedPointer; import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp; import com.oracle.graal.lir.amd64.AMD64Move.StoreOp; import com.oracle.graal.nodes.*; @@ -427,12 +428,12 @@ * algorithms may differ. */ if (isCompressCandidate(access)) { - if (runtime().config.useCompressedOops && kind == Kind.Object) { - append(new LoadCompressedPointer(kind, result, runtime().heapBaseRegister().asValue(), loadAddress, access != null ? state(access) : null, runtime().config.narrowOopBase, - runtime().config.narrowOopShift, runtime().config.logMinObjAlignment)); - } else if (runtime().config.useCompressedKlassPointers && kind == Kind.Long) { - append(new LoadCompressedPointer(kind, result, runtime().heapBaseRegister().asValue(), loadAddress, access != null ? state(access) : null, runtime().config.narrowKlassBase, - runtime().config.narrowKlassShift, runtime().config.logKlassAlignment)); + if (runtime().useCompressedOops() && kind == Kind.Object) { + append(new LoadCompressedPointer(kind, result, runtime().heapBaseRegister().asValue(), loadAddress, access != null ? state(access) : null, getNarrowOopBase(), getNarrowOopShift(), + getLogMinObjectAlignment())); + } else if (runtime().useCompressedKlassPointers() && kind == Kind.Long) { + append(new LoadCompressedPointer(kind, result, runtime().heapBaseRegister().asValue(), loadAddress, access != null ? state(access) : null, getNarrowKlassBase(), getNarrowKlassShift(), + getLogKlassAlignment())); } else { append(new LoadOp(kind, result, loadAddress, access != null ? state(access) : null)); } @@ -449,29 +450,29 @@ if (isConstant(inputVal)) { Constant c = asConstant(inputVal); if (canStoreConstant(c)) { - if (inputVal.getKind() == Kind.Object) { - append(new StoreConstantOp(kind, storeAddress, c, state, runtime().config.useCompressedOops && isCompressCandidate(access))); - } else if (inputVal.getKind() == Kind.Long) { - append(new StoreConstantOp(kind, storeAddress, c, state, runtime().config.useCompressedKlassPointers && isCompressCandidate(access))); + if (inputVal.getKind() == Kind.Object && runtime().useCompressedOops() && isCompressCandidate(access)) { + append(new StoreCompressedConstantOp(kind, storeAddress, c, state)); + } else if (inputVal.getKind() == Kind.Long && runtime().useCompressedKlassPointers() && isCompressCandidate(access)) { + append(new StoreCompressedConstantOp(kind, storeAddress, c, state)); } else { - append(new StoreConstantOp(kind, storeAddress, c, state, false)); + append(new StoreConstantOp(kind, storeAddress, c, state)); } return; } } Variable input = load(inputVal); if (isCompressCandidate(access)) { - if (runtime().config.useCompressedOops && kind == Kind.Object) { + if (runtime().useCompressedOops() && kind == Kind.Object) { if (input.getKind() == Kind.Object) { Variable scratch = newVariable(Kind.Long); - append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, runtime().config.narrowOopBase, runtime().config.narrowOopShift, runtime().config.logMinObjAlignment)); + append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, getNarrowOopBase(), getNarrowOopShift(), getLogMinObjectAlignment())); } else { // the input oop is already compressed append(new StoreOp(input.getKind(), storeAddress, input, state)); } - } else if (runtime().config.useCompressedKlassPointers && kind == Kind.Long) { + } else if (runtime().useCompressedKlassPointers() && kind == Kind.Long) { Variable scratch = newVariable(Kind.Long); - append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, runtime().config.narrowKlassBase, runtime().config.narrowKlassShift, runtime().config.logKlassAlignment)); + append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, getNarrowKlassBase(), getNarrowKlassShift(), getLogKlassAlignment())); } else { append(new StoreOp(kind, storeAddress, input, state)); } @@ -480,6 +481,30 @@ } } + private int getLogMinObjectAlignment() { + return runtime().config.logMinObjAlignment; + } + + private int getNarrowOopShift() { + return runtime().config.narrowOopShift; + } + + private long getNarrowOopBase() { + return runtime().config.narrowOopBase; + } + + private int getLogKlassAlignment() { + return runtime().config.logKlassAlignment; + } + + private int getNarrowKlassShift() { + return runtime().config.narrowKlassShift; + } + + private long getNarrowKlassBase() { + return runtime().config.narrowKlassBase; + } + @Override public void visitCompareAndSwap(LoweredCompareAndSwapNode node, Value address) { Kind kind = node.getNewValue().kind(); @@ -489,9 +514,9 @@ AMD64AddressValue addressValue = asAddressValue(address); RegisterValue raxRes = AMD64.rax.asValue(kind); emitMove(raxRes, expected); - if (runtime().config.useCompressedOops && node.isCompressible()) { + if (runtime().useCompressedOops() && node.isCompressible()) { Variable scratch = newVariable(Kind.Long); - append(new CompareAndSwapCompressedOp(raxRes, addressValue, raxRes, newValue, scratch, runtime().config.narrowOopBase, runtime().config.narrowOopShift, runtime().config.logMinObjAlignment)); + append(new CompareAndSwapCompressedOp(raxRes, addressValue, raxRes, newValue, scratch, getNarrowOopBase(), getNarrowOopShift(), getLogMinObjectAlignment())); } else { append(new CompareAndSwapOp(raxRes, addressValue, raxRes, newValue)); } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Tue Sep 03 14:09:56 2013 -0700 @@ -0,0 +1,250 @@ +/* + * 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.hotspot.amd64; + +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.amd64.*; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.amd64.AMD64Move.LoadOp; +import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp; +import com.oracle.graal.lir.asm.*; + +public class AMD64HotSpotMove { + + public static class StoreCompressedConstantOp extends StoreConstantOp { + + public StoreCompressedConstantOp(Kind kind, AMD64AddressValue address, Constant input, LIRFrameState state) { + super(kind, address, input, state); + } + + @Override + public void emitMemAccess(AMD64MacroAssembler masm) { + if (kind == Kind.Long) { + if (NumUtil.isInt(input.asLong())) { + masm.movl(address.toAddress(), (int) input.asLong()); + } else { + throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); + } + } else if (kind == Kind.Object) { + if (input.isNull()) { + masm.movl(address.toAddress(), 0); + } else { + throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); + } + } else { + throw GraalInternalError.shouldNotReachHere("Attempt to store compressed constant of wrong type."); + } + } + } + + public static class LoadCompressedPointer extends LoadOp { + + private long base; + private int shift; + private int alignment; + @Alive({REG}) protected AllocatableValue heapBaseRegister; + + public LoadCompressedPointer(Kind kind, AllocatableValue result, AllocatableValue heapBaseRegister, AMD64AddressValue address, LIRFrameState state, long base, int shift, int alignment) { + super(kind, result, address, state); + this.base = base; + this.shift = shift; + this.alignment = alignment; + this.heapBaseRegister = heapBaseRegister; + assert kind == Kind.Object || kind == Kind.Long; + } + + @Override + public void emitMemAccess(AMD64MacroAssembler masm) { + Register resRegister = asRegister(result); + masm.movl(resRegister, address.toAddress()); + if (kind == Kind.Object) { + decodePointer(masm, resRegister, asRegister(heapBaseRegister), base, shift, alignment); + } else { + decodeKlassPointer(masm, resRegister, asRegister(heapBaseRegister), base, shift, alignment); + } + } + } + + public static class StoreCompressedPointer extends AMD64LIRInstruction { + + protected final Kind kind; + private long base; + private int shift; + private int alignment; + @Temp({REG}) private AllocatableValue scratch; + @Alive({REG}) protected AllocatableValue input; + @Alive({COMPOSITE}) protected AMD64AddressValue address; + @State protected LIRFrameState state; + + public StoreCompressedPointer(Kind kind, AMD64AddressValue address, AllocatableValue input, AllocatableValue scratch, LIRFrameState state, long base, int shift, int alignment) { + this.base = base; + this.shift = shift; + this.alignment = alignment; + this.scratch = scratch; + this.kind = kind; + this.address = address; + this.state = state; + this.input = input; + assert kind == Kind.Object || kind == Kind.Long; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + Register heapBase = ((HotSpotRuntime) tasm.runtime).heapBaseRegister(); + masm.movq(asRegister(scratch), asRegister(input)); + if (kind == Kind.Object) { + encodePointer(masm, asRegister(scratch), heapBase, base, shift, alignment); + } else { + encodeKlassPointer(masm, asRegister(scratch), heapBase, base, shift, alignment); + } + if (state != null) { + tasm.recordImplicitException(masm.codeBuffer.position(), state); + } + masm.movl(address.toAddress(), asRegister(scratch)); + } + } + + @Opcode("CAS") + public static class CompareAndSwapCompressedOp extends AMD64LIRInstruction { + + @Def protected AllocatableValue result; + @Alive({COMPOSITE}) protected AMD64AddressValue address; + @Alive protected AllocatableValue cmpValue; + @Alive protected AllocatableValue newValue; + @Temp({REG}) protected AllocatableValue scratch; + + private long base; + private int shift; + private int alignment; + + public CompareAndSwapCompressedOp(AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, AllocatableValue newValue, AllocatableValue scratch, long base, int shift, + int alignment) { + this.base = base; + this.shift = shift; + this.alignment = alignment; + this.scratch = scratch; + this.result = result; + this.address = address; + this.cmpValue = cmpValue; + this.newValue = newValue; + assert cmpValue.getKind() == Kind.Object; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + compareAndSwapCompressed(tasm, masm, result, address, cmpValue, newValue, scratch, base, shift, alignment); + } + } + + protected static void compareAndSwapCompressed(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, + AllocatableValue newValue, AllocatableValue scratch, long base, int shift, int alignment) { + assert AMD64.rax.equals(asRegister(cmpValue)) && AMD64.rax.equals(asRegister(result)); + final Register scratchRegister = asRegister(scratch); + final Register cmpRegister = asRegister(cmpValue); + final Register newRegister = asRegister(newValue); + Register heapBase = ((HotSpotRuntime) tasm.runtime).heapBaseRegister(); + encodePointer(masm, cmpRegister, heapBase, base, shift, alignment); + masm.movq(scratchRegister, newRegister); + encodePointer(masm, scratchRegister, heapBase, base, shift, alignment); + if (tasm.target.isMP) { + masm.lock(); + } + masm.cmpxchgl(scratchRegister, address.toAddress()); + } + + private static void encodePointer(AMD64MacroAssembler masm, Register scratchRegister, Register heapBaseRegister, long base, int shift, int alignment) { + // If the base is zero, the uncompressed address has to be shifted right + // in order to be compressed. + if (base == 0) { + if (shift != 0) { + assert alignment == shift : "Encode algorithm is wrong"; + masm.shrq(scratchRegister, alignment); + } + } else { + // Otherwise the heap base, which resides always in register 12, is subtracted + // followed by right shift. + masm.testq(scratchRegister, scratchRegister); + // If the stored reference is null, move the heap to scratch + // register and then calculate the compressed oop value. + masm.cmovq(ConditionFlag.Equal, scratchRegister, heapBaseRegister); + masm.subq(scratchRegister, heapBaseRegister); + masm.shrq(scratchRegister, alignment); + } + } + + private static void decodePointer(AMD64MacroAssembler masm, Register resRegister, Register heapBaseRegister, long base, int shift, int alignment) { + // If the base is zero, the compressed address has to be shifted left + // in order to be uncompressed. + if (base == 0) { + if (shift != 0) { + assert alignment == shift : "Decode algorithm is wrong"; + masm.shlq(resRegister, alignment); + } + } else { + Label done = new Label(); + masm.shlq(resRegister, alignment); + masm.jccb(ConditionFlag.Equal, done); + // Otherwise the heap base is added to the shifted address. + masm.addq(resRegister, heapBaseRegister); + masm.bind(done); + } + } + + private static void encodeKlassPointer(AMD64MacroAssembler masm, Register scratchRegister, Register heapBaseRegister, long base, int shift, int alignment) { + if (base != 0) { + masm.subq(scratchRegister, heapBaseRegister); + } + if (shift != 0) { + assert alignment == shift : "Encode algorithm is wrong"; + masm.shrq(scratchRegister, alignment); + } + } + + private static void decodeKlassPointer(AMD64MacroAssembler masm, Register resRegister, Register heapBaseRegister, long base, int shift, int alignment) { + if (shift != 0) { + assert alignment == shift : "Decode algorithm is wrong"; + masm.shlq(resRegister, alignment); + if (base != 0) { + masm.addq(resRegister, heapBaseRegister); + } + } else { + assert base == 0 : "Sanity"; + } + } + + public static void decodeKlassPointer(AMD64MacroAssembler masm, Register register, Register heapBaseRegister, AMD64Address address, long narrowKlassBase, int narrowKlassShift, + int logKlassAlignment) { + masm.movl(register, address); + decodeKlassPointer(masm, register, heapBaseRegister, narrowKlassBase, narrowKlassShift, logKlassAlignment); + } +} diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Tue Sep 03 14:09:56 2013 -0700 @@ -113,6 +113,8 @@ */ public static final DebugTimer CompilationTime = Debug.timer("CompilationTime"); + public static final DebugTimer CodeInstallationTime = Debug.timer("CodeInstallation"); + public void runCompilation() { /* * no code must be outside this try/finally because it could happen otherwise that @@ -164,7 +166,9 @@ } } - installMethod(result); + try (TimerCloseable b = CodeInstallationTime.start()) { + installMethod(result); + } stats.finish(method); } catch (BailoutException bailout) { Debug.metric("Bailouts").increment(); diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Tue Sep 03 14:09:56 2013 -0700 @@ -313,31 +313,15 @@ linkForeignCall(r, G1WBPOSTCALL, c.writeBarrierPostAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); linkForeignCall(r, VALIDATE_OBJECT, c.validateObject, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); - if (IntrinsifyObjectMethods.getValue()) { - r.registerSubstitutions(ObjectSubstitutions.class); - } - if (IntrinsifySystemMethods.getValue()) { - r.registerSubstitutions(SystemSubstitutions.class); - } - if (IntrinsifyThreadMethods.getValue()) { - r.registerSubstitutions(ThreadSubstitutions.class); - } - if (IntrinsifyUnsafeMethods.getValue()) { - r.registerSubstitutions(UnsafeSubstitutions.class); - } - if (IntrinsifyClassMethods.getValue()) { - r.registerSubstitutions(ClassSubstitutions.class); - } - if (IntrinsifyAESMethods.getValue()) { - r.registerSubstitutions(AESCryptSubstitutions.class); - r.registerSubstitutions(CipherBlockChainingSubstitutions.class); - } - if (IntrinsifyCRC32Methods.getValue()) { - r.registerSubstitutions(CRC32Substitutions.class); - } - if (IntrinsifyReflectionMethods.getValue()) { - r.registerSubstitutions(ReflectionSubstitutions.class); - } + r.registerSubstitutions(ObjectSubstitutions.class); + r.registerSubstitutions(SystemSubstitutions.class); + r.registerSubstitutions(ThreadSubstitutions.class); + r.registerSubstitutions(UnsafeSubstitutions.class); + r.registerSubstitutions(ClassSubstitutions.class); + r.registerSubstitutions(AESCryptSubstitutions.class); + r.registerSubstitutions(CipherBlockChainingSubstitutions.class); + r.registerSubstitutions(CRC32Substitutions.class); + r.registerSubstitutions(ReflectionSubstitutions.class); checkcastDynamicSnippets = new CheckCastDynamicSnippets.Templates(this, r, graalRuntime.getTarget()); instanceofSnippets = new InstanceOfSnippets.Templates(this, r, graalRuntime.getTarget()); @@ -361,6 +345,12 @@ public abstract Register threadRegister(); /** + * Returns the register used by the runtime for maintaining the heap base address for compressed + * pointers. + */ + public abstract Register heapBaseRegister(); + + /** * Gets the stack pointer register. */ public abstract Register stackPointerRegister(); @@ -494,6 +484,14 @@ return Array.getLength(array.asObject()); } + public boolean useCompressedOops() { + return config.useCompressedOops; + } + + public boolean useCompressedKlassPointers() { + return config.useCompressedKlassPointers; + } + @Override public void lower(Node n, LoweringTool tool) { StructuredGraph graph = (StructuredGraph) n.graph(); @@ -879,13 +877,13 @@ private FloatingReadNode createReadHub(StructuredGraph graph, Kind wordKind, ValueNode object, GuardingNode guard) { LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, config.hubOffset, graph); assert !object.isConstant() || object.asConstant().isNull(); - return graph.add(new FloatingReadNode(object, location, null, StampFactory.forKind(wordKind()), guard, BarrierType.NONE, config.useCompressedKlassPointers)); + return graph.add(new FloatingReadNode(object, location, null, StampFactory.forKind(wordKind()), guard, BarrierType.NONE, useCompressedKlassPointers())); } private WriteNode createWriteHub(StructuredGraph graph, Kind wordKind, ValueNode object, ValueNode value) { LocationNode location = ConstantLocationNode.create(ANY_LOCATION, wordKind, config.hubOffset, graph); assert !object.isConstant() || object.asConstant().isNull(); - return graph.add(new WriteNode(object, value, location, BarrierType.NONE, config.useCompressedKlassPointers)); + return graph.add(new WriteNode(object, value, location, BarrierType.NONE, useCompressedKlassPointers())); } private static BarrierType getFieldLoadBarrierType(HotSpotResolvedJavaField loadField) { @@ -943,7 +941,7 @@ } public int getScalingFactor(Kind kind) { - if (config.useCompressedOops && kind == Kind.Object) { + if (useCompressedOops() && kind == Kind.Object) { return this.graalRuntime.getTarget().arch.getSizeInBytes(Kind.Int); } else { return this.graalRuntime.getTarget().arch.getSizeInBytes(kind); @@ -1150,7 +1148,7 @@ case Int: return Constant.forInt(base == null ? unsafe.getInt(displacement) : unsafe.getInt(base, displacement)); case Long: - if (displacement == config().hubOffset && this.getGraalRuntime().getRuntime().config.useCompressedKlassPointers) { + if (displacement == config().hubOffset && useCompressedKlassPointers()) { if (base == null) { throw new GraalInternalError("Base of object must not be null"); } else { diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Tue Sep 03 14:09:56 2013 -0700 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.replacements; -import static com.oracle.graal.phases.GraalOptions.*; +import static com.oracle.graal.compiler.GraalCompiler.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; @@ -93,7 +93,7 @@ @Override protected StructuredGraph getSnippetGraph(LoweringTool tool) { - if (!IntrinsifyArrayCopy.getValue()) { + if (!shouldIntrinsify(getTargetMethod())) { return null; } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteSubstitutions.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteSubstitutions.java Tue Sep 03 14:09:56 2013 -0700 @@ -22,8 +22,6 @@ */ package com.oracle.graal.hotspot.replacements; -import static com.oracle.graal.phases.GraalOptions.*; - import java.lang.invoke.*; import com.oracle.graal.api.code.*; @@ -37,11 +35,9 @@ @Override public void registerReplacements(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) { - if (IntrinsifyCallSiteTarget.getValue()) { - replacements.registerSubstitutions(ConstantCallSiteSubstitutions.class); - replacements.registerSubstitutions(MutableCallSiteSubstitutions.class); - replacements.registerSubstitutions(VolatileCallSiteSubstitutions.class); - } + replacements.registerSubstitutions(ConstantCallSiteSubstitutions.class); + replacements.registerSubstitutions(MutableCallSiteSubstitutions.class); + replacements.registerSubstitutions(VolatileCallSiteSubstitutions.class); } @ClassSubstitution(ConstantCallSite.class) diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Tue Sep 03 14:09:56 2013 -0700 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.replacements; -import static com.oracle.graal.phases.GraalOptions.*; +import static com.oracle.graal.compiler.GraalCompiler.*; import java.lang.reflect.*; @@ -52,7 +52,7 @@ @Override protected StructuredGraph getSnippetGraph(LoweringTool tool) { - if (!IntrinsifyObjectClone.getValue()) { + if (!shouldIntrinsify(getTargetMethod())) { return null; } @@ -121,7 +121,7 @@ ResolvedJavaType type = getConcreteType(obj.stamp(), tool.getAssumptions()); if (isCloneableType(type, tool.getMetaAccessProvider())) { if (!type.isArray()) { - VirtualInstanceNode newVirtual = new VirtualInstanceNode(type); + VirtualInstanceNode newVirtual = new VirtualInstanceNode(type, true); ResolvedJavaField[] fields = newVirtual.getFields(); ValueNode[] state = new ValueNode[fields.length]; diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java Tue Sep 03 14:09:56 2013 -0700 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.replacements; -import static com.oracle.graal.phases.GraalOptions.*; +import static com.oracle.graal.compiler.GraalCompiler.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; @@ -65,7 +65,7 @@ * @return ConstantNode of the caller class, or null */ private ConstantNode getCallerClassNode(MetaAccessProvider runtime) { - if (!IntrinsifyReflectionMethods.getValue()) { + if (!shouldIntrinsify(getTargetMethod())) { return null; } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Tue Sep 03 14:09:56 2013 -0700 @@ -32,7 +32,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.MoveOp; @@ -117,34 +116,6 @@ } } - public static class LoadCompressedPointer extends LoadOp { - - private long base; - private int shift; - private int alignment; - @Alive({REG}) protected AllocatableValue heapBaseRegister; - - public LoadCompressedPointer(Kind kind, AllocatableValue result, AllocatableValue heapBaseRegister, AMD64AddressValue address, LIRFrameState state, long base, int shift, int alignment) { - super(kind, result, address, state); - this.base = base; - this.shift = shift; - this.alignment = alignment; - this.heapBaseRegister = heapBaseRegister; - assert kind == Kind.Object || kind == Kind.Long; - } - - @Override - public void emitMemAccess(AMD64MacroAssembler masm) { - Register resRegister = asRegister(result); - masm.movl(resRegister, address.toAddress()); - if (kind == Kind.Object) { - decodePointer(masm, resRegister, asRegister(heapBaseRegister), base, shift, alignment); - } else { - decodeKlassPointer(masm, resRegister, asRegister(heapBaseRegister), base, shift, alignment); - } - } - } - public static class LoadOp extends MemOp { @Def({REG}) protected AllocatableValue result; @@ -188,44 +159,6 @@ } } - public static class StoreCompressedPointer extends AMD64LIRInstruction { - - protected final Kind kind; - private long base; - private int shift; - private int alignment; - @Temp({REG}) private AllocatableValue scratch; - @Alive({REG}) protected AllocatableValue input; - @Alive({COMPOSITE}) protected AMD64AddressValue address; - @State protected LIRFrameState state; - - public StoreCompressedPointer(Kind kind, AMD64AddressValue address, AllocatableValue input, AllocatableValue scratch, LIRFrameState state, long base, int shift, int alignment) { - this.base = base; - this.shift = shift; - this.alignment = alignment; - this.scratch = scratch; - this.kind = kind; - this.address = address; - this.state = state; - this.input = input; - assert kind == Kind.Object || kind == Kind.Long; - } - - @Override - public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - masm.movq(asRegister(scratch), asRegister(input)); - if (kind == Kind.Object) { - encodePointer(masm, asRegister(scratch), tasm.runtime.heapBaseRegister(), base, shift, alignment); - } else { - encodeKlassPointer(masm, asRegister(scratch), tasm.runtime.heapBaseRegister(), base, shift, alignment); - } - if (state != null) { - tasm.recordImplicitException(masm.codeBuffer.position(), state); - } - masm.movl(address.toAddress(), asRegister(scratch)); - } - } - public static class StoreOp extends MemOp { @Use({REG}) protected AllocatableValue input; @@ -271,12 +204,10 @@ public static class StoreConstantOp extends MemOp { protected final Constant input; - private final boolean compressible; - public StoreConstantOp(Kind kind, AMD64AddressValue address, Constant input, LIRFrameState state, boolean compressible) { + public StoreConstantOp(Kind kind, AMD64AddressValue address, Constant input, LIRFrameState state) { super(kind, address, state); this.input = input; - this.compressible = compressible; } @Override @@ -295,11 +226,7 @@ break; case Long: if (NumUtil.isInt(input.asLong())) { - if (compressible) { - masm.movl(address.toAddress(), (int) input.asLong()); - } else { - masm.movslq(address.toAddress(), (int) input.asLong()); - } + masm.movslq(address.toAddress(), (int) input.asLong()); } else { throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); } @@ -311,11 +238,7 @@ throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); case Object: if (input.isNull()) { - if (compressible) { - masm.movl(address.toAddress(), 0); - } else { - masm.movptr(address.toAddress(), 0); - } + masm.movptr(address.toAddress(), 0); } else { throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); } @@ -410,38 +333,6 @@ } } - @Opcode("CAS") - public static class CompareAndSwapCompressedOp extends AMD64LIRInstruction { - - @Def protected AllocatableValue result; - @Alive({COMPOSITE}) protected AMD64AddressValue address; - @Alive protected AllocatableValue cmpValue; - @Alive protected AllocatableValue newValue; - @Temp({REG}) protected AllocatableValue scratch; - - private long base; - private int shift; - private int alignment; - - public CompareAndSwapCompressedOp(AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, AllocatableValue newValue, AllocatableValue scratch, long base, int shift, - int alignment) { - this.base = base; - this.shift = shift; - this.alignment = alignment; - this.scratch = scratch; - this.result = result; - this.address = address; - this.cmpValue = cmpValue; - this.newValue = newValue; - assert cmpValue.getKind() == Kind.Object; - } - - @Override - public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - compareAndSwapCompressed(tasm, masm, result, address, cmpValue, newValue, scratch, base, shift, alignment); - } - } - public static void move(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Value input) { if (isRegister(input)) { if (isRegister(result)) { @@ -650,85 +541,4 @@ throw GraalInternalError.shouldNotReachHere(); } } - - protected static void compareAndSwapCompressed(TargetMethodAssembler tasm, AMD64MacroAssembler masm, AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, - AllocatableValue newValue, AllocatableValue scratch, long base, int shift, int alignment) { - assert AMD64.rax.equals(asRegister(cmpValue)) && AMD64.rax.equals(asRegister(result)); - final Register scratchRegister = asRegister(scratch); - final Register cmpRegister = asRegister(cmpValue); - final Register newRegister = asRegister(newValue); - encodePointer(masm, cmpRegister, tasm.runtime.heapBaseRegister(), base, shift, alignment); - masm.movq(scratchRegister, newRegister); - encodePointer(masm, scratchRegister, tasm.runtime.heapBaseRegister(), base, shift, alignment); - if (tasm.target.isMP) { - masm.lock(); - } - masm.cmpxchgl(scratchRegister, address.toAddress()); - } - - private static void encodePointer(AMD64MacroAssembler masm, Register scratchRegister, Register heapBaseRegister, long base, int shift, int alignment) { - // If the base is zero, the uncompressed address has to be shifted right - // in order to be compressed. - if (base == 0) { - if (shift != 0) { - assert alignment == shift : "Encode algorithm is wrong"; - masm.shrq(scratchRegister, alignment); - } - } else { - // Otherwise the heap base, which resides always in register 12, is subtracted - // followed by right shift. - masm.testq(scratchRegister, scratchRegister); - // If the stored reference is null, move the heap to scratch - // register and then calculate the compressed oop value. - masm.cmovq(ConditionFlag.Equal, scratchRegister, heapBaseRegister); - masm.subq(scratchRegister, heapBaseRegister); - masm.shrq(scratchRegister, alignment); - } - } - - private static void decodePointer(AMD64MacroAssembler masm, Register resRegister, Register heapBaseRegister, long base, int shift, int alignment) { - // If the base is zero, the compressed address has to be shifted left - // in order to be uncompressed. - if (base == 0) { - if (shift != 0) { - assert alignment == shift : "Decode algorithm is wrong"; - masm.shlq(resRegister, alignment); - } - } else { - Label done = new Label(); - masm.shlq(resRegister, alignment); - masm.jccb(ConditionFlag.Equal, done); - // Otherwise the heap base is added to the shifted address. - masm.addq(resRegister, heapBaseRegister); - masm.bind(done); - } - } - - private static void encodeKlassPointer(AMD64MacroAssembler masm, Register scratchRegister, Register heapBaseRegister, long base, int shift, int alignment) { - if (base != 0) { - masm.subq(scratchRegister, heapBaseRegister); - } - if (shift != 0) { - assert alignment == shift : "Encode algorithm is wrong"; - masm.shrq(scratchRegister, alignment); - } - } - - private static void decodeKlassPointer(AMD64MacroAssembler masm, Register resRegister, Register heapBaseRegister, long base, int shift, int alignment) { - if (shift != 0) { - assert alignment == shift : "Decode algorithm is wrong"; - masm.shlq(resRegister, alignment); - if (base != 0) { - masm.addq(resRegister, heapBaseRegister); - } - } else { - assert base == 0 : "Sanity"; - } - } - - public static void decodeKlassPointer(AMD64MacroAssembler masm, Register register, Register heapBaseRegister, AMD64Address address, long narrowKlassBase, int narrowKlassShift, - int logKlassAlignment) { - masm.movl(register, address); - decodeKlassPointer(masm, register, heapBaseRegister, narrowKlassBase, narrowKlassShift, logKlassAlignment); - } } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java Tue Sep 03 14:09:56 2013 -0700 @@ -55,6 +55,19 @@ } } + public static class ReturnNoValOp extends PTXLIRInstruction { + + public ReturnNoValOp() { } + + @Override + public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { + if (tasm.frameContext != null) { + tasm.frameContext.leave(tasm); + } + masm.ret(); + } + } + public static class BranchOp extends PTXLIRInstruction implements StandardOp.BranchOp { protected Condition condition; diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java Tue Sep 03 14:09:56 2013 -0700 @@ -0,0 +1,264 @@ +/* + * 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.lir.ptx; + +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.ptx.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; + +public class PTXMemOp { + + // Load operation from .global state space + @Opcode("LOAD") + public static class LoadOp extends PTXLIRInstruction { + + private final Kind kind; + @Def({REG}) protected AllocatableValue result; + @Use({COMPOSITE}) protected PTXAddressValue address; + @State protected LIRFrameState state; + + public LoadOp(Kind kind, AllocatableValue result, PTXAddressValue address, LIRFrameState state) { + this.kind = kind; + this.result = result; + this.address = address; + this.state = state; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { + PTXAddress addr = address.toAddress(); + switch (kind) { + case Byte: + masm.ld_global_s8(asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Short: + masm.ld_global_s16(asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Char: + masm.ld_global_u16(asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Int: + masm.ld_global_s32(asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Long: + masm.ld_global_s64(asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Float: + masm.ld_global_f32(asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Double: + masm.ld_global_f64(asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Object: + masm.ld_global_u32(asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } + + // Store operation from .global state space + @Opcode("STORE") + public static class StoreOp extends PTXLIRInstruction { + + private final Kind kind; + @Use({COMPOSITE}) protected PTXAddressValue address; + @Use({REG}) protected AllocatableValue input; + @State protected LIRFrameState state; + + public StoreOp(Kind kind, PTXAddressValue address, AllocatableValue input, LIRFrameState state) { + this.kind = kind; + this.address = address; + this.input = input; + this.state = state; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { + assert isRegister(input); + PTXAddress addr = address.toAddress(); + switch (kind) { + case Byte: + masm.st_global_s8(addr.getBase(), addr.getDisplacement(), asRegister(input)); + break; + case Short: + masm.st_global_s8(addr.getBase(), addr.getDisplacement(), asRegister(input)); + break; + case Int: + masm.st_global_s32(addr.getBase(), addr.getDisplacement(), asRegister(input)); + break; + case Long: + masm.st_global_s64(addr.getBase(), addr.getDisplacement(), asRegister(input)); + break; + case Float: + masm.st_global_f32(addr.getBase(), addr.getDisplacement(), asRegister(input)); + break; + case Double: + masm.st_global_f64(addr.getBase(), addr.getDisplacement(), asRegister(input)); + break; + case Object: + masm.st_global_u64(addr.getBase(), addr.getDisplacement(), asRegister(input)); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + address.getKind()); + } + } + } + + // Load operation from .param state space + @Opcode("LOAD") + public static class LoadParamOp extends PTXLIRInstruction { + + private final Kind kind; + @Def({REG}) protected AllocatableValue result; + @Use({COMPOSITE}) protected PTXAddressValue address; + @State protected LIRFrameState state; + + public LoadParamOp(Kind kind, AllocatableValue result, PTXAddressValue address, LIRFrameState state) { + this.kind = kind; + this.result = result; + this.address = address; + this.state = state; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { + PTXAddress addr = address.toAddress(); + switch (kind) { + case Byte: + masm.ld_from_state_space(".param.s8", asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Short: + masm.ld_from_state_space(".param.s16", asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Char: + masm.ld_from_state_space(".param.s16", asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Int: + masm.ld_from_state_space(".param.s32", asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Long: + masm.ld_from_state_space(".param.s64", asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Float: + masm.ld_from_state_space(".param.f32", asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Double: + masm.ld_from_state_space(".param.f64", asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Object: + masm.ld_from_state_space(".param.u64", asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } + + // Load contents of return value pointer from return argument in + // .param state space + @Opcode("LOAD_RET_ADDR") + public static class LoadReturnAddrOp extends PTXLIRInstruction { + + private final Kind kind; + @Def({REG}) protected AllocatableValue result; + @Use({COMPOSITE}) protected PTXAddressValue address; + @State protected LIRFrameState state; + + public LoadReturnAddrOp(Kind kind, AllocatableValue result, PTXAddressValue address, LIRFrameState state) { + this.kind = kind; + this.result = result; + this.address = address; + this.state = state; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { + PTXAddress addr = address.toAddress(); + switch (kind) { + case Int: + masm.ld_return_address("u32", asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + case Long: + masm.ld_return_address("u64", asRegister(result), addr.getBase(), addr.getDisplacement()); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } + + // Store operation from .global state space + @Opcode("STORE_RETURN_VALUE") + public static class StoreReturnValOp extends PTXLIRInstruction { + + private final Kind kind; + @Use({COMPOSITE}) protected PTXAddressValue address; + @Use({REG}) protected AllocatableValue input; + @State protected LIRFrameState state; + + public StoreReturnValOp(Kind kind, PTXAddressValue address, AllocatableValue input, LIRFrameState state) { + this.kind = kind; + this.address = address; + this.input = input; + this.state = state; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { + assert isRegister(input); + PTXAddress addr = address.toAddress(); + // masm.st_global_return_value_s64(addr.getBase(), addr.getDisplacement(), asRegister(input)); + + switch (kind) { + case Byte: + case Short: + masm.st_global_return_value_s8(addr.getBase(), addr.getDisplacement(), asRegister(input)); + break; + case Int: + masm.st_global_return_value_s32(addr.getBase(), addr.getDisplacement(), asRegister(input)); + break; + case Long: + masm.st_global_return_value_s64(addr.getBase(), addr.getDisplacement(), asRegister(input)); + break; + case Float: + masm.st_global_return_value_f32(addr.getBase(), addr.getDisplacement(), asRegister(input)); + break; + case Double: + masm.st_global_return_value_f64(addr.getBase(), addr.getDisplacement(), asRegister(input)); + break; + case Object: + masm.st_global_return_value_u64(addr.getBase(), addr.getDisplacement(), asRegister(input)); + break; + default: + throw GraalInternalError.shouldNotReachHere("missing: " + address.getKind()); + } + } + } +} diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java Tue Sep 03 14:09:56 2013 -0700 @@ -116,100 +116,6 @@ } } - public static class LoadOp extends PTXLIRInstruction { - - private final Kind kind; - @Def({REG}) protected AllocatableValue result; - @Use({COMPOSITE}) protected PTXAddressValue address; - @State protected LIRFrameState state; - - public LoadOp(Kind kind, AllocatableValue result, PTXAddressValue address, LIRFrameState state) { - this.kind = kind; - this.result = result; - this.address = address; - this.state = state; - } - - @Override - public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { - PTXAddress addr = address.toAddress(); - switch (kind) { - case Byte: - masm.ld_global_s8(asRegister(result), addr.getBase(), addr.getDisplacement()); - break; - case Short: - masm.ld_global_s16(asRegister(result), addr.getBase(), addr.getDisplacement()); - break; - case Char: - masm.ld_global_u16(asRegister(result), addr.getBase(), addr.getDisplacement()); - break; - case Int: - masm.ld_global_s32(asRegister(result), addr.getBase(), addr.getDisplacement()); - break; - case Long: - masm.ld_global_s64(asRegister(result), addr.getBase(), addr.getDisplacement()); - break; - case Float: - masm.ld_global_f32(asRegister(result), addr.getBase(), addr.getDisplacement()); - break; - case Double: - masm.ld_global_f64(asRegister(result), addr.getBase(), addr.getDisplacement()); - break; - case Object: - masm.ld_global_u32(asRegister(result), addr.getBase(), addr.getDisplacement()); - break; - default: - throw GraalInternalError.shouldNotReachHere(); - } - } - } - - public static class StoreOp extends PTXLIRInstruction { - - private final Kind kind; - @Use({COMPOSITE}) protected PTXAddressValue address; - @Use({REG}) protected AllocatableValue input; - @State protected LIRFrameState state; - - public StoreOp(Kind kind, PTXAddressValue address, AllocatableValue input, LIRFrameState state) { - this.kind = kind; - this.address = address; - this.input = input; - this.state = state; - } - - @Override - public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { - assert isRegister(input); - PTXAddress addr = address.toAddress(); - switch (kind) { - case Byte: - masm.st_global_s8(addr.getBase(), addr.getDisplacement(), asRegister(input)); - break; - case Short: - masm.st_global_s8(addr.getBase(), addr.getDisplacement(), asRegister(input)); - break; - case Int: - masm.st_global_s32(addr.getBase(), addr.getDisplacement(), asRegister(input)); - break; - case Long: - masm.st_global_s64(addr.getBase(), addr.getDisplacement(), asRegister(input)); - break; - case Float: - masm.st_global_f32(addr.getBase(), addr.getDisplacement(), asRegister(input)); - break; - case Double: - masm.st_global_f64(addr.getBase(), addr.getDisplacement(), asRegister(input)); - break; - case Object: - masm.st_global_s32(addr.getBase(), addr.getDisplacement(), asRegister(input)); - break; - default: - throw GraalInternalError.shouldNotReachHere("missing: " + address.getKind()); - } - } - } - public static class LeaOp extends PTXLIRInstruction { @Def({REG}) protected AllocatableValue result; diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXParameterOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXParameterOp.java Tue Sep 03 14:09:56 2013 -0700 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.oracle.graal.lir.ptx; + +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.ptx.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; + +public class PTXParameterOp extends LIRInstruction { + + @Def({REG}) protected Value[] params; + + public PTXParameterOp(Value[] params) { + this.params = params; + } + + @Override + public void emitCode(TargetMethodAssembler tasm) { + PTXAssembler ptxasm = (PTXAssembler) tasm.asm; + // Emit parameter directives for arguments + int argCount = params.length; + for (int i = 0; i < argCount; i++) { + Kind paramKind = params[i].getKind(); + switch (paramKind) { + case Int : + ptxasm.param_32_decl(asIntReg(params[i]), (i == (argCount - 1))); + break; + case Long : + ptxasm.param_64_decl(asLongReg(params[i]), (i == (argCount - 1))); + break; + case Float : + ptxasm.param_32_decl(asFloatReg(params[i]), (i == (argCount - 1))); + break; + case Double : + ptxasm.param_64_decl(asDoubleReg(params[i]), (i == (argCount - 1))); + break; + default : + throw GraalInternalError.shouldNotReachHere("unhandled parameter type " + paramKind.toString()); + } + } + } +} diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java Tue Sep 03 14:09:56 2013 -0700 @@ -25,6 +25,7 @@ import java.lang.annotation.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.debug.*; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; import com.oracle.graal.lir.LIRInstruction.ValueProcedure; @@ -45,8 +46,11 @@ private final CompositeValueClass valueClass; + private static final DebugMetric COMPOSITE_VALUE_COUNT = Debug.metric("CompositeValues"); + public CompositeValue(PlatformKind kind) { super(kind); + COMPOSITE_VALUE_COUNT.increment(); valueClass = CompositeValueClass.get(getClass()); } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Tue Sep 03 14:09:56 2013 -0700 @@ -30,6 +30,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.lir.asm.*; @@ -211,10 +212,13 @@ */ private int id; + private static final DebugMetric LIR_NODE_COUNT = Debug.metric("LIRNodes"); + /** * Constructs a new LIR instruction. */ public LIRInstruction() { + LIR_NODE_COUNT.increment(); instructionClass = LIRInstructionClass.get(getClass()); id = -1; } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Tue Sep 03 14:09:56 2013 -0700 @@ -77,6 +77,14 @@ } /** + * Returns a node for a primitive constant. + */ + public static ConstantNode forPrimitive(Constant constant, Graph graph) { + assert constant.getKind() != Kind.Object; + return forConstant(constant, null, graph); + } + + /** * Returns a node for a double constant. * * @param d the double value for which to create the instruction diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Tue Sep 03 14:09:56 2013 -0700 @@ -34,7 +34,7 @@ * variable. */ @NodeInfo(nameTemplate = "{p#type/s}Phi({i#values})") -public final class PhiNode extends FloatingNode implements Canonicalizable, Node.IterableNodeType, GuardingNode { +public class PhiNode extends FloatingNode implements Canonicalizable, Node.IterableNodeType, GuardingNode { public static enum PhiType { Value(null), // normal value phis diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryNode.java Tue Sep 03 14:09:56 2013 -0700 @@ -83,6 +83,57 @@ } } + public static BinaryNode add(ValueNode x, ValueNode y) { + assert x.kind() == y.kind(); + switch (x.kind()) { + case Byte: + case Char: + case Short: + case Int: + case Long: + return IntegerArithmeticNode.add(x, y); + case Float: + case Double: + return x.graph().unique(new FloatAddNode(x.kind(), x, y, false)); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + public static BinaryNode sub(ValueNode x, ValueNode y) { + assert x.kind() == y.kind(); + switch (x.kind()) { + case Byte: + case Char: + case Short: + case Int: + case Long: + return IntegerArithmeticNode.sub(x, y); + case Float: + case Double: + return x.graph().unique(new FloatSubNode(x.kind(), x, y, false)); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + + public static BinaryNode mul(ValueNode x, ValueNode y) { + assert x.kind() == y.kind(); + switch (x.kind()) { + case Byte: + case Char: + case Short: + case Int: + case Long: + return IntegerArithmeticNode.mul(x, y); + case Float: + case Double: + return x.graph().unique(new FloatMulNode(x.kind(), x, y, false)); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + public static boolean canTryReassociate(BinaryNode node) { return node instanceof IntegerAddNode || node instanceof IntegerSubNode || node instanceof IntegerMulNode || node instanceof AndNode || node instanceof OrNode || node instanceof XorNode; } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Tue Sep 03 14:09:56 2013 -0700 @@ -85,7 +85,7 @@ public void virtualize(VirtualizerTool tool) { if (instanceClass != null) { assert !instanceClass().isArray(); - VirtualInstanceNode virtualObject = new VirtualInstanceNode(instanceClass()); + VirtualInstanceNode virtualObject = new VirtualInstanceNode(instanceClass(), true); ResolvedJavaField[] fields = virtualObject.getFields(); ValueNode[] state = new ValueNode[fields.length]; for (int i = 0; i < state.length; i++) { diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java Tue Sep 03 14:09:56 2013 -0700 @@ -36,6 +36,7 @@ private final int length; public VirtualArrayNode(ResolvedJavaType componentType, int length) { + super(true); this.componentType = componentType; this.length = length; } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualBoxingNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualBoxingNode.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualBoxingNode.java Tue Sep 03 14:09:56 2013 -0700 @@ -31,7 +31,7 @@ private final Kind boxingKind; public VirtualBoxingNode(ResolvedJavaType type, Kind boxingKind) { - super(type); + super(type, false); this.boxingKind = boxingKind; } @@ -41,11 +41,6 @@ } @Override - public boolean hasIdentity() { - return false; - } - - @Override public ValueNode getMaterializedRepresentation(FixedNode fixed, ValueNode[] entries, int[] locks) { assert entries.length == 1; assert locks.length == 0; diff -r 20b642493616 -r 1f03076a121b 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 Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java Tue Sep 03 14:09:56 2013 -0700 @@ -32,12 +32,12 @@ private final ResolvedJavaType type; private final ResolvedJavaField[] fields; - public VirtualInstanceNode(ResolvedJavaType type) { - this.type = type; - this.fields = type.getInstanceFields(true); + public VirtualInstanceNode(ResolvedJavaType type, boolean hasIdentity) { + this(type, type.getInstanceFields(true), hasIdentity); } - public VirtualInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields) { + public VirtualInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields, boolean hasIdentity) { + super(hasIdentity); this.type = type; this.fields = fields; } @@ -97,7 +97,7 @@ @Override public VirtualInstanceNode duplicate() { - return new VirtualInstanceNode(type); + return new VirtualInstanceNode(type, fields, super.hasIdentity()); } @Override diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java Tue Sep 03 14:09:56 2013 -0700 @@ -23,14 +23,18 @@ package com.oracle.graal.nodes.virtual; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -public abstract class VirtualObjectNode extends ValueNode implements LIRLowerable { +public abstract class VirtualObjectNode extends ValueNode implements LIRLowerable, Node.IterableNodeType { + + private boolean hasIdentity; - public VirtualObjectNode() { + public VirtualObjectNode(boolean hasIdentity) { super(StampFactory.virtual()); + this.hasIdentity = hasIdentity; } /** @@ -72,7 +76,11 @@ * comparison of two virtual objects is determined by comparing their contents. */ public boolean hasIdentity() { - return true; + return hasIdentity; + } + + public void setIdentity(boolean identity) { + this.hasIdentity = identity; } /** diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java Tue Sep 03 14:09:56 2013 -0700 @@ -110,9 +110,6 @@ private static void iterateInputs(NodeFlood flood, StructuredGraph graph) { for (Node node : graph.getNodes()) { - if (node instanceof LocalNode) { - flood.add(node); - } if (flood.isMarked(node)) { for (Node input : node.inputs()) { flood.add(input); diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Tue Sep 03 14:09:56 2013 -0700 @@ -54,10 +54,11 @@ private FixedWithNextNode lastFixedNode; private ControlFlowGraph cfg; - public LoweringToolImpl(PhaseContext context, GuardingNode guardAnchor, NodeBitMap activeGuards, ControlFlowGraph cfg) { + public LoweringToolImpl(PhaseContext context, GuardingNode guardAnchor, NodeBitMap activeGuards, FixedWithNextNode lastFixedNode, ControlFlowGraph cfg) { this.context = context; this.guardAnchor = guardAnchor; this.activeGuards = activeGuards; + this.lastFixedNode = lastFixedNode; this.cfg = cfg; } @@ -216,11 +217,10 @@ private void process(final Block b, final NodeBitMap activeGuards, final GuardingNode anchor) { - final LoweringToolImpl loweringTool = new LoweringToolImpl(context, anchor, activeGuards, schedule.getCFG()); + final LoweringToolImpl loweringTool = new LoweringToolImpl(context, anchor, activeGuards, b.getBeginNode(), schedule.getCFG()); // Lower the instructions of this block. List nodes = schedule.nodesFor(b); - loweringTool.setLastFixedNode(b.getBeginNode()); for (Node node : nodes) { if (node.isDeleted()) { diff -r 20b642493616 -r 1f03076a121b 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 Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Tue Sep 03 14:09:56 2013 -0700 @@ -89,12 +89,12 @@ @Option(help = "") public static final OptionValue DeoptsToDisableOptimisticOptimization = new OptionValue<>(40); - // comilation queue - @Option(help = "") + // compilation queue + @Option(help = "Compile all methods in all classes on given class path") public static final OptionValue CompileTheWorld = new OptionValue<>(null); - @Option(help = "") + @Option(help = "First class to consider when using CompileTheWorld") public static final OptionValue CompileTheWorldStartAt = new OptionValue<>(1); - @Option(help = "") + @Option(help = "Last class to consider when using CompileTheWorld") public static final OptionValue CompileTheWorldStopAt = new OptionValue<>(Integer.MAX_VALUE); // graph caching @@ -290,33 +290,6 @@ @Option(help = "") public static final OptionValue OptPushThroughPi = new OptionValue<>(true); - // Intrinsification settings - @Option(help = "") - public static final OptionValue IntrinsifyObjectClone = new OptionValue<>(false); - @Option(help = "") - public static final OptionValue IntrinsifyArrayCopy = new OptionValue<>(true); - @Option(help = "") - public static final OptionValue IntrinsifyObjectMethods = new OptionValue<>(true); - @Option(help = "") - public static final OptionValue IntrinsifySystemMethods = new OptionValue<>(true); - @Option(help = "") - public static final OptionValue IntrinsifyClassMethods = new OptionValue<>(true); - @Option(help = "") - public static final OptionValue IntrinsifyThreadMethods = new OptionValue<>(true); - @Option(help = "") - public static final OptionValue IntrinsifyUnsafeMethods = new OptionValue<>(true); - @Option(help = "") - public static final OptionValue IntrinsifyMathMethods = new OptionValue<>(true); - @Option(help = "") - public static final OptionValue IntrinsifyAESMethods = new OptionValue<>(true); - @Option(help = "") - public static final OptionValue IntrinsifyCRC32Methods = new OptionValue<>(true); - @Option(help = "") - public static final OptionValue IntrinsifyReflectionMethods = new OptionValue<>(true); - @Option(help = "") - public static final OptionValue IntrinsifyInstalledCodeMethods = new OptionValue<>(true); - @Option(help = "") - public static final OptionValue IntrinsifyCallSiteTarget = new OptionValue<>(true); /** * Counts the various paths taken through snippets. diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Sep 03 14:09:56 2013 -0700 @@ -861,7 +861,7 @@ private static List filterSchedulableNodes(List list) { List result = new ArrayList<>(); for (ScheduledNode n : list) { - if (!(n instanceof LocalNode) && !(n instanceof PhiNode)) { + if (!(n instanceof PhiNode)) { result.add(n); } } @@ -984,7 +984,7 @@ } private void addToLatestSorting(Block b, ScheduledNode i, List sortedInstructions, NodeBitMap visited, List reads, NodeBitMap beforeLastLocation) { - if (i == null || visited.isMarked(i) || cfg.getNodeToBlock().get(i) != b || i instanceof PhiNode || i instanceof LocalNode) { + if (i == null || visited.isMarked(i) || cfg.getNodeToBlock().get(i) != b || i instanceof PhiNode) { return; } @@ -1045,7 +1045,7 @@ private void addToEarliestSorting(Block b, ScheduledNode i, List sortedInstructions, NodeBitMap visited) { ScheduledNode instruction = i; while (true) { - if (instruction == null || visited.isMarked(instruction) || cfg.getNodeToBlock().get(instruction) != b || instruction instanceof PhiNode || instruction instanceof LocalNode) { + if (instruction == null || visited.isMarked(instruction) || cfg.getNodeToBlock().get(instruction) != b || instruction instanceof PhiNode) { return; } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Tue Sep 03 14:09:56 2013 -0700 @@ -23,6 +23,7 @@ package com.oracle.graal.replacements; import static com.oracle.graal.api.meta.MetaUtil.*; +import static com.oracle.graal.compiler.GraalCompiler.*; import static com.oracle.graal.phases.GraalOptions.*; import java.lang.reflect.*; @@ -138,7 +139,7 @@ Member originalMethod = originalMethod(classSubstitution, methodSubstitution.optional(), originalName, originalParameters); if (originalMethod != null) { ResolvedJavaMethod original = registerMethodSubstitution(originalMethod, substituteMethod); - if (original != null && methodSubstitution.forced()) { + if (original != null && methodSubstitution.forced() && shouldIntrinsify(original)) { forcedSubstitutions.add(original); } } @@ -149,7 +150,7 @@ Member originalMethod = originalMethod(classSubstitution, macroSubstitution.optional(), originalName, originalParameters); if (originalMethod != null) { ResolvedJavaMethod original = registerMacroSubstitution(originalMethod, macroSubstitution.macro()); - if (original != null && macroSubstitution.forced()) { + if (original != null && macroSubstitution.forced() && shouldIntrinsify(original)) { forcedSubstitutions.add(original); } } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Sep 03 14:09:56 2013 -0700 @@ -42,6 +42,7 @@ import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; 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.PhasePlan.PhasePosition; import com.oracle.graal.phases.common.*; @@ -184,8 +185,17 @@ materializeNode.replaceAtUsages(materializeNode.getFrame()); graph.removeFixed(materializeNode); } - for (VirtualOnlyInstanceNode virtualOnlyNode : graph.getNodes(VirtualOnlyInstanceNode.class)) { - virtualOnlyNode.setAllowMaterialization(true); + for (VirtualObjectNode virtualObjectNode : graph.getNodes(VirtualObjectNode.class)) { + if (virtualObjectNode instanceof VirtualOnlyInstanceNode) { + VirtualOnlyInstanceNode virtualOnlyInstanceNode = (VirtualOnlyInstanceNode) virtualObjectNode; + virtualOnlyInstanceNode.setAllowMaterialization(true); + } else if (virtualObjectNode instanceof VirtualInstanceNode) { + VirtualInstanceNode virtualInstanceNode = (VirtualInstanceNode) virtualObjectNode; + ResolvedJavaType type = virtualInstanceNode.type(); + if (type.getAnnotation(CompilerDirectives.ValueType.class) != null) { + virtualInstanceNode.setIdentity(false); + } + } } // Convert deopt to guards. diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Tue Sep 03 14:09:56 2013 -0700 @@ -205,6 +205,10 @@ } private void expandPath(StructuredGraph newGraph, int maxNodes, NodeBitMap visitedNodes, AbstractBeginNode start, Queue workQueue) { + if (start.isDeleted()) { + return; + } + FixedNode next = start; while (!visitedNodes.isMarked(next)) { visitedNodes.mark(next); diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Tue Sep 03 14:09:56 2013 -0700 @@ -92,12 +92,12 @@ throw new RuntimeException("Frame field not found: " + fieldName); } - public static class VirtualOnlyInstanceNode extends VirtualInstanceNode implements Node.IterableNodeType { + public static class VirtualOnlyInstanceNode extends VirtualInstanceNode { private boolean allowMaterialization; public VirtualOnlyInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields) { - super(type, fields); + super(type, fields, false); } @Override diff -r 20b642493616 -r 1f03076a121b 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 Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java Tue Sep 03 14:09:56 2013 -0700 @@ -67,9 +67,6 @@ } for (Node node : graph.getNodes()) { - if (node instanceof LocalNode) { - flood.add(node); - } if (flood.isMarked(node)) { for (Node input : node.inputs()) { flood.add(input); diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/CompilerErrorTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/CompilerErrorTest.java Tue Sep 03 14:09:56 2013 -0700 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2012, 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.truffle.api.dsl.test; + +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; + +public class CompilerErrorTest { + + abstract static class Visiblity01 extends ValueNode { + + @Specialization + @SuppressWarnings("static-method") + @ExpectError("Method annotated with @Specialization must not be private.") + private Object s() { + return null; + } + + } + + @ExpectError("Classes containing a @Specialization annotation must not be private.") + private abstract static class Visiblity02 extends ValueNode { + + @Specialization + public Object s() { + return null; + } + + } + + // assert no error + @ExpectError({}) + private abstract static class Visiblity03 extends ValueNode { + + } + +} diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GuardsTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GuardsTest.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/GuardsTest.java Tue Sep 03 14:09:56 2013 -0700 @@ -34,11 +34,15 @@ import com.oracle.truffle.api.dsl.test.GuardsTestFactory.GuardWithBoxedPrimitiveFactory; import com.oracle.truffle.api.dsl.test.GuardsTestFactory.GuardWithObjectFactory; import com.oracle.truffle.api.dsl.test.GuardsTestFactory.InvocationGuardFactory; +import com.oracle.truffle.api.dsl.test.GuardsTestFactory.TestAbstractGuard1Factory; import com.oracle.truffle.api.dsl.test.GuardsTestFactory.TestGuardResolve1Factory; import com.oracle.truffle.api.dsl.test.GuardsTestFactory.TestGuardResolve2Factory; import com.oracle.truffle.api.dsl.test.GuardsTestFactory.TestGuardResolve3Factory; import com.oracle.truffle.api.dsl.test.NodeContainerTest.Str; import com.oracle.truffle.api.dsl.test.NodeContainerTest.StrBase; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.Abstract; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.BExtendsAbstract; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.CExtendsAbstract; import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; @@ -271,4 +275,43 @@ } } + @NodeChild("expression") + public abstract static class TestGuardResolve4 extends ValueNode { + + boolean guard(StrBase primitive) { + return false; + } + + @Specialization(guards = "guard") + int doSpecialized(Str value0) { + return 42; + } + } + + @Test + public void testAbstractGuard1() { + TestRootNode root = createRoot(TestAbstractGuard1Factory.getInstance()); + + assertEquals(BExtendsAbstract.INSTANCE, executeWith(root, BExtendsAbstract.INSTANCE)); + assertEquals(CExtendsAbstract.INSTANCE, executeWith(root, CExtendsAbstract.INSTANCE)); + } + + @NodeChild("expression") + public abstract static class TestAbstractGuard1 extends ValueNode { + + boolean guard(Abstract value0) { + return true; + } + + @Specialization(order = 1, guards = "guard") + BExtendsAbstract doSpecialized1(BExtendsAbstract value0) { + return value0; + } + + @Specialization(order = 2, guards = "guard") + CExtendsAbstract doSpecialized2(CExtendsAbstract value0) { + return value0; + } + } + } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeFieldTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeFieldTest.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/NodeFieldTest.java Tue Sep 03 14:09:56 2013 -0700 @@ -146,4 +146,21 @@ } + @Test + public void testObjectContainer() { + assertEquals("42", createCallTarget(ObjectContainerNodeFactory.create("42")).call()); + } + + @NodeField(name = "object", type = Object.class) + abstract static class ObjectContainerNode extends ValueNode { + + public abstract Object getObject(); + + @Specialization + Object containerField() { + return getObject(); + } + + } + } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SpecializationGroupingTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SpecializationGroupingTest.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/SpecializationGroupingTest.java Tue Sep 03 14:09:56 2013 -0700 @@ -26,10 +26,13 @@ import com.oracle.truffle.api.*; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.dsl.test.SpecializationGroupingTestFactory.TestElseConnectionBug1Factory; +import com.oracle.truffle.api.dsl.test.SpecializationGroupingTestFactory.TestElseConnectionBug2Factory; import com.oracle.truffle.api.dsl.test.SpecializationGroupingTestFactory.TestGroupingFactory; import com.oracle.truffle.api.dsl.test.TypeSystemTest.SimpleTypes; import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; +import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; /** @@ -154,6 +157,83 @@ } + @Test + public void testElseConnectionBug1() { + CallTarget target = TestHelper.createCallTarget(TestElseConnectionBug1Factory.create(new GenericInt())); + Assert.assertEquals(42, target.call()); + } + + @SuppressWarnings("unused") + @NodeChild(value = "genericChild", type = GenericInt.class) + public abstract static class TestElseConnectionBug1 extends ValueNode { + + @Specialization(order = 1, rewriteOn = {SlowPathException.class}, guards = "isInitialized") + public int doInteger(int value) throws SlowPathException { + throw new SlowPathException(); + } + + @Specialization(order = 3, guards = "isInitialized") + public int doObject(int value) { + return value == 42 ? value : 0; + } + + @Specialization(order = 4, guards = "!isInitialized") + public Object doUninitialized(int value) { + throw new AssertionError(); + } + + boolean isInitialized(int value) { + return true; + } + } + + public static final class GenericInt extends ValueNode { + + @Override + public Object execute(VirtualFrame frame) { + return executeInt(frame); + } + + @Override + public int executeInt(VirtualFrame frame) { + return 42; + } + + } + + @Test + public void testElseConnectionBug2() { + TestHelper.assertRuns(TestElseConnectionBug2Factory.getInstance(), 42, 42); + } + + @SuppressWarnings("unused") + @NodeChild + public abstract static class TestElseConnectionBug2 extends ValueNode { + + @Specialization(order = 2, guards = "guard0") + public int doGuard0(int value) { + throw new AssertionError(); + } + + @Specialization(order = 3, guards = "guard1") + public int doGuard1(int value) { + throw new AssertionError(); + } + + @Specialization(order = 4, guards = "!guard0") + public int doUninitialized(int value) { + return value; + } + + boolean guard0(int value) { + return false; + } + + boolean guard1(int value) { + return false; + } + } + private static class MockAssumption implements Assumption { int checked; diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestHelper.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestHelper.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TestHelper.java Tue Sep 03 14:09:56 2013 -0700 @@ -22,6 +22,8 @@ */ package com.oracle.truffle.api.dsl.test; +import static org.junit.Assert.*; + import java.util.*; import com.oracle.truffle.api.*; @@ -75,4 +77,69 @@ return createCallTarget(node).call(new TestArguments(values)); } + static Object array(Object... val) { + return val; + } + + static List> permutations(List list) { + return permutations(new ArrayList(), list, new ArrayList>()); + } + + static Object[][] permutations(Object... list) { + List> permutations = permutations(Arrays.asList(list)); + + Object[][] a = new Object[permutations.size()][]; + int index = 0; + for (List p : permutations) { + a[index] = p.toArray(new Object[p.size()]); + index++; + } + + return a; + } + + static List> permutations(List prefix, List suffix, List> output) { + if (suffix.size() == 1) { + ArrayList newElement = new ArrayList<>(prefix); + newElement.addAll(suffix); + output.add(newElement); + return output; + } + + for (int i = 0; i < suffix.size(); i++) { + List newPrefix = new ArrayList<>(prefix); + newPrefix.add(suffix.get(i)); + List newSuffix = new ArrayList<>(suffix); + newSuffix.remove(i); + permutations(newPrefix, newSuffix, output); + } + + return output; + } + + /* Methods tests all test values in combinational order. */ + static void assertRuns(NodeFactory factory, Object result, Object... testValues) { + // test each run by its own. + for (int i = 0; i < testValues.length; i++) { + assertValue(createRoot(factory), result, testValues); + } + + // test all combinations of the test values + List> permuts = permutations(Arrays.asList(testValues)); + for (List list : permuts) { + TestRootNode root = createRoot(factory); + for (Object object : list) { + assertValue(root, result, object); + } + } + } + + static void assertValue(TestRootNode root, Object result, Object testValues) { + if (testValues instanceof Object[]) { + assertEquals(result, executeWith(root, (Object[]) testValues)); + } else { + assertEquals(result, executeWith(root, testValues)); + } + } + } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemErrorsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemErrorsTest.java Tue Sep 03 14:09:56 2013 -0700 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.dsl.test; + +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.*; + +public class TypeSystemErrorsTest { + + @TypeSystem({int.class, boolean.class}) + public static class Types0 { + + } + + @ExpectError("Invalid type order. The type(s) [java.lang.String] are inherited from a earlier defined type java.lang.CharSequence.") + @TypeSystem({CharSequence.class, String.class}) + public static class Types1 { + + } + + @TypeSystem({int.class, boolean.class}) + public static class Types2 { + + @TypeCast + @ExpectError("The provided return type \"String\" does not match expected return type \"int\".%") + String asInteger(Object value) { + return (String) value; + } + + } + + @TypeSystem({int.class, boolean.class}) + public static class Types3 { + + @TypeCast + @ExpectError("The provided return type \"boolean\" does not match expected return type \"int\".%") + boolean asInteger(Object value) { + return (boolean) value; + } + + } + + @TypeSystemReference(Types0.class) + @NodeChild + @ExpectError("The @TypeSystem of the node and the @TypeSystem of the @NodeChild does not match. Types0 != SimpleTypes. ") + abstract static class ErrorNode1 extends ValueNode { + + } + +} diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java Tue Sep 03 14:09:56 2013 -0700 @@ -30,7 +30,7 @@ public class TypeSystemTest { - @TypeSystem({int.class, boolean.class, String.class, Str.class, CallTarget.class, Object[].class}) + @TypeSystem({int.class, boolean.class, String.class, Str.class, CallTarget.class, BExtendsAbstract.class, CExtendsAbstract.class, Abstract.class, Object[].class}) static class SimpleTypes { static int intCheck; @@ -73,6 +73,14 @@ return SimpleTypesGen.SIMPLETYPES.expectObjectArray(execute(frame)); } + public BExtendsAbstract executeBExtendsAbstract(VirtualFrame frame) throws UnexpectedResultException { + return SimpleTypesGen.SIMPLETYPES.expectBExtendsAbstract(execute(frame)); + } + + public CExtendsAbstract executeCExtendsAbstract(VirtualFrame frame) throws UnexpectedResultException { + return SimpleTypesGen.SIMPLETYPES.expectCExtendsAbstract(execute(frame)); + } + public abstract Object execute(VirtualFrame frame); @Override @@ -154,4 +162,18 @@ } + abstract static class Abstract { + } + + static final class BExtendsAbstract extends Abstract { + + static final BExtendsAbstract INSTANCE = new BExtendsAbstract(); + + } + + static final class CExtendsAbstract extends Abstract { + + static final CExtendsAbstract INSTANCE = new CExtendsAbstract(); + } + } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/ExpectError.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/ExpectError.java Tue Sep 03 14:09:56 2013 -0700 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2012, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.dsl; + +import java.lang.annotation.*; + +/** + * This annotation is internally known by the dsl processor and used to expect errors for testing + * purposes. This is not part of public API. + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface ExpectError { + + String[] value(); + +} diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/ImplicitCast.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/ImplicitCast.java Tue Sep 03 14:09:56 2013 -0700 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.dsl; + +import java.lang.annotation.*; + +/** + * EXPERIMENTAL Filter feature. May change or disappear without notice. This feature is not + * functional yet. + */ +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.METHOD}) +public @interface ImplicitCast { + +} diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java Tue Sep 03 14:09:56 2013 -0700 @@ -205,4 +205,13 @@ @Target({ElementType.METHOD}) public @interface SlowPath { } + + /** + * Marks classes as value types. Reference comparisons (==) between instances of those classes + * have undefined semantics and can either return true or false. + */ + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.TYPE}) + public @interface ValueType { + } } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/AbstractParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/AbstractParser.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/AbstractParser.java Tue Sep 03 14:09:56 2013 -0700 @@ -65,7 +65,7 @@ return null; } - model.emitMessages((TypeElement) element, log); + model.emitMessages(context, (TypeElement) element, log); return filterErrorElements(model); } catch (CompileErrorException e) { log.message(Kind.WARNING, element, null, null, "The truffle processor could not parse class due to error: %s", e.getMessage()); diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleProcessor.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleProcessor.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleProcessor.java Tue Sep 03 14:09:56 2013 -0700 @@ -96,7 +96,7 @@ private static void handleThrowable(AnnotationProcessor generator, Throwable t, Element e) { String message = "Uncaught error in " + generator.getClass().getSimpleName() + " while processing " + e; - generator.getContext().getLog().message(Kind.ERROR, e, null, null, message + ": " + Utils.printException(t)); + generator.getContext().getEnvironment().getMessager().printMessage(Kind.ERROR, message + ": " + Utils.printException(t), e); } @SuppressWarnings("unchecked") diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java Tue Sep 03 14:09:56 2013 -0700 @@ -30,6 +30,7 @@ import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.*; +import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.api.nodes.Node.Child; @@ -56,6 +57,7 @@ private final TypeMirror compilerAsserts; private final DeclaredType slowPath; private final DeclaredType truffleOptions; + private final TypeElement expectError; private final List errors = new ArrayList<>(); @@ -74,6 +76,11 @@ nodeInfoKind = getRequired(context, NodeInfo.Kind.class); slowPath = getRequired(context, SlowPath.class); truffleOptions = getRequired(context, TruffleOptions.class); + expectError = (TypeElement) getRequired(context, ExpectError.class).asElement(); + } + + public TypeElement getExpectError() { + return expectError; } public DeclaredType getNodeInfoAnnotation() { diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Utils.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Utils.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/Utils.java Tue Sep 03 14:09:56 2013 -0700 @@ -423,6 +423,8 @@ return getSimpleName(mirror); case ERROR: throw new CompileErrorException("Type error " + mirror); + case EXECUTABLE: + return ((ExecutableType) mirror).toString(); case NONE: return "$none"; default: @@ -755,6 +757,10 @@ public static AnnotationMirror findAnnotationMirror(ProcessingEnvironment processingEnv, List mirrors, Class annotationClass) { TypeElement expectedAnnotationType = processingEnv.getElementUtils().getTypeElement(annotationClass.getCanonicalName()); + return findAnnotationMirror(mirrors, expectedAnnotationType); + } + + public static AnnotationMirror findAnnotationMirror(List mirrors, TypeElement expectedAnnotationType) { for (AnnotationMirror mirror : mirrors) { DeclaredType annotationType = mirror.getAnnotationType(); TypeElement actualAnnotationType = (TypeElement) annotationType.asElement(); diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastParser.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastParser.java Tue Sep 03 14:09:56 2013 -0700 @@ -61,7 +61,7 @@ } @Override - public CreateCastData create(TemplateMethod method) { + public CreateCastData create(TemplateMethod method, boolean invalid) { AnnotationMirror mirror = method.getMarkerAnnotation(); List childNames = Utils.getAnnotationValueList(String.class, mirror, "value"); CreateCastData cast = new CreateCastData(method, childNames); diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeMethodParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeMethodParser.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeMethodParser.java Tue Sep 03 14:09:56 2013 -0700 @@ -73,17 +73,13 @@ @Override protected List nodeTypeMirrors(NodeData nodeData) { - // executable types not yet available - if (nodeData.getTypeSystem() == null) { - return Collections.emptyList(); - } - List types = new ArrayList<>(nodeData.getTypeSystem().getPrimitiveTypeMirrors()); - types.add(nodeData.getTypeSystem().getVoidType().getPrimitiveType()); + List types = new ArrayList<>(getNode().getTypeSystem().getPrimitiveTypeMirrors()); + types.add(getNode().getTypeSystem().getVoidType().getPrimitiveType()); return types; } @Override - public ExecutableTypeData create(TemplateMethod method) { + public ExecutableTypeData create(TemplateMethod method, boolean invalid) { TypeData resolvedType = method.getReturnType().getTypeSystemType(); return new ExecutableTypeData(method, method.getMethod(), getNode().getTypeSystem(), resolvedType); } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/GenericParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/GenericParser.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/GenericParser.java Tue Sep 03 14:09:56 2013 -0700 @@ -61,7 +61,7 @@ } @Override - public SpecializationData create(TemplateMethod method) { + public SpecializationData create(TemplateMethod method, boolean invalid) { SpecializationData data = new SpecializationData(method, true, false, false); return data; } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Tue Sep 03 14:09:56 2013 -0700 @@ -621,6 +621,9 @@ int index = 0; for (VariableElement param : element.getParameters()) { + if (Utils.isObject(param.asType())) { + continue; + } builder.string(" && "); if (!param.asType().getKind().isPrimitive()) { builder.string("(arguments[" + index + "] == null || "); @@ -639,7 +642,9 @@ index = 0; for (VariableElement param : element.getParameters()) { builder.startGroup(); - builder.string("(").type(param.asType()).string(") "); + if (!Utils.isObject(param.asType())) { + builder.string("(").type(param.asType()).string(") "); + } builder.string("arguments[").string(String.valueOf(index)).string("]"); builder.end(); index++; @@ -2392,15 +2397,13 @@ } private CodeTree createExecuteBody(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData execType) { - TypeData primaryType = specialization.getReturnType().getTypeSystemType(); - CodeTreeBuilder builder = new CodeTreeBuilder(parent); List primaryExecutes = findFunctionalExecutableType(specialization, execType.getEvaluatedCount()); if (primaryExecutes.contains(execType) || primaryExecutes.isEmpty()) { builder.tree(createFunctionalExecute(builder, specialization, execType)); - } else if (needsCastingExecuteMethod(execType, primaryType)) { + } else if (needsCastingExecuteMethod(execType)) { assert !primaryExecutes.isEmpty(); builder.tree(createCastingExecute(builder, specialization, execType, primaryExecutes.get(0))); } else { @@ -2431,13 +2434,10 @@ return method; } - private boolean needsCastingExecuteMethod(ExecutableTypeData execType, TypeData primaryType) { + private boolean needsCastingExecuteMethod(ExecutableTypeData execType) { if (execType.isAbstract()) { return true; } - if (Utils.isPrimitiveOrVoid(primaryType.getPrimitiveType()) && Utils.isPrimitiveOrVoid(execType.getType().getPrimitiveType())) { - return true; - } if (execType.getType().isGeneric()) { return true; } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeMethodParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeMethodParser.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeMethodParser.java Tue Sep 03 14:09:56 2013 -0700 @@ -85,10 +85,14 @@ return methodSpec; } - private void addDefaultChildren(boolean shortCircuitsEnabled, String shortCircuitName, MethodSpec methodSpec) { + public void addDefaultChildren(boolean shortCircuitsEnabled, String breakName, MethodSpec methodSpec) { // children are null when parsing executable types if (getNode().getChildren() != null) { for (NodeChildData child : getNode().getChildren()) { + String valueName = child.getName(); + if (breakName != null && valueName.equals(breakName)) { + break; + } if (child.getExecutionKind() == ExecutionKind.DEFAULT) { ParameterSpec spec = createValueParameterSpec(child.getName(), child.getNodeData(), child.getExecuteWith().size()); if (child.getCardinality().isMany()) { @@ -97,10 +101,6 @@ } methodSpec.addRequired(spec); } else if (child.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT) { - String valueName = child.getName(); - if (shortCircuitName != null && valueName.equals(shortCircuitName)) { - break; - } if (shortCircuitsEnabled) { methodSpec.addRequired(new ParameterSpec(shortCircuitValueName(valueName), getContext().getType(boolean.class))); diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java Tue Sep 03 14:09:56 2013 -0700 @@ -199,6 +199,10 @@ } for (NodeData splittedNode : nodes) { + if (templateType.getModifiers().contains(Modifier.PRIVATE) && splittedNode.getSpecializations().size() > 0) { + splittedNode.addError("Classes containing a @%s annotation must not be private.", Specialization.class.getSimpleName()); + } + finalizeSpecializations(elements, splittedNode); verifyNode(splittedNode, elements); createPolymorphicSpecializations(splittedNode); @@ -328,11 +332,13 @@ nodeData.setNodeContainer(nodeContainer != null); nodeData.setTypeSystem(typeSystem); nodeData.setFields(parseFields(typeHierarchy, elements)); - parsedNodes.put(Utils.getQualifiedName(templateType), nodeData); - // parseChildren invokes cyclic parsing. nodeData.setChildren(parseChildren(elements, typeHierarchy)); nodeData.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, nodeData).parse(elements))); + // resolveChildren invokes cyclic parsing. + parsedNodes.put(Utils.getQualifiedName(templateType), nodeData); + resolveChildren(nodeData); + return nodeData; } @@ -380,6 +386,27 @@ return fields; } + private void resolveChildren(NodeData node) { + for (NodeChildData nodeChild : node.getChildren()) { + NodeData fieldNodeData = resolveNode(Utils.fromTypeMirror(nodeChild.getNodeType())); + nodeChild.setNode(fieldNodeData); + if (fieldNodeData == null) { + nodeChild.addError("Node type '%s' is invalid or not a valid Node.", Utils.getQualifiedName(nodeChild.getNodeType())); + } else if (!Utils.typeEquals(fieldNodeData.getTypeSystem().getTemplateType().asType(), (node.getTypeSystem().getTemplateType().asType()))) { + nodeChild.addError("The @%s of the node and the @%s of the @%s does not match. %s != %s. ", TypeSystem.class.getSimpleName(), TypeSystem.class.getSimpleName(), + NodeChild.class.getSimpleName(), Utils.getSimpleName(node.getTypeSystem().getTemplateType()), Utils.getSimpleName(fieldNodeData.getTypeSystem().getTemplateType())); + } + if (fieldNodeData != null) { + List types = nodeChild.findGenericExecutableTypes(context); + if (types.isEmpty()) { + AnnotationValue executeWithValue = Utils.getAnnotationValue(nodeChild.getMessageAnnotation(), "executeWith"); + nodeChild.addError(executeWithValue, "No generic execute method found with %s evaluated arguments for node type %s.", nodeChild.getExecuteWith().size(), + Utils.getSimpleName(nodeChild.getNodeType())); + } + } + } + } + private List parseChildren(List elements, final List typeHierarchy) { Set shortCircuits = new HashSet<>(); for (ExecutableElement method : ElementFilter.methodsIn(elements)) { @@ -454,12 +481,6 @@ continue; } - NodeData fieldNodeData = resolveNode(Utils.fromTypeMirror(childType)); - nodeChild.setNode(fieldNodeData); - if (fieldNodeData == null) { - nodeChild.addError("Node type '%s' is invalid or not a valid Node.", Utils.getQualifiedName(childType)); - } - index++; } } @@ -512,12 +533,6 @@ if (child.getNodeData() == null) { continue; } - - List types = child.findGenericExecutableTypes(context); - if (types.isEmpty()) { - child.addError(executeWithValue, "No generic execute method found with %s evaluated arguments for node type %s.", executeWith.size(), Utils.getSimpleName(child.getNodeType())); - continue; - } } return filteredChildren; @@ -1006,9 +1021,6 @@ for (TemplateMethod method : nodeData.getAllTemplateMethods()) { unusedElements.remove(method.getMethod()); } - if (nodeData.getExtensionElements() != null) { - unusedElements.removeAll(nodeData.getExtensionElements()); - } for (NodeFieldData field : nodeData.getFields()) { if (field.getGetter() != null) { diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitParser.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitParser.java Tue Sep 03 14:09:56 2013 -0700 @@ -58,7 +58,7 @@ } @Override - public ShortCircuitData create(TemplateMethod method) { + public ShortCircuitData create(TemplateMethod method, boolean invalid) { String shortCircuitValue = Utils.getAnnotationValue(String.class, method.getMarkerAnnotation(), "value"); if (!shortCircuitValues.contains(shortCircuitValue)) { diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java Tue Sep 03 14:09:56 2013 -0700 @@ -41,12 +41,14 @@ private final List typeGuards; private final List guards; + private final NodeData node; private final SpecializationData specialization; private final List children = new ArrayList<>(); private SpecializationGroup parent; private SpecializationGroup(SpecializationData data) { + this.node = data.getNode(); this.assumptions = new ArrayList<>(); this.typeGuards = new ArrayList<>(); this.guards = new ArrayList<>(); @@ -61,9 +63,11 @@ } public SpecializationGroup(List children, List assumptionMatches, List typeGuardsMatches, List guardMatches) { + assert !children.isEmpty() : "children must not be empty"; this.assumptions = assumptionMatches; this.typeGuards = typeGuardsMatches; this.guards = guardMatches; + this.node = children.get(0).node; this.specialization = null; updateChildren(children); } @@ -106,18 +110,23 @@ } private GuardData findNegatedGuardInPrevious(GuardData guard) { - SpecializationGroup previous = this; - while ((previous = previous.getPreviousGroup()) != null) { - List elseConnectedGuards = previous.getElseConnectableGuards(); + SpecializationGroup previous = this.getPreviousGroup(); + if (previous == null) { + return null; + } + List elseConnectedGuards = previous.getElseConnectableGuards(); - if (previous == null || previous.getGuards().size() != elseConnectedGuards.size() + 1) { - return null; - } - GuardData previousGuard = previous.getGuards().get(elseConnectedGuards.size()); - if (guard.getMethod().equals(previousGuard.getMethod())) { - assert guard.isNegated() != previousGuard.isNegated(); - return guard; - } + if (previous == null || previous.getGuards().size() != elseConnectedGuards.size() + 1) { + return null; + } + + if (elseConnectedGuards.contains(guard)) { + return guard; + } + + GuardData previousGuard = previous.getGuards().get(elseConnectedGuards.size()); + if (guard.getMethod().equals(previousGuard.getMethod()) && guard.isNegated() != previousGuard.isNegated()) { + return guard; } return null; } @@ -205,16 +214,29 @@ for (Iterator iterator = guardMatches.iterator(); iterator.hasNext();) { GuardData guardMatch = iterator.next(); - List guardTypes = TemplateMethod.getSignatureTypes(guardMatch.getParameters()); - for (int i = 0; i < guardTypes.size(); i++) { - TypeMirror guardType = guardTypes.get(i); - int signatureIndex = i + 1; + int signatureIndex = 0; + for (ActualParameter parameter : guardMatch.getParameters()) { + signatureIndex++; + if (!parameter.getSpecification().isSignature()) { + continue; + } + + TypeMirror guardType = parameter.getType(); // object guards can be safely moved up if (Utils.isObject(guardType)) { continue; } + // generic guards can be safely moved up + SpecializationData generic = first.node.getGenericSpecialization(); + if (generic != null) { + ActualParameter genericParameter = generic.findParameter(parameter.getLocalName()); + if (genericParameter != null && Utils.typeEquals(genericParameter.getType(), guardType)) { + continue; + } + } + // signature index required for moving up guards if (containsIndex(typeGuardsMatches, signatureIndex) || (first.getParent() != null && first.getParent().containsTypeGuardIndex(signatureIndex))) { continue; diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationListenerParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationListenerParser.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationListenerParser.java Tue Sep 03 14:09:56 2013 -0700 @@ -47,7 +47,7 @@ } @Override - public SpecializationListenerData create(TemplateMethod method) { + public SpecializationListenerData create(TemplateMethod method, boolean invalid) { return new SpecializationListenerData(method); } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationMethodParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationMethodParser.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationMethodParser.java Tue Sep 03 14:09:56 2013 -0700 @@ -44,7 +44,7 @@ } @Override - public SpecializationData create(TemplateMethod method) { + public SpecializationData create(TemplateMethod method, boolean invalid) { return parseSpecialization(method); } @@ -57,7 +57,6 @@ int order = Utils.getAnnotationValue(Integer.class, method.getMarkerAnnotation(), "order"); if (order < 0 && order != Specialization.DEFAULT_ORDER) { method.addError("Invalid order attribute %d. The value must be >= 0 or the default value."); - return null; } AnnotationValue rewriteValue = Utils.getAnnotationValue(method.getMarkerAnnotation(), "rewriteOn"); diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java Tue Sep 03 14:09:56 2013 -0700 @@ -51,13 +51,21 @@ public abstract Element getMessageElement(); - public final void emitMessages(TypeElement baseElement, Log log) { - emitMessagesImpl(baseElement, log, new HashSet()); + public final void emitMessages(ProcessorContext context, TypeElement baseElement, Log log) { + emitMessagesImpl(context, baseElement, log, new HashSet(), null); } - private void emitMessagesImpl(TypeElement baseElement, Log log, Set visitedSinks) { + private void emitMessagesImpl(ProcessorContext context, TypeElement baseElement, Log log, Set visitedSinks, List verifiedMessages) { + List childMessages; + if (verifiedMessages == null) { + childMessages = collectMessagesWithElementChildren(new HashSet(), getMessageElement()); + } else { + childMessages = verifiedMessages; + } + verifyExpectedMessages(context, log, childMessages); + for (Message message : getMessages()) { - emitDefault(baseElement, log, message); + emitDefault(context, baseElement, log, message); } for (MessageContainer sink : findChildContainers()) { @@ -66,18 +74,95 @@ } visitedSinks.add(sink); - sink.emitMessagesImpl(baseElement, log, visitedSinks); + if (sink.getMessageElement() == this.getMessageElement()) { + sink.emitMessagesImpl(context, baseElement, log, visitedSinks, childMessages); + } else { + sink.emitMessagesImpl(context, baseElement, log, visitedSinks, null); + } + } + } + + private List collectMessagesWithElementChildren(Set visitedSinks, Element e) { + if (visitedSinks.contains(this)) { + return Collections.emptyList(); + } + visitedSinks.add(this); + + List foundMessages = new ArrayList<>(); + if (Utils.typeEquals(getMessageElement().asType(), e.asType())) { + foundMessages.addAll(getMessages()); + } + for (MessageContainer sink : findChildContainers()) { + foundMessages.addAll(sink.collectMessagesWithElementChildren(visitedSinks, e)); + } + return foundMessages; + } + + private void verifyExpectedMessages(ProcessorContext context, Log log, List msgs) { + TypeElement expectError = context.getTruffleTypes().getExpectError(); + if (expectError != null) { + Element element = getMessageElement(); + AnnotationMirror mirror = Utils.findAnnotationMirror(element.getAnnotationMirrors(), expectError); + if (mirror != null) { + List values = Utils.getAnnotationValueList(String.class, mirror, "value"); + if (values == null) { + values = Collections.emptyList(); + } + if (values.size() != msgs.size()) { + log.message(Kind.ERROR, element, mirror, Utils.getAnnotationValue(mirror, "value"), String.format("Error count expected %s but was %s.", values.size(), msgs.size())); + } + } } } - private void emitDefault(TypeElement baseType, Log log, Message message) { + private void emitDefault(ProcessorContext context, TypeElement baseType, Log log, Message message) { + Kind kind = message.getKind(); + + Element messageElement = getMessageElement(); + AnnotationMirror messageAnnotation = getMessageAnnotation(); + AnnotationValue messageValue = getMessageAnnotationValue(); + if (message.getAnnotationValue() != null) { + messageValue = message.getAnnotationValue(); + } + + String text = message.getText(); + TypeElement rootEnclosing = Utils.findRootEnclosingType(getMessageElement()); - if (rootEnclosing != null && Utils.typeEquals(baseType.asType(), rootEnclosing.asType()) && this == message.getOriginalContainer()) { - log.message(message.getKind(), getMessageElement(), getMessageAnnotation(), getMessageAnnotationValue(), message.getText()); - } else { + TypeElement baseEnclosing = Utils.findRootEnclosingType(baseType); + if (rootEnclosing == null || !Utils.typeEquals(baseEnclosing.asType(), rootEnclosing.asType()) || this != message.getOriginalContainer()) { + // redirect message MessageContainer original = message.getOriginalContainer(); - log.message(message.getKind(), baseType, null, null, wrapText(original.getMessageElement(), original.getMessageAnnotation(), message.getText())); + messageElement = baseType; + messageAnnotation = null; + messageValue = null; + text = wrapText(original.getMessageElement(), original.getMessageAnnotation(), message.getText()); } + + TypeElement expectError = context.getTruffleTypes().getExpectError(); + if (expectError != null) { + AnnotationMirror mirror = Utils.findAnnotationMirror(messageElement.getAnnotationMirrors(), expectError); + if (mirror != null) { + List expectedTexts = Utils.getAnnotationValueList(String.class, mirror, "value"); + boolean found = false; + for (String expectedText : expectedTexts) { + if (expectedText.endsWith("%") && text.startsWith(expectedText.substring(0, expectedText.length() - 1))) { + found = true; + break; + } else if (text.equals(expectedText)) { + found = true; + break; + } + } + if (!found) { + log.message(kind, messageElement, mirror, Utils.getAnnotationValue(mirror, "value"), "Message expected one of '%s' but was '%s'.", expectedTexts, text); + } else { + return; + } + + } + } + + log.message(kind, messageElement, messageAnnotation, messageValue, text); } private static String wrapText(Element element, AnnotationMirror mirror, String text) { diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/Template.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/Template.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/Template.java Tue Sep 03 14:09:56 2013 -0700 @@ -27,7 +27,6 @@ import javax.lang.model.element.*; import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.api.element.*; import com.oracle.truffle.dsl.processor.typesystem.*; public abstract class Template extends MessageContainer { @@ -36,8 +35,6 @@ private final String templateMethodName; private final AnnotationMirror annotation; - private List extensionElements; - public Template(TypeElement templateType, String templateMethodName, AnnotationMirror annotation) { this.templateType = templateType; this.templateMethodName = templateMethodName; @@ -68,14 +65,6 @@ return annotation; } - public List getExtensionElements() { - return extensionElements; - } - - public void setExtensionElements(List extensionMethods) { - this.extensionElements = extensionMethods; - } - @Override public String toString() { return getClass().getSimpleName() + "[" + Utils.getSimpleName(getTemplateType()) + "]"; diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java Tue Sep 03 14:09:56 2013 -0700 @@ -43,7 +43,7 @@ protected final T template; private boolean emitErrors = true; - private boolean parseNullOnError = true; + private boolean parseNullOnError = false; public TemplateMethodParser(ProcessorContext context, T template) { this.template = template; @@ -76,7 +76,7 @@ public abstract MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror); - public abstract E create(TemplateMethod method); + public abstract E create(TemplateMethod method, boolean invalid); public abstract boolean isParsable(ExecutableElement method); @@ -104,7 +104,8 @@ E parsedMethod = parse(method, mirror); if (method.getModifiers().contains(Modifier.PRIVATE) && emitErrors) { - parsedMethod.addError("Method must not be private."); + parsedMethod.addError("Method annotated with @%s must not be private.", getAnnotationType().getSimpleName()); + parsedMethods.add(parsedMethod); valid = false; continue; } @@ -142,7 +143,7 @@ ActualParameter returnTypeMirror = matchParameter(returnTypeSpec, method.getReturnType(), template, 0, false); if (returnTypeMirror == null) { if (emitErrors) { - E invalidMethod = create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, Collections. emptyList())); + E invalidMethod = create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, Collections. emptyList()), true); String expectedReturnType = returnTypeSpec.toSignatureString(true); String actualReturnType = Utils.getSimpleName(method.getReturnType()); @@ -163,7 +164,7 @@ List parameters = parseParameters(methodSpecification, parameterTypes); if (parameters == null) { if (isEmitErrors()) { - E invalidMethod = create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, Collections. emptyList())); + E invalidMethod = create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, Collections. emptyList()), true); String message = String.format("Method signature %s does not match to the expected signature: \n%s", createActualSignature(methodSpecification, method), methodSpecification.toSignatureString(method.getSimpleName().toString())); invalidMethod.addError(message); @@ -173,7 +174,7 @@ } } - return create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, parameters)); + return create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, parameters), false); } private static String createActualSignature(MethodSpec spec, ExecutableElement method) { diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardData.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardData.java Tue Sep 03 14:09:56 2013 -0700 @@ -60,7 +60,7 @@ @Override public String toString() { - return getMethodName() + getParameters().toString(); + return (negated ? "!" : "") + getMethodName() + getParameters().toString(); } } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardParser.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardParser.java Tue Sep 03 14:09:56 2013 -0700 @@ -79,7 +79,7 @@ } @Override - public GuardData create(TemplateMethod method) { + public GuardData create(TemplateMethod method, boolean invalid) { GuardData guard = new GuardData(method, specialization, negated); /* * Update parameters in way that parameter specifications match again the node field names diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastData.java Tue Sep 03 14:09:56 2013 -0700 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2012, 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.truffle.dsl.processor.typesystem; + +import com.oracle.truffle.dsl.processor.template.*; + +public class ImplicitCastData extends TemplateMethod { + + public ImplicitCastData(TemplateMethod method) { + super(method); + } + +} diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastParser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastParser.java Tue Sep 03 14:09:56 2013 -0700 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2012, 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.truffle.dsl.processor.typesystem; + +import java.lang.annotation.*; +import java.util.*; + +import javax.lang.model.element.*; +import javax.lang.model.type.*; + +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.dsl.processor.*; +import com.oracle.truffle.dsl.processor.template.*; + +public class ImplicitCastParser extends TypeSystemMethodParser { + + public ImplicitCastParser(ProcessorContext context, TypeSystemData typeSystem) { + super(context, typeSystem); + } + + @Override + public Class getAnnotationType() { + return ImplicitCast.class; + } + + @Override + public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { + List types = new ArrayList<>(); + for (TypeData typeData : getTypeSystem().getTypes()) { + types.add(typeData.getPrimitiveType()); + } + MethodSpec spec = new MethodSpec(new ParameterSpec("target", types)); + spec.addRequired(new ParameterSpec("source", types)).setSignature(true); + return spec; + } + + @Override + public ImplicitCastData create(TemplateMethod method, boolean invalid) { + return new ImplicitCastData(method); + } + +} diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCastParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCastParser.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCastParser.java Tue Sep 03 14:09:56 2013 -0700 @@ -48,10 +48,25 @@ } @Override - public TypeCastData create(TemplateMethod method) { + public TypeCastData create(TemplateMethod method, boolean invalid) { + if (invalid) { + return new TypeCastData(method, null, null); + } + TypeData targetType = findTypeByMethodName(method, "as"); ActualParameter parameter = method.findParameter("valueValue"); - return new TypeCastData(method, parameter.getTypeSystemType(), targetType); + + TypeData sourceType = null; + if (parameter != null) { + sourceType = getTypeSystem().findTypeData(parameter.getType()); + } + TypeCastData cast = new TypeCastData(method, sourceType, targetType); + + if (targetType != method.getReturnType().getTypeSystemType()) { + cast.addError("Cast type %s does not match to the returned type %s.", Utils.getSimpleName(targetType.getPrimitiveType()), + method.getReturnType() != null ? Utils.getSimpleName(method.getReturnType().getTypeSystemType().getPrimitiveType()) : null); + } + return cast; } @Override diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCheckParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCheckParser.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeCheckParser.java Tue Sep 03 14:09:56 2013 -0700 @@ -48,7 +48,7 @@ } @Override - public TypeCheckData create(TemplateMethod method) { + public TypeCheckData create(TemplateMethod method, boolean invalid) { TypeData checkedType = findTypeByMethodName(method, "is"); assert checkedType != null; ActualParameter parameter = method.findParameter("valueValue"); diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemData.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemData.java Tue Sep 03 14:09:56 2013 -0700 @@ -36,6 +36,9 @@ private List primitiveTypeMirrors = new ArrayList<>(); private List boxedTypeMirrors = new ArrayList<>(); + private List casts; + private List checks; + private TypeMirror genericType; private TypeData voidType; @@ -58,6 +61,14 @@ } } + public void setCasts(List casts) { + this.casts = casts; + } + + public void setChecks(List checks) { + this.checks = checks; + } + void setGenericType(TypeMirror genericType) { this.genericType = genericType; } @@ -72,6 +83,12 @@ if (types != null) { sinks.addAll(types); } + if (checks != null) { + sinks.addAll(checks); + } + if (casts != null) { + sinks.addAll(casts); + } return sinks; } diff -r 20b642493616 -r 1f03076a121b graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemParser.java Tue Sep 03 14:09:35 2013 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/TypeSystemParser.java Tue Sep 03 14:09:56 2013 -0700 @@ -37,7 +37,7 @@ public class TypeSystemParser extends TemplateParser { - public static final List> ANNOTATIONS = Arrays.asList(TypeSystem.class); + public static final List> ANNOTATIONS = Arrays.asList(TypeSystem.class, ExpectError.class); public TypeSystemParser(ProcessorContext c) { super(c); @@ -84,11 +84,17 @@ verifyExclusiveMethodAnnotation(typeSystem, TypeCast.class, TypeCheck.class); List elements = new ArrayList<>(context.getEnvironment().getElementUtils().getAllMembers(templateType)); - + List implicitCasts = new ImplicitCastParser(context, typeSystem).parse(elements); List casts = new TypeCastParser(context, typeSystem).parse(elements); List checks = new TypeCheckParser(context, typeSystem).parse(elements); - if (casts == null || checks == null) { + if (casts == null || checks == null || implicitCasts == null) { + return typeSystem; + } + typeSystem.setCasts(casts); + typeSystem.setChecks(checks); + + if (typeSystem.hasErrors()) { return typeSystem; } diff -r 20b642493616 -r 1f03076a121b mx/.pylintrc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mx/.pylintrc Tue Sep 03 14:09:56 2013 -0700 @@ -0,0 +1,275 @@ +[MASTER] + +# Specify a configuration file. +#rcfile= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Profiled execution. +profile=no + +# Add files or directories to the blacklist. They should be base names, not +# paths. +ignore=CVS + +# Pickle collected data for later comparisons. +persistent=yes + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + + +[MESSAGES CONTROL] + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time. See also the "--disable" option for examples. +#enable= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once).You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use"--disable=all --enable=classes +# --disable=W" +disable=attribute-defined-outside-init,arguments-differ, + bare-except,global-statement,protected-access,redefined-outer-name, + unused-argument,star-args,pointless-string-statement,old-style-class, + too-many-lines,missing-docstring,no-init + +[REPORTS] + +# Set the output format. Available formats are text, parseable, colorized, msvs +# (visual studio) and html. You can also give a reporter class, eg +# mypackage.mymodule.MyReporterClass. +output-format=text + +# Put messages in a separate file for each module / package specified on the +# command line instead of printing them on stdout. Reports (if any) will be +# written in a file name "pylint_global.[txt|html]". +files-output=no + +# Tells whether to display a full report or only the messages +reports=no + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Add a comment according to your evaluation note. This is used by the global +# evaluation report (RP0004). +comment=no + +# Template used to display messages. This is a python new-style format string +# used to format the massage information. See doc for all details +#msg-template= + + +[BASIC] + +# Required attributes for module, separated by a comma +required-attributes= + +# List of builtins function names that should not be used, separated by a comma +bad-functions=filter,apply,input + +# Regular expression which should only match correct module names +module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ + +# Regular expression which should only match correct module level names +const-rgx=[a-zA-Z0-9_]{2,30}$ + +# Regular expression which should only match correct class names +class-rgx=[A-Z_][a-zA-Z0-9]+$ + +# Regular expression which should only match correct function names +function-rgx=[a-z_][a-zA-Z0-9_]{1,30}$ + +# Regular expression which should only match correct method names +method-rgx=[a-z_][a-zA-Z0-9_]{2,30}$ + +# Regular expression which should only match correct instance attribute names +attr-rgx=[a-z_][a-zA-Z0-9_]{1,30}$ + +# Regular expression which should only match correct argument names +argument-rgx=[a-z_][a-zA-Z0-9_]{0,30}$ + +# Regular expression which should only match correct variable names +variable-rgx=[a-z_][a-zA-Z0-9_]{0,30}$ + +# Regular expression which should only match correct attribute names in class +# bodies +class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ + +# Regular expression which should only match correct list comprehension / +# generator expression variable names +inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ + +# Good variable names which should always be accepted, separated by a comma +good-names=i,j,k,ex,Run,_ + +# Bad variable names which should always be refused, separated by a comma +bad-names=foo,bar,baz,toto,tutu,tata + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=.* + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + + +[FORMAT] + +# Maximum number of characters on a single line. +max-line-length=300 + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$ + +# Maximum number of lines in a module +max-module-lines=1000 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME + + +[SIMILARITIES] + +# Minimum lines number of a similarity. +min-similarity-lines=4 + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + +# Ignore imports when computing similarities. +ignore-imports=no + + +[TYPECHECK] + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# List of classes names for which member attributes should not be checked +# (useful for classes with attributes dynamically set). +ignored-classes=SQLObject + +# When zope mode is activated, add a predefined set of Zope acquired attributes +# to generated-members. +zope=no + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E0201 when accessed. Python regular +# expressions are accepted. +generated-members=REQUEST,acl_users,aq_parent + + +[VARIABLES] + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# A regular expression matching the beginning of the name of dummy variables +# (i.e. not used). +dummy-variables-rgx=_$|dummy + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid to define new builtins when possible. +additional-builtins= + + +[CLASSES] + +# List of interface methods to ignore, separated by a comma. This is used for +# instance to not check methods defines in Zope's Interface base class. +ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__,__new__,setUp + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=mcs + + +[DESIGN] + +# Maximum number of arguments for function / method +max-args=5 + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore +ignored-argument-names=_.* + +# Maximum number of locals for function / method body +max-locals=15 + +# Maximum number of return / yield for function / method body +max-returns=6 + +# Maximum number of branch for function / method body +max-branches=12 + +# Maximum number of statements in function / method body +max-statements=50 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + + +[IMPORTS] + +# Deprecated modules which should not be used, separated by a comma +deprecated-modules=regsub,TERMIOS,Bastion,rexec + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled) +import-graph= + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled) +ext-import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled) +int-import-graph= + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "Exception" +overgeneral-exceptions=Exception diff -r 20b642493616 -r 1f03076a121b mx/commands.py --- a/mx/commands.py Tue Sep 03 14:09:35 2013 -0700 +++ b/mx/commands.py Tue Sep 03 14:09:56 2013 -0700 @@ -45,10 +45,10 @@ _vmChoices = { 'graal' : 'All compilation is performed with Graal. This includes bootstrapping Graal itself unless -XX:-BootstrapGraal is used.', 'server' : 'Normal compilation is performed with the tiered system (i.e., client + server), Truffle compilation is performed with Graal. Use this for optimal Truffle performance.', - 'client' : None, # normal compilation with client compiler, explicit compilation (e.g., by Truffle) with Graal - 'server-nograal' : None, # all compilation with tiered system (i.e., client + server), Graal omitted - 'client-nograal' : None, # all compilation with client compiler, Graal omitted - 'original' : None, # default VM copied from bootstrap JDK + 'client' : None, # normal compilation with client compiler, explicit compilation (e.g., by Truffle) with Graal + 'server-nograal' : None, # all compilation with tiered system (i.e., client + server), Graal omitted + 'client-nograal' : None, # all compilation with client compiler, Graal omitted + 'original' : None, # default VM copied from bootstrap JDK } """ The VM that will be run by the 'vm' command and built by default by the 'build' command. @@ -95,14 +95,13 @@ items = [k for k in _vmChoices.keys() if _vmChoices[k] is not None] descriptions = [_vmChoices[k] for k in _vmChoices.keys() if _vmChoices[k] is not None] vm = mx.select_items(items, descriptions, allowMultiple=False) - answer = raw_input('Persist this choice by adding "DEFAULT_VM=' + vm + '" to ' + envPath + '? [Yn]: ') - if not answer.lower().startswith('n'): + if mx.ask_yes_no('Persist this choice by adding "DEFAULT_VM=' + vm + '" to ' + envPath, 'y'): with open(envPath, 'a') as fp: print >> fp, 'DEFAULT_VM=' + vm _vm = vm return vm -""" +""" A context manager that can be used with the 'with' statement to set the VM used by all VM executions within the scope of the 'with' statement. For example: @@ -117,17 +116,17 @@ self.build = build if build else _vmbuild self.previousVm = _vm self.previousBuild = _vmbuild - + def __enter__(self): global _vm, _vmbuild _vm = self.vm _vmbuild = self.build - + def __exit__(self, exc_type, exc_value, traceback): global _vm, _vmbuild _vm = self.previousVm _vmbuild = self.previousBuild - + def _chmodDir(chmodFlags, dirname, fnames): os.chmod(dirname, chmodFlags) for name in fnames: @@ -145,7 +144,7 @@ shutil.rmtree(name) elif os.path.isfile(name): os.unlink(name) - + rmIfExists(join(_graal_home, 'build')) rmIfExists(join(_graal_home, 'build-nograal')) rmIfExists(_jdksDir()) @@ -154,7 +153,7 @@ def export(args): """create a GraalVM zip file for distribution""" - parser = ArgumentParser(prog='mx export'); + parser = ArgumentParser(prog='mx export') parser.add_argument('--omit-vm-build', action='store_false', dest='vmbuild', help='omit VM build step') parser.add_argument('--omit-dist-init', action='store_false', dest='distInit', help='omit class files and IDE configurations from distribution') parser.add_argument('zipfile', nargs=REMAINDER, metavar='zipfile') @@ -201,13 +200,13 @@ vmOpts, benchmarksAndOptions = _extract_VM_args(args, useDoubleDash=availableBenchmarks is None) if availableBenchmarks is None: - harnessArgs = benchmarksAndOptions + harnessArgs = benchmarksAndOptions return runBenchmark(None, harnessArgs, vmOpts) if len(benchmarksAndOptions) == 0: mx.abort('at least one benchmark name or "all" must be specified') benchmarks = list(itertools.takewhile(lambda x: not x.startswith('-'), benchmarksAndOptions)) - harnessArgs = benchmarksAndOptions[len(benchmarks):] + harnessArgs = benchmarksAndOptions[len(benchmarks):] if 'all' in benchmarks: benchmarks = availableBenchmarks @@ -229,7 +228,7 @@ def launcher(bm, harnessArgs, extraVmOpts): return sanitycheck.getDacapo(bm, harnessArgs).test(_get_vm(), extraVmOpts=extraVmOpts) - + _run_benchmark(args, sanitycheck.dacapoSanityWarmup.keys(), launcher) def scaladacapo(args): @@ -281,12 +280,11 @@ def _handle_missing_VM(bld, vm): mx.log('The ' + bld + ' ' + vm + ' VM has not been created') if sys.stdout.isatty(): - answer = raw_input('Build it now? [Yn]: ') - if not answer.lower().startswith('n'): + if mx.ask_yes_no('Build it now', 'y'): with VM(vm, bld): build([]) return - mx.abort('You need to run "mx --vm ' + vm + '--vmbuild ' + bld + ' build" to build the selected VM') + mx.abort('You need to run "mx --vm ' + vm + ' --vmbuild ' + bld + ' build" to build the selected VM') def _jdk(build='product', vmToCheck=None, create=False, installGraalJar=True): """ @@ -334,7 +332,7 @@ if mx.get_os() != 'windows': chmodRecursive(jdk, 0755) shutil.move(join(_vmLibDirInJdk(jdk), defaultVM), join(_vmLibDirInJdk(jdk), 'original')) - + with open(jvmCfg, 'w') as fp: for line in jvmCfgLines: @@ -350,10 +348,10 @@ if _installed_jdks and mx._opts.verbose: mx.log("Could not find JDK directory at " + jdk) _handle_missing_VM(build, vmToCheck if vmToCheck else 'graal') - + if installGraalJar: _installGraalJarInJdks(mx.distribution('GRAAL')) - + if vmToCheck is not None: jvmCfg = _vmCfgInJdk(jdk) found = False @@ -364,7 +362,7 @@ break if not found: _handle_missing_VM(build, vmToCheck) - + return jdk def _installGraalJarInJdks(graalDist): @@ -380,25 +378,27 @@ 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={}): +def _runInDebugShell(cmd, workingDir, logFile=None, findInOutput=None, respondTo=None): + if respondTo is None: + respondTo = {} newLine = os.linesep - STARTTOKEN = 'RUNINDEBUGSHELL_STARTSEQUENCE' - ENDTOKEN = 'RUNINDEBUGSHELL_ENDSEQUENCE' + startToken = 'RUNINDEBUGSHELL_STARTSEQUENCE' + endToken = 'RUNINDEBUGSHELL_ENDSEQUENCE' winSDK = mx.get_env('WIN_SDK', 'C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\') - + if not exists(winSDK): mx.abort("Could not find Windows SDK : '" + winSDK + "' does not exist") - + if not exists(join(winSDK, 'Bin', 'SetEnv.cmd')): mx.abort("Invalid Windows SDK path (" + winSDK + ") : could not find Bin/SetEnv.cmd (you can use the WIN_SDK environment variable to specify an other path)") - p = subprocess.Popen('cmd.exe /E:ON /V:ON /K ""' + winSDK + '/Bin/SetEnv.cmd" & echo ' + STARTTOKEN + '"', \ + p = subprocess.Popen('cmd.exe /E:ON /V:ON /K ""' + winSDK + '/Bin/SetEnv.cmd" & echo ' + startToken + '"', \ shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP) stdout = p.stdout stdin = p.stdin @@ -406,20 +406,20 @@ log = open(logFile, 'w') ret = False while True: - + # encoding may be None on windows plattforms if sys.stdout.encoding is None: encoding = 'utf-8' else: encoding = sys.stdout.encoding - + line = stdout.readline().decode(encoding) if logFile: log.write(line.encode('utf-8')) line = line.strip() mx.log(line) - if line == STARTTOKEN: - stdin.write('cd /D ' + workingDir + ' & ' + cmd + ' & echo ' + ENDTOKEN + newLine) + if line == startToken: + stdin.write('cd /D ' + workingDir + ' & ' + cmd + ' & echo ' + endToken + newLine) for regex in respondTo.keys(): match = regex.search(line) if match: @@ -428,7 +428,7 @@ match = findInOutput.search(line) if match: ret = True - if line == ENDTOKEN: + if line == endToken: if not findInOutput: stdin.write('echo ERRXXX%errorlevel%' + newLine) else: @@ -436,7 +436,7 @@ if line.startswith('ERRXXX'): if line == 'ERRXXX0': ret = True - break; + break stdin.write('exit' + newLine) if logFile: log.close() @@ -458,16 +458,16 @@ 'INSTALL' : 'Install the built VM into the JDK? (default: y)', 'ZIP_DEBUGINFO_FILES' : 'Install zipped debug symbols file? (default: 0)', } - + mx.log('HotSpot build variables that can be set by the -D option to "mx build":') mx.log('') for n in sorted(buildVars.iterkeys()): mx.log(n) mx.log(textwrap.fill(buildVars[n], initial_indent=' ', subsequent_indent=' ', width=200)) - + mx.log('') mx.log('Note that these variables can be given persistent values in the file ' + join(_graal_home, 'mx', 'env') + ' (see \'mx about\').') - + def build(args, vm=None): """build the VM binary @@ -488,7 +488,7 @@ return result # Call mx.build to compile the Java sources - parser=AP() + parser = AP() parser.add_argument('--export-dir', help='directory to which graal.jar and graal.options will be copied', metavar='') parser.add_argument('-D', action='append', help='set a HotSpot build variable (run \'mx buildvars\' to list variables)', metavar='name=value') opts2 = mx.build(['--source', '1.7'] + args, parser=parser) @@ -522,7 +522,11 @@ else: assert vm == 'graal', vm buildSuffix = 'graal' - + + if _installed_jdks: + if not mx.ask_yes_no("You are going to build because --installed-jdks is set (" + _installed_jdks + ") - are you sure you want to continue", 'n'): + mx.abort(1) + for build in builds: if build == 'ide-build-target': build = os.environ.get('IDE_BUILD_TARGET', None) @@ -577,7 +581,7 @@ variant = {'client': 'compiler1', 'server': 'compiler2'}.get(vm, vm) project_config = variant + '_' + build _runInDebugShell('msbuild ' + _graal_home + r'\build\vs-amd64\jvm.vcproj /p:Configuration=' + project_config + ' /target:clean', _graal_home) - winCompileCmd = r'set HotSpotMksHome=' + mksHome + r'& set OUT_DIR=' + jdk + r'& set JAVA_HOME=' + jdk + r'& set path=%JAVA_HOME%\bin;%path%;%HotSpotMksHome%& cd /D "' +_graal_home + r'\make\windows"& call create.bat ' + _graal_home + winCompileCmd = r'set HotSpotMksHome=' + mksHome + r'& set OUT_DIR=' + jdk + r'& set JAVA_HOME=' + jdk + r'& set path=%JAVA_HOME%\bin;%path%;%HotSpotMksHome%& cd /D "' + _graal_home + r'\make\windows"& call create.bat ' + _graal_home print(winCompileCmd) winCompileSuccess = re.compile(r"^Writing \.vcxproj file:") if not _runInDebugShell(winCompileCmd, _graal_home, compilelogfile, winCompileSuccess): @@ -590,14 +594,14 @@ else: cpus = multiprocessing.cpu_count() runCmd = [mx.gmake_cmd()] - runCmd.append(build + buildSuffix) + runCmd.append(build + buildSuffix) env = os.environ.copy() - + if opts2.D: for nv in opts2.D: name, value = nv.split('=', 1) env[name.strip()] = value - + env.setdefault('ARCH_DATA_MODEL', '64') env.setdefault('LANG', 'C') env.setdefault('HOTSPOT_BUILD_JOBS', str(cpus)) @@ -645,7 +649,7 @@ if line.strip() == vmKnown.strip(): found = True lines.append(line) - + if not found: mx.log('Appending "' + prefix + 'KNOWN" to ' + jvmCfg) if mx.get_os() != 'windows': @@ -699,7 +703,7 @@ for p in mx.projects(): excludes += _find_classes_with_annotations(p, None, ['@Snippet', '@ClassSubstitution', '@Test'], includeInnerClasses=True).keys() excludes += p.find_classes_with_matching_source_line(None, lambda line: 'JaCoCo Exclude' in line, includeInnerClasses=True).keys() - + includes = ['com.oracle.graal.*'] agentOptions = { 'append' : 'true' if _jacoco == 'append' else 'false', @@ -714,12 +718,12 @@ exe = join(jdk, 'bin', mx.exe_suffix('java')) pfx = _vm_prefix.split() if _vm_prefix is not None else [] - + if '-version' in args: - ignoredArgs = args[args.index('-version')+1:] + ignoredArgs = args[args.index('-version') + 1:] if len(ignoredArgs) > 0: mx.log("Warning: The following options will be ignored by the vm because they come after the '-version' argument: " + ' '.join(ignoredArgs)) - + return mx.run(pfx + [exe, '-' + vm] + args, nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd, timeout=timeout) def _find_classes_with_annotations(p, pkgRoot, annotations, includeInnerClasses=False): @@ -728,7 +732,7 @@ (ignoring preceding whitespace) and return the fully qualified class name for each Java source file matched in a list. """ - + matches = lambda line : len([a for a in annotations if line == a or line.startswith(a + '(')]) != 0 return p.find_classes_with_matching_source_line(pkgRoot, matches, includeInnerClasses) @@ -740,7 +744,7 @@ if useDoubleDash: if args[i] == '--': vmArgs = args[:i] - remainder = args[i + 1:] + remainder = args[i + 1:] return vmArgs, remainder else: if not args[i].startswith('-'): @@ -750,25 +754,19 @@ else: continue vmArgs = args[:i] - remainder = args[i:] + remainder = args[i:] return vmArgs, remainder - + return args, [] - + def _run_tests(args, harness, annotations, testfile): - - + + vmArgs, tests = _extract_VM_args(args) for t in tests: if t.startswith('-'): mx.abort('VM option ' + t + ' must precede ' + tests[0]) - def containsAny(c, substrings): - for s in substrings: - if s in c: - return True - return False - candidates = [] for p in mx.projects(): if mx.java().javaCompliance < p.javaCompliance: @@ -833,14 +831,14 @@ If filters are supplied, only tests whose fully qualified name includes a filter as a substring are run. - + For example, this command line: - + mx unittest -G:Dump= -G:MethodFilter=BC_aload.* -G:+PrintCFG BC_aload - + will run all JUnit test classes that contain 'BC_aload' in their - fully qualified name and will pass these options to the VM: - + fully qualified name and will pass these options to the VM: + -G:Dump= -G:MethodFilter=BC_aload.* -G:+PrintCFG To get around command line length limitations on some OSes, the @@ -853,7 +851,7 @@ As with all other commands, using the global '-v' before 'unittest' command will cause mx to show the complete command line it uses to run the VM. -""" +""" def unittest(args): """run the JUnit tests (all testcases){0}""" @@ -875,8 +873,8 @@ vmsDefault = ','.join(_vmChoices.keys()) vmbuildsDefault = ','.join(_vmbuildChoices) - - parser = ArgumentParser(prog='mx buildvms'); + + parser = ArgumentParser(prog='mx buildvms') parser.add_argument('--vms', help='a comma separated list of VMs to build (default: ' + vmsDefault + ')', metavar='', default=vmsDefault) parser.add_argument('--builds', help='a comma separated list of build types (default: ' + vmbuildsDefault + ')', metavar='', default=vmbuildsDefault) parser.add_argument('-n', '--no-check', action='store_true', help='omit running "java -version" after each build') @@ -897,7 +895,8 @@ start = time.time() mx.log('BEGIN: ' + v + '-' + vmbuild + '\t(see: ' + logFile + ')') # Run as subprocess so that output can be directed to a file - subprocess.check_call([sys.executable, '-u', join('mxtool', 'mx.py'), '--vm', v, '--vmbuild', vmbuild, 'build'], cwd=_graal_home, stdout=log, stderr=subprocess.STDOUT) + subprocess.check_call([sys.executable, '-u', join('mxtool', 'mx.py'), '--vm', v, '--vmbuild', + vmbuild, 'build'], cwd=_graal_home, stdout=log, stderr=subprocess.STDOUT) duration = datetime.timedelta(seconds=time.time() - start) mx.log('END: ' + v + '-' + vmbuild + '\t[' + str(duration) + ']') else: @@ -936,7 +935,7 @@ mx.abort(codeOrMessage) return self - parser = ArgumentParser(prog='mx gate'); + parser = ArgumentParser(prog='mx gate') parser.add_argument('-j', '--omit-java-clean', action='store_false', dest='cleanJava', help='omit cleaning Java native code') parser.add_argument('-n', '--omit-native-clean', action='store_false', dest='cleanNative', help='omit cleaning and building native code') parser.add_argument('-g', '--only-build-graalvm', action='store_false', dest='buildNonGraal', help='only build the Graal VM') @@ -945,7 +944,7 @@ args = parser.parse_args(args) global _jacoco - + tasks = [] total = Task('Gate') try: @@ -976,7 +975,7 @@ if mx.canonicalizeprojects([]) != 0: t.abort('Rerun "mx canonicalizeprojects" and check-in the modified mx/projects files.') tasks.append(t.stop()) - + t = Task('BuildJava') build(['--no-native', '--jdt-warning-as-error']) tasks.append(t.stop()) @@ -985,10 +984,10 @@ if mx.checkstyle([]) != 0: t.abort('Checkstyle warnings were found') tasks.append(t.stop()) - + if exists('jacoco.exec'): os.unlink('jacoco.exec') - + if args.jacocout is not None: _jacoco = 'append' else: @@ -1007,10 +1006,10 @@ t = Task('BootstrapWithGCVerification:product') vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version']) tasks.append(t.stop()) - + with VM('graal', 'product'): t = Task('BootstrapWithG1GCVerification:product') - vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:-UseSerialGC','-XX:+UseG1GC','-XX:+UseNewCode','-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version']) + vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:-UseSerialGC', '-XX:+UseG1GC', '-XX:+UseNewCode', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version']) tasks.append(t.stop()) with VM('graal', 'product'): @@ -1023,7 +1022,7 @@ vm(['-G:+AOTCompilation', '-G:+VerifyPhases', '-esa', '-version']) tasks.append(t.stop()) - with VM('server', 'product'): # hosted mode + with VM('server', 'product'): # hosted mode t = Task('UnitTests:hosted-product') unittest([]) tasks.append(t.stop()) @@ -1037,7 +1036,7 @@ if args.jacocout is not None: jacocoreport([args.jacocout]) - + _jacoco = 'off' t = Task('CleanAndBuildGraalVisualizer') @@ -1058,7 +1057,7 @@ t = Task('DaCapo_pmd:' + theVm + ':' + vmbuild) dacapo(['pmd']) tasks.append(t.stop()) - + t = Task('UnitTests:' + theVm + ':' + vmbuild) unittest(['-XX:CompileCommand=exclude,*::run*', 'graal.api']) tasks.append(t.stop()) @@ -1078,7 +1077,7 @@ mx.log(' ' + str(t.duration) + '\t' + t.title) mx.log(' =======') mx.log(' ' + str(total.duration)) - + def deoptalot(args): """bootstrap a fastdebug Graal VM with DeoptimizeALot and VerifyOops on @@ -1088,15 +1087,15 @@ if len(args) > 0 and args[0].isdigit(): count = int(args[0]) del args[0] - + for _ in range(count): if not vm(['-XX:+DeoptimizeALot', '-XX:+VerifyOops'] + args + ['-version'], vmbuild='fastdebug') == 0: mx.abort("Failed") - + def longtests(args): - + deoptalot(['15', '-Xmx48m']) - + dacapo(['100', 'eclipse', '-esa']) def gv(args): @@ -1131,7 +1130,7 @@ vm = _get_vm() if len(args) is 0: args = ['all'] - + vmArgs = [arg for arg in args if arg.startswith('-')] def benchmarks_in_group(group): @@ -1140,7 +1139,7 @@ results = {} benchmarks = [] - #DaCapo + # DaCapo if ('dacapo' in args or 'all' in args): benchmarks += sanitycheck.getDacapos(level=sanitycheck.SanityCheckLevel.Benchmark) else: @@ -1163,23 +1162,23 @@ if (iterations > 0): benchmarks += [sanitycheck.getScalaDacapo(scaladacapo, ['-n', str(iterations)])] - #Bootstrap + # Bootstrap if ('bootstrap' in args or 'all' in args): benchmarks += sanitycheck.getBootstraps() - #SPECjvm2008 + # SPECjvm2008 if ('specjvm2008' in args or 'all' in args): benchmarks += [sanitycheck.getSPECjvm2008(['-ikv', '-wt', '120', '-it', '120'])] else: specjvms = benchmarks_in_group('specjvm2008') for specjvm in specjvms: benchmarks += [sanitycheck.getSPECjvm2008(['-ikv', '-wt', '120', '-it', '120', specjvm])] - + if ('specjbb2005' in args or 'all' in args): benchmarks += [sanitycheck.getSPECjbb2005()] - - if ('specjbb2013' in args): # or 'all' in args //currently not in default set + + if ('specjbb2013' in args): # or 'all' in args //currently not in default set benchmarks += [sanitycheck.getSPECjbb2013()] - + if ('ctw-full' in args): benchmarks.append(sanitycheck.getCTW(vm, sanitycheck.CTWMode.Full)) if ('ctw-noinline' in args): @@ -1198,10 +1197,10 @@ def specjvm2008(args): """run one or more SPECjvm2008 benchmarks""" - + def launcher(bm, harnessArgs, extraVmOpts): return sanitycheck.getSPECjvm2008(harnessArgs + [bm]).bench(_get_vm(), extraVmOpts=extraVmOpts) - + availableBenchmarks = set(sanitycheck.specjvm2008Names) for name in sanitycheck.specjvm2008Names: parts = name.rsplit('.', 1) @@ -1212,23 +1211,23 @@ availableBenchmarks.add(group) _run_benchmark(args, sorted(availableBenchmarks), launcher) - + def specjbb2013(args): """runs the composite SPECjbb2013 benchmark""" - + def launcher(bm, harnessArgs, extraVmOpts): assert bm is None return sanitycheck.getSPECjbb2013(harnessArgs).bench(_get_vm(), extraVmOpts=extraVmOpts) - + _run_benchmark(args, None, launcher) def specjbb2005(args): """runs the composite SPECjbb2005 benchmark""" - + def launcher(bm, harnessArgs, extraVmOpts): assert bm is None return sanitycheck.getSPECjbb2005(harnessArgs).bench(_get_vm(), extraVmOpts=extraVmOpts) - + _run_benchmark(args, None, launcher) def hsdis(args, copyToDir=None): @@ -1252,17 +1251,17 @@ Run a tool over the input files to convert all embedded HexCodeFiles to a disassembled format.""" - parser = ArgumentParser(prog='mx hcfdis'); + parser = ArgumentParser(prog='mx hcfdis') parser.add_argument('-m', '--map', help='address to symbol map applied to disassembler output') parser.add_argument('files', nargs=REMAINDER, metavar='files...') args = parser.parse_args(args) - + path = join(_graal_home, 'lib', 'hcfdis-1.jar') if not exists(path): mx.download(path, ['http://lafo.ssw.uni-linz.ac.at/hcfdis-1.jar']) mx.run_java(['-jar', path] + args.files) - + if args.map is not None: addressRE = re.compile(r'0[xX]([A-Fa-f0-9]+)') with open(args.map) as fp: @@ -1271,8 +1270,8 @@ for l in lines: addressAndSymbol = l.split(' ', 1) if len(addressAndSymbol) == 2: - address, symbol = addressAndSymbol; - if address.startswith('0x'): + address, symbol = addressAndSymbol + if address.startswith('0x'): address = long(address, 16) symbols[address] = symbol for f in args.files: @@ -1358,11 +1357,11 @@ mx.add_argument('--vmcwd', dest='vm_cwd', help='current directory will be changed to before the VM is executed', default=None, metavar='') mx.add_argument('--installed-jdks', help='the base directory in which the JDKs cloned from $JAVA_HOME exist. ' + 'The VM selected by --vm and --vmbuild options is under this directory (i.e., ' + - join('', '', 'jre', 'lib', '', mx.add_lib_prefix(mx.add_lib_suffix('jvm'))) + ')', default=None, metavar='') + join('', '', '', 'jre', 'lib', '', mx.add_lib_prefix(mx.add_lib_suffix('jvm'))) + ')', default=None, metavar='') if (_vmSourcesAvailable): mx.add_argument('--vm', action='store', dest='vm', choices=_vmChoices.keys(), help='the VM type to build/run') - mx.add_argument('--vmbuild', action='store', dest='vmbuild', choices=_vmbuildChoices, help='the VM build to build/run (default: ' + _vmbuildChoices[0] +')') + mx.add_argument('--vmbuild', action='store', dest='vmbuild', choices=_vmbuildChoices, help='the VM build to build/run (default: ' + _vmbuildChoices[0] + ')') mx.add_argument('--ecl', action='store_true', dest='make_eclipse_launch', help='create launch configuration for running VM execution(s) in Eclipse') mx.add_argument('--vmprefix', action='store', dest='vm_prefix', help='prefix for running the VM (e.g. "/usr/bin/gdb --args")', metavar='') mx.add_argument('--gdb', action='store_const', const='/usr/bin/gdb --args', dest='vm_prefix', help='alias for --vmprefix "/usr/bin/gdb --args"') @@ -1371,9 +1370,9 @@ 'export': [export, '[-options] [zipfile]'], }) - mx.commands.update(commands) + mx._commands.update(commands) -def mx_post_parse_cmd_line(opts):# +def mx_post_parse_cmd_line(opts): # # TODO _minVersion check could probably be part of a Suite in mx? if (mx.java().version < _minVersion) : mx.abort('Requires Java version ' + str(_minVersion) + ' or greater, got version ' + str(mx.java().version)) diff -r 20b642493616 -r 1f03076a121b mx/outputparser.py --- a/mx/outputparser.py Tue Sep 03 14:09:35 2013 -0700 +++ b/mx/outputparser.py Tue Sep 03 14:09:56 2013 -0700 @@ -26,13 +26,13 @@ import re class OutputParser: - + def __init__(self): self.matchers = [] - + def addMatcher(self, matcher): self.matchers.append(matcher) - + def parse(self, output): valueMaps = [] for matcher in self.matchers: @@ -47,12 +47,12 @@ given as the group name enclosed in '<' and '>'. """ class ValuesMatcher: - + def __init__(self, regex, valuesTemplate): assert isinstance(valuesTemplate, dict) self.regex = regex self.valuesTemplate = valuesTemplate - + def parse(self, text, valueMaps): for match in self.regex.finditer(text): valueMap = {} @@ -62,10 +62,10 @@ assert not valueMap.has_key(key), key valueMap[key] = value valueMaps.append(valueMap) - + def get_template_value(self, match, template): def replace_var(m): groupName = m.group(1) return match.group(groupName) - + return re.sub(r'<([\w]+)>', replace_var, template) diff -r 20b642493616 -r 1f03076a121b mx/projects --- a/mx/projects Tue Sep 03 14:09:35 2013 -0700 +++ b/mx/projects Tue Sep 03 14:09:56 2013 -0700 @@ -288,7 +288,7 @@ # graal.nodes project@com.oracle.graal.nodes@subDir=graal project@com.oracle.graal.nodes@sourceDirs=src -project@com.oracle.graal.nodes@dependencies=com.oracle.graal.api.code,com.oracle.graal.graph,com.oracle.graal.debug,com.oracle.graal.api.replacements +project@com.oracle.graal.nodes@dependencies=com.oracle.graal.graph,com.oracle.graal.debug,com.oracle.graal.api.replacements,com.oracle.graal.api.code project@com.oracle.graal.nodes@checkstyle=com.oracle.graal.graph project@com.oracle.graal.nodes@javaCompliance=1.7 project@com.oracle.graal.nodes@workingSets=Graal,Graph diff -r 20b642493616 -r 1f03076a121b mx/sanitycheck.py --- a/mx/sanitycheck.py Tue Sep 03 14:09:35 2013 -0700 +++ b/mx/sanitycheck.py Tue Sep 03 14:09:56 2013 -0700 @@ -27,31 +27,31 @@ import re, mx, commands, os, sys, StringIO, subprocess from os.path import isfile, join, exists -gc='UseSerialGC' +gc = 'UseSerialGC' dacapoSanityWarmup = { - 'avrora': [0, 0, 3, 6, 13], - 'batik': [0, 0, 5, 5, 20], - 'eclipse': [2, 4, 5, 10, 16], + 'avrora': [0, 0, 3, 6, 13], + 'batik': [0, 0, 5, 5, 20], + 'eclipse': [2, 4, 5, 10, 16], 'fop': [4, 8, 10, 20, 30], - 'h2': [0, 0, 5, 5, 8], - 'jython': [0, 0, 5, 10, 13], - 'luindex': [0, 0, 5, 10, 10], - 'lusearch': [0, 4, 5, 5, 8], - 'pmd': [0, 0, 5, 10, 13], - 'sunflow': [0, 2, 5, 10, 15], - 'tomcat': [0, 0, 5, 10, 15], - 'tradebeans': [0, 0, 5, 10, 13], - 'tradesoap': [2, 4, 5, 10, 15], - 'xalan': [0, 0, 5, 10, 18], + 'h2': [0, 0, 5, 5, 8], + 'jython': [0, 0, 5, 10, 13], + 'luindex': [0, 0, 5, 10, 10], + 'lusearch': [0, 4, 5, 5, 8], + 'pmd': [0, 0, 5, 10, 13], + 'sunflow': [0, 2, 5, 10, 15], + 'tomcat': [0, 0, 5, 10, 15], + 'tradebeans': [0, 0, 5, 10, 13], + 'tradesoap': [2, 4, 5, 10, 15], + 'xalan': [0, 0, 5, 10, 18], } dacapoScalaSanityWarmup = { # (tw) actors sometimes fails verification; hardly reproducible - 'actors': [0, 0, 0, 0, 0], + 'actors': [0, 0, 0, 0, 0], # (lstadler) apparat was disabled due to a deadlock which I think is the benchmarks fault. - 'apparat': [0, 0, 0, 0, 0], - 'factorie': [0, 0, 2, 5, 5], + 'apparat': [0, 0, 0, 0, 0], + 'factorie': [0, 0, 2, 5, 5], 'kiama': [0, 0, 3, 13, 15], 'scalac': [0, 0, 5, 15, 20], 'scaladoc': [0, 0, 5, 15, 15], @@ -59,8 +59,8 @@ 'scalariform':[0, 0, 6, 15, 20], 'scalatest': [0, 0, 2, 10, 12], 'scalaxb': [0, 0, 5, 15, 25], -#(gdub) specs sometimes returns a non-zero value event though there is no apparent failure - 'specs': [0, 0, 0, 0, 0], +# (gdub) specs sometimes returns a non-zero value event though there is no apparent failure + 'specs': [0, 0, 0, 0, 0], 'tmt': [0, 0, 3, 10, 12] } @@ -137,60 +137,68 @@ 'xml.validation' ] +def _noneAsEmptyList(a): + if a is None: + return [] + return a + class SanityCheckLevel: Fast, Gate, Normal, Extensive, Benchmark = range(5) - -def getSPECjbb2005(benchArgs = []): - + +def getSPECjbb2005(benchArgs=None): + benchArgs = [] if benchArgs is None else benchArgs + specjbb2005 = mx.get_env('SPECJBB2005') if specjbb2005 is None or not exists(join(specjbb2005, 'jbb.jar')): mx.abort('Please set the SPECJBB2005 environment variable to a SPECjbb2005 directory') - + score = re.compile(r"^Valid run, Score is (?P[0-9]+)$", re.MULTILINE) error = re.compile(r"VALIDATION ERROR") success = re.compile(r"^Valid run, Score is [0-9]+$", re.MULTILINE) matcher = ValuesMatcher(score, {'group' : 'SPECjbb2005', 'name' : 'score', 'score' : ''}) classpath = ['jbb.jar', 'check.jar'] - return Test("SPECjbb2005", ['spec.jbb.JBBmain', '-propfile', 'SPECjbb.props'] + benchArgs, [success], [error], [matcher], vmOpts=['-Xms3g', '-XX:+'+gc, '-XX:-UseCompressedOops', '-cp', os.pathsep.join(classpath)], defaultCwd=specjbb2005) + return Test("SPECjbb2005", ['spec.jbb.JBBmain', '-propfile', 'SPECjbb.props'] + benchArgs, [success], [error], [matcher], vmOpts=['-Xms3g', '-XX:+' + gc, '-XX:-UseCompressedOops', '-cp', os.pathsep.join(classpath)], defaultCwd=specjbb2005) -def getSPECjbb2013(benchArgs = []): - +def getSPECjbb2013(benchArgs=None): + specjbb2013 = mx.get_env('SPECJBB2013') if specjbb2013 is None or not exists(join(specjbb2013, 'specjbb2013.jar')): mx.abort('Please set the SPECJBB2013 environment variable to a SPECjbb2013 directory') - + jops = re.compile(r"^RUN RESULT: hbIR \(max attempted\) = [0-9]+, hbIR \(settled\) = [0-9]+, max-jOPS = (?P[0-9]+), critical-jOPS = (?P[0-9]+)$", re.MULTILINE) - #error? + # error? success = re.compile(r"org.spec.jbb.controller: Run finished", re.MULTILINE) matcherMax = ValuesMatcher(jops, {'group' : 'SPECjbb2013', 'name' : 'max', 'score' : ''}) matcherCritical = ValuesMatcher(jops, {'group' : 'SPECjbb2013', 'name' : 'critical', 'score' : ''}) - return Test("SPECjbb2013", ['-jar', 'specjbb2013.jar', '-m', 'composite'] + benchArgs, [success], [], [matcherCritical, matcherMax], vmOpts=['-Xmx6g', '-Xms6g', '-Xmn3g', '-XX:+UseParallelOldGC', '-XX:-UseAdaptiveSizePolicy', '-XX:-UseBiasedLocking', '-XX:-UseCompressedOops'], defaultCwd=specjbb2013) - -def getSPECjvm2008(benchArgs=[]): - + return Test("SPECjbb2013", ['-jar', 'specjbb2013.jar', '-m', 'composite'] + + _noneAsEmptyList(benchArgs), [success], [], [matcherCritical, matcherMax], + vmOpts=['-Xmx6g', '-Xms6g', '-Xmn3g', '-XX:+UseParallelOldGC', '-XX:-UseAdaptiveSizePolicy', '-XX:-UseBiasedLocking', '-XX:-UseCompressedOops'], defaultCwd=specjbb2013) + +def getSPECjvm2008(benchArgs=None): + specjvm2008 = mx.get_env('SPECJVM2008') if specjvm2008 is None or not exists(join(specjvm2008, 'SPECjvm2008.jar')): mx.abort('Please set the SPECJVM2008 environment variable to a SPECjvm2008 directory') - + score = re.compile(r"^(Score on|Noncompliant) (?P[a-zA-Z0-9\._]+)( result)?: (?P[0-9]+((,|\.)[0-9]+)?)( SPECjvm2008 Base)? ops/m$", re.MULTILINE) error = re.compile(r"^Errors in benchmark: ", re.MULTILINE) # The ' ops/m' at the end of the success string is important : it's how you can tell valid and invalid runs apart success = re.compile(r"^(Noncompliant c|C)omposite result: [0-9]+((,|\.)[0-9]+)?( SPECjvm2008 (Base|Peak))? ops/m$", re.MULTILINE) matcher = ValuesMatcher(score, {'group' : 'SPECjvm2008', 'name' : '', 'score' : ''}) - - return Test("SPECjvm2008", ['-jar', 'SPECjvm2008.jar'] + benchArgs, [success], [error], [matcher], vmOpts=['-Xms3g', '-XX:+'+gc, '-XX:-UseCompressedOops'], defaultCwd=specjvm2008) + + return Test("SPECjvm2008", ['-jar', 'SPECjvm2008.jar'] + _noneAsEmptyList(benchArgs), [success], [error], [matcher], vmOpts=['-Xms3g', '-XX:+' + gc, '-XX:-UseCompressedOops'], defaultCwd=specjvm2008) -def getDacapos(level=SanityCheckLevel.Normal, gateBuildLevel=None, dacapoArgs=[]): +def getDacapos(level=SanityCheckLevel.Normal, gateBuildLevel=None, dacapoArgs=None): checks = [] - + for (bench, ns) in dacapoSanityWarmup.items(): if ns[level] > 0: if gateBuildLevel is None or gateBuildLevel in dacapoGateBuildLevels[bench]: - checks.append(getDacapo(bench, ['-n', str(ns[level])] + dacapoArgs)) - + checks.append(getDacapo(bench, ['-n', str(ns[level])] + _noneAsEmptyList(dacapoArgs))) + return checks -def getDacapo(name, dacapoArgs=[]): +def getDacapo(name, dacapoArgs=None): dacapo = mx.get_env('DACAPO_CP') if dacapo is None: l = mx.library('DACAPO', False) @@ -198,31 +206,31 @@ dacapo = l.get_path(True) else: mx.abort('DaCapo 9.12 jar file must be specified with DACAPO_CP environment variable or as DACAPO library') - + if not isfile(dacapo) or not dacapo.endswith('.jar'): mx.abort('Specified DaCapo jar file does not exist or is not a jar file: ' + dacapo) - + dacapoSuccess = re.compile(r"^===== DaCapo 9\.12 ([a-zA-Z0-9_]+) PASSED in ([0-9]+) msec =====$", re.MULTILINE) dacapoFail = re.compile(r"^===== DaCapo 9\.12 ([a-zA-Z0-9_]+) FAILED (warmup|) =====$", re.MULTILINE) dacapoTime = re.compile(r"===== DaCapo 9\.12 (?P[a-zA-Z0-9_]+) PASSED in (?P