# HG changeset patch # User Thomas Wuerthinger # Date 1382435017 -7200 # Node ID ce8dd5fa8d545635b9c7dd8c28f662a56c2717ad # Parent 3ee8ae69d676ede55b308bbb3c32f6353523ed8b# Parent bddf5ae62522295bcbc119d2db82d9d9a0daeabe Merge. diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ExternalCompilationResult.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ExternalCompilationResult.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ExternalCompilationResult.java Tue Oct 22 11:43:37 2013 +0200 @@ -23,12 +23,12 @@ package com.oracle.graal.api.code; /** - * Represents the output from compiling a method generated by graal, but executing - * in a memory and computational subsystem outside the graal host system. + * Represents the output from compiling a method generated by Graal, but executing in a memory and + * computational subsystem outside the Graal host system. * - * Output may include the compiled machine code, associated - * data and references, relocation information, deoptimization information, - * as this result is generated from a structure graph on the graal host system. + * Output may include the compiled machine code, associated data and references, relocation + * information, deoptimization information, as this result is generated from a structure graph on + * the Graal host system. */ public class ExternalCompilationResult extends CompilationResult { @@ -45,7 +45,8 @@ /** * Set the address for the point of entry to the external compilation result. - * @param addr The address of the entry point. + * + * @param addr the address of the entry point */ public void setEntryPoint(long addr) { entryPoint = addr; @@ -53,9 +54,10 @@ /** * Return the address for the point of entry to the external compilation result. + * * @return address value */ public long getEntryPoint() { - return entryPoint; + return entryPoint; } } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/NameAndSignature.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/NameAndSignature.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/NameAndSignature.java Tue Oct 22 11:43:37 2013 +0200 @@ -27,10 +27,11 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; +import com.oracle.graal.runtime.*; class NameAndSignature { - public static final MetaAccessProvider runtime = Graal.getRequiredCapability(MetaAccessProvider.class); + public static final MetaAccessProvider metaAccess = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders().getMetaAccess(); final String name; final Class returnType; @@ -71,14 +72,14 @@ public boolean signatureEquals(ResolvedJavaMethod m) { Signature s = m.getSignature(); ResolvedJavaType declaringClass = m.getDeclaringClass(); - if (!s.getReturnType(declaringClass).resolve(declaringClass).equals(runtime.lookupJavaType(returnType))) { + if (!s.getReturnType(declaringClass).resolve(declaringClass).equals(metaAccess.lookupJavaType(returnType))) { return false; } if (s.getParameterCount(false) != parameterTypes.length) { return false; } for (int i = 0; i < parameterTypes.length; i++) { - if (!s.getParameterType(i, declaringClass).resolve(declaringClass).equals(runtime.lookupJavaType(parameterTypes[i]))) { + if (!s.getParameterType(i, declaringClass).resolve(declaringClass).equals(metaAccess.lookupJavaType(parameterTypes[i]))) { return false; } } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestBytecodeDisassemblerProvider.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestBytecodeDisassemblerProvider.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestBytecodeDisassemblerProvider.java Tue Oct 22 11:43:37 2013 +0200 @@ -25,7 +25,7 @@ import org.junit.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.runtime.*; +import com.oracle.graal.java.*; /** * Tests for {@link BytecodeDisassemblerProvider}. @@ -40,7 +40,7 @@ */ @Test public void disassembleTest() { - BytecodeDisassemblerProvider dis = Graal.getRuntime().getCapability(BytecodeDisassemblerProvider.class); + BytecodeDisassemblerProvider dis = new BytecodeDisassembler(); if (dis != null) { int count = 0; for (ResolvedJavaMethod m : methods.values()) { diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java Tue Oct 22 11:43:37 2013 +0200 @@ -33,6 +33,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; +import com.oracle.graal.phases.util.*; +import com.oracle.graal.runtime.*; /** * Context for type related api.meta tests. @@ -40,13 +42,17 @@ public class TypeUniverse { public final Unsafe unsafe; - public final MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class); - public final ConstantReflectionProvider constantReflection = Graal.getRequiredCapability(ConstantReflectionProvider.class); + + public final MetaAccessProvider metaAccess; + public final ConstantReflectionProvider constantReflection; public final Collection> classes = new HashSet<>(); public final Map, Class> arrayClasses = new HashMap<>(); public final List constants = new ArrayList<>(); public TypeUniverse() { + Providers providers = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders(); + metaAccess = providers.getMetaAccess(); + constantReflection = providers.getConstantReflection(); Unsafe theUnsafe = null; try { theUnsafe = Unsafe.getUnsafe(); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java Tue Oct 22 11:43:37 2013 +0200 @@ -73,4 +73,8 @@ * @return the encoded value as an integer */ Constant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason); + + DeoptimizationReason decodeDeoptReason(Constant constant); + + DeoptimizationAction decodeDeoptAction(Constant constant); } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Graal.java --- a/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Graal.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Graal.java Tue Oct 22 11:43:37 2013 +0200 @@ -69,10 +69,5 @@ public T getCapability(Class clazz) { return null; } - - @Override - public T getCapability(Class clazz, String selector) { - return null; - } } } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/GraalRuntime.java --- a/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/GraalRuntime.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/GraalRuntime.java Tue Oct 22 11:43:37 2013 +0200 @@ -27,14 +27,4 @@ String getName(); T getCapability(Class clazz); - - /** - * Requests a capability represented by a given class. - * - * @param selector a value the runtime will use to refine the capability returned (if any). An - * example may be the name of an architecture when asking for a capability - * representing a compiler backend. - */ - T getCapability(Class clazz, String selector); - } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java --- a/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Tue Oct 22 11:43:37 2013 +0200 @@ -918,9 +918,8 @@ public void emit(PTXAssembler asm) { if (booleanOperator != null) { - asm.emitString("setp." + operator.getOperator() + "." + booleanOperator.getOperator() + typeForKind(kind) + " %p" + predicate + emitValue(first) + emitValue(second) + ", %r;"); // Predicates -// need to be objects - + // Predicates need to be objects + asm.emitString("setp." + operator.getOperator() + "." + booleanOperator.getOperator() + typeForKind(kind) + " %p" + predicate + emitValue(first) + emitValue(second) + ", %r;"); } else { asm.emitString("setp." + operator.getOperator() + "." + typeForKind(kind) + " %p" + predicate + emitValue(first) + emitValue(second) + ";"); } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java --- a/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java Tue Oct 22 11:43:37 2013 +0200 @@ -30,6 +30,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.asm.*; +import com.oracle.graal.phases.util.*; +import com.oracle.graal.runtime.*; import com.oracle.graal.test.*; public abstract class AssemblerTest extends GraalTest { @@ -43,8 +45,9 @@ } public AssemblerTest() { - this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class); - this.codeCache = Graal.getRequiredCapability(CodeCacheProvider.class); + Providers providers = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders(); + this.metaAccess = providers.getMetaAccess(); + this.codeCache = providers.getCodeCache(); } public MetaAccessProvider getMetaAccess() { @@ -62,7 +65,7 @@ InstalledCode code = codeCache.addMethod(method, compResult); - DisassemblerProvider dis = Graal.getRuntime().getCapability(DisassemblerProvider.class); + DisassemblerProvider dis = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getDisassembler(); if (dis != null) { String disasm = dis.disassemble(code); Assert.assertTrue(code.toString(), disasm == null || disasm.length() > 0); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java Tue Oct 22 11:43:37 2013 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.compiler.test.*; import com.oracle.graal.hotspot.hsail.*; +import com.oracle.graal.hsail.*; import com.oracle.graal.nodes.*; /** @@ -34,7 +35,7 @@ public class BasicHSAILTest extends GraalCompilerTest { public BasicHSAILTest() { - super("HSAIL"); + super(HSAIL.class); } public void testAdd() { diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayPTXTest.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayPTXTest.java Tue Oct 22 11:43:37 2013 +0200 @@ -35,15 +35,9 @@ @Test public void testArray() { - int[] array1 = { - 1, 2, 3, 4, 5, 6, 7, 8, 9 - }; - int[] array2 = { - 1, 2, 3, 4, 5, 6, 7, 8, 9 - }; - int[] array3 = { - 1, 2, 3, 4, 5, 6, 7, 8, 9 - }; + int[] array1 = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + int[] array2 = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + int[] array3 = {1, 2, 3, 4, 5, 6, 7, 8, 9}; invoke(compile("testStoreArray1I"), array1, 2); printReport("testStoreArray1I: " + Arrays.toString(array1)); @@ -60,17 +54,14 @@ array[i] = 42; } - public static void testStoreArrayWarp0(int[] array, - @Warp(dimension = X) int i) { + public static void testStoreArrayWarp0(int[] array, @Warp(dimension = X) int i) { array[i] = 42; } - public static void testStoreArrayWarp1I(@ParallelOver(dimension = X) int[] array, - @Warp(dimension = X) int i) { + public static void testStoreArrayWarp1I(@ParallelOver(dimension = X) int[] array, @Warp(dimension = X) int i) { array[i] = 42; } - public static void main(String[] args) { ArrayPTXTest test = new ArrayPTXTest(); for (Method m : ArrayPTXTest.class.getMethods()) { diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java Tue Oct 22 11:43:37 2013 +0200 @@ -60,12 +60,10 @@ } else { printReport("testIfElse2I: no VALUE"); } - Boolean bret = (Boolean) invoke(compile("testIntegerTestBranch2I"), - 0xff00, 0x00ff); + Boolean bret = (Boolean) invoke(compile("testIntegerTestBranch2I"), 0xff00, 0x00ff); if (bret != null) { printReport("testIntegerTestBranch2I: " + bret); - printReport("testIntegerTestBranch2I: actual: " + - testIntegerTestBranch2I(0xff00, 0x00ff)); + printReport("testIntegerTestBranch2I: actual: " + testIntegerTestBranch2I(0xff00, 0x00ff)); } else { printReport("testIntegerTestBranch2I: no VALUE"); } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java Tue Oct 22 11:43:37 2013 +0200 @@ -31,6 +31,7 @@ @Test public void testAdd() { + // @formatter:off /* Integer r4 = (Integer) invoke(compile("testAdd2B"), (byte) 6, (byte) 4); if (r4 == null) { printReport("testAdd2B FAILED"); @@ -39,6 +40,7 @@ } else { printReport("testAdd2B FAILED"); } */ + // @formatter:on Integer r4 = (Integer) invoke(compile("testAdd2I"), 18, 24); if (r4 == null) { @@ -346,7 +348,6 @@ return (int) a; } - public static void main(String[] args) { IntegerPTXTest test = new IntegerPTXTest(); for (Method m : IntegerPTXTest.class.getMethods()) { diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java Tue Oct 22 11:43:37 2013 +0200 @@ -42,6 +42,7 @@ import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.ptx.*; public abstract class PTXTestBase extends GraalCompilerTest { @@ -55,7 +56,7 @@ } public PTXTestBase() { - super("PTX"); + super(PTX.class); } protected CompilationResult compile(String test) { diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Tue Oct 22 11:43:37 2013 +0200 @@ -242,14 +242,14 @@ case Object: append(new BranchOp(finalCondition, label, kind)); break; -// case Float: -// append(new CompareOp(FCMP, x, y)); -// append(new BranchOp(condition, label)); -// break; -// case Double: -// append(new CompareOp(DCMP, x, y)); -// append(new BranchOp(condition, label)); -// break; + // case Float: + // append(new CompareOp(FCMP, x, y)); + // append(new BranchOp(condition, label)); + // break; + // case Double: + // append(new CompareOp(DCMP, x, y)); + // append(new BranchOp(condition, label)); + // break; default: throw GraalInternalError.shouldNotReachHere("" + left.getKind()); } @@ -631,7 +631,7 @@ @Override public Value emitUDiv(Value a, Value b, DeoptimizingNode deopting) { -// LIRFrameState state = state(deopting); + // LIRFrameState state = state(deopting); switch (a.getKind().getStackKind()) { case Int: // emitDivRem(IUDIV, a, b, state); @@ -646,7 +646,7 @@ @Override public Value emitURem(Value a, Value b, DeoptimizingNode deopting) { -// LIRFrameState state = state(deopting); + // LIRFrameState state = state(deopting); switch (a.getKind().getStackKind()) { case Int: // emitDivRem(IUREM, a, b, state); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Oct 22 11:43:37 2013 +0200 @@ -54,6 +54,7 @@ import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.printer.*; +import com.oracle.graal.runtime.*; import com.oracle.graal.test.*; /** @@ -82,9 +83,9 @@ private final Suites suites; public GraalCompilerTest() { - this.backend = Graal.getRequiredCapability(Backend.class); + this.backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend(); this.providers = getBackend().getProviders(); - this.suites = Graal.getRequiredCapability(SuitesProvider.class).createSuites(); + this.suites = backend.getSuites().createSuites(); } /** @@ -93,16 +94,17 @@ * * @param arch the name of the desired backend architecture */ - public GraalCompilerTest(String arch) { - Backend b = Graal.getRuntime().getCapability(Backend.class, arch); + public GraalCompilerTest(Class arch) { + RuntimeProvider runtime = Graal.getRequiredCapability(RuntimeProvider.class); + Backend b = runtime.getBackend(arch); if (b != null) { this.backend = b; } else { // Fall back to the default/host backend - this.backend = Graal.getRuntime().getCapability(Backend.class); + this.backend = runtime.getHostBackend(); } this.providers = backend.getProviders(); - this.suites = Graal.getRequiredCapability(SuitesProvider.class).createSuites(); + this.suites = backend.getSuites().createSuites(); } @BeforeClass @@ -530,7 +532,7 @@ Debug.dump(new Object[]{compResult, code}, "After code installation"); } if (Debug.isLogEnabled()) { - DisassemblerProvider dis = Graal.getRuntime().getCapability(DisassemblerProvider.class); + DisassemblerProvider dis = backend.getDisassembler(); if (dis != null) { String text = dis.disassemble(code); if (text != null) { diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Tue Oct 22 11:43:37 2013 +0200 @@ -553,8 +553,7 @@ @Override public SchedulePhase call() throws Exception { Assumptions assumptions = new Assumptions(false); - HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), - OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new CanonicalizerPhase(true).apply(graph, context); if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); @@ -576,8 +575,7 @@ new FloatingReadPhase().apply(graph); new RemoveValueProxyPhase().apply(graph); - MidTierContext midContext = new MidTierContext(getProviders(), assumptions, getCodeCache().getTarget(), - OptimisticOptimizations.ALL); + MidTierContext midContext = new MidTierContext(getProviders(), assumptions, getCodeCache().getTarget(), OptimisticOptimizations.ALL); new GuardLoweringPhase().apply(graph, midContext); new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, midContext); new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, midContext); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Tue Oct 22 11:43:37 2013 +0200 @@ -86,7 +86,7 @@ PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false)); new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context); new FloatingReadPhase().apply(graph); - new EliminatePartiallyRedundantGuardsPhase(true, false).apply(graph); + new OptimizeGuardAnchors().apply(graph); new ReadEliminationPhase().apply(graph); new CanonicalizerPhase(true).apply(graph, context); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java Tue Oct 22 11:43:37 2013 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.compiler.test.ea; -import java.util.concurrent.*; - import org.junit.*; import com.oracle.graal.api.code.*; @@ -32,12 +30,14 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.java.*; +import com.oracle.graal.loop.phases.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.schedule.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.virtual.phases.ea.*; @@ -223,31 +223,97 @@ testEscapeAnalysis("testNewNodeSnippet", null, false); } - private ReturnNode testEscapeAnalysis(String snippet, final Constant expectedConstantResult, final boolean iterativeEscapeAnalysis) { - ResolvedJavaMethod method = getMetaAccess().lookupJavaMethod(getMethod(snippet)); - final StructuredGraph graph = new StructuredGraph(method); + private static final TestObject2 staticObj = new TestObject2(null); + + public static Object testFullyUnrolledLoopSnippet() { + /* + * This tests a case that can appear if PEA is performed both before and after loop + * unrolling/peeling: If the VirtualInstanceNode is not anchored correctly to stay within + * the loop, it will not be duplicated, and therefore the resulting object will reference + * itself, and not a second (different) object. + */ + TestObject2 obj = staticObj; + for (int i = 0; i < 2; i++) { + obj = new TestObject2(obj); + } + return obj.o; + } - return Debug.scope("GraalCompiler", new Object[]{graph, method, getCodeCache()}, new Callable() { + @Test + public void testFullyUnrolledLoop() { + testEscapeAnalysisUnrolled("testFullyUnrolledLoopSnippet"); + } + + private static Object staticField; + + private static TestObject2 inlinedPart(TestObject2 obj) { + TestObject2 ret = new TestObject2(obj); + staticField = null; + return ret; + } + + public static Object testPeeledLoopSnippet() { + TestObject2 obj = staticObj; + int i = 0; + do { + obj = inlinedPart(obj); + } while (i++ < 10); + staticField = obj; + return obj.o; + } - public ReturnNode call() { - new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); + @Test + public void testPeeledLoop() { + testEscapeAnalysisPeeled("testPeeledLoopSnippet"); + } + + private StructuredGraph graph; + private HighTierContext context; + private ReturnNode returnNode; + + private void testEscapeAnalysis(String snippet, final Constant expectedConstantResult, final boolean iterativeEscapeAnalysis) { + prepareGraph(snippet, iterativeEscapeAnalysis); + if (expectedConstantResult != null) { + Assert.assertTrue(returnNode.result().toString(), returnNode.result().isConstant()); + Assert.assertEquals(expectedConstantResult, returnNode.result().asConstant()); + } + int newInstanceCount = graph.getNodes().filter(NewInstanceNode.class).count() + graph.getNodes().filter(NewArrayNode.class).count() + + graph.getNodes().filter(CommitAllocationNode.class).count(); + Assert.assertEquals(0, newInstanceCount); + } + private void testEscapeAnalysisUnrolled(String snippet) { + prepareGraph(snippet, false); + new LoopFullUnrollPhase(new CanonicalizerPhase(true)).apply(graph, context); + new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context); + Assert.assertTrue(returnNode.result() instanceof AllocatedObjectNode); + CommitAllocationNode commit = ((AllocatedObjectNode) returnNode.result()).getCommit(); + Assert.assertEquals(1, commit.getValues().size()); + Assert.assertEquals(1, commit.getVirtualObjects().size()); + Assert.assertTrue("non-cyclic data structure expected", commit.getVirtualObjects().get(0) != commit.getValues().get(0)); + } + + private void testEscapeAnalysisPeeled(String snippet) { + prepareGraph(snippet, false); + new LoopTransformHighPhase().apply(graph); + new LoopTransformLowPhase().apply(graph); + new SchedulePhase().apply(graph); + } + + private void prepareGraph(String snippet, final boolean iterativeEscapeAnalysis) { + graph = new StructuredGraph(getMetaAccess().lookupJavaMethod(getMethod(snippet))); + Debug.scope("GraalCompiler", new Object[]{graph, getMetaAccess().lookupJavaMethod(getMethod(snippet)), getCodeCache()}, new Runnable() { + + public void run() { + new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); Assumptions assumptions = new Assumptions(false); - HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); new CanonicalizerPhase(true).apply(graph, context); new PartialEscapePhase(iterativeEscapeAnalysis, new CanonicalizerPhase(true)).apply(graph, context); Assert.assertEquals(1, graph.getNodes().filter(ReturnNode.class).count()); - ReturnNode returnNode = graph.getNodes().filter(ReturnNode.class).first(); - if (expectedConstantResult != null) { - Assert.assertTrue(returnNode.result().toString(), returnNode.result().isConstant()); - Assert.assertEquals(expectedConstantResult, returnNode.result().asConstant()); - } - int newInstanceCount = graph.getNodes().filter(NewInstanceNode.class).count() + graph.getNodes().filter(NewArrayNode.class).count() + - graph.getNodes().filter(CommitAllocationNode.class).count(); - Assert.assertEquals(0, newInstanceCount); - return returnNode; + returnNode = graph.getNodes().filter(ReturnNode.class).first(); } }); } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Tue Oct 22 11:43:37 2013 +0200 @@ -32,7 +32,6 @@ import com.oracle.graal.alloc.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.alloc.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; @@ -133,9 +132,9 @@ * argument can be null. * @return the result of the compilation */ - public static CompilationResult compileGraph(final StructuredGraph graph, final CallingConvention cc, final ResolvedJavaMethod installedCodeOwner, final Providers providers, + public static T compileGraph(final StructuredGraph graph, final CallingConvention cc, final ResolvedJavaMethod installedCodeOwner, final Providers providers, final Backend backend, final TargetDescription target, final GraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts, - final SpeculationLog speculationLog, final Suites suites, final CompilationResult compilationResult) { + final SpeculationLog speculationLog, final Suites suites, final T compilationResult) { Debug.scope("GraalCompiler", new Object[]{graph, providers.getCodeCache()}, new Runnable() { public void run() { @@ -290,17 +289,4 @@ Debug.dump(result, "After code generation"); } - - /** - * Creates a set of providers via {@link Graal#getRequiredCapability(Class)}. - */ - public static Providers getGraalProviders() { - MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class); - CodeCacheProvider codeCache = Graal.getRequiredCapability(CodeCacheProvider.class); - ConstantReflectionProvider constantReflection = Graal.getRequiredCapability(ConstantReflectionProvider.class); - ForeignCallsProvider foreignCalls = Graal.getRequiredCapability(ForeignCallsProvider.class); - LoweringProvider lowerer = Graal.getRequiredCapability(LoweringProvider.class); - Replacements replacements = Graal.getRequiredCapability(Replacements.class); - return new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements); - } } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Tue Oct 22 11:43:37 2013 +0200 @@ -52,6 +52,8 @@ "Complete - aggregate by qualified name%n" + "Thread - aggregate by qualified name and thread") public static final OptionValue DebugValueSummary = new OptionValue<>("Name"); + @Option(help = "Omit reporting 0-value metrics") + public static final OptionValue SuppressZeroDebugValues = new OptionValue<>(false); @Option(help = "Send Graal IR to dump handlers on error") public static final OptionValue DumpOnError = new OptionValue<>(false); @Option(help = "Enable expensive assertions") diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Tue Oct 22 11:43:37 2013 +0200 @@ -64,7 +64,7 @@ } if (OptEliminatePartiallyRedundantGuards.getValue()) { - appendPhase(new EliminatePartiallyRedundantGuardsPhase(false, true)); + appendPhase(new OptimizeGuardAnchors()); } if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { @@ -72,7 +72,7 @@ } if (OptEliminatePartiallyRedundantGuards.getValue()) { - appendPhase(new EliminatePartiallyRedundantGuardsPhase(true, true)); + appendPhase(new OptimizeGuardAnchors()); } if (OptCanonicalizer.getValue()) { diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Tue Oct 22 11:43:37 2013 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; /** @@ -54,6 +55,10 @@ return providers.getForeignCalls(); } + public abstract SuitesProvider getSuites(); + + public abstract DisassemblerProvider getDisassembler(); + public TargetDescription getTarget() { return providers.getCodeCache().getTarget(); } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MetricImpl.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MetricImpl.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MetricImpl.java Tue Oct 22 11:43:37 2013 +0200 @@ -28,6 +28,8 @@ public MetricImpl(String name, boolean conditional) { super(name, conditional); + // Allows for zero-count metrics to be shown + getCurrentValue(); } public void increment() { diff -r 3ee8ae69d676 -r ce8dd5fa8d54 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 Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Tue Oct 22 11:43:37 2013 +0200 @@ -125,7 +125,8 @@ return registry.make(key); } - static final int NOT_ITERABLE = -1; + public static final int NOT_ITERABLE = -1; + public static final int NODE_LIST = -2; private static final Class NODE_CLASS = Node.class; private static final Class INPUT_LIST_CLASS = NodeInputList.class; @@ -817,6 +818,12 @@ } } + public NodeList getNodeList(Node node, Position pos) { + long offset = pos.input ? inputOffsets[pos.index] : successorOffsets[pos.index]; + assert pos.subIndex == NODE_LIST; + return getNodeList(node, offset); + } + public String getName(Position pos) { return fieldNames.get(pos.input ? inputOffsets[pos.index] : successorOffsets[pos.index]); } @@ -1175,20 +1182,64 @@ return false; } - public List getFirstLevelInputPositions() { - List positions = new ArrayList<>(inputOffsets.length); - for (int i = 0; i < inputOffsets.length; i++) { - positions.add(new Position(true, i, NOT_ITERABLE)); - } - return positions; + public Collection getFirstLevelInputPositions() { + return new AbstractCollection() { + @Override + public Iterator iterator() { + return new Iterator() { + int i = 0; + + public void remove() { + throw new UnsupportedOperationException(); + } + + public Position next() { + Position pos = new Position(true, i, i >= directInputCount ? 0 : NOT_ITERABLE); + i++; + return pos; + } + + public boolean hasNext() { + return i < inputOffsets.length; + } + }; + } + + @Override + public int size() { + return inputOffsets.length; + } + }; } - public List getFirstLevelSuccessorPositions() { - List positions = new ArrayList<>(successorOffsets.length); - for (int i = 0; i < successorOffsets.length; i++) { - positions.add(new Position(false, i, NOT_ITERABLE)); - } - return positions; + public Collection getFirstLevelSuccessorPositions() { + return new AbstractCollection() { + @Override + public Iterator iterator() { + return new Iterator() { + int i = 0; + + public void remove() { + throw new UnsupportedOperationException(); + } + + public Position next() { + Position pos = new Position(false, i, i >= directSuccessorCount ? 0 : NOT_ITERABLE); + i++; + return pos; + } + + public boolean hasNext() { + return i < successorOffsets.length; + } + }; + } + + @Override + public int size() { + return successorOffsets.length; + } + }; } public Class getJavaClass() { diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Tue Oct 22 11:43:37 2013 +0200 @@ -39,6 +39,7 @@ import com.oracle.graal.asm.amd64.*; import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; @@ -239,6 +240,19 @@ Label verifiedStub = new Label(); // Emit the prefix + emitCodePrefix(installedCodeOwner, tasm, asm, regConfig, config, verifiedStub); + + // Emit code for the LIR + emitCodeBody(installedCodeOwner, tasm, lirGen); + + // Emit the suffix + emitCodeSuffix(installedCodeOwner, tasm, lirGen, asm, frameMap); + } + + /** + * @param installedCodeOwner see {@link Backend#emitCode} + */ + protected void emitCodePrefix(ResolvedJavaMethod installedCodeOwner, TargetMethodAssembler tasm, AMD64MacroAssembler asm, RegisterConfig regConfig, HotSpotVMConfig config, Label verifiedStub) { HotSpotProviders providers = getProviders(); if (installedCodeOwner != null && !isStatic(installedCodeOwner.getModifiers())) { tasm.recordMark(Marks.MARK_UNVERIFIED_ENTRY); @@ -263,10 +277,20 @@ tasm.recordMark(Marks.MARK_OSR_ENTRY); asm.bind(verifiedStub); tasm.recordMark(Marks.MARK_VERIFIED_ENTRY); + } - // Emit code for the LIR + /** + * @param installedCodeOwner see {@link Backend#emitCode} + */ + protected void emitCodeBody(ResolvedJavaMethod installedCodeOwner, TargetMethodAssembler tasm, LIRGenerator lirGen) { lirGen.lir.emitCode(tasm); + } + /** + * @param installedCodeOwner see {@link Backend#emitCode} + */ + protected void emitCodeSuffix(ResolvedJavaMethod installedCodeOwner, TargetMethodAssembler tasm, LIRGenerator lirGen, AMD64MacroAssembler asm, FrameMap frameMap) { + HotSpotProviders providers = getProviders(); HotSpotFrameContext frameContext = (HotSpotFrameContext) tasm.frameContext; if (frameContext != null && !frameContext.isStub) { HotSpotForeignCallsProvider foreignCalls = providers.getForeignCalls(); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Tue Oct 22 11:43:37 2013 +0200 @@ -30,6 +30,7 @@ import com.oracle.graal.api.runtime.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.util.*; @ServiceProvider(HotSpotBackendFactory.class) @@ -51,26 +52,67 @@ assert host == null; TargetDescription target = createTarget(runtime.getConfig()); - HotSpotMetaAccessProvider metaAccess = new HotSpotMetaAccessProvider(runtime); - HotSpotCodeCacheProvider codeCache = new AMD64HotSpotCodeCacheProvider(runtime, target); - HotSpotConstantReflectionProvider constantReflection = new HotSpotConstantReflectionProvider(runtime); + HotSpotMetaAccessProvider metaAccess = createMetaAccess(runtime); + HotSpotCodeCacheProvider codeCache = createCodeCache(runtime, target); + HotSpotConstantReflectionProvider constantReflection = createConstantReflection(runtime); Value[] nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(runtime.getConfig(), codeCache.getRegisterConfig()); - HotSpotForeignCallsProvider foreignCalls = new AMD64HotSpotForeignCallsProvider(runtime, metaAccess, codeCache, nativeABICallerSaveRegisters); - HotSpotLoweringProvider lowerer = new AMD64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls); + HotSpotForeignCallsProvider foreignCalls = createForeignCalls(runtime, metaAccess, codeCache, nativeABICallerSaveRegisters); + HotSpotLoweringProvider lowerer = createLowerer(runtime, metaAccess, foreignCalls); // Replacements cannot have speculative optimizations since they have // to be valid for the entire run of the VM. Assumptions assumptions = new Assumptions(false); Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null); - HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, runtime.getConfig(), assumptions); - HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(runtime); - HotSpotSuitesProvider suites = new HotSpotSuitesProvider(runtime); - HotSpotRegisters registers = new HotSpotRegisters(AMD64.r15, AMD64.r12, AMD64.rsp); + Replacements replacements = createReplacements(runtime, assumptions, p); + HotSpotDisassemblerProvider disassembler = createDisassembler(runtime); + HotSpotSuitesProvider suites = createSuites(runtime); + HotSpotRegisters registers = createRegisters(); HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); + return createBackend(runtime, providers); + } + + protected AMD64HotSpotBackend createBackend(HotSpotGraalRuntime runtime, HotSpotProviders providers) { return new AMD64HotSpotBackend(runtime, providers); } - private static Value[] createNativeABICallerSaveRegisters(HotSpotVMConfig config, RegisterConfig regConfig) { + protected HotSpotRegisters createRegisters() { + return new HotSpotRegisters(AMD64.r15, AMD64.r12, AMD64.rsp); + } + + protected HotSpotDisassemblerProvider createDisassembler(HotSpotGraalRuntime runtime) { + return new HotSpotDisassemblerProvider(runtime); + } + + protected Replacements createReplacements(HotSpotGraalRuntime runtime, Assumptions assumptions, Providers p) { + return new HotSpotReplacementsImpl(p, runtime.getConfig(), assumptions); + } + + protected AMD64HotSpotForeignCallsProvider createForeignCalls(HotSpotGraalRuntime runtime, HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, + Value[] nativeABICallerSaveRegisters) { + return new AMD64HotSpotForeignCallsProvider(runtime, metaAccess, codeCache, nativeABICallerSaveRegisters); + } + + protected HotSpotConstantReflectionProvider createConstantReflection(HotSpotGraalRuntime runtime) { + return new HotSpotConstantReflectionProvider(runtime); + } + + protected AMD64HotSpotCodeCacheProvider createCodeCache(HotSpotGraalRuntime runtime, TargetDescription target) { + return new AMD64HotSpotCodeCacheProvider(runtime, target); + } + + protected HotSpotMetaAccessProvider createMetaAccess(HotSpotGraalRuntime runtime) { + return new HotSpotMetaAccessProvider(runtime); + } + + protected HotSpotSuitesProvider createSuites(HotSpotGraalRuntime runtime) { + return new HotSpotSuitesProvider(runtime); + } + + protected AMD64HotSpotLoweringProvider createLowerer(HotSpotGraalRuntime runtime, HotSpotMetaAccessProvider metaAccess, HotSpotForeignCallsProvider foreignCalls) { + return new AMD64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls); + } + + protected Value[] createNativeABICallerSaveRegisters(HotSpotVMConfig config, RegisterConfig regConfig) { List callerSave = new ArrayList<>(Arrays.asList(regConfig.getAllocatableRegisters())); if (config.windowsOs) { // http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java Tue Oct 22 11:43:37 2013 +0200 @@ -81,7 +81,7 @@ if (hsailCompResult != null) { hsailCompResult.dumpCompilationResult(); } - return hsailCompResult.getCompilationResult(); + return hsailCompResult; } // Implementations of the CompileAndDispatch interface. diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILCompilationResult.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILCompilationResult.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILCompilationResult.java Tue Oct 22 11:43:37 2013 +0200 @@ -33,10 +33,10 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.*; -import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hsail.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; @@ -44,13 +44,15 @@ import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; +import com.oracle.graal.runtime.*; /** * Class that represents a HSAIL compilation result. Includes the compiled HSAIL code. */ -public class HSAILCompilationResult { +public class HSAILCompilationResult extends CompilationResult { - private CompilationResult compResult; + private static final long serialVersionUID = -4178700465275724625L; + private static final String propPkgName = HSAILCompilationResult.class.getPackage().getName(); private static Level logLevel; private static ConsoleHandler consoleHandler; @@ -78,7 +80,8 @@ static final HSAILHotSpotBackend backend; static { // Look for installed HSAIL backend - HSAILHotSpotBackend b = (HSAILHotSpotBackend) Graal.getRuntime().getCapability(Backend.class, "HSAIL"); + RuntimeProvider runtime = Graal.getRequiredCapability(RuntimeProvider.class); + HSAILHotSpotBackend b = (HSAILHotSpotBackend) runtime.getBackend(HSAIL.class); if (b == null) { // Fall back to a new instance b = new HSAILHotSpotBackendFactory().createBackend(runtime(), runtime().getHostBackend()); @@ -137,11 +140,11 @@ phasePlan.addPhase(PhasePosition.AFTER_PARSING, new HSAILPhase()); new HSAILPhase().apply(graph); CallingConvention cc = getHSAILCallingConvention(Type.JavaCallee, target, graph.method(), false); - SuitesProvider suitesProvider = Graal.getRequiredCapability(SuitesProvider.class); + SuitesProvider suitesProvider = backend.getSuites(); try { - CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, graph.method(), providers, backend, target, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), - suitesProvider.getDefaultSuites(), new CompilationResult()); - return new HSAILCompilationResult(compResult); + HSAILCompilationResult compResult = GraalCompiler.compileGraph(graph, cc, graph.method(), providers, backend, target, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), + suitesProvider.getDefaultSuites(), new HSAILCompilationResult()); + return compResult; } catch (GraalInternalError e) { String partialCode = backend.getPartialCodeString(); if (partialCode != null && !partialCode.equals("")) { @@ -165,20 +168,15 @@ } } - protected HSAILCompilationResult(CompilationResult compResultInput) { - compResult = compResultInput; - } - - public CompilationResult getCompilationResult() { - return compResult; + protected HSAILCompilationResult() { } public String getHSAILCode() { - return new String(compResult.getTargetCode(), 0, compResult.getTargetCodeSize()); + return new String(getTargetCode(), 0, getTargetCodeSize()); } public void dumpCompilationResult() { - logger.fine("targetCodeSize=" + compResult.getTargetCodeSize()); + logger.fine("targetCodeSize=" + getTargetCodeSize()); logger.fine(getHSAILCode()); } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotCodeCacheProvider.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotCodeCacheProvider.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotCodeCacheProvider.java Tue Oct 22 11:43:37 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.hotspot.hsail; +import java.util.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; @@ -35,6 +37,12 @@ } @Override + public String disassemble(CompilationResult compResult, InstalledCode installedCode) { + byte[] code = installedCode == null ? Arrays.copyOf(compResult.getTargetCode(), compResult.getTargetCodeSize()) : installedCode.getCode(); + return new String(code); + } + + @Override protected RegisterConfig createRegisterConfig() { return new HSAILRegisterConfig(); } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java Tue Oct 22 11:43:37 2013 +0200 @@ -55,10 +55,7 @@ private final Register[] nativeGeneralParameterRegisters; private static Register[] initAllocatable() { - Register[] registers = new Register[] { - r0, r1, r2, r3, r4, r5, r6, r7, - r8, r9, r10, r11, r12, r13, r14, r15, - }; + Register[] registers = new Register[]{r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15}; return registers; } @@ -94,9 +91,8 @@ throw GraalInternalError.unimplemented("PTXHotSpotRegisterConfig.getRegisterForRole()"); } - private static CallingConvention callingConvention(@SuppressWarnings("unused") Register[] generalParameterRegisters, - JavaType returnType, JavaType[] parameterTypes, - Type type, TargetDescription target, boolean stackOnly) { + private static CallingConvention callingConvention(@SuppressWarnings("unused") Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, + TargetDescription target, boolean stackOnly) { assert stackOnly == false; diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java Tue Oct 22 11:43:37 2013 +0200 @@ -41,13 +41,13 @@ @Override public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { // TODO the patched call address looks odd (and is invalid) compared to other runtime calls: -// 0xffffffff749bb5fc: call 0xffffffff415a720c ; {runtime_call} -// [Exception Handler] -// 0xffffffff749bb604: call 0xffffffff749bb220 ; {runtime_call} -// 0xffffffff749bb608: nop -// [Deopt Handler Code] -// 0xffffffff749bb60c: call 0xffffffff748da540 ; {runtime_call} -// 0xffffffff749bb610: nop + // 0xffffffff749bb5fc: call 0xffffffff415a720c ; {runtime_call} + // [Exception Handler] + // 0xffffffff749bb604: call 0xffffffff749bb220 ; {runtime_call} + // 0xffffffff749bb608: nop + // [Deopt Handler Code] + // 0xffffffff749bb60c: call 0xffffffff748da540 ; {runtime_call} + // 0xffffffff749bb610: nop SPARCCall.directCall(tasm, masm, tasm.foreignCalls.lookupForeignCall(UNCOMMON_TRAP), null, false, info); } } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java Tue Oct 22 11:43:37 2013 +0200 @@ -41,14 +41,14 @@ public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { leaveFrame(tasm); -// SPARCHotSpotBackend backend = (SPARCHotSpotBackend) -// HotSpotGraalRuntime.runtime().getBackend(); -// final boolean isStub = true; -// HotSpotFrameContext frameContext = backend.new HotSpotFrameContext(isStub); -// frameContext.enter(tasm); + // SPARCHotSpotBackend backend = (SPARCHotSpotBackend) + // HotSpotGraalRuntime.runtime().getBackend(); + // final boolean isStub = true; + // HotSpotFrameContext frameContext = backend.new HotSpotFrameContext(isStub); + // frameContext.enter(tasm); Register scratch = g3; SPARCCall.indirectJmp(tasm, masm, scratch, tasm.foreignCalls.lookupForeignCall(UNCOMMON_TRAP)); -// frameContext.leave(tasm); + // frameContext.leave(tasm); } } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Tue Oct 22 11:43:37 2013 +0200 @@ -154,7 +154,7 @@ @Override public void emitTailcall(Value[] args, Value address) { -// append(new AMD64TailcallOp(args, address)); + // append(new AMD64TailcallOp(args, address)); throw GraalInternalError.unimplemented(); } @@ -242,14 +242,16 @@ assert access == null || access instanceof HeapAccess; if (isCompressCandidate(access)) { if (config.useCompressedOops && kind == Kind.Object) { -// append(new LoadCompressedPointer(kind, result, loadAddress, access != null ? state(access) : -// null, config.narrowOopBase, config.narrowOopShift, -// config.logMinObjAlignment)); + // append(new LoadCompressedPointer(kind, result, loadAddress, access != null ? + // state(access) : + // null, config.narrowOopBase, config.narrowOopShift, + // config.logMinObjAlignment)); throw GraalInternalError.unimplemented(); } else if (config.useCompressedClassPointers && kind == Kind.Long) { -// append(new LoadCompressedPointer(kind, result, loadAddress, access != null ? state(access) : -// null, config.narrowKlassBase, config.narrowKlassShift, -// config.logKlassAlignment)); + // append(new LoadCompressedPointer(kind, result, loadAddress, access != null ? + // state(access) : + // null, config.narrowKlassBase, config.narrowKlassShift, + // config.logKlassAlignment)); throw GraalInternalError.unimplemented(); } else { append(new LoadOp(kind, result, loadAddress, access != null ? state(access) : null)); @@ -280,21 +282,21 @@ Variable input = load(inputVal); if (isCompressCandidate(access)) { if (config.useCompressedOops && kind == Kind.Object) { -// if (input.getKind() == Kind.Object) { -// Variable scratch = newVariable(Kind.Long); -// append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, -// config.narrowOopBase, config.narrowOopShift, -// config.logMinObjAlignment)); -// } else { -// // the input oop is already compressed -// append(new StoreOp(input.getKind(), storeAddress, input, state)); -// } + // if (input.getKind() == Kind.Object) { + // Variable scratch = newVariable(Kind.Long); + // append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, + // config.narrowOopBase, config.narrowOopShift, + // config.logMinObjAlignment)); + // } else { + // // the input oop is already compressed + // append(new StoreOp(input.getKind(), storeAddress, input, state)); + // } throw GraalInternalError.unimplemented(); } else if (config.useCompressedClassPointers && kind == Kind.Long) { -// Variable scratch = newVariable(Kind.Long); -// append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, -// config.narrowKlassBase, config.narrowKlassShift, -// config.logKlassAlignment)); + // Variable scratch = newVariable(Kind.Long); + // append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, + // config.narrowKlassBase, config.narrowKlassShift, + // config.logKlassAlignment)); throw GraalInternalError.unimplemented(); } else { append(new StoreOp(kind, storeAddress, input, state)); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Tue Oct 22 11:43:37 2013 +0200 @@ -41,6 +41,7 @@ import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.runtime.*; /** * use @@ -204,7 +205,7 @@ phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); // create suites everytime, as we modify options for the compiler - final Suites suitesLocal = Graal.getRequiredCapability(SuitesProvider.class).createSuites(); + final Suites suitesLocal = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites().createSuites(); final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog(), suitesLocal, new CompilationResult()); addMethod(method, compResult); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java Tue Oct 22 11:43:37 2013 +0200 @@ -33,6 +33,7 @@ import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.runtime.*; /** * The following tests perform object/array equality and assignments in various ways. The selected @@ -43,7 +44,7 @@ private final MetaAccessProvider metaAccess; public CompressedOopTest() { - this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class); + this.metaAccess = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders().getMetaAccess(); } private HotSpotInstalledCode getInstalledCode(String name) throws Exception { diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java Tue Oct 22 11:43:37 2013 +0200 @@ -35,6 +35,7 @@ import com.oracle.graal.compiler.test.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.runtime.*; public class InstalledCodeExecuteHelperTest extends GraalCompilerTest { @@ -43,7 +44,7 @@ Object[] argsToBind; public InstalledCodeExecuteHelperTest() { - this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class); + this.metaAccess = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders().getMetaAccess(); } @Test diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Tue Oct 22 11:43:37 2013 +0200 @@ -43,6 +43,7 @@ import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.runtime.*; /** * The following unit tests assert the presence of write barriers for both Serial and G1 GCs. @@ -58,7 +59,7 @@ private final MetaAccessProvider metaAccess; public WriteBarrierAdditionTest() { - this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class); + this.metaAccess = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders().getMetaAccess(); } public static class Container { diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Tue Oct 22 11:43:37 2013 +0200 @@ -140,7 +140,11 @@ @Override public CompilationResult call() throws Exception { - backend.getRuntime().evictDeoptedGraphs(); + GraphCache graphCache = backend.getRuntime().getGraphCache(); + if (graphCache != null) { + graphCache.removeStaleGraphs(); + } + HotSpotProviders providers = backend.getProviders(); Replacements replacements = providers.getReplacements(); graph = replacements.getMethodSubstitution(method); @@ -153,8 +157,8 @@ InliningUtil.InlinedBytecodes.add(method.getCodeSize()); CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); Suites suites = providers.getSuites().getDefaultSuites(); - return GraalCompiler.compileGraph(graph, cc, method, providers, backend, backend.getTarget(), backend.getRuntime().getCache(), plan, optimisticOpts, - method.getSpeculationLog(), suites, new CompilationResult()); + return GraalCompiler.compileGraph(graph, cc, method, providers, backend, backend.getTarget(), graphCache, plan, optimisticOpts, method.getSpeculationLog(), suites, + new CompilationResult()); } }); } finally { diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java Tue Oct 22 11:43:37 2013 +0200 @@ -22,12 +22,14 @@ */ package com.oracle.graal.hotspot; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.phases.tiers.*; import com.oracle.graal.word.*; /** @@ -82,4 +84,14 @@ public HotSpotProviders getProviders() { return (HotSpotProviders) super.getProviders(); } + + @Override + public SuitesProvider getSuites() { + return getProviders().getSuites(); + } + + @Override + public DisassemblerProvider getDisassembler() { + return getProviders().getDisassembler(); + } } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Tue Oct 22 11:43:37 2013 +0200 @@ -38,15 +38,14 @@ import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.logging.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.options.*; import com.oracle.graal.phases.*; -import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.runtime.*; /** * Singleton class holding the instance of the {@link GraalRuntime}. */ -public final class HotSpotGraalRuntime implements GraalRuntime { +public final class HotSpotGraalRuntime implements GraalRuntime, RuntimeProvider { private static final HotSpotGraalRuntime instance = new HotSpotGraalRuntime(); static { @@ -106,11 +105,11 @@ for (HotSpotBackendFactory factory : ServiceLoader.loadInstalled(HotSpotBackendFactory.class)) { if (factory.getArchitecture().equalsIgnoreCase(architecture)) { if (factory.getGraalRuntimeName().equals(GraalRuntime.getValue())) { - assert selected == null; + assert selected == null || checkFactoryOverriding(selected, factory); selected = factory; } if (factory.getGraalRuntimeName().equals("basic")) { - assert basic == null; + assert basic == null || checkFactoryOverriding(basic, factory); basic = factory; } else { nonBasic = factory; @@ -136,6 +135,18 @@ } /** + * Checks that a factory overriding is valid. A factory B can only override/replace a factory A + * if the B.getClass() is a subclass of A.getClass(). This models the assumption that B is + * extends the behavior of A and has therefore understood the behavior expected of A. + * + * @param baseFactory + * @param overridingFactory + */ + private static boolean checkFactoryOverriding(HotSpotBackendFactory baseFactory, HotSpotBackendFactory overridingFactory) { + return baseFactory.getClass().isAssignableFrom(overridingFactory.getClass()); + } + + /** * Gets the kind of a word value on the {@linkplain #getHostBackend() host} backend. */ public static Kind getHostWordKind() { @@ -173,15 +184,13 @@ protected/* final */CompilerToGPU compilerToGpu; protected/* final */VMToCompiler vmToCompiler; - protected final HotSpotProviders hostProviders; - private HotSpotRuntimeInterpreterInterface runtimeInterpreterInterface; private volatile HotSpotGraphCache cache; protected final HotSpotVMConfig config; private final HotSpotBackend hostBackend; - private final Map backends = new HashMap<>(); + private final Map, HotSpotBackend> backends = new HashMap<>(); private HotSpotGraalRuntime() { CompilerToVM toVM = new CompilerToVMImpl(); @@ -210,31 +219,36 @@ printConfig(config); } - String hostArchitecture = getHostArchitecture(); - hostBackend = findFactory(hostArchitecture).createBackend(this, null); - hostProviders = hostBackend.getProviders(); - backends.put(hostArchitecture, hostBackend); + String hostArchitecture = getHostArchitectureName(); + hostBackend = registerBackend(findFactory(hostArchitecture).createBackend(this, null)); - String[] gpuArchitectures = getGPUArchitectures(); + String[] gpuArchitectures = getGPUArchitectureNames(); for (String arch : gpuArchitectures) { HotSpotBackendFactory factory = findFactory(arch); if (factory == null) { throw new GraalInternalError("No backend available for specified GPU architecture \"%s\"", arch); } - backends.put(factory.getArchitecture(), factory.createBackend(this, hostBackend)); + registerBackend(factory.createBackend(this, hostBackend)); } GraalOptions.StackShadowPages.setValue(config.stackShadowPages); if (GraalOptions.CacheGraphs.getValue()) { - cache = new HotSpotGraphCache(); + cache = new HotSpotGraphCache(compilerToVm); } } + private HotSpotBackend registerBackend(HotSpotBackend backend) { + Class arch = backend.getTarget().arch.getClass(); + HotSpotBackend oldValue = backends.put(arch, backend); + assert oldValue == null : "cannot overwrite existing backend for architecture " + arch.getSimpleName(); + return backend; + } + /** * Gets the host architecture name for the purpose of finding the corresponding * {@linkplain HotSpotBackendFactory backend}. */ - private static String getHostArchitecture() { + private static String getHostArchitectureName() { String arch = System.getProperty("os.arch"); switch (arch) { case "x86_64": @@ -250,16 +264,17 @@ /** * Gets the names of the supported GPU architectures for the purpose of finding the * corresponding {@linkplain HotSpotBackendFactory backend} objects. This method first looks for - * a comma separated list of names in the {@value #GRAAL_GPU_ISALIST_PROPERTY_NAME} system - * property. If this property is not set, then the GPU native support code is queried. + * a comma or {@link java.io.File#pathSeparatorChar} separated list of names in the + * {@value #GRAAL_GPU_ISALIST_PROPERTY_NAME} system property. If this property is not set, then + * the GPU native support code is queried. */ - private String[] getGPUArchitectures() { + private static String[] getGPUArchitectureNames() { String gpuList = System.getProperty(GRAAL_GPU_ISALIST_PROPERTY_NAME); - if (gpuList != null) { - String[] gpus = gpuList.split(","); + if (gpuList != null && !gpuList.isEmpty()) { + String[] gpus = gpuList.split("[,:]"); return gpus; } - return compilerToGpu.getAvailableGPUArchitectures(); + return new String[0]; } private static void printConfig(HotSpotVMConfig config) { @@ -285,7 +300,7 @@ return hostBackend.getTarget(); } - public HotSpotGraphCache getCache() { + public HotSpotGraphCache getGraphCache() { return cache; } @@ -335,26 +350,13 @@ public HotSpotRuntimeInterpreterInterface getRuntimeInterpreterInterface() { if (runtimeInterpreterInterface == null) { - runtimeInterpreterInterface = new HotSpotRuntimeInterpreterInterface(hostProviders.getMetaAccess()); + runtimeInterpreterInterface = new HotSpotRuntimeInterpreterInterface(getHostProviders().getMetaAccess()); } return runtimeInterpreterInterface; } public HotSpotProviders getHostProviders() { - return hostProviders; - } - - public void evictDeoptedGraphs() { - if (cache != null) { - long[] deoptedGraphs = getCompilerToVM().getDeoptedLeafGraphIds(); - if (deoptedGraphs != null) { - if (deoptedGraphs.length == 0) { - cache.clear(); - } else { - cache.removeGraphs(deoptedGraphs); - } - } - } + return getHostBackend().getProviders(); } @Override @@ -363,60 +365,24 @@ } @SuppressWarnings("unchecked") - public static T getCapability(HotSpotBackend backend, Class clazz) { - HotSpotProviders providers = backend.getProviders(); - if (clazz == LoweringProvider.class) { - return (T) providers.getLowerer(); - } - if (clazz == CodeCacheProvider.class) { - return (T) providers.getCodeCache(); - } - if (clazz == MetaAccessProvider.class) { - return (T) providers.getMetaAccess(); - } - if (clazz == ConstantReflectionProvider.class) { - return (T) providers.getConstantReflection(); - } - if (clazz == ForeignCallsProvider.class) { - return (T) providers.getForeignCalls(); - } - if (clazz == DisassemblerProvider.class) { - return (T) providers.getDisassembler(); - } - if (clazz == BytecodeDisassemblerProvider.class) { - return (T) providers.getBytecodeDisassembler(); - } - if (clazz == SuitesProvider.class) { - return (T) providers.getSuites(); - } - if (clazz == Replacements.class) { - return (T) providers.getReplacements(); - } - if (clazz == HotSpotRegistersProvider.class) { - return (T) providers.getRegisters(); - } - if (clazz == Backend.class) { - return (T) backend; + @Override + public T getCapability(Class clazz) { + if (clazz == RuntimeProvider.class) { + return (T) this; } return null; } - @Override - public T getCapability(Class clazz) { - return getCapability(clazz, null); - } - - @Override - public T getCapability(Class clazz, String selector) { - HotSpotBackend backend = selector == null ? hostBackend : backends.get(selector); - return backend == null ? null : getCapability(backend, clazz); - } - public HotSpotBackend getHostBackend() { return hostBackend; } - public Map getBackends() { + public Backend getBackend(Class arch) { + assert arch != Architecture.class; + return backends.get(arch); + } + + public Map, HotSpotBackend> getBackends() { return Collections.unmodifiableMap(backends); } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPU.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPU.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPU.java Tue Oct 22 11:43:37 2013 +0200 @@ -48,11 +48,6 @@ int availableProcessors(); /** - * Gets the architecture names of the available GPUs. - */ - String[] getAvailableGPUArchitectures(); - - /** * Attempts to generate and return a bound function to the loaded method kernel on the GPU. * * @param code the text or binary values for a method kernel diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPUImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPUImpl.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPUImpl.java Tue Oct 22 11:43:37 2013 +0200 @@ -39,8 +39,6 @@ public native int availableProcessors(); - public native String[] getAvailableGPUArchitectures(); - public native Object executeExternalMethodVarargs(Object[] args, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; public native Object executeParallelMethodVarargs(int dimX, int dimY, int dimZ, Object[] args, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Tue Oct 22 11:43:37 2013 +0200 @@ -193,7 +193,7 @@ List initializedLowerers = new ArrayList<>(); List initializedForeignCalls = new ArrayList<>(); - for (Map.Entry e : runtime.getBackends().entrySet()) { + for (Map.Entry e : runtime.getBackends().entrySet()) { HotSpotBackend backend = e.getValue(); HotSpotProviders providers = backend.getProviders(); @@ -361,8 +361,8 @@ bootstrapRunning = false; TTY.println(" in %d ms (compiled %d methods)", System.currentTimeMillis() - startTime, compileQueue.getCompletedTaskCount()); - if (runtime.getCache() != null) { - runtime.getCache().clear(); + if (runtime.getGraphCache() != null) { + runtime.getGraphCache().clear(); } System.gc(); phaseTransition("bootstrap2"); @@ -533,7 +533,7 @@ for (DebugValue value : debugValues) { long l = scope.map.getCurrentValue(value.getIndex()); - if (l != 0) { + if (l != 0 || !SuppressZeroDebugValues.getValue()) { scope.print(); printIndent(scope.level + 1); TTY.println(value.getName() + "=" + value.toString(l)); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphCache.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphCache.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphCache.java Tue Oct 22 11:43:37 2013 +0200 @@ -30,6 +30,7 @@ import java.util.Map.Entry; import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -96,7 +97,8 @@ private final Map> cachedGraphIds = Collections.synchronizedMap(new LRUCache()); - public HotSpotGraphCache() { + public HotSpotGraphCache(CompilerToVM compilerToVM) { + this.compilerToVM = compilerToVM; if (PrintGraphCache.getValue()) { Runtime.getRuntime().addShutdownHook(new Thread() { @@ -127,7 +129,7 @@ } @Override - public void put(StructuredGraph graph, boolean hasMatureProfilingInfo) { + public boolean put(StructuredGraph graph, boolean hasMatureProfilingInfo) { assert graph.method() != null; if (hasMatureProfilingInfo) { cachedGraphIds.put(graph.graphId(), new WeakReference<>(graph.method())); @@ -136,7 +138,9 @@ if (PrintGraphCache.getValue()) { putCounter++; } + return true; } + return false; } public void clear() { @@ -174,4 +178,17 @@ } } } + + private final CompilerToVM compilerToVM; + + public void removeStaleGraphs() { + long[] deoptedGraphs = compilerToVM.getDeoptedLeafGraphIds(); + if (deoptedGraphs != null) { + if (deoptedGraphs.length == 0) { + clear(); + } else { + removeGraphs(deoptedGraphs); + } + } + } } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Tue Oct 22 11:43:37 2013 +0200 @@ -79,14 +79,29 @@ return runtime.getCompilerToVM().getJavaField(reflectionField); } + private static final int ACTION_SHIFT = 0; + private static final int ACTION_MASK = 0x07; + private static final int REASON_SHIFT = 3; + private static final int REASON_MASK = 0x1f; + @Override public Constant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason) { - final int actionShift = 0; - final int reasonShift = 3; - int actionValue = convertDeoptAction(action); int reasonValue = convertDeoptReason(reason); - return Constant.forInt(~(((reasonValue) << reasonShift) + ((actionValue) << actionShift))); + Constant c = Constant.forInt(~(((reasonValue) << REASON_SHIFT) + ((actionValue) << ACTION_SHIFT))); + return c; + } + + public DeoptimizationReason decodeDeoptReason(Constant constant) { + int reasonValue = ((~constant.asInt()) >> REASON_SHIFT) & REASON_MASK; + DeoptimizationReason reason = convertDeoptReason(reasonValue); + return reason; + } + + public DeoptimizationAction decodeDeoptAction(Constant constant) { + int actionValue = ((~constant.asInt()) >> ACTION_SHIFT) & ACTION_MASK; + DeoptimizationAction action = convertDeoptAction(actionValue); + return action; } public int convertDeoptAction(DeoptimizationAction action) { @@ -106,6 +121,22 @@ } } + public DeoptimizationAction convertDeoptAction(int action) { + if (action == runtime.getConfig().deoptActionNone) { + return DeoptimizationAction.None; + } else if (action == runtime.getConfig().deoptActionMaybeRecompile) { + return DeoptimizationAction.RecompileIfTooManyDeopts; + } else if (action == runtime.getConfig().deoptActionReinterpret) { + return DeoptimizationAction.InvalidateReprofile; + } else if (action == runtime.getConfig().deoptActionMakeNotEntrant) { + return DeoptimizationAction.InvalidateRecompile; + } else if (action == runtime.getConfig().deoptActionMakeNotCompilable) { + return DeoptimizationAction.InvalidateStopCompiling; + } else { + throw GraalInternalError.shouldNotReachHere(); + } + } + public int convertDeoptReason(DeoptimizationReason reason) { switch (reason) { case None: @@ -140,4 +171,38 @@ throw GraalInternalError.shouldNotReachHere(); } } + + public DeoptimizationReason convertDeoptReason(int reason) { + if (reason == runtime.getConfig().deoptReasonNone) { + return DeoptimizationReason.None; + } else if (reason == runtime.getConfig().deoptReasonNullCheck) { + return DeoptimizationReason.NullCheckException; + } else if (reason == runtime.getConfig().deoptReasonRangeCheck) { + return DeoptimizationReason.BoundsCheckException; + } else if (reason == runtime.getConfig().deoptReasonClassCheck) { + return DeoptimizationReason.ClassCastException; + } else if (reason == runtime.getConfig().deoptReasonArrayCheck) { + return DeoptimizationReason.ArrayStoreException; + } else if (reason == runtime.getConfig().deoptReasonUnreached0) { + return DeoptimizationReason.UnreachedCode; + } else if (reason == runtime.getConfig().deoptReasonTypeCheckInlining) { + return DeoptimizationReason.TypeCheckedInliningViolated; + } else if (reason == runtime.getConfig().deoptReasonOptimizedTypeCheck) { + return DeoptimizationReason.OptimizedTypeCheckViolated; + } else if (reason == runtime.getConfig().deoptReasonNotCompiledExceptionHandler) { + return DeoptimizationReason.NotCompiledExceptionHandler; + } else if (reason == runtime.getConfig().deoptReasonUnresolved) { + return DeoptimizationReason.Unresolved; + } else if (reason == runtime.getConfig().deoptReasonJsrMismatch) { + return DeoptimizationReason.JavaSubroutineMismatch; + } else if (reason == runtime.getConfig().deoptReasonDiv0Check) { + return DeoptimizationReason.ArithmeticException; + } else if (reason == runtime.getConfig().deoptReasonConstraint) { + return DeoptimizationReason.RuntimeConstraint; + } else if (reason == runtime.getConfig().deoptReasonLoopLimitCheck) { + return DeoptimizationReason.LoopLimitCheck; + } else { + throw GraalInternalError.shouldNotReachHere(Integer.toHexString(reason)); + } + } } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProviders.java Tue Oct 22 11:43:37 2013 +0200 @@ -23,7 +23,6 @@ package com.oracle.graal.hotspot.meta; import com.oracle.graal.api.meta.*; -import com.oracle.graal.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.util.*; @@ -59,10 +58,6 @@ return disassembler; } - public BytecodeDisassemblerProvider getBytecodeDisassembler() { - return new BytecodeDisassembler(); - } - @Override public HotSpotForeignCallsProvider getForeignCalls() { return (HotSpotForeignCallsProvider) super.getForeignCalls(); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Tue Oct 22 11:43:37 2013 +0200 @@ -93,7 +93,8 @@ } // the canonicalization before loop unrolling is needed to propagate the length into // additions, etc. - PhaseContext context = new PhaseContext(tool.getMetaAccess(), tool.getCodeCache(), tool.getConstantReflection(), tool.getForeignCalls(), tool.getLowerer(), tool.assumptions(), tool.getReplacements()); + PhaseContext context = new PhaseContext(tool.getMetaAccess(), tool.getCodeCache(), tool.getConstantReflection(), tool.getForeignCalls(), tool.getLowerer(), tool.assumptions(), + tool.getReplacements()); new CanonicalizerPhase(true).apply(snippetGraph, context); new LoopFullUnrollPhase(new CanonicalizerPhase(true)).apply(snippetGraph, context); new CanonicalizerPhase(true).apply(snippetGraph, context); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/Test.java --- a/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/Test.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/Test.java Tue Oct 22 11:43:37 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.api.runtime.*; import com.oracle.graal.java.decompiler.test.example.*; import com.oracle.graal.printer.*; +import com.oracle.graal.runtime.*; public class Test { @@ -38,7 +39,7 @@ */ public static void main(String[] args) throws NoSuchMethodException, SecurityException { DebugEnvironment.initialize(System.out); - MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class); + MetaAccessProvider metaAccess = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders().getMetaAccess(); Method method = Example.class.getDeclaredMethod("loop7", new Class[]{int.class, int.class}); final ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(method); TestUtil.compileMethod(javaMethod); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java --- a/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java Tue Oct 22 11:43:37 2013 +0200 @@ -36,12 +36,15 @@ import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; +import com.oracle.graal.runtime.*; public class TestUtil { public static void compileMethod(ResolvedJavaMethod method) { - Providers providers = GraalCompiler.getGraalProviders(); - Suites suites = Graal.getRequiredCapability(SuitesProvider.class).createSuites(); + Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend(); + Providers providers = backend.getProviders(); + SuitesProvider suitesProvider = backend.getSuites(); + Suites suites = suitesProvider.createSuites(); StructuredGraph graph = new StructuredGraph(method); MetaAccessProvider metaAccess = providers.getMetaAccess(); ForeignCallsProvider foreignCalls = providers.getForeignCalls(); @@ -50,7 +53,6 @@ GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); - Backend backend = Graal.getRequiredCapability(Backend.class); GraalCompiler.compileGraph(graph, cc, method, providers, backend, providers.getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog(), suites, new CompilationResult()); } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 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 Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Oct 22 11:43:37 2013 +0200 @@ -795,7 +795,7 @@ eagerResolvingForSnippets(cpi, opcode); JavaMethod result = constantPool.lookupMethod(cpi, opcode); // assert !graphBuilderConfig.unresolvedIsError() || ((result instanceof ResolvedJavaMethod) -// && ((ResolvedJavaMethod) result).getDeclaringClass().isInitialized()) : result; + // && ((ResolvedJavaMethod) result).getDeclaringClass().isInitialized()) : result; return result; } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java --- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java Tue Oct 22 11:43:37 2013 +0200 @@ -53,7 +53,6 @@ } } - public static class ForeignCallNoArgOp extends HSAILLIRInstruction { @Def({REG}) protected Value out; @@ -80,7 +79,6 @@ } } - public static class CompareBranchOp extends HSAILLIRInstruction implements StandardOp.BranchOp { @Opcode protected final HSAILCompare opcode; diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java --- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java Tue Oct 22 11:43:37 2013 +0200 @@ -129,7 +129,6 @@ } } - public abstract static class MemOp extends HSAILLIRInstruction { protected final Kind kind; @@ -268,8 +267,6 @@ masm.emitCompressedOopDecode(result, narrowOopBase, narrowOopShift); } - - public static class LeaOp extends HSAILLIRInstruction { @Def({REG}) protected AllocatableValue result; diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXCompare.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXCompare.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXCompare.java Tue Oct 22 11:43:37 2013 +0200 @@ -67,8 +67,7 @@ } } - public static void emit(PTXAssembler masm, PTXCompare opcode, - Condition condition, Value x, Value y, int p) { + public static void emit(PTXAssembler masm, PTXCompare opcode, Condition condition, Value x, Value y, int p) { if (isConstant(x)) { new Setp(condition, x, y, p).emit(masm); } else if (isConstant(y)) { diff -r 3ee8ae69d676 -r ce8dd5fa8d54 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 Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java Tue Oct 22 11:43:37 2013 +0200 @@ -43,8 +43,7 @@ @Use({COMPOSITE}) protected PTXAddressValue address; @State protected LIRFrameState state; - public LoadOp(Kind kind, Variable result, PTXAddressValue address, - LIRFrameState state) { + public LoadOp(Kind kind, Variable result, PTXAddressValue address, LIRFrameState state) { this.kind = kind; this.result = result; this.address = address; @@ -63,8 +62,7 @@ case Float: case Double: case Object: - new Ld(Global, result, addr.getBase(), - Constant.forLong(addr.getDisplacement())).emit(masm); + new Ld(Global, result, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -99,8 +97,7 @@ case Float: case Double: case Object: - new St(Global, input, addr.getBase(), - Constant.forLong(addr.getDisplacement())).emit(masm); + new St(Global, input, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm); break; default: throw GraalInternalError.shouldNotReachHere("missing: " + address.getKind()); @@ -117,8 +114,7 @@ @Use({COMPOSITE}) protected PTXAddressValue address; @State protected LIRFrameState state; - public LoadParamOp(Kind kind, Variable result, PTXAddressValue address, - LIRFrameState state) { + public LoadParamOp(Kind kind, Variable result, PTXAddressValue address, LIRFrameState state) { this.kind = kind; this.result = result; this.address = address; @@ -137,8 +133,7 @@ case Float: case Double: case Object: - new Ld(Parameter, result, addr.getBase(), - Constant.forLong(addr.getDisplacement())).emit(masm); + new Ld(Parameter, result, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -156,8 +151,7 @@ @Use({COMPOSITE}) protected PTXAddressValue address; @State protected LIRFrameState state; - public LoadReturnAddrOp(Kind kind, Variable result, - PTXAddressValue address, LIRFrameState state) { + public LoadReturnAddrOp(Kind kind, Variable result, PTXAddressValue address, LIRFrameState state) { this.kind = kind; this.result = result; this.address = address; @@ -172,8 +166,7 @@ case Long: case Float: case Double: - new Ld(Parameter, result, addr.getBase(), - Constant.forLong(addr.getDisplacement())).emit(masm); + new Ld(Parameter, result, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm); break; default: throw GraalInternalError.shouldNotReachHere(); @@ -190,8 +183,7 @@ @Use({REG}) protected Variable input; @State protected LIRFrameState state; - public StoreReturnValOp(Kind kind, PTXAddressValue address, - Variable input, LIRFrameState state) { + public StoreReturnValOp(Kind kind, PTXAddressValue address, Variable input, LIRFrameState state) { this.kind = kind; this.address = address; this.input = input; @@ -210,8 +202,7 @@ case Float: case Double: case Object: - new St(Global, input, addr.getBase(), - Constant.forLong(addr.getDisplacement())).emit(masm); + new St(Global, input, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm); break; default: throw GraalInternalError.shouldNotReachHere("missing: " + address.getKind()); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/ParallelOver.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/ParallelOver.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/ParallelOver.java Tue Oct 22 11:43:37 2013 +0200 @@ -25,6 +25,7 @@ import static com.oracle.graal.lir.ptx.ThreadDimension.*; import java.lang.annotation.*; + @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.PARAMETER}) public @interface ParallelOver { @@ -33,4 +34,3 @@ ThreadDimension dimension() default X; } - diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/ThreadDimension.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/ThreadDimension.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/ThreadDimension.java Tue Oct 22 11:43:37 2013 +0200 @@ -23,8 +23,5 @@ package com.oracle.graal.lir.ptx; public enum ThreadDimension { -X, -Y, -Z + X, Y, Z } - diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/Warp.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/Warp.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/Warp.java Tue Oct 22 11:43:37 2013 +0200 @@ -34,4 +34,3 @@ ThreadDimension dimension() default X; } - diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Tue Oct 22 11:43:37 2013 +0200 @@ -143,45 +143,45 @@ } } else { throw GraalInternalError.shouldNotReachHere(); -// SPARCAddress src = (SPARCAddress) tasm.asAddress(input); -// switch (opcode) { -// case IPOPCNT: -// new Ldsw(src, tmp).emit(masm); -// // clear upper word for 64 bit POPC -// new Srl(tmp, g0, dst).emit(masm); -// new Popc(tmp, dst).emit(masm); -// break; -// case LPOPCNT: -// new Ldx(src, tmp).emit(masm); -// new Popc(tmp, dst).emit(masm); -// break; -// case BSF: -// assert input.getKind() == Kind.Int; -// new Ldsw(src, tmp).emit(masm); -// new Srl(tmp, 1, tmp).emit(masm); -// new Srl(tmp, 0, dst).emit(masm); -// new Or(tmp, tmp, dst).emit(masm); -// new Srl(dst, 2, tmp).emit(masm); -// new Or(dst, tmp, dst).emit(masm); -// new Srl(dst, 4, tmp).emit(masm); -// new Or(dst, tmp, dst).emit(masm); -// new Srl(dst, 8, tmp).emit(masm); -// new Or(dst, tmp, dst).emit(masm); -// new Srl(dst, 16, tmp).emit(masm); -// new Or(dst, tmp, dst).emit(masm); -// new Popc(dst, dst).emit(masm); -// new Mov(Kind.Int.getBitCount(), tmp).emit(masm); -// new Sub(tmp, dst, dst).emit(masm); -// break; -// case IBSR: -// // masm.bsrl(dst, src); -// // countLeadingZerosI_bsr masm.bsrq(dst, src); -// // masm.bsrl(dst, src); -// case LBSR: -// // masm.bsrq(dst, src); -// default: -// throw GraalInternalError.shouldNotReachHere("missing: " + opcode); -// } + // SPARCAddress src = (SPARCAddress) tasm.asAddress(input); + // switch (opcode) { + // case IPOPCNT: + // new Ldsw(src, tmp).emit(masm); + // // clear upper word for 64 bit POPC + // new Srl(tmp, g0, dst).emit(masm); + // new Popc(tmp, dst).emit(masm); + // break; + // case LPOPCNT: + // new Ldx(src, tmp).emit(masm); + // new Popc(tmp, dst).emit(masm); + // break; + // case BSF: + // assert input.getKind() == Kind.Int; + // new Ldsw(src, tmp).emit(masm); + // new Srl(tmp, 1, tmp).emit(masm); + // new Srl(tmp, 0, dst).emit(masm); + // new Or(tmp, tmp, dst).emit(masm); + // new Srl(dst, 2, tmp).emit(masm); + // new Or(dst, tmp, dst).emit(masm); + // new Srl(dst, 4, tmp).emit(masm); + // new Or(dst, tmp, dst).emit(masm); + // new Srl(dst, 8, tmp).emit(masm); + // new Or(dst, tmp, dst).emit(masm); + // new Srl(dst, 16, tmp).emit(masm); + // new Or(dst, tmp, dst).emit(masm); + // new Popc(dst, dst).emit(masm); + // new Mov(Kind.Int.getBitCount(), tmp).emit(masm); + // new Sub(tmp, dst, dst).emit(masm); + // break; + // case IBSR: + // // masm.bsrl(dst, src); + // // countLeadingZerosI_bsr masm.bsrq(dst, src); + // // masm.bsrl(dst, src); + // case LBSR: + // // masm.bsrq(dst, src); + // default: + // throw GraalInternalError.shouldNotReachHere("missing: " + opcode); + // } } } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Tue Oct 22 11:43:37 2013 +0200 @@ -446,8 +446,8 @@ } // Load jump table entry into scratch and jump to it -// masm.movslq(value, new AMD64Address(scratch, value, Scale.Times4, 0)); -// masm.addq(scratch, value); + // masm.movslq(value, new AMD64Address(scratch, value, Scale.Times4, 0)); + // masm.addq(scratch, value); new Jmp(new SPARCAddress(scratch, 0)).emit(masm); new Nop().emit(masm); // delay slot diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Tue Oct 22 11:43:37 2013 +0200 @@ -213,7 +213,7 @@ @Opcode("CAS") public static class CompareAndSwapOp extends SPARCLIRInstruction { -// @Def protected AllocatableValue result; + // @Def protected AllocatableValue result; @Use protected AllocatableValue address; @Use protected AllocatableValue cmpValue; @Use protected AllocatableValue newValue; diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java Tue Oct 22 11:43:37 2013 +0200 @@ -107,8 +107,7 @@ private static boolean verifyFlags(Field field, Class type, EnumSet flags) { if (flags.contains(REG)) { - assert type.isAssignableFrom(REGISTER_VALUE_CLASS) || - type.isAssignableFrom(VARIABLE_CLASS) : "Cannot assign RegisterValue / Variable to field with REG flag:" + field; + assert type.isAssignableFrom(REGISTER_VALUE_CLASS) || type.isAssignableFrom(VARIABLE_CLASS) : "Cannot assign RegisterValue / Variable to field with REG flag:" + field; } if (flags.contains(STACK)) { assert type.isAssignableFrom(STACK_SLOT_CLASS) : "Cannot assign StackSlot to field with STACK flag:" + field; diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java Tue Oct 22 11:43:37 2013 +0200 @@ -63,7 +63,8 @@ private List exceptionInfoList; - public TargetMethodAssembler(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext, CompilationResult compilationResult) { + public TargetMethodAssembler(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext, + CompilationResult compilationResult) { this.target = codeCache.getTarget(); this.codeCache = codeCache; this.foreignCalls = foreignCalls; diff -r 3ee8ae69d676 -r ce8dd5fa8d54 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 Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Tue Oct 22 11:43:37 2013 +0200 @@ -32,6 +32,7 @@ import com.oracle.graal.nodes.VirtualState.NodeClosure; import com.oracle.graal.nodes.VirtualState.VirtualClosure; import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.nodes.virtual.*; public abstract class LoopFragment { @@ -181,10 +182,16 @@ final NodeBitMap notloopNodes = graph.createNodeBitMap(true); for (AbstractBeginNode b : blocks) { for (Node n : b.getBlockNodes()) { + if (n instanceof CommitAllocationNode) { + for (VirtualObjectNode obj : ((CommitAllocationNode) n).getVirtualObjects()) { + markFloating(obj, nodes, notloopNodes); + } + } for (Node usage : n.usages()) { markFloating(usage, nodes, notloopNodes); } } + } return nodes; diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginStateSplitNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginStateSplitNode.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginStateSplitNode.java Tue Oct 22 11:43:37 2013 +0200 @@ -25,9 +25,11 @@ import com.oracle.graal.nodes.type.*; /** - * Base class for {@link AbstractBeginNode}s that are associated with a frame state. TODO (dnsimon) this not - * needed until {@link AbstractBeginNode} no longer implements {@link StateSplit} which is not possible - * until loop peeling works without requiring begin nodes to have frames states + * Base class for {@link AbstractBeginNode}s that are associated with a frame state. + * + * TODO (dnsimon) this not needed until {@link AbstractBeginNode} no longer implements + * {@link StateSplit} which is not possible until loop peeling works without requiring begin nodes + * to have frames states. */ public abstract class BeginStateSplitNode extends AbstractBeginNode implements StateSplit { diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ControlSplitNode.java Tue Oct 22 11:43:37 2013 +0200 @@ -22,13 +22,14 @@ */ package com.oracle.graal.nodes; +import com.oracle.graal.graph.*; import com.oracle.graal.nodes.type.*; /** * The {@code ControlSplitNode} is a base class for all instructions that split the control flow * (ie. have more than one successor). */ -public abstract class ControlSplitNode extends FixedNode { +public abstract class ControlSplitNode extends FixedNode implements IterableNodeType { public ControlSplitNode(Stamp stamp) { super(stamp); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Tue Oct 22 11:43:37 2013 +0200 @@ -33,6 +33,8 @@ private final DeoptimizationReason reason; public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason) { + assert action != null; + assert reason != null; this.action = action; this.reason = reason; } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java Tue Oct 22 11:43:37 2013 +0200 @@ -23,9 +23,11 @@ package com.oracle.graal.nodes; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.spi.*; -public class DynamicDeoptimizeNode extends AbstractDeoptimizeNode implements LIRLowerable { +public class DynamicDeoptimizeNode extends AbstractDeoptimizeNode implements LIRLowerable, Canonicalizable { @Input private ValueNode actionAndReason; public DynamicDeoptimizeNode(ValueNode actionAndReason) { @@ -44,4 +46,15 @@ public void generate(LIRGeneratorTool generator) { generator.emitDeoptimize(generator.operand(actionAndReason), this); } + + @Override + public Node canonical(CanonicalizerTool tool) { + if (actionAndReason.isConstant()) { + Constant constant = actionAndReason.asConstant(); + DeoptimizeNode newDeopt = graph().add(new DeoptimizeNode(tool.getMetaAccess().decodeDeoptAction(constant), tool.getMetaAccess().decodeDeoptReason(constant))); + newDeopt.setDeoptimizationState(getDeoptimizationState()); + return newDeopt; + } + return this; + } } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Tue Oct 22 11:43:37 2013 +0200 @@ -358,9 +358,9 @@ if (trueValue.kind() != Kind.Int && trueValue.kind() != Kind.Long) { return false; } - if (trueValue.isConstant() && falseValue.isConstant()) { - ConditionalNode materialize = graph().unique(new ConditionalNode(condition(), trueValue, falseValue)); - graph().replaceFloating(singlePhi, materialize); + ConditionalNode conditional = canonicalizeConditionalCascade(trueValue, falseValue); + if (conditional != null) { + graph().replaceFloating(singlePhi, conditional); removeEmptyIf(tool); return true; } @@ -371,6 +371,44 @@ return false; } + private ConditionalNode canonicalizeConditionalCascade(ValueNode trueValue, ValueNode falseValue) { + if (trueValue.isConstant() && falseValue.isConstant()) { + return graph().unique(new ConditionalNode(condition(), trueValue, falseValue)); + } else { + ConditionalNode conditional = null; + ValueNode constant = null; + boolean negateCondition; + if (trueValue instanceof ConditionalNode && falseValue.isConstant()) { + conditional = (ConditionalNode) trueValue; + constant = falseValue; + negateCondition = true; + } else if (falseValue instanceof ConditionalNode && trueValue.isConstant()) { + conditional = (ConditionalNode) falseValue; + constant = trueValue; + negateCondition = false; + } else { + return null; + } + boolean negateConditionalCondition; + ValueNode otherValue; + if (constant == conditional.x()) { + otherValue = conditional.y(); + negateConditionalCondition = false; + } else if (constant == conditional.y()) { + otherValue = conditional.x(); + negateConditionalCondition = true; + } else { + return null; + } + if (otherValue.isConstant()) { + double shortCutProbability = probability(trueSuccessor()); + LogicNode newCondition = LogicNode.or(condition(), negateCondition, conditional.condition(), negateConditionalCondition, shortCutProbability); + return graph().unique(new ConditionalNode(newCondition, constant, otherValue)); + } + } + return null; + } + /** * Tries to connect code that initializes a variable directly with the successors of an if * construct that switches on the variable. For example, the pseudo code below: diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Tue Oct 22 11:43:37 2013 +0200 @@ -32,7 +32,7 @@ import com.oracle.graal.nodes.util.*; @NodeInfo(nameTemplate = "Invoke!#{p#targetMethod/s}") -public class InvokeWithExceptionNode extends ControlSplitNode implements IterableNodeType, Invoke, MemoryCheckpoint.Single, LIRLowerable { +public class InvokeWithExceptionNode extends ControlSplitNode implements Invoke, MemoryCheckpoint.Single, LIRLowerable { private static final double EXCEPTION_PROBA = 1e-5; diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Tue Oct 22 11:43:37 2013 +0200 @@ -91,9 +91,7 @@ @Override public boolean verify() { Node lla = lastLocationAccess(); - if (lla != null && !(isMemoryCheckPoint(lla) || isMemoryPhi(lla) || isMemoryProxy(lla))) { - assert false : "lastLocationAccess of " + this + " should be a MemoryCheckpoint, but is " + lla; - } + assert lla == null || isMemoryCheckPoint(lla) || isMemoryPhi(lla) || isMemoryProxy(lla) : "lastLocationAccess of " + this + " should be a MemoryCheckpoint, but is " + lla; return super.verify(); } } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraphCache.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraphCache.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraphCache.java Tue Oct 22 11:43:37 2013 +0200 @@ -25,10 +25,32 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; +/** + * A cache for graphs associated with {@linkplain StructuredGraph#method() methods}. + */ public interface GraphCache { - void put(StructuredGraph graph, boolean hasMatureProfilingInfo); + /** + * Requests that a graph be added to this cache. + * + * @param hasMatureProfilingInfo indicates that the caller has + * {@linkplain ProfilingInfo#isMature() mature} profiling info for the method + * associated with the graph + * @return true if {@code graph} was added to this cache, false otherwise + */ + boolean put(StructuredGraph graph, boolean hasMatureProfilingInfo); + /** + * Gets the graph from this cache associated with a given method. + * + * @param method a method for which a cached graph is requested + * @return the graph cached for {@code method} or null if it does not exist + */ StructuredGraph get(ResolvedJavaMethod method); + /** + * The cache will remove graphs it considers stale. For example, graphs associated with + * installed code that has subsequently be deoptimized might be considered stale. + */ + void removeStaleGraphs(); } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Tue Oct 22 11:43:37 2013 +0200 @@ -296,39 +296,39 @@ graph.replaceFloating((FloatingNode) node, canonical); } } else { - assert node instanceof FixedWithNextNode && node.predecessor() != null : node + " -> " + canonical + " : node should be fixed & connected (" + node.predecessor() + ")"; - FixedWithNextNode fixedWithNext = (FixedWithNextNode) node; - + assert node instanceof FixedNode && node.predecessor() != null : node + " -> " + canonical + " : node should be fixed & connected (" + node.predecessor() + ")"; + FixedNode fixed = (FixedNode) node; if (canonical instanceof ControlSinkNode) { // case 7 FixedWithNextNode pred = (FixedWithNextNode) node.predecessor(); - GraphUtil.killCFG(fixedWithNext); + GraphUtil.killCFG(fixed); pred.setNext((FixedNode) canonical); return true; - } - - // When removing a fixed node, new canonicalization - // opportunities for its successor may arise - assert fixedWithNext.next() != null; - tool.addToWorkList(fixedWithNext.next()); - - if (canonical == null) { - // case 3 - graph.removeFixed(fixedWithNext); - } else if (canonical instanceof FloatingNode) { - // case 4 - graph.replaceFixedWithFloating(fixedWithNext, (FloatingNode) canonical); } else { - assert canonical instanceof FixedNode; - if (canonical.predecessor() == null) { - assert !canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " shouldn't have successors"; - // case 5 - graph.replaceFixedWithFixed(fixedWithNext, (FixedWithNextNode) canonical); + assert fixed instanceof FixedWithNextNode; + FixedWithNextNode fixedWithNext = (FixedWithNextNode) fixed; + // When removing a fixed node, new canonicalization + // opportunities for its successor may arise + assert fixedWithNext.next() != null; + tool.addToWorkList(fixedWithNext.next()); + if (canonical == null) { + // case 3 + graph.removeFixed(fixedWithNext); + } else if (canonical instanceof FloatingNode) { + // case 4 + graph.replaceFixedWithFloating(fixedWithNext, (FloatingNode) canonical); } else { - assert canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " should have successors"; - // case 6 - node.replaceAtUsages(canonical); - graph.removeFixed(fixedWithNext); + assert canonical instanceof FixedNode; + if (canonical.predecessor() == null) { + assert !canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " shouldn't have successors"; + // case 5 + graph.replaceFixedWithFixed(fixedWithNext, (FixedWithNextNode) canonical); + } else { + assert canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " should have successors"; + // case 6 + node.replaceAtUsages(canonical); + graph.removeFixed(fixedWithNext); + } } } } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Tue Oct 22 11:43:37 2013 +0200 @@ -318,44 +318,43 @@ ShortCircuitOrNode disjunction = (ShortCircuitOrNode) condition; registerCondition(disjunction.isXNegated(), disjunction.getX(), anchor); registerCondition(disjunction.isYNegated(), disjunction.getY(), anchor); - } else { - state.addCondition(isTrue, condition, anchor); + } + state.addCondition(isTrue, condition, anchor); - if (isTrue && condition instanceof InstanceOfNode) { - InstanceOfNode instanceOf = (InstanceOfNode) condition; - ValueNode object = instanceOf.object(); - state.addNullness(false, object); - state.addType(instanceOf.type(), object); - } else if (condition instanceof IsNullNode) { - IsNullNode nullCheck = (IsNullNode) condition; - state.addNullness(isTrue, nullCheck.object()); - } else if (condition instanceof ObjectEqualsNode) { - ObjectEqualsNode equals = (ObjectEqualsNode) condition; - ValueNode x = equals.x(); - ValueNode y = equals.y(); - if (isTrue) { - if (state.isNull(x) && !state.isNull(y)) { - metricObjectEqualsRegistered.increment(); - state.addNullness(true, y); - } else if (!state.isNull(x) && state.isNull(y)) { - metricObjectEqualsRegistered.increment(); - state.addNullness(true, x); - } - if (state.isNonNull(x) && !state.isNonNull(y)) { - metricObjectEqualsRegistered.increment(); - state.addNullness(false, y); - } else if (!state.isNonNull(x) && state.isNonNull(y)) { - metricObjectEqualsRegistered.increment(); - state.addNullness(false, x); - } - } else { - if (state.isNull(x) && !state.isNonNull(y)) { - metricObjectEqualsRegistered.increment(); - state.addNullness(false, y); - } else if (!state.isNonNull(x) && state.isNull(y)) { - metricObjectEqualsRegistered.increment(); - state.addNullness(false, x); - } + if (isTrue && condition instanceof InstanceOfNode) { + InstanceOfNode instanceOf = (InstanceOfNode) condition; + ValueNode object = instanceOf.object(); + state.addNullness(false, object); + state.addType(instanceOf.type(), object); + } else if (condition instanceof IsNullNode) { + IsNullNode nullCheck = (IsNullNode) condition; + state.addNullness(isTrue, nullCheck.object()); + } else if (condition instanceof ObjectEqualsNode) { + ObjectEqualsNode equals = (ObjectEqualsNode) condition; + ValueNode x = equals.x(); + ValueNode y = equals.y(); + if (isTrue) { + if (state.isNull(x) && !state.isNull(y)) { + metricObjectEqualsRegistered.increment(); + state.addNullness(true, y); + } else if (!state.isNull(x) && state.isNull(y)) { + metricObjectEqualsRegistered.increment(); + state.addNullness(true, x); + } + if (state.isNonNull(x) && !state.isNonNull(y)) { + metricObjectEqualsRegistered.increment(); + state.addNullness(false, y); + } else if (!state.isNonNull(x) && state.isNonNull(y)) { + metricObjectEqualsRegistered.increment(); + state.addNullness(false, x); + } + } else { + if (state.isNull(x) && !state.isNonNull(y)) { + metricObjectEqualsRegistered.increment(); + state.addNullness(false, y); + } else if (!state.isNonNull(x) && state.isNull(y)) { + metricObjectEqualsRegistered.increment(); + state.addNullness(false, x); } } } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/EliminatePartiallyRedundantGuardsPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/EliminatePartiallyRedundantGuardsPhase.java Tue Oct 22 11:42:10 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.phases.common; - -import java.util.*; -import java.util.Map.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.PhiNode.PhiType; -import com.oracle.graal.phases.*; - -public class EliminatePartiallyRedundantGuardsPhase extends Phase { - - private static final DebugMetric metricPRGuardsEliminatedAtMerge = Debug.metric("PRGuardsEliminatedAtMerge"); - private static final DebugMetric metricPRGuardsEliminatedAtSplit = Debug.metric("PRGuardsEliminatedAtSplit"); - - private final boolean eliminateAtSplit; - private final boolean eliminateAtMerge; - - public EliminatePartiallyRedundantGuardsPhase(boolean eliminateAtSplit, boolean eliminateAtMerge) { - assert eliminateAtMerge || eliminateAtSplit; - this.eliminateAtSplit = eliminateAtSplit; - this.eliminateAtMerge = eliminateAtMerge; - } - - private static class Condition { - - final LogicNode conditionNode; - final boolean negated; - - public Condition(LogicNode conditionNode, boolean negated) { - this.conditionNode = conditionNode; - this.negated = negated; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((conditionNode == null) ? 0 : conditionNode.hashCode()); - result = prime * result + (negated ? 1231 : 1237); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - Condition other = (Condition) obj; - if (conditionNode == null) { - if (other.conditionNode != null) { - return false; - } - } else if (!conditionNode.equals(other.conditionNode)) { - return false; - } - if (negated != other.negated) { - return false; - } - return true; - } - } - - @Override - protected void run(StructuredGraph graph) { - boolean hits; - do { - hits = false; - if (eliminateAtMerge) { - for (MergeNode merge : graph.getNodes(MergeNode.class)) { - hits |= eliminateAtMerge(merge); - } - } - if (eliminateAtSplit) { - for (ControlSplitNode controlSplit : graph.getNodes().filter(ControlSplitNode.class)) { - hits |= eliminateAtControlSplit(controlSplit); - } - } - } while (hits); - } - - private static boolean eliminateAtMerge(MergeNode merge) { - if (merge.forwardEndCount() < 2) { - return false; - } - Collection hits = new LinkedList<>(); - for (GuardNode guard : merge.guards()) { - for (AbstractEndNode end : merge.forwardEnds()) { - AbstractBeginNode begin = AbstractBeginNode.prevBegin(end); - boolean found = false; - for (GuardNode predecessorGuard : begin.guards()) { - if (guard.condition() == predecessorGuard.condition() && guard.negated() == predecessorGuard.negated()) { - hits.add(guard); - found = true; - break; - } - } - if (found) { - break; - } - } - } - Graph graph = merge.graph(); - for (GuardNode guard : hits) { - PhiNode phi = graph.addWithoutUnique(new PhiNode(PhiType.Guard, merge, null)); - for (AbstractEndNode otherEnd : merge.forwardEnds()) { - phi.addInput(graph.unique(new GuardNode(guard.condition(), AbstractBeginNode.prevBegin(otherEnd), guard.reason(), guard.action(), guard.negated()))); - } - guard.replaceAndDelete(phi); - metricPRGuardsEliminatedAtMerge.increment(); - } - return !hits.isEmpty(); - } - - private static boolean eliminateAtControlSplit(ControlSplitNode controlSplit) { - Map> conditionToGuard = new HashMap<>(); - for (Node successor : controlSplit.successors()) { - AbstractBeginNode begin = (AbstractBeginNode) successor; - for (GuardNode guard : begin.guards()) { - Condition condition = new Condition(guard.condition(), guard.negated()); - Collection guards = conditionToGuard.get(condition); - if (guards == null) { - guards = new LinkedList<>(); - conditionToGuard.put(condition, guards); - } - guards.add(guard); - } - } - - boolean hits = false; - for (Entry> entry : conditionToGuard.entrySet()) { - Collection guards = entry.getValue(); - if (guards.size() < 2) { - continue; - } - DeoptimizationReason reason = null; - DeoptimizationAction action = DeoptimizationAction.None; - Set begins = new HashSet<>(3); - for (GuardNode guard : guards) { - AbstractBeginNode begin = (AbstractBeginNode) guard.getGuard(); - begins.add(begin); - if (guard.action().ordinal() > action.ordinal()) { - action = guard.action(); - } - if (reason == null) { - reason = guard.reason(); - } else if (reason != guard.reason()) { - reason = DeoptimizationReason.None; - } - } - if (begins.size() == controlSplit.successors().count()) { - hits = true; - Condition condition = entry.getKey(); - GuardNode newGuard = controlSplit.graph().unique(new GuardNode(condition.conditionNode, AbstractBeginNode.prevBegin(controlSplit), reason, action, condition.negated)); - for (GuardNode guard : guards) { - guard.replaceAndDelete(newGuard); - metricPRGuardsEliminatedAtSplit.increment(); - } - } - } - return hits; - } -} diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchors.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchors.java Tue Oct 22 11:43:37 2013 +0200 @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.phases.common; + +import java.util.*; + +import com.oracle.graal.debug.*; +import com.oracle.graal.graph.NodeClass.NodeClassIterator; +import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.phases.*; + +public class OptimizeGuardAnchors extends Phase { + private static final DebugMetric metricGuardsAnchorOptimized = Debug.metric("GuardsAnchorOptimized"); + private static final DebugMetric metricGuardsOptimizedAtSplit = Debug.metric("GuardsOptimizedAtSplit"); + + private static class LazyCFG { + private ControlFlowGraph cfg; + private StructuredGraph graph; + + public LazyCFG(StructuredGraph graph) { + this.graph = graph; + } + + public ControlFlowGraph get() { + if (cfg == null) { + cfg = ControlFlowGraph.compute(graph, true, false, true, true); + } + return cfg; + } + } + + @Override + protected void run(StructuredGraph graph) { + LazyCFG cfg = new LazyCFG(graph); + for (AbstractBeginNode begin : graph.getNodes(AbstractBeginNode.class)) { + if (!(begin instanceof StartNode || begin.predecessor() instanceof ControlSplitNode)) { + NodeIterable guards = begin.guards(); + if (guards.isNotEmpty()) { + AbstractBeginNode newAnchor = computeOptimalAnchor(cfg.get(), begin); + // newAnchor == begin is possible because postdominator computation assumes that + // loops never end + if (newAnchor != begin) { + for (GuardNode guard : guards.snapshot()) { + guard.setGuard(newAnchor); + } + metricGuardsAnchorOptimized.increment(); + } + } + } + } + for (ControlSplitNode controlSplit : graph.getNodes(ControlSplitNode.class)) { + otpimizeAtControlSplit(controlSplit, cfg); + } + } + + private static AbstractBeginNode computeOptimalAnchor(ControlFlowGraph cfg, AbstractBeginNode begin) { + Block anchor = cfg.blockFor(begin); + while (anchor.getDominator() != null && anchor.getDominator().getPostdominator() == anchor) { + anchor = anchor.getDominator(); + } + return anchor.getBeginNode(); + } + + private static void otpimizeAtControlSplit(ControlSplitNode controlSplit, LazyCFG cfg) { + AbstractBeginNode successor = findMinimumUsagesSuccessor(controlSplit); + int successorCount = controlSplit.successors().count(); + List otherGuards = new ArrayList<>(successorCount - 1); + for (GuardNode guard : successor.guards().snapshot()) { + if (guard.condition().usages().count() < successorCount) { + continue; + } + + for (GuardNode conditonGuard : guard.condition().usages().filter(GuardNode.class)) { + if (conditonGuard != guard) { + GuardingNode conditonGuardAnchor = conditonGuard.getGuard(); + if (conditonGuardAnchor.asNode().predecessor() == controlSplit && compatibleGuards(guard, conditonGuard)) { + otherGuards.add(conditonGuard); + } + } + } + + if (otherGuards.size() == successorCount - 1) { + AbstractBeginNode anchor = computeOptimalAnchor(cfg.get(), AbstractBeginNode.prevBegin(controlSplit)); + GuardNode newGuard = controlSplit.graph().unique(new GuardNode(guard.condition(), anchor, guard.reason(), guard.action(), guard.negated())); + for (GuardNode otherGuard : otherGuards) { + otherGuard.replaceAndDelete(newGuard); + } + guard.replaceAndDelete(newGuard); + metricGuardsOptimizedAtSplit.increment(); + } + otherGuards.clear(); + } + } + + private static boolean compatibleGuards(GuardNode guard, GuardNode conditonGuard) { + return conditonGuard.negated() == guard.negated() && conditonGuard.action() == guard.action() && conditonGuard.reason() == guard.reason(); + } + + private static AbstractBeginNode findMinimumUsagesSuccessor(ControlSplitNode controlSplit) { + NodeClassIterator successors = controlSplit.successors().iterator(); + AbstractBeginNode min = (AbstractBeginNode) successors.next(); + int minUsages = min.usages().count(); + while (successors.hasNext()) { + AbstractBeginNode successor = (AbstractBeginNode) successors.next(); + int count = successor.usages().count(); + if (count < minUsages) { + minUsages = count; + min = successor; + } + } + return min; + } +} diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Tue Oct 22 11:43:37 2013 +0200 @@ -32,7 +32,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; -import com.oracle.graal.graph.NodeClass.NodeClassIterator; import com.oracle.graal.graph.NodeClass.Position; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; @@ -42,7 +41,7 @@ public class BinaryGraphPrinter implements GraphPrinter { - private static final int CONSTANT_POOL_MAX_SIZE = 2000; + private static final int CONSTANT_POOL_MAX_SIZE = 8000; private static final int BEGIN_GROUP = 0x00; private static final int BEGIN_GRAPH = 0x01; @@ -71,10 +70,10 @@ private static final int KLASS = 0x00; private static final int ENUM_KLASS = 0x01; - private static final class ConstantPool extends LinkedHashMap { + private static final class ConstantPool extends LinkedHashMap { - private final LinkedList availableIds; - private int nextId; + private final LinkedList availableIds; + private char nextId; private static final long serialVersionUID = -2676889957907285681L; public ConstantPool() { @@ -83,7 +82,7 @@ } @Override - protected boolean removeEldestEntry(java.util.Map.Entry eldest) { + protected boolean removeEldestEntry(java.util.Map.Entry eldest) { if (size() > CONSTANT_POOL_MAX_SIZE) { availableIds.addFirst(eldest.getValue()); return true; @@ -91,15 +90,15 @@ return false; } - private Integer nextAvailableId() { + private Character nextAvailableId() { if (!availableIds.isEmpty()) { return availableIds.removeFirst(); } return nextId++; } - public int add(Object obj) { - Integer id = nextAvailableId(); + public char add(Object obj) { + Character id = nextAvailableId(); put(obj, id); return id; } @@ -149,6 +148,7 @@ } private void ensureAvailable(int i) throws IOException { + assert buffer.capacity() >= i : "Can not make " + i + " bytes available, buffer is too small"; while (buffer.remaining() < i) { flush(); } @@ -186,10 +186,10 @@ private void writeString(String str) throws IOException { writeInt(str.length()); - ensureAvailable(str.length() * 2); - for (int i = 0; i < str.length(); i++) { - buffer.putChar(str.charAt(i)); - } + int sizeInBytes = str.length() * 2; + ensureAvailable(sizeInBytes); + buffer.asCharBuffer().put(str); + buffer.position(buffer.position() + sizeInBytes); } private void writeBytes(byte[] b) throws IOException { @@ -207,10 +207,10 @@ writeInt(-1); } else { writeInt(b.length); - ensureAvailable(b.length * 4); - for (int i = 0; i < b.length; i++) { - buffer.putInt(b[i]); - } + int sizeInBytes = b.length * 4; + ensureAvailable(sizeInBytes); + buffer.asIntBuffer().put(b); + buffer.position(buffer.position() + sizeInBytes); } } @@ -219,10 +219,10 @@ writeInt(-1); } else { writeInt(b.length); - ensureAvailable(b.length * 8); - for (int i = 0; i < b.length; i++) { - buffer.putDouble(b[i]); - } + int sizeInBytes = b.length * 8; + ensureAvailable(sizeInBytes); + buffer.asDoubleBuffer().put(b); + buffer.position(buffer.position() + sizeInBytes); } } @@ -231,7 +231,7 @@ writeByte(POOL_NULL); return; } - Integer id = constantPool.get(object); + Character id = constantPool.get(object); if (id == null) { addPoolEntry(object); } else { @@ -250,7 +250,7 @@ } else { writeByte(POOL_STRING); } - writeInt(id.intValue()); + writeShort(id.charValue()); } } @@ -262,9 +262,9 @@ } private void addPoolEntry(Object object) throws IOException { - int index = constantPool.add(object); + char index = constantPool.add(object); writeByte(POOL_NEW); - writeInt(index); + writeShort(index); if (object instanceof Class) { Class klass = (Class) object; writeByte(POOL_CLASS); @@ -293,14 +293,16 @@ writeByte(POOL_NODE_CLASS); writeString(nodeClass.getJavaClass().getSimpleName()); writeString(nodeClass.getNameTemplate()); - List directInputPositions = nodeClass.getFirstLevelInputPositions(); + Collection directInputPositions = nodeClass.getFirstLevelInputPositions(); writeShort((char) directInputPositions.size()); for (Position pos : directInputPositions) { + writeByte(pos.subIndex == NodeClass.NOT_ITERABLE ? 0 : 1); writePoolObject(nodeClass.getName(pos)); } - List directSuccessorPositions = nodeClass.getFirstLevelSuccessorPositions(); + Collection directSuccessorPositions = nodeClass.getFirstLevelSuccessorPositions(); writeShort((char) directSuccessorPositions.size()); for (Position pos : directSuccessorPositions) { + writeByte(pos.subIndex == NodeClass.NOT_ITERABLE ? 0 : 1); writePoolObject(nodeClass.getName(pos)); } } else if (object instanceof ResolvedJavaMethod) { @@ -411,25 +413,53 @@ writePoolObject(key); writePropertyObject(entry.getValue()); } - // successors - NodeClassIterable successors = node.successors(); - writeShort((char) successors.count()); - NodeClassIterator suxIt = successors.iterator(); - while (suxIt.hasNext()) { - Position pos = suxIt.nextPosition(); - Node sux = nodeClass.get(node, pos); - writeInt(sux.getId()); - writeShort((char) pos.index); + // inputs + Collection directInputPositions = nodeClass.getFirstLevelInputPositions(); + for (Position pos : directInputPositions) { + if (pos.subIndex == NodeClass.NOT_ITERABLE) { + Node in = nodeClass.get(node, pos); + if (in != null) { + writeInt(in.getId()); + } else { + writeInt(-1); + } + } else { + NodeList list = nodeClass.getNodeList(node, pos); + int listSize = list.count(); + assert listSize == ((char) listSize); + writeShort((char) listSize); + for (Node in : list) { + if (in != null) { + writeInt(in.getId()); + } else { + writeInt(-1); + } + } + } } - // inputs - NodeClassIterable inputs = node.inputs(); - writeShort((char) inputs.count()); - NodeClassIterator inIt = inputs.iterator(); - while (inIt.hasNext()) { - Position pos = inIt.nextPosition(); - Node in = nodeClass.get(node, pos); - writeInt(in.getId()); - writeShort((char) pos.index); + // successors + Collection directSuccessorPositions = nodeClass.getFirstLevelSuccessorPositions(); + for (Position pos : directSuccessorPositions) { + if (pos.subIndex == NodeClass.NOT_ITERABLE) { + Node sux = nodeClass.get(node, pos); + if (sux != null) { + writeInt(sux.getId()); + } else { + writeInt(-1); + } + } else { + NodeList list = nodeClass.getNodeList(node, pos); + int listSize = list.count(); + assert listSize == ((char) listSize); + writeShort((char) listSize); + for (Node sux : list) { + if (sux != null) { + writeInt(sux.getId()); + } else { + writeInt(-1); + } + } + } } props.clear(); } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.ptx/src/com/oracle/graal/ptx/PTX.java --- a/graal/com.oracle.graal.ptx/src/com/oracle/graal/ptx/PTX.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.ptx/src/com/oracle/graal/ptx/PTX.java Tue Oct 22 11:43:37 2013 +0200 @@ -35,10 +35,9 @@ */ public class PTX extends Architecture { - public static final RegisterCategory REG = new RegisterCategory("REG"); - public static final RegisterCategory SREG = new RegisterCategory("SREG"); - public static final RegisterCategory PARAM = new RegisterCategory("PARAM"); - + public static final RegisterCategory REG = new RegisterCategory("REG"); + public static final RegisterCategory SREG = new RegisterCategory("SREG"); + public static final RegisterCategory PARAM = new RegisterCategory("PARAM"); // @formatter:off @@ -194,8 +193,7 @@ // @formatter:on public PTX() { - super("PTX", 8, ByteOrder.LITTLE_ENDIAN, false, allRegisters, - LOAD_STORE | STORE_STORE, 0, r15.encoding + 1, 8); + super("PTX", 8, ByteOrder.LITTLE_ENDIAN, false, allRegisters, LOAD_STORE | STORE_STORE, 0, r15.encoding + 1, 8); } @Override @@ -232,5 +230,4 @@ } } - } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java Tue Oct 22 11:43:37 2013 +0200 @@ -51,8 +51,7 @@ StructuredGraph graph = parse(snippet); PhasePlan phasePlan = getDefaultPhasePlan(); Assumptions assumptions = new Assumptions(true); - HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan, - OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan, OptimisticOptimizations.ALL); Debug.dump(graph, "Graph"); new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); Debug.dump(graph, "Graph"); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Oct 22 11:43:37 2013 +0200 @@ -71,6 +71,8 @@ protected final ResolvedJavaMethod method; protected final boolean[] constantParameters; protected final boolean[] varargsParameters; + private final DebugMetric instantiationCounter; + private final DebugTimer instantiationTimer; /** * The parameter names, taken from the local variables table. Only used for assertion @@ -80,7 +82,8 @@ protected SnippetInfo(ResolvedJavaMethod method) { this.method = method; - + instantiationCounter = Debug.metric("SnippetInstantiationCount[" + method.getName() + "]"); + instantiationTimer = Debug.timer("SnippetInstantiationTime[" + method.getName() + "]"); assert Modifier.isStatic(method.getModifiers()) : "snippet method must be static: " + MetaUtil.format("%H.%n", method); int count = method.getSignature().getParameterCount(false); constantParameters = new boolean[count]; @@ -316,6 +319,7 @@ } private static final DebugTimer SnippetCreationAndSpecialization = Debug.timer("SnippetCreationAndSpecialization"); + private static final DebugMetric SnippetSpecializations = Debug.metric("SnippetSpecializations"); /** * Base class for snippet classes. It provides a cache for {@link SnippetTemplate}s. @@ -355,6 +359,7 @@ protected SnippetTemplate template(final Arguments args) { SnippetTemplate template = templates.get(args.cacheKey); if (template == null) { + SnippetSpecializations.increment(); try (TimerCloseable a = SnippetCreationAndSpecialization.start()) { template = Debug.scope("SnippetSpecialization", args.info.method, new Callable() { @@ -385,9 +390,6 @@ return false; } - private final DebugMetric instantiationCounter; - private final DebugTimer instantiationTimer; - /** * Creates a snippet template. */ @@ -580,9 +582,6 @@ this.deoptNodes = curDeoptNodes; this.stampNodes = curStampNodes; this.returnNode = retNode; - - this.instantiationCounter = Debug.metric("SnippetInstantiationCount[" + method.getName() + "]"); - this.instantiationTimer = Debug.timer("SnippetInstantiationTime[" + method.getName() + "]"); } private static boolean checkAllVarargPlaceholdersAreDeleted(int parameterCount, ConstantNode[] placeholders) { @@ -865,8 +864,8 @@ */ public Map instantiate(MetaAccessProvider metaAccess, FixedNode replacee, UsageReplacer replacer, Arguments args) { assert checkSnippetKills(replacee); - try (TimerCloseable a = instantiationTimer.start()) { - instantiationCounter.increment(); + try (TimerCloseable a = args.info.instantiationTimer.start()) { + args.info.instantiationCounter.increment(); // Inline the snippet nodes, replacing parameters with the given args in the process StartNode entryPointNode = snippet.start(); FixedNode firstCFGNode = entryPointNode.next(); @@ -958,8 +957,8 @@ */ public void instantiate(MetaAccessProvider metaAccess, FloatingNode replacee, UsageReplacer replacer, LoweringTool tool, Arguments args) { assert checkSnippetKills(replacee); - try (TimerCloseable a = instantiationTimer.start()) { - instantiationCounter.increment(); + try (TimerCloseable a = args.info.instantiationTimer.start()) { + args.info.instantiationCounter.increment(); // Inline the snippet nodes, replacing parameters with the given args in the process String name = snippet.name == null ? "{copy}" : snippet.name + "{copy}"; diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.runtime/src/com/oracle/graal/runtime/RuntimeProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.runtime/src/com/oracle/graal/runtime/RuntimeProvider.java Tue Oct 22 11:43:37 2013 +0200 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.runtime; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.nodes.spi.*; + +/** + * A runtime supporting a host backend as well, zero or more additional backends and an optional + * {@linkplain GraphCache graph cache}. + */ +public interface RuntimeProvider { + + /** + * Gets the host backend. + */ + Backend getHostBackend(); + + /** + * Gets the backend for a given architecture. + * + * @param arch a specific architecture class + */ + Backend getBackend(Class arch); + + /** + * Gets the graph cache (if any) maintained by this runtime. + */ + GraphCache getGraphCache(); +} diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64HotSpotTruffleBackend.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64HotSpotTruffleBackend.java Tue Oct 22 11:43:37 2013 +0200 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.hotspot.amd64; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.amd64.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.truffle.*; +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.frame.*; + +/** + * Subclass of {@link AMD64HotSpotBackend} that injects special code into + * {@link OptimizedCallTarget#call(PackedFrame, Arguments)} for making a tail-call to the entry + * point of the target callee. + */ +class AMD64HotSpotTruffleBackend extends AMD64HotSpotBackend { + + private ResolvedJavaMethod optimizedCallTargetCall; + + public AMD64HotSpotTruffleBackend(HotSpotGraalRuntime runtime, HotSpotProviders providers) { + super(runtime, providers); + } + + private ResolvedJavaMethod getInstrumentedMethod() throws GraalInternalError { + if (optimizedCallTargetCall == null) { + try { + optimizedCallTargetCall = getProviders().getMetaAccess().lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("call", PackedFrame.class, Arguments.class)); + } catch (NoSuchMethodException | SecurityException e) { + throw new GraalInternalError(e); + } + } + return optimizedCallTargetCall; + } + + @Override + protected void emitCodePrefix(ResolvedJavaMethod installedCodeOwner, TargetMethodAssembler tasm, AMD64MacroAssembler asm, RegisterConfig regConfig, HotSpotVMConfig config, Label verifiedStub) { + super.emitCodePrefix(installedCodeOwner, tasm, asm, regConfig, config, verifiedStub); + if (getInstrumentedMethod().equals(installedCodeOwner)) { + // TODO emit tailcall code + } + } +} diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64HotSpotTruffleBackendFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64HotSpotTruffleBackendFactory.java Tue Oct 22 11:43:37 2013 +0200 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.hotspot.amd64; + +import com.oracle.graal.api.runtime.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.amd64.*; +import com.oracle.graal.hotspot.meta.*; + +/** + * Factory to create a Truffle-specialized AMD64 HotSpot backend. + */ +@ServiceProvider(HotSpotBackendFactory.class) +public class AMD64HotSpotTruffleBackendFactory extends AMD64HotSpotBackendFactory { + + @Override + protected AMD64HotSpotBackend createBackend(HotSpotGraalRuntime runtime, HotSpotProviders providers) { + return new AMD64HotSpotTruffleBackend(runtime, providers); + } +} diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ExactMathTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ExactMathTest.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ExactMathTest.java Tue Oct 22 11:43:37 2013 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.runtime.*; import com.oracle.graal.truffle.substitutions.*; import com.oracle.truffle.api.*; @@ -36,7 +37,8 @@ public ExactMathTest() { if (!substitutionsInstalled) { - Graal.getRequiredCapability(Replacements.class).registerSubstitutions(ExactMathSubstitutions.class); + Replacements replacements = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders().getReplacements(); + replacements.registerSubstitutions(ExactMathSubstitutions.class); substitutionsInstalled = true; } } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Tue Oct 22 11:43:37 2013 +0200 @@ -28,6 +28,7 @@ import org.junit.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.debug.*; import com.oracle.graal.java.*; @@ -41,6 +42,7 @@ import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.printer.*; +import com.oracle.graal.runtime.*; import com.oracle.graal.truffle.*; import com.oracle.graal.virtual.phases.ea.*; import com.oracle.truffle.api.*; @@ -58,7 +60,7 @@ Replacements truffleReplacements = ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements(); Providers providers = getProviders().copyWith(truffleReplacements); TruffleCache truffleCache = new TruffleCache(providers, GraphBuilderConfiguration.getDefault(), TruffleCompilerImpl.Optimizations); - this.partialEvaluator = new PartialEvaluator(providers, truffleCache); + this.partialEvaluator = new PartialEvaluator(Graal.getRequiredCapability(RuntimeProvider.class), providers, truffleCache); DebugEnvironment.initialize(System.out); } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/TruffleRuntimeTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/TruffleRuntimeTest.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/TruffleRuntimeTest.java Tue Oct 22 11:43:37 2013 +0200 @@ -26,8 +26,8 @@ import org.junit.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; +import com.oracle.graal.runtime.*; import com.oracle.graal.truffle.*; import com.oracle.truffle.api.*; @@ -35,7 +35,7 @@ @Test public void testGraalCapabilities() { - assertNotNull(Graal.getRuntime().getCapability(MetaAccessProvider.class)); + assertNotNull(Graal.getRuntime().getCapability(RuntimeProvider.class)); } @Test diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationPolicy.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationPolicy.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/CompilationPolicy.java Tue Oct 22 11:43:37 2013 +0200 @@ -31,17 +31,21 @@ private int loopAndInvokeCounter; private long prevTimestamp; - private final int initialInvokeCounter; private final int compilationThreshold; + private final String name; - public CompilationPolicy(final int compilationThreshold, final int initialInvokeCounter) { + public CompilationPolicy(final int compilationThreshold, final int initialInvokeCounter, final String name) { this.invokeCounter = initialInvokeCounter; this.loopAndInvokeCounter = compilationThreshold; this.originalInvokeCounter = compilationThreshold; - this.prevTimestamp = System.currentTimeMillis(); + this.prevTimestamp = System.nanoTime(); this.compilationThreshold = compilationThreshold; - this.initialInvokeCounter = initialInvokeCounter; + this.name = name; + } + + public String getName() { + return this.name; } public int getInvokeCounter() { @@ -91,19 +95,23 @@ public boolean compileOrInline() { if (invokeCounter <= 0 && loopAndInvokeCounter <= 0) { if (TruffleUseTimeForCompilationDecision.getValue()) { - long timestamp = System.currentTimeMillis(); - if ((timestamp - prevTimestamp) < TruffleCompilationDecisionTime.getValue()) { + long timestamp = System.nanoTime(); + long timespan = (timestamp - prevTimestamp); + if (timespan < (TruffleCompilationDecisionTime.getValue())) { return true; } - this.invokeCounter = initialInvokeCounter; this.loopAndInvokeCounter = compilationThreshold; this.originalInvokeCounter = compilationThreshold; this.prevTimestamp = timestamp; + if (TruffleCompilationDecisionTimePrintFail.getValue()) { + // Checkstyle: stop + System.out.println(name + ": timespan " + (timespan / 1000000) + " ms larger than threshold"); + // Checkstyle: resume + } } else { return true; } } return false; } - } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Tue Oct 22 11:43:37 2013 +0200 @@ -46,7 +46,7 @@ protected OptimizedCallTarget(RootNode rootNode, FrameDescriptor descriptor, TruffleCompiler compiler, int invokeCounter, int compilationThreshold) { super(rootNode, descriptor); this.compiler = compiler; - this.compilationPolicy = new CompilationPolicy(compilationThreshold, invokeCounter); + this.compilationPolicy = new CompilationPolicy(compilationThreshold, invokeCounter, rootNode.toString()); this.rootNode.setCallTarget(this); if (TruffleCallTargetProfiling.getValue()) { diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Oct 22 11:43:37 2013 +0200 @@ -36,8 +36,6 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node; import com.oracle.graal.graph.spi.*; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.java.*; import com.oracle.graal.loop.*; import com.oracle.graal.nodes.*; @@ -51,6 +49,7 @@ import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; +import com.oracle.graal.runtime.*; import com.oracle.graal.truffle.nodes.asserts.*; import com.oracle.graal.truffle.nodes.frame.*; import com.oracle.graal.truffle.nodes.frame.NewFrameNode.VirtualOnlyInstanceNode; @@ -70,15 +69,15 @@ private final CanonicalizerPhase canonicalizer; private final ResolvedJavaType[] skippedExceptionTypes; private Set constantReceivers; - private final HotSpotGraphCache cache; + private final GraphCache cache; private final TruffleCache truffleCache; - public PartialEvaluator(Providers providers, TruffleCache truffleCache) { + public PartialEvaluator(RuntimeProvider runtime, Providers providers, TruffleCache truffleCache) { this.providers = providers; CustomCanonicalizer customCanonicalizer = new PartialEvaluatorCanonicalizer(providers.getMetaAccess(), providers.getConstantReflection()); this.canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue(), customCanonicalizer); this.skippedExceptionTypes = TruffleCompilerImpl.getSkippedExceptionTypes(providers.getMetaAccess()); - this.cache = HotSpotGraalRuntime.runtime().getCache(); + this.cache = runtime.getGraphCache(); this.truffleCache = truffleCache; try { diff -r 3ee8ae69d676 -r ce8dd5fa8d54 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 Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Tue Oct 22 11:43:37 2013 +0200 @@ -38,7 +38,6 @@ 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.*; import com.oracle.graal.nodes.spi.*; @@ -47,6 +46,7 @@ import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.printer.*; +import com.oracle.graal.runtime.*; import com.oracle.graal.truffle.nodes.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.nodes.*; @@ -63,7 +63,7 @@ private final PartialEvaluator partialEvaluator; private final Backend backend; private final ResolvedJavaType[] skippedExceptionTypes; - private final HotSpotGraalRuntime runtime; + private final RuntimeProvider runtime; private final TruffleCache truffleCache; private final ThreadPoolExecutor compileQueue; @@ -73,11 +73,11 @@ OptimisticOptimizations.Optimization.RemoveNeverExecutedCode, OptimisticOptimizations.Optimization.UseTypeCheckedInlining, OptimisticOptimizations.Optimization.UseTypeCheckHints); public TruffleCompilerImpl() { + this.runtime = Graal.getRequiredCapability(RuntimeProvider.class); + this.backend = runtime.getHostBackend(); Replacements truffleReplacements = ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements(); - this.providers = GraalCompiler.getGraalProviders().copyWith(truffleReplacements); - this.suites = Graal.getRequiredCapability(SuitesProvider.class).createSuites(); - this.backend = Graal.getRequiredCapability(Backend.class); - this.runtime = HotSpotGraalRuntime.runtime(); + this.providers = backend.getProviders().copyWith(truffleReplacements); + this.suites = backend.getSuites().createSuites(); this.skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess()); // Create compilation queue. @@ -87,7 +87,7 @@ config.setSkippedExceptionTypes(skippedExceptionTypes); this.truffleCache = new TruffleCache(providers, config, TruffleCompilerImpl.Optimizations); - this.partialEvaluator = new PartialEvaluator(providers, truffleCache); + this.partialEvaluator = new PartialEvaluator(runtime, providers, truffleCache); if (Debug.isEnabled()) { DebugEnvironment.initialize(System.out); @@ -128,7 +128,10 @@ final StructuredGraph graph; final GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault(); config.setSkippedExceptionTypes(skippedExceptionTypes); - runtime.evictDeoptedGraphs(); + GraphCache graphCache = runtime.getGraphCache(); + if (graphCache != null) { + graphCache.removeStaleGraphs(); + } if (TraceTruffleInliningTree.getValue()) { printInlineTree(compilable.getRootNode()); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Tue Oct 22 11:43:37 2013 +0200 @@ -72,6 +72,10 @@ @Option(help = "") public static final OptionValue TruffleCompilationDecisionTime = new OptionValue<>(100); @Option(help = "") + public static final OptionValue TruffleCompilationDecisionTime = new OptionValue<>(100 * 1000000L); + @Option(help = "") + public static final OptionValue TruffleCompilationDecisionTimePrintFail = new OptionValue<>(false); + @Option(help = "") public static final OptionValue TruffleBackgroundCompilation = new OptionValue<>(true); // tracing diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java Tue Oct 22 11:43:37 2013 +0200 @@ -26,12 +26,13 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.compiler.*; +import com.oracle.graal.api.runtime.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; +import com.oracle.graal.runtime.*; import com.oracle.graal.truffle.substitutions.*; /** @@ -47,7 +48,7 @@ } static Replacements makeInstance() { - Providers graalProviders = GraalCompiler.getGraalProviders(); + Providers graalProviders = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders(); Replacements truffleReplacements = new TruffleReplacements(graalProviders); truffleReplacements.registerSubstitutions(CompilerAssertsSubstitutions.class); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Tue Oct 22 11:43:37 2013 +0200 @@ -34,6 +34,7 @@ import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.nodes.virtual.*; +import com.oracle.graal.runtime.*; import com.oracle.graal.truffle.*; import com.oracle.graal.truffle.nodes.*; import com.oracle.truffle.api.*; @@ -45,7 +46,7 @@ */ public class NewFrameNode extends FixedWithNextNode implements IterableNodeType, VirtualizableAllocation, Canonicalizable { - static final ResolvedJavaType FRAME_TYPE = Graal.getRequiredCapability(MetaAccessProvider.class).lookupJavaType(FrameWithoutBoxing.class); + static final ResolvedJavaType FRAME_TYPE = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders().getMetaAccess().lookupJavaType(FrameWithoutBoxing.class); @Input private ValueNode descriptor; @Input private ValueNode caller; diff -r 3ee8ae69d676 -r ce8dd5fa8d54 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 Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Tue Oct 22 11:43:37 2013 +0200 @@ -170,8 +170,8 @@ * @param reason a description of the reason for the replacement * @return the new node */ - @SuppressWarnings({"unchecked"}) public final T replace(T newNode, String reason) { + CompilerDirectives.transferToInterpreter(); if (this.getParent() == null) { throw new IllegalStateException("This node cannot be replaced, because it does not yet have a parent."); } @@ -180,13 +180,40 @@ newNode.assignSourceSection(sourceSection); } onReplace(newNode, reason); - return (T) this.getParent().replaceChild(this, newNode); + ((Node) newNode).parent = this.parent; + if (!NodeUtil.replaceChild(this.parent, this, newNode)) { + fixupTree(); + } + return newNode; } - private T replaceChild(T oldChild, T newChild) { - NodeUtil.replaceChild(this, oldChild, newChild); - adoptChild(newChild); - return newChild; + /** + * Rewrite has failed; the tree is likely inconsistent, so fix any stale parent references. + * + * This is a rather expensive operation but rare to occur. + */ + private void fixupTree() { + Node rootNode = NodeUtil.findParent(this, RootNode.class); + if (rootNode == null) { + throw new UnsupportedOperationException("Tree does not have a root node."); + } + int fixCount = rootNode.fixupChildren(); + assert fixCount != 0 : "sanity check failed: missing @Child[ren] or adoptChild?"; + // if nothing had to be fixed, rewrite failed due to node not being a proper child. + } + + private int fixupChildren() { + int fixCount = 0; + for (Node child : getChildren()) { + if (child != null) { + if (child.parent != this) { + child.parent = this; + fixCount++; + } + fixCount += child.fixupChildren(); + } + } + return fixCount; } /** diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Tue Oct 22 11:43:37 2013 +0200 @@ -976,7 +976,7 @@ private List createImplicitChildrenAccessors() { NodeData node = getModel().getNode(); -// Map> expectTypes = new HashMap<>(); + // Map> expectTypes = new HashMap<>(); @SuppressWarnings("unchecked") List> expectTypes = Arrays.> asList(new Set[node.getGenericSpecialization().getParameters().size()]); @@ -2688,8 +2688,8 @@ final SpecializationData polymorphic = node.getGenericPolymorphicSpecialization(); ExecutableElement executeCached = nodeGen.getMethod(executeCachedName(polymorphic)); -// ExecutableTypeData execType = new ExecutableTypeData(polymorphic, executeCached, -// node.getTypeSystem(), polymorphic.getReturnType().getTypeSystemType()); + // ExecutableTypeData execType = new ExecutableTypeData(polymorphic, executeCached, + // node.getTypeSystem(), polymorphic.getReturnType().getTypeSystemType()); ExecutableTypeMethodParser parser = new ExecutableTypeMethodParser(getContext(), node); ExecutableTypeData execType = parser.parse(Arrays.asList(executeCached)).get(0); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java Tue Oct 22 11:43:37 2013 +0200 @@ -227,7 +227,7 @@ List polymorphicSignature = new ArrayList<>(); // TODO we should support more optimized for boxing -// List updatePolymorphic = generic.getReturnTypeAndParameters(); + // List updatePolymorphic = generic.getReturnTypeAndParameters(); List updatePolymorphic = Arrays.asList(); for (ActualParameter genericParameter : updatePolymorphic) { if (!genericParameter.getSpecification().isSignature()) { diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java Tue Oct 22 11:43:37 2013 +0200 @@ -21,9 +21,10 @@ * questions. */ - // The content of this file is automatically generated. DO NOT EDIT. +// The content of this file is automatically generated. DO NOT EDIT. package com.oracle.truffle.sl.parser; + import java.util.*; import com.oracle.truffle.sl.*; diff -r 3ee8ae69d676 -r ce8dd5fa8d54 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.java Tue Oct 22 11:42:10 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.java Tue Oct 22 11:43:37 2013 +0200 @@ -21,7 +21,7 @@ * questions. */ - // The content of this file is automatically generated. DO NOT EDIT. +// The content of this file is automatically generated. DO NOT EDIT. package com.oracle.truffle.sl.parser; diff -r 3ee8ae69d676 -r ce8dd5fa8d54 hotspot/.project --- a/hotspot/.project Tue Oct 22 11:42:10 2013 +0200 +++ b/hotspot/.project Tue Oct 22 11:43:37 2013 +0200 @@ -96,6 +96,11 @@ PARENT-1-PROJECT_LOC/src/cpu/x86/vm + ptx + 2 + PARENT-1-PROJECT_LOC/src/gpu/ptx/vm + + sparc 2 PARENT-1-PROJECT_LOC/src/cpu/sparc/vm @@ -121,6 +126,11 @@ PARENT-1-PROJECT_LOC/src/os_cpu/bsd_x86/vm + bsd_ptx + 2 + PARENT-1-PROJECT_LOC/src/os_gpu/bsd_ptx/vm + + windows 2 PARENT-1-PROJECT_LOC/src/os/windows/vm @@ -141,6 +151,11 @@ PARENT-1-PROJECT_LOC/src/os_cpu/linux_x86/vm + linux_ptx + 2 + PARENT-1-PROJECT_LOC/src/os_gpu/linux_ptx/vm + + linux_sparc 2 PARENT-1-PROJECT_LOC/src/os_cpu/linux_sparc/vm diff -r 3ee8ae69d676 -r ce8dd5fa8d54 make/bsd/makefiles/gcc.make --- a/make/bsd/makefiles/gcc.make Tue Oct 22 11:42:10 2013 +0200 +++ b/make/bsd/makefiles/gcc.make Tue Oct 22 11:43:37 2013 +0200 @@ -313,6 +313,14 @@ OPT_CFLAGS/loopTransform.o += $(OPT_CFLAGS/NOOPT) OPT_CFLAGS/unsafe.o += -O1 endif + # Clang 5.0 + ifeq ($(shell expr $(CC_VER_MAJOR) = 5 \& $(CC_VER_MINOR) = 0), 1) + OPT_CFLAGS/graalCompilerToVM.o += -O1 + OPT_CFLAGS/unsafe.o += -O1 + # Specific optimization level plus precompiled headers produces: + # error: __OPTIMIZE_SIZE__ predefined macro was enabled in PCH file but is currently disabled + USE_PRECOMPILED_HEADER = 0 + endif else # 6835796. Problem in GCC 4.3.0 with mulnode.o optimized compilation. ifeq ($(shell expr $(CC_VER_MAJOR) = 4 \& $(CC_VER_MINOR) = 3), 1) diff -r 3ee8ae69d676 -r ce8dd5fa8d54 make/windows/makefiles/projectcreator.make --- a/make/windows/makefiles/projectcreator.make Tue Oct 22 11:42:10 2013 +0200 +++ b/make/windows/makefiles/projectcreator.make Tue Oct 22 11:43:37 2013 +0200 @@ -193,7 +193,6 @@ ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \ -define_compiler2 COMPILER2 \ -define_compiler2 GRAAL \ - -define_compiler2 TIERED \ -ignorePath_compiler2 graal/generated \ -additionalFile_compiler2 $(Platform_arch_model).ad \ -additionalFile_compiler2 ad_$(Platform_arch_model).cpp \ diff -r 3ee8ae69d676 -r ce8dd5fa8d54 mx/commands.py --- a/mx/commands.py Tue Oct 22 11:42:10 2013 +0200 +++ b/mx/commands.py Tue Oct 22 11:43:37 2013 +0200 @@ -989,8 +989,8 @@ global _jacoco _jacoco = 'off' - t = Task('CleanAndBuildGraalVisualizer') - mx.run(['ant', '-f', join(_graal_home, 'visualizer', 'build.xml'), '-q', 'clean', 'build']) + t = Task('CleanAndBuildIdealGraphVisualizer') + mx.run(['ant', '-f', join(_graal_home, 'src', 'share', 'tools', 'IdealGraphVisualizer', 'build.xml'), '-q', 'clean', 'build']) tasks.append(t.stop()) # Prevent Graal modifications from breaking the standard builds diff -r 3ee8ae69d676 -r ce8dd5fa8d54 mx/projects --- a/mx/projects Tue Oct 22 11:42:10 2013 +0200 +++ b/mx/projects Tue Oct 22 11:43:37 2013 +0200 @@ -32,6 +32,7 @@ com.oracle.graal.hotspot.amd64,\ com.oracle.graal.hotspot.ptx,\ com.oracle.graal.truffle,\ +com.oracle.graal.truffle.hotspot.amd64,\ com.oracle.graal.hotspot.sparc,\ com.oracle.graal.hotspot,\ com.oracle.graal.hotspot.hsail @@ -61,7 +62,7 @@ # graal.api.meta.test project@com.oracle.graal.api.meta.test@subDir=graal project@com.oracle.graal.api.meta.test@sourceDirs=src -project@com.oracle.graal.api.meta.test@dependencies=JUNIT,com.oracle.graal.api.meta,com.oracle.graal.api.runtime +project@com.oracle.graal.api.meta.test@dependencies=JUNIT,com.oracle.graal.runtime,com.oracle.graal.java project@com.oracle.graal.api.meta.test@checkstyle=com.oracle.graal.graph project@com.oracle.graal.api.meta.test@javaCompliance=1.7 project@com.oracle.graal.api.meta.test@workingSets=API,Graal,Test @@ -117,7 +118,7 @@ # graal.hotspot project@com.oracle.graal.hotspot@subDir=graal project@com.oracle.graal.hotspot@sourceDirs=src -project@com.oracle.graal.hotspot@dependencies=com.oracle.graal.replacements,com.oracle.graal.printer +project@com.oracle.graal.hotspot@dependencies=com.oracle.graal.replacements,com.oracle.graal.runtime,com.oracle.graal.printer project@com.oracle.graal.hotspot@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hotspot@annotationProcessors=com.oracle.graal.replacements.verifier,com.oracle.graal.service.processor project@com.oracle.graal.hotspot@javaCompliance=1.7 @@ -414,6 +415,14 @@ project@com.oracle.graal.compiler.sparc.test@javaCompliance=1.7 project@com.oracle.graal.compiler.sparc.test@workingSets=Graal,SPARC,Test +# graal.runtime +project@com.oracle.graal.runtime@subDir=graal +project@com.oracle.graal.runtime@sourceDirs=src +project@com.oracle.graal.runtime@dependencies=com.oracle.graal.compiler +project@com.oracle.graal.runtime@checkstyle=com.oracle.graal.graph +project@com.oracle.graal.runtime@javaCompliance=1.7 +project@com.oracle.graal.runtime@workingSets=Graal + # graal.bytecode project@com.oracle.graal.bytecode@subDir=graal project@com.oracle.graal.bytecode@sourceDirs=src @@ -440,7 +449,7 @@ # graal.java.decompiler.test project@com.oracle.graal.java.decompiler.test@subDir=graal project@com.oracle.graal.java.decompiler.test@sourceDirs=src -project@com.oracle.graal.java.decompiler.test@dependencies=com.oracle.graal.printer +project@com.oracle.graal.java.decompiler.test@dependencies=com.oracle.graal.printer,com.oracle.graal.runtime project@com.oracle.graal.java.decompiler.test@checkstyle=com.oracle.graal.graph project@com.oracle.graal.java.decompiler.test@javaCompliance=1.7 project@com.oracle.graal.java.decompiler.test@workingSets=Graal,Test @@ -464,7 +473,7 @@ # graal.compiler.test project@com.oracle.graal.compiler.test@subDir=graal project@com.oracle.graal.compiler.test@sourceDirs=src -project@com.oracle.graal.compiler.test@dependencies=com.oracle.graal.test,com.oracle.graal.printer +project@com.oracle.graal.compiler.test@dependencies=com.oracle.graal.test,com.oracle.graal.printer,com.oracle.graal.runtime project@com.oracle.graal.compiler.test@checkstyle=com.oracle.graal.graph project@com.oracle.graal.compiler.test@javaCompliance=1.7 project@com.oracle.graal.compiler.test@workingSets=Graal,Test @@ -488,7 +497,7 @@ # graal.asm.test project@com.oracle.graal.asm.test@subDir=graal project@com.oracle.graal.asm.test@sourceDirs=src -project@com.oracle.graal.asm.test@dependencies=com.oracle.graal.api.runtime,com.oracle.graal.test,com.oracle.graal.asm +project@com.oracle.graal.asm.test@dependencies=com.oracle.graal.test,com.oracle.graal.runtime project@com.oracle.graal.asm.test@checkstyle=com.oracle.graal.graph project@com.oracle.graal.asm.test@javaCompliance=1.7 project@com.oracle.graal.asm.test@workingSets=Graal,Assembler,Test @@ -628,7 +637,7 @@ # graal.truffle project@com.oracle.graal.truffle@subDir=graal project@com.oracle.graal.truffle@sourceDirs=src -project@com.oracle.graal.truffle@dependencies=com.oracle.truffle.api,com.oracle.graal.hotspot +project@com.oracle.graal.truffle@dependencies=com.oracle.truffle.api,com.oracle.graal.replacements,com.oracle.graal.runtime,com.oracle.graal.printer project@com.oracle.graal.truffle@checkstyle=com.oracle.graal.graph project@com.oracle.graal.truffle@javaCompliance=1.7 project@com.oracle.graal.truffle@workingSets=Graal,Truffle @@ -641,4 +650,11 @@ project@com.oracle.graal.truffle.test@javaCompliance=1.7 project@com.oracle.graal.truffle.test@workingSets=Graal,Truffle,Test - +# graal.truffle.hotspot.amd64 +project@com.oracle.graal.truffle.hotspot.amd64@subDir=graal +project@com.oracle.graal.truffle.hotspot.amd64@sourceDirs=src +project@com.oracle.graal.truffle.hotspot.amd64@dependencies=com.oracle.graal.truffle,com.oracle.graal.hotspot.amd64 +project@com.oracle.graal.truffle.hotspot.amd64@checkstyle=com.oracle.graal.graph +project@com.oracle.graal.truffle.hotspot.amd64@javaCompliance=1.7 +project@com.oracle.graal.truffle.hotspot.amd64@annotationProcessors=com.oracle.graal.service.processor +project@com.oracle.graal.truffle.hotspot.amd64@workingSets=Graal,Truffle diff -r 3ee8ae69d676 -r ce8dd5fa8d54 mxtool/mx.py --- a/mxtool/mx.py Tue Oct 22 11:42:10 2013 +0200 +++ b/mxtool/mx.py Tue Oct 22 11:43:37 2013 +0200 @@ -55,17 +55,18 @@ commands.py Suite specific extensions to the commands available to mx. - includes + imports Other suites to be loaded. This is recursive. Each - line in an includes file is a path to a suite directory. + line in an imports file is the name of an imported suite. + The suite is located using a SuiteModel (cf searchpath) env A set of environment variable definitions. These override any existing environment variables. Common properties set here include JAVA_HOME and IGNORED_PROJECTS. -The includes and env files are typically not put under version control -as they usually contain local file-system paths. +The env file is typically not put under version control +as it usually contain local file-system paths. The projects file is like the pom.xml file from Maven except that it is a properties file (not XML). Each non-comment line @@ -156,9 +157,13 @@ _suites = dict() _annotationProcessors = None _mainSuite = None +_src_suitemodel = None +_dst_suitemodel = None _opts = None _java = None _check_global_structures = True # can be set False to allow suites with duplicate definitions to load without aborting +_warn = False +_hg = None """ @@ -493,38 +498,291 @@ deps.append(self) return deps +class HgConfig: + """ + Encapsulates access to Mercurial (hg) + """ + def __init__(self): + self.missing = 'no hg executable found' + try: + subprocess.check_output(['hg']) + self.has_hg = True + except OSError: + self.has_hg = False + warn(self.missing) + + def _check(self, abortOnFail=True): + if not self.has_hg: + if abortOnFail: + abort(self.missing) + else: + warn(self.missing) + return self.has_hg + + def _tip(self, s, abortOnError=True): + if not self.has_hg: + return None + try: + version = subprocess.check_output(['hg', 'tip', '-R', s.dir, '--template', '{node}']) + if s.version is not None and s.version != version: + abort('version of suite ' + s.name +' has changed during run') + return version + except subprocess.CalledProcessError: + if abortOnError: + abort('failed to get tip revision id') + else: + return None + + def _canpush(self, s, strict=True): + try: + output = subprocess.check_output(['hg', '-R', s.dir, 'status']) + # super strict + return output == '' + except subprocess.CalledProcessError: + return False + + def _default_push(self, sdir): + with open(join(sdir, '.hg', 'hgrc')) as f: + for line in f: + line = line.rstrip() + if line.startswith('default = '): + return line[len('default = '):] + return None + +class SuiteModel: + """ + Defines how to locate a URL/path for a suite, including imported suites. + Conceptually a SuiteModel is defined by a primary suite URL/path and a + map from suite name to URL/path for imported suites. + Subclasses define a specfic implementation. + """ + def __init__(self): + self.primaryDir = None + self.suitenamemap = {} + + def _find_suite_dir(self, suitename): + """locates the URL/path for suitename or None if not found""" + abort('_find_suite_dir not implemented') + + def _set_primary_dir(self, d): + """informs that d is the primary suite directory""" + self._primaryDir = d + + def _importee_dir(self, importer_dir, suitename): + """returns the directory path for an import of suitename, given importer_dir""" + abort('_importee_dir not implemented') + + def _nestedsuites_dirname(self): + """Returns the dirname that contains any nested suites if the model supports that""" + return None + + def _mxDirName(self, name): + # temporary workaround until mx.graal exists + if name == 'graal': + return 'mx' + else: + return 'mx.' + name + + def _search_dir(self, searchDir, mxDirName): + for dd in os.listdir(searchDir): + sd = _is_suite_dir(join(searchDir, dd), mxDirName) + if sd is not None: + return sd + + def _create_suitenamemap(self, optionspec, suitemap): + """Three ways to specify a suite name mapping, in order of precedence: + 1. Explicitly in optionspec. + 2. In suitemap. + 3. in MXSUITEMAP environment variable. + """ + if optionspec != '': + spec = optionspec + elif suitemap is not None: + spec = suitemap + elif get_env('MXSUITEMAP') is not None: + spec = get_env('MXSUITEMAP') + else: + return + pairs = spec.split(',') + for pair in pairs: + mappair = pair.split('=') + self.suitenamemap[mappair[0]] = mappair[1] + + @staticmethod + def _set_suitemodel(option, suitemap): + if option.startswith('sibling'): + return SiblingSuiteModel(os.getcwd(), option, suitemap) + elif option.startswith('nested'): + return NestedImportsSuiteModel(os.getcwd(), option, suitemap) + elif option.startswith('path'): + return PathSuiteModel(option[len('path:'):]) + else: + abort('unknown suitemodel type: ' + option) + + @staticmethod + def _parse_options(): + # suite-specific args may match the known args so there is no way at this early stage + # to use ArgParser to handle the suite model global arguments, so we just do it manually. + def _get_argvalue(arg, args, i): + if i < len(args): + return args[i] + else: + abort('value expected with ' + arg) + + args = sys.argv[1:] + src_suitemodel_arg = dst_suitemodel_arg = 'sibling' + suitemap_arg = None + + i = 0 + while i < len(args): + arg = args[i] + if arg == '--src-suitemodel': + src_suitemodel_arg = _get_argvalue(arg, args, i + 1) + elif arg == '--dst-suitemodel': + dst_suitemodel_arg = _get_argvalue(arg, args, i + 1) + elif arg == '--suitemap': + suitemap_arg = _get_argvalue(arg, args, i + 1) + elif arg == '-w': + # to get warnings on suite loading issues before command line is parsed + global _warn + _warn = True + + i = i + 1 + + global _src_suitemodel + _src_suitemodel = SuiteModel._set_suitemodel(src_suitemodel_arg, suitemap_arg) + global _dst_suitemodel + _dst_suitemodel = SuiteModel._set_suitemodel(dst_suitemodel_arg, suitemap_arg) + + +class SiblingSuiteModel(SuiteModel): + """All suites are siblings in the same parent directory, recorded as _suiteRootDir""" + def __init__(self, suiteRootDir, option, suitemap): + SuiteModel.__init__(self) + self._suiteRootDir = suiteRootDir + self._create_suitenamemap(option[len('sibling:'):], suitemap) + + def _find_suite_dir(self, name): + return self._search_dir(self._suiteRootDir, self._mxDirName(name)) + + def _set_primary_dir(self, d): + SuiteModel._set_primary_dir(self, d) + self._suiteRootDir = dirname(d) + + def _importee_dir(self, importer_dir, suitename): + if self.suitenamemap.has_key(suitename): + suitename = self.suitenamemap[suitename] + return join(dirname(importer_dir), suitename) + +class NestedImportsSuiteModel(SuiteModel): + """Imported suites are all siblings in an 'imported_suites' directory of the primary suite""" + def _imported_suites_dirname(self): + return "imported_suites" + + def __init__(self, primaryDir, option, suitemap): + SuiteModel.__init__(self) + self._primaryDir = primaryDir + self._create_suitenamemap(option[len('nested:'):], suitemap) + + def _find_suite_dir(self, name): + return self._search_dir(join(self._primaryDir, self._imported_suites_dirname()), self._mxDirName(name)) + + def _importee_dir(self, importer_dir, suitename): + if self.suitenamemap.has_key(suitename): + suitename = self.suitenamemap[suitename] + if basename(importer_dir) == basename(self._primaryDir): + # primary is importer + this_imported_suites_dirname = join(importer_dir, self._imported_suites_dirname()) + if not exists(this_imported_suites_dirname): + os.mkdir(this_imported_suites_dirname) + return join(this_imported_suites_dirname, suitename) + else: + return join(dirname(importer_dir), suitename) + + def _nestedsuites_dirname(self): + return self._imported_suites_dirname() + +class PathSuiteModel(SuiteModel): + """The most general model. Uses a map from suitename to URL/path provided by the user""" + def __init__(self, path): + SuiteModel.__init__(self) + paths = path.split(',') + self.suit_to_url = {} + for path in paths: + pair = path.split('=') + if len(pair) > 1: + suitename = pair[0] + suiteurl = pair[1] + else: + suitename = basename(pair[0]) + suiteurl = pair[0] + self.suit_to_url[suitename] = suiteurl + + def _find_suite_dir(self, suitename): + if self.suit_to_url.has_key(suitename): + return self.suit_to_url[suitename] + else: + return None + + def _importee_dir(self, importer_dir, suitename): + if suitename in self.suit_to_url: + return self.suit_to_url[suitename] + else: + abort('suite ' + suitename + ' not found') + +class SuiteImport: + def __init__(self, name, version): + self.name = name + self.version = version + + @staticmethod + def _parse_specification(specification): + pair = specification.split(',') + name = pair[0] + if len(pair) > 1: + version = pair[1] + else: + version = None + return SuiteImport(name, version) + + @staticmethod + def _tostring(name, version): + return name + ',' + version + + def __str__(self): + return self.name + ',' + self.version + class Suite: - def __init__(self, d, mxDir, primary): - self.dir = d + def __init__(self, mxDir, primary, load=True): + self.dir = dirname(mxDir) self.mxDir = mxDir self.projects = [] self.libs = [] self.dists = [] - self.includes = [] + self.imports = [] self.commands = None self.primary = primary - self._load_env(mxDir) - self._load_commands(mxDir) - self._load_includes(mxDir) - self.name = d # re-initialized in _load_projects + self.name = _suitename(mxDir) # validated in _load_projects + self.version = None # _hg._tip checks current version if not None + self.version = _hg._tip(self, False) + if load: + # load suites bottom up to make sure command overriding works properly + self._load_imports() + self._load_env() + self._load_commands() + _suites[self.name] = self def __str__(self): return self.name - def _load_projects(self, mxDir): + def _load_projects(self): libsMap = dict() projsMap = dict() distsMap = dict() - projectsFile = join(mxDir, 'projects') + projectsFile = join(self.mxDir, 'projects') if not exists(projectsFile): return - def _find_suite_key(): - for items in _suites.items(): - if items[1].dir == self.dir: - return items[0] - raise KeyError - with open(projectsFile) as f: prefix = '' for line in f: @@ -544,10 +802,7 @@ if parts[0] != 'suite': abort('Single part property must be "suite": ' + key) if self.name != value: - currentKey = _find_suite_key() - _suites.pop(currentKey) - self.name = value - _suites[value] = self + abort('suite name in project file does not match ' + _suitename(self.mxDir)) continue if len(parts) != 3: abort('Property name does not have 3 parts separated by "@": ' + key) @@ -616,38 +871,89 @@ if self.name is None: abort('Missing "suite=" in ' + projectsFile) - def _load_commands(self, mxDir): - commandsPath = join(mxDir, 'commands.py') + def _commands_name(self): + return 'mx_' + self.name + + def _find_commands(self, name): + commandsPath = join(self.mxDir, name + '.py') if exists(commandsPath): + return name + else: + return None + + def _load_commands(self): + commandsName = self._find_commands(self._commands_name()) + if commandsName is None: + # backwards compatibility + commandsName = self._find_commands('commands') + if commandsName is not None: + if commandsName in sys.modules: + abort(commandsName + '.py in suite ' + self.name + ' duplicates ' + sys.modules[commandsName].__file__) # temporarily extend the Python path - sys.path.insert(0, mxDir) - mod = __import__('commands') - - self.commands = sys.modules.pop('commands') - sys.modules[join(mxDir, 'commands')] = self.commands + sys.path.insert(0, self.mxDir) + mod = __import__(commandsName) + + self.commands = sys.modules.pop(commandsName) + sys.modules[commandsName] = self.commands # revert the Python path del sys.path[0] if not hasattr(mod, 'mx_init'): - abort(commandsPath + ' must define an mx_init(env) function') + abort(commandsName + '.py in suite ' + self.name + ' must define an mx_init(suite) function') if hasattr(mod, 'mx_post_parse_cmd_line'): self.mx_post_parse_cmd_line = mod.mx_post_parse_cmd_line mod.mx_init(self) self.commands = mod - def _load_includes(self, mxDir): - includes = join(mxDir, 'includes') - if exists(includes): - with open(includes) as f: + def _visit_imports(self, visitor, **extra_args): + """ + Visitor support for the imports file. + For each line of the imports file that specifies an import, the visitor function is + called with this suite, a SuiteImport instance created from the line and any extra args + passed to this call. In addition, if extra_args contains a key 'update_versions' that is True, + a StringIO value is added to extra_args with key 'updated_imports', and the visitor is responsible + for writing a (possibly) updated import line to the file, and the file is (possibly) updated after + all imports are processed. + N.B. There is no built-in support for avoiding visiting the same suite multiple times, + as this function only visits the imports of a singkle suite. If a (recursive) visitor function + wishes to visit a suite exactly once, it must manage that through extra_args. + """ + importsFile = join(self.mxDir, 'imports') + if exists(importsFile): + update_versions = extra_args.has_key('update_versions') and extra_args['update_versions'] + out = StringIO.StringIO() if update_versions else None + extra_args['updated_imports'] = out + with open(importsFile) as f: for line in f: - include = expandvars_in_property(line.strip()) - self.includes.append(include) - _loadSuite(os.path.abspath(include), False) - - def _load_env(self, mxDir): - e = join(mxDir, 'env') + sline = line.strip() + if len(sline) == 0 or sline.startswith('#'): + if out is not None: + out.write(sline + '\n') + continue + suite_import = SuiteImport._parse_specification(line.strip()) + visitor(self, suite_import, **extra_args) + + if out is not None: + update_file(importsFile, out.getvalue()) + + @staticmethod + def _find_and_loadsuite(suite, suite_import, **extra_args): + """visitor for the initial suite load""" + importMxDir = _src_suitemodel._find_suite_dir(suite_import.name) + if importMxDir is None: + abort('import ' + suite_import.name + ' not found') + suite.imports.append(suite_import) + imported_suite = _loadSuite(importMxDir, False) + if imported_suite.version != suite.version: + warn('import version of ' + imported_suite.name +' does not match tip of ' + suite.version) + + def _load_imports(self): + self._visit_imports(self._find_and_loadsuite) + + def _load_env(self): + e = join(self.mxDir, 'env') if exists(e): with open(e) as f: lineNum = 0 @@ -661,8 +967,8 @@ os.environ[key.strip()] = expandvars_in_property(value.strip()) def _post_init(self, opts): - self._load_projects(self.mxDir) - # set the global data structures, checking for conflicts unless _global_structures is False + self._load_projects() + # set the global data structures, checking for conflicts unless _check_global_structures is False for p in self.projects: existing = _projects.get(p.name) if existing is not None and _check_global_structures: @@ -680,7 +986,7 @@ if existing is not None and _check_global_structures: # allow redefinition, so use path from existing # abort('cannot redefine distribution ' + d.name) - print('WARNING: distribution ' + d.name + ' redefined') + warn('distribution ' + d.name + ' redefined') d.path = existing.path _dists[d.name] = d if hasattr(self, 'mx_post_parse_cmd_line'): @@ -777,28 +1083,16 @@ else: abort('Unknown operating system ' + sys.platform) -def _loadSuite(d, primary=False): +def _loadSuite(mxDir, primary=False): """ - Load a suite from the 'mx' or 'mx.bbb' subdirectory of d, where 'bbb' is basename of d + Load a suite from 'mxDir'. """ - mxDefaultDir = join(d, 'mx') - name = os.path.basename(d) - mxTaggedDir = mxDefaultDir + '.' + name - mxDir = None - if exists(mxTaggedDir) and isdir(mxTaggedDir): - mxDir = mxTaggedDir - else: - if exists(mxDefaultDir) and isdir(mxDefaultDir): - mxDir = mxDefaultDir - - - if mxDir is None: - return None - if len([s for s in _suites.itervalues() if s.dir == d]) == 0: - s = Suite(d, mxDir, primary) - # N.B. this will be updated once the projects file has been read - _suites[name] = s - return s + for s in _suites.itervalues(): + if s.mxDir == mxDir: + return s + # create the new suite + s = Suite(mxDir, primary) + return s def suites(opt_limit_to_suite=False): """ @@ -822,6 +1116,7 @@ abort('suite named ' + name + ' not found') return s + def projects_from_names(projectNames): """ Get the list of projects corresponding to projectNames; all projects if None @@ -1020,7 +1315,7 @@ else: break - envPath = join(_mainSuite.dir, 'mx', 'env') + envPath = join(_mainSuite.mxDir, 'env') if ask_yes_no('Persist this setting by adding "JAVA_HOME=' + javaHome + '" to ' + envPath, 'y'): with open(envPath, 'a') as fp: print >> fp, 'JAVA_HOME=' + javaHome @@ -1028,7 +1323,6 @@ return javaHome class ArgParser(ArgumentParser): - # Override parent to append the list of available commands def format_help(self): return ArgumentParser.format_help(self) + _format_commands() @@ -1041,6 +1335,7 @@ self.add_argument('-v', action='store_true', dest='verbose', help='enable verbose output') self.add_argument('-V', action='store_true', dest='very_verbose', help='enable very verbose output') + self.add_argument('-w', action='store_true', dest='warn', help='enable warning messages') self.add_argument('--dbg', type=int, dest='java_dbg_port', help='make Java processes wait on for a debugger', metavar='') self.add_argument('-d', action='store_const', const=8000, dest='java_dbg_port', help='alias for "-dbg 8000"') self.add_argument('--cp-pfx', dest='cp_prefix', help='class path prefix', metavar='') @@ -1052,6 +1347,9 @@ self.add_argument('--java-home', help='bootstrap JDK installation directory (must be JDK 6 or later)', metavar='') self.add_argument('--ignore-project', action='append', dest='ignored_projects', help='name of project to ignore', metavar='', default=[]) self.add_argument('--suite', action='append', dest='specific_suites', help='limit command to given suite', default=[]) + self.add_argument('--src-suitemodel', help='mechanism for locating imported suites', metavar='', default='sibling') + self.add_argument('--dst-suitemodel', help='mechanism for placing cloned/pushed suites', metavar='', default='sibling') + self.add_argument('--suitemap', help='explicit remapping of suite names', metavar='') if get_os() != 'windows': # Time outs are (currently) implemented with Unix specific functionality self.add_argument('--timeout', help='timeout (in seconds) for command', type=int, default=0, metavar='') @@ -1606,7 +1904,7 @@ javaCompliance = java().javaCompliance - defaultEcjPath = join(_mainSuite.dir, 'mx', 'ecj.jar') + defaultEcjPath = join(_mainSuite.mxDir, 'ecj.jar') parser = parser if parser is not None else ArgumentParser(prog='mx build') parser.add_argument('-f', action='store_true', dest='force', help='force build (disables timestamp checking)') @@ -1803,7 +2101,7 @@ jdtProperties = join(p.dir, '.settings', 'org.eclipse.jdt.core.prefs') - rootJdtProperties = join(p.suite.dir, 'mx', 'eclipse-settings', 'org.eclipse.jdt.core.prefs') + rootJdtProperties = join(p.suite.mxDir, 'eclipse-settings', 'org.eclipse.jdt.core.prefs') if not exists(jdtProperties) or os.path.getmtime(jdtProperties) < os.path.getmtime(rootJdtProperties): # Try to fix a missing properties file by running eclipseinit eclipseinit([], buildProcessorJars=False) @@ -2122,7 +2420,7 @@ The exit code of this command reflects how many files were updated.""" changedFiles = 0 - for s in suites(): + for s in suites(True): projectsFile = join(s.mxDir, 'projects') if not exists(projectsFile): continue @@ -2682,8 +2980,7 @@ if _isAnnotationProcessorDependency(p): _genEclipseBuilder(out, p, 'Jar.launch', 'archive ' + p.name, refresh=False, async=False, xmlIndent='', xmlStandalone='no') - # Refresh.launch seems to cause occasional build looping in Eclipse - # _genEclipseBuilder(out, p, 'Refresh.launch', '', refresh=True, async=True) + _genEclipseBuilder(out, p, 'Refresh.launch', '', refresh=True, async=True) if projToDist.has_key(p.name): dist, distDeps = projToDist[p.name] @@ -2763,12 +3060,20 @@ launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.ui.ATTR_CONSOLE_OUTPUT_ON', 'value': consoleOn}) launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND', 'value': 'true' if async else 'false'}) - baseDir = dirname(dirname(os.path.abspath(__file__))) + # expect to find the OS command to invoke mx in the same directory + baseDir = dirname(os.path.abspath(__file__)) cmd = 'mx.sh' if get_os() == 'windows': cmd = 'mx.cmd' - launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_LOCATION', 'value': join(baseDir, cmd) }) + cmdPath = join(baseDir, cmd) + if not os.path.exists(cmdPath): + # backwards compatibility for when the commands lived in parent of mxtool + cmdPath = join(dirname(baseDir), cmd) + if not os.path.exists(cmdPath): + abort('cannot locate ' + cmd) + + launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_LOCATION', 'value': cmdPath}) launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS', 'value': 'auto,full,incremental'}) launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS', 'value': mxCommand}) launchOut.element('booleanAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED', 'value': 'true'}) @@ -3210,18 +3515,24 @@ """find directories corresponding to deleted Java projects and delete them""" for suite in suites(True): projectDirs = [p.dir for p in suite.projects] - for root, dirnames, files in os.walk(suite.dir): - currentDir = join(suite.dir, root) - if currentDir in projectDirs: - # don't traverse subdirs of an existing project + for dirpath, dirnames, files in os.walk(suite.dir): + if dirpath == suite.dir: + # no point in traversing .hg + if '.hg' in dirnames: + dirnames.remove('.hg') + # if there are nested suites must not scan those now, as they are not in projectDirs + if _src_suitemodel._nestedsuites_dirname() in dirnames: + dirnames.remove(_src_suitemodel._nestedsuites_dirname()) + elif dirpath in projectDirs: + # don't traverse subdirs of an existing project in this suite dirnames[:] = [] else: projectConfigFiles = frozenset(['.classpath', 'nbproject']) indicators = projectConfigFiles.intersection(files) if len(indicators) != 0: - if not sys.stdout.isatty() or ask_yes_no(currentDir + ' looks like a removed project -- delete it', 'n'): - shutil.rmtree(currentDir) - log('Deleted ' + currentDir) + if not sys.stdout.isatty() or ask_yes_no(dirpath + ' looks like a removed project -- delete it', 'n'): + shutil.rmtree(dirpath) + log('Deleted ' + dirpath) def javadoc(args, parser=None, docDir='javadoc', includeDeps=True, stdDoclet=True): """generate javadoc for some/all Java projects""" @@ -3625,9 +3936,270 @@ if exists(tmpbase): shutil.rmtree(tmpbase) +def _kwArg(kwargs): + if len(kwargs) > 0: + return kwargs.pop(0) + return None + +def sclone(args): + """clone a suite repository, and its imported suites""" + _hg._check(True) + parser = ArgumentParser(prog='mx sclone') + parser.add_argument('--source', help='url/path of repo containing suite', metavar='') + parser.add_argument('--dest', help='destination directory (default basename of source)', metavar='') + parser.add_argument("--no-imports", action='store_true', help='do not clone imported suites') + parser.add_argument('nonKWArgs', nargs=REMAINDER, metavar='source [dest]...') + args = parser.parse_args(args) + # check for non keyword args + if args.source is None: + args.source = _kwArg(args.nonKWArgs) + if args.dest is None: + args.dest = _kwArg(args.nonKWArgs) + if len(args.nonKWArgs) > 0: + abort('unrecognized args: ' + ' '.join(args.nonKWArgs)) + + if args.source is None: + # must be primary suite and dest is required + if _mainSuite is None: + abort('--source missing and no primary suite found') + if args.dest is None: + abort('--dest required when --source is not given') + source = _mainSuite.dir + else: + source = args.source + + if args.dest is not None: + dest = args.dest + else: + dest = basename(source) + + dest = os.path.abspath(dest) + # We can now set the primary dir for the src/dst suitemodel + _dst_suitemodel._set_primary_dir(dest) + _src_suitemodel._set_primary_dir(source) + + _sclone(source, dest, None, args.no_imports) + +def _sclone(source, dest, version, no_imports): + cmd = ['hg', 'clone'] + if version is not None: + cmd.append('-r') + cmd.append(version) + cmd.append(source) + cmd.append(dest) + + run(cmd) + + mxDir = _is_suite_dir(dest) + if mxDir is None: + warn(source + ' is not an mx suite') + return None + + # create a Suite (without loading) to enable imports visitor + s = Suite(mxDir, False, load=False) + if not no_imports: + s._visit_imports(_scloneimports_visitor, source=source) + return s + +def _scloneimports_visitor(s, suite_import, source, **extra_args): + """ + cloneimports visitor for Suite._visit_imports. + The destination information is encapsulated by 's' + """ + _scloneimports(s, suite_import, source) + +def _scloneimports_suitehelper(sdir): + mxDir = _is_suite_dir(sdir) + if mxDir is None: + abort(sdir + ' is not an mx suite') + else: + # create a Suite (without loading) to enable imports visitor + return Suite(mxDir, False, load=False) + +def _scloneimports(s, suite_import, source): + # clone first, then visit imports once we can locate them + importee_source = _src_suitemodel._importee_dir(source, suite_import.name) + importee_dest = _dst_suitemodel._importee_dir(s.dir, suite_import.name) + if exists(importee_dest): + importee_suite = _scloneimports_suitehelper(importee_dest) + importee_suite._visit_imports(_scloneimports_visitor, source=importee_source) + else: + _sclone(importee_source, importee_dest, suite_import.version, False) + # _clone handles the recursive visit of the new imports + +def scloneimports(args): + """clone the imports of an existing suite""" + _hg._check(True) + parser = ArgumentParser(prog='mx scloneimports') + parser.add_argument('--source', help='url/path of repo containing suite', metavar='') + parser.add_argument('nonKWArgs', nargs=REMAINDER, metavar='source [dest]...') + args = parser.parse_args(args) + # check for non keyword args + if args.source is None: + args.source = _kwArg(args.nonKWArgs) + + if not os.path.isdir(args.source): + abort(args.source + ' is not a directory') + + s = _scloneimports_suitehelper(args.source) + + default_path = _hg._default_push(args.source) + + if default_path is None: + abort('no default path in ' + join(args.source, '.hg', 'hgrc')) + + # We can now set the primary dir for the dst suitemodel + # N.B. source is effectively the destination and the default_path is the (original) source + _dst_suitemodel._set_primary_dir(args.source) + + s._visit_imports(_scloneimports_visitor, source=default_path) + +def _spush_import_visitor(s, suite_import, dest, checks, clonemissing, **extra_args): + """push visitor for Suite._visit_imports""" + if dest is not None: + dest = _dst_suitemodel._importee_dir(dest, suite_import.name) + _spush(suite(suite_import.name), suite_import, dest, checks, clonemissing) + +def _spush_check_import_visitor(s, suite_import, **extra_args): + """push check visitor for Suite._visit_imports""" + currentTip = _hg._tip(suite(suite_import.name)) + if currentTip != suite_import.version: + abort('import version of ' + suite_import.name + ' in suite ' + s.name + ' does not match tip') + +def _spush(s, suite_import, dest, checks, clonemissing): + if checks: + if not _hg._canpush(s): + abort('working directory ' + s.dir + ' contains uncommitted changes, push aborted') + + # check imports first + if checks: + s._visit_imports(_spush_check_import_visitor) + + # ok, push imports + s._visit_imports(_spush_import_visitor, dest=dest, checks=checks, clonemissing=clonemissing) + + dest_exists = True + + if clonemissing: + if not os.path.exists(dest): + dest_exists = False + + def add_version(cmd, suite_import): + if suite_import is not None and suite_import.version is not None: + cmd.append('-r') + cmd.append(suite_import.version) + + if dest_exists: + cmd = ['hg', '-R', s.dir, 'push'] + add_version(cmd, suite_import) + if dest is not None: + cmd.append(dest) + rc = run(cmd, nonZeroIsFatal=False) + if rc != 0: + # rc of 1 not an error, means no changes + if rc != 1: + abort("push failed, exit code " + str(rc)) + else: + cmd = ['hg', 'clone'] + add_version(cmd, suite_import) + cmd.append(s.dir) + cmd.append(dest) + run(cmd) + +def spush(args): + """push primary suite and all its imports""" + _hg._check(True) + parser = ArgumentParser(prog='mx spush') + parser.add_argument('--dest', help='url/path of repo to push to (default as per hg push)', metavar='') + parser.add_argument('--no-checks', action='store_true', help='checks on status, versions are disabled') + parser.add_argument('--clonemissing', action='store_true', help='clone missing imported repos at destination (forces --no-checks)') + parser.add_argument('nonKWArgs', nargs=REMAINDER, metavar='source [dest]...') + args = parser.parse_args(args) + if args.dest is None: + args.dest = _kwArg(args.nonKWArgs) + if len(args.nonKWArgs) > 0: + abort('unrecognized args: ' + ' '.join(args.nonKWArgs)) + + if args.dest is not None and not os.path.isdir(args.dest): + abort('destination must be a directory') + + s = _check_primary_suite() + + if args.clonemissing: + if args.dest is None: + abort('--dest required with --clonemissing') + args.nochecks = True + + if args.dest is not None: + _dst_suitemodel._set_primary_dir(args.dest) + + _spush(s, None, args.dest, not args.no_checks, args.clonemissing) + +def _supdate_import_visitor(s, suite_import, **extra_args): + _supdate(suite(suite_import.name), suite_import) + +def _supdate(s, suite_import): + s._visit_imports(_supdate_import_visitor) + + run(['hg', '-R', s.dir, 'update']) + +def supdate(args): + """update primary suite and all its imports""" + + _hg._check(True) + s = _check_primary_suite() + + _supdate(s, None) + +def _scheck_imports_visitor(s, suite_import, update_versions, updated_imports): + """checkimportversions visitor for Suite._visit_imports""" + _scheck_imports(suite(suite_import.name), suite_import, update_versions, updated_imports) + +def _scheck_imports(s, suite_import, update_versions, updated_imports): + # check imports recursively + s._visit_imports(_scheck_imports_visitor, update_versions=update_versions) + + currentTip = _hg._tip(s) + if currentTip != suite_import.version: + print('import version of ' + s.name + ' does not match tip' + (': updating' if update_versions else '')) + + if update_versions: + suite_import.version = currentTip + line = str(suite_import) + updated_imports.write(line + '\n') + +def scheckimports(args): + """check that suite import versions are up to date""" + parser = ArgumentParser(prog='mx scheckimports') + parser.add_argument('--update-versions', help='update imported version ids', action='store_true') + args = parser.parse_args(args) + _check_primary_suite()._visit_imports(_scheck_imports_visitor, update_versions=args.update_versions) + +def _spull_import_visitor(s, suite_import, update_versions, updated_imports): + """pull visitor for Suite._visit_imports""" + _spull(suite(suite_import.name), update_versions, updated_imports) + +def _spull(s, update_versions, updated_imports): + _hg._check(True) + # pull imports first + s._visit_imports(_spull_import_visitor, update_versions=update_versions) + + run(['hg', '-R', s.dir, 'pull', '-u']) + if update_versions and updated_imports is not None: + tip = _hg._tip(s) + updated_imports.write(SuiteImport._tostring(s.name, tip) + '\n') + +def spull(args): + """pull primary suite and all its imports""" + _hg._check(True) + parser = ArgumentParser(prog='mx spull') + parser.add_argument('--update-versions', action='store_true', help='update version ids of imported suites') + args = parser.parse_args(args) + + _spull(_check_primary_suite(), args.update_versions, None) + def findclass(args, logToConsole=True): """find all classes matching a given substring""" - matches = [] for entry, filename in classpath_walk(includeBootClasspath=True): if filename.endswith('.class'): @@ -3734,17 +4306,19 @@ def update_commands(suite, new_commands): for key, value in new_commands.iteritems(): - if _commands.has_key(key) and not suite.primary: - pass - # print("WARNING: attempt to redefine command '" + key + "' in suite " + suite.dir) - else: - _commands[key] = value + if _commands.has_key(key): + warn("redefining command '" + key + "' in suite " + suite.name) + _commands[key] = value + +def warn(msg): + if _warn: + print('WARNING: ' + msg) # Table of commands in alphabetical order. # Keys are command names, value are lists: [, , ...] # If any of the format args are instances of Callable, then they are called with an 'env' are before being # used in the call to str.format(). -# Extensions should update this table directly +# Suite extensions should not update this table directly, but use update_commands _commands = { 'about': [about, ''], 'build': [build, '[options]'], @@ -3760,6 +4334,12 @@ 'ideinit': [ideinit, ''], 'archive': [archive, '[options]'], 'projectgraph': [projectgraph, ''], + 'sclone': [sclone, '[options]'], + 'scheckimports': [scheckimports, ''], + 'scloneimports': [scloneimports, '[options]'], + 'spull': [spull, '[options'], + 'spush': [spush, '[options'], + 'supdate': [supdate, ''], 'pylint': [pylint, ''], 'javap': [javap, ''], 'javadoc': [javadoc, '[options]'], @@ -3770,36 +4350,71 @@ _argParser = ArgParser() -def _findPrimarySuite(): - def is_suite_dir(d): +def _suitename(mxDir): + base = os.path.basename(mxDir) + parts = base.split('.') + # temporary workaround until mx.graal exists + if len(parts) == 1: + return 'graal' + else: + return parts[1] + +def _is_suite_dir(d, mxDirName=None): + """ + Checks if d contains a suite. + If mxDirName is None, matches any suite name, otherwise checks for exactly that suite. + """ + if os.path.isdir(d): for f in os.listdir(d): - if f == 'mx' or fnmatch.fnmatch(f, 'mx.*'): + if (mxDirName == None and (f == 'mx' or fnmatch.fnmatch(f, 'mx.*'))) or f == mxDirName: mxDir = join(d, f) if exists(mxDir) and isdir(mxDir) and exists(join(mxDir, 'projects')): - return dirname(mxDir) - - - # try current working directory first - if is_suite_dir(os.getcwd()): - return os.getcwd() - - # now search path of my executable - me = sys.argv[0] - parent = dirname(me) - while parent: - if is_suite_dir(parent): - return parent - parent = dirname(parent) + return mxDir + +def _check_primary_suite(): + if _mainSuite is None: + abort('no primary suite found') + else: + return _mainSuite + +def _needs_primary_suite(command): + return not command.startswith("sclone") + +def _findPrimarySuiteMxDir(): + # try current working directory first, the look up the tree + curdir = os.getcwd() + while curdir: + mxDir = _is_suite_dir(curdir) + if mxDir is not None: + return mxDir + parent = dirname(curdir) + if curdir == parent: + return None + curdir = parent + return None def main(): - primarySuiteDir = _findPrimarySuite() - if primarySuiteDir: + SuiteModel._parse_options() + + global _hg + _hg = HgConfig() + + primarySuiteMxDir = _findPrimarySuiteMxDir() + if primarySuiteMxDir: + _src_suitemodel._set_primary_dir(dirname(primarySuiteMxDir)) global _mainSuite - _mainSuite = _loadSuite(primarySuiteDir, True) + _mainSuite = _loadSuite(primarySuiteMxDir, True) opts, commandAndArgs = _argParser._parse_cmd_line() + if primarySuiteMxDir is None: + msg = 'no primary suite found' + if len(commandAndArgs) > 0 and _needs_primary_suite(commandAndArgs[0]): + abort(msg) + else: + warn(msg) + global _opts, _java _opts = opts _java = JavaConfig(opts) diff -r 3ee8ae69d676 -r ce8dd5fa8d54 src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java Tue Oct 22 11:42:10 2013 +0200 +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java Tue Oct 22 11:43:37 2013 +0200 @@ -201,12 +201,21 @@ } } + private static class Port { + public final boolean isList; + public final String name; + private Port(boolean isList, String name) { + this.isList = isList; + this.name = name; + } + } + private static class NodeClass { public final String className; public final String nameTemplate; - public final List inputs; - public final List sux; - private NodeClass(String className, String nameTemplate, List inputs, List sux) { + public final List inputs; + public final List sux; + private NodeClass(String className, String nameTemplate, List inputs, List sux) { this.className = className; this.nameTemplate = nameTemplate; this.inputs = inputs; @@ -301,9 +310,8 @@ int len = readInt(); ensureAvailable(len * 2); char[] chars = new char[len]; - for (int i = 0; i < len; i++) { - chars[i] = buffer.getChar(); - } + buffer.asCharBuffer().get(chars); + buffer.position(buffer.position() + len * 2); return new String(chars); } @@ -377,7 +385,7 @@ return (T) addPoolEntry(klass); } assert assertObjectType(klass, type); - int index = readInt(); + char index = readShort(); if (index < 0 || index >= constantPool.size()) { throw new IOException("Invalid constant pool index : " + index); } @@ -409,7 +417,7 @@ } private Object addPoolEntry(Class klass) throws IOException { - int index = readInt(); + char index = readShort(); int type = readByte(); assert assertObjectType(klass, type) : "Wrong object type : " + klass + " != " + type; Object obj; @@ -441,14 +449,18 @@ String className = readString(); String nameTemplate = readString(); int inputCount = readShort(); - List inputs = new ArrayList<>(inputCount); + List inputs = new ArrayList<>(inputCount); for (int i = 0; i < inputCount; i++) { - inputs.add(readPoolObject(String.class)); + boolean isList = readByte() != 0; + String name = readPoolObject(String.class); + inputs.add(new Port(isList, name)); } int suxCount = readShort(); - List sux = new ArrayList<>(suxCount); + List sux = new ArrayList<>(suxCount); for (int i = 0; i < suxCount; i++) { - sux.add(readPoolObject(String.class)); + boolean isList = readByte() != 0; + String name = readPoolObject(String.class); + sux.add(new Port(isList, name)); } obj = new NodeClass(className, nameTemplate, inputs, sux); break; @@ -685,17 +697,44 @@ } } int edgesStart = edges.size(); - int suxCount = readShort(); - for (int j = 0; j < suxCount; j++) { - int sux = readInt(); - int index = readShort(); - edges.add(new Edge(id, sux, (char) j, nodeClass.sux.get(index), false)); + int portNum = 0; + for (Port p : nodeClass.inputs) { + if (p.isList) { + int size = readShort(); + for (int j = 0; j < size; j++) { + int in = readInt(); + if (in >= 0) { + edges.add(new Edge(in, id, (char) (preds + portNum), p.name + "[" + j + "]", true)); + portNum++; + } + } + } else { + int in = readInt(); + if (in >= 0) { + edges.add(new Edge(in, id, (char) (preds + portNum), p.name, true)); + portNum++; + } + } + } - int inputCount = readShort(); - for (int j = 0; j < inputCount; j++) { - int in = readInt(); - int index = readShort(); - edges.add(new Edge(in, id, (char) (preds + j), nodeClass.inputs.get(index), true)); + portNum = 0; + for (Port p : nodeClass.sux) { + if (p.isList) { + int size = readShort(); + for (int j = 0; j < size; j++) { + int sux = readInt(); + if (sux >= 0) { + edges.add(new Edge(id, sux, (char) portNum, p.name + "[" + j + "]", false)); + portNum++; + } + } + } else { + int sux = readInt(); + if (sux >= 0) { + edges.add(new Edge(id, sux, (char) portNum, p.name, false)); + portNum++; + } + } } properties.setProperty("name", createName(edges.subList(edgesStart, edges.size()), props, nodeClass.nameTemplate)); properties.setProperty("class", nodeClass.className); diff -r 3ee8ae69d676 -r ce8dd5fa8d54 src/share/vm/gc_interface/collectedHeap.cpp --- a/src/share/vm/gc_interface/collectedHeap.cpp Tue Oct 22 11:42:10 2013 +0200 +++ b/src/share/vm/gc_interface/collectedHeap.cpp Tue Oct 22 11:43:37 2013 +0200 @@ -506,7 +506,7 @@ " to threads list is doomed to failure!"); for (JavaThread *thread = Threads::first(); thread; thread = thread->next()) { if (use_tlab) thread->tlab().make_parsable(retire_tlabs); -#ifdef COMPILER2 +#if defined(COMPILER2) || defined(GRAAL) // The deferred store barriers must all have been flushed to the // card-table (or other remembered set structure) before GC starts // processing the card-table (or other remembered set). diff -r 3ee8ae69d676 -r ce8dd5fa8d54 src/share/vm/graal/graalCompilerToGPU.cpp --- a/src/share/vm/graal/graalCompilerToGPU.cpp Tue Oct 22 11:42:10 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToGPU.cpp Tue Oct 22 11:43:37 2013 +0200 @@ -190,29 +190,6 @@ return gpu::available_processors(); C2V_END -static objArrayHandle newSingletonStringArray(const char* value, TRAPS) { - objArrayHandle nullRes; - objArrayOop res = oopFactory::new_objArray(SystemDictionary::String_klass(), 1, CHECK_(nullRes)); - objArrayHandle res_h = objArrayHandle(THREAD, res); - Handle valueString = java_lang_String::create_from_str(value, CHECK_(nullRes)); - res_h->obj_at_put(0, valueString()); - return res_h; -} - -C2V_VMENTRY(jobject, getAvailableGPUArchitectures, (JNIEnv *env, jobject)) - if (UseGPU) { - if (gpu::is_available() && gpu::has_gpu_linkage()) { - if (gpu::get_target_il_type() == gpu::PTX) { - return JNIHandles::make_local(newSingletonStringArray("PTX", THREAD)()); - } - if (gpu::get_target_il_type() == gpu::HSAIL) { - return JNIHandles::make_local(newSingletonStringArray("HSAIL", THREAD)()); - } - } - } - return JNIHandles::make_local(oopFactory::new_objArray(SystemDictionary::String_klass(), 0, THREAD)); -C2V_END - C2V_VMENTRY(jboolean, deviceDetach, (JNIEnv *env, jobject)) return true; C2V_END @@ -258,7 +235,6 @@ {CC"deviceInit", CC"()Z", FN_PTR(deviceInit)}, {CC"deviceDetach", CC"()Z", FN_PTR(deviceDetach)}, {CC"availableProcessors", CC"()I", FN_PTR(availableProcessors)}, - {CC"getAvailableGPUArchitectures", CC"()["STRING, FN_PTR(getAvailableGPUArchitectures)}, {CC"executeExternalMethodVarargs", CC"(["OBJECT HS_INSTALLED_CODE")"OBJECT, FN_PTR(executeExternalMethodVarargs)}, {CC"executeParallelMethodVarargs", CC"(III["OBJECT HS_INSTALLED_CODE")"OBJECT, FN_PTR(executeParallelMethodVarargs)}, }; diff -r 3ee8ae69d676 -r ce8dd5fa8d54 src/share/vm/graal/graalGlobals.hpp --- a/src/share/vm/graal/graalGlobals.hpp Tue Oct 22 11:42:10 2013 +0200 +++ b/src/share/vm/graal/graalGlobals.hpp Tue Oct 22 11:43:37 2013 +0200 @@ -55,7 +55,7 @@ product(intx, TraceGraal, 0, \ "Trace level for Graal") \ \ - product(bool, GraalDeferredInitBarriers, true, \ + product(bool, GraalDeferredInitBarriers, false, \ "Defer write barriers of young objects") \ \ develop(bool, GraalUseFastLocking, true, \ diff -r 3ee8ae69d676 -r ce8dd5fa8d54 src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Tue Oct 22 11:42:10 2013 +0200 +++ b/src/share/vm/runtime/arguments.cpp Tue Oct 22 11:43:37 2013 +0200 @@ -35,6 +35,7 @@ #include "prims/jvmtiExport.hpp" #include "runtime/arguments.hpp" #include "runtime/globals_extension.hpp" +#include "runtime/gpu.hpp" #include "runtime/java.hpp" #include "services/management.hpp" #include "services/memTracker.hpp" @@ -130,6 +131,9 @@ SystemProperty *Arguments::_java_home = NULL; SystemProperty *Arguments::_java_class_path = NULL; SystemProperty *Arguments::_sun_boot_class_path = NULL; +#ifdef GRAAL +SystemProperty *Arguments::_graal_gpu_isalist = NULL; +#endif char* Arguments::_meta_index_path = NULL; char* Arguments::_meta_index_dir = NULL; @@ -193,6 +197,9 @@ _sun_boot_class_path = new SystemProperty("sun.boot.class.path", NULL, true); _java_class_path = new SystemProperty("java.class.path", "", true); +#ifdef GRAAL + _graal_gpu_isalist = new SystemProperty("graal.gpu.isalist", NULL, true); +#endif // Add to System Property list. PropertyList_add(&_system_properties, _java_ext_dirs); @@ -202,6 +209,9 @@ PropertyList_add(&_system_properties, _java_home); PropertyList_add(&_system_properties, _java_class_path); PropertyList_add(&_system_properties, _sun_boot_class_path); +#ifdef GRAAL + PropertyList_add(&_system_properties, _graal_gpu_isalist); +#endif // Set OS specific system properties values os::init_system_properties_values(); @@ -3801,6 +3811,24 @@ } } +#ifdef GRAAL + if (_graal_gpu_isalist->value() == NULL) { + // Initialize the graal.gpu.isalist system property if + // a) it was not explicitly defined by the user and + // b) at least one GPU is available. + // GPU offload can be disabled by setting the property + // to the empty string on the command line + if (gpu::is_available() && gpu::has_gpu_linkage()) { + if (gpu::get_target_il_type() == gpu::PTX) { + _graal_gpu_isalist->append_value("PTX"); + } + if (gpu::get_target_il_type() == gpu::HSAIL) { + _graal_gpu_isalist->append_value("HSAIL"); + } + } + } +#endif + return JNI_OK; } diff -r 3ee8ae69d676 -r ce8dd5fa8d54 src/share/vm/runtime/arguments.hpp --- a/src/share/vm/runtime/arguments.hpp Tue Oct 22 11:42:10 2013 +0200 +++ b/src/share/vm/runtime/arguments.hpp Tue Oct 22 11:43:37 2013 +0200 @@ -264,6 +264,9 @@ static SystemProperty *_java_home; static SystemProperty *_java_class_path; static SystemProperty *_sun_boot_class_path; +#ifdef GRAAL + static SystemProperty *_graal_gpu_isalist; +#endif // Meta-index for knowing what packages are in the boot class path static char* _meta_index_path; diff -r 3ee8ae69d676 -r ce8dd5fa8d54 src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Tue Oct 22 11:42:10 2013 +0200 +++ b/src/share/vm/runtime/globals.hpp Tue Oct 22 11:43:37 2013 +0200 @@ -3774,9 +3774,6 @@ product(bool, TraceGPUInteraction, false, \ "Trace external GPU Interaction") \ \ - product(bool, UseGPU, false, \ - "Run code on GPU") \ - \ diagnostic(ccstr, SharedArchiveFile, NULL, \ "Override the default location of the CDS archive file") \ \