# HG changeset patch # User Josef Eisl # Date 1396376782 -7200 # Node ID 93de07975ea974ff43ebc1509ec96866d8dcf2a5 # Parent 77ce71dff86b6e916cf28d2d0f15f28b56d59e69 Create dedicated BaselineBytecodeParser, BytecodeLIRBuilder and amd64 specialization. diff -r 77ce71dff86b -r 93de07975ea9 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java Tue Apr 01 20:26:22 2014 +0200 @@ -0,0 +1,620 @@ +/* + * Copyright (c) 2014, 2014, 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.baseline; + +import static com.oracle.graal.phases.GraalOptions.*; +import static java.lang.reflect.Modifier.*; + +import java.util.*; + +import com.oracle.graal.alloc.*; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.meta.ResolvedJavaType.Representation; +import com.oracle.graal.bytecode.*; +import com.oracle.graal.compiler.alloc.*; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; +import com.oracle.graal.graph.*; +import com.oracle.graal.java.*; +import com.oracle.graal.java.BciBlockMapping.BciBlock; +import com.oracle.graal.lir.*; +import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert; +import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.phases.*; + +public class BaselineBytecodeParser extends AbstractBytecodeParser implements BytecodeParserTool { + private Backend backend; + protected LIRGenerator gen; + private LIRGenerationResult lirGenRes; + private BytecodeLIRBuilder lirBuilder; + + public BaselineBytecodeParser(MetaAccessProvider metaAccess, ResolvedJavaMethod method, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, + LIRFrameStateBuilder frameState, BytecodeStream stream, ProfilingInfo profilingInfo, ConstantPool constantPool, int entryBCI, Backend backend) { + + super(metaAccess, method, graphBuilderConfig, optimisticOpts, frameState, stream, profilingInfo, constantPool, entryBCI); + this.backend = backend; + } + + public LIRGenerationResult getLIRGenerationResult() { + return lirGenRes; + } + + @Override + protected void build() { + if (PrintProfilingInformation.getValue()) { + TTY.println("Profiling info for " + MetaUtil.format("%H.%n(%p)", method)); + TTY.println(MetaUtil.indent(MetaUtil.profileToString(profilingInfo, method, CodeUtil.NEW_LINE), " ")); + } + + try (Indent indent = Debug.logAndIndent("build graph for %s", method)) { + + // compute the block map, setup exception handlers and get the entrypoint(s) + BciBlockMapping blockMap = BciBlockMapping.create(method); + // add predecessors + for (BciBlock block : blockMap.blocks) { + for (BciBlock successor : block.getSuccessors()) { + successor.getPredecessors().add(block); + } + } + + if (isSynchronized(method.getModifiers())) { + throw GraalInternalError.unimplemented("Handle synchronized methods"); + } + + // TODO: clear non live locals + + currentBlock = blockMap.startBlock; + if (blockMap.startBlock.isLoopHeader) { + throw GraalInternalError.unimplemented("Handle start block as loop header"); + } + + // add loops ? how do we add looks when we haven't parsed the bytecode? + + // create the control flow graph + LIRControlFlowGraph cfg = new LIRControlFlowGraph(blockMap.blocks.toArray(new BciBlock[0]), new Loop[0]); + + BlocksToDoubles blockProbabilities = new BlocksToDoubles(blockMap.blocks.size()); + for (BciBlock b : blockMap.blocks) { + blockProbabilities.put(b, 1); + } + + // create the LIR + List> linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blockMap.blocks.size(), blockMap.startBlock, blockProbabilities); + List> codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blockMap.blocks.size(), blockMap.startBlock, blockProbabilities); + LIR lir = new LIR(cfg, linearScanOrder, codeEmittingOrder); + + FrameMap frameMap = backend.newFrameMap(); + TargetDescription target = backend.getTarget(); + CallingConvention cc = CodeUtil.getCallingConvention(backend.getProviders().getCodeCache(), CallingConvention.Type.JavaCallee, method, false); + this.lirGenRes = backend.newLIRGenerationResult(lir, frameMap, null); + this.gen = backend.newLIRGenerator(cc, lirGenRes); + this.lirBuilder = backend.newBytecodeLIRBuilder(gen, this); + + try (Scope ds = Debug.scope("BackEnd", lir)) { + try (Scope s = Debug.scope("LIRGen", gen)) { + + // possibly add all the arguments to slots in the local variable array + + for (BciBlock block : blockMap.blocks) { + emitBlock(block); + } + + gen.beforeRegisterAllocation(); + Debug.dump(lir, "After LIR generation"); + } catch (Throwable e) { + throw Debug.handle(e); + } + + try (Scope s = Debug.scope("Allocator")) { + + if (backend.shouldAllocateRegisters()) { + new LinearScan(target, lir, frameMap).allocate(); + } + } catch (Throwable e) { + throw Debug.handle(e); + } + } catch (Throwable e) { + throw Debug.handle(e); + } + } catch (Throwable e) { + throw Debug.handle(e); + } + } + + private void emitBlock(BciBlock b) { + if (lirGenRes.getLIR().getLIRforBlock(b) == null) { + for (BciBlock pred : b.getPredecessors()) { + if (!b.isLoopHeader() || !pred.isLoopEnd()) { + emitBlock(pred); + } + } + processBlock(b); + } + } + + @Override + protected void handleUnresolvedLoadConstant(JavaType type) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void handleUnresolvedCheckCast(JavaType type, Value object) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void handleUnresolvedInstanceOf(JavaType type, Value object) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void handleUnresolvedNewInstance(JavaType type) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void handleUnresolvedNewObjectArray(JavaType type, Value length) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void handleUnresolvedNewMultiArray(JavaType type, List dims) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void handleUnresolvedLoadField(JavaField field, Value receiver) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void handleUnresolvedStoreField(JavaField field, Value value, Value receiver) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void handleUnresolvedExceptionType(Representation representation, JavaType type) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genLoadIndexed(Value index, Value array, Kind kind) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genStoreIndexed(Value array, Value index, Kind kind, Value value) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genIntegerAdd(Kind kind, Value x, Value y) { + return gen.emitAdd(x, y); + } + + @Override + protected Value genIntegerSub(Kind kind, Value x, Value y) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genIntegerMul(Kind kind, Value x, Value y) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genFloatAdd(Kind kind, Value x, Value y, boolean isStrictFP) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genFloatSub(Kind kind, Value x, Value y, boolean isStrictFP) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genFloatMul(Kind kind, Value x, Value y, boolean isStrictFP) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genFloatDiv(Kind kind, Value x, Value y, boolean isStrictFP) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genFloatRem(Kind kind, Value x, Value y, boolean isStrictFP) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genIntegerDiv(Kind kind, Value x, Value y) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genIntegerRem(Kind kind, Value x, Value y) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genNegateOp(Value x) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genLeftShift(Kind kind, Value x, Value y) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genRightShift(Kind kind, Value x, Value y) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genUnsignedRightShift(Kind kind, Value x, Value y) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genAnd(Kind kind, Value x, Value y) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genOr(Kind kind, Value x, Value y) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genXor(Kind kind, Value x, Value y) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genNormalizeCompare(Value x, Value y, boolean isUnorderedLess) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genFloatConvert(FloatConvert op, Value input) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genNarrow(Value input, int bitCount) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genSignExtend(Value input, int bitCount) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genZeroExtend(Value input, int bitCount) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genObjectEquals(Value x, Value y) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genIntegerEquals(Value x, Value y) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genIntegerLessThan(Value x, Value y) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genUnique(Value x) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genIf(Value condition, Value falseSuccessor, Value trueSuccessor, double d) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void genThrow() { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genCheckCast(ResolvedJavaType type, Value object, JavaTypeProfile profileForTypeCheck, boolean b) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genInstanceOf(ResolvedJavaType type, Value object, JavaTypeProfile profileForTypeCheck) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genConditional(Value x) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value createNewInstance(ResolvedJavaType type, boolean fillContents) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value createNewArray(ResolvedJavaType elementType, Value length, boolean fillContents) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value createNewMultiArray(ResolvedJavaType type, List dims) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genLoadField(Value receiver, ResolvedJavaField field) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void emitNullCheck(Value receiver) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void emitBoundsCheck(Value index, Value length) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genArrayLength(Value x) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genStoreField(Value receiver, ResolvedJavaField field, Value value) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void genInvokeStatic(JavaMethod target) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void genInvokeInterface(JavaMethod target) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void genInvokeDynamic(JavaMethod target) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void genInvokeVirtual(JavaMethod target) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void genInvokeSpecial(JavaMethod target) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void genReturn(Value x) { + if (x != null) { + AllocatableValue operand = gen.resultOperandFor(x.getKind()); + gen.emitMove(operand, x); + } + gen.emitReturn(x); + } + + @Override + protected Value genMonitorEnter(Value x) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genMonitorExit(Value x, Value returnValue) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void genJsr(int dest) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void genRet(int localIndex) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void setBlockSuccessor(Value switchNode, int i, Value createBlockTarget) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value genIntegerSwitch(Value value, int size, int[] keys, double[] keyProbabilities, int[] keySuccessors) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value appendConstant(Constant constant) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value append(Value v) { + return v; + } + + @Override + protected Value genDeoptimization() { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value createTarget(BciBlock trueBlock, AbstractFrameStateBuilder state) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected Value createBlockTarget(double probability, BciBlock bciBlock, AbstractFrameStateBuilder stateAfter) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void processBlock(BciBlock block) { + iterateBytecodesForBlock(block); + } + + @Override + protected void appendGoto(Value target) { + // TODO Auto-generated method stub + throw GraalInternalError.unimplemented("Auto-generated method stub"); + } + + @Override + protected void iterateBytecodesForBlock(BciBlock block) { + gen.doBlockStart(block); + + if (block == gen.getResult().getLIR().getControlFlowGraph().getStartBlock()) { + assert block.getPredecessorCount() == 0; + lirBuilder.emitPrologue(method); + } else { + assert block.getPredecessorCount() > 0; + } + + int endBCI = stream.endBCI(); + + stream.setBCI(block.startBci); + int bci = block.startBci; + BytecodesParsed.add(block.endBci - bci); + + while (bci < endBCI) { + + // read the opcode + int opcode = stream.currentBC(); + // traceState(); + traceInstruction(bci, opcode, bci == block.startBci); + + processBytecode(bci, opcode); + + stream.next(); + bci = stream.currentBCI(); + + if (bci < endBCI) { + if (bci > block.endBci) { + assert !block.getSuccessor(0).isExceptionEntry; + assert block.numNormalSuccessors() == 1; + // we fell through to the next block, add a goto and break + appendGoto(createTarget(block.getSuccessor(0), frameState)); + break; + } + } + } + + assert LIR.verifyBlock(gen.getResult().getLIR(), block); + gen.doBlockEnd(block); + } + + public void storeLocal(int i, Value x) { + frameState.storeLocal(i, x); + } + +} \ No newline at end of file diff -r 77ce71dff86b -r 93de07975ea9 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java --- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java Tue Apr 01 15:47:58 2014 +0200 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java Tue Apr 01 20:26:22 2014 +0200 @@ -31,20 +31,16 @@ import com.oracle.graal.alloc.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ResolvedJavaType.Representation; import com.oracle.graal.bytecode.*; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.alloc.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; -import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.java.*; -import com.oracle.graal.java.BciBlockMapping.BciBlock; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; -import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.phases.*; @@ -73,7 +69,7 @@ LIRFrameStateBuilder frameState = new LIRFrameStateBuilder(method); - BytecodeParser parser = new BytecodeParser(metaAccess, method, graphBuilderConfig, optimisticOpts, frameState, stream, profilingInfo, constantPool, entryBCI, backend); + BaselineBytecodeParser parser = new BaselineBytecodeParser(metaAccess, method, graphBuilderConfig, optimisticOpts, frameState, stream, profilingInfo, constantPool, entryBCI, backend); // build blocks and LIR instructions try { @@ -84,596 +80,8 @@ // emitCode Assumptions assumptions = new Assumptions(OptAssumptions.getValue()); - GraalCompiler.emitCode(backend, assumptions, parser.lirGenRes, compilationResult, installedCodeOwner, factory); + GraalCompiler.emitCode(backend, assumptions, parser.getLIRGenerationResult(), compilationResult, installedCodeOwner, factory); return compilationResult; } - - private static class BytecodeParser extends AbstractBytecodeParser { - private Backend backend; - private LIRGenerator lirGen; - private LIRGenerationResult lirGenRes; - private BciBlock[] loopHeaders; - - public BytecodeParser(MetaAccessProvider metaAccess, ResolvedJavaMethod method, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts, - LIRFrameStateBuilder frameState, BytecodeStream stream, ProfilingInfo profilingInfo, ConstantPool constantPool, int entryBCI, Backend backend) { - - super(metaAccess, method, graphBuilderConfig, optimisticOpts, frameState, stream, profilingInfo, constantPool, entryBCI); - this.backend = backend; - } - - protected void build() { - if (PrintProfilingInformation.getValue()) { - TTY.println("Profiling info for " + MetaUtil.format("%H.%n(%p)", method)); - TTY.println(MetaUtil.indent(MetaUtil.profileToString(profilingInfo, method, CodeUtil.NEW_LINE), " ")); - } - - try (Indent indent = Debug.logAndIndent("build graph for %s", method)) { - - // compute the block map, setup exception handlers and get the entrypoint(s) - BciBlockMapping blockMap = BciBlockMapping.create(method); - loopHeaders = blockMap.loopHeaders; - - // add predecessors - for (BciBlock block : blockMap.blocks) { - for (BciBlock successor : block.getSuccessors()) { - successor.getPredecessors().add(block); - } - } - - if (isSynchronized(method.getModifiers())) { - throw GraalInternalError.unimplemented("Handle synchronized methods"); - } - - // TODO: clear non live locals - - currentBlock = blockMap.startBlock; - if (blockMap.startBlock.isLoopHeader) { - throw GraalInternalError.unimplemented("Handle start block as loop header"); - } - - // add loops ? how do we add looks when we haven't parsed the bytecode? - - // create the control flow graph - LIRControlFlowGraph cfg = new LIRControlFlowGraph(blockMap.blocks.toArray(new BciBlock[0]), new Loop[0]); - - BlocksToDoubles blockProbabilities = new BlocksToDoubles(blockMap.blocks.size()); - for (BciBlock b : blockMap.blocks) { - blockProbabilities.put(b, 1); - } - - // create the LIR - List> linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blockMap.blocks.size(), blockMap.startBlock, blockProbabilities); - List> codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blockMap.blocks.size(), blockMap.startBlock, blockProbabilities); - LIR lir = new LIR(cfg, linearScanOrder, codeEmittingOrder); - - FrameMap frameMap = backend.newFrameMap(); - TargetDescription target = backend.getTarget(); - CallingConvention cc = CodeUtil.getCallingConvention(backend.getProviders().getCodeCache(), CallingConvention.Type.JavaCallee, method, false); - this.lirGenRes = backend.newLIRGenerationResult(lir, frameMap, null); - this.lirGen = backend.newLIRGenerator(cc, lirGenRes); - - try (Scope ds = Debug.scope("BackEnd", lir)) { - try (Scope s = Debug.scope("LIRGen", lirGen)) { - - // possibly add all the arguments to slots in the local variable array - - for (BciBlock block : blockMap.blocks) { - emitBlock(block); - } - - lirGen.beforeRegisterAllocation(); - Debug.dump(lir, "After LIR generation"); - } catch (Throwable e) { - throw Debug.handle(e); - } - - try (Scope s = Debug.scope("Allocator")) { - - if (backend.shouldAllocateRegisters()) { - new LinearScan(target, lir, frameMap).allocate(); - } - } catch (Throwable e) { - throw Debug.handle(e); - } - } catch (Throwable e) { - throw Debug.handle(e); - } - } catch (Throwable e) { - throw Debug.handle(e); - } - } - - private void emitBlock(BciBlock b) { - if (lirGenRes.getLIR().getLIRforBlock(b) == null) { - for (BciBlock pred : b.getPredecessors()) { - if (!b.isLoopHeader() || !pred.isLoopEnd()) { - emitBlock(pred); - } - } - processBlock(b); - } - } - - @Override - protected void handleUnresolvedLoadConstant(JavaType type) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void handleUnresolvedCheckCast(JavaType type, Value object) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void handleUnresolvedInstanceOf(JavaType type, Value object) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void handleUnresolvedNewInstance(JavaType type) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void handleUnresolvedNewObjectArray(JavaType type, Value length) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void handleUnresolvedNewMultiArray(JavaType type, List dims) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void handleUnresolvedLoadField(JavaField field, Value receiver) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void handleUnresolvedStoreField(JavaField field, Value value, Value receiver) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void handleUnresolvedExceptionType(Representation representation, JavaType type) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genLoadIndexed(Value index, Value array, Kind kind) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genStoreIndexed(Value array, Value index, Kind kind, Value value) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genIntegerAdd(Kind kind, Value x, Value y) { - return lirGen.emitAdd(x, y); - } - - @Override - protected Value genIntegerSub(Kind kind, Value x, Value y) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genIntegerMul(Kind kind, Value x, Value y) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genFloatAdd(Kind kind, Value x, Value y, boolean isStrictFP) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genFloatSub(Kind kind, Value x, Value y, boolean isStrictFP) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genFloatMul(Kind kind, Value x, Value y, boolean isStrictFP) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genFloatDiv(Kind kind, Value x, Value y, boolean isStrictFP) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genFloatRem(Kind kind, Value x, Value y, boolean isStrictFP) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genIntegerDiv(Kind kind, Value x, Value y) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genIntegerRem(Kind kind, Value x, Value y) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genNegateOp(Value x) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genLeftShift(Kind kind, Value x, Value y) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genRightShift(Kind kind, Value x, Value y) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genUnsignedRightShift(Kind kind, Value x, Value y) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genAnd(Kind kind, Value x, Value y) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genOr(Kind kind, Value x, Value y) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genXor(Kind kind, Value x, Value y) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genNormalizeCompare(Value x, Value y, boolean isUnorderedLess) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genFloatConvert(FloatConvert op, Value input) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genNarrow(Value input, int bitCount) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genSignExtend(Value input, int bitCount) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genZeroExtend(Value input, int bitCount) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genObjectEquals(Value x, Value y) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genIntegerEquals(Value x, Value y) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genIntegerLessThan(Value x, Value y) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genUnique(Value x) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genIf(Value condition, Value falseSuccessor, Value trueSuccessor, double d) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void genThrow() { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genCheckCast(ResolvedJavaType type, Value object, JavaTypeProfile profileForTypeCheck, boolean b) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genInstanceOf(ResolvedJavaType type, Value object, JavaTypeProfile profileForTypeCheck) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genConditional(Value x) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value createNewInstance(ResolvedJavaType type, boolean fillContents) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value createNewArray(ResolvedJavaType elementType, Value length, boolean fillContents) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value createNewMultiArray(ResolvedJavaType type, List dims) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genLoadField(Value receiver, ResolvedJavaField field) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void emitNullCheck(Value receiver) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void emitBoundsCheck(Value index, Value length) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genArrayLength(Value x) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genStoreField(Value receiver, ResolvedJavaField field, Value value) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void genInvokeStatic(JavaMethod target) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void genInvokeInterface(JavaMethod target) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void genInvokeDynamic(JavaMethod target) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void genInvokeVirtual(JavaMethod target) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void genInvokeSpecial(JavaMethod target) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void genReturn(Value x) { - lirGen.emitReturn(x); - } - - @Override - protected Value genMonitorEnter(Value x) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genMonitorExit(Value x, Value returnValue) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void genJsr(int dest) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void genRet(int localIndex) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void setBlockSuccessor(Value switchNode, int i, Value createBlockTarget) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value genIntegerSwitch(Value value, int size, int[] keys, double[] keyProbabilities, int[] keySuccessors) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value appendConstant(Constant constant) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value append(Value v) { - return v; - } - - @Override - protected Value genDeoptimization() { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value createTarget(BciBlock trueBlock, AbstractFrameStateBuilder state) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected Value createBlockTarget(double probability, BciBlock bciBlock, AbstractFrameStateBuilder stateAfter) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void processBlock(BciBlock block) { - iterateBytecodesForBlock(block); - } - - @Override - protected void appendGoto(Value target) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); - } - - @Override - protected void iterateBytecodesForBlock(BciBlock block) { - lirGen.doBlockStart(block); - - if (block == lirGen.getResult().getLIR().getControlFlowGraph().getStartBlock()) { - assert block.getPredecessorCount() == 0; - emitPrologue(); - } else { - assert block.getPredecessorCount() > 0; - } - - int endBCI = stream.endBCI(); - - stream.setBCI(block.startBci); - int bci = block.startBci; - BytecodesParsed.add(block.endBci - bci); - - while (bci < endBCI) { - - // read the opcode - int opcode = stream.currentBC(); - // traceState(); - traceInstruction(bci, opcode, bci == block.startBci); - - processBytecode(bci, opcode); - - stream.next(); - bci = stream.currentBCI(); - - if (bci < endBCI) { - if (bci > block.endBci) { - assert !block.getSuccessor(0).isExceptionEntry; - assert block.numNormalSuccessors() == 1; - // we fell through to the next block, add a goto and break - appendGoto(createTarget(block.getSuccessor(0), frameState)); - break; - } - } - } - - assert LIR.verifyBlock(lirGen.getResult().getLIR(), block); - lirGen.doBlockEnd(block); - } - - protected void emitPrologue() { - CallingConvention incomingArguments = lirGen.getCallingConvention(); - - Value[] params = new Value[incomingArguments.getArgumentCount()]; - for (int i = 0; i < params.length; i++) { - params[i] = LIRGenerator.toStackKind(incomingArguments.getArgument(i)); - if (ValueUtil.isStackSlot(params[i])) { - StackSlot slot = ValueUtil.asStackSlot(params[i]); - if (slot.isInCallerFrame() && !lirGen.getResult().getLIR().hasArgInCallerFrame()) { - lirGen.getResult().getLIR().setHasArgInCallerFrame(); - } - } - } - - lirGen.emitIncomingValues(params); - - Signature sig = method.getSignature(); - boolean isStatic = Modifier.isStatic(method.getModifiers()); - for (int i = 0; i < sig.getParameterCount(!isStatic); i++) { - Value paramValue = params[i]; - assert paramValue.getKind() == sig.getParameterKind(i).getStackKind(); - frameState.storeLocal(i, lirGen.emitMove(paramValue)); - } - - } - - } } diff -r 77ce71dff86b -r 93de07975ea9 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/BytecodeLIRBuilder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/BytecodeLIRBuilder.java Tue Apr 01 20:26:22 2014 +0200 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2014, 2014, 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.gen; + +import java.lang.reflect.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; + +public class BytecodeLIRBuilder { + protected final LIRGenerator gen; + protected final BytecodeParserTool parser; + + public BytecodeLIRBuilder(LIRGenerator gen, BytecodeParserTool parser) { + this.gen = gen; + this.parser = parser; + } + + public void emitPrologue(ResolvedJavaMethod method) { + CallingConvention incomingArguments = gen.getCallingConvention(); + + Value[] params = new Value[incomingArguments.getArgumentCount()]; + for (int i = 0; i < params.length; i++) { + params[i] = LIRGenerator.toStackKind(incomingArguments.getArgument(i)); + if (ValueUtil.isStackSlot(params[i])) { + StackSlot slot = ValueUtil.asStackSlot(params[i]); + if (slot.isInCallerFrame() && !gen.getResult().getLIR().hasArgInCallerFrame()) { + gen.getResult().getLIR().setHasArgInCallerFrame(); + } + } + } + + gen.emitIncomingValues(params); + + Signature sig = method.getSignature(); + boolean isStatic = Modifier.isStatic(method.getModifiers()); + for (int i = 0; i < sig.getParameterCount(!isStatic); i++) { + Value paramValue = params[i]; + assert paramValue.getKind() == sig.getParameterKind(i).getStackKind(); + parser.storeLocal(i, gen.emitMove(paramValue)); + } + + } + +} \ No newline at end of file diff -r 77ce71dff86b -r 93de07975ea9 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/BytecodeParserTool.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/BytecodeParserTool.java Tue Apr 01 20:26:22 2014 +0200 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2014, 2014, 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.gen; + +import com.oracle.graal.api.meta.*; + +/** + * visible interface of bytecode parsers + */ +public interface BytecodeParserTool { + + void storeLocal(int i, Value x); + +} diff -r 77ce71dff86b -r 93de07975ea9 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Tue Apr 01 15:47:58 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Tue Apr 01 20:26:22 2014 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.nodes.*; @@ -72,6 +73,14 @@ public abstract NodeLIRBuilder newNodeLIRGenerator(StructuredGraph graph, LIRGenerator lirGen); /** + * @param gen the LIRGenerator the BytecodeLIRBuilder should use + * @param parser the bytecode parser the BytecodeLIRBuilder should use + */ + public BytecodeLIRBuilder newBytecodeLIRBuilder(LIRGenerator gen, BytecodeParserTool parser) { + throw GraalInternalError.unimplemented("Baseline compilation is not available for this Backend!"); + } + + /** * Creates the assembler used to emit the machine code. */ protected abstract Assembler createAssembler(FrameMap frameMap); diff -r 77ce71dff86b -r 93de07975ea9 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Tue Apr 01 15:47:58 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Tue Apr 01 20:26:22 2014 +0200 @@ -86,6 +86,12 @@ return new AMD64HotSpotNodeLIRBuilder(graph, lirGen); } + @Override + public BytecodeLIRBuilder newBytecodeLIRBuilder(LIRGenerator gen, BytecodeParserTool parser) { + return new AMD64HotSpotBytecodeLIRBuilder(gen, parser); + + } + /** * Emits code to do stack overflow checking. * diff -r 77ce71dff86b -r 93de07975ea9 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBytecodeLIRBuilder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBytecodeLIRBuilder.java Tue Apr 01 20:26:22 2014 +0200 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014, 2014, 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 java.lang.reflect.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.hotspot.amd64.AMD64HotSpotLIRGenerator.SaveRbp; +import com.oracle.graal.lir.StandardOp.NoOp; + +public class AMD64HotSpotBytecodeLIRBuilder extends BytecodeLIRBuilder { + + public AMD64HotSpotBytecodeLIRBuilder(LIRGenerator gen, BytecodeParserTool parser) { + super(gen, parser); + } + + private AMD64HotSpotLIRGenerator getGen() { + return (AMD64HotSpotLIRGenerator) gen; + } + + private SaveRbp getSaveRbp() { + return getGen().saveRbp; + } + + private void setSaveRbp(SaveRbp saveRbp) { + getGen().saveRbp = saveRbp; + } + + @Override + public void emitPrologue(ResolvedJavaMethod method) { + CallingConvention incomingArguments = gen.getCallingConvention(); + + Value[] params = new Value[incomingArguments.getArgumentCount() + 1]; + for (int i = 0; i < params.length - 1; i++) { + params[i] = LIRGenerator.toStackKind(incomingArguments.getArgument(i)); + if (ValueUtil.isStackSlot(params[i])) { + StackSlot slot = ValueUtil.asStackSlot(params[i]); + if (slot.isInCallerFrame() && !gen.getResult().getLIR().hasArgInCallerFrame()) { + gen.getResult().getLIR().setHasArgInCallerFrame(); + } + } + } + params[params.length - 1] = rbp.asValue(Kind.Long); + + gen.emitIncomingValues(params); + + setSaveRbp(((AMD64HotSpotLIRGenerator) gen).new SaveRbp(new NoOp(gen.getCurrentBlock(), gen.getResult().getLIR().getLIRforBlock(gen.getCurrentBlock()).size()))); + gen.append(getSaveRbp().placeholder); + + Signature sig = method.getSignature(); + boolean isStatic = Modifier.isStatic(method.getModifiers()); + for (int i = 0; i < sig.getParameterCount(!isStatic); i++) { + Value paramValue = params[i]; + assert paramValue.getKind() == sig.getParameterKind(i).getStackKind(); + parser.storeLocal(i, gen.emitMove(paramValue)); + } + } + +}