# HG changeset patch # User Thomas Wuerthinger # Date 1363310295 -3600 # Node ID 5284877c419dc5c5eb6b1e895e8dbf7a0bf7b478 # Parent b2f88686f68b562340a37394fae9efafc62c5c27# Parent 09290d9deab3a51a2aa1f017578bbc8177ff7e91 Merge. diff -r b2f88686f68b -r 5284877c419d graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java Thu Mar 14 19:20:43 2013 +0100 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java Fri Mar 15 02:18:15 2013 +0100 @@ -31,7 +31,6 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.phases.*; /** * PTX specific backend. @@ -63,25 +62,22 @@ } @Override - public TargetMethodAssembler newAssembler(FrameMap frameMap, LIR lir) { + public TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult) { // Omit the frame if the method: // - has no spill slots or other slots allocated during register allocation // - has no callee-saved registers // - has no incoming arguments passed on the stack // - has no instructions with debug info - boolean omitFrame = GraalOptions.CanOmitFrame && frameMap.frameSize() == frameMap.initialFrameSize && frameMap.registerConfig.getCalleeSaveLayout().registers.length == 0 && - !lir.hasArgInCallerFrame() && !lir.hasDebugInfo(); - + FrameMap frameMap = lirGen.frameMap; AbstractAssembler masm = new PTXAssembler(target, frameMap.registerConfig); - HotSpotFrameContext frameContext = omitFrame ? null : new HotSpotFrameContext(); - TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext); + HotSpotFrameContext frameContext = new HotSpotFrameContext(); + TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, compilationResult); tasm.setFrameSize(frameMap.frameSize()); - tasm.compilationResult.setCustomStackAreaOffset(frameMap.offsetToCustomArea()); return tasm; } @Override - public void emitCode(TargetMethodAssembler tasm, ResolvedJavaMethod method, LIR lir) { + public void emitCode(TargetMethodAssembler tasm, ResolvedJavaMethod method, LIRGenerator lirGen) { // Emit the prologue final String name = method.getName(); Buffer codeBuffer = tasm.asm.codeBuffer; @@ -103,7 +99,7 @@ codeBuffer.emitString(" .reg .u32 %r<16>;"); // Emit code for the LIR - lir.emitCode(tasm); + lirGen.lir.emitCode(tasm); // Emit the epilogue codeBuffer.emitString0("}"); diff -r b2f88686f68b -r 5284877c419d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Thu Mar 14 19:20:43 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri Mar 15 02:18:15 2013 +0100 @@ -51,9 +51,10 @@ final StructuredGraph graph, final GraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts, final SpeculationLog speculationLog) { assert (method.getModifiers() & Modifier.NATIVE) == 0 : "compiling native methods is not supported"; - return Debug.scope("GraalCompiler", new Object[]{graph, method, runtime}, new Callable() { + final CompilationResult compilationResult = new CompilationResult(); + Debug.scope("GraalCompiler", new Object[]{graph, method, runtime}, new Runnable() { - public CompilationResult call() { + public void run() { final Assumptions assumptions = new Assumptions(GraalOptions.OptAssumptions); final LIR lir = Debug.scope("FrontEnd", new Callable() { @@ -61,21 +62,23 @@ return emitHIR(runtime, target, graph, assumptions, cache, plan, optimisticOpts, speculationLog); } }); - final FrameMap frameMap = Debug.scope("BackEnd", lir, new Callable() { + final LIRGenerator lirGen = Debug.scope("BackEnd", lir, new Callable() { - public FrameMap call() { + public LIRGenerator call() { return emitLIR(backend, target, lir, graph, method); } }); - return Debug.scope("CodeGen", frameMap, new Callable() { + Debug.scope("CodeGen", lirGen, new Runnable() { - public CompilationResult call() { - return emitCode(backend, getLeafGraphIdArray(graph), assumptions, method, lir, frameMap); + public void run() { + emitCode(backend, getLeafGraphIdArray(graph), assumptions, method, lirGen, compilationResult); } }); } }); + + return compilationResult; } private static long[] getLeafGraphIdArray(StructuredGraph graph) { @@ -233,11 +236,11 @@ } - public static FrameMap emitLIR(Backend backend, final TargetDescription target, final LIR lir, StructuredGraph graph, final ResolvedJavaMethod method) { + public static LIRGenerator emitLIR(Backend backend, final TargetDescription target, final LIR lir, StructuredGraph graph, final ResolvedJavaMethod method) { final FrameMap frameMap = backend.newFrameMap(); - final LIRGenerator lirGenerator = backend.newLIRGenerator(graph, frameMap, method, lir); + final LIRGenerator lirGen = backend.newLIRGenerator(graph, frameMap, method, lir); - Debug.scope("LIRGen", lirGenerator, new Runnable() { + Debug.scope("LIRGen", lirGen, new Runnable() { public void run() { for (Block b : lir.linearScanOrder()) { @@ -254,23 +257,25 @@ emitBlock(pred); } } - lirGenerator.doBlock(b); + lirGen.doBlock(b); } } }); + lirGen.beforeRegisterAllocation(); + Debug.scope("Allocator", new Runnable() { public void run() { - new LinearScan(target, method, lir, lirGenerator, frameMap).allocate(); + new LinearScan(target, method, lir, lirGen, frameMap).allocate(); } }); - return frameMap; + return lirGen; } - public static CompilationResult emitCode(Backend backend, long[] leafGraphIds, Assumptions assumptions, ResolvedJavaMethod method, LIR lir, FrameMap frameMap) { - TargetMethodAssembler tasm = backend.newAssembler(frameMap, lir); - backend.emitCode(tasm, method, lir); + public static void emitCode(Backend backend, long[] leafGraphIds, Assumptions assumptions, ResolvedJavaMethod method, LIRGenerator lirGen, CompilationResult compilationResult) { + TargetMethodAssembler tasm = backend.newAssembler(lirGen, compilationResult); + backend.emitCode(tasm, method, lirGen); CompilationResult result = tasm.finishTargetMethod(method, false); if (!assumptions.isEmpty()) { result.setAssumptions(assumptions); @@ -278,6 +283,5 @@ result.setLeafGraphIds(leafGraphIds); Debug.dump(result, "After code generation"); - return result; } } diff -r b2f88686f68b -r 5284877c419d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Thu Mar 14 19:20:43 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri Mar 15 02:18:15 2013 +0100 @@ -54,14 +54,15 @@ */ public abstract class LIRGenerator extends LIRGeneratorTool { + public final FrameMap frameMap; + public final NodeMap nodeOperands; + public final LIR lir; + protected final StructuredGraph graph; protected final CodeCacheProvider runtime; protected final TargetDescription target; protected final ResolvedJavaMethod method; - protected final FrameMap frameMap; - public final NodeMap nodeOperands; - protected final LIR lir; private final DebugInfoBuilder debugInfoBuilder; private Block currentBlock; diff -r b2f88686f68b -r 5284877c419d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Thu Mar 14 19:20:43 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Fri Mar 15 02:18:15 2013 +0100 @@ -52,16 +52,13 @@ public abstract LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, ResolvedJavaMethod method, LIR lir); - public abstract TargetMethodAssembler newAssembler(FrameMap frameMap, LIR lir); + public abstract TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult); /** * Emits the code for a given method. This includes any architecture/runtime specific * prefix/suffix. A prefix typically contains the code for setting up the frame, spilling * callee-save registers, stack overflow checking, handling multiple entry points etc. A suffix * may contain out-of-line stubs and method end guard instructions. - * - * @param method the method associated with {@code lir} - * @param lir the LIR of {@code method} */ - public abstract void emitCode(TargetMethodAssembler tasm, ResolvedJavaMethod method, LIR lir); + public abstract void emitCode(TargetMethodAssembler tasm, ResolvedJavaMethod method, LIRGenerator lirGen); } diff -r b2f88686f68b -r 5284877c419d graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Thu Mar 14 19:20:43 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Fri Mar 15 02:18:15 2013 +0100 @@ -187,6 +187,20 @@ public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason) { append(new AMD64DeoptimizeOp(action, reason, state(reason))); } + + /** + * The slot reserved for storing the original return address when a frame is marked for + * deoptimization. The return address slot in the callee is overwritten with the address of + * a deoptimization stub. + */ + StackSlot deoptimizationRescueSlot; + + @Override + public void beforeRegisterAllocation() { + if (lir.hasDebugInfo()) { + deoptimizationRescueSlot = frameMap.allocateSpillSlot(Kind.Long); + } + } } /** @@ -259,25 +273,30 @@ } @Override - public TargetMethodAssembler newAssembler(FrameMap frameMap, LIR lir) { + public TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult) { // Omit the frame if the method: // - has no spill slots or other slots allocated during register allocation // - has no callee-saved registers // - has no incoming arguments passed on the stack // - has no instructions with debug info + FrameMap frameMap = lirGen.frameMap; + LIR lir = lirGen.lir; boolean omitFrame = GraalOptions.CanOmitFrame && frameMap.frameSize() == frameMap.initialFrameSize && frameMap.registerConfig.getCalleeSaveLayout().registers.length == 0 && !lir.hasArgInCallerFrame() && !lir.hasDebugInfo(); AbstractAssembler masm = new AMD64MacroAssembler(target, frameMap.registerConfig); HotSpotFrameContext frameContext = omitFrame ? null : new HotSpotFrameContext(); - TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext); + TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, compilationResult); tasm.setFrameSize(frameMap.frameSize()); - tasm.compilationResult.setCustomStackAreaOffset(frameMap.offsetToCustomArea()); + StackSlot deoptimizationRescueSlot = ((HotSpotAMD64LIRGenerator) lirGen).deoptimizationRescueSlot; + if (deoptimizationRescueSlot != null) { + tasm.compilationResult.setCustomStackAreaOffset(frameMap.offsetForStackSlot(deoptimizationRescueSlot)); + } return tasm; } @Override - public void emitCode(TargetMethodAssembler tasm, ResolvedJavaMethod method, LIR lir) { + public void emitCode(TargetMethodAssembler tasm, ResolvedJavaMethod method, LIRGenerator lirGen) { AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm; FrameMap frameMap = tasm.frameMap; RegisterConfig regConfig = frameMap.registerConfig; @@ -304,7 +323,7 @@ tasm.recordMark(Marks.MARK_VERIFIED_ENTRY); // Emit code for the LIR - lir.emitCode(tasm); + lirGen.lir.emitCode(tasm); boolean frameOmitted = tasm.frameContext == null; if (!frameOmitted) { @@ -316,7 +335,7 @@ } else { // No need to emit the stubs for entries back into the method since // it has no calls that can cause such "return" entries - assert !frameMap.accessesCallerFrame(); + assert !frameMap.accessesCallerFrame() : method; } if (unverifiedStub != null) { diff -r b2f88686f68b -r 5284877c419d graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Thu Mar 14 19:20:43 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Fri Mar 15 02:18:15 2013 +0100 @@ -47,13 +47,13 @@ } @Override - public TargetMethodAssembler newAssembler(FrameMap frameMap, LIR lir) { + public TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult) { // SPARC: Create assembler. return null; } @Override - public void emitCode(TargetMethodAssembler tasm, ResolvedJavaMethod method, LIR lir) { + public void emitCode(TargetMethodAssembler tasm, ResolvedJavaMethod method, LIRGenerator lirGen) { // SPARC: Emit code } } diff -r b2f88686f68b -r 5284877c419d graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Thu Mar 14 19:20:43 2013 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Fri Mar 15 02:18:15 2013 +0100 @@ -70,17 +70,11 @@ * The spill slot area also includes stack allocated memory blocks (ALLOCA blocks). The size of such * a block may be greater than the size of a normal spill slot or the word size. *

- * A runtime has two ways to reserve space in the stack frame for its own use: - *

    - *
  • A memory block somewhere in the frame of size - * {@link CodeCacheProvider#getCustomStackAreaSize()}. The offset to this block is returned in - * {@link CompilationResult#getCustomStackAreaOffset()}. - *
  • At the beginning of the overflow argument area: The calling convention can specify that the - * first overflow stack argument is not at offset 0, but at a specified offset o. Use - * {@link CodeCacheProvider#getMinimumOutgoingSize()} to make sure that call-free methods also have - * this space reserved. Then the VM can use memory the memory at offset 0 relative to the stack - * pointer. - *
+ * A runtime can reserve space at the beginning of the overflow argument area. The calling + * convention can specify that the first overflow stack argument is not at offset 0, but at a + * specified offset. Use {@link CodeCacheProvider#getMinimumOutgoingSize()} to make sure that + * call-free methods also have this space reserved. Then the VM can use the memory at offset 0 + * relative to the stack pointer. */ public final class FrameMap { @@ -117,12 +111,6 @@ private final List objectStackBlocks; /** - * The stack area reserved for use by the VM, or {@code null} if the VM does not request stack - * space. - */ - private final StackSlot customArea; - - /** * Records whether an offset to an incoming stack argument was ever returned by * {@link #offsetForStackSlot(StackSlot)}. */ @@ -139,7 +127,6 @@ this.spillSize = returnAddressSize() + calleeSaveAreaSize(); this.outgoingSize = runtime.getMinimumOutgoingSize(); this.objectStackBlocks = new ArrayList<>(); - this.customArea = allocateStackBlock(runtime.getCustomStackAreaSize(), false); this.initialFrameSize = currentFrameSize(); } @@ -223,16 +210,6 @@ } /** - * Gets the offset of the stack area stack block reserved for use by the VM, or -1 if the VM - * does not request stack space. - * - * @return The offset to the custom area (in bytes). - */ - public int offsetToCustomArea() { - return customArea == null ? -1 : offsetForStackSlot(customArea); - } - - /** * Informs the frame map that the compiled code calls a particular method, which may need stack * space for outgoing arguments. * diff -r b2f88686f68b -r 5284877c419d graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java Thu Mar 14 19:20:43 2013 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java Fri Mar 15 02:18:15 2013 +0100 @@ -60,12 +60,12 @@ private List exceptionInfoList; - public TargetMethodAssembler(TargetDescription target, CodeCacheProvider runtime, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext) { + public TargetMethodAssembler(TargetDescription target, CodeCacheProvider runtime, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext, CompilationResult compilationResult) { this.target = target; this.runtime = runtime; this.frameMap = frameMap; this.asm = asm; - this.compilationResult = new CompilationResult(); + this.compilationResult = compilationResult; this.frameContext = frameContext; } diff -r b2f88686f68b -r 5284877c419d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Thu Mar 14 19:20:43 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Fri Mar 15 02:18:15 2013 +0100 @@ -134,4 +134,10 @@ public abstract void visitBreakpointNode(BreakpointNode i); public abstract void emitUnwind(Value operand); + + /** + * Called just before register allocation is performed on the LIR owned by this generator. + */ + public void beforeRegisterAllocation() { + } } diff -r b2f88686f68b -r 5284877c419d graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Thu Mar 14 19:20:43 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Fri Mar 15 02:18:15 2013 +0100 @@ -189,7 +189,7 @@ return prefix; } - if (!specialization.getNode().getGenericSpecialization().isUseSpecializationsForGeneric() || !specialization.getNode().needsRewrites(context)) { + if (!specialization.getNode().needsRewrites(context)) { return prefix; } @@ -939,7 +939,7 @@ private List createGeneratedGenericMethod(NodeData node) { TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getActualType(); - if (node.getGenericSpecialization().isUseSpecializationsForGeneric() && node.needsRewrites(context)) { + if (node.needsRewrites(context)) { List methods = new ArrayList<>(); List specializations = node.getSpecializations(); @@ -1219,7 +1219,14 @@ if (specialization.getMethod() == null && !node.needsRewrites(context)) { emitEncounteredSynthetic(builder); } else if (specialization.isUninitialized() || specialization.isGeneric()) { - builder.startReturn().startCall(factoryClassName(node), generatedGenericMethodName(null)); + String genericMethodName; + if (!specialization.isUseSpecializationsForGeneric()) { + genericMethodName = generatedGenericMethodName(specialization); + } else { + genericMethodName = generatedGenericMethodName(null); + } + + builder.startReturn().startCall(factoryClassName(node), genericMethodName); builder.string("this"); addValueParameterNames(builder, specialization, null, true, true); builder.end().end(); diff -r b2f88686f68b -r 5284877c419d graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java Thu Mar 14 19:20:43 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java Fri Mar 15 02:18:15 2013 +0100 @@ -211,8 +211,16 @@ public ExecutableTypeData findAnyGenericExecutableType(ProcessorContext context) { List types = findGenericExecutableTypes(context); - if (!types.isEmpty()) { - return types.get(0); + for (ExecutableTypeData type : types) { + if (type.getType().isGeneric()) { + return type; + } + } + + for (ExecutableTypeData type : types) { + if (!type.getType().isVoid()) { + return type; + } } return null; } diff -r b2f88686f68b -r 5284877c419d graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java Thu Mar 14 19:20:43 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java Fri Mar 15 02:18:15 2013 +0100 @@ -110,6 +110,14 @@ valid = false; } } + Collections.sort(parsedMethods, new Comparator() { + + @Override + public int compare(TemplateMethod o1, TemplateMethod o2) { + return o1.getMethodName().compareTo(o2.getMethodName()); + } + }); + if (!valid && parseNullOnError) { return null; } diff -r b2f88686f68b -r 5284877c419d graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WriteLocalNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WriteLocalNode.java Thu Mar 14 19:20:43 2013 +0100 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WriteLocalNode.java Fri Mar 15 02:18:15 2013 +0100 @@ -64,7 +64,7 @@ return right; } - @Generic + @Generic(useSpecializations = false) public Object writeGeneric(VirtualFrame frame, Object right) { frame.setObject(slot, right); return right; diff -r b2f88686f68b -r 5284877c419d make/windows/makefiles/projectcreator.make --- a/make/windows/makefiles/projectcreator.make Thu Mar 14 19:20:43 2013 +0100 +++ b/make/windows/makefiles/projectcreator.make Fri Mar 15 02:18:15 2013 +0100 @@ -176,8 +176,9 @@ ################################################## ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \ -define_compiler1 COMPILER1 \ + -define_compiler1 GRAAL \ -ignorePath_compiler1 core \ - $(ProjectCreatorIDEOptionsIgnoreGraal:TARGET=compiler1) \ + -ignorePath_compiler1 graal/generated \ $(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=compiler1) ################################################## @@ -196,6 +197,7 @@ ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \ -define_compiler2 COMPILER2 \ -define_compiler2 GRAAL \ + -define_compiler2 TIERED \ -ignorePath_compiler2 core \ -ignorePath_compiler2 graal/generated \ -additionalFile_compiler2 $(Platform_arch_model).ad \