Mercurial > hg > graal-compiler
changeset 8311:5663e3c7eabe
Merge.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Fri, 15 Mar 2013 21:18:47 +0100 |
parents | 89006c76f737 (current diff) 5115f468f8a4 (diff) |
children | b1dff27a1da6 |
files | graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64DeoptimizationStub.java graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXDeoptimizationStub.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/snippets/AMD64ConvertSnippets.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Code.java graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXCode.java |
diffstat | 48 files changed, 1078 insertions(+), 954 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java Fri Mar 15 21:18:47 2013 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.api.code; +import static com.oracle.graal.api.meta.MetaUtil.*; + import java.util.*; import com.oracle.graal.api.meta.*; @@ -65,31 +67,48 @@ this.id = id; } + private static StringBuilder appendValue(StringBuilder buf, Value value, Set<VirtualObject> visited) { + if (value instanceof VirtualObject) { + VirtualObject vo = (VirtualObject) value; + buf.append("vobject:").append(toJavaName(vo.type, false)).append(':').append(vo.id); + if (!visited.contains(vo)) { + visited.add(vo); + buf.append('{'); + if (vo.values == null) { + buf.append("<uninitialized>"); + } else { + if (vo.type.isArray()) { + for (int i = 0; i < vo.values.length; i++) { + if (i != 0) { + buf.append(','); + } + buf.append(i).append('='); + appendValue(buf, vo.values[i], visited); + } + } else { + ResolvedJavaField[] fields = vo.type.getInstanceFields(true); + assert fields.length == vo.values.length : vo.type + ", fields=" + Arrays.toString(fields) + ", values=" + vo.values; + for (int i = 0; i < vo.values.length; i++) { + if (i != 0) { + buf.append(','); + } + buf.append(fields[i].getName()).append('='); + appendValue(buf, vo.values[i], visited); + } + } + } + buf.append('}'); + } + } else { + buf.append(value); + } + return buf; + } + @Override public String toString() { - StringBuilder buf = new StringBuilder("vobject:").append(MetaUtil.toJavaName(type, false)).append(':').append(id).append('{'); - if (values == null) { - buf.append("<uninitialized>"); - } else { - if (type.isArray()) { - for (int i = 0; i < values.length; i++) { - if (i != 0) { - buf.append(','); - } - buf.append(i).append('=').append(values[i]); - } - } else { - ResolvedJavaField[] fields = type.getInstanceFields(true); - assert fields.length == values.length : type + ", fields=" + Arrays.toString(fields) + ", values=" + values; - for (int i = 0; i < values.length; i++) { - if (i != 0) { - buf.append(','); - } - buf.append(fields[i].getName()).append('=').append(values[i]); - } - } - } - return buf.append('}').toString(); + Set<VirtualObject> visited = Collections.newSetFromMap(new IdentityHashMap<VirtualObject, Boolean>()); + return appendValue(new StringBuilder(), this, visited).toString(); } /**
--- a/graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/AMD64AllocatorTest.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.compiler.amd64.test/src/com/oracle/graal/compiler/amd64/test/AMD64AllocatorTest.java Fri Mar 15 21:18:47 2013 +0100 @@ -30,7 +30,7 @@ @Test public void test1() { - test("test1snippet", 2, 1, 0); + test("test1snippet", 3, 1, 0); } public static long test1snippet(long x) { @@ -39,7 +39,7 @@ @Test public void test2() { - test("test2snippet", 2, 0, 0); + test("test2snippet", 3, 0, 0); } public static long test2snippet(long x) {
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64DeoptimizationStub.java Fri Mar 15 21:18:33 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.compiler.amd64; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.RuntimeCallTarget.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.asm.*; -import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.amd64.*; -import com.oracle.graal.lir.asm.*; - -public class AMD64DeoptimizationStub extends AMD64Code { - - public static final Descriptor DEOPTIMIZE = new Descriptor("deoptimize", true, void.class); - - public final Label label = new Label(); - public final LIRFrameState info; - public final DeoptimizationAction action; - public final DeoptimizationReason reason; - - public AMD64DeoptimizationStub(DeoptimizationAction action, DeoptimizationReason reason, LIRFrameState info) { - this.action = action; - this.reason = reason; - this.info = info; - } - - @Override - public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - Register scratch = tasm.frameMap.registerConfig.getScratchRegister(); - masm.bind(label); - masm.movl(scratch, tasm.runtime.encodeDeoptActionAndReason(action, reason)); - AMD64Call.directCall(tasm, masm, tasm.runtime.lookupRuntimeCall(DEOPTIMIZE), info); - } - - @Override - public String description() { - return "deopt stub[reason=" + reason + ", action=" + action + "]"; - } -}
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Mar 15 21:18:47 2013 +0100 @@ -67,7 +67,6 @@ import com.oracle.graal.lir.amd64.AMD64Move.MembarOp; import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp; import com.oracle.graal.lir.amd64.AMD64Move.MoveToRegOp; -import com.oracle.graal.lir.amd64.AMD64Move.NullCheckOp; import com.oracle.graal.lir.amd64.AMD64Move.StackLeaOp; import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp; import com.oracle.graal.lir.amd64.AMD64Move.StoreOp; @@ -255,23 +254,23 @@ } @Override - public void emitJump(LabelRef label, LIRFrameState info) { - append(new JumpOp(label, info)); + public void emitJump(LabelRef label) { + append(new JumpOp(label)); } @Override - public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label, LIRFrameState info) { + public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label) { boolean mirrored = emitCompare(left, right); Condition finalCondition = mirrored ? cond.mirror() : cond; switch (left.getKind().getStackKind()) { case Int: case Long: case Object: - append(new BranchOp(finalCondition, label, info)); + append(new BranchOp(finalCondition, label)); break; case Float: case Double: - append(new FloatBranchOp(finalCondition, unorderedIsTrue, label, info)); + append(new FloatBranchOp(finalCondition, unorderedIsTrue, label)); break; default: throw GraalInternalError.shouldNotReachHere("" + left.getKind()); @@ -279,14 +278,14 @@ } @Override - public void emitOverflowCheckBranch(LabelRef destination, LIRFrameState info, boolean negated) { - append(new BranchOp(negated ? ConditionFlag.NoOverflow : ConditionFlag.Overflow, destination, info)); + public void emitOverflowCheckBranch(LabelRef destination, boolean negated) { + append(new BranchOp(negated ? ConditionFlag.NoOverflow : ConditionFlag.Overflow, destination)); } @Override - public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label, LIRFrameState info) { + public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label) { emitIntegerTest(left, right); - append(new BranchOp(negated ? Condition.NE : Condition.EQ, label, info)); + append(new BranchOp(negated ? Condition.NE : Condition.EQ, label)); } @Override @@ -773,13 +772,6 @@ } @Override - public void emitDeoptimizeOnOverflow(DeoptimizationAction action, DeoptimizationReason reason) { - LIRFrameState info = state(reason); - LabelRef stubEntry = createDeoptStub(action, reason, info); - append(new BranchOp(ConditionFlag.Overflow, stubEntry, info)); - } - - @Override public void emitMembar(int barriers) { int necessaryBarriers = target.arch.requiredBarriers(barriers); if (target.isMP && necessaryBarriers != 0) { @@ -899,29 +891,6 @@ } @Override - protected LabelRef createDeoptStub(DeoptimizationAction action, DeoptimizationReason reason, LIRFrameState info) { - assert info.topFrame.getBCI() >= 0 : "invalid bci for deopt framestate"; - AMD64DeoptimizationStub stub = new AMD64DeoptimizationStub(action, reason, info); - lir.stubs.add(stub); - return LabelRef.forLabel(stub.label); - } - - @Override - public void emitGuardCheck(LogicNode comp, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) { - if (comp instanceof IsNullNode && negated) { - emitNullCheckGuard(((IsNullNode) comp).object()); - } else { - super.emitGuardCheck(comp, deoptReason, action, negated); - } - } - - private void emitNullCheckGuard(ValueNode object) { - Variable value = load(operand(object)); - LIRFrameState info = state(); - append(new NullCheckOp(value, info)); - } - - @Override public void visitCompareAndSwap(CompareAndSwapNode node) { Kind kind = node.newValue().kind(); assert kind == node.expected().kind();
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java Fri Mar 15 21:18:47 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("}");
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXDeoptimizationStub.java Fri Mar 15 21:18:33 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * 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.compiler.ptx; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.RuntimeCallTarget.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.asm.*; -import com.oracle.graal.asm.ptx.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.ptx.*; -import com.oracle.graal.lir.asm.*; - -public class PTXDeoptimizationStub extends PTXCode { - - public static final Descriptor DEOPTIMIZE = new Descriptor("deoptimize", true, void.class); - public static final Descriptor SET_DEOPT_INFO = new Descriptor("setDeoptInfo", true, void.class, Object.class); - - public final Label label = new Label(); - public final LIRFrameState info; - public final DeoptimizationAction action; - public final DeoptimizationReason reason; - - public PTXDeoptimizationStub(DeoptimizationAction action, DeoptimizationReason reason, LIRFrameState info) { - this.action = action; - this.reason = reason; - this.info = info; - } - - @Override - public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) { - masm.exit(); - } - - @Override - public String description() { - return "deopt stub[reason=" + reason + ", action=" + action + "]"; - } -}
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Fri Mar 15 21:18:47 2013 +0100 @@ -179,20 +179,20 @@ } @Override - public void emitJump(LabelRef label, LIRFrameState info) { - append(new JumpOp(label, info)); + public void emitJump(LabelRef label) { + append(new JumpOp(label)); } @Override - public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label, LIRFrameState info) { + public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label) { switch (left.getKind().getStackKind()) { case Int: append(new CompareOp(ICMP, cond, left, right)); - append(new BranchOp(cond, label, info)); + append(new BranchOp(cond, label)); break; case Object: append(new CompareOp(ACMP, cond, left, right)); - append(new BranchOp(cond, label, info)); + append(new BranchOp(cond, label)); break; default: throw GraalInternalError.shouldNotReachHere("" + left.getKind()); @@ -200,12 +200,12 @@ } @Override - public void emitOverflowCheckBranch(LabelRef label, LIRFrameState info, boolean negated) { + public void emitOverflowCheckBranch(LabelRef label, boolean negated) { throw new InternalError("NYI"); } @Override - public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label, LIRFrameState info) { + public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label) { throw new InternalError("NYI"); } @@ -349,11 +349,6 @@ } @Override - public void emitDeoptimizeOnOverflow(DeoptimizationAction action, DeoptimizationReason reason) { - throw new InternalError("NYI"); - } - - @Override public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason) { append(new ReturnOp(Value.ILLEGAL)); } @@ -453,14 +448,6 @@ } @Override - protected LabelRef createDeoptStub(DeoptimizationAction action, DeoptimizationReason reason, LIRFrameState info) { - assert info.topFrame.getBCI() >= 0 : "invalid bci for deopt framestate"; - PTXDeoptimizationStub stub = new PTXDeoptimizationStub(action, reason, info); - lir.stubs.add(stub); - return LabelRef.forLabel(stub.label); - } - - @Override public void visitCompareAndSwap(CompareAndSwapNode node) { throw new InternalError("NYI"); }
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Fri Mar 15 21:18:47 2013 +0100 @@ -62,7 +62,7 @@ } @Override - public void emitJump(LabelRef label, LIRFrameState info) { + public void emitJump(LabelRef label) { @SuppressWarnings("unused") SPARCLIRInstruction instruction = null; // SPARC: Auto-generated method stub @@ -70,19 +70,19 @@ } @Override - public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label, LIRFrameState info) { + public void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label) { // SPARC: Auto-generated method stub } @Override - public void emitOverflowCheckBranch(LabelRef label, LIRFrameState info, boolean negated) { + public void emitOverflowCheckBranch(LabelRef label, boolean negated) { // SPARC: Auto-generated method stub } @Override - public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label, LIRFrameState info) { + public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label) { // SPARC: Auto-generated method stub } @@ -118,12 +118,6 @@ } @Override - protected LabelRef createDeoptStub(DeoptimizationAction action, DeoptimizationReason reason, LIRFrameState info) { - // SPARC: Auto-generated method stub - return null; - } - - @Override protected void emitSequentialSwitch(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) { // SPARC: Auto-generated method stub @@ -340,12 +334,6 @@ } @Override - public void emitDeoptimizeOnOverflow(DeoptimizationAction action, DeoptimizationReason reason) { - // SPARC: Auto-generated method stub - - } - - @Override public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason) { // SPARC: Auto-generated method stub
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri Mar 15 21:18:47 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<CompilationResult>() { + 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<LIR>() { @@ -61,21 +62,23 @@ return emitHIR(runtime, target, graph, assumptions, cache, plan, optimisticOpts, speculationLog); } }); - final FrameMap frameMap = Debug.scope("BackEnd", lir, new Callable<FrameMap>() { + final LIRGenerator lirGen = Debug.scope("BackEnd", lir, new Callable<LIRGenerator>() { - public FrameMap call() { + public LIRGenerator call() { return emitLIR(backend, target, lir, graph, method); } }); - return Debug.scope("CodeGen", frameMap, new Callable<CompilationResult>() { + 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) { @@ -201,7 +204,7 @@ plan.runPhases(PhasePosition.LOW_LEVEL, graph); - new GuardLoweringPhase().apply(graph); + new GuardLoweringPhase(target).apply(graph); // Add safepoints to loops new SafepointInsertionPhase().apply(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; } }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri Mar 15 21:18:47 2013 +0100 @@ -54,17 +54,18 @@ */ public abstract class LIRGenerator extends LIRGeneratorTool { + public final FrameMap frameMap; + public final NodeMap<Value> 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<Value> nodeOperands; - protected final LIR lir; private final DebugInfoBuilder debugInfoBuilder; - private Block currentBlock; + protected Block currentBlock; private ValueNode currentInstruction; private ValueNode lastInstructionPrinted; // Debugging only private FrameState lastState; @@ -349,27 +350,6 @@ List<ScheduledNode> nodes = lir.nodesFor(block); for (int i = 0; i < nodes.size(); i++) { Node instr = nodes.get(i); - - if (GraalOptions.OptImplicitNullChecks) { - Node nextInstr = null; - if (i < nodes.size() - 1) { - nextInstr = nodes.get(i + 1); - } - - if (instr instanceof GuardNode) { - GuardNode guardNode = (GuardNode) instr; - if (guardNode.condition() instanceof IsNullNode && guardNode.negated()) { - IsNullNode isNullNode = (IsNullNode) guardNode.condition(); - if (nextInstr instanceof Access) { - Access access = (Access) nextInstr; - if (isNullNode.object() == access.object() && canBeNullCheck(access.location())) { - access.setNullCheck(true); - continue; - } - } - } - } - } if (GraalOptions.TraceLIRGeneratorLevel >= 3) { TTY.println("LIRGen for " + instr); } @@ -410,7 +390,7 @@ NodeClassIterable successors = block.getEndNode().successors(); assert successors.isNotEmpty() : "should have at least one successor : " + block.getEndNode(); - emitJump(getLIRBlock((FixedNode) successors.first()), null); + emitJump(getLIRBlock((FixedNode) successors.first())); } if (GraalOptions.TraceLIRGeneratorLevel >= 1) { @@ -469,10 +449,6 @@ ((LIRLowerable) node).generate(this); } - private boolean canBeNullCheck(LocationNode location) { - return !(location instanceof IndexedLocationNode) && location.displacement() < this.target().implicitNullCheckLimit; - } - protected CallingConvention createCallingConvention() { return frameMap.registerConfig.getCallingConvention(JavaCallee, method.getSignature().getReturnType(null), MetaUtil.signatureToTypes(method), target, false); } @@ -571,7 +547,7 @@ } resolver.dispose(); - append(new JumpOp(getLIRBlock(merge), null)); + append(new JumpOp(getLIRBlock(merge))); } private Value operandForPhi(PhiNode phi) { @@ -589,89 +565,46 @@ @Override public void emitIf(IfNode x) { - emitBranch(x.condition(), getLIRBlock(x.trueSuccessor()), getLIRBlock(x.falseSuccessor()), null); + emitBranch(x.condition(), getLIRBlock(x.trueSuccessor()), getLIRBlock(x.falseSuccessor())); } - @Override - public void emitGuardCheck(LogicNode comp, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) { - if (comp instanceof LogicConstantNode && ((LogicConstantNode) comp).getValue() != negated) { - // True constant, nothing to emit. - // False constants are handled within emitBranch. - } else { - // Fall back to a normal branch. - LIRFrameState info = state(deoptReason); - LabelRef stubEntry = createDeoptStub(action, deoptReason, info); - if (negated) { - emitBranch(comp, stubEntry, null, info); - } else { - emitBranch(comp, null, stubEntry, info); - } - } - } - - public void emitBranch(LogicNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRFrameState info) { + public void emitBranch(LogicNode node, LabelRef trueSuccessor, LabelRef falseSuccessor) { if (node instanceof IsNullNode) { - emitNullCheckBranch((IsNullNode) node, trueSuccessor, falseSuccessor, info); + emitNullCheckBranch((IsNullNode) node, trueSuccessor, falseSuccessor); } else if (node instanceof CompareNode) { - emitCompareBranch((CompareNode) node, trueSuccessor, falseSuccessor, info); + emitCompareBranch((CompareNode) node, trueSuccessor, falseSuccessor); } else if (node instanceof LogicConstantNode) { - emitConstantBranch(((LogicConstantNode) node).getValue(), trueSuccessor, falseSuccessor, info); + emitConstantBranch(((LogicConstantNode) node).getValue(), trueSuccessor, falseSuccessor); } else if (node instanceof IntegerTestNode) { - emitIntegerTestBranch((IntegerTestNode) node, trueSuccessor, falseSuccessor, info); + emitIntegerTestBranch((IntegerTestNode) node, trueSuccessor, falseSuccessor); } else { throw GraalInternalError.unimplemented(node.toString()); } } - private void emitNullCheckBranch(IsNullNode node, LabelRef trueSuccessor, LabelRef falseSuccessor, LIRFrameState info) { - if (falseSuccessor != null) { - emitCompareBranch(operand(node.object()), Constant.NULL_OBJECT, Condition.NE, false, falseSuccessor, info); - if (trueSuccessor != null) { - emitJump(trueSuccessor, null); - } - } else { - emitCompareBranch(operand(node.object()), Constant.NULL_OBJECT, Condition.EQ, false, trueSuccessor, info); - } + private void emitNullCheckBranch(IsNullNode node, LabelRef trueSuccessor, LabelRef falseSuccessor) { + emitCompareBranch(operand(node.object()), Constant.NULL_OBJECT, Condition.NE, false, falseSuccessor); + emitJump(trueSuccessor); } - public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessorBlock, LabelRef falseSuccessorBlock, LIRFrameState info) { - if (falseSuccessorBlock != null) { - emitCompareBranch(operand(compare.x()), operand(compare.y()), compare.condition().negate(), !compare.unorderedIsTrue(), falseSuccessorBlock, info); - if (trueSuccessorBlock != null) { - emitJump(trueSuccessorBlock, null); - } - } else { - emitCompareBranch(operand(compare.x()), operand(compare.y()), compare.condition(), compare.unorderedIsTrue(), trueSuccessorBlock, info); - } + public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessorBlock, LabelRef falseSuccessorBlock) { + emitCompareBranch(operand(compare.x()), operand(compare.y()), compare.condition().negate(), !compare.unorderedIsTrue(), falseSuccessorBlock); + emitJump(trueSuccessorBlock); } - public void emitOverflowCheckBranch(LabelRef noOverflowBlock, LabelRef overflowBlock, LIRFrameState info) { - if (overflowBlock != null) { - emitOverflowCheckBranch(overflowBlock, info, false); - if (noOverflowBlock != null) { - emitJump(noOverflowBlock, null); - } - } else { - emitOverflowCheckBranch(noOverflowBlock, info, true); - } + public void emitOverflowCheckBranch(LabelRef noOverflowBlock, LabelRef overflowBlock) { + emitOverflowCheckBranch(overflowBlock, false); + emitJump(noOverflowBlock); } - public void emitIntegerTestBranch(IntegerTestNode test, LabelRef trueSuccessorBlock, LabelRef falseSuccessorBlock, LIRFrameState info) { - if (falseSuccessorBlock != null) { - emitIntegerTestBranch(operand(test.x()), operand(test.y()), true, falseSuccessorBlock, info); - if (trueSuccessorBlock != null) { - emitJump(trueSuccessorBlock, null); - } - } else { - emitIntegerTestBranch(operand(test.x()), operand(test.y()), false, trueSuccessorBlock, info); - } + public void emitIntegerTestBranch(IntegerTestNode test, LabelRef trueSuccessorBlock, LabelRef falseSuccessorBlock) { + emitIntegerTestBranch(operand(test.x()), operand(test.y()), true, falseSuccessorBlock); + emitJump(trueSuccessorBlock); } - public void emitConstantBranch(boolean value, LabelRef trueSuccessorBlock, LabelRef falseSuccessorBlock, LIRFrameState info) { + public void emitConstantBranch(boolean value, LabelRef trueSuccessorBlock, LabelRef falseSuccessorBlock) { LabelRef block = value ? trueSuccessorBlock : falseSuccessorBlock; - if (block != null) { - emitJump(block, info); - } + emitJump(block); } @Override @@ -698,13 +631,13 @@ } } - public abstract void emitJump(LabelRef label, LIRFrameState info); + public abstract void emitJump(LabelRef label); - public abstract void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label, LIRFrameState info); + public abstract void emitCompareBranch(Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef label); - public abstract void emitOverflowCheckBranch(LabelRef label, LIRFrameState info, boolean negated); + public abstract void emitOverflowCheckBranch(LabelRef label, boolean negated); - public abstract void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label, LIRFrameState info); + public abstract void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label); public abstract Variable emitConditionalMove(Value leftVal, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue); @@ -744,7 +677,7 @@ protected abstract void emitCall(RuntimeCallTarget callTarget, Value result, Value[] arguments, Value[] temps, Value targetAddress, LIRFrameState info); - private static Value toStackKind(Value value) { + protected static Value toStackKind(Value value) { if (value.getKind().getStackKind() != value.getKind()) { // We only have stack-kinds in the LIR, so convert the operand kind for values from the // calling convention. @@ -776,8 +709,6 @@ return result; } - protected abstract LabelRef createDeoptStub(DeoptimizationAction action, DeoptimizationReason reason, LIRFrameState info); - @Override public Variable emitCall(RuntimeCallTarget callTarget, CallingConvention cc, boolean canTrap, Value... args) { LIRFrameState info = canTrap ? state() : null; @@ -846,7 +777,7 @@ public void emitSwitch(SwitchNode x) { int keyCount = x.keyCount(); if (keyCount == 0) { - emitJump(getLIRBlock(x.defaultSuccessor()), null); + emitJump(getLIRBlock(x.defaultSuccessor())); } else { Variable value = load(operand(x.value())); LabelRef defaultTarget = x.defaultSuccessor() == null ? null : getLIRBlock(x.defaultSuccessor()); @@ -858,7 +789,7 @@ long valueRange = x.keyAt(keyCount - 1).asLong() - x.keyAt(0).asLong() + 1; int switchRangeCount = switchRangeCount(x); if (switchRangeCount == 0) { - emitJump(getLIRBlock(x.defaultSuccessor()), null); + emitJump(getLIRBlock(x.defaultSuccessor())); } else if (switchRangeCount >= GraalOptions.MinimumJumpTableSize && keyCount / (double) valueRange >= GraalOptions.MinTableSwitchDensity) { int minValue = x.keyAt(0).asInt(); assert valueRange < Integer.MAX_VALUE;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Fri Mar 15 21:18:47 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); }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Fri Mar 15 21:18:47 2013 +0100 @@ -25,6 +25,7 @@ import static com.oracle.graal.amd64.AMD64.*; import static com.oracle.graal.api.code.CallingConvention.Type.*; import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.phases.GraalOptions.*; import java.lang.reflect.*; @@ -36,22 +37,15 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.asm.amd64.AMD64Address.Scale; import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; -import com.oracle.graal.compiler.amd64.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.nodes.*; -import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; -import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.phases.*; /** @@ -73,122 +67,6 @@ return new HotSpotAMD64LIRGenerator(graph, runtime(), target, frameMap, method, lir); } - static final class HotSpotAMD64LIRGenerator extends AMD64LIRGenerator implements HotSpotLIRGenerator { - - private HotSpotRuntime runtime() { - return (HotSpotRuntime) runtime; - } - - private HotSpotAMD64LIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) { - super(graph, runtime, target, frameMap, method, lir); - } - - @Override - protected boolean needOnlyOopMaps() { - // Stubs only need oop maps - return runtime().asStub(method) != null; - } - - @Override - protected CallingConvention createCallingConvention() { - Stub stub = runtime().asStub(method); - if (stub != null) { - return stub.getLinkage().getCallingConvention(); - } - - if (graph.getEntryBCI() == StructuredGraph.INVOCATION_ENTRY_BCI) { - return super.createCallingConvention(); - } else { - return frameMap.registerConfig.getCallingConvention(JavaCallee, method.getSignature().getReturnType(null), new JavaType[]{runtime.lookupJavaType(long.class)}, target, false); - } - } - - @Override - public void visitSafepointNode(SafepointNode i) { - LIRFrameState info = state(); - append(new AMD64SafepointOp(info, runtime().config, this)); - } - - @Override - public void visitExceptionObject(ExceptionObjectNode x) { - HotSpotVMConfig config = runtime().config; - RegisterValue thread = runtime().threadRegister().asValue(); - Value exception = emitLoad(Kind.Object, thread, config.threadExceptionOopOffset, Value.ILLEGAL, 0, false); - emitStore(Kind.Object, thread, config.threadExceptionOopOffset, Value.ILLEGAL, 0, Constant.NULL_OBJECT, false); - emitStore(Kind.Long, thread, config.threadExceptionPcOffset, Value.ILLEGAL, 0, Constant.LONG_0, false); - setResult(x, exception); - } - - @SuppressWarnings("hiding") - @Override - public void visitDirectCompareAndSwap(DirectCompareAndSwapNode x) { - Kind kind = x.newValue().kind(); - assert kind == x.expectedValue().kind(); - - Value expected = loadNonConst(operand(x.expectedValue())); - Variable newVal = load(operand(x.newValue())); - - int disp = 0; - AMD64AddressValue address; - Value index = operand(x.offset()); - if (ValueUtil.isConstant(index) && NumUtil.isInt(ValueUtil.asConstant(index).asLong() + disp)) { - assert !runtime.needsDataPatch(asConstant(index)); - disp += (int) ValueUtil.asConstant(index).asLong(); - address = new AMD64AddressValue(kind, load(operand(x.object())), disp); - } else { - address = new AMD64AddressValue(kind, load(operand(x.object())), load(index), Scale.Times1, disp); - } - - RegisterValue rax = AMD64.rax.asValue(kind); - emitMove(rax, expected); - append(new CompareAndSwapOp(rax, address, rax, newVal)); - - Variable result = newVariable(x.kind()); - emitMove(result, rax); - setResult(x, result); - } - - @Override - public void emitTailcall(Value[] args, Value address) { - append(new AMD64TailcallOp(args, address)); - - } - - @Override - protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { - InvokeKind invokeKind = ((HotSpotDirectCallTargetNode) callTarget).invokeKind(); - if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) { - append(new AMD64HotspotDirectVirtualCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind)); - } else { - assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special; - HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) callTarget.target(); - Constant metaspaceMethod = resolvedMethod.getMetaspaceMethodConstant(); - append(new AMD64HotspotDirectStaticCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind, metaspaceMethod)); - } - } - - @Override - protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { - Value metaspaceMethod = AMD64.rbx.asValue(); - emitMove(metaspaceMethod, operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod())); - Value targetAddress = AMD64.rax.asValue(); - emitMove(targetAddress, operand(callTarget.computedAddress())); - append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, temps, metaspaceMethod, targetAddress, callState)); - } - - @Override - public void emitUnwind(Value exception) { - RegisterValue exceptionParameter = AMD64.rax.asValue(); - emitMove(exceptionParameter, exception); - append(new AMD64HotSpotUnwindOp(exceptionParameter)); - } - - @Override - public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason) { - append(new AMD64DeoptimizeOp(action, reason, state(reason))); - } - } - /** * Emits code to do stack overflow checking. * @@ -224,8 +102,7 @@ AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm; emitStackOverflowCheck(tasm, false); - asm.push(rbp); - asm.decrementq(rsp, frameSize - 8); // account for the push of RBP above + asm.decrementq(rsp, frameSize); if (GraalOptions.ZapStackOnMethodEntry) { final int intSize = 4; for (int i = 0; i < frameSize / intSize; ++i) { @@ -253,31 +130,35 @@ asm.restore(csl, frameToCSA); } - asm.incrementq(rsp, frameSize - 8); // account for the pop of RBP below - asm.pop(rbp); + asm.incrementq(rsp, frameSize); } } @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(); + HotSpotAMD64LIRGenerator gen = (HotSpotAMD64LIRGenerator) lirGen; + FrameMap frameMap = gen.frameMap; + LIR lir = gen.lir; + boolean omitFrame = CanOmitFrame && !frameMap.frameNeedsAllocating() && !lir.hasArgInCallerFrame(); 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 = gen.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 +185,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 +197,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) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java Fri Mar 15 21:18:47 2013 +0100 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.amd64; + +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.amd64.*; + +/** + * Superclass for operations that use the value of RBP saved in a method's prologue. + */ +abstract class AMD64HotSpotEpilogueOp extends AMD64LIRInstruction { + + /** + * The type of location (i.e., stack or register) in which RBP is saved is not known until + * initial LIR generation is finished. Until then, we use a placeholder variable so that LIR + * verification is successful. + */ + private static final Variable PLACEHOLDER = new Variable(Kind.Long, Integer.MAX_VALUE, Register.RegisterFlag.CPU); + + @Use({REG, STACK}) protected AllocatableValue savedRbp = PLACEHOLDER; +}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Fri Mar 15 21:18:47 2013 +0100 @@ -111,12 +111,7 @@ }; csl = new CalleeSaveLayout(0, -1, 8, regs); } else { - // We reserve space for saving RBP but don't explicitly specify - // it as a callee save register since we explicitly do the saving - // with push and pop in HotSpotFrameContext - final int size = 8; - final Register[] regs = {}; - csl = new CalleeSaveLayout(0, size, 8, regs); + csl = null; } attributesMap = RegisterAttributes.createMap(this, AMD64.allRegisters);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java Fri Mar 15 21:18:47 2013 +0100 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.amd64; + +import static com.oracle.graal.amd64.AMD64.*; +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.asm.*; + +/** + * Performs an unwind to throw an exception. + */ +@Opcode("RETURN") +final class AMD64HotSpotReturnOp extends AMD64HotSpotEpilogueOp { + + @Use({REG, ILLEGAL}) protected Value value; + + AMD64HotSpotReturnOp(Value value) { + this.value = value; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + if (isStackSlot(savedRbp)) { + // Restoring RBP from the stack must be done before the frame is removed + masm.movq(rbp, (AMD64Address) tasm.asAddress(savedRbp)); + } else { + Register framePointer = asRegister(savedRbp); + if (framePointer != rbp) { + masm.movq(rbp, framePointer); + } + } + if (tasm.frameContext != null) { + tasm.frameContext.leave(tasm); + } + masm.ret(0); + } +}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Fri Mar 15 21:18:47 2013 +0100 @@ -25,6 +25,7 @@ import static com.oracle.graal.amd64.AMD64.*; import static com.oracle.graal.compiler.amd64.AMD64LIRGenerator.*; import static com.oracle.graal.hotspot.amd64.AMD64DeoptimizeOp.*; +import static com.oracle.graal.hotspot.amd64.AMD64HotSpotUnwindOp.*; import static com.oracle.graal.hotspot.nodes.IdentityHashCodeStubCall.*; import static com.oracle.graal.hotspot.nodes.MonitorEnterStubCall.*; import static com.oracle.graal.hotspot.nodes.MonitorExitStubCall.*; @@ -46,11 +47,11 @@ import com.oracle.graal.compiler.target.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.amd64.snippets.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.snippets.*; +import com.oracle.graal.snippets.amd64.*; public class AMD64HotSpotRuntime extends HotSpotRuntime { @@ -60,10 +61,10 @@ Kind word = graalRuntime.getTarget().wordKind; // @formatter:off - addRuntimeCall(AMD64HotSpotUnwindOp.UNWIND_EXCEPTION, config.unwindExceptionStub, - /* temps */ null, - /* ret */ ret(Kind.Void), - /* arg0: exception */ javaCallingConvention(Kind.Object)); + addRuntimeCall(UNWIND_EXCEPTION, config.unwindExceptionStub, + /* temps */ null, + /* ret */ ret(Kind.Void), + /* arg0: exception */ rax.asValue(Kind.Object)); addRuntimeCall(DEOPTIMIZE, config.deoptimizeStub, /* temps */ null,
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java Fri Mar 15 21:18:47 2013 +0100 @@ -23,11 +23,12 @@ package com.oracle.graal.hotspot.amd64; import static com.oracle.graal.amd64.AMD64.*; +import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import com.oracle.graal.amd64.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.RuntimeCallTarget.*; +import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.lir.LIRInstruction.Opcode; import com.oracle.graal.lir.amd64.*; @@ -36,24 +37,39 @@ /** * Performs an unwind to throw an exception. */ -@Opcode("CALL_INDIRECT") -final class AMD64HotSpotUnwindOp extends AMD64LIRInstruction { +@Opcode("UNWIND") +final class AMD64HotSpotUnwindOp extends AMD64HotSpotEpilogueOp { public static final Descriptor UNWIND_EXCEPTION = new Descriptor("unwindException", true, void.class, Object.class); + /** + * Unwind stub expects the exception in RAX. + */ + public static final Register EXCEPTION = AMD64.rax; + @Use({REG}) protected AllocatableValue exception; - @Temp private RegisterValue framePointer; AMD64HotSpotUnwindOp(AllocatableValue exception) { this.exception = exception; - assert exception == AMD64.rax.asValue(); - framePointer = AMD64.rbp.asValue(); + assert asRegister(exception) == EXCEPTION; } @Override public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - masm.movq(framePointer.getRegister(), rsp); - masm.incrementq(framePointer.getRegister(), tasm.frameMap.frameSize() - 8); + // Copy the saved RBP value into the slot just below the return address + // so that the stub can pick it up from there. + AMD64Address rbpSlot; + int rbpSlotOffset = tasm.frameMap.frameSize() - 8; + if (isStackSlot(savedRbp)) { + rbpSlot = (AMD64Address) tasm.asAddress(savedRbp); + assert rbpSlot.getDisplacement() == rbpSlotOffset; + } else { + rbpSlot = new AMD64Address(rsp, rbpSlotOffset); + masm.movq(rbpSlot, asRegister(savedRbp)); + } + + // Pass the address of the RBP slot in RBP itself + masm.leaq(rbp, rbpSlot); AMD64Call.directCall(tasm, masm, tasm.runtime.lookupRuntimeCall(UNWIND_EXCEPTION), null); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/HotSpotAMD64LIRGenerator.java Fri Mar 15 21:18:47 2013 +0100 @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.amd64; + +import static com.oracle.graal.amd64.AMD64.*; +import static com.oracle.graal.api.code.CallingConvention.Type.*; +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.hotspot.amd64.AMD64HotSpotUnwindOp.*; + +import java.util.*; + +import com.oracle.graal.amd64.*; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; +import com.oracle.graal.asm.amd64.AMD64Address.*; +import com.oracle.graal.compiler.amd64.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.hotspot.stubs.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.*; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.amd64.AMD64Move.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.java.MethodCallTargetNode.*; + +/** + * LIR generator specialized for AMD64 HotSpot. + */ +final class HotSpotAMD64LIRGenerator extends AMD64LIRGenerator implements HotSpotLIRGenerator { + + private HotSpotRuntime runtime() { + return (HotSpotRuntime) runtime; + } + + HotSpotAMD64LIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) { + super(graph, runtime, target, frameMap, method, lir); + } + + /** + * 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; + + /** + * The position at which the instruction for saving RBP should be inserted. + */ + Block saveRbpBlock; + int saveRbpIndex; + + /** + * The slot reserved for saving RBP. + */ + StackSlot rbpSlot; + + /** + * List of epilogue operations that need to restore RBP. + */ + List<AMD64HotSpotEpilogueOp> epilogueOps = new ArrayList<>(2); + + @Override + protected void emitPrologue() { + + CallingConvention incomingArguments = createCallingConvention(); + + RegisterValue rbpParam = rbp.asValue(Kind.Long); + Value[] params = new Value[incomingArguments.getArgumentCount() + 1]; + for (int i = 0; i < params.length - 1; i++) { + params[i] = toStackKind(incomingArguments.getArgument(i)); + if (isStackSlot(params[i])) { + StackSlot slot = ValueUtil.asStackSlot(params[i]); + if (slot.isInCallerFrame() && !lir.hasArgInCallerFrame()) { + lir.setHasArgInCallerFrame(); + } + } + } + params[params.length - 1] = rbpParam; + + ParametersOp paramsOp = new ParametersOp(params); + append(paramsOp); + saveRbpBlock = currentBlock; + saveRbpIndex = lir.lir(saveRbpBlock).size(); + append(paramsOp); // placeholder + rbpSlot = frameMap.allocateSpillSlot(Kind.Long); + assert rbpSlot.getRawOffset() == -16 : rbpSlot.getRawOffset(); + + for (LocalNode local : graph.getNodes(LocalNode.class)) { + Value param = params[local.index()]; + assert param.getKind() == local.kind().getStackKind(); + setResult(local, emitMove(param)); + } + } + + @Override + protected void emitReturn(Value input) { + AMD64HotSpotReturnOp op = new AMD64HotSpotReturnOp(input); + epilogueOps.add(op); + append(op); + } + + @Override + protected boolean needOnlyOopMaps() { + // Stubs only need oop maps + return runtime().asStub(method) != null; + } + + @Override + protected CallingConvention createCallingConvention() { + Stub stub = runtime().asStub(method); + if (stub != null) { + return stub.getLinkage().getCallingConvention(); + } + + if (graph.getEntryBCI() == StructuredGraph.INVOCATION_ENTRY_BCI) { + return super.createCallingConvention(); + } else { + return frameMap.registerConfig.getCallingConvention(JavaCallee, method.getSignature().getReturnType(null), new JavaType[]{runtime.lookupJavaType(long.class)}, target, false); + } + } + + @Override + public void visitSafepointNode(SafepointNode i) { + LIRFrameState info = state(); + append(new AMD64SafepointOp(info, runtime().config, this)); + } + + @Override + public void visitExceptionObject(ExceptionObjectNode x) { + HotSpotVMConfig config = runtime().config; + RegisterValue thread = runtime().threadRegister().asValue(); + Value exception = emitLoad(Kind.Object, thread, config.threadExceptionOopOffset, Value.ILLEGAL, 0, false); + emitStore(Kind.Object, thread, config.threadExceptionOopOffset, Value.ILLEGAL, 0, Constant.NULL_OBJECT, false); + emitStore(Kind.Long, thread, config.threadExceptionPcOffset, Value.ILLEGAL, 0, Constant.LONG_0, false); + setResult(x, exception); + } + + @SuppressWarnings("hiding") + @Override + public void visitDirectCompareAndSwap(DirectCompareAndSwapNode x) { + Kind kind = x.newValue().kind(); + assert kind == x.expectedValue().kind(); + + Value expected = loadNonConst(operand(x.expectedValue())); + Variable newVal = load(operand(x.newValue())); + + int disp = 0; + AMD64AddressValue address; + Value index = operand(x.offset()); + if (ValueUtil.isConstant(index) && NumUtil.isInt(ValueUtil.asConstant(index).asLong() + disp)) { + assert !runtime.needsDataPatch(asConstant(index)); + disp += (int) ValueUtil.asConstant(index).asLong(); + address = new AMD64AddressValue(kind, load(operand(x.object())), disp); + } else { + address = new AMD64AddressValue(kind, load(operand(x.object())), load(index), Scale.Times1, disp); + } + + RegisterValue rax = AMD64.rax.asValue(kind); + emitMove(rax, expected); + append(new CompareAndSwapOp(rax, address, rax, newVal)); + + Variable result = newVariable(x.kind()); + emitMove(result, rax); + setResult(x, result); + } + + @Override + public void emitTailcall(Value[] args, Value address) { + append(new AMD64TailcallOp(args, address)); + + } + + @Override + protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { + InvokeKind invokeKind = ((HotSpotDirectCallTargetNode) callTarget).invokeKind(); + if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) { + append(new AMD64HotspotDirectVirtualCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind)); + } else { + assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special; + HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) callTarget.target(); + Constant metaspaceMethod = resolvedMethod.getMetaspaceMethodConstant(); + append(new AMD64HotspotDirectStaticCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind, metaspaceMethod)); + } + } + + @Override + protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { + Value metaspaceMethod = AMD64.rbx.asValue(); + emitMove(metaspaceMethod, operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod())); + Value targetAddress = AMD64.rax.asValue(); + emitMove(targetAddress, operand(callTarget.computedAddress())); + append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, temps, metaspaceMethod, targetAddress, callState)); + } + + @Override + public void emitUnwind(Value exception) { + RegisterValue exceptionParameter = EXCEPTION.asValue(); + emitMove(exceptionParameter, exception); + AMD64HotSpotUnwindOp op = new AMD64HotSpotUnwindOp(exceptionParameter); + epilogueOps.add(op); + append(op); + } + + @Override + public void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason) { + append(new AMD64DeoptimizeOp(action, reason, state())); + } + + @Override + public void beforeRegisterAllocation() { + assert rbpSlot != null; + RegisterValue rbpParam = rbp.asValue(Kind.Long); + AllocatableValue savedRbp; + LIRInstruction saveRbp; + if (lir.hasDebugInfo()) { + savedRbp = rbpSlot; + deoptimizationRescueSlot = frameMap.allocateSpillSlot(Kind.Long); + } else { + frameMap.freeSpillSlot(rbpSlot); + savedRbp = newVariable(Kind.Long); + } + + for (AMD64HotSpotEpilogueOp op : epilogueOps) { + op.savedRbp = savedRbp; + } + + saveRbp = new MoveFromRegOp(savedRbp, rbpParam); + lir.lir(saveRbpBlock).set(saveRbpIndex, saveRbp); + } +}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/snippets/AMD64ConvertSnippets.java Fri Mar 15 21:18:33 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.hotspot.amd64.snippets; - -import static com.oracle.graal.snippets.SnippetTemplate.*; -import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*; -import static com.oracle.graal.snippets.nodes.BranchProbabilityNode.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.debug.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.calc.ConvertNode.Op; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.snippets.*; -import com.oracle.graal.snippets.Snippet.Parameter; -import com.oracle.graal.snippets.SnippetTemplate.AbstractTemplates; -import com.oracle.graal.snippets.SnippetTemplate.Arguments; -import com.oracle.graal.snippets.SnippetTemplate.Key; - -/** - * Snippets used for conversion operations on AMD64 where the AMD64 instruction used does not match - * the semantics of the JVM specification. - */ -public class AMD64ConvertSnippets implements SnippetsInterface { - - /** - * Converts a float to an int. - * <p> - * This snippet accounts for the semantics of the x64 CVTTSS2SI instruction used to do the - * conversion. If the float value is a NaN, infinity or if the result of the conversion is - * larger than {@link Integer#MAX_VALUE} then CVTTSS2SI returns {@link Integer#MIN_VALUE} and - * extra tests are required on the float value to return the correct int value. - * - * @param input the float being converted - * @param result the result produced by the CVTTSS2SI instruction - */ - @Snippet - public static int f2i(@Parameter("input") float input, @Parameter("result") int result) { - if (result == Integer.MIN_VALUE) { - probability(NOT_FREQUENT_PROBABILITY); - if (Float.isNaN(input)) { - // input is NaN -> return 0 - return 0; - } else if (input > 0.0f) { - // input is > 0 -> return max int - return Integer.MAX_VALUE; - } - } - return result; - } - - /** - * Converts a float to a long. - * <p> - * This snippet accounts for the semantics of the x64 CVTTSS2SI instruction used to do the - * conversion. If the float value is a NaN or infinity then CVTTSS2SI returns - * {@link Long#MIN_VALUE} and extra tests are required on the float value to return the correct - * long value. - * - * @param input the float being converted - * @param result the result produced by the CVTTSS2SI instruction - */ - @Snippet - public static long f2l(@Parameter("input") float input, @Parameter("result") long result) { - if (result == Long.MIN_VALUE) { - probability(NOT_FREQUENT_PROBABILITY); - if (Float.isNaN(input)) { - // input is NaN -> return 0 - return 0; - } else if (input > 0.0f) { - // input is > 0 -> return max int - return Long.MAX_VALUE; - } - } - return result; - } - - /** - * Converts a double to an int. - * <p> - * This snippet accounts for the semantics of the x64 CVTTSD2SI instruction used to do the - * conversion. If the double value is a NaN, infinity or if the result of the conversion is - * larger than {@link Integer#MAX_VALUE} then CVTTSD2SI returns {@link Integer#MIN_VALUE} and - * extra tests are required on the double value to return the correct int value. - * - * @param input the double being converted - * @param result the result produced by the CVTTSS2SI instruction - */ - @Snippet - public static int d2i(@Parameter("input") double input, @Parameter("result") int result) { - if (result == Integer.MIN_VALUE) { - probability(NOT_FREQUENT_PROBABILITY); - if (Double.isNaN(input)) { - // input is NaN -> return 0 - return 0; - } else if (input > 0.0d) { - // input is positive -> return maxInt - return Integer.MAX_VALUE; - } - } - return result; - } - - /** - * Converts a double to a long. - * <p> - * This snippet accounts for the semantics of the x64 CVTTSD2SI instruction used to do the - * conversion. If the double value is a NaN, infinity or if the result of the conversion is - * larger than {@link Long#MAX_VALUE} then CVTTSD2SI returns {@link Long#MIN_VALUE} and extra - * tests are required on the double value to return the correct long value. - * - * @param input the double being converted - * @param result the result produced by the CVTTSS2SI instruction - */ - @Snippet - public static long d2l(@Parameter("input") double input, @Parameter("result") long result) { - if (result == Long.MIN_VALUE) { - probability(NOT_FREQUENT_PROBABILITY); - if (Double.isNaN(input)) { - // input is NaN -> return 0 - return 0; - } else if (input > 0.0d) { - // input is positive -> return maxInt - return Long.MAX_VALUE; - } - } - return result; - } - - public static class Templates extends AbstractTemplates<AMD64ConvertSnippets> { - - private final ResolvedJavaMethod f2i; - private final ResolvedJavaMethod f2l; - private final ResolvedJavaMethod d2i; - private final ResolvedJavaMethod d2l; - - public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target) { - super(runtime, assumptions, target, AMD64ConvertSnippets.class); - f2i = snippet("f2i", float.class, int.class); - f2l = snippet("f2l", float.class, long.class); - d2i = snippet("d2i", double.class, int.class); - d2l = snippet("d2l", double.class, long.class); - } - - public void lower(ConvertNode convert, LoweringTool tool) { - if (convert.opcode == Op.F2I) { - lower0(convert, tool, f2i); - } else if (convert.opcode == Op.F2L) { - lower0(convert, tool, f2l); - } else if (convert.opcode == Op.D2I) { - lower0(convert, tool, d2i); - } else if (convert.opcode == Op.D2L) { - lower0(convert, tool, d2l); - } - } - - private void lower0(ConvertNode convert, LoweringTool tool, ResolvedJavaMethod snippet) { - StructuredGraph graph = (StructuredGraph) convert.graph(); - - // Insert a unique placeholder node in place of the Convert node so that the - // Convert node can be used as an input to the snippet. All usage of the - // Convert node are replaced by the placeholder which in turn is replaced by the - // snippet. - - LocalNode replacee = graph.add(new LocalNode(Integer.MAX_VALUE, convert.stamp())); - convert.replaceAtUsages(replacee); - Key key = new Key(snippet); - Arguments arguments = arguments("input", convert.value()).add("result", convert); - SnippetTemplate template = cache.get(key, assumptions); - Debug.log("Lowering %s in %s: node=%s, template=%s, arguments=%s", convert.opcode, graph, convert, template, arguments); - template.instantiate(runtime, replacee, DEFAULT_REPLACER, tool, arguments); - } - } -}
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Fri Mar 15 21:18:47 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 } }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Mar 15 21:18:47 2013 +0100 @@ -827,7 +827,7 @@ /** * Gets the kind of array elements for the array type code that appears in a * {@link Bytecodes#NEWARRAY} bytecode. - * + * * @param code the array type code * @return the kind from the array type code */ @@ -964,7 +964,7 @@ private void emitExplicitExceptions(ValueNode receiver, ValueNode outOfBoundsIndex) { assert receiver != null; - if (!GraalOptions.AllowExplicitExceptionChecks || (optimisticOpts.useExceptionProbability() && profilingInfo.getExceptionSeen(bci()) == ExceptionSeen.FALSE)) { + if (optimisticOpts.useExceptionProbabilityForOperations() && profilingInfo.getExceptionSeen(bci()) == ExceptionSeen.FALSE) { return; } @@ -1224,7 +1224,7 @@ /** * Helper function that sums up the probabilities of all keys that lead to a specific successor. - * + * * @return an array of size successorCount with the accumulated probability for each successor. */ private static double[] successorProbabilites(int successorCount, int[] keySuccessors, double[] keyProbabilities) {
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Code.java Fri Mar 15 21:18:33 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.lir.amd64; - -import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.asm.*; - -/** - * Convenience class to provide AMD64MacroAssembler for the {@link #emitCode} method. - */ -public abstract class AMD64Code implements LIR.Code { - - @Override - public final void emitCode(TargetMethodAssembler tasm) { - emitCode(tasm, (AMD64MacroAssembler) tasm.asm); - } - - public abstract void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm); -}
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Fri Mar 15 21:18:47 2013 +0100 @@ -63,16 +63,14 @@ public static class BranchOp extends AMD64LIRInstruction implements StandardOp.BranchOp { protected ConditionFlag condition; protected LabelRef destination; - @State protected LIRFrameState state; - public BranchOp(Condition condition, LabelRef destination, LIRFrameState info) { - this(intCond(condition), destination, info); + public BranchOp(Condition condition, LabelRef destination) { + this(intCond(condition), destination); } - public BranchOp(ConditionFlag condition, LabelRef destination, LIRFrameState state) { + public BranchOp(ConditionFlag condition, LabelRef destination) { this.condition = condition; this.destination = destination; - this.state = state; } @Override @@ -96,8 +94,8 @@ public static class FloatBranchOp extends BranchOp { protected boolean unorderedIsTrue; - public FloatBranchOp(Condition condition, boolean unorderedIsTrue, LabelRef destination, LIRFrameState info) { - super(floatCond(condition), destination, info); + public FloatBranchOp(Condition condition, boolean unorderedIsTrue, LabelRef destination) { + super(floatCond(condition), destination); this.unorderedIsTrue = unorderedIsTrue; }
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXCode.java Fri Mar 15 21:18:33 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.lir.ptx; - -import com.oracle.graal.asm.ptx.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.asm.*; - -/** - * Convenience class to provide PTXAssembler for the {@link #emitCode} method. - */ -public abstract class PTXCode implements LIR.Code { - - @Override - public final void emitCode(TargetMethodAssembler tasm) { - emitCode(tasm, (PTXAssembler) tasm.asm); - } - - public abstract void emitCode(TargetMethodAssembler tasm, PTXAssembler masm); -}
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java Fri Mar 15 21:18:47 2013 +0100 @@ -54,12 +54,10 @@ protected Condition condition; protected LabelRef destination; - @State protected LIRFrameState state; - public BranchOp(Condition condition, LabelRef destination, LIRFrameState state) { + public BranchOp(Condition condition, LabelRef destination) { this.condition = condition; this.destination = destination; - this.state = state; } @Override
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Fri Mar 15 21:18:47 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. * <p> - * A runtime has two ways to reserve space in the stack frame for its own use: - * <ul> - * <li>A memory block somewhere in the frame of size - * {@link CodeCacheProvider#getCustomStackAreaSize()}. The offset to this block is returned in - * {@link CompilationResult#getCustomStackAreaOffset()}. - * <li>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. - * </ul> + * 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 { @@ -89,14 +83,9 @@ public final RegisterConfig registerConfig; /** - * The initial frame size, not including the size of the return address. This is the constant - * space reserved by the runtime for all compiled methods. - */ - public final int initialFrameSize; - - /** - * The final frame size, not including the size of the return address. The value is only set - * after register allocation is complete, i.e., after all spill slots have been allocated. + * The final frame size, not including the size of the + * {@link Architecture#getReturnAddressSize() return address slot}. The value is only set after + * register allocation is complete, i.e., after all spill slots have been allocated. */ private int frameSize; @@ -117,12 +106,6 @@ private final List<StackSlot> 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,8 +122,6 @@ this.spillSize = returnAddressSize() + calleeSaveAreaSize(); this.outgoingSize = runtime.getMinimumOutgoingSize(); this.objectStackBlocks = new ArrayList<>(); - this.customArea = allocateStackBlock(runtime.getCustomStackAreaSize(), false); - this.initialFrameSize = currentFrameSize(); } private int returnAddressSize() { @@ -161,7 +142,8 @@ } /** - * Gets the frame size of the compiled frame, not including the size of the return address. + * Gets the frame size of the compiled frame, not including the size of the + * {@link Architecture#getReturnAddressSize() return address slot}. * * @return The size of the frame (in bytes). */ @@ -171,7 +153,17 @@ } /** - * Gets the total frame size of the compiled frame, including the size of the return address. + * Determines if any space is used in the frame apart from the + * {@link Architecture#getReturnAddressSize() return address slot}. + */ + public boolean frameNeedsAllocating() { + int unalignedFrameSize = outgoingSize + spillSize - returnAddressSize(); + return unalignedFrameSize != 0; + } + + /** + * Gets the total frame size of the compiled frame, including the size of the + * {@link Architecture#getReturnAddressSize() return address slot}. * * @return The total size of the frame (in bytes). */ @@ -194,6 +186,21 @@ */ public void finish() { assert this.frameSize == -1 : "must only be set once"; + if (freedSlots != null) { + // If the freed slots cover the complete spill area (except for the return + // address slot), then the spill size is reset to its initial value. + // Without this, frameNeedsAllocating() would never return true. + int total = 0; + for (StackSlot s : freedSlots) { + total += target.sizeInBytes(s.getKind()); + } + int initialSpillSize = returnAddressSize() + calleeSaveAreaSize(); + if (total == spillSize - initialSpillSize) { + // reset spill area size + spillSize = initialSpillSize; + } + freedSlots = null; + } frameSize = currentFrameSize(); } @@ -223,16 +230,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. * @@ -265,11 +262,36 @@ */ public StackSlot allocateSpillSlot(Kind kind) { assert frameSize == -1 : "frame size must not yet be fixed"; + if (freedSlots != null) { + for (Iterator<StackSlot> iter = freedSlots.iterator(); iter.hasNext();) { + StackSlot s = iter.next(); + if (s.getKind() == kind) { + iter.remove(); + if (freedSlots.isEmpty()) { + freedSlots = null; + } + return s; + } + } + } int size = target.sizeInBytes(kind); spillSize = NumUtil.roundUp(spillSize + size, size); return getSlot(kind, 0); } + private List<StackSlot> freedSlots; + + /** + * Frees a spill slot that was obtained via {@link #allocateSpillSlot(Kind)} such that it can be + * reused for the next allocation request for the same kind of slot. + */ + public void freeSpillSlot(StackSlot slot) { + if (freedSlots == null) { + freedSlots = new ArrayList<>(); + } + freedSlots.add(slot); + } + /** * Reserves a block of memory in the frame of the method being compiled. The returned block is * aligned on a word boundary. If the requested size is 0, the method returns {@code null}.
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java Fri Mar 15 21:18:47 2013 +0100 @@ -56,12 +56,6 @@ */ private final List<Block> codeEmittingOrder; - /** - * Various out-of-line stubs to be emitted near the end of the method after all other LIR code - * has been emitted. - */ - public final List<Code> stubs; - private int numVariables; public SpillMoveFactory spillMoveFactory; @@ -78,19 +72,6 @@ private final SpeculationLog speculationLog; /** - * An opaque chunk of machine code. - */ - public interface Code { - - void emitCode(TargetMethodAssembler tasm); - - /** - * A description of this code stub useful for commenting the code in a disassembly. - */ - String description(); - } - - /** * Creates a new LIR instance for the specified compilation. */ public LIR(ControlFlowGraph cfg, BlockMap<List<ScheduledNode>> blockToNodesMap, List<Block> linearScanOrder, List<Block> codeEmittingOrder, SpeculationLog speculationLog) { @@ -99,8 +80,6 @@ this.codeEmittingOrder = codeEmittingOrder; this.linearScanOrder = linearScanOrder; this.lirInstructions = new BlockMap<>(cfg); - - stubs = new ArrayList<>(); this.speculationLog = speculationLog; } @@ -116,7 +95,7 @@ } /** - * Determines if any instruction in the LIR has any debug info associated with it. + * Determines if any instruction in the LIR has debug info associated with it. */ public boolean hasDebugInfo() { for (Block b : linearScanOrder()) { @@ -167,11 +146,6 @@ for (Block b : codeEmittingOrder()) { emitBlock(tasm, b); } - - // generate code stubs - for (Code c : stubs) { - emitCodeStub(tasm, c); - } } private void emitBlock(TargetMethodAssembler tasm, Block block) { @@ -202,13 +176,6 @@ } } - private static void emitCodeStub(TargetMethodAssembler tasm, Code code) { - if (Debug.isDumpEnabled()) { - tasm.blockComment(String.format("code stub: %s", code.description())); - } - code.emitCode(tasm); - } - public void setHasArgInCallerFrame() { hasArgInCallerFrame = true; }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Fri Mar 15 21:18:47 2013 +0100 @@ -80,11 +80,9 @@ public static class JumpOp extends LIRInstruction { private final LabelRef destination; - @State protected LIRFrameState state; - public JumpOp(LabelRef destination, LIRFrameState state) { + public JumpOp(LabelRef destination) { this.destination = destination; - this.state = state; } @Override
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java Fri Mar 15 21:18:47 2013 +0100 @@ -60,12 +60,12 @@ private List<ExceptionInfo> 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; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Fri Mar 15 21:18:47 2013 +0100 @@ -29,7 +29,7 @@ import com.oracle.graal.nodes.type.*; @NodeInfo(nameTemplate = "FixedGuard(!={p#negated}) {p#reason/s}") -public final class FixedGuardNode extends FixedWithNextNode implements Simplifiable, Lowerable, LIRLowerable, Node.IterableNodeType, Negatable { +public final class FixedGuardNode extends FixedWithNextNode implements Simplifiable, Lowerable, Node.IterableNodeType, Negatable { @Input private LogicNode condition; private final DeoptimizationReason reason; @@ -79,11 +79,6 @@ } @Override - public void generate(LIRGeneratorTool gen) { - gen.emitGuardCheck(condition, reason, action, negated); - } - - @Override public void simplify(SimplifierTool tool) { if (condition instanceof LogicConstantNode) { LogicConstantNode c = (LogicConstantNode) condition;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedNode.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedNode.java Fri Mar 15 21:18:47 2013 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes; +import java.util.*; + import com.oracle.graal.nodes.type.*; public abstract class FixedNode extends ValueNode { @@ -32,6 +34,10 @@ super(stamp); } + public FixedNode(Stamp stamp, List<ValueNode> dependencies) { + super(stamp, dependencies); + } + public FixedNode(Stamp stamp, ValueNode... dependencies) { super(stamp, dependencies); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedWithNextNode.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedWithNextNode.java Fri Mar 15 21:18:47 2013 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes; +import java.util.*; + import com.oracle.graal.nodes.type.*; /** @@ -43,6 +45,10 @@ super(stamp); } + public FixedWithNextNode(Stamp stamp, List<ValueNode> dependencies) { + super(stamp, dependencies); + } + public FixedWithNextNode(Stamp stamp, ValueNode... dependencies) { super(stamp, dependencies); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Fri Mar 15 21:18:47 2013 +0100 @@ -42,7 +42,7 @@ * control flow would have reached the guarded node (without taking exceptions into account). */ @NodeInfo(nameTemplate = "Guard(!={p#negated}) {p#reason/s}") -public final class GuardNode extends FloatingNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType, Negatable { +public final class GuardNode extends FloatingNode implements Canonicalizable, Node.IterableNodeType, Negatable { @Input private LogicNode condition; private final DeoptimizationReason reason; @@ -91,11 +91,6 @@ } @Override - public void generate(LIRGeneratorTool gen) { - gen.emitGuardCheck(condition(), reason(), action(), negated()); - } - - @Override public ValueNode canonical(CanonicalizerTool tool) { if (condition() instanceof LogicConstantNode) { LogicConstantNode c = (LogicConstantNode) condition();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Fri Mar 15 21:18:47 2013 +0100 @@ -28,7 +28,6 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.nodes.type.*; -import com.oracle.graal.nodes.type.GenericStamp.*; import com.oracle.graal.nodes.util.*; /** @@ -174,9 +173,6 @@ @Override public boolean verify() { - for (ValueNode v : dependencies().nonNull()) { - assertTrue(!(v.stamp() instanceof GenericStamp) || ((GenericStamp) v.stamp()).type() == GenericStampType.Dependency, "cannot depend on node with stamp %s", v.stamp()); - } assertTrue(kind() != null, "Should have a valid kind"); assertTrue(kind() == kind().getStackKind(), "Should have a stack kind : %s", kind()); return super.verify();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java Fri Mar 15 21:18:47 2013 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes.extended; +import java.util.*; + import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; @@ -58,6 +60,12 @@ this.location = location; } + public AccessNode(ValueNode object, ValueNode location, Stamp stamp, List<ValueNode> dependencies) { + super(stamp, dependencies); + this.object = object; + this.location = location; + } + public AccessNode(ValueNode object, ValueNode location, Stamp stamp, ValueNode... dependencies) { super(stamp, dependencies); this.object = object;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Mar 15 21:18:47 2013 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes.extended; +import java.util.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -37,6 +39,10 @@ super(object, location, stamp); } + public ReadNode(ValueNode object, ValueNode location, Stamp stamp, List<ValueNode> dependencies) { + super(object, location, stamp, dependencies); + } + private ReadNode(ValueNode object, int displacement, Object locationIdentity, Kind kind) { super(object, object.graph().add(new LocationNode(locationIdentity, kind, displacement)), StampFactory.forKind(kind)); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Fri Mar 15 21:18:47 2013 +0100 @@ -64,7 +64,7 @@ return previousAnchor; } } - for (Node node : dependencies().nonNull().and(isNotA(BeginNode.class))) { + for (Node node : dependencies().nonNull().and(isNotA(FixedNode.class))) { if (node instanceof ConstantNode) { continue; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Fri Mar 15 21:18:47 2013 +0100 @@ -97,8 +97,6 @@ public abstract void emitMembar(int barriers); - public abstract void emitDeoptimizeOnOverflow(DeoptimizationAction action, DeoptimizationReason reason); - public abstract void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason); public abstract Value emitCall(RuntimeCallTarget callTarget, CallingConvention cc, boolean canTrap, Value... args); @@ -107,8 +105,6 @@ public abstract void emitConditional(ConditionalNode i); - public abstract void emitGuardCheck(LogicNode comp, DeoptimizationReason deoptReason, DeoptimizationAction deoptAction, boolean negated); - public abstract void emitSwitch(SwitchNode i); public abstract void emitInvoke(Invoke i); @@ -134,4 +130,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() { + } }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Fri Mar 15 21:18:47 2013 +0100 @@ -23,30 +23,47 @@ package com.oracle.graal.phases.common; import java.util.*; +import java.util.Map.Entry; +import com.oracle.graal.api.code.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.schedule.*; public class GuardLoweringPhase extends Phase { + private TargetDescription target; + + public GuardLoweringPhase(TargetDescription target) { + this.target = target; + } + @Override protected void run(StructuredGraph graph) { SchedulePhase schedule = new SchedulePhase(); schedule.apply(graph); for (Block block : schedule.getCFG().getBlocks()) { - processBlock(block, schedule, graph); + processBlock(block, schedule, graph, target); } } - private static void processBlock(Block block, SchedulePhase schedule, StructuredGraph graph) { + private static void processBlock(Block block, SchedulePhase schedule, StructuredGraph graph, TargetDescription target) { List<ScheduledNode> nodes = schedule.nodesFor(block); + if (GraalOptions.OptImplicitNullChecks && target.implicitNullCheckLimit > 0) { + useImplicitNullChecks(block.getBeginNode(), nodes, graph, target); + } FixedWithNextNode lastFixed = block.getBeginNode(); BeginNode lastFastPath = null; for (Node node : nodes) { + if (!node.isAlive()) { + continue; + } if (lastFastPath != null && node instanceof FixedNode) { lastFastPath.setNext((FixedNode) node); lastFastPath = null; @@ -81,4 +98,70 @@ } } } + + private static void useImplicitNullChecks(BeginNode begin, List<ScheduledNode> nodes, StructuredGraph graph, TargetDescription target) { + ListIterator<ScheduledNode> iterator = nodes.listIterator(); + IdentityHashMap<ValueNode, GuardNode> nullGuarded = new IdentityHashMap<>(); + FixedWithNextNode lastFixed = begin; + FixedWithNextNode reconnect = null; + while (iterator.hasNext()) { + Node node = iterator.next(); + + if (reconnect != null && node instanceof FixedNode) { + reconnect.setNext((FixedNode) node); + reconnect = null; + } + if (node instanceof FixedWithNextNode) { + lastFixed = (FixedWithNextNode) node; + } + + if (node instanceof GuardNode) { + GuardNode guard = (GuardNode) node; + if (guard.negated() && guard.condition() instanceof IsNullNode) { + ValueNode obj = ((IsNullNode) guard.condition()).object(); + nullGuarded.put(obj, guard); + } + } else if (node instanceof Access) { + Access access = (Access) node; + GuardNode guard = nullGuarded.get(access.object()); + if (guard != null && isImplicitNullCheck(access.location(), target)) { + NodeInputList<ValueNode> dependencies = ((ValueNode) access).dependencies(); + dependencies.remove(guard); + if (access instanceof FloatingReadNode) { + ReadNode read = graph.add(new ReadNode(access.object(), access.location(), ((FloatingReadNode) access).stamp(), dependencies)); + node.replaceAndDelete(read); + access = read; + lastFixed.setNext(read); + lastFixed = read; + reconnect = read; + iterator.set(read); + } + assert access instanceof AccessNode; + access.setNullCheck(true); + LogicNode condition = guard.condition(); + guard.replaceAndDelete(access.node()); + if (condition.usages().isEmpty()) { + GraphUtil.killWithUnusedFloatingInputs(condition); + } + nullGuarded.remove(access.object()); + } + } + if (node instanceof StateSplit && ((StateSplit) node).stateAfter() != null) { + nullGuarded.clear(); + } else { + Iterator<Entry<ValueNode, GuardNode>> it = nullGuarded.entrySet().iterator(); + while (it.hasNext()) { + Entry<ValueNode, GuardNode> entry = it.next(); + GuardNode guard = entry.getValue(); + if (guard.usages().contains(node)) { + it.remove(); + } + } + } + } + } + + private static boolean isImplicitNullCheck(LocationNode location, TargetDescription target) { + return !(location instanceof IndexedLocationNode) && location.displacement() < target.implicitNullCheckLimit; + } }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Fri Mar 15 21:18:47 2013 +0100 @@ -83,7 +83,7 @@ public ValueNode createGuard(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) { if (GraalOptions.OptEliminateGuards) { for (Node usage : condition.usages()) { - if (!activeGuards.isNew(usage) && activeGuards.isMarked(usage) && ((GuardNode) usage).negated() == negated && ((GuardNode) usage).dependencies().contains(guardAnchor)) { + if (!activeGuards.isNew(usage) && activeGuards.isMarked(usage) && ((GuardNode) usage).negated() == negated) { return (GuardNode) usage; } }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Fri Mar 15 21:18:47 2013 +0100 @@ -157,7 +157,7 @@ public static boolean UseProfilingInformation = true; static boolean RemoveNeverExecutedCode = true; static boolean UseExceptionProbability = true; - public static boolean AllowExplicitExceptionChecks = true; + static boolean UseExceptionProbabilityForOperations = true; public static boolean OmitHotExceptionStacktrace = ____; public static boolean GenSafepoints = true; public static boolean GenLoopSafepoints = true; @@ -167,7 +167,7 @@ public static boolean GenAssertionCode = ____; public static boolean AlignCallsForPatching = true; public static boolean ResolveClassBeforeStaticInvoke = ____; - public static boolean CanOmitFrame = false; + public static boolean CanOmitFrame = true; public static int SafepointPollOffset = 256; public static boolean MemoryAwareScheduling = true; @@ -185,7 +185,7 @@ public static boolean SupportJsrBytecodes = true; public static boolean OptAssumptions = true; - public static boolean OptConvertDeoptsToGuards = true; + public static boolean OptConvertDeoptsToGuards = ____; public static boolean OptReadElimination = true; public static boolean OptCanonicalizer = true; public static boolean OptScheduleOutOfLoops = true;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java Fri Mar 15 21:18:33 2013 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/OptimisticOptimizations.java Fri Mar 15 21:18:47 2013 +0100 @@ -33,8 +33,8 @@ public static final OptimisticOptimizations NONE = new OptimisticOptimizations(EnumSet.noneOf(Optimization.class)); private static final DebugMetric disabledOptimisticOptsMetric = Debug.metric("DisabledOptimisticOpts"); - private static enum Optimization { - RemoveNeverExecutedCode, UseTypeCheckedInlining, UseTypeCheckHints, UseExceptionProbability + public static enum Optimization { + RemoveNeverExecutedCode, UseTypeCheckedInlining, UseTypeCheckHints, UseExceptionProbabilityForOperations, UseExceptionProbability } private final Set<Optimization> enabledOpts; @@ -42,6 +42,7 @@ public OptimisticOptimizations(ResolvedJavaMethod method) { this.enabledOpts = EnumSet.noneOf(Optimization.class); + enabledOpts.add(Optimization.UseExceptionProbabilityForOperations); addOptimization(method, DeoptimizationReason.UnreachedCode, Optimization.RemoveNeverExecutedCode); addOptimization(method, DeoptimizationReason.TypeCheckedInliningViolated, Optimization.UseTypeCheckedInlining); addOptimization(method, DeoptimizationReason.OptimizedTypeCheckViolated, Optimization.UseTypeCheckHints); @@ -60,6 +61,22 @@ } } + public OptimisticOptimizations remove(Optimization... optimizations) { + Set<Optimization> newOptimizations = EnumSet.copyOf(enabledOpts); + for (Optimization o : optimizations) { + newOptimizations.remove(o); + } + return new OptimisticOptimizations(newOptimizations); + } + + public OptimisticOptimizations add(Optimization... optimizations) { + Set<Optimization> newOptimizations = EnumSet.copyOf(enabledOpts); + for (Optimization o : optimizations) { + newOptimizations.add(o); + } + return new OptimisticOptimizations(newOptimizations); + } + private OptimisticOptimizations(Set<Optimization> enabledOpts) { this.enabledOpts = enabledOpts; } @@ -92,6 +109,10 @@ return GraalOptions.UseExceptionProbability && enabledOpts.contains(Optimization.UseExceptionProbability); } + public boolean useExceptionProbabilityForOperations() { + return GraalOptions.UseExceptionProbabilityForOperations && enabledOpts.contains(Optimization.UseExceptionProbabilityForOperations); + } + public boolean lessOptimisticThan(OptimisticOptimizations other) { for (Optimization opt : Optimization.values()) { if (!enabledOpts.contains(opt) && other.enabledOpts.contains(opt)) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.snippets.amd64/src/com/oracle/graal/snippets/amd64/AMD64ConvertSnippets.java Fri Mar 15 21:18:47 2013 +0100 @@ -0,0 +1,196 @@ +/* + * 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.snippets.amd64; + +import static com.oracle.graal.snippets.SnippetTemplate.*; +import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*; +import static com.oracle.graal.snippets.nodes.BranchProbabilityNode.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.calc.ConvertNode.Op; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.snippets.*; +import com.oracle.graal.snippets.Snippet.Parameter; +import com.oracle.graal.snippets.SnippetTemplate.AbstractTemplates; +import com.oracle.graal.snippets.SnippetTemplate.Arguments; +import com.oracle.graal.snippets.SnippetTemplate.Key; + +/** + * Snippets used for conversion operations on AMD64 where the AMD64 instruction used does not match + * the semantics of the JVM specification. + */ +public class AMD64ConvertSnippets implements SnippetsInterface { + + /** + * Converts a float to an int. + * <p> + * This snippet accounts for the semantics of the x64 CVTTSS2SI instruction used to do the + * conversion. If the float value is a NaN, infinity or if the result of the conversion is + * larger than {@link Integer#MAX_VALUE} then CVTTSS2SI returns {@link Integer#MIN_VALUE} and + * extra tests are required on the float value to return the correct int value. + * + * @param input the float being converted + * @param result the result produced by the CVTTSS2SI instruction + */ + @Snippet + public static int f2i(@Parameter("input") float input, @Parameter("result") int result) { + if (result == Integer.MIN_VALUE) { + probability(NOT_FREQUENT_PROBABILITY); + if (Float.isNaN(input)) { + // input is NaN -> return 0 + return 0; + } else if (input > 0.0f) { + // input is > 0 -> return max int + return Integer.MAX_VALUE; + } + } + return result; + } + + /** + * Converts a float to a long. + * <p> + * This snippet accounts for the semantics of the x64 CVTTSS2SI instruction used to do the + * conversion. If the float value is a NaN or infinity then CVTTSS2SI returns + * {@link Long#MIN_VALUE} and extra tests are required on the float value to return the correct + * long value. + * + * @param input the float being converted + * @param result the result produced by the CVTTSS2SI instruction + */ + @Snippet + public static long f2l(@Parameter("input") float input, @Parameter("result") long result) { + if (result == Long.MIN_VALUE) { + probability(NOT_FREQUENT_PROBABILITY); + if (Float.isNaN(input)) { + // input is NaN -> return 0 + return 0; + } else if (input > 0.0f) { + // input is > 0 -> return max int + return Long.MAX_VALUE; + } + } + return result; + } + + /** + * Converts a double to an int. + * <p> + * This snippet accounts for the semantics of the x64 CVTTSD2SI instruction used to do the + * conversion. If the double value is a NaN, infinity or if the result of the conversion is + * larger than {@link Integer#MAX_VALUE} then CVTTSD2SI returns {@link Integer#MIN_VALUE} and + * extra tests are required on the double value to return the correct int value. + * + * @param input the double being converted + * @param result the result produced by the CVTTSS2SI instruction + */ + @Snippet + public static int d2i(@Parameter("input") double input, @Parameter("result") int result) { + if (result == Integer.MIN_VALUE) { + probability(NOT_FREQUENT_PROBABILITY); + if (Double.isNaN(input)) { + // input is NaN -> return 0 + return 0; + } else if (input > 0.0d) { + // input is positive -> return maxInt + return Integer.MAX_VALUE; + } + } + return result; + } + + /** + * Converts a double to a long. + * <p> + * This snippet accounts for the semantics of the x64 CVTTSD2SI instruction used to do the + * conversion. If the double value is a NaN, infinity or if the result of the conversion is + * larger than {@link Long#MAX_VALUE} then CVTTSD2SI returns {@link Long#MIN_VALUE} and extra + * tests are required on the double value to return the correct long value. + * + * @param input the double being converted + * @param result the result produced by the CVTTSS2SI instruction + */ + @Snippet + public static long d2l(@Parameter("input") double input, @Parameter("result") long result) { + if (result == Long.MIN_VALUE) { + probability(NOT_FREQUENT_PROBABILITY); + if (Double.isNaN(input)) { + // input is NaN -> return 0 + return 0; + } else if (input > 0.0d) { + // input is positive -> return maxInt + return Long.MAX_VALUE; + } + } + return result; + } + + public static class Templates extends AbstractTemplates<AMD64ConvertSnippets> { + + private final ResolvedJavaMethod f2i; + private final ResolvedJavaMethod f2l; + private final ResolvedJavaMethod d2i; + private final ResolvedJavaMethod d2l; + + public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target) { + super(runtime, assumptions, target, AMD64ConvertSnippets.class); + f2i = snippet("f2i", float.class, int.class); + f2l = snippet("f2l", float.class, long.class); + d2i = snippet("d2i", double.class, int.class); + d2l = snippet("d2l", double.class, long.class); + } + + public void lower(ConvertNode convert, LoweringTool tool) { + if (convert.opcode == Op.F2I) { + lower0(convert, tool, f2i); + } else if (convert.opcode == Op.F2L) { + lower0(convert, tool, f2l); + } else if (convert.opcode == Op.D2I) { + lower0(convert, tool, d2i); + } else if (convert.opcode == Op.D2L) { + lower0(convert, tool, d2l); + } + } + + private void lower0(ConvertNode convert, LoweringTool tool, ResolvedJavaMethod snippet) { + StructuredGraph graph = (StructuredGraph) convert.graph(); + + // Insert a unique placeholder node in place of the Convert node so that the + // Convert node can be used as an input to the snippet. All usage of the + // Convert node are replaced by the placeholder which in turn is replaced by the + // snippet. + + LocalNode replacee = graph.add(new LocalNode(Integer.MAX_VALUE, convert.stamp())); + convert.replaceAtUsages(replacee); + Key key = new Key(snippet); + Arguments arguments = arguments("input", convert.value()).add("result", convert); + SnippetTemplate template = cache.get(key, assumptions); + Debug.log("Lowering %s in %s: node=%s, template=%s, arguments=%s", convert.opcode, graph, convert, template, arguments); + template.instantiate(runtime, replacee, DEFAULT_REPLACER, tool, arguments); + } + } +}
--- a/make/build-graal.xml Fri Mar 15 21:18:33 2013 +0100 +++ b/make/build-graal.xml Fri Mar 15 21:18:47 2013 +0100 @@ -23,33 +23,54 @@ or visit www.oracle.com if you need additional information or have any questions. --> - -<project name="graal" basedir="." default="main"> - <property name="src.dir" value="${gamma.dir}/graal"/> +<project basedir="." default="main" name="graal"> + <property name="src.dir" value="${gamma.dir}/graal"/> <property name="classes.dir" value="${shared.dir}/graal"/> - <property name="jar.dir" value="${shared.dir}"/> - <property name="jar.file" value="${jar.dir}/graal.jar"/> - - <target name="main" depends="jar"/> - + <property name="jar.dir" value="${shared.dir}"/> + <property name="jar.file" value="${jar.dir}/graal.jar"/> + <target depends="jar" name="main"/> <target name="compile"> <mkdir dir="${classes.dir}"/> - <javac srcdir="${src.dir}" destdir="${classes.dir}" debug="on" includeantruntime="false"> - <include name="com.oracle.graal.*/**"/> - <exclude name="com.oracle.graal.test/**"/> - <exclude name="com.oracle.graal.*.test/**"/> - <exclude name="com.oracle.graal.jtt/**"/> + <javac debug="on" destdir="${classes.dir}" includeantruntime="false"> + <src path="${src.dir}/com.oracle.graal.api.meta"/> + <src path="${src.dir}/com.oracle.graal.api.code"/> + <src path="${src.dir}/com.oracle.graal.graph"/> + <src path="${src.dir}/com.oracle.graal.debug"/> + <src path="${src.dir}/com.oracle.graal.nodes"/> + <src path="${src.dir}/com.oracle.graal.phases"/> + <src path="${src.dir}/com.oracle.graal.phases.common"/> + <src path="${src.dir}/com.oracle.graal.virtual"/> + <src path="${src.dir}/com.oracle.graal.loop"/> + <src path="${src.dir}/com.oracle.graal.alloc"/> + <src path="${src.dir}/com.oracle.graal.asm"/> + <src path="${src.dir}/com.oracle.graal.lir"/> + <src path="${src.dir}/com.oracle.graal.compiler"/> + <src path="${src.dir}/com.oracle.graal.bytecode"/> + <src path="${src.dir}/com.oracle.graal.java"/> + <src path="${src.dir}/com.oracle.graal.word"/> + <src path="${src.dir}/com.oracle.graal.snippets"/> + <src path="${src.dir}/com.oracle.graal.api.runtime"/> + <src path="${src.dir}/com.oracle.graal.printer"/> + <src path="${src.dir}/com.oracle.graal.hotspot"/> + <src path="${src.dir}/com.oracle.graal.amd64"/> + <src path="${src.dir}/com.oracle.graal.asm.amd64"/> + <src path="${src.dir}/com.oracle.graal.lir.amd64"/> + <src path="${src.dir}/com.oracle.graal.compiler.amd64"/> + <src path="${src.dir}/com.oracle.graal.hotspot.amd64"/> + <src path="${src.dir}/com.oracle.graal.sparc"/> + <src path="${src.dir}/com.oracle.graal.asm.sparc"/> + <src path="${src.dir}/com.oracle.graal.lir.sparc"/> + <src path="${src.dir}/com.oracle.graal.compiler.sparc"/> + <src path="${src.dir}/com.oracle.graal.hotspot.sparc"/> <compilerarg value="-XDignore.symbol.file"/> </javac> </target> - - <target name="jar" depends="compile"> + <target depends="compile" name="jar"> <mkdir dir="${jar.dir}"/> - <jar destfile="${jar.file}" basedir="${classes.dir}"/> + <jar basedir="${classes.dir}" destfile="${jar.file}"/> </target> - <target name="clean"> <delete dir="${classes.dir}"/> - <delete file="${jar.file}"/> + <delete file="${jar.filr}"/> </target> </project>
--- a/make/windows/makefiles/projectcreator.make Fri Mar 15 21:18:33 2013 +0100 +++ b/make/windows/makefiles/projectcreator.make Fri Mar 15 21:18:47 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 \
--- a/mx/commands.py Fri Mar 15 21:18:33 2013 +0100 +++ b/mx/commands.py Fri Mar 15 21:18:47 2013 +0100 @@ -52,31 +52,6 @@ _make_eclipse_launch = False -_copyrightTemplate = """/* - * Copyright (c) {0}, 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. - */ - -""" - _minVersion = mx.JavaVersion('1.7.0_04') def _chmodDir(chmodFlags, dirname, fnames): @@ -462,6 +437,71 @@ build = _vmbuild if _vmSourcesAvailable else 'product' print join(_graal_home, 'jdk' + str(mx.java().version), build) +def initantbuild(args): + """(re)generates an ant build file for producing graal.jar""" + parser=ArgumentParser(prog='mx initantbuild') + parser.add_argument('-f', '--buildfile', help='file to generate', default=join(_graal_home, 'make', 'build-graal.xml')) + + args = parser.parse_args(args) + + out = mx.XMLDoc() + + out.comment(""" + 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. Oracle designates this + particular file as subject to the "Classpath" exception as provided + by Oracle in the LICENSE file that accompanied this code. + + This code is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + version 2 for more details (a copy is included in the LICENSE file that + accompanied this code). + + You should have received a copy of the GNU General Public License version + 2 along with this work; if not, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + + Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + or visit www.oracle.com if you need additional information or have any + questions. +""") + + out.open('project', {'name' : 'graal', 'default' : 'main', 'basedir' : '.'}) + out.element('property', {'name' : 'src.dir', 'value' : '${gamma.dir}/graal'}) + out.element('property', {'name' : 'classes.dir', 'value' : '${shared.dir}/graal'}) + out.element('property', {'name' : 'jar.dir', 'value' : '${shared.dir}'}) + out.element('property', {'name' : 'jar.file', 'value' : '${jar.dir}/graal.jar'}) + + out.element('target', {'name' : 'main', 'depends' : 'jar'}) + + out.open('target', {'name' : 'compile'}) + out.element('mkdir', {'dir' : '${classes.dir}'}) + out.open('javac', {'destdir' : '${classes.dir}', 'debug' : 'on', 'includeantruntime' : 'false', }) + for p in mx.sorted_deps(mx.distribution('GRAAL').deps): + out.element('src', {'path' : '${src.dir}/' + p.name}) + out.element('compilerarg', {'value' : '-XDignore.symbol.file'}) + out.close('javac') + out.close('target') + + out.open('target', {'name' : 'jar', 'depends' : 'compile'}) + out.element('mkdir', {'dir' : '${jar.dir}'}) + out.element('jar', {'destfile' : '${jar.file}', 'basedir' : '${classes.dir}'}) + out.close('target') + + out.open('target', {'name' : 'clean'}) + out.element('delete', {'dir' : '${classes.dir}'}) + out.element('delete', {'file' : '${jar.filr}'}) + out.close('target') + + out.close('project') + + mx.update_file(args.buildfile, out.xml(indent=' ', newl='\n')) + def build(args, vm=None): """build the VM binary @@ -490,6 +530,8 @@ else: assert vm == 'graal', vm buildSuffix = 'graal' + + initantbuild([]) for build in builds: if build == 'ide-build-target': @@ -1132,6 +1174,7 @@ 'clean': [clean, ''], 'hsdis': [hsdis, '[att]'], 'hcfdis': [hcfdis, ''], + 'initantbuild' : [initantbuild, '[-options]'], 'igv' : [igv, ''], 'jdkhome': [jdkhome, ''], 'dacapo': [dacapo, '[[n] benchmark] [VM options|@DaCapo options]'],
--- a/mx/projects Fri Mar 15 21:18:33 2013 +0100 +++ b/mx/projects Fri Mar 15 21:18:47 2013 +0100 @@ -89,7 +89,7 @@ # graal.hotspot.amd64 project@com.oracle.graal.hotspot.amd64@subDir=graal project@com.oracle.graal.hotspot.amd64@sourceDirs=src -project@com.oracle.graal.hotspot.amd64@dependencies=com.oracle.graal.hotspot,com.oracle.graal.compiler.amd64 +project@com.oracle.graal.hotspot.amd64@dependencies=com.oracle.graal.hotspot,com.oracle.graal.compiler.amd64,com.oracle.graal.snippets.amd64 project@com.oracle.graal.hotspot.amd64@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hotspot.amd64@javaCompliance=1.7 @@ -182,6 +182,13 @@ project@com.oracle.graal.snippets@checkstyle=com.oracle.graal.graph project@com.oracle.graal.snippets@javaCompliance=1.7 +# graal.snippets.amd64 +project@com.oracle.graal.snippets.amd64@subDir=graal +project@com.oracle.graal.snippets.amd64@sourceDirs=src +project@com.oracle.graal.snippets.amd64@dependencies=com.oracle.graal.snippets +project@com.oracle.graal.snippets.amd64@checkstyle=com.oracle.graal.graph +project@com.oracle.graal.snippets.amd64@javaCompliance=1.7 + # graal.snippets.test project@com.oracle.graal.snippets.test@subDir=graal project@com.oracle.graal.snippets.test@sourceDirs=src
--- a/mxtool/mx.py Fri Mar 15 21:18:33 2013 +0100 +++ b/mxtool/mx.py Fri Mar 15 21:18:47 2013 +0100 @@ -630,6 +630,9 @@ e.ownerDocument = self return e + def comment(self, txt): + self.current.appendChild(self.createComment(txt)) + def open(self, tag, attributes={}, data=None): element = self.createElement(tag) for key, value in attributes.items():