Mercurial > hg > graal-compiler
changeset 12566:c17bfad2fa98
Merge.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Thu, 24 Oct 2013 15:56:08 +0200 |
parents | e47f373499ec (current diff) b247ddd2fa0f (diff) |
children | 0d3e4d940925 |
files | |
diffstat | 95 files changed, 1379 insertions(+), 921 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Thu Oct 24 15:56:08 2013 +0200 @@ -42,6 +42,16 @@ InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult); /** + * Sets the given compilation result as the default implementation of the given method. + * + * @param method a method to which the executable code is begin added + * @param compResult the compilation result to be added + * @return a reference to the compiled and ready-to-run code or null if the code installation + * failed + */ + InstalledCode setDefaultMethod(ResolvedJavaMethod method, CompilationResult compResult); + + /** * Returns a disassembly of some compiled code. * * @param compResult some compiled code
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Thu Oct 24 15:56:08 2013 +0200 @@ -326,6 +326,8 @@ private int customStackAreaOffset = -1; private int registerRestoreEpilogueOffset = -1; + private final String name; + /** * The buffer containing the emitted machine code. */ @@ -347,6 +349,14 @@ */ private long[] leafGraphIds; + public CompilationResult() { + this(null); + } + + public CompilationResult(String name) { + this.name = name; + } + public void setAssumptions(Assumptions assumptions) { this.assumptions = assumptions; } @@ -620,4 +630,8 @@ } return unmodifiableList(marks); } + + public String getName() { + return name; + } }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ExternalCompilationResult.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ExternalCompilationResult.java Thu Oct 24 15:56:08 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; } }
--- a/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java Thu Oct 24 15:56:08 2013 +0200 @@ -360,18 +360,18 @@ assert var instanceof Variable; assert val instanceof Constant; Constant constant = (Constant) val; - return ("[" + emitRegister((Variable) var, false) + " + " + constant.asBoxedValue() + "]"); + return ("[" + ((space == PTXStateSpace.Parameter) ? emitParameter((Variable) var) : emitRegister((Variable) var, false)) + " + " + constant.asBoxedValue() + "]"); } @Override public String emitRegister(Variable var, boolean comma) { - /* - * if (space == Parameter) { return ("param" + var.index); } else { return ("%r" + - * var.index); } - */ return ("%r" + var.index); } + public String emitParameter(Variable v) { + return ("param" + v.index); + } + public String emit(boolean isLoad) { if (isLoad) { return (space.getStateName() + "." + typeForKind(valueKind) + " " + emitRegister(dest, false) + ", " + emitAddress(source1, source2) + ";"); @@ -671,7 +671,7 @@ } public String emitParameter(Variable v) { - return (" %r" + v.index); + return (" param" + v.index); } public void emit(PTXAssembler asm) { @@ -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) + ";"); }
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayPTXTest.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayPTXTest.java Thu Oct 24 15:56:08 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()) {
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java Thu Oct 24 15:56:08 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"); }
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java Thu Oct 24 15:56:08 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()) {
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Thu Oct 24 15:56:08 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);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Thu Oct 24 15:56:08 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);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Thu Oct 24 15:56:08 2013 +0200 @@ -138,32 +138,44 @@ Debug.scope("GraalCompiler", new Object[]{graph, providers.getCodeCache()}, new Runnable() { public void run() { - final Assumptions assumptions = new Assumptions(OptAssumptions.getValue()); - final LIR lir = Debug.scope("FrontEnd", new Callable<LIR>() { + compileGraphNoScope(graph, cc, installedCodeOwner, providers, backend, target, cache, plan, optimisticOpts, speculationLog, suites, compilationResult); + } + }); - public LIR call() { - try (TimerCloseable a = FrontEnd.start()) { - return emitHIR(providers, target, graph, assumptions, cache, plan, optimisticOpts, speculationLog, suites); - } - } - }); - try (TimerCloseable a = BackEnd.start()) { - final LIRGenerator lirGen = Debug.scope("BackEnd", lir, new Callable<LIRGenerator>() { + return compilationResult; + } - public LIRGenerator call() { - return emitLIR(backend, target, lir, graph, cc); - } - }); - Debug.scope("CodeGen", lirGen, new Runnable() { + /** + * Same as {@link #compileGraph} but without entering a + * {@linkplain Debug#scope(String, Object[], Runnable) debug scope}. + */ + public static <T extends CompilationResult> T compileGraphNoScope(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 T compilationResult) { + final Assumptions assumptions = new Assumptions(OptAssumptions.getValue()); + final LIR lir = Debug.scope("FrontEnd", new Callable<LIR>() { - public void run() { - emitCode(backend, getLeafGraphIdArray(graph), assumptions, lirGen, compilationResult, installedCodeOwner); - } - - }); + public LIR call() { + try (TimerCloseable a = FrontEnd.start()) { + return emitHIR(providers, target, graph, assumptions, cache, plan, optimisticOpts, speculationLog, suites); } } }); + try (TimerCloseable a = BackEnd.start()) { + final LIRGenerator lirGen = Debug.scope("BackEnd", lir, new Callable<LIRGenerator>() { + + public LIRGenerator call() { + return emitLIR(backend, target, lir, graph, cc); + } + }); + Debug.scope("CodeGen", lirGen, new Runnable() { + + public void run() { + emitCode(backend, getLeafGraphIdArray(graph), assumptions, lirGen, compilationResult, installedCodeOwner); + } + + }); + } return compilationResult; }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Thu Oct 24 15:56:08 2013 +0200 @@ -52,6 +52,8 @@ "Complete - aggregate by qualified name%n" + "Thread - aggregate by qualified name and thread") public static final OptionValue<String> DebugValueSummary = new OptionValue<>("Name"); + @Option(help = "Omit reporting 0-value metrics") + public static final OptionValue<Boolean> SuppressZeroDebugValues = new OptionValue<>(false); @Option(help = "Send Graal IR to dump handlers on error") public static final OptionValue<Boolean> DumpOnError = new OptionValue<>(false); @Option(help = "Enable expensive assertions") @@ -67,7 +69,11 @@ // @formatter:on public static boolean areDebugScopePatternsEnabled() { - return DumpOnError.getValue() || Dump.getValue() != null || Meter.getValue() != null || Time.getValue() != null || Log.getValue() != null; + return DumpOnError.getValue() || Dump.getValue() != null || Log.getValue() != null || areMetricsOrTimersEnabled(); + } + + public static boolean areMetricsOrTimersEnabled() { + return Meter.getValue() != null || Time.getValue() != null; } private final DebugFilter logFilter;
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MetricImpl.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MetricImpl.java Thu Oct 24 15:56:08 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() {
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Thu Oct 24 15:56:08 2013 +0200 @@ -1194,7 +1194,7 @@ } public Position next() { - Position pos = new Position(true, i, i >= directInputCount ? 0 : NOT_ITERABLE); + Position pos = new Position(true, i, i >= directInputCount ? NODE_LIST : NOT_ITERABLE); i++; return pos; } @@ -1224,7 +1224,7 @@ } public Position next() { - Position pos = new Position(false, i, i >= directSuccessorCount ? 0 : NOT_ITERABLE); + Position pos = new Position(false, i, i >= directSuccessorCount ? NODE_LIST : NOT_ITERABLE); i++; return pos; }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Thu Oct 24 15:56:08 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();
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Thu Oct 24 15:56:08 2013 +0200 @@ -210,7 +210,7 @@ } } - private static void decodePointer(AMD64MacroAssembler masm, Register resRegister, Register heapBaseRegister, long base, int shift, int alignment) { + public static void decodePointer(AMD64MacroAssembler masm, Register resRegister, Register heapBaseRegister, long base, int shift, int alignment) { // If the base is zero, the compressed address has to be shifted left // in order to be uncompressed. if (base == 0) {
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java Thu Oct 24 15:56:08 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;
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java Thu Oct 24 15:56:08 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); } }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java Thu Oct 24 15:56:08 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); } }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Thu Oct 24 15:56:08 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));
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java Thu Oct 24 15:56:08 2013 +0200 @@ -48,7 +48,7 @@ @Override protected InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) { HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method; - HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, true); + HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, compResult.getName(), true); HotSpotCompiledNmethod compiledNmethod = new HotSpotCompiledNmethod(hsMethod, StructuredGraph.INVOCATION_ENTRY_BCI, compResult); CodeInstallResult result = runtime().getCompilerToVM().installCode(compiledNmethod, installedCode, null); Assert.assertEquals("Error installing method " + method + ": " + result, result, CodeInstallResult.OK);
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Thu Oct 24 15:56:08 2013 +0200 @@ -175,7 +175,7 @@ } public static Object test5Snippet() throws Exception { - return UnsafeLoadNode.load(wr, useCompressedOops() ? 12 : 16, Kind.Object); + return UnsafeLoadNode.load(wr, useCompressedOops() ? 12 : 16, Kind.Object, LocationIdentity.ANY_LOCATION); } /** @@ -250,7 +250,7 @@ public static Object testUnsafeLoad(Object a, Object b, Object c) throws Exception { final int offset = (c == null ? 0 : ((Integer) c).intValue()); final long displacement = (b == null ? 0 : ((Long) b).longValue()); - return UnsafeLoadNode.load(a, offset + displacement, Kind.Object); + return UnsafeLoadNode.load(a, offset + displacement, Kind.Object, LocationIdentity.ANY_LOCATION); } private HotSpotInstalledCode getInstalledCode(String name) throws Exception {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Thu Oct 24 15:56:08 2013 +0200 @@ -105,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; @@ -135,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() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Thu Oct 24 15:56:08 2013 +0200 @@ -218,6 +218,8 @@ long readUnsafeKlassPointer(Object o); + void doNotInlineOrCompile(long metaspaceMethod); + /** * Invalidates the profiling information and restarts profiling upon the next invocation. *
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Thu Oct 24 15:56:08 2013 +0200 @@ -178,6 +178,9 @@ public native long readUnsafeKlassPointer(Object o); @Override + public native void doNotInlineOrCompile(long metaspaceMethod); + + @Override public Object executeCompiledMethod(Object arg1, Object arg2, Object arg3, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException { return executeCompiledMethodIntrinsic(arg1, arg2, arg3, hotspotInstalledCode); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Thu Oct 24 15:56:08 2013 +0200 @@ -401,7 +401,7 @@ CompilationTask.withinEnqueue.set(Boolean.FALSE); } - if (Debug.isEnabled() && areDebugScopePatternsEnabled()) { + if (Debug.isEnabled() && areMetricsOrTimersEnabled()) { List<DebugValueMap> topLevelMaps = DebugValueMap.getTopLevelMaps(); List<DebugValue> debugValues = KeyRegistry.getDebugValues(); if (debugValues.size() > 0) { @@ -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));
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Thu Oct 24 15:56:08 2013 +0200 @@ -36,6 +36,7 @@ import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult; import com.oracle.graal.java.*; +import com.oracle.graal.nodes.*; import com.oracle.graal.printer.*; /** @@ -157,7 +158,7 @@ } public HotSpotInstalledCode installMethod(HotSpotResolvedJavaMethod method, int entryBCI, CompilationResult compResult) { - HotSpotInstalledCode installedCode = new HotSpotNmethod(method, true); + HotSpotInstalledCode installedCode = new HotSpotNmethod(method, compResult.getName(), true); runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(method, entryBCI, compResult), installedCode, method.getSpeculationLog()); return installedCode; } @@ -165,7 +166,7 @@ @Override public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) { HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method; - HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, false); + HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, compResult.getName(), false); CodeInstallResult result = runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(hotspotMethod, -1, compResult), code, null); if (result != CodeInstallResult.OK) { return null; @@ -173,10 +174,15 @@ return code; } + public InstalledCode setDefaultMethod(ResolvedJavaMethod method, CompilationResult compResult) { + HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method; + return installMethod(hotspotMethod, StructuredGraph.INVOCATION_ENTRY_BCI, compResult); + } + public InstalledCode addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult) { HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) method; - HotSpotInstalledCode icode = new HotSpotNmethod(javaMethod, false, true); + HotSpotInstalledCode icode = new HotSpotNmethod(javaMethod, compResult.getName(), false, true); HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(javaMethod, -1, compResult); CompilerToVM vm = runtime.getCompilerToVM(); CodeInstallResult result = vm.installCode(compiled, icode, null);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java Thu Oct 24 15:56:08 2013 +0200 @@ -46,17 +46,17 @@ private final HotSpotResolvedJavaMethod method; private final boolean isDefault; private final boolean isExternal; + private final String name; - public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault) { - this.method = method; - this.isDefault = isDefault; - this.isExternal = false; + public HotSpotNmethod(HotSpotResolvedJavaMethod method, String name, boolean isDefault) { + this(method, name, isDefault, false); } - public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault, boolean isExternal) { + public HotSpotNmethod(HotSpotResolvedJavaMethod method, String name, boolean isDefault, boolean isExternal) { this.method = method; this.isDefault = isDefault; this.isExternal = isExternal; + this.name = name; } public boolean isDefault() { @@ -84,7 +84,7 @@ @Override public String toString() { - return String.format("InstalledNmethod[method=%s, codeBlob=0x%x, isDefault=%b]", method, getCodeBlob(), isDefault); + return String.format("InstalledNmethod[method=%s, codeBlob=0x%x, isDefault=%b, name=]", method, getCodeBlob(), isDefault, name); } @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Thu Oct 24 15:56:08 2013 +0200 @@ -190,6 +190,14 @@ } /** + * Manually adds a DontInline annotation to this method. + */ + public void setDontInline() { + dontInline = true; + runtime().getCompilerToVM().doNotInlineOrCompile(metaspaceMethod); + } + + /** * Returns true if this method is one of the special methods that is ignored by security stack * walks. *
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java Thu Oct 24 15:56:08 2013 +0200 @@ -66,7 +66,7 @@ } private static void crypt(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset, boolean encrypt) { - Object kObject = UnsafeLoadNode.load(rcvr, kOffset, Kind.Object); + Object kObject = UnsafeLoadNode.load(rcvr, kOffset, Kind.Object, LocationIdentity.ANY_LOCATION); Word kAddr = (Word) Word.fromObject(kObject).add(arrayBaseOffset(Kind.Byte)); Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset); Word outAddr = Word.unsigned(GetObjectAddressNode.get(out) + arrayBaseOffset(Kind.Byte) + outOffset);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Thu Oct 24 15:56:08 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);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java Thu Oct 24 15:56:08 2013 +0200 @@ -78,9 +78,6 @@ return arraycopyMethods.get(kind); } - private static final Kind VECTOR_KIND = Kind.Long; - private static final long VECTOR_SIZE = arrayIndexScale(Kind.Long); - private static void checkedCopy(Object src, int srcPos, Object dest, int destPos, int length, Kind baseKind) { Object nonNullSrc = guardingNonNull(src); Object nonNullDest = guardingNonNull(dest); @@ -88,32 +85,32 @@ UnsafeArrayCopyNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, baseKind); } - public static int checkArrayType(Word hub) { + private static int checkArrayType(Word hub) { int layoutHelper = readLayoutHelper(hub); - if (layoutHelper >= 0) { + if (probability(SLOW_PATH_PROBABILITY, layoutHelper >= 0)) { DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } return layoutHelper; } - public static void checkLimits(Object src, int srcPos, Object dest, int destPos, int length) { - if (srcPos < 0) { + private static void checkLimits(Object src, int srcPos, Object dest, int destPos, int length) { + if (probability(SLOW_PATH_PROBABILITY, srcPos < 0)) { checkAIOOBECounter.inc(); DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } - if (destPos < 0) { + if (probability(SLOW_PATH_PROBABILITY, destPos < 0)) { checkAIOOBECounter.inc(); DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } - if (length < 0) { + if (probability(SLOW_PATH_PROBABILITY, length < 0)) { checkAIOOBECounter.inc(); DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } - if (srcPos + length > ArrayLengthNode.arrayLength(src)) { + if (probability(SLOW_PATH_PROBABILITY, srcPos + length > ArrayLengthNode.arrayLength(src))) { checkAIOOBECounter.inc(); DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } - if (destPos + length > ArrayLengthNode.arrayLength(dest)) { + if (probability(SLOW_PATH_PROBABILITY, destPos + length > ArrayLengthNode.arrayLength(dest))) { checkAIOOBECounter.inc(); DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint); } @@ -170,12 +167,6 @@ @Snippet public static void arraycopy(Object[] src, int srcPos, Object[] dest, int destPos, int length) { - arrayObjectCopy(src, srcPos, dest, destPos, length); - } - - // Does NOT perform store checks - @Snippet - public static void arrayObjectCopy(Object src, int srcPos, Object dest, int destPos, int length) { objectCounter.inc(); checkedCopy(src, srcPos, dest, destPos, length, Kind.Object); } @@ -193,7 +184,7 @@ checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length); if (probability(FAST_PATH_PROBABILITY, isObjectArray)) { genericObjectExactCallCounter.inc(); - arrayObjectCopy(nonNullSrc, srcPos, nonNullDest, destPos, length); + UnsafeArrayCopyNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, Kind.Object); } else { genericPrimitiveCallCounter.inc(); UnsafeArrayCopyNode.arraycopyPrimitive(nonNullSrc, srcPos, nonNullDest, destPos, length, layoutHelper);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java Thu Oct 24 15:56:08 2013 +0200 @@ -62,7 +62,7 @@ @MethodSubstitution(isStatic = false) static void encrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { - Object embeddedCipher = UnsafeLoadNode.load(rcvr, embeddedCipherOffset, Kind.Object); + Object embeddedCipher = UnsafeLoadNode.load(rcvr, embeddedCipherOffset, Kind.Object, LocationIdentity.ANY_LOCATION); if (getAESCryptClass().isInstance(embeddedCipher)) { crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, true); } else { @@ -72,7 +72,7 @@ @MethodSubstitution(isStatic = false) static void decrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { - Object embeddedCipher = UnsafeLoadNode.load(rcvr, embeddedCipherOffset, Kind.Object); + Object embeddedCipher = UnsafeLoadNode.load(rcvr, embeddedCipherOffset, Kind.Object, LocationIdentity.ANY_LOCATION); if (in != out && getAESCryptClass().isInstance(embeddedCipher)) { crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, false); } else { @@ -81,8 +81,8 @@ } private static void crypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset, Object embeddedCipher, boolean encrypt) { - Object kObject = UnsafeLoadNode.load(embeddedCipher, AESCryptSubstitutions.kOffset, Kind.Object); - Object rObject = UnsafeLoadNode.load(rcvr, rOffset, Kind.Object); + Object kObject = UnsafeLoadNode.load(embeddedCipher, AESCryptSubstitutions.kOffset, Kind.Object, LocationIdentity.ANY_LOCATION); + Object rObject = UnsafeLoadNode.load(rcvr, rOffset, Kind.Object, LocationIdentity.ANY_LOCATION); Word kAddr = (Word) Word.fromObject(kObject).add(arrayBaseOffset(Kind.Byte)); Word rAddr = (Word) Word.fromObject(rObject).add(arrayBaseOffset(Kind.Byte)); Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Thu Oct 24 15:56:08 2013 +0200 @@ -485,7 +485,7 @@ public static Word loadWordFromObject(Object object, int offset) { assert offset != hubOffset() : "Use loadHubIntrinsic instead"; - return loadWordFromObjectIntrinsic(object, offset, getWordKind()); + return loadWordFromObjectIntrinsic(object, offset, getWordKind(), LocationIdentity.ANY_LOCATION); } @NodeIntrinsic(value = ReadRegisterNode.class, setStampFromReturnType = true) @@ -493,7 +493,7 @@ @SuppressWarnings("unused") @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true) - private static Word loadWordFromObjectIntrinsic(Object object, long offset, @ConstantNodeParameter Kind wordKind) { + private static Word loadWordFromObjectIntrinsic(Object object, long offset, @ConstantNodeParameter Kind wordKind, @ConstantNodeParameter LocationIdentity locationIdentity) { return Word.unsigned(unsafeReadWord(object, offset)); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopyNode.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopyNode.java Thu Oct 24 15:56:08 2013 +0200 @@ -112,6 +112,9 @@ @Override public LocationIdentity getLocationIdentity() { + if (elementKind != null) { + return NamedLocationIdentity.getArrayLocation(elementKind); + } return ANY_LOCATION; }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java Thu Oct 24 15:56:08 2013 +0200 @@ -34,20 +34,24 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.replacements.*; +import com.oracle.graal.replacements.Snippet.Fold; import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates; import com.oracle.graal.replacements.SnippetTemplate.Arguments; import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo; -import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.word.*; +/** + * As opposed to {@link ArrayCopySnippets}, these Snippets do <b>not</b> perform store checks. + */ public class UnsafeArrayCopySnippets implements Snippets { private static final boolean supportsUnalignedMemoryAccess = runtime().getTarget().arch.supportsUnalignedMemoryAccess(); + // TODO: make vector kind architecture dependent private static final Kind VECTOR_KIND = Kind.Long; - private static final long VECTOR_SIZE = arrayIndexScale(Kind.Long); + private static final long VECTOR_SIZE = arrayIndexScale(VECTOR_KIND); - private static void vectorizedCopy(Object src, int srcPos, Object dest, int destPos, int length, Kind baseKind) { + private static void vectorizedCopy(Object src, int srcPos, Object dest, int destPos, int length, Kind baseKind, LocationIdentity locationIdentity) { int arrayBaseOffset = arrayBaseOffset(baseKind); int elementSize = arrayIndexScale(baseKind); long byteLength = (long) length * elementSize; @@ -86,143 +90,101 @@ for (long i = 0; i < postLoopBytes; i += elementSize) { srcOffset -= elementSize; destOffset -= elementSize; - Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind); - UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind); + Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind, locationIdentity); + UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind, locationIdentity); } // Main-loop for (long i = 0; i < mainLoopBytes; i += VECTOR_SIZE) { srcOffset -= VECTOR_SIZE; destOffset -= VECTOR_SIZE; - Long a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a.longValue(), VECTOR_KIND); + Long a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, VECTOR_KIND, locationIdentity); + UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a.longValue(), VECTOR_KIND, locationIdentity); } // Pre-loop for (long i = 0; i < preLoopBytes; i += elementSize) { srcOffset -= elementSize; destOffset -= elementSize; - Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind); - UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind); + Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind, locationIdentity); + UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind, locationIdentity); } } else { // Pre-loop for (long i = 0; i < preLoopBytes; i += elementSize) { - Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind); - UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind); + Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind, locationIdentity); + UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind, locationIdentity); srcOffset += elementSize; destOffset += elementSize; } // Main-loop for (long i = 0; i < mainLoopBytes; i += VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a.longValue(), VECTOR_KIND); + Long a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, VECTOR_KIND, locationIdentity); + UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a.longValue(), VECTOR_KIND, locationIdentity); srcOffset += VECTOR_SIZE; destOffset += VECTOR_SIZE; } // Post-loop for (long i = 0; i < postLoopBytes; i += elementSize) { - Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind); - UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind); + Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind, locationIdentity); + UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind, locationIdentity); srcOffset += elementSize; destOffset += elementSize; } } } + @Fold + private static LocationIdentity getArrayLocation(Kind kind) { + return NamedLocationIdentity.getArrayLocation(kind); + } + @Snippet public static void arraycopyByte(byte[] src, int srcPos, byte[] dest, int destPos, int length) { - vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Byte); + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Byte, getArrayLocation(Kind.Byte)); } @Snippet public static void arraycopyBoolean(boolean[] src, int srcPos, boolean[] dest, int destPos, int length) { - vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Byte); + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Byte, getArrayLocation(Kind.Boolean)); } @Snippet public static void arraycopyChar(char[] src, int srcPos, char[] dest, int destPos, int length) { - vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Char); + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Char, getArrayLocation(Kind.Char)); } @Snippet public static void arraycopyShort(short[] src, int srcPos, short[] dest, int destPos, int length) { - vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Short); + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Short, getArrayLocation(Kind.Short)); } @Snippet public static void arraycopyInt(int[] src, int srcPos, int[] dest, int destPos, int length) { - vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Int); + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Int, getArrayLocation(Kind.Int)); } @Snippet public static void arraycopyFloat(float[] src, int srcPos, float[] dest, int destPos, int length) { - vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Float); + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Float, getArrayLocation(Kind.Float)); } @Snippet public static void arraycopyLong(long[] src, int srcPos, long[] dest, int destPos, int length) { - Kind baseKind = Kind.Long; - int arrayBaseOffset = arrayBaseOffset(baseKind); - long byteLength = (long) length * arrayIndexScale(baseKind); - long srcOffset = (long) srcPos * arrayIndexScale(baseKind); - long destOffset = (long) destPos * arrayIndexScale(baseKind); - if (src == dest && srcPos < destPos) { // bad aliased case - for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, arrayBaseOffset + i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, arrayBaseOffset + i + destOffset, a.longValue(), VECTOR_KIND); - } - } else { - for (long i = 0; i < byteLength; i += VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, arrayBaseOffset + i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, arrayBaseOffset + i + destOffset, a.longValue(), VECTOR_KIND); - } - } + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Long, getArrayLocation(Kind.Long)); } @Snippet public static void arraycopyDouble(double[] src, int srcPos, double[] dest, int destPos, int length) { - Kind baseKind = Kind.Double; - int arrayBaseOffset = arrayBaseOffset(baseKind); - long byteLength = (long) length * arrayIndexScale(baseKind); - long srcOffset = (long) srcPos * arrayIndexScale(baseKind); - long destOffset = (long) destPos * arrayIndexScale(baseKind); - if (src == dest && srcPos < destPos) { // bad aliased case - for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) { - Long a = UnsafeLoadNode.load(src, arrayBaseOffset + i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, arrayBaseOffset + i + destOffset, a.longValue(), VECTOR_KIND); - } - } else { - for (long i = 0; i < byteLength; i += VECTOR_SIZE) { - /* - * TODO atomicity problem on 32-bit architectures: The JVM spec requires double - * values to be copied atomically, but not long values. For example, on Intel 32-bit - * this code is not atomic as long as the vector kind remains Kind.Long. - */ - Long a = UnsafeLoadNode.load(src, arrayBaseOffset + i + srcOffset, VECTOR_KIND); - UnsafeStoreNode.store(dest, arrayBaseOffset + i + destOffset, a.longValue(), VECTOR_KIND); - } - } + /* + * TODO atomicity problem on 32-bit architectures: The JVM spec requires double values to be + * copied atomically, but not long values. For example, on Intel 32-bit this code is not + * atomic as long as the vector kind remains Kind.Long. + */ + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Double, getArrayLocation(Kind.Double)); } - /** - * Does NOT perform store checks. - */ @Snippet public static void arraycopyObject(Object[] src, int srcPos, Object[] dest, int destPos, int length) { - final int scale = arrayIndexScale(Kind.Object); - int arrayBaseOffset = arrayBaseOffset(Kind.Object); - if (src == dest && srcPos < destPos) { // bad aliased case - long start = (long) (length - 1) * scale; - for (long i = start; i >= 0; i -= scale) { - Object a = UnsafeLoadNode.load(src, arrayBaseOffset + i + (long) srcPos * scale, Kind.Object); - DirectObjectStoreNode.storeObject(dest, arrayBaseOffset, i + (long) destPos * scale, a); - } - } else { - long end = (long) length * scale; - for (long i = 0; i < end; i += scale) { - Object a = UnsafeLoadNode.load(src, arrayBaseOffset + i + (long) srcPos * scale, Kind.Object); - DirectObjectStoreNode.storeObject(dest, arrayBaseOffset, i + (long) destPos * scale, a); - } - } + vectorizedCopy(src, srcPos, dest, destPos, length, Kind.Object, getArrayLocation(Kind.Object)); } @Snippet
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Oct 24 15:56:08 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; }
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java Thu Oct 24 15:56:08 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;
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java Thu Oct 24 15:56:08 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;
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXCompare.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXCompare.java Thu Oct 24 15:56:08 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)) {
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java Thu Oct 24 15:56:08 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());
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/ParallelOver.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/ParallelOver.java Thu Oct 24 15:56:08 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; } -
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/ThreadDimension.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/ThreadDimension.java Thu Oct 24 15:56:08 2013 +0200 @@ -23,8 +23,5 @@ package com.oracle.graal.lir.ptx; public enum ThreadDimension { -X, -Y, -Z + X, Y, Z } -
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/Warp.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/Warp.java Thu Oct 24 15:56:08 2013 +0200 @@ -34,4 +34,3 @@ ThreadDimension dimension() default X; } -
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java Thu Oct 24 15:56:08 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); + // } } }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Thu Oct 24 15:56:08 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
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Thu Oct 24 15:56:08 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;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java Thu Oct 24 15:56:08 2013 +0200 @@ -107,8 +107,7 @@ private static boolean verifyFlags(Field field, Class<?> type, EnumSet<OperandFlag> 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;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java Thu Oct 24 15:56:08 2013 +0200 @@ -63,7 +63,8 @@ private List<ExceptionInfo> 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;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginStateSplitNode.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginStateSplitNode.java Thu Oct 24 15:56:08 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 {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Thu Oct 24 15:56:08 2013 +0200 @@ -99,9 +99,8 @@ DeoptimizeNode deopt = graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, reason)); deopt.setDeoptimizationState(getDeoptimizationState()); setNext(deopt); - } else { - this.replaceAtUsages(null); } + this.replaceAtUsages(null); graph().removeFixed(this); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Thu Oct 24 15:56:08 2013 +0200 @@ -45,7 +45,7 @@ @Input private LogicNode condition; private final DeoptimizationReason reason; - private final DeoptimizationAction action; + private DeoptimizationAction action; private boolean negated; public GuardNode(LogicNode condition, GuardingNode anchor, DeoptimizationReason reason, DeoptimizationAction action, boolean negated) { @@ -107,4 +107,8 @@ public void negate() { negated = !negated; } + + public void setAction(DeoptimizationAction invalidaterecompile) { + this.action = invalidaterecompile; + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Thu Oct 24 15:56:08 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(); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Thu Oct 24 15:56:08 2013 +0200 @@ -37,8 +37,8 @@ public class UnsafeLoadNode extends UnsafeAccessNode implements Lowerable, Virtualizable { @Input private LogicNode guardingCondition; - public UnsafeLoadNode(ValueNode object, ValueNode offset, Kind accessKind) { - this(object, offset, accessKind, LocationIdentity.ANY_LOCATION, null); + public UnsafeLoadNode(ValueNode object, ValueNode offset, Kind accessKind, LocationIdentity locationIdentity) { + this(object, offset, accessKind, locationIdentity, null); } public UnsafeLoadNode(ValueNode object, ValueNode offset, Kind accessKind, LocationIdentity locationIdentity, LogicNode condition) { @@ -78,9 +78,9 @@ return this.graph().add(new LoadFieldNode(object(), field)); } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "unused"}) @NodeIntrinsic - public static <T> T load(Object object, long offset, @ConstantNodeParameter Kind kind) { + public static <T> T load(Object object, long offset, @ConstantNodeParameter Kind kind, @ConstantNodeParameter LocationIdentity locationIdentity) { if (kind == Kind.Boolean) { return (T) (Boolean) unsafe.getBoolean(object, offset); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Thu Oct 24 15:56:08 2013 +0200 @@ -39,10 +39,6 @@ @Input private ValueNode value; @Input(notDataflow = true) private FrameState stateAfter; - public UnsafeStoreNode(ValueNode object, ValueNode offset, ValueNode value, Kind accessKind) { - this(object, offset, value, accessKind, LocationIdentity.ANY_LOCATION); - } - public UnsafeStoreNode(ValueNode object, ValueNode offset, ValueNode value, Kind accessKind, LocationIdentity locationIdentity) { super(StampFactory.forVoid(), object, offset, accessKind, locationIdentity); assert accessKind != Kind.Void && accessKind != Kind.Illegal; @@ -106,55 +102,55 @@ @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, long offset, Object value, @ConstantNodeParameter Kind kind) { + public static void store(Object object, long offset, Object value, @ConstantNodeParameter Kind kind, @ConstantNodeParameter LocationIdentity locationIdentity) { unsafe.putObject(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, long offset, boolean value, @ConstantNodeParameter Kind kind) { + public static void store(Object object, long offset, boolean value, @ConstantNodeParameter Kind kind, @ConstantNodeParameter LocationIdentity locationIdentity) { unsafe.putBoolean(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, long offset, byte value, @ConstantNodeParameter Kind kind) { + public static void store(Object object, long offset, byte value, @ConstantNodeParameter Kind kind, @ConstantNodeParameter LocationIdentity locationIdentity) { unsafe.putByte(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, long offset, char value, @ConstantNodeParameter Kind kind) { + public static void store(Object object, long offset, char value, @ConstantNodeParameter Kind kind, @ConstantNodeParameter LocationIdentity locationIdentity) { unsafe.putChar(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, long offset, double value, @ConstantNodeParameter Kind kind) { + public static void store(Object object, long offset, double value, @ConstantNodeParameter Kind kind, @ConstantNodeParameter LocationIdentity locationIdentity) { unsafe.putDouble(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, long offset, float value, @ConstantNodeParameter Kind kind) { + public static void store(Object object, long offset, float value, @ConstantNodeParameter Kind kind, @ConstantNodeParameter LocationIdentity locationIdentity) { unsafe.putFloat(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, long offset, int value, @ConstantNodeParameter Kind kind) { + public static void store(Object object, long offset, int value, @ConstantNodeParameter Kind kind, @ConstantNodeParameter LocationIdentity locationIdentity) { unsafe.putInt(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, long offset, long value, @ConstantNodeParameter Kind kind) { + public static void store(Object object, long offset, long value, @ConstantNodeParameter Kind kind, @ConstantNodeParameter LocationIdentity locationIdentity) { unsafe.putLong(object, offset, value); } @SuppressWarnings("unused") @NodeIntrinsic - public static void store(Object object, long offset, short value, @ConstantNodeParameter Kind kind) { + public static void store(Object object, long offset, short value, @ConstantNodeParameter Kind kind, @ConstantNodeParameter LocationIdentity locationIdentity) { unsafe.putShort(object, offset, value); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java Thu Oct 24 15:56:08 2013 +0200 @@ -185,7 +185,9 @@ return StampFactory.illegal(Kind.Illegal); } IntegerStamp other = (IntegerStamp) otherStamp; - return createStamp(other, Math.min(upperBound, other.upperBound), Math.max(lowerBound, other.lowerBound), downMask | other.downMask, upMask & other.upMask); + long newDownMask = downMask | other.downMask; + long newLowerBound = Math.max(lowerBound, other.lowerBound) | newDownMask; + return createStamp(other, Math.min(upperBound, other.upperBound), newLowerBound, newDownMask, upMask & other.upMask); } @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java Thu Oct 24 15:56:08 2013 +0200 @@ -238,14 +238,15 @@ if (shiftCount != 0) { long lowerBound; long upperBound; + long downMask = value.downMask() >>> shiftCount; if (value.lowerBound() < 0) { - lowerBound = 0; + lowerBound = downMask; upperBound = IntegerStamp.defaultMask(kind) >>> shiftCount; } else { lowerBound = value.lowerBound() >>> shiftCount; upperBound = value.upperBound() >>> shiftCount; } - return new IntegerStamp(kind, lowerBound, upperBound, value.downMask() >>> shiftCount, value.upMask() >>> shiftCount); + return new IntegerStamp(kind, lowerBound, upperBound, downMask, value.upMask() >>> shiftCount); } } long mask = IntegerStamp.upMaskFor(kind, value.lowerBound(), value.upperBound());
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchors.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchors.java Thu Oct 24 15:56:08 2013 +0200 @@ -89,10 +89,9 @@ int successorCount = controlSplit.successors().count(); List<GuardNode> otherGuards = new ArrayList<>(successorCount - 1); for (GuardNode guard : successor.guards().snapshot()) { - if (guard.condition().usages().count() < successorCount) { + if (guard.isDeleted() || guard.condition().usages().count() < successorCount) { continue; } - for (GuardNode conditonGuard : guard.condition().usages().filter(GuardNode.class)) { if (conditonGuard != guard) { GuardingNode conditonGuardAnchor = conditonGuard.getGuard();
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Thu Oct 24 15:56:08 2013 +0200 @@ -407,6 +407,7 @@ writeInt(node.getId()); writePoolObject(nodeClass); writeByte(node.predecessor() == null ? 0 : 1); + // properties writeShort((char) props.size()); for (Entry<Object, Object> entry : props.entrySet()) { String key = entry.getKey().toString(); @@ -414,54 +415,42 @@ writePropertyObject(entry.getValue()); } // inputs - Collection<Position> 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); - } + writeEdges(node, nodeClass.getFirstLevelInputPositions()); + // successors + writeEdges(node, nodeClass.getFirstLevelSuccessorPositions()); + + props.clear(); + } + } + + private void writeEdges(Node node, Collection<Position> positions) throws IOException { + NodeClass nodeClass = node.getNodeClass(); + for (Position pos : positions) { + if (pos.subIndex == NodeClass.NOT_ITERABLE) { + Node edge = nodeClass.get(node, pos); + writeNodeRef(edge); + } else { + NodeList<?> list = nodeClass.getNodeList(node, pos); + if (list == null) { + writeShort((char) 0); } 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); - } + for (Node edge : list) { + writeNodeRef(edge); } } } - // successors - Collection<Position> 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(); + } + } + + @SuppressWarnings("deprecation") + private void writeNodeRef(Node edge) throws IOException { + if (edge != null) { + writeInt(edge.getId()); + } else { + writeInt(-1); } }
--- a/graal/com.oracle.graal.ptx/src/com/oracle/graal/ptx/PTX.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.ptx/src/com/oracle/graal/ptx/PTX.java Thu Oct 24 15:56:08 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 @@ } } - }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java Thu Oct 24 15:56:08 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");
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java Thu Oct 24 15:56:08 2013 +0200 @@ -64,22 +64,22 @@ @MethodSubstitution private static Node getNode(Node node, long offset) { - return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object), Node.class, false, false); + return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object, LocationIdentity.ANY_LOCATION), Node.class, false, false); } @MethodSubstitution private static NodeList getNodeList(Node node, long offset) { - return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object), NodeList.class, false, false); + return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object, LocationIdentity.ANY_LOCATION), NodeList.class, false, false); } @MethodSubstitution private static void putNode(Node node, long offset, Node value) { - UnsafeStoreNode.store(node, offset, value, Kind.Object); + UnsafeStoreNode.store(node, offset, value, Kind.Object, LocationIdentity.ANY_LOCATION); } @MethodSubstitution private static void putNodeList(Node node, long offset, NodeList value) { - UnsafeStoreNode.store(node, offset, value, Kind.Object); + UnsafeStoreNode.store(node, offset, value, Kind.Object, LocationIdentity.ANY_LOCATION); } }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Thu Oct 24 15:56:08 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<SnippetTemplate>() { @@ -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) { @@ -801,7 +800,7 @@ // check if some node in snippet graph also kills the same location LocationIdentity locationIdentity = ((MemoryCheckpoint.Single) replacee).getLocationIdentity(); if (locationIdentity == ANY_LOCATION) { - assert !(memoryMap.getLastLocationAccess(ANY_LOCATION) instanceof StartNode); + assert !(memoryMap.getLastLocationAccess(ANY_LOCATION) instanceof StartNode) : replacee + " kills ANY_LOCATION, but snippet does not"; } assert kills.contains(locationIdentity) : replacee + " kills " + locationIdentity + ", but snippet doesn't contain a kill to this location"; return true; @@ -865,8 +864,8 @@ */ public Map<Node, Node> 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}";
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsafeSubstitutions.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsafeSubstitutions.java Thu Oct 24 15:56:08 2013 +0200 @@ -53,7 +53,7 @@ @MethodSubstitution(isStatic = false) public static Object getObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { - return UnsafeLoadNode.load(o, offset, Kind.Object); + return UnsafeLoadNode.load(o, offset, Kind.Object, LocationIdentity.ANY_LOCATION); } @MethodSubstitution(isStatic = false) @@ -66,7 +66,7 @@ @MethodSubstitution(isStatic = false) public static void putObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, Object x) { - UnsafeStoreNode.store(o, offset, x, Kind.Object); + UnsafeStoreNode.store(o, offset, x, Kind.Object, LocationIdentity.ANY_LOCATION); } @MethodSubstitution(isStatic = false) @@ -85,7 +85,7 @@ @MethodSubstitution(isStatic = false) public static int getInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { - Integer value = UnsafeLoadNode.load(o, offset, Kind.Int); + Integer value = UnsafeLoadNode.load(o, offset, Kind.Int, LocationIdentity.ANY_LOCATION); return value; } @@ -99,7 +99,7 @@ @MethodSubstitution(isStatic = false) public static void putInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, int x) { - UnsafeStoreNode.store(o, offset, x, Kind.Int); + UnsafeStoreNode.store(o, offset, x, Kind.Int, LocationIdentity.ANY_LOCATION); } @MethodSubstitution(isStatic = false) @@ -119,7 +119,7 @@ @MethodSubstitution(isStatic = false) public static boolean getBoolean(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Boolean result = UnsafeLoadNode.load(o, offset, Kind.Boolean); + Boolean result = UnsafeLoadNode.load(o, offset, Kind.Boolean, LocationIdentity.ANY_LOCATION); return result; } @@ -133,7 +133,7 @@ @MethodSubstitution(isStatic = false) public static void putBoolean(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, boolean x) { - UnsafeStoreNode.store(o, offset, x, Kind.Boolean); + UnsafeStoreNode.store(o, offset, x, Kind.Boolean, LocationIdentity.ANY_LOCATION); } @MethodSubstitution(isStatic = false) @@ -146,7 +146,7 @@ @MethodSubstitution(isStatic = false) public static byte getByte(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Byte result = UnsafeLoadNode.load(o, offset, Kind.Byte); + Byte result = UnsafeLoadNode.load(o, offset, Kind.Byte, LocationIdentity.ANY_LOCATION); return result; } @@ -160,7 +160,7 @@ @MethodSubstitution(isStatic = false) public static void putByte(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, byte x) { - UnsafeStoreNode.store(o, offset, x, Kind.Byte); + UnsafeStoreNode.store(o, offset, x, Kind.Byte, LocationIdentity.ANY_LOCATION); } @MethodSubstitution(isStatic = false) @@ -173,7 +173,7 @@ @MethodSubstitution(isStatic = false) public static short getShort(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Short result = UnsafeLoadNode.load(o, offset, Kind.Short); + Short result = UnsafeLoadNode.load(o, offset, Kind.Short, LocationIdentity.ANY_LOCATION); return result; } @@ -187,7 +187,7 @@ @MethodSubstitution(isStatic = false) public static void putShort(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, short x) { - UnsafeStoreNode.store(o, offset, x, Kind.Short); + UnsafeStoreNode.store(o, offset, x, Kind.Short, LocationIdentity.ANY_LOCATION); } @MethodSubstitution(isStatic = false) @@ -200,7 +200,7 @@ @MethodSubstitution(isStatic = false) public static char getChar(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Character result = UnsafeLoadNode.load(o, offset, Kind.Char); + Character result = UnsafeLoadNode.load(o, offset, Kind.Char, LocationIdentity.ANY_LOCATION); return result; } @@ -214,7 +214,7 @@ @MethodSubstitution(isStatic = false) public static void putChar(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, char x) { - UnsafeStoreNode.store(o, offset, x, Kind.Char); + UnsafeStoreNode.store(o, offset, x, Kind.Char, LocationIdentity.ANY_LOCATION); } @MethodSubstitution(isStatic = false) @@ -227,7 +227,7 @@ @MethodSubstitution(isStatic = false) public static long getLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Long result = UnsafeLoadNode.load(o, offset, Kind.Long); + Long result = UnsafeLoadNode.load(o, offset, Kind.Long, LocationIdentity.ANY_LOCATION); return result; } @@ -241,7 +241,7 @@ @MethodSubstitution(isStatic = false) public static void putLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, long x) { - UnsafeStoreNode.store(o, offset, x, Kind.Long); + UnsafeStoreNode.store(o, offset, x, Kind.Long, LocationIdentity.ANY_LOCATION); } @MethodSubstitution(isStatic = false) @@ -261,7 +261,7 @@ @MethodSubstitution(isStatic = false) public static float getFloat(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Float result = UnsafeLoadNode.load(o, offset, Kind.Float); + Float result = UnsafeLoadNode.load(o, offset, Kind.Float, LocationIdentity.ANY_LOCATION); return result; } @@ -275,7 +275,7 @@ @MethodSubstitution(isStatic = false) public static void putFloat(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, float x) { - UnsafeStoreNode.store(o, offset, x, Kind.Float); + UnsafeStoreNode.store(o, offset, x, Kind.Float, LocationIdentity.ANY_LOCATION); } @MethodSubstitution(isStatic = false) @@ -288,7 +288,7 @@ @MethodSubstitution(isStatic = false) public static double getDouble(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) { @JavacBug(id = 6995200) - Double result = UnsafeLoadNode.load(o, offset, Kind.Double); + Double result = UnsafeLoadNode.load(o, offset, Kind.Double, LocationIdentity.ANY_LOCATION); return result; } @@ -302,7 +302,7 @@ @MethodSubstitution(isStatic = false) public static void putDouble(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, double x) { - UnsafeStoreNode.store(o, offset, x, Kind.Double); + UnsafeStoreNode.store(o, offset, x, Kind.Double, LocationIdentity.ANY_LOCATION); } @MethodSubstitution(isStatic = false)
--- /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 Thu Oct 24 15:56:08 2013 +0200 @@ -0,0 +1,99 @@ +/* + * 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.amd64.*; +import com.oracle.graal.api.code.CallingConvention.Type; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.*; +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.graal.truffle.hotspot.amd64.util.*; +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 HotSpotResolvedJavaMethod optimizedCallTargetCall; + + public AMD64HotSpotTruffleBackend(HotSpotGraalRuntime runtime, HotSpotProviders providers) { + super(runtime, providers); + } + + private ResolvedJavaMethod getInstrumentedMethod() throws GraalInternalError { + if (optimizedCallTargetCall == null) { + try { + optimizedCallTargetCall = (HotSpotResolvedJavaMethod) getProviders().getMetaAccess().lookupJavaMethod( + OptimizedCallTarget.class.getDeclaredMethod("call", PackedFrame.class, Arguments.class)); + optimizedCallTargetCall.setDontInline(); + } 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)) { + HotSpotProviders providers = getRuntime().getHostProviders(); + Register thisRegister = providers.getCodeCache().getRegisterConfig().getCallingConventionRegisters(Type.JavaCall, Kind.Object)[0]; + Register spillRegister = AMD64.r10; // TODO(mg): fix me + AMD64Address nMethodAddress = new AMD64Address(thisRegister, OptimizedCallTargetFieldInfo.getCompiledMethodFieldOffset()); + if (config.useCompressedOops) { + asm.movl(spillRegister, nMethodAddress); + AMD64HotSpotMove.decodePointer(asm, spillRegister, providers.getRegisters().getHeapBaseRegister(), config.narrowOopBase, config.narrowOopShift, config.logMinObjAlignment); + } else { + asm.movq(spillRegister, nMethodAddress); + } + Label doProlog = new Label(); + + asm.cmpq(spillRegister, 0); + asm.jcc(ConditionFlag.Equal, doProlog); + + AMD64Address codeBlobAddress = new AMD64Address(spillRegister, OptimizedCallTargetFieldInfo.getCodeBlobFieldOffset()); + asm.movq(spillRegister, codeBlobAddress); + asm.cmpq(spillRegister, 0); + asm.jcc(ConditionFlag.Equal, doProlog); + + AMD64Address verifiedEntryPointAddress = new AMD64Address(spillRegister, config.nmethodEntryOffset); + asm.movq(spillRegister, verifiedEntryPointAddress); + asm.jmp(spillRegister); + + asm.bind(doProlog); + } + } +}
--- /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 Thu Oct 24 15:56:08 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); + } +}
--- /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/util/OptimizedCallTargetFieldInfo.java Thu Oct 24 15:56:08 2013 +0200 @@ -0,0 +1,63 @@ +/* + * 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.util; + +import java.lang.reflect.*; + +import sun.misc.*; + +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.truffle.*; + +public class OptimizedCallTargetFieldInfo { + + private static final Unsafe unsafe = UnsafeAccess.unsafe; + private static int compiledMethodFieldOffset = -1; + private static int codeBlobFieldOffset = -1; + + public static int getCodeBlobFieldOffset() { + if (codeBlobFieldOffset == -1) { + codeBlobFieldOffset = getFieldOffset("codeBlob", HotSpotInstalledCode.class); + } + return codeBlobFieldOffset; + } + + public static int getCompiledMethodFieldOffset() { + if (compiledMethodFieldOffset == -1) { + compiledMethodFieldOffset = getFieldOffset("compiledMethod", OptimizedCallTarget.class); + } + return compiledMethodFieldOffset; + + } + + private static int getFieldOffset(String name, Class container) { + try { + container.getDeclaredField(name).setAccessible(true); + Field field = container.getDeclaredField(name); + return (int) unsafe.objectFieldOffset(field); + } catch (NoSuchFieldException | SecurityException e) { + throw GraalInternalError.shouldNotReachHere(); + } + } +}
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Thu Oct 24 15:56:08 2013 +0200 @@ -102,7 +102,7 @@ compilable.call(null, arguments); } while (compilable.inline()); - StructuredGraph graph = Debug.scope("TruffleCompilation", new DebugDumpScope("TruffleCompilation: " + compilable), new Callable<StructuredGraph>() { + StructuredGraph graph = Debug.scope("TruffleCompilation", new TruffleDebugJavaMethod(compilable), new Callable<StructuredGraph>() { @Override public StructuredGraph call() {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Thu Oct 24 15:56:08 2013 +0200 @@ -22,11 +22,28 @@ */ package com.oracle.graal.truffle; +import static com.oracle.graal.api.code.CodeUtil.*; import static com.oracle.graal.truffle.TruffleCompilerOptions.*; +import java.lang.reflect.*; import java.util.*; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CallingConvention.Type; +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.graph.*; +import com.oracle.graal.java.*; +import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.PhasePlan.PhasePosition; +import com.oracle.graal.phases.common.*; +import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.phases.util.*; +import com.oracle.graal.runtime.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.impl.*; @@ -47,6 +64,7 @@ private ArrayList<String> excludes; private GraalTruffleRuntime() { + installOptimizedCallTargetCallMethod(); } public String getName() { @@ -138,4 +156,43 @@ } } } + + public static void installOptimizedCallTargetCallMethod() { + Providers providers = getGraalProviders(); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + ResolvedJavaMethod resolvedCallMethod = metaAccess.lookupJavaMethod(getCallMethod()); + providers.getCodeCache().setDefaultMethod(resolvedCallMethod, compileMethod(resolvedCallMethod)); + } + + private static Method getCallMethod() { + Method method; + try { + method = OptimizedCallTarget.class.getDeclaredMethod("call", new Class[]{PackedFrame.class, Arguments.class}); + } catch (NoSuchMethodException | SecurityException e) { + throw GraalInternalError.shouldNotReachHere(); + } + return method; + } + + private static CompilationResult compileMethod(ResolvedJavaMethod javaMethod) { + Providers providers = getGraalProviders(); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + Suites suites = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites().createSuites(); + suites.getHighTier().findPhase(InliningPhase.class).remove(); + StructuredGraph graph = new StructuredGraph(javaMethod); + ForeignCallsProvider foreignCalls = providers.getForeignCalls(); + new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); + PhasePlan phasePlan = new PhasePlan(); + 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(RuntimeProvider.class).getHostBackend(); + return GraalCompiler.compileGraph(graph, cc, javaMethod, providers, backend, providers.getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog(), suites, + new CompilationResult()); + } + + private static Providers getGraalProviders() { + RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class); + return runtimeProvider.getHostBackend().getProviders(); + } }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Thu Oct 24 15:56:08 2013 +0200 @@ -75,6 +75,14 @@ } private Object callHelper(PackedFrame caller, Arguments args) { + if (compiledMethod != null && compiledMethod.isValid()) { + TruffleRuntime runtime = Truffle.getRuntime(); + if (runtime instanceof GraalTruffleRuntime) { + OUT.printf("[truffle] reinstall OptimizedCallTarget.call code with frame prolog shortcut."); + OUT.println(); + GraalTruffleRuntime.installOptimizedCallTargetCallMethod(); + } + } if (TruffleCallTargetProfiling.getValue()) { callCount++; }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Thu Oct 24 15:56:08 2013 +0200 @@ -104,7 +104,7 @@ final StructuredGraph graph = new StructuredGraph(executeHelperMethod); - Debug.scope("createGraph", graph, new Runnable() { + Debug.scope("createGraph", new Runnable() { @Override public void run() {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Thu Oct 24 15:56:08 2013 +0200 @@ -95,7 +95,7 @@ } public InstalledCode compile(final OptimizedCallTarget compilable) { - Object[] debug = new Object[]{new DebugDumpScope("Truffle: " + compilable)}; + Object[] debug = new Object[]{new TruffleDebugJavaMethod(compilable)}; return Debug.scope("Truffle", debug, new Callable<InstalledCode>() { @Override @@ -132,13 +132,17 @@ } public InstalledCode compileMethodHelper(final StructuredGraph graph, final GraphBuilderConfiguration config, final Assumptions assumptions) { - return compileMethodHelper(graph, config, null, assumptions); + return Debug.scope("Truffle", graph, new Callable<InstalledCode>() { + public InstalledCode call() throws Exception { + return compileMethodHelper(graph, config, null, assumptions); + } + }); } public InstalledCode compileMethodHelper(final StructuredGraph graph, final GraphBuilderConfiguration config, final OptimizedCallTarget compilable, final Assumptions assumptions) { final PhasePlan plan = createPhasePlan(config); - Debug.scope("TruffleFinal", graph, new Runnable() { + Debug.scope("TruffleFinal", new Runnable() { @Override public void run() { @@ -151,10 +155,15 @@ @Override public CompilationResult call() { try (TimerCloseable a = CompilationTime.start()) { - CodeCacheProvider codeCache = providers.getCodeCache(); - CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false); - return GraalCompiler.compileGraph(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, plan, OptimisticOptimizations.ALL, new SpeculationLog(), suites, - new CompilationResult()); + return Debug.scope("GraalCompiler", new Object[]{providers.getCodeCache()}, new Callable<CompilationResult>() { + public CompilationResult call() { + CodeCacheProvider codeCache = providers.getCodeCache(); + CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false); + CompilationResult compilationResult = new CompilationResult(compilable.toString()); + return GraalCompiler.compileGraphNoScope(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, plan, OptimisticOptimizations.ALL, + new SpeculationLog(), suites, compilationResult); + } + }); } } }); @@ -175,7 +184,7 @@ result.setAssumptions(newAssumptions); - InstalledCode compiledMethod = Debug.scope("CodeInstall", new Object[]{graph.method()}, new Callable<InstalledCode>() { + InstalledCode compiledMethod = Debug.scope("CodeInstall", new Object[]{providers.getCodeCache()}, new Callable<InstalledCode>() { @Override public InstalledCode call() throws Exception {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java Thu Oct 24 15:56:08 2013 +0200 @@ -0,0 +1,132 @@ +/* + * 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; + +import static com.oracle.graal.api.meta.MetaUtil.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.debug.*; +import com.oracle.truffle.api.impl.*; + +/** + * Enables a Truffle compilable to masquerade as a {@link JavaMethod} for use as a context value in + * {@linkplain Debug#scope(String, Object[], Runnable) debug scopes}. + */ +public class TruffleDebugJavaMethod implements JavaMethod { + private final DefaultCallTarget compilable; + + private static final JavaType declaringClass = new JavaType() { + + public String getName() { + return "LTruffle;"; + } + + public JavaType getComponentType() { + return null; + } + + public JavaType getArrayClass() { + throw new UnsupportedOperationException(); + } + + public Kind getKind() { + return Kind.Object; + } + + public ResolvedJavaType resolve(ResolvedJavaType accessingClass) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean equals(Object obj) { + return obj.getClass() == getClass(); + } + + @Override + public int hashCode() { + return getName().hashCode(); + } + }; + + private static final Signature signature = new Signature() { + + public JavaType getReturnType(ResolvedJavaType accessingClass) { + return declaringClass; + } + + public Kind getReturnKind() { + return declaringClass.getKind(); + } + + public JavaType getParameterType(int index, ResolvedJavaType accessingClass) { + throw new IndexOutOfBoundsException(); + } + + public int getParameterSlots(boolean withReceiver) { + return 0; + } + + public Kind getParameterKind(int index) { + throw new IndexOutOfBoundsException(); + } + + public int getParameterCount(boolean receiver) { + return 0; + } + }; + + public TruffleDebugJavaMethod(DefaultCallTarget compilable) { + this.compilable = compilable; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof TruffleDebugJavaMethod) { + TruffleDebugJavaMethod other = (TruffleDebugJavaMethod) obj; + return other.compilable.equals(compilable); + } + return false; + } + + @Override + public int hashCode() { + return compilable.hashCode(); + } + + public Signature getSignature() { + return signature; + } + + public String getName() { + return compilable.toString().replace('.', '_').replace(' ', '_'); + } + + public JavaType getDeclaringClass() { + return declaringClass; + } + + @Override + public String toString() { + return format("Truffle<%n(%p)>", this); + } +}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Thu Oct 24 15:56:08 2013 +0200 @@ -163,7 +163,7 @@ ConstantNode tagDefault = ConstantNode.forByte((byte) 0, graph()); for (int i = 0; i < frameSize; i++) { objectArrayEntryState[i] = objectDefault; - primitiveArrayEntryState[i] = initialValue(frameDescriptor.getSlots().get(i).getKind()); + primitiveArrayEntryState[i] = initialPrimitiveValue(frameDescriptor.getSlots().get(i).getKind()); tagArrayEntryState[i] = tagDefault; } tool.getAssumptions().record(new AssumptionValidAssumption((OptimizedAssumption) frameDescriptor.getVersion())); @@ -186,7 +186,7 @@ tool.replaceWithVirtual(virtualFrame); } - private ValueNode initialValue(FrameSlotKind kind) { + private ValueNode initialPrimitiveValue(FrameSlotKind kind) { Kind graalKind = null; switch (kind) { case Boolean: @@ -208,9 +208,8 @@ graalKind = Kind.Long; break; case Object: - graalKind = Kind.Object; - break; case Illegal: + // won't be stored in the primitive array, so default to long graalKind = Kind.Long; break; default:
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java Thu Oct 24 15:56:08 2013 +0200 @@ -34,6 +34,9 @@ public class OptimizedCallTargetSubstitutions { @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false) + public static native Object call(OptimizedCallTarget target, PackedFrame caller, Arguments args); + + @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false) public static native Object callHelper(OptimizedCallTarget target, PackedFrame caller, Arguments args); @MacroSubstitution(macro = NeverInlineMacroNode.class, isStatic = false)
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Thu Oct 24 15:56:08 2013 +0200 @@ -976,7 +976,7 @@ private List<CodeExecutableElement> createImplicitChildrenAccessors() { NodeData node = getModel().getNode(); -// Map<NodeChildData, Set<TypeData>> expectTypes = new HashMap<>(); + // Map<NodeChildData, Set<TypeData>> expectTypes = new HashMap<>(); @SuppressWarnings("unchecked") List<Set<TypeData>> expectTypes = Arrays.<Set<TypeData>> 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);
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java Thu Oct 24 15:56:08 2013 +0200 @@ -227,7 +227,7 @@ List<TypeData> polymorphicSignature = new ArrayList<>(); // TODO we should support more optimized for boxing -// List<ActualParameter> updatePolymorphic = generic.getReturnTypeAndParameters(); + // List<ActualParameter> updatePolymorphic = generic.getReturnTypeAndParameters(); List<ActualParameter> updatePolymorphic = Arrays.asList(); for (ActualParameter genericParameter : updatePolymorphic) { if (!genericParameter.getSpecification().isSignature()) {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BlockNode.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/BlockNode.java Thu Oct 24 15:56:08 2013 +0200 @@ -23,6 +23,7 @@ package com.oracle.truffle.sl.nodes; import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; public class BlockNode extends StatementNode { @@ -33,6 +34,7 @@ } @Override + @ExplodeLoop public void executeVoid(VirtualFrame frame) { for (StatementNode statement : statements) { statement.executeVoid(frame);
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java Thu Oct 24 15:56:08 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.*;
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.java Mon Oct 21 11:07:47 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.java Thu Oct 24 15:56:08 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;
--- a/make/bsd/makefiles/gcc.make Mon Oct 21 11:07:47 2013 +0200 +++ b/make/bsd/makefiles/gcc.make Thu Oct 24 15:56:08 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)
--- a/make/solaris/makefiles/jsig.make Mon Oct 21 11:07:47 2013 +0200 +++ b/make/solaris/makefiles/jsig.make Thu Oct 24 15:56:08 2013 +0200 @@ -79,9 +79,9 @@ install_jsig: $(LIBJSIG) @echo "Copying $(LIBJSIG) to $(DEST_JSIG)" - $(QUIETLY) test -f $(LIBJSIG_DEBUGINFO) && \ + -$(QUIETLY) test -f $(LIBJSIG_DEBUGINFO) && \ cp -f $(LIBJSIG_DEBUGINFO) $(DEST_JSIG_DEBUGINFO) - $(QUIETLY) test -f $(LIBJSIG_DIZ) && \ + -$(QUIETLY) test -f $(LIBJSIG_DIZ) && \ cp -f $(LIBJSIG_DIZ) $(DEST_JSIG_DIZ) $(QUIETLY) cp -f $(LIBJSIG) $(DEST_JSIG) && echo "Done"
--- a/make/solaris/makefiles/vm.make Mon Oct 21 11:07:47 2013 +0200 +++ b/make/solaris/makefiles/vm.make Thu Oct 24 15:56:08 2013 +0200 @@ -341,9 +341,9 @@ install_jvm: $(LIBJVM) @echo "Copying $(LIBJVM) to $(DEST_JVM)" - $(QUIETLY) test -f $(LIBJVM_DEBUGINFO) && \ + -$(QUIETLY) test -f $(LIBJVM_DEBUGINFO) && \ cp -f $(LIBJVM_DEBUGINFO) $(DEST_JVM_DEBUGINFO) - $(QUIETLY) test -f $(LIBJVM_DIZ) && \ + -$(QUIETLY) test -f $(LIBJVM_DIZ) && \ cp -f $(LIBJVM_DIZ) $(DEST_JVM_DIZ) $(QUIETLY) cp -f $(LIBJVM) $(DEST_JVM) && echo "Done"
--- a/mx/commands.py Mon Oct 21 11:07:47 2013 +0200 +++ b/mx/commands.py Thu Oct 24 15:56:08 2013 +0200 @@ -244,7 +244,7 @@ if machine in ['amd64', 'AMD64', 'x86_64', 'i86pc']: return 'amd64' if machine in ['sun4v', 'sun4u']: - return 'sparc' + return 'sparcv9' if machine == 'i386' and mx.get_os() == 'darwin': try: # Support for Snow Leopard and earlier version of MacOSX @@ -320,11 +320,14 @@ for line in f: if line.startswith('-') and defaultVM is None: parts = line.split() - assert len(parts) == 2, parts - assert parts[1] == 'KNOWN', parts[1] - defaultVM = parts[0][1:] - jvmCfgLines += ['# default VM is a copy of the unmodified ' + defaultVM + ' VM\n'] - jvmCfgLines += ['-original KNOWN\n'] + if len(parts) == 2: + assert parts[1] == 'KNOWN', parts[1] + defaultVM = parts[0][1:] + jvmCfgLines += ['# default VM is a copy of the unmodified ' + defaultVM + ' VM\n'] + jvmCfgLines += ['-original KNOWN\n'] + else: + # skip lines which we cannot parse (e.g. '-hotspot ALIASED_TO -client') + pass else: jvmCfgLines += [line] @@ -989,8 +992,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
--- a/mx/projects Mon Oct 21 11:07:47 2013 +0200 +++ b/mx/projects Thu Oct 24 15:56:08 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 @@ -649,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
--- a/mxtool/mx.py Mon Oct 21 11:07:47 2013 +0200 +++ b/mxtool/mx.py Thu Oct 24 15:56:08 2013 +0200 @@ -27,119 +27,9 @@ # r""" -mx is a command line tool inspired by mvn (http://maven.apache.org/) -and hg (http://mercurial.selenic.com/). It includes a mechanism for -managing the dependencies between a set of projects (like Maven) -as well as making it simple to run commands -(like hg is the interface to the Mercurial commands). - -The organizing principle of mx is a project suite. A suite is a directory -containing one or more projects. It's not coincidental that this closely -matches the layout of one or more projects in a Mercurial repository. -The configuration information for a suite lives in an 'mx' sub-directory -at the top level of the suite. A suite is given a name by a 'suite=name' -property in the 'mx/projects' file (if omitted the name is suite directory). -An 'mx' subdirectory can be named as plain 'mx' or 'mx.name', where -'name' is typically the name as the suite name. -The latter is useful to avoid clashes in IDE project names. - -When launched, mx treats the current working directory as a suite. -This is the primary suite. All other suites are called included suites. - -The configuration files (i.e. in the 'mx' sub-directory) of a suite are: - - projects - Defines the projects and libraries in the suite and the - dependencies between them. - - commands.py - Suite specific extensions to the commands available to mx. - - imports - Other suites to be loaded. This is recursive. Each - 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 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 -in the file specifies an attribute of a project or library. The main -difference between a project and a library is that the former contains -source code built by the mx tool where as the latter is an external -dependency. The format of the projects file is - -Library specification format: - - library@<name>@<prop>=<value> - -Built-in library properties (* = required): - - *path - The file system path for the library to appear on a class path. - - urls - A comma separated list of URLs from which the library (jar) can - be downloaded and saved in the location specified by 'path'. - - optional - If "true" then this library will be omitted from a class path - if it doesn't exist on the file system and no URLs are specified. - - sourcePath - The file system path for a jar file containing the library sources. - - sourceUrls - A comma separated list of URLs from which the library source jar can - be downloaded and saved in the location specified by 'sourcePath'. - -Project specification format: - - project@<name>@<prop>=<value> - -The name of a project also denotes the directory it is in. - -Built-in project properties (* = required): - - subDir - The sub-directory of the suite in which the project directory is - contained. If not specified, the project directory is directly - under the suite directory. - - *sourceDirs - A comma separated list of source directory names (relative to - the project directory). - - dependencies - A comma separated list of the libraries and project the project - depends upon (transitive dependencies should be omitted). - - checkstyle - The project whose Checkstyle configuration - (i.e. <project>/.checkstyle_checks.xml) is used. - - native - "true" if the project is native. - - javaCompliance - The minimum JDK version (format: x.y) to which the project's - sources comply (required for non-native projects). - - workingSets - A comma separated list of working set names. The project belongs - to the given working sets, for which the eclipseinit command - will generate Eclipse configurations. - -Other properties can be specified for projects and libraries for use -by extension commands. - -Property values can use environment variables with Bash syntax (e.g. ${HOME}). +mx is a command line tool for managing the development of Java code organized as suites of projects. + +Full documentation can be found at https://wiki.openjdk.java.net/display/Graal/The+mx+Tool """ import sys, os, errno, time, subprocess, shlex, types, urllib2, contextlib, StringIO, zipfile, signal, xml.sax.saxutils, tempfile, fnmatch @@ -156,13 +46,15 @@ _dists = dict() _suites = dict() _annotationProcessors = None -_mainSuite = None +_primary_suite_path = None +_primary_suite = 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 """ @@ -497,6 +389,58 @@ deps.append(self) return deps +class HgConfig: + """ + Encapsulates access to Mercurial (hg) + """ + def __init__(self): + self.missing = 'no hg executable found' + self.has_hg = None + + def check(self, abortOnFail=True): + if self.has_hg is None: + try: + subprocess.check_output(['hg']) + self.has_hg = True + except OSError: + self.has_hg = False + warn(self.missing) + + if not self.has_hg: + if abortOnFail: + abort(self.missing) + else: + warn(self.missing) + + def tip(self, sDir, abortOnError=True): + try: + return subprocess.check_output(['hg', 'tip', '-R', sDir, '--template', '{node}']) + except OSError: + warn(self.missing) + except subprocess.CalledProcessError: + if abortOnError: + abort('failed to get tip revision id') + else: + return None + + def can_push(self, s, strict=True): + try: + output = subprocess.check_output(['hg', '-R', s.dir, 'status']) + # super strict + return output == '' + except OSError: + warn(self.missing) + 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. @@ -508,19 +452,19 @@ self.primaryDir = None self.suitenamemap = {} - def _find_suite_dir(self, suitename): + 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): + 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): + 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): + abort('importee_dir not implemented') + + def nestedsuites_dirname(self): """Returns the dirname that contains any nested suites if the model supports that""" return None @@ -557,7 +501,7 @@ self.suitenamemap[mappair[0]] = mappair[1] @staticmethod - def _set_suitemodel(option, suitemap): + def set_suitemodel(option, suitemap): if option.startswith('sibling'): return SiblingSuiteModel(os.getcwd(), option, suitemap) elif option.startswith('nested'): @@ -568,7 +512,7 @@ abort('unknown suitemodel type: ' + option) @staticmethod - def _parse_options(): + 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): @@ -590,12 +534,19 @@ 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 + elif arg == '-p' or arg == '--primary-suite-path': + global _primary_suite_path + _primary_suite_path = os.path.abspath(_get_argvalue(arg, args, i + 1)) i = i + 1 global _src_suitemodel - _src_suitemodel = SuiteModel._set_suitemodel(src_suitemodel_arg, suitemap_arg) + _src_suitemodel = SuiteModel.set_suitemodel(src_suitemodel_arg, suitemap_arg) global _dst_suitemodel - _dst_suitemodel = SuiteModel._set_suitemodel(dst_suitemodel_arg, suitemap_arg) + _dst_suitemodel = SuiteModel.set_suitemodel(dst_suitemodel_arg, suitemap_arg) class SiblingSuiteModel(SuiteModel): @@ -605,14 +556,14 @@ self._suiteRootDir = suiteRootDir self._create_suitenamemap(option[len('sibling:'):], suitemap) - def _find_suite_dir(self, name): + 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) + def set_primary_dir(self, d): + SuiteModel.set_primary_dir(self, d) self._suiteRootDir = dirname(d) - def _importee_dir(self, importer_dir, suitename): + def importee_dir(self, importer_dir, suitename): if self.suitenamemap.has_key(suitename): suitename = self.suitenamemap[suitename] return join(dirname(importer_dir), suitename) @@ -627,10 +578,10 @@ self._primaryDir = primaryDir self._create_suitenamemap(option[len('nested:'):], suitemap) - def _find_suite_dir(self, name): + 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): + def importee_dir(self, importer_dir, suitename): if self.suitenamemap.has_key(suitename): suitename = self.suitenamemap[suitename] if basename(importer_dir) == basename(self._primaryDir): @@ -642,7 +593,7 @@ else: return join(dirname(importer_dir), suitename) - def _nestedsuites_dirname(self): + def nestedsuites_dirname(self): return self._imported_suites_dirname() class PathSuiteModel(SuiteModel): @@ -661,13 +612,13 @@ suiteurl = pair[0] self.suit_to_url[suitename] = suiteurl - def _find_suite_dir(self, suitename): + 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): + def importee_dir(self, importer_dir, suitename): if suitename in self.suit_to_url: return self.suit_to_url[suitename] else: @@ -679,7 +630,7 @@ self.version = version @staticmethod - def _parse_specification(specification): + def parse_specification(specification): pair = specification.split(',') name = pair[0] if len(pair) > 1: @@ -689,10 +640,10 @@ return SuiteImport(name, version) @staticmethod - def _tostring(name, version): + def tostring(name, version): return name + ',' + version - def _self_tostring(self): + def __str__(self): return self.name + ',' + self.version class Suite: @@ -706,8 +657,6 @@ self.commands = None self.primary = primary self.name = _suitename(mxDir) # validated in _load_projects - self.version = None # _hgtip checks current version if not None - self.version = _hgtip(self, False) if load: # load suites bottom up to make sure command overriding works properly self._load_imports() @@ -718,6 +667,10 @@ def __str__(self): return self.name + def version(self, abortOnError=True): + # we do not cache the version + return _hg.tip(self.dir, abortOnError) + def _load_projects(self): libsMap = dict() projsMap = dict() @@ -815,7 +768,7 @@ abort('Missing "suite=<name>" in ' + projectsFile) def _commands_name(self): - return 'mx_' + self.name + return 'mx_' + self.name.replace('-','_') def _find_commands(self, name): commandsPath = join(self.mxDir, name + '.py') @@ -850,7 +803,7 @@ mod.mx_init(self) self.commands = mod - def _visit_imports(self, visitor, **extra_args): + 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 @@ -860,7 +813,7 @@ 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 + as this function only visits the imports of a single 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') @@ -875,25 +828,25 @@ if out is not None: out.write(sline + '\n') continue - suite_import = SuiteImport._parse_specification(line.strip()) + 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): + def _find_and_loadsuite(importing_suite, suite_import, **extra_args): """visitor for the initial suite load""" - importMxDir = _src_suitemodel._find_suite_dir(suite_import.name) + 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) + importing_suite.imports.append(suite_import) + _loadSuite(importMxDir, False) + # we do not check at this stage whether the tip version of imported_suite + # matches that of the import, since during development, this can and will change def _load_imports(self): - self._visit_imports(self._find_and_loadsuite) + self.visit_imports(self._find_and_loadsuite) def _load_env(self): e = join(self.mxDir, 'env') @@ -1258,7 +1211,7 @@ else: break - envPath = join(_mainSuite.mxDir, 'env') + envPath = join(_primary_suite.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 @@ -1279,6 +1232,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('-p', '--primary-suite-path', help='set the primary suite directory', metavar='<path>') self.add_argument('--dbg', type=int, dest='java_dbg_port', help='make Java processes wait on <port> for a debugger', metavar='<port>') 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='<arg>') @@ -1847,7 +1801,7 @@ javaCompliance = java().javaCompliance - defaultEcjPath = join(_mainSuite.mxDir, 'ecj.jar') + defaultEcjPath = join(_primary_suite.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)') @@ -2166,7 +2120,7 @@ if len(modified) != 0: if args.backup: backup = os.path.abspath('eclipseformat.backup.zip') - arcbase = _mainSuite.dir + arcbase = _primary_suite.dir zf = zipfile.ZipFile(backup, 'w', zipfile.ZIP_DEFLATED) for fi in modified: arcname = os.path.relpath(fi.path, arcbase).replace(os.sep, '/') @@ -2420,7 +2374,7 @@ self.path = path self.timestamp = os.path.getmtime(path) if exists(path) else None - def outOfDate(self, arg): + def isOlderThan(self, arg): if not self.timestamp: return True if isinstance(arg, types.ListType): @@ -2480,7 +2434,7 @@ timestamp = TimeStampFile(join(p.suite.mxDir, 'checkstyle-timestamps', sourceDir[len(p.suite.dir) + 1:].replace(os.sep, '_') + '.timestamp')) mustCheck = False if not args.force and timestamp.exists(): - mustCheck = timestamp.outOfDate(javafilelist) + mustCheck = timestamp.isOlderThan(javafilelist) else: mustCheck = True @@ -2791,7 +2745,7 @@ if refreshOnly and not timestamp.exists(): return - if not timestamp.outOfDate(projectsFile): + if not timestamp.isOlderThan(projectsFile) and not TimeStampFile(projectsFile).isOlderThan(__file__): logv('[Eclipse configurations are up to date - skipping]') return @@ -2922,12 +2876,12 @@ out.close('buildCommand') if _isAnnotationProcessorDependency(p): - _genEclipseBuilder(out, p, 'Jar.launch', 'archive ' + p.name, refresh=False, async=False, xmlIndent='', xmlStandalone='no') - _genEclipseBuilder(out, p, 'Refresh.launch', '', refresh=True, async=True) + _genEclipseBuilder(out, p, 'Jar', 'archive ' + p.name, refresh=False, async=False, xmlIndent='', xmlStandalone='no') + _genEclipseBuilder(out, p, 'Refresh', '', refresh=True, async=True) if projToDist.has_key(p.name): dist, distDeps = projToDist[p.name] - _genEclipseBuilder(out, p, 'Create' + dist.name + 'Dist.launch', 'archive @' + dist.name, refresh=False, async=True) + _genEclipseBuilder(out, p, 'Create' + dist.name + 'Dist', 'archive @' + dist.name, logToFile=True, refresh=False, async=True) out.close('buildSpec') out.open('natures') @@ -2989,7 +2943,8 @@ """ return p in sorted_deps(annotation_processors()) -def _genEclipseBuilder(dotProjectDoc, p, name, mxCommand, refresh=True, async=False, logToConsole=False, xmlIndent='\t', xmlStandalone=None): +def _genEclipseBuilder(dotProjectDoc, p, name, mxCommand, refresh=True, async=False, logToConsole=False, logToFile=False, appendToLogFile=True, xmlIndent='\t', xmlStandalone=None): + externalToolDir = join(p.dir, '.externalToolBuilders') launchOut = XMLDoc() consoleOn = 'true' if logToConsole else 'false' launchOut.open('launchConfiguration', {'type' : 'org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType'}) @@ -3002,6 +2957,10 @@ launchOut.element('stringAttribute', {'key' : 'org.eclipse.debug.core.ATTR_REFRESH_SCOPE', 'value': '${project}'}) 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'}) + if logToFile: + logFile = join(externalToolDir, name + '.log') + launchOut.element('stringAttribute', {'key' : 'org.eclipse.debug.ui.ATTR_CAPTURE_IN_FILE', 'value': logFile}) + launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.ui.ATTR_APPEND_TO_FILE', 'value': 'true' if appendToLogFile else 'false'}) # expect to find the OS command to invoke mx in the same directory baseDir = dirname(os.path.abspath(__file__)) @@ -3025,11 +2984,9 @@ launchOut.close('launchConfiguration') - externalToolDir = join(p.dir, '.externalToolBuilders') - if not exists(externalToolDir): os.makedirs(externalToolDir) - update_file(join(externalToolDir, name), launchOut.xml(indent=xmlIndent, standalone=xmlStandalone, newl='\n')) + update_file(join(externalToolDir, name + '.launch'), launchOut.xml(indent=xmlIndent, standalone=xmlStandalone, newl='\n')) dotProjectDoc.open('buildCommand') dotProjectDoc.element('name', data='org.eclipse.ui.externaltools.ExternalToolBuilder') @@ -3037,7 +2994,7 @@ dotProjectDoc.open('arguments') dotProjectDoc.open('dictionary') dotProjectDoc.element('key', data='LaunchConfigHandle') - dotProjectDoc.element('value', data='<project>/.externalToolBuilders/' + name) + dotProjectDoc.element('value', data='<project>/.externalToolBuilders/' + name + '.launch') dotProjectDoc.close('dictionary') dotProjectDoc.open('dictionary') dotProjectDoc.element('key', data='incclean') @@ -3060,7 +3017,7 @@ if os.environ.has_key('WORKSPACE'): expected_wsroot = os.environ['WORKSPACE'] else: - expected_wsroot = _mainSuite.dir + expected_wsroot = _primary_suite.dir wsroot = _find_eclipse_wsroot(expected_wsroot) if wsroot is None: @@ -3198,7 +3155,7 @@ if refreshOnly and not timestamp.exists(): return - if not timestamp.outOfDate(projectsFile): + if not timestamp.isOlderThan(projectsFile) and not TimeStampFile(projectsFile).isOlderThan(__file__): logv('[NetBeans configurations are up to date - skipping]') return @@ -3464,8 +3421,8 @@ 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()) + 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[:] = [] @@ -3617,7 +3574,7 @@ names.append(p.name) links = ['-link', 'http://docs.oracle.com/javase/' + str(_java.javaCompliance.value) + '/docs/api/'] - out = join(_mainSuite.dir, docDir) + out = join(_primary_suite.dir, docDir) if args.base is not None: out = join(args.base, docDir) cp = classpath() @@ -3886,6 +3843,7 @@ def sclone(args): """clone a suite repository, and its imported suites""" + _hg.check() parser = ArgumentParser(prog='mx sclone') parser.add_argument('--source', help='url/path of repo containing suite', metavar='<url>') parser.add_argument('--dest', help='destination directory (default basename of source)', metavar='<path>') @@ -3902,11 +3860,11 @@ if args.source is None: # must be primary suite and dest is required - if _mainSuite is None: + if _primary_suite 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 + source = _primary_suite.dir else: source = args.source @@ -3917,8 +3875,8 @@ 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) + _dst_suitemodel.set_primary_dir(dest) + _src_suitemodel.set_primary_dir(source) _sclone(source, dest, None, args.no_imports) @@ -3940,12 +3898,12 @@ # 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) + s.visit_imports(_scloneimports_visitor, source=source) return s def _scloneimports_visitor(s, suite_import, source, **extra_args): """ - cloneimports visitor for Suite._visit_imports. + cloneimports visitor for Suite.visit_imports. The destination information is encapsulated by 's' """ _scloneimports(s, suite_import, source) @@ -3960,17 +3918,21 @@ 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) + 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): + # already exists in the suite model, but may be wrong version importee_suite = _scloneimports_suitehelper(importee_dest) - importee_suite._visit_imports(_scloneimports_visitor, source=importee_source) + if suite_import.version is not None and importee_suite.version() != suite_import.version: + abort("imported version of " + suite_import.name + " in " + s.name + " does not match the version in already existing suite: " + importee_suite.dir) + 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() parser = ArgumentParser(prog='mx scloneimports') parser.add_argument('--source', help='url/path of repo containing suite', metavar='<url>') parser.add_argument('nonKWArgs', nargs=REMAINDER, metavar='source [dest]...') @@ -3984,40 +3946,40 @@ s = _scloneimports_suitehelper(args.source) - default_path = _hgdefault_push(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) + _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""" + """push visitor for Suite.visit_imports""" if dest is not None: - dest = _dst_suitemodel._importee_dir(dest, suite_import.name) + 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 = _hgtip(suite(suite_import.name)) + """push check visitor for Suite.visit_imports""" + currentTip = suite(suite_import.name).version() if currentTip != suite_import.version: - abort('import version of ' + suite_import.name + ' in suite ' + s.name + ' does not match tip') + abort('imported 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 _hgcanpush(s): + if not _hg.can_push(s): abort('working directory ' + s.dir + ' contains uncommitted changes, push aborted') # check imports first if checks: - s._visit_imports(_spush_check_import_visitor) + s.visit_imports(_spush_check_import_visitor) # ok, push imports - s._visit_imports(_spush_import_visitor, dest=dest, checks=checks, clonemissing=clonemissing) + s.visit_imports(_spush_import_visitor, dest=dest, checks=checks, clonemissing=clonemissing) dest_exists = True @@ -4049,6 +4011,7 @@ def spush(args): """push primary suite and all its imports""" + _hg.check() parser = ArgumentParser(prog='mx spush') parser.add_argument('--dest', help='url/path of repo to push to (default as per hg push)', metavar='<path>') parser.add_argument('--no-checks', action='store_true', help='checks on status, versions are disabled') @@ -4071,40 +4034,41 @@ args.nochecks = True if args.dest is not None: - _dst_suitemodel._set_primary_dir(args.dest) - - _spush(s, None, args.dest, not args.nochecks, args.clonemissing) + _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) + s.visit_imports(_supdate_import_visitor) run(['hg', '-R', s.dir, 'update']) def supdate(args): """update primary suite and all its imports""" + _hg.check() 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): + """scheckimports visitor for Suite.visit_imports""" + _scheck_imports(s, suite(suite_import.name), suite_import, update_versions, updated_imports) + +def _scheck_imports(importing_suite, imported_suite, suite_import, update_versions, updated_imports): # check imports recursively - s._visit_imports(_scheck_imports_visitor, update_versions=update_versions) - - currentTip = _hgtip(s) + imported_suite.visit_imports(_scheck_imports_visitor, update_versions=update_versions) + + currentTip = imported_suite.version() if currentTip != suite_import.version: - print('import version of ' + s.name + ' does not match tip' + (': updating' if update_versions else '')) + print('imported version of ' + imported_suite.name + ' in ' + importing_suite.name + ' does not match tip' + (': updating' if update_versions else '')) if update_versions: suite_import.version = currentTip - line = suite_import._self_tostring() + line = str(suite_import) updated_imports.write(line + '\n') def scheckimports(args): @@ -4112,51 +4076,25 @@ 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 _hgtip(s, abortOnError=True): - 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 _hgcanpush(s): - try: - output = subprocess.check_output(['hg', '-R', s.dir, 'status']) - # super strict - return output == '' - except subprocess.CalledProcessError: - return False - -def _hgdefault_push(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 + _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""" + """pull visitor for Suite.visit_imports""" _spull(suite(suite_import.name), update_versions, updated_imports) def _spull(s, update_versions, updated_imports): + _hg.check() # pull imports first - s._visit_imports(_spull_import_visitor, update_versions=update_versions) + 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 = _hgtip(s) - updated_imports.write(SuiteImport._tostring(s.name, tip) + '\n') + tip = s.version() + updated_imports.write(SuiteImport.tostring(s.name, tip) + '\n') def spull(args): """pull primary suite and all its imports""" + _hg.check() 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) @@ -4337,45 +4275,74 @@ return mxDir def _check_primary_suite(): - if _mainSuite is None: + if _primary_suite is None: abort('no primary suite found') else: - return _mainSuite + return _primary_suite def _needs_primary_suite(command): return not command.startswith("sclone") +def _needs_primary_suite_cl(): + return not any("sclone" in s for s in sys.argv[1:]) + +def _findPrimarySuiteMxDirFrom(d): + """ search for a suite directory upwards from 'd' """ + while d: + mxDir = _is_suite_dir(d) + if mxDir is not None: + return mxDir + parent = dirname(d) + if d == parent: + return None + d = parent + + return None + def _findPrimarySuiteMxDir(): - # try current working directory first, the look up the tree - curdir = os.getcwd() - while curdir: - mxDir = _is_suite_dir(curdir) + # check for explicit setting + if _primary_suite_path is not None: + mxDir = _is_suite_dir(_primary_suite_path) if mxDir is not None: return mxDir - parent = dirname(curdir) - if curdir == parent: - return None - curdir = parent - - return None + else: + abort(_primary_suite_path + ' does not contain an mx suite') + + # try current working directory first + mxDir = _findPrimarySuiteMxDirFrom(os.getcwd()) + if mxDir is not None: + return mxDir + # backwards compatibility: search from path of this file + return _findPrimarySuiteMxDirFrom(dirname(__file__)) def main(): - SuiteModel._parse_options() - + SuiteModel.parse_options() + + global _hg + _hg = HgConfig() + + primary_suite_error = 'no primary suite found' primarySuiteMxDir = _findPrimarySuiteMxDir() if primarySuiteMxDir: - _src_suitemodel._set_primary_dir(dirname(primarySuiteMxDir)) - global _mainSuite - _mainSuite = _loadSuite(primarySuiteMxDir, True) + _src_suitemodel.set_primary_dir(dirname(primarySuiteMxDir)) + global _primary_suite + _primary_suite = _loadSuite(primarySuiteMxDir, True) + else: + # in general this is an error, except for the sclone/scloneimports commands, + # and an extensions command will likely not parse in this case, as any extra arguments + # will not have been added to _argParser. + # If the command line does not contain a string matching one of the exceptions, we can safely abort, + # but not otherwise, as we can't be sure the string isn't in a value for some other option. + if _needs_primary_suite_cl(): + abort(primary_suite_error) 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) + abort(primary_suite_error) else: - warn(msg) + warn(primary_suite_error) global _opts, _java _opts = opts
--- a/src/gpu/ptx/vm/gpu_ptx.cpp Mon Oct 21 11:07:47 2013 +0200 +++ b/src/gpu/ptx/vm/gpu_ptx.cpp Thu Oct 24 15:56:08 2013 +0200 @@ -385,7 +385,7 @@ case T_INT: { int return_val; - status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._return_value_ptr, T_INT_BYTE_SIZE); + status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._dev_return_value, T_INT_BYTE_SIZE); if (status != GRAAL_CUDA_SUCCESS) { tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status); return false; @@ -396,7 +396,7 @@ case T_BOOLEAN: { int return_val; - status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._return_value_ptr, T_INT_BYTE_SIZE); + status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._dev_return_value, T_INT_BYTE_SIZE); if (status != GRAAL_CUDA_SUCCESS) { tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status); return false; @@ -407,7 +407,7 @@ case T_FLOAT: { float return_val; - status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._return_value_ptr, T_FLOAT_BYTE_SIZE); + status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._dev_return_value, T_FLOAT_BYTE_SIZE); if (status != GRAAL_CUDA_SUCCESS) { tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status); return false; @@ -418,7 +418,7 @@ case T_DOUBLE: { double return_val; - status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._return_value_ptr, T_DOUBLE_BYTE_SIZE); + status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._dev_return_value, T_DOUBLE_BYTE_SIZE); if (status != GRAAL_CUDA_SUCCESS) { tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status); return false; @@ -429,7 +429,7 @@ case T_LONG: { long return_val; - status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._return_value_ptr, T_LONG_BYTE_SIZE); + status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._dev_return_value, T_LONG_BYTE_SIZE); if (status != GRAAL_CUDA_SUCCESS) { tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status); return false; @@ -443,11 +443,11 @@ tty->print_cr("[CUDA] TODO *** Unhandled return type: %d", return_type); } - // handle post-invocation object and array arguemtn - ptxka.reiterate(); + // Copy all reference arguments from device to host memory. + ptxka.copyRefArgsFromDtoH(); // Free device memory allocated for result - status = gpu::Ptx::_cuda_cu_memfree(ptxka._return_value_ptr); + status = gpu::Ptx::_cuda_cu_memfree(ptxka._dev_return_value); if (status != GRAAL_CUDA_SUCCESS) { tty->print_cr("[CUDA] *** Error (%d) Failed to free device memory of return value", status); return false;
--- a/src/gpu/ptx/vm/ptxKernelArguments.cpp Mon Oct 21 11:07:47 2013 +0200 +++ b/src/gpu/ptx/vm/ptxKernelArguments.cpp Thu Oct 24 15:56:08 2013 +0200 @@ -32,127 +32,132 @@ // Get next java argument oop PTXKernelArguments::next_arg(BasicType expectedType) { assert(_index < _args->length(), "out of bounds"); - oop arg = ((objArrayOop) (_args))->obj_at(_index++); assert(expectedType == T_OBJECT || java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch"); - return arg; } void PTXKernelArguments::do_int() { - if (is_after_invocation()) { + // If the parameter is a return value, + if (is_return_type()) { + if (is_kernel_arg_setup()) { + // Allocate device memory for T_INT return value pointer on device. Size in bytes + int status = gpu::Ptx::_cuda_cu_memalloc(&_dev_return_value, T_INT_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; return; + } + // Push _dev_return_value to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _dev_return_value; } - // If the parameter is a return value, - if (is_return_type()) { - // Allocate device memory for T_INT return value pointer on device. Size in bytes - int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_INT_BYTE_SIZE); - if (status != GRAAL_CUDA_SUCCESS) { - tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); - _success = false; - return; - } - // Push _return_value_ptr to _kernelBuffer - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; - _bufferOffset += sizeof(_return_value_ptr); - } else { - // Get the next java argument and its value which should be a T_INT - oop arg = next_arg(T_INT); - // Copy the java argument value to kernelArgBuffer - jvalue intval; - if (java_lang_boxing_object::get_value(arg, &intval) != T_INT) { - tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT"); - _success = false; - return; - } - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = intval.i; - _bufferOffset += sizeof(intval.i); + _bufferOffset += sizeof(_dev_return_value); + } else { + // Get the next java argument and its value which should be a T_INT + oop arg = next_arg(T_INT); + // Copy the java argument value to kernelArgBuffer + jvalue intval; + if (java_lang_boxing_object::get_value(arg, &intval) != T_INT) { + tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT"); + _success = false; + return; } - return; + if (is_kernel_arg_setup()) { + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = intval.i; + } + // Advance _bufferOffset + _bufferOffset += sizeof(intval.i); + } + return; } void PTXKernelArguments::do_float() { - if (is_after_invocation()) { + // If the parameter is a return value, + if (is_return_type()) { + if (is_kernel_arg_setup()) { + // Allocate device memory for T_INT return value pointer on device. Size in bytes + int status = gpu::Ptx::_cuda_cu_memalloc(&_dev_return_value, T_FLOAT_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; return; + } + // Push _dev_return_value to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _dev_return_value; } - // If the parameter is a return value, - if (is_return_type()) { - // Allocate device memory for T_INT return value pointer on device. Size in bytes - int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_FLOAT_BYTE_SIZE); - if (status != GRAAL_CUDA_SUCCESS) { - tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); - _success = false; - return; - } - // Push _return_value_ptr to _kernelBuffer - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; - _bufferOffset += sizeof(_return_value_ptr); - } else { - // Get the next java argument and its value which should be a T_INT - oop arg = next_arg(T_FLOAT); - // Copy the java argument value to kernelArgBuffer - jvalue floatval; - if (java_lang_boxing_object::get_value(arg, &floatval) != T_FLOAT) { - tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT"); - _success = false; - return; - } - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = (gpu::Ptx::CUdeviceptr) floatval.f; - _bufferOffset += sizeof(floatval.f); + // Advance _bufferOffset + _bufferOffset += sizeof(_dev_return_value); + } else { + // Get the next java argument and its value which should be a T_FLOAT + oop arg = next_arg(T_FLOAT); + // Copy the java argument value to kernelArgBuffer + jvalue floatval; + if (java_lang_boxing_object::get_value(arg, &floatval) != T_FLOAT) { + tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_FLOAT"); + _success = false; + return; } - return; + if (is_kernel_arg_setup()) { + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = (gpu::Ptx::CUdeviceptr) floatval.f; + } + // Advance _bufferOffset + _bufferOffset += sizeof(floatval.f); + } + return; } void PTXKernelArguments::do_double() { - if (is_after_invocation()) { + // If the parameter is a return value, + jvalue doubleval; + if (is_return_type()) { + if (is_kernel_arg_setup()) { + // Allocate device memory for T_INT return value pointer on device. Size in bytes + int status = gpu::Ptx::_cuda_cu_memalloc(&_dev_return_value, T_DOUBLE_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; return; + } + // Push _dev_return_value to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _dev_return_value; } - // If the parameter is a return value, - jvalue doubleval; - if (is_return_type()) { - // Allocate device memory for T_INT return value pointer on device. Size in bytes - int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_DOUBLE_BYTE_SIZE); - if (status != GRAAL_CUDA_SUCCESS) { - tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); - _success = false; - return; - } - // Push _return_value_ptr to _kernelBuffer - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; - // _bufferOffset += sizeof(_return_value_ptr); - _bufferOffset += sizeof(doubleval.d); - } else { - // Get the next java argument and its value which should be a T_INT - oop arg = next_arg(T_FLOAT); - // Copy the java argument value to kernelArgBuffer - if (java_lang_boxing_object::get_value(arg, &doubleval) != T_DOUBLE) { - tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT"); - _success = false; - return; - } - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = (gpu::Ptx::CUdeviceptr) doubleval.d; - _bufferOffset += sizeof(doubleval.d); + // Advance _bufferOffset + _bufferOffset += sizeof(doubleval.d); + } else { + // Get the next java argument and its value which should be a T_INT + oop arg = next_arg(T_FLOAT); + // Copy the java argument value to kernelArgBuffer + if (java_lang_boxing_object::get_value(arg, &doubleval) != T_DOUBLE) { + tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT"); + _success = false; + return; } - return; + if (is_kernel_arg_setup()) { + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = (gpu::Ptx::CUdeviceptr) doubleval.d; + } + // Advance _bufferOffset + _bufferOffset += sizeof(doubleval.d); + } + return; } void PTXKernelArguments::do_long() { - if (is_after_invocation()) { - return; - } // If the parameter is a return value, if (is_return_type()) { - // Allocate device memory for T_LONG return value pointer on device. Size in bytes - int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_LONG_BYTE_SIZE); - if (status != GRAAL_CUDA_SUCCESS) { - tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); - _success = false; - return; + if (is_kernel_arg_setup()) { + // Allocate device memory for T_LONG return value pointer on device. Size in bytes + int status = gpu::Ptx::_cuda_cu_memalloc(&_dev_return_value, T_LONG_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; + return; + } + // Push _dev_return_value to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _dev_return_value; } - // Push _return_value_ptr to _kernelBuffer - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; - _bufferOffset += sizeof(_return_value_ptr); + // Advance _bufferOffset + _bufferOffset += sizeof(_dev_return_value); } else { // Get the next java argument and its value which should be a T_LONG oop arg = next_arg(T_LONG); @@ -163,119 +168,132 @@ _success = false; return; } - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.j; + if (is_kernel_arg_setup()) { + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.j; + } + // Advance _bufferOffset _bufferOffset += sizeof(val.j); } return; } void PTXKernelArguments::do_byte() { - if (is_after_invocation()) { + // If the parameter is a return value, + if (is_return_type()) { + if (is_kernel_arg_setup()) { + // Allocate device memory for T_BYTE return value pointer on device. Size in bytes + int status = gpu::Ptx::_cuda_cu_memalloc(&_dev_return_value, T_BYTE_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; return; + } + // Push _dev_return_value to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _dev_return_value; } - // If the parameter is a return value, - if (is_return_type()) { - // Allocate device memory for T_BYTE return value pointer on device. Size in bytes - int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_BYTE_SIZE); - if (status != GRAAL_CUDA_SUCCESS) { - tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); - _success = false; - return; - } - // Push _return_value_ptr to _kernelBuffer - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; - _bufferOffset += sizeof(_return_value_ptr); - } else { - // Get the next java argument and its value which should be a T_BYTE - oop arg = next_arg(T_BYTE); - // Copy the java argument value to kernelArgBuffer - jvalue val; - if (java_lang_boxing_object::get_value(arg, &val) != T_BYTE) { - tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_BYTE"); - _success = false; - return; - } - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.b; - _bufferOffset += sizeof(val.b); + // Advance _bufferOffset + _bufferOffset += sizeof(_dev_return_value); + } else { + // Get the next java argument and its value which should be a T_BYTE + oop arg = next_arg(T_BYTE); + // Copy the java argument value to kernelArgBuffer + jvalue val; + if (java_lang_boxing_object::get_value(arg, &val) != T_BYTE) { + tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_BYTE"); + _success = false; + return; } - return; + if (is_kernel_arg_setup()) { + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.b; + } + // Advance _bufferOffset + _bufferOffset += sizeof(val.b); + } + return; } void PTXKernelArguments::do_bool() { - if (is_after_invocation()) { + // If the parameter is a return value, + if (is_return_type()) { + if (is_kernel_arg_setup()) { + // Allocate device memory for T_BYTE return value pointer on device. Size in bytes + int status = gpu::Ptx::_cuda_cu_memalloc(&_dev_return_value, T_BOOLEAN_SIZE); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); + _success = false; return; + } + // Push _dev_return_value to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _dev_return_value; } - // If the parameter is a return value, - if (is_return_type()) { - // Allocate device memory for T_BYTE return value pointer on device. Size in bytes - int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_BOOLEAN_SIZE); - if (status != GRAAL_CUDA_SUCCESS) { - tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); - _success = false; - return; - } - // Push _return_value_ptr to _kernelBuffer - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; - _bufferOffset += sizeof(_return_value_ptr); - } else { - // Get the next java argument and its value which should be a T_BYTE - oop arg = next_arg(T_BYTE); - // Copy the java argument value to kernelArgBuffer - jvalue val; - if (java_lang_boxing_object::get_value(arg, &val) != T_BOOLEAN) { - tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_BYTE"); - _success = false; - return; - } - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.z; - _bufferOffset += sizeof(val.z); + // Advance _bufferOffset + _bufferOffset += sizeof(_dev_return_value); + } else { + // Get the next java argument and its value which should be a T_BYTE + oop arg = next_arg(T_BYTE); + // Copy the java argument value to kernelArgBuffer + jvalue val; + if (java_lang_boxing_object::get_value(arg, &val) != T_BOOLEAN) { + tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_BYTE"); + _success = false; + return; } - return; + if (is_kernel_arg_setup()) { + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.z; + } + // Advance _bufferOffset + _bufferOffset += sizeof(val.z); + } + return; } void PTXKernelArguments::do_array(int begin, int end) { - gpu::Ptx::CUdeviceptr _array_ptr; - int status; - - // Get the next java argument and its value which should be a T_ARRAY - oop arg = next_arg(T_OBJECT); - int array_size = arg->size() * HeapWordSize; + // Get the next java argument and its value which should be a T_ARRAY + oop arg = next_arg(T_OBJECT); + assert(arg->is_array(), "argument value not an array"); + // Size of array argument + int argSize = arg->size() * HeapWordSize; + // Device pointer to array argument. + gpu::Ptx::CUdeviceptr arrayArgOnDev; + int status; - if (is_after_invocation()) { - _array_ptr = *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]); - status = gpu::Ptx::_cuda_cu_memcpy_dtoh(arg, _array_ptr, array_size); - if (status != GRAAL_CUDA_SUCCESS) { - tty->print_cr("[CUDA] *** Error (%d) Failed to copy array argument to host", status); - _success = false; - return; - } else { - // tty->print_cr("device: %x host: %x size: %d", _array_ptr, arg, array_size); - } - return; + if (is_kernel_arg_setup()) { + // Allocate device memory for array argument on device. Size in bytes + status = gpu::Ptx::_cuda_cu_memalloc(&arrayArgOnDev, argSize); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for array argument on device", + status); + _success = false; + return; } - // Allocate device memory for T_ARRAY return value pointer on device. Size in bytes - status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, array_size); - if (status != GRAAL_CUDA_SUCCESS) { - tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status); - _success = false; - return; - } - status = gpu::Ptx::_cuda_cu_memcpy_htod(_return_value_ptr, arg, array_size); + // Copy array argument to device + status = gpu::Ptx::_cuda_cu_memcpy_htod(arrayArgOnDev, arg, argSize); if (status != GRAAL_CUDA_SUCCESS) { - tty->print_cr("[CUDA] *** Error (%d) Failed to copy array to device argument", status); - _success = false; - return; - } else { - // tty->print_cr("host: %x device: %x size: %d", arg, _return_value_ptr, array_size); + tty->print_cr("[CUDA] *** Error (%d) Failed to copy array argument content to device memory", + status); + _success = false; + return; } - // Push _return_value_ptr to _kernelBuffer - *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr; - _bufferOffset += sizeof(_return_value_ptr); - return; + + // Push device array argument to _kernelBuffer + *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = arrayArgOnDev; + } else { + arrayArgOnDev = *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]); + status = gpu::Ptx::_cuda_cu_memcpy_dtoh(arg, arrayArgOnDev, argSize); + if (status != GRAAL_CUDA_SUCCESS) { + tty->print_cr("[CUDA] *** Error (%d) Failed to copy array argument to host", status); + _success = false; + return; + } + } + + // Advance _bufferOffset + _bufferOffset += sizeof(arrayArgOnDev); + return; } void PTXKernelArguments::do_void() { - return; + return; } // TODO implement other do_*
--- a/src/gpu/ptx/vm/ptxKernelArguments.hpp Mon Oct 21 11:07:47 2013 +0200 +++ b/src/gpu/ptx/vm/ptxKernelArguments.hpp Thu Oct 24 15:56:08 2013 +0200 @@ -42,7 +42,13 @@ char _kernelArgBuffer[1024]; // Current offset into _kernelArgBuffer size_t _bufferOffset; - gpu::Ptx::CUdeviceptr _return_value_ptr; + // Device pointer holding return value + gpu::Ptx::CUdeviceptr _dev_return_value; + + // Indicates if signature iteration is being done during kernel + // setup i.e., java arguments are being copied to device pointers. + bool _kernelArgSetup; + private: // Array of java argument oops arrayOop _args; @@ -51,7 +57,6 @@ // Flag to indicate successful creation of kernel argument buffer bool _success; - bool _afterInvoocation; // Get next java argument oop next_arg(BasicType expectedType); @@ -62,7 +67,9 @@ _args = args; _success = true; _bufferOffset = 0; - _return_value_ptr = 0; + _dev_return_value = 0; + _kernelArgSetup = true; + //_dev_call_by_reference_args_index = 0; if (!is_static) { // TODO : Create a device argument for receiver object and add it to _kernelBuffer tty->print_cr("{CUDA] ****** TODO: Support for execution of non-static java methods not implemented yet."); @@ -80,23 +87,23 @@ return _bufferOffset; } - void reiterate() { - _afterInvoocation = true; - _bufferOffset = 0; - _index = 0; - iterate(); - } + void copyRefArgsFromDtoH() { + _kernelArgSetup = false; + _bufferOffset = 0; + _index = 0; + iterate(); + } - inline bool is_after_invocation() { - return _afterInvoocation; - } + inline bool is_kernel_arg_setup() { + return _kernelArgSetup; + } // Get the return oop value oop get_return_oop(); // get device return value ptr - gpu::Ptx::CUdeviceptr get_return_value_ptr() { - return _return_value_ptr; + gpu::Ptx::CUdeviceptr get_dev_return_value() { + return _dev_return_value; }
--- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/GraalEdgeColorFilter.java Mon Oct 21 11:07:47 2013 +0200 +++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/GraalEdgeColorFilter.java Thu Oct 24 15:56:08 2013 +0200 @@ -32,6 +32,7 @@ import com.sun.hotspot.igv.graph.InputSlot; import java.awt.Color; import java.util.List; +import java.util.regex.Pattern; /** * Filter that colors usage and successor edges differently. @@ -55,6 +56,7 @@ @Override public void apply(Diagram d) { List<Figure> figures = d.getFigures(); + Pattern ndf = Pattern.compile(".*#NDF(\\[[0-9]*\\])?"); for (Figure f : figures) { Properties p = f.getProperties(); int predCount; @@ -78,7 +80,7 @@ is.setColor(color); for (Connection c : is.getConnections()) { - if (c.getLabel() == null || !c.getLabel().endsWith("#NDF")) { + if (c.getLabel() == null || !ndf.matcher(c.getLabel()).matches()) { c.setColor(color); if (c.getStyle() != ConnectionStyle.DASHED) { c.setStyle(style);
--- a/src/share/tools/IdealGraphVisualizer/nbproject/project.properties Mon Oct 21 11:07:47 2013 +0200 +++ b/src/share/tools/IdealGraphVisualizer/nbproject/project.properties Thu Oct 24 15:56:08 2013 +0200 @@ -40,5 +40,5 @@ # Disable assertions for RequestProcessor to prevent annoying messages in case # of multiple SceneAnimator update tasks in the default RequestProcessor. -run.args.extra = -J-server -J-da:org.openide.util.RequestProcessor -J-Xms2g -J-Xmx4g +run.args.extra = -J-server -J-da:org.openide.util.RequestProcessor -J-Xms2g -J-Xmx8g debug.args.extra = -J-server -J-da:org.openide.util.RequestProcessor
--- a/src/share/vm/gc_interface/collectedHeap.cpp Mon Oct 21 11:07:47 2013 +0200 +++ b/src/share/vm/gc_interface/collectedHeap.cpp Thu Oct 24 15:56:08 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).
--- a/src/share/vm/graal/graalCompilerToVM.cpp Mon Oct 21 11:07:47 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Thu Oct 24 15:56:08 2013 +0200 @@ -642,6 +642,13 @@ return id; } +C2V_VMENTRY(void, doNotInlineOrCompile,(JNIEnv *, jobject, jlong metaspace_method)) + methodHandle method = asMethod(metaspace_method); + method->set_not_c1_compilable(); + method->set_not_c2_compilable(); + method->set_dont_inline(true); +C2V_END + C2V_ENTRY(void, initializeConfiguration, (JNIEnv *env, jobject, jobject config)) #define set_boolean(name, value) do { env->SetBooleanField(config, getFieldID(env, config, name, "Z"), value); } while (0) @@ -1196,6 +1203,7 @@ {CC"getUniqueImplementor", CC"("HS_RESOLVED_TYPE")"RESOLVED_TYPE, FN_PTR(getUniqueImplementor)}, {CC"getStackTraceElement", CC"("METASPACE_METHOD"I)"STACK_TRACE_ELEMENT, FN_PTR(getStackTraceElement)}, {CC"initializeMethod", CC"("METASPACE_METHOD HS_RESOLVED_METHOD")V", FN_PTR(initializeMethod)}, + {CC"doNotInlineOrCompile", CC"("METASPACE_METHOD")V", FN_PTR(doNotInlineOrCompile)}, {CC"initializeMethodData", CC"("METASPACE_METHOD_DATA METHOD_DATA")V", FN_PTR(initializeMethodData)}, {CC"isMethodCompilable", CC"("METASPACE_METHOD")Z", FN_PTR(isMethodCompilable)}, {CC"getCompiledCodeSize", CC"("METASPACE_METHOD")I", FN_PTR(getCompiledCodeSize)},
--- a/src/share/vm/graal/graalGlobals.hpp Mon Oct 21 11:07:47 2013 +0200 +++ b/src/share/vm/graal/graalGlobals.hpp Thu Oct 24 15:56:08 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, \
--- a/src/share/vm/graal/graalJavaAccess.hpp Mon Oct 21 11:07:47 2013 +0200 +++ b/src/share/vm/graal/graalJavaAccess.hpp Thu Oct 24 15:56:08 2013 +0200 @@ -85,6 +85,7 @@ start_class(HotSpotNmethod) \ boolean_field(HotSpotNmethod, isDefault) \ boolean_field(HotSpotNmethod, isExternal) \ + oop_field(HotSpotNmethod, name, "Ljava/lang/String;") \ end_class \ start_class(HotSpotCompiledCode) \ oop_field(HotSpotCompiledCode, comp, "Lcom/oracle/graal/api/code/CompilationResult;") \
--- a/src/share/vm/runtime/deoptimization.cpp Mon Oct 21 11:07:47 2013 +0200 +++ b/src/share/vm/runtime/deoptimization.cpp Thu Oct 24 15:56:08 2013 +0200 @@ -89,6 +89,7 @@ #ifdef GRAAL #include "graal/graalCompiler.hpp" +#include "graal/graalJavaAccess.hpp" #endif @@ -1420,6 +1421,19 @@ if (TraceDeoptimization) { // make noise on the tty tty->print("Uncommon trap occurred in"); nm->method()->print_short_name(tty); +#ifdef GRAAL + oop installedCode = nm->graal_installed_code(); + if (installedCode != NULL) { + oop installedCodeName = HotSpotNmethod::name(installedCode); + if (installedCodeName != NULL) { + tty->print(" (Graal: installedCodeName=%s) ", java_lang_String::as_utf8_string(installedCodeName)); + } else { + tty->print(" (Graal: installed code has no name) "); + } + } else { + tty->print(" (Graal: no installed code) "); + } +#endif //GRAAL tty->print(" (@" INTPTR_FORMAT ") thread=" UINTX_FORMAT " reason=%s action=%s unloaded_class_index=%d", fr.pc(), os::current_thread_id(),