# HG changeset patch # User Christian Humer # Date 1378477036 -7200 # Node ID cefd4cb3cb2de4600442101b229ccf843939f005 # Parent f1c3f50ac36e94c231acaa895231faa4f974a5d9# Parent edf875b3c091f3f0f368689fc402c50cfcab0900 Merge. diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Fri Sep 06 16:17:16 2013 +0200 @@ -594,6 +594,7 @@ "getDeclaredMethods", "getDeclaredConstructors", "isInitialized", + "isLinked", "getEncoding", "hasFinalizableSubclass", "hasFinalizer", diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Fri Sep 06 16:17:16 2013 +0200 @@ -34,9 +34,14 @@ /** * Returns the bytecode of this method, if the method has code. The returned byte array does not - * contain breakpoints or non-Java bytecodes. + * contain breakpoints or non-Java bytecodes. This may return null if the + * {@link #getDeclaringClass() holder} is not {@link ResolvedJavaType#isLinked() linked}. * - * @return the bytecode of the method, or {@code null} if {@code getCodeSize() == 0} + * The contained constant pool indices may not be the ones found in the original class file but + * they can be used with the Graal API (e.g. methods in {@link ConstantPool}). + * + * @return the bytecode of the method, or {@code null} if {@code getCodeSize() == 0} or if the + * code is not ready. */ byte[] getCode(); diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Fri Sep 06 16:17:16 2013 +0200 @@ -112,7 +112,8 @@ int getModifiers(); /** - * Checks whether this type is initialized. + * Checks whether this type is initialized. If a type is initialized it implies that is was + * {@link #isLinked() linked} and that the static initializer has run. * * @return {@code true} if this type is initialized */ @@ -124,6 +125,14 @@ void initialize(); /** + * Checks whether this type is linked and verified. When a type is linked the static initializer + * has not necessarily run. An {@link #isInitialized() initialized} type is always linked. + * + * @return {@code true} if this type is linked + */ + boolean isLinked(); + + /** * Determines if this type is either the same as, or is a superclass or superinterface of, the * type represented by the specified parameter. This method is identical to * {@link Class#isAssignableFrom(Class)} in terms of the value return for this type. diff -r f1c3f50ac36e -r cefd4cb3cb2d 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 Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Fri Sep 06 16:17:16 2013 +0200 @@ -272,69 +272,69 @@ } public final void ld_global_b8(Register d, Register a, long immOff) { - emitString("ld.global.b8" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.b8" + " " + "%r" + d.encoding() + ", [" + a + " + " + immOff + "]" + ";" + ""); } public final void ld_global_b16(Register d, Register a, long immOff) { - emitString("ld.global.b16" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.b16" + " " + "%r" + d.encoding() + ", [" + a + " + " + immOff + "]" + ";" + ""); } public final void ld_global_b32(Register d, Register a, long immOff) { - emitString("ld.global.b32" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.b32" + " " + "%r" + d.encoding() + ", [" + a + " + " + immOff + "]" + ";" + ""); } public final void ld_global_b64(Register d, Register a, long immOff) { - emitString("ld.global.b64" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.b64" + " " + "%r" + d.encoding() + ", [" + a + " + " + immOff + "]" + ";" + ""); } public final void ld_global_u8(Register d, Register a, long immOff) { - emitString("ld.global.u8" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.u8" + " " + "%r" + d.encoding() + ", [" + a + " + " + immOff + "]" + ";" + ""); } public final void ld_global_u16(Register d, Register a, long immOff) { - emitString("ld.global.u16" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.u16" + " " + "%r" + d.encoding() + ", [" + a + " + " + immOff + "]" + ";" + ""); } public final void ld_global_u32(Register d, Register a, long immOff) { - emitString("ld.global.u32" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.u32" + " " + "%r" + d.encoding() + ", [" + a + " + " + immOff + "]" + ";" + ""); } public final void ld_global_u64(Register d, Register a, long immOff) { - emitString("ld.global.u64" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.u64" + " " + "%r" + d.encoding() + ", [" + a + " + " + immOff + "]" + ";" + ""); } public final void ld_global_s8(Register d, Register a, long immOff) { - emitString("ld.global.s8" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.s8" + " " + "%r" + d.encoding() + ", [" + a + " + " + immOff + "]" + ";" + ""); } public final void ld_global_s16(Register d, Register a, long immOff) { - emitString("ld.global.s16" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.s16" + " " + "%r" + d.encoding() + ", [" + a + " + " + immOff + "]" + ";" + ""); } public final void ld_global_s32(Register d, Register a, long immOff) { - emitString("ld.global.s32" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.s32" + " " + "%r" + d.encoding() + ", [" + a + " + " + immOff + "]" + ";" + ""); } public final void ld_global_s64(Register d, Register a, long immOff) { - emitString("ld.global.s64" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.s64" + " " + "%r" + d.encoding() + ", [" + a + " + " + immOff + "]" + ";" + ""); } public final void ld_global_f32(Register d, Register a, long immOff) { - emitString("ld.global.f32" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.f32" + " " + "%r" + d.encoding() + ", [" + a + " + " + immOff + "]" + ";" + ""); } public final void ld_global_f64(Register d, Register a, long immOff) { - emitString("ld.global.f64" + " " + "%r" + d.encoding() + ", [" + a.toString() + " + " + immOff + "]" + ";" + ""); + emitString("ld.global.f64" + " " + "%r" + d.encoding() + ", [" + a + " + " + 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 + "]" + ";" + ""); + emitString("ld" + s + " " + "%r" + d.encoding() + ", [" + a + " + " + 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 + "]" + ";" + ""); + emitString("ld.param." + s + " " + "%r" + d.encoding() + ", [" + a + " + " + immOff + "]" + ";" + ""); } public final void mov_b16(Register d, Register a) { @@ -429,68 +429,68 @@ emitString("mov.f64" + " " + "%r" + d.encoding() + ", " + f64 + ";" + ""); } - public final void mul_f32(Register d, Register a, Register b) { - emitString("mul.f32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); + public final void mul_lo_f32(Register d, Register a, Register b) { + emitString("mul.lo.f32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); } - public final void mul_f64(Register d, Register a, Register b) { - emitString("smul.f64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); + public final void mul_lo_f64(Register d, Register a, Register b) { + emitString("mul.lo.f64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); } - public final void mul_s16(Register d, Register a, Register b) { - emitString("mul.s16" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); + public final void mul_lo_s16(Register d, Register a, Register b) { + emitString("mul.lo.s16" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); } - public final void mul_s32(Register d, Register a, Register b) { - emitString("mul.s32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); + public final void mul_lo_s32(Register d, Register a, Register b) { + emitString("mul.lo.s32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); } - public final void mul_s64(Register d, Register a, Register b) { - emitString("mul.s64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); + public final void mul_lo_s64(Register d, Register a, Register b) { + emitString("mul.lo.s64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); } - public final void mul_s16(Register d, Register a, short s16) { - emitString("mul.s16" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + s16 + ";" + ""); + public final void mul_lo_s16(Register d, Register a, short s16) { + emitString("mul.lo.s16" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + s16 + ";" + ""); } - public final void mul_s32(Register d, Register a, int s32) { - emitString("mul.s32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + s32 + ";" + ""); + public final void mul_lo_s32(Register d, Register a, int s32) { + emitString("mul.lo.s32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + s32 + ";" + ""); } - public final void mul_s64(Register d, Register a, long s64) { - emitString("mul.s64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + s64 + ";" + ""); + public final void mul_lo_s64(Register d, Register a, long s64) { + emitString("mul.lo.s64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + s64 + ";" + ""); } - public final void mul_f32(Register d, Register a, float f32) { - emitString("mul.f32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + f32 + ";" + ""); + public final void mul_lo_f32(Register d, Register a, float f32) { + emitString("mul.lo.f32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + f32 + ";" + ""); } - public final void mul_f64(Register d, Register a, double f64) { - emitString("mul.f64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + f64 + ";" + ""); + public final void mul_lo_f64(Register d, Register a, double f64) { + emitString("mul.lo.f64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + f64 + ";" + ""); } - public final void mul_u16(Register d, Register a, Register b) { - emitString("mul.u16" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); + public final void mul_lo_u16(Register d, Register a, Register b) { + emitString("mul.lo.u16" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); } - public final void mul_u32(Register d, Register a, Register b) { - emitString("mul.u32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); + public final void mul_lo_u32(Register d, Register a, Register b) { + emitString("mul.lo.u32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); } - public final void mul_u64(Register d, Register a, Register b) { - emitString("mul.u64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); + public final void mul_lo_u64(Register d, Register a, Register b) { + emitString("mul.lo.u64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); } - public final void mul_u16(Register d, Register a, short u16) { - emitString("mul.u16" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + u16 + ";" + ""); + public final void mul_lo_u16(Register d, Register a, short u16) { + emitString("mul.lo.u16" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + u16 + ";" + ""); } - public final void mul_u32(Register d, Register a, int u32) { - emitString("mul.u32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + u32 + ";" + ""); + public final void mul_lo_u32(Register d, Register a, int u32) { + emitString("mul.lo.u32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + u32 + ";" + ""); } - public final void mul_u64(Register d, Register a, long u64) { - emitString("mul.u64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + u64 + ";" + ""); + public final void mul_lo_u64(Register d, Register a, long u64) { + emitString("mul.lo.u64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + u64 + ";" + ""); } public final void neg_f32(Register d, Register a) { @@ -550,15 +550,15 @@ } public final void param_8_decl(Register d, boolean lastParam) { - emitString(".param" + " " + ".s8" + " " + d.toString() + (lastParam ? "" : ",")); + emitString(".param" + " " + ".s8" + " " + d + (lastParam ? "" : ",")); } public final void param_32_decl(Register d, boolean lastParam) { - emitString(".param" + " " + ".s32" + " " + d.toString() + (lastParam ? "" : ",")); + emitString(".param" + " " + ".s32" + " " + d + (lastParam ? "" : ",")); } public final void param_64_decl(Register d, boolean lastParam) { - emitString(".param" + " " + ".s64" + " " + d.toString() + (lastParam ? "" : ",")); + emitString(".param" + " " + ".s64" + " " + d + (lastParam ? "" : ",")); } public final void popc_b32(Register d, Register a) { @@ -849,54 +849,32 @@ emitString("setp.ge.u32" + " " + "%p" + ", " + u32 + ", %r" + b.encoding() + ";" + ""); } - public final void shl_s16(Register d, Register a, Register b) { - emitString("shl.s16" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); - } - - public final void shl_s32(Register d, Register a, Register b) { - emitString("shl.s32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); + // Shift left - only types supported are .b16, .b32 and .b64 + public final void shl_b16(Register d, Register a, Register b) { + emitString("shl.b16" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); } - public final void shl_s64(Register d, Register a, Register b) { - emitString("shl.s64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); + public final void shl_b32(Register d, Register a, Register b) { + emitString("shl.b32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); } - public final void shl_s16(Register d, Register a, int u32) { - emitString("shl.s16" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + u32 + ";" + ""); - } - - public final void shl_s32(Register d, Register a, int u32) { - emitString("shl.s32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + u32 + ";" + ""); - } - - public final void shl_s64(Register d, Register a, int u32) { - emitString("shl.s64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + u32 + ";" + ""); + public final void shl_b64(Register d, Register a, Register b) { + emitString("shl.b64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); } - public final void shl_u16(Register d, Register a, Register b) { - emitString("shl.u16" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); - } - - public final void shl_u32(Register d, Register a, Register b) { - emitString("shl.u32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); - } - - public final void shl_u64(Register d, Register a, Register b) { - emitString("shl.u64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); + public final void shl_b16_const(Register d, Register a, int b) { + emitString("shl.b16" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + b + ";" + ""); } - public final void shl_u16(Register d, Register a, int u32) { - emitString("shl.u16" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + u32 + ";" + ""); + public final void shl_b32_const(Register d, Register a, int b) { + emitString("shl.b32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + b + ";" + ""); } - public final void shl_u32(Register d, Register a, int u32) { - emitString("shl.u32" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + u32 + ";" + ""); + public final void shl_b64_const(Register d, Register a, int b) { + emitString("shl.b64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + b + ";" + ""); } - public final void shl_u64(Register d, Register a, int u32) { - emitString("shl.u64" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", " + u32 + ";" + ""); - } - + // Shift Right instruction public final void shr_s16(Register d, Register a, Register b) { emitString("shr.s16" + " " + "%r" + d.encoding() + ", %r" + a.encoding() + ", %r" + b.encoding() + ";" + ""); } diff -r f1c3f50ac36e -r cefd4cb3cb2d 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 Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java Fri Sep 06 16:17:16 2013 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.compiler.ptx.test; -import org.junit.Test; +import org.junit.*; import java.lang.reflect.Method; @@ -32,10 +32,19 @@ @Test public void testAdd() { + Integer r4 = (Integer) invoke(compile("testAdd2I"), 18, 24); + if (r4 == null) { + printReport("testAdd2I FAILED"); + } else if (r4.intValue() == testAdd2I(18, 24)) { + printReport("testAdd2I PASSED"); + } else { + printReport("testAdd2I FAILED"); + } + Long r2 = (Long) invoke(compile("testAdd2L"), (long) 12, (long) 6); if (r2 == null) { printReport("testAdd2L FAILED"); - } else if (r2.longValue() == 18) { + } else if (r2.longValue() == testAdd2L(12, 6)) { printReport("testAdd2L PASSED"); } else { printReport("testAdd2L FAILED"); @@ -43,10 +52,10 @@ //invoke(compile("testAdd2B"), (byte) 6, (byte) 4); - Integer r4 = (Integer) invoke(compile("testAddIConst"), 5); + r4 = (Integer) invoke(compile("testAddIConst"), 5); if (r4 == null) { printReport("testAddIConst FAILED"); - } else if (r4.intValue() == 37) { + } else if (r4.intValue() == testAddIConst(5)) { printReport("testAddIConst PASSED"); } else { printReport("testAddIConst FAILED"); @@ -55,20 +64,12 @@ r4 = (Integer) invoke(compile("testAddConstI"), 7); if (r4 == null) { printReport("testAddConstI FAILED"); - } else if (r4.intValue() == 39) { + } else if (r4.intValue() == testAddConstI(7)) { 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) { @@ -93,20 +94,21 @@ @Test public void testSub() { - Long r2 = (Long) invoke(compile("testSub2L"), (long) 12, (long) 6); - if (r2 == null) { - printReport("testSub2I FAILED (null return value)"); - } else if (r2.longValue() == 6) { + + Integer r1 = (Integer) invoke(compile("testSub2I"), 18, 4); + + if (r1 == null) { + printReport("testSub2I FAILED"); + } else if (r1.intValue() == testSub2I(18, 4)) { 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) { + Long r2 = (Long) invoke(compile("testSub2L"), (long) 12, (long) 6); + if (r2 == null) { + printReport("testSub2I FAILED (null return value)"); + } else if (r2.longValue() == testSub2L(12, 6)) { printReport("testSub2I PASSED"); } else { printReport("testSub2I FAILED"); @@ -115,7 +117,7 @@ r1 = (Integer) invoke(compile("testSubIConst"), 35); if (r1 == null) { printReport("testSubIConst FAILED"); - } else if (r1.intValue() == 3) { + } else if (r1.intValue() == testSubIConst(35)) { printReport("testSubIConst PASSED"); } else { printReport("testSubIConst FAILED"); @@ -124,7 +126,7 @@ r1 = (Integer) invoke(compile("testSubConstI"), 12); if (r1 == null) { printReport("testSubConstI FAILED"); - } else if (r1.intValue() == 20) { + } else if (r1.intValue() == testSubConstI(12)) { printReport("testSubConstI PASSED"); } else { printReport("testSubConstI FAILED"); @@ -149,10 +151,42 @@ @Test public void testMul() { - invoke(compile("testMul2I"), 8, 4); - invoke(compile("testMul2L"), (long) 12, (long) 6); - invoke(compile("testMulIConst"), 4); - invoke(compile("testMulConstI"), 5); + + Integer r1 = (Integer) invoke(compile("testMul2I"), 8, 4); + if (r1 == null) { + printReport("testMul2I FAILED"); + } else if (r1.intValue() == testMul2I(8, 4)) { + printReport("testMul2I PASSED"); + } else { + printReport("testMul2I FAILED"); + } + + Long r2 = (Long) invoke(compile("testMul2L"), (long) 12, (long) 6); + if (r2 == null) { + printReport("testMul2L FAILED"); + } else if (r2.longValue() == testMul2L(12, 6)) { + printReport("testMul2L PASSED"); + } else { + printReport("testMul2L FAILED"); + } + + r1 = (Integer) invoke(compile("testMulIConst"), 4); + if (r1 == null) { + printReport("testMulIConst FAILED"); + } else if (r1.intValue() == testMulIConst(4)) { + printReport("testMulIConst PASSED"); + } else { + printReport("testMulIConst FAILED"); + } + + r1 = (Integer) invoke(compile("testMulConstI"), 5); + if (r1 == null) { + printReport("testMulConstI FAILED"); + } else if (r1.intValue() == testMulConstI(5)) { + printReport("testMulConstI PASSED"); + } else { + printReport("testMulConstI FAILED"); + } } public static int testMul2I(int a, int b) { @@ -170,12 +204,44 @@ public static int testMulConstI(int a) { return 32 * a; } + @Test public void testDiv() { - invoke(compile("testDiv2I"), 8, 4); - invoke(compile("testDiv2L"), (long) 12, (long) 6); - invoke(compile("testDivIConst"), 64); - invoke(compile("testDivConstI"), 8); + Integer r1 = (Integer) invoke(compile("testDiv2I"), 8, 4); + if (r1 == null) { + printReport("testDiv2I FAILED (null value returned)"); + } else if (r1.intValue() == testDiv2I(8, 4)) { + printReport("testDiv2I PASSED"); + } else { + printReport("testDiv2I FAILED"); + } + + Long r2 = (Long) invoke(compile("testDiv2L"), (long) 12, (long) 6); + if (r2 == null) { + printReport("testDiv2L FAILED (null value returned)"); + } else if (r2.longValue() == testDiv2L(12, 6)) { + printReport("testDiv2L PASSED"); + } else { + printReport("testDiv2L FAILED"); + } + + r1 = (Integer) invoke(compile("testDivIConst"), 64); + if (r1 == null) { + printReport("testDivIConst FAILED (null value returned)"); + } else if (r1.intValue() == testDivIConst(64)) { + printReport("testDivIConst PASSED"); + } else { + printReport("testDivIConst FAILED"); + } + + r1 = (Integer) invoke(compile("testDivConstI"), 8); + if (r1 == null) { + printReport("testDivConstI FAILED (null value returned)"); + } else if (r1.intValue() == testDivConstI(8)) { + printReport("testDivConstI PASSED"); + } else { + printReport("testDivConstI FAILED"); + } } public static int testDiv2I(int a, int b) { @@ -196,8 +262,23 @@ @Test public void testRem() { - invoke(compile("testRem2I"), 8, 4); - invoke(compile("testRem2L"), (long) 12, (long) 6); + Integer r1 = (Integer) invoke(compile("testRem2I"), 8, 4); + if (r1 == null) { + printReport("testRem2I FAILED (null value returned)"); + } else if (r1.intValue() == testRem2I(8, 4)) { + printReport("testRem2I PASSED"); + } else { + printReport("testRem2I FAILED"); + } + + Long r2 = (Long) invoke(compile("testRem2L"), (long) 12, (long) 6); + if (r2 == null) { + printReport("testRem2L FAILED (null value returned)"); + } else if (r1.longValue() == testRem2L(12, 6)) { + printReport("testRem2L PASSED"); + } else { + printReport("testRem2L FAILED"); + } } public static int testRem2I(int a, int b) { @@ -207,11 +288,27 @@ public static long testRem2L(long a, long b) { return a % b; } - + @Ignore @Test public void testIntConversion() { - invoke(compile("testI2L"), 8); - invoke(compile("testL2I"), (long) 12); + Long r1 = (Long) invoke(compile("testI2L"), 8); + if (r1 == null) { + printReport("testI2L FAILED (null value returned)"); + } else if (r1.longValue() == testI2L(8)) { + printReport("testI2L PASSED"); + } else { + printReport("testI2L FAILED"); + } + + Integer r2 = (Integer) invoke(compile("testL2I"), (long) 12); + if (r2 == null) { + printReport("testL2I FAILED (null value returned)"); + } else if (r1.longValue() == testL2I(12)) { + printReport("testL2I PASSED"); + } else { + printReport("testL2I FAILED"); + } + // invoke(compile("testI2C"), 65); // invoke(compile("testI2B"), 9); // invoke(compile("testI2F"), 17); diff -r f1c3f50ac36e -r cefd4cb3cb2d 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 Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java Fri Sep 06 16:17:16 2013 +0200 @@ -174,7 +174,7 @@ } for (Integer i : signed32) { - codeBuffer.emitString(" .reg .s32 %r" + i.intValue() + ";"); + codeBuffer.emitString(".reg .s32 %r" + i.intValue() + ";"); } for (Integer i : signed64) { codeBuffer.emitString(".reg .s64 %r" + i.intValue() + ";"); diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Fri Sep 06 16:17:16 2013 +0200 @@ -686,9 +686,8 @@ List instructions = ir.lir(block); int numInst = instructions.size(); - // iterate all instructions of the block. skip the first because it is always a label - assert !instructions.get(0).hasOperands() : "first operation must always be a label"; - for (int j = 1; j < numInst; j++) { + // iterate all instructions of the block + for (int j = 0; j < numInst; j++) { final LIRInstruction op = instructions.get(j); ValueProcedure useProc = new ValueProcedure() { @@ -1174,10 +1173,8 @@ } // iterate all instructions of the block in reverse order. - // skip the first instruction because it is always a label // definitions of intervals are processed before uses - assert !instructions.get(0).hasOperands() : "first operation must always be a label"; - for (int j = instructions.size() - 1; j >= 1; j--) { + for (int j = instructions.size() - 1; j >= 0; j--) { final LIRInstruction op = instructions.get(j); final int opId = op.id(); diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri Sep 06 16:17:16 2013 +0200 @@ -40,7 +40,6 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.JumpOp; import com.oracle.graal.lir.StandardOp.LabelOp; -import com.oracle.graal.lir.StandardOp.ParametersOp; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; @@ -405,7 +404,7 @@ } public void emitIncomingValues(Value[] params) { - append(new ParametersOp(params)); + ((LabelOp) lir.lir(currentBlock).get(0)).setIncomingValues(params); } @Override diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Fri Sep 06 16:17:16 2013 +0200 @@ -40,6 +40,16 @@ private final ArrayList nodes; + /** + * Records the modification count for nodes. This is only used in assertions. + */ + private int[] nodeModCounts; + + /** + * Records the modification count for nodes' usage lists. This is only used in assertions. + */ + private int[] nodeUsageModCounts; + // these two arrays contain one entry for each NodeClass, indexed by NodeClass.iterableId. // they contain the first and last pointer to a linked list of all nodes with this type. private final ArrayList nodeCacheFirst; @@ -87,6 +97,18 @@ this(null); } + static final boolean MODIFICATION_COUNTS_ENABLED = assertionsEnabled(); + + /** + * Determines if assertions are enabled for the {@link Graph} class. + */ + @SuppressWarnings("all") + private static boolean assertionsEnabled() { + boolean enabled = false; + assert enabled = true; + return enabled; + } + /** * Creates an empty Graph with a given name. * @@ -97,6 +119,46 @@ nodeCacheFirst = new ArrayList<>(NodeClass.cacheSize()); nodeCacheLast = new ArrayList<>(NodeClass.cacheSize()); this.name = name; + if (MODIFICATION_COUNTS_ENABLED) { + nodeModCounts = new int[nodes.size()]; + nodeUsageModCounts = new int[nodes.size()]; + } + } + + int modCount(Node node) { + if (node.id >= 0 && node.id < nodeModCounts.length) { + return nodeModCounts[node.id]; + } + return 0; + } + + void incModCount(Node node) { + if (node.id >= 0) { + if (node.id >= nodeModCounts.length) { + nodeModCounts = Arrays.copyOf(nodeModCounts, node.id + 30); + } + nodeModCounts[node.id]++; + } else { + assert false; + } + } + + int usageModCount(Node node) { + if (node.id >= 0 && node.id < nodeUsageModCounts.length) { + return nodeUsageModCounts[node.id]; + } + return 0; + } + + void incUsageModCount(Node node) { + if (node.id >= 0) { + if (node.id >= nodeUsageModCounts.length) { + nodeUsageModCounts = Arrays.copyOf(nodeUsageModCounts, node.id + 30); + } + nodeUsageModCounts[node.id]++; + } else { + assert false; + } } /** diff -r f1c3f50ac36e -r cefd4cb3cb2d 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 Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Fri Sep 06 16:17:16 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.graph; +import static com.oracle.graal.graph.Graph.*; + import java.lang.annotation.*; import java.util.*; @@ -119,9 +121,18 @@ // therefore points to the next Node of the same type. Node typeCacheNext; - private NodeUsagesList usages; + private static final int INLINE_USAGE_COUNT = 2; + private static final Node[] NO_NODES = {}; + + /** + * Head of usage list. The elements of the usage list in order are {@link #usage0}, + * {@link #usage1} and {@link #extraUsages}. The first null entry terminates the list. + */ + private Node usage0; + private Node usage1; + private Node[] extraUsages = NO_NODES; + private Node predecessor; - private int modCount; public Node() { this.graph = null; @@ -156,8 +167,211 @@ return getNodeClass().getSuccessorIterable(this); } + class NodeUsageIterator implements Iterator { + + private final int expectedModCount = usageModCount(); + int index = -1; + Node current; + + private void advance() { + assert index == -1 || current != null; + current = null; + index++; + if (index == 0) { + current = usage0; + } else if (index == 1) { + current = usage1; + } else { + if (index - INLINE_USAGE_COUNT < extraUsages.length) { + current = extraUsages[index - INLINE_USAGE_COUNT]; + } + } + } + + public NodeUsageIterator() { + advance(); + } + + public boolean hasNext() { + assert expectedModCount == usageModCount(); + return current != null; + } + + public Node next() { + assert expectedModCount == usageModCount(); + Node result = current; + if (result == null) { + throw new NoSuchElementException(); + } + advance(); + return result; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + } + + class NodeUsageIterable extends AbstractNodeIterable { + + public NodeUsageIterator iterator() { + return new NodeUsageIterator(); + } + + @Override + public boolean isEmpty() { + return usage0 == null; + } + + @Override + public boolean isNotEmpty() { + return usage0 != null; + } + + @Override + public int count() { + if (usage0 == null) { + return 0; + } + if (usage1 == null) { + return 1; + } + return 2 + indexOfLastNonNull(extraUsages) + 1; + } + } + + /** + * Gets the list of nodes that use this node (e.g., as an input). + */ public final NodeIterable usages() { - return usages; + return new NodeUsageIterable(); + } + + /** + * Finds the index of the last non-null entry in a node array. The search assumes that all + * non-null entries precede the first null entry in the array. + * + * @param nodes the array to search + * @return the index of the last non-null entry in {@code nodes} if it exists, else -1 + */ + private static int indexOfLastNonNull(Node[] nodes) { + if (nodes.length == 0 || nodes[0] == null) { + return -1; + } + if (nodes[nodes.length - 1] != null) { + return nodes.length - 1; + } + + // binary search + int low = 0; + int high = nodes.length - 1; + while (true) { + int mid = (low + high) >>> 1; + if (nodes[mid] == null) { + if (nodes[mid - 1] != null) { + return mid - 1; + } + high = mid - 1; + } else { + if (mid == nodes.length - 1 || nodes[mid + 1] == null) { + return mid; + } + low = mid + 1; + } + } + } + + /** + * Adds a given node to this node's {@linkplain #usages() usages}. + * + * @param node the node to add + */ + private void addUsage(Node node) { + incUsageModCount(); + if (usage0 == null) { + usage0 = node; + } else if (usage1 == null) { + usage1 = node; + } else { + int length = extraUsages.length; + if (length == 0) { + extraUsages = new Node[4]; + extraUsages[0] = node; + } else { + int lastNonNull = indexOfLastNonNull(extraUsages); + if (lastNonNull == length - 1) { + extraUsages = Arrays.copyOf(extraUsages, length * 2 + 1); + extraUsages[length] = node; + } else if (lastNonNull == -1) { + extraUsages[0] = node; + } else { + extraUsages[lastNonNull + 1] = node; + } + } + } + } + + /** + * Removes a given node from this node's {@linkplain #usages() usages}. + * + * @param node the node to remove + * @return whether or not {@code usage} was in the usage list + */ + private boolean removeUsage(Node node) { + // It is critical that this method maintains the invariant that + // the usage list has no null element preceding a non-null element + incUsageModCount(); + if (usage0 == node) { + if (usage1 != null) { + int lastNonNull = indexOfLastNonNull(extraUsages); + if (lastNonNull >= 0) { + usage0 = extraUsages[lastNonNull]; + extraUsages[lastNonNull] = null; + } else { + // usage1 is the last element + usage0 = usage1; + usage1 = null; + } + } else { + // usage0 is the last element + usage0 = null; + } + return true; + } + if (usage1 == node) { + int lastNonNull = indexOfLastNonNull(extraUsages); + if (lastNonNull >= 0) { + usage1 = extraUsages[lastNonNull]; + extraUsages[lastNonNull] = null; + } else { + // usage1 is the last element + usage1 = null; + } + return true; + } + int lastNonNull = indexOfLastNonNull(extraUsages); + if (lastNonNull >= 0) { + for (int i = 0; i <= lastNonNull; ++i) { + Node n = extraUsages[i]; + if (n == node) { + if (i < lastNonNull) { + extraUsages[i] = extraUsages[lastNonNull]; + extraUsages[lastNonNull] = null; + } else { + extraUsages[i] = null; + } + return true; + } + } + } + return false; + } + + private void clearUsages() { + incUsageModCount(); + usage0 = null; + usage1 = null; + extraUsages = NO_NODES; } public final Node predecessor() { @@ -165,11 +379,29 @@ } final int modCount() { - return modCount; + if (MODIFICATION_COUNTS_ENABLED && graph != null) { + return graph.modCount(this); + } + return 0; } final void incModCount() { - modCount++; + if (MODIFICATION_COUNTS_ENABLED && graph != null) { + graph.incModCount(this); + } + } + + final int usageModCount() { + if (MODIFICATION_COUNTS_ENABLED && graph != null) { + return graph.usageModCount(this); + } + return 0; + } + + final void incUsageModCount() { + if (MODIFICATION_COUNTS_ENABLED && graph != null) { + graph.incUsageModCount(this); + } } public boolean isDeleted() { @@ -185,7 +417,6 @@ * newInput: removes this node from oldInput's usages and adds this node to newInput's usages. */ protected void updateUsages(Node oldInput, Node newInput) { - assert assertTrue(usages != null, "usages == null while adding %s to %s", newInput, this); if (oldInput != newInput) { if (oldInput != null) { boolean result = removeThisFromUsages(oldInput); @@ -196,8 +427,7 @@ if (inputChanged != null) { inputChanged.nodeChanged(this); } - assert newInput.usages != null : "not yet added? " + newInput; - newInput.usages.add(this); + newInput.addUsage(this); } else if (oldInput != null && oldInput.usages().isEmpty()) { NodeChangedListener nodeChangedListener = graph.usagesDroppedZero; if (nodeChangedListener != null) { @@ -213,7 +443,6 @@ * this node to newSuccessor's predecessors. */ protected void updatePredecessor(Node oldSuccessor, Node newSuccessor) { - assert assertTrue(usages != null, "usages == null while adding %s to %s", newSuccessor, this); if (oldSuccessor != newSuccessor) { if (oldSuccessor != null) { assert assertTrue(oldSuccessor.predecessor == this, "wrong predecessor in old successor (%s): %s", oldSuccessor, oldSuccessor.predecessor); @@ -230,7 +459,6 @@ assert assertTrue(id == INITIAL_ID, "unexpected id: %d", id); this.graph = newGraph; newGraph.register(this); - usages = new NodeUsagesList(); for (Node input : inputs()) { updateUsages(null, input); } @@ -253,7 +481,7 @@ public void replaceAtUsages(Node other) { assert checkReplaceWith(other); - for (Node usage : usages) { + for (Node usage : usages()) { boolean result = usage.getNodeClass().replaceFirstInput(usage, this, other); assert assertTrue(result, "not found in inputs, usage: %s", usage); if (other != null) { @@ -261,10 +489,10 @@ if (inputChanged != null) { inputChanged.nodeChanged(usage); } - other.usages.add(usage); + other.addUsage(usage); } } - usages.clear(); + clearUsages(); } public void replaceAtPredecessor(Node other) { @@ -314,11 +542,7 @@ } private boolean removeThisFromUsages(Node n) { - if (n.usages.remove(this)) { - return true; - } else { - return false; - } + return n.removeUsage(this); } public void clearSuccessors() { @@ -332,7 +556,7 @@ } private boolean checkDeletion() { - assertTrue(usages.isEmpty(), "cannot delete node %s because of usages: %s", this, usages); + assertTrue(usages().isEmpty(), "cannot delete node %s because of usages: %s", this, usages()); assertTrue(predecessor == null, "cannot delete node %s because of predecessor: %s", this, predecessor); return true; } @@ -355,7 +579,7 @@ NodeClass clazz = getNodeClass(); clazz.copyInputs(this, newNode); for (Node input : inputs()) { - input.usages.add(newNode); + input.addUsage(newNode); } return newNode; } @@ -373,9 +597,10 @@ newNode.typeCacheNext = null; newNode.id = INITIAL_ID; into.register(newNode); - newNode.usages = new NodeUsagesList(); + newNode.usage0 = null; + newNode.usage1 = null; + newNode.extraUsages = NO_NODES; newNode.predecessor = null; - newNode.modCount = 0; return newNode; } @@ -576,10 +801,10 @@ } if (precision > 0) { - if (this.usages.count() > 0) { + if (!usages().isEmpty()) { formatter.format(" usages={"); int z = 0; - for (Node usage : this.usages) { + for (Node usage : usages()) { if (z != 0) { formatter.format(", "); } diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Sep 06 16:17:16 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.graph; +import static com.oracle.graal.graph.Graph.*; + import java.lang.reflect.*; import java.util.*; import java.util.Map.Entry; @@ -432,7 +434,7 @@ */ private NodeClassIterator(Node node, long[] offsets, int directCount) { this.node = node; - this.modCount = node.modCount(); + this.modCount = MODIFICATION_COUNTS_ENABLED ? node.modCount() : 0; this.offsets = offsets; this.directCount = directCount; index = NOT_ITERABLE; diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeInputList.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeInputList.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeInputList.java Fri Sep 06 16:17:16 2013 +0200 @@ -39,13 +39,13 @@ public NodeInputList(Node self, T[] elements) { super(elements); - assert self.usages() == null; + assert self.usages().isEmpty(); this.self = self; } public NodeInputList(Node self, List elements) { super(elements); - assert self.usages() == null; + assert self.usages().isEmpty(); this.self = self; } diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeSuccessorList.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeSuccessorList.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeSuccessorList.java Fri Sep 06 16:17:16 2013 +0200 @@ -37,7 +37,7 @@ public NodeSuccessorList(Node self, T[] elements) { super(elements); - assert self.usages() == null; + assert self.usages().isEmpty(); this.self = self; } diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeUsagesList.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeUsagesList.java Fri Sep 06 16:17:01 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.graph; - -import java.util.*; - -import com.oracle.graal.graph.iterators.*; - -public final class NodeUsagesList extends AbstractNodeIterable { - - protected static final Node[] EMPTY_NODE_ARRAY = new Node[0]; - - protected Node[] nodes = EMPTY_NODE_ARRAY; - private int size; - private int modCount; - - NodeUsagesList() { - this.size = 0; - this.nodes = EMPTY_NODE_ARRAY; - } - - NodeUsagesList(Node[] nodes) { - this.size = nodes.length; - this.nodes = nodes; - } - - @Override - public boolean isEmpty() { - return size == 0; - } - - @Override - public boolean isNotEmpty() { - return size > 0; - } - - @Override - public int count() { - return size; - } - - @Override - public Iterator iterator() { - return new Iterator() { - - private final int expectedModCount = NodeUsagesList.this.modCount; - private int index = 0; - - @Override - public boolean hasNext() { - assert expectedModCount == NodeUsagesList.this.modCount; - return index < NodeUsagesList.this.size; - } - - @Override - public Node next() { - assert expectedModCount == NodeUsagesList.this.modCount; - return NodeUsagesList.this.nodes[index++]; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - - @Override - public boolean contains(Node other) { - for (int i = 0; i < size; i++) { - if (nodes[i] == other) { - return true; - } - } - return false; - } - - @Override - public List snapshot() { - return Arrays.asList(Arrays.copyOf(NodeUsagesList.this.nodes, NodeUsagesList.this.size)); - } - - private void incModCount() { - modCount++; - } - - boolean add(Node node) { - incModCount(); - if (size == nodes.length) { - nodes = Arrays.copyOf(nodes, nodes.length * 2 + 1); - } - nodes[size++] = node; - return true; - } - - void copyAndClear(NodeUsagesList other) { - incModCount(); - other.incModCount(); - nodes = other.nodes; - size = other.size; - nodes = EMPTY_NODE_ARRAY; - size = 0; - } - - void clear() { - incModCount(); - nodes = EMPTY_NODE_ARRAY; - size = 0; - } - - boolean remove(Node node) { - int i = 0; - incModCount(); - while (i < size && nodes[i] != node) { - i++; - } - if (i < size) { - i++; - while (i < size) { - nodes[i - 1] = nodes[i]; - i++; - } - nodes[--size] = null; - return true; - } else { - return false; - } - } - - @Override - public String toString() { - StringBuilder str = new StringBuilder(); - str.append('['); - for (int i = 0; i < size; i++) { - if (i > 0) { - str.append(", "); - } - str.append(nodes[i]); - } - str.append(']'); - return str.toString(); - } -} diff -r f1c3f50ac36e -r cefd4cb3cb2d 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 Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Fri Sep 06 16:17:16 2013 +0200 @@ -45,7 +45,7 @@ import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.LIRInstruction.ValueProcedure; -import com.oracle.graal.lir.StandardOp.ParametersOp; +import com.oracle.graal.lir.StandardOp.LabelOp; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.*; @@ -214,7 +214,7 @@ }; for (Block block : lir.codeEmittingOrder()) { for (LIRInstruction op : lir.lir(block)) { - if (op instanceof ParametersOp) { + if (op instanceof LabelOp) { // Don't consider this as a definition } else { op.forEachTemp(defProc); diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Fri Sep 06 16:17:16 2013 +0200 @@ -46,7 +46,6 @@ import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; -import com.oracle.graal.lir.StandardOp.ParametersOp; import com.oracle.graal.lir.StandardOp.PlaceholderOp; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp; @@ -162,9 +161,8 @@ } } params[params.length - 1] = rbpParam; - ParametersOp paramsOp = new ParametersOp(params); - append(paramsOp); + emitIncomingValues(params); saveRbp = new SaveRbp(new PlaceholderOp(currentBlock, lir.lir(currentBlock).size())); append(saveRbp.placeholder); diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Fri Sep 06 16:17:16 2013 +0200 @@ -226,4 +226,6 @@ void reprofile(long metaspaceMethod); void invalidateInstalledCode(HotSpotInstalledCode hotspotInstalledCode); + + boolean isTypeLinked(HotSpotResolvedObjectType hotSpotResolvedObjectType); } diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Fri Sep 06 16:17:16 2013 +0200 @@ -102,6 +102,8 @@ @Override public native boolean isTypeInitialized(HotSpotResolvedObjectType klass); + public native boolean isTypeLinked(HotSpotResolvedObjectType hotSpotResolvedObjectType); + @Override public native boolean hasFinalizableSubclass(HotSpotResolvedObjectType klass); diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Fri Sep 06 16:17:16 2013 +0200 @@ -138,7 +138,7 @@ if (codeSize == 0) { return null; } - if (code == null) { + if (code == null && graalRuntime().getCompilerToVM().isTypeLinked(holder)) { code = graalRuntime().getCompilerToVM().initializeBytecode(metaspaceMethod, new byte[codeSize]); assert code.length == codeSize : "expected: " + codeSize + ", actual: " + code.length; } diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Fri Sep 06 16:17:16 2013 +0200 @@ -83,6 +83,7 @@ private ResolvedJavaType[] interfaces; private ConstantPool constantPool; private boolean isInitialized; + private boolean isLinked; private ResolvedJavaType arrayOfType; /** @@ -292,9 +293,18 @@ } @Override + public boolean isLinked() { + if (!isLinked) { + isLinked = graalRuntime().getCompilerToVM().isTypeLinked(this); + } + return isLinked; + } + + @Override public void initialize() { if (!isInitialized) { graalRuntime().getCompilerToVM().initializeType(this); + assert graalRuntime().getCompilerToVM().isTypeInitialized(this); } isInitialized = true; } diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Fri Sep 06 16:17:16 2013 +0200 @@ -112,6 +112,10 @@ return true; } + public boolean isLinked() { + return true; + } + @Override public boolean isInstance(Constant obj) { return false; diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Sep 06 16:17:16 2013 +0200 @@ -242,7 +242,7 @@ // remove dead FrameStates for (Node n : currentGraph.getNodes(FrameState.class)) { - if (n.usages().count() == 0 && n.predecessor() == null) { + if (n.usages().isEmpty() && n.predecessor() == null) { n.safeDelete(); } } diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java Fri Sep 06 16:17:16 2013 +0200 @@ -316,7 +316,7 @@ masm.cvt_f32_f64(asFloatReg(dst), asDoubleReg(src)); break; case LSHL: - masm.shl_s64(asLongReg(dst), asLongReg(dst), asIntReg(src)); + masm.shl_b64(asLongReg(dst), asLongReg(dst), asIntReg(src)); break; case LSHR: masm.shr_s64(asLongReg(dst), asLongReg(dst), asIntReg(src)); @@ -360,19 +360,19 @@ switch (opcode) { case IADD: masm.add_s32(asIntReg(dst), asIntReg(src1), tasm.asIntConst(src2)); break; case ISUB: masm.sub_s32(asIntReg(dst), asIntReg(src1), tasm.asIntConst(src2)); break; - case IMUL: masm.mul_s32(asIntReg(dst), asIntReg(src1), tasm.asIntConst(src2)); break; + case IMUL: masm.mul_lo_s32(asIntReg(dst), asIntReg(src1), tasm.asIntConst(src2)); break; case IAND: masm.and_b32(asIntReg(dst), asIntReg(src1), tasm.asIntConst(src2)); break; - case ISHL: masm.shl_s32(asIntReg(dst), asIntReg(src1), tasm.asIntConst(src2)); break; + case ISHL: masm.shl_b32_const(asIntReg(dst), asIntReg(src1), tasm.asIntConst(src2)); break; case ISHR: masm.shr_s32(asIntReg(dst), asIntReg(src1), tasm.asIntConst(src2)); break; case IUSHR: masm.shr_u32(asIntReg(dst), asIntReg(src1), tasm.asIntConst(src2)); break; case IXOR: masm.xor_b32(asIntReg(dst), asIntReg(src1), tasm.asIntConst(src2)); break; case LXOR: masm.xor_b64(asLongReg(dst), asLongReg(src1), tasm.asLongConst(src2)); break; case LUSHR: masm.shr_u64(asLongReg(dst), asLongReg(src1), tasm.asLongConst(src2)); break; case FADD: masm.add_f32(asFloatReg(dst), asFloatReg(src1), tasm.asFloatConst(src2)); break; - case FMUL: masm.mul_f32(asFloatReg(dst), asFloatReg(src1), tasm.asFloatConst(src2)); break; + case FMUL: masm.mul_lo_f32(asFloatReg(dst), asFloatReg(src1), tasm.asFloatConst(src2)); break; case FDIV: masm.div_f32(asFloatReg(dst), asFloatReg(src1), tasm.asFloatConst(src2)); break; case DADD: masm.add_f64(asDoubleReg(dst), asDoubleReg(src1), tasm.asDoubleConst(src2)); break; - case DMUL: masm.mul_f64(asDoubleReg(dst), asDoubleReg(src1), tasm.asDoubleConst(src2)); break; + case DMUL: masm.mul_lo_f64(asDoubleReg(dst), asDoubleReg(src1), tasm.asDoubleConst(src2)); break; case DDIV: masm.div_f64(asDoubleReg(dst), asDoubleReg(src1), tasm.asDoubleConst(src2)); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -387,34 +387,34 @@ // case D: new Mul(Double, dst, src1, src2); case IADD: masm.add_s32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break; case ISUB: masm.sub_s32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break; - case IMUL: masm.mul_s32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break; + case IMUL: masm.mul_lo_s32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break; case IDIV: masm.div_s32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break; case IAND: masm.and_b32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break; case IOR: masm.or_b32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break; case IXOR: masm.xor_b32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break; - case ISHL: masm.shl_s32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break; + case ISHL: masm.shl_b32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break; case ISHR: masm.shr_s32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break; case IUSHR: masm.shr_u32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break; case IREM: masm.rem_s32(asIntReg(dst), asIntReg(src1), asIntReg(src2)); break; case LADD: masm.add_s64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break; case LSUB: masm.sub_s64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break; - case LMUL: masm.mul_s64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break; + case LMUL: masm.mul_lo_s64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break; case LDIV: masm.div_s64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break; case LAND: masm.and_b64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break; - case LOR: masm.or_b64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break; + case LOR: masm.or_b64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break; case LXOR: masm.xor_b64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break; - case LSHL: masm.shl_s64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break; + case LSHL: masm.shl_b64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break; case LSHR: masm.shr_s64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break; case LUSHR: masm.shr_u64(asLongReg(dst), asLongReg(src1), asIntReg(src2)); break; case LREM: masm.rem_s64(asLongReg(dst), asLongReg(src1), asLongReg(src2)); break; case FADD: masm.add_f32(asFloatReg(dst), asFloatReg(src1), asFloatReg(src2)); break; case FSUB: masm.sub_f32(asFloatReg(dst), asFloatReg(src1), asFloatReg(src2)); break; - case FMUL: masm.mul_f32(asFloatReg(dst), asFloatReg(src1), asFloatReg(src2)); break; + case FMUL: masm.mul_lo_f32(asFloatReg(dst), asFloatReg(src1), asFloatReg(src2)); break; case FDIV: masm.div_f32(asFloatReg(dst), asFloatReg(src1), asFloatReg(src2)); break; case FREM: masm.div_f32(asFloatReg(dst), asFloatReg(src1), asFloatReg(src2)); break; case DADD: masm.add_f64(asDoubleReg(dst), asDoubleReg(src1), asDoubleReg(src2)); break; case DSUB: masm.sub_f64(asDoubleReg(dst), asDoubleReg(src1), asDoubleReg(src2)); break; - case DMUL: masm.mul_f64(asDoubleReg(dst), asDoubleReg(src1), asDoubleReg(src2)); break; + case DMUL: masm.mul_lo_f64(asDoubleReg(dst), asDoubleReg(src1), asDoubleReg(src2)); break; case DDIV: masm.div_f64(asDoubleReg(dst), asDoubleReg(src1), asDoubleReg(src2)); break; case DREM: masm.div_f64(asDoubleReg(dst), asDoubleReg(src1), asDoubleReg(src2)); break; default: diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java Fri Sep 06 16:17:16 2013 +0200 @@ -158,7 +158,7 @@ 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()); + masm.ld_from_state_space(".param.u16", asRegister(result), addr.getBase(), addr.getDisplacement()); break; case Int: masm.ld_from_state_space(".param.s32", asRegister(result), addr.getBase(), addr.getDisplacement()); diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXParameterOp.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXParameterOp.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXParameterOp.java Fri Sep 06 16:17:16 2013 +0200 @@ -42,23 +42,23 @@ @Override public void emitCode(TargetMethodAssembler tasm) { - PTXAssembler ptxasm = (PTXAssembler) tasm.asm; + PTXAssembler masm = (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))); + masm.param_32_decl(asIntReg(params[i]), (i == (argCount - 1))); break; case Long : - ptxasm.param_64_decl(asLongReg(params[i]), (i == (argCount - 1))); + masm.param_64_decl(asLongReg(params[i]), (i == (argCount - 1))); break; case Float : - ptxasm.param_32_decl(asFloatReg(params[i]), (i == (argCount - 1))); + masm.param_32_decl(asFloatReg(params[i]), (i == (argCount - 1))); break; case Double : - ptxasm.param_64_decl(asDoubleReg(params[i]), (i == (argCount - 1))); + masm.param_64_decl(asDoubleReg(params[i]), (i == (argCount - 1))); break; default : throw GraalInternalError.shouldNotReachHere("unhandled parameter type " + paramKind.toString()); diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Fri Sep 06 16:17:16 2013 +0200 @@ -54,12 +54,30 @@ */ public static class LabelOp extends LIRInstruction { + private static final Value[] NO_VALUES = new Value[0]; + + /** + * In the LIR, every register and variable must be defined before it is used. For method + * parameters that are passed in fixed registers, exception objects passed to the exception + * handler in a fixed register, or any other use of a fixed register not defined in this + * method, an artificial definition is necessary. To avoid spill moves to be inserted + * between the label at the beginning of a block an an actual definition in the second + * instruction of a block, the registers are defined here in the label. + */ + @Def({REG, STACK}) private Value[] incomingValues; + private final Label label; private final boolean align; public LabelOp(Label label, boolean align) { this.label = label; this.align = align; + this.incomingValues = NO_VALUES; + } + + public void setIncomingValues(Value[] values) { + assert incomingValues.length == 0; + incomingValues = values; } @Override @@ -121,25 +139,6 @@ } /** - * Meta-operation that defines the incoming method parameters. In the LIR, every register and - * variable must be defined before it is used. This operation is the definition point of method - * parameters, but is otherwise a no-op. In particular, it is not the actual method prologue. - */ - public static final class ParametersOp extends LIRInstruction { - - @Def({REG, STACK}) protected Value[] params; - - public ParametersOp(Value[] params) { - this.params = params; - } - - @Override - public void emitCode(TargetMethodAssembler tasm) { - // No code to emit. - } - } - - /** * Placeholder for a LIR instruction that will be subsequently replaced. */ public static class PlaceholderOp extends LIRInstruction { diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Fri Sep 06 16:17:16 2013 +0200 @@ -145,11 +145,11 @@ } } - protected static NodeBitMap computeNodes(Graph graph, Collection blocks) { + protected static NodeBitMap computeNodes(Graph graph, Iterable blocks) { return computeNodes(graph, blocks, Collections. emptyList()); } - protected static NodeBitMap computeNodes(Graph graph, Collection blocks, Collection earlyExits) { + protected static NodeBitMap computeNodes(Graph graph, Iterable blocks, Iterable earlyExits) { final NodeBitMap nodes = graph.createNodeBitMap(true); for (AbstractBeginNode b : blocks) { for (Node n : b.getBlockNodes()) { @@ -229,12 +229,28 @@ return false; } - public static Collection toHirBlocks(Collection blocks) { - List hir = new ArrayList<>(blocks.size()); - for (Block b : blocks) { - hir.add(b.getBeginNode()); - } - return hir; + public static NodeIterable toHirBlocks(final Iterable blocks) { + return new AbstractNodeIterable() { + + public Iterator iterator() { + final Iterator it = blocks.iterator(); + return new Iterator() { + + public void remove() { + throw new UnsupportedOperationException(); + } + + public AbstractBeginNode next() { + return it.next().getBeginNode(); + } + + public boolean hasNext() { + return it.hasNext(); + } + }; + } + + }; } /** diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java Fri Sep 06 16:17:16 2013 +0200 @@ -231,7 +231,7 @@ StructuredGraph graph = graph(); if (endsToMerge.size() == 1) { AbstractEndNode end = endsToMerge.get(0); - assert end.usages().count() == 0; + assert end.usages().isEmpty(); newExit = graph.add(new BeginNode()); end.replaceAtPredecessor(newExit); end.safeDelete(); diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopEndNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopEndNode.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopEndNode.java Fri Sep 06 16:17:16 2013 +0200 @@ -72,7 +72,7 @@ @Override public boolean verify() { assertTrue(loopBegin != null, "must have a loop begin"); - assertTrue(usages().count() == 0, "LoopEnds can not be used"); + assertTrue(usages().isEmpty(), "LoopEnds can not be used"); return super.verify(); } diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Fri Sep 06 16:17:16 2013 +0200 @@ -144,15 +144,19 @@ return copy(name); } - @Override - public StructuredGraph copy(String newName) { - StructuredGraph copy = new StructuredGraph(newName, method, graphId, entryBCI); + public StructuredGraph copy(String newName, ResolvedJavaMethod newMethod) { + StructuredGraph copy = new StructuredGraph(newName, newMethod, graphId, entryBCI); HashMap replacements = new HashMap<>(); replacements.put(start, copy.start); copy.addDuplicates(getNodes(), replacements); return copy; } + @Override + public StructuredGraph copy(String newName) { + return copy(newName, method); + } + public LocalNode getLocal(int index) { for (LocalNode local : getNodes(LocalNode.class)) { if (local.index() == index) { diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Sep 06 16:17:16 2013 +0200 @@ -72,7 +72,7 @@ public static ValueNode canonicalizeRead(ValueNode read, LocationNode location, ValueNode object, CanonicalizerTool tool, boolean compressible) { MetaAccessProvider runtime = tool.runtime(); - if (read.usages().count() == 0) { + if (read.usages().isEmpty()) { // Read without usages can be savely removed. return null; } diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java Fri Sep 06 16:17:16 2013 +0200 @@ -23,9 +23,7 @@ package com.oracle.graal.nodes.java; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -74,12 +72,4 @@ public ValueNode mirror() { return mirror; } - - @Override - public boolean verify() { - for (Node usage : usages()) { - assertTrue(usage instanceof IfNode || usage instanceof FixedGuardNode || usage instanceof ConditionalNode, "unsupported usage: %s", usage); - } - return super.verify(); - } } diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Fri Sep 06 16:17:16 2013 +0200 @@ -512,7 +512,7 @@ while ((current = nextQueuedNode()) != null) { assert current.isAlive(); - if (current instanceof Invoke) { + if (current instanceof Invoke && ((Invoke) current).callTarget() instanceof MethodCallTargetNode) { if (current != start) { invokes.addLast((Invoke) current); } diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/RemoveValueProxyPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/RemoveValueProxyPhase.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/RemoveValueProxyPhase.java Fri Sep 06 16:17:16 2013 +0200 @@ -39,7 +39,7 @@ FrameState stateAfter = exit.stateAfter(); if (stateAfter != null) { exit.setStateAfter(null); - if (stateAfter.usages().count() == 0) { + if (stateAfter.usages().isEmpty()) { stateAfter.safeDelete(); } } diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Fri Sep 06 16:17:16 2013 +0200 @@ -36,6 +36,7 @@ import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.internal.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; @@ -107,6 +108,10 @@ }); } + public static final DebugTimer PartialEvaluationTime = Debug.timer("PartialEvaluationTime"); + public static final DebugTimer CompilationTime = Debug.timer("CompilationTime"); + public static final DebugTimer CodeInstallationTime = Debug.timer("CodeInstallation"); + private InstalledCode compileMethodImpl(final OptimizedCallTarget compilable) { final StructuredGraph graph; final GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(); @@ -115,7 +120,9 @@ compilable.timeCompilationStarted = System.nanoTime(); Assumptions assumptions = new Assumptions(true); - graph = partialEvaluator.createGraph(compilable, assumptions); + try (TimerCloseable a = PartialEvaluationTime.start()) { + graph = partialEvaluator.createGraph(compilable, assumptions); + } compilable.timePartialEvaluationFinished = System.nanoTime(); compilable.nodeCountPartialEval = graph.getNodeCount(); InstalledCode compiledMethod = compileMethodHelper(graph, config, compilable, assumptions); @@ -143,9 +150,11 @@ @Override public CompilationResult call() { - CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); - return GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, replacements, backend, runtime.getTarget(), null, plan, OptimisticOptimizations.ALL, new SpeculationLog(), - suites, new CompilationResult()); + try (TimerCloseable a = CompilationTime.start()) { + CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); + return GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, replacements, backend, runtime.getTarget(), null, plan, OptimisticOptimizations.ALL, new SpeculationLog(), + suites, new CompilationResult()); + } } }); @@ -169,11 +178,13 @@ @Override public InstalledCode call() throws Exception { - InstalledCode installedCode = runtime.addMethod(graph.method(), result); - if (installedCode != null) { - Debug.dump(new Object[]{result, installedCode}, "After code installation"); + try (TimerCloseable a = CodeInstallationTime.start()) { + InstalledCode installedCode = runtime.addMethod(graph.method(), result); + if (installedCode != null) { + Debug.dump(new Object[]{result, installedCode}, "After code installation"); + } + return installedCode; } - return installedCode; } }); diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Fri Sep 06 16:17:16 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,6 +59,11 @@ CompilerAsserts.neverPartOfCompilation(); } + protected Node(SourceSection sourceSection) { + CompilerAsserts.neverPartOfCompilation(); + this.sourceSection = sourceSection; + } + /** * Assigns a link to a guest language source section to this node. * diff -r f1c3f50ac36e -r cefd4cb3cb2d graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Fri Sep 06 16:17:01 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Fri Sep 06 16:17:16 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,13 @@ */ public abstract class RootNode extends Node { + protected RootNode() { + } + + protected RootNode(SourceSection sourceSection) { + super(sourceSection); + } + /** * Executes this function using the specified frame and returns the result value. * diff -r f1c3f50ac36e -r cefd4cb3cb2d mx/.pylintrc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mx/.pylintrc Fri Sep 06 16:17:16 2013 +0200 @@ -0,0 +1,278 @@ +[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=no + +# 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,no-self-use,too-many-statements, + too-many-locals,too-few-public-methods,too-many-instance-attributes, + too-many-arguments,too-many-branches,too-many-public-methods, + abstract-method + +[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,40}$ + +# Regular expression which should only match correct method names +method-rgx=[a-z_][a-zA-Z0-9_]{2,40}$ + +# 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 f1c3f50ac36e -r cefd4cb3cb2d mx/commands.py --- a/mx/commands.py Fri Sep 06 16:17:01 2013 +0200 +++ b/mx/commands.py Fri Sep 06 16:17:16 2013 +0200 @@ -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,8 +280,7 @@ 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 @@ -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,12 +436,44 @@ if line.startswith('ERRXXX'): if line == 'ERRXXX0': ret = True - break; + break stdin.write('exit' + newLine) if logFile: log.close() return ret +def pylint(args): + """run pylint (if available) over Python source files""" + rcfile = join(_graal_home, 'mx', '.pylintrc') + if not exists(rcfile): + mx.log('pylint configuration file does not exist: ' + rcfile) + return + + try: + output = subprocess.check_output(['pylint', '--version'], stderr=subprocess.STDOUT) + m = re.match(r'.*pylint (\d+)\.(\d+)\.(\d+).*', output, re.DOTALL) + if not m: + mx.log('could not determine pylint version from ' + output) + return + major, minor, micro = (int(m.group(1)), int(m.group(2)), int(m.group(3))) + if major < 1: + mx.log('require pylint version >= 1 (got {0}.{1}.{2})'.format(major, minor, micro)) + return + except BaseException: + mx.log('pylint is not available') + return + + + env = os.environ.copy() + env['PYTHONPATH'] = dirname(mx.__file__) + + versioned = subprocess.check_output(['hg', 'locate', '-f'], stderr=subprocess.STDOUT).split(os.linesep) + for f in versioned: + if f.endswith('.py'): + pyfile = f + mx.log('Running pylint on ' + pyfile + '...') + mx.run(['pylint', '--reports=n', '--rcfile=' + rcfile, pyfile], env=env) + def jdkhome(args, vm=None): """print the JDK directory selected for the 'vm' command""" @@ -458,16 +490,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 +520,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 +554,11 @@ else: assert vm == 'graal', vm buildSuffix = 'graal' - + + if _installed_jdks and _installed_jdks != _graal_home: + if not mx.ask_yes_no("Warning: building while --installed-jdks is set (" + _installed_jdks + ") is not recommanded - 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 +613,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 +626,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 +681,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 +735,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 +750,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 +764,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 +776,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 +786,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 +863,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 +883,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 +905,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 +927,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 +967,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,11 +976,15 @@ args = parser.parse_args(args) global _jacoco - + tasks = [] total = Task('Gate') try: + t = Task('Pylint') + pylint([]) + tasks.append(t.stop()) + t = Task('Clean') cleanArgs = [] if not args.cleanNative: @@ -976,7 +1011,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 +1020,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 +1042,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 +1058,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 +1072,7 @@ if args.jacocout is not None: jacocoreport([args.jacocout]) - + _jacoco = 'off' t = Task('CleanAndBuildGraalVisualizer') @@ -1058,7 +1093,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 +1113,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 +1123,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 +1166,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 +1175,7 @@ results = {} benchmarks = [] - #DaCapo + # DaCapo if ('dacapo' in args or 'all' in args): benchmarks += sanitycheck.getDacapos(level=sanitycheck.SanityCheckLevel.Benchmark) else: @@ -1163,23 +1198,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,37 +1233,36 @@ 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) if len(parts) > 1: assert len(parts) == 2 group = parts[0] - print group 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 +1286,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 +1305,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: @@ -1334,6 +1368,7 @@ 'hcfdis': [hcfdis, ''], 'igv' : [igv, ''], 'jdkhome': [jdkhome, ''], + 'pylint': [pylint, ''], 'dacapo': [dacapo, '[VM options] benchmarks...|"all" [DaCapo options]'], 'scaladacapo': [scaladacapo, '[VM options] benchmarks...|"all" [Scala DaCapo options]'], 'specjvm2008': [specjvm2008, '[VM options] benchmarks...|"all" [SPECjvm2008 options]'], @@ -1362,7 +1397,7 @@ 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 +1406,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 f1c3f50ac36e -r cefd4cb3cb2d mx/outputparser.py --- a/mx/outputparser.py Fri Sep 06 16:17:01 2013 +0200 +++ b/mx/outputparser.py Fri Sep 06 16:17:16 2013 +0200 @@ -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 f1c3f50ac36e -r cefd4cb3cb2d mx/sanitycheck.py --- a/mx/sanitycheck.py Fri Sep 06 16:17:01 2013 +0200 +++ b/mx/sanitycheck.py Fri Sep 06 16:17:16 2013 +0200 @@ -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] } @@ -77,7 +77,8 @@ 'sunflow': [ 'fastdebug', 'debug'], 'tomcat': ['product', 'fastdebug', 'debug'], 'tradebeans': ['product', 'fastdebug', 'debug'], - 'tradesoap': ['product'], + # tradesoap is too unreliable for the gate, often crashing with "java.net.BindException: Address already in use" + 'tradesoap': [ ], 'xalan': ['product', 'fastdebug', 'debug'], } @@ -137,60 +138,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 +207,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