Mercurial > hg > graal-compiler
view graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java @ 5233:efbb1e33e2f3
removed XIR prologue and epilogues - architecture and runtime specific subclass of Backend is now used instead
removed XIR ops: Align, StackOverflowCheck, PushFrame, PopFrame, RawBytes
enhanced disassembly to annotate marks
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Thu, 12 Apr 2012 15:55:03 +0200 |
parents | |
children | 15c857decc43 |
line wrap: on
line source
/* * 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.target.amd64; import static com.oracle.graal.hotspot.ri.HotSpotXirGenerator.*; import static com.oracle.max.asm.target.amd64.AMD64.*; import static com.oracle.max.cri.ci.CiCallingConvention.Type.*; import static com.oracle.max.cri.ci.CiValueUtil.*; import java.lang.reflect.*; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.compiler.target.amd64.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.ri.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; import com.oracle.max.asm.*; import com.oracle.max.asm.target.amd64.*; import com.oracle.max.asm.target.amd64.AMD64Assembler.ConditionFlag; import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ri.*; import com.oracle.max.cri.xir.*; public class HotSpotAMD64Backend extends Backend { public HotSpotAMD64Backend(RiRuntime runtime, CiTarget target) { super(runtime, target); } @Override public LIRGenerator newLIRGenerator(Graph graph, FrameMap frameMap, RiResolvedMethod method, LIR lir, RiXirGenerator xir) { return new AMD64LIRGenerator(graph, runtime, target, frameMap, method, lir, xir); } @Override public AMD64XirAssembler newXirAssembler() { return new AMD64XirAssembler(target); } class HotSpotFrameContext implements FrameContext { private final LIR lir; private boolean needsLeave; public HotSpotFrameContext(LIR lir) { this.lir = lir; } @Override public void enter(TargetMethodAssembler tasm) { FrameMap frameMap = tasm.frameMap; int frameSize = frameMap.frameSize(); if (frameSize != 0) { AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm; emitStackOverflowCheck(tasm, lir, false); asm.push(rbp); asm.movq(rbp, rsp); asm.decrementq(rsp, frameSize - 8); // account for the push of RBP above if (GraalOptions.ZapStackOnMethodEntry) { final int intSize = 4; for (int i = 0; i < frameSize / intSize; ++i) { asm.movl(new CiAddress(CiKind.Int, rsp.asValue(), i * intSize), 0xC1C1C1C1); } } CiCalleeSaveLayout csl = frameMap.registerConfig.getCalleeSaveLayout(); if (csl != null && csl.size != 0) { int frameToCSA = frameMap.offsetToCalleeSaveArea(); assert frameToCSA >= 0; asm.save(csl, frameToCSA); } needsLeave = true; } } @Override public void leave(TargetMethodAssembler tasm) { if (!needsLeave) { return; } int frameSize = tasm.frameMap.frameSize(); AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm; CiCalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout(); RiRegisterConfig regConfig = tasm.frameMap.registerConfig; if (csl != null && csl.size != 0) { tasm.targetMethod.setRegisterRestoreEpilogueOffset(asm.codeBuffer.position()); // saved all registers, restore all registers int frameToCSA = tasm.frameMap.offsetToCalleeSaveArea(); asm.restore(csl, frameToCSA); } asm.incrementq(rsp, frameSize - 8); // account for the pop of RBP below asm.pop(rbp); if (GraalOptions.GenSafepoints) { HotSpotVMConfig config = ((HotSpotRuntime) runtime).config; // If at the return point, then the frame has already been popped // so deoptimization cannot be performed here. The HotSpot runtime // detects this case - see the definition of frame::should_be_deoptimized() CiRegister scratch = regConfig.getScratchRegister(); if (config.isPollingPageFar) { asm.movq(scratch, config.safepointPollingAddress); tasm.recordMark(MARK_POLL_RETURN_FAR); asm.movq(scratch, new CiAddress(tasm.target.wordKind, scratch.asValue())); } else { tasm.recordMark(MARK_POLL_RETURN_NEAR); asm.movq(scratch, new CiAddress(tasm.target.wordKind, rip.asValue())); } } } } @Override public TargetMethodAssembler newAssembler(FrameMap frameMap, LIR lir) { AbstractAssembler masm = new AMD64MacroAssembler(target, frameMap.registerConfig); HotSpotFrameContext frameContext = new HotSpotFrameContext(lir); TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime, frameMap, masm, frameContext); tasm.setFrameSize(frameMap.frameSize()); tasm.targetMethod.setCustomStackAreaOffset(frameMap.offsetToCustomArea()); return tasm; } @Override public void emitCode(TargetMethodAssembler tasm, RiResolvedMethod method, LIR lir) { AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm; FrameMap frameMap = tasm.frameMap; RiRegisterConfig regConfig = frameMap.registerConfig; HotSpotVMConfig config = ((HotSpotRuntime) runtime).config; Label unverifiedStub = new Label(); CiRegister scratch = regConfig.getScratchRegister(); // Emit the prefix tasm.recordMark(MARK_OSR_ENTRY); tasm.recordMark(MARK_UNVERIFIED_ENTRY); boolean isStatic = Modifier.isStatic(method.accessFlags()); if (!isStatic) { CiCallingConvention cc = regConfig.getCallingConvention(JavaCallee, new CiKind[] {CiKind.Object}, target, false); CiRegister inlineCacheKlass = rax; // see definition of IC_Klass in c1_LIRAssembler_x86.cpp CiRegister receiver = asRegister(cc.locations[0]); CiAddress src = new CiAddress(target.wordKind, receiver.asValue(), config.hubOffset); asm.movq(scratch, src); asm.cmpq(inlineCacheKlass, scratch); asm.jcc(ConditionFlag.notEqual, unverifiedStub); } asm.align(config.codeEntryAlignment); tasm.recordMark(MARK_VERIFIED_ENTRY); // Emit code for the LIR lir.emitCode(tasm); // Emit the suffix (i.e. out-of-line stubs) CiRegister thread = r15; CiRegister exceptionOop = regConfig.getScratchRegister(); Label unwind = new Label(); asm.bind(unwind); tasm.recordMark(MARK_UNWIND_ENTRY); CiAddress exceptionOopField = new CiAddress(CiKind.Object, thread.asValue(), config.threadExceptionOopOffset); CiAddress exceptionPcField = new CiAddress(CiKind.Object, thread.asValue(), config.threadExceptionPcOffset); asm.movq(exceptionOop, exceptionOopField); asm.xorq(scratch, scratch); asm.movq(exceptionOopField, scratch); asm.movq(exceptionPcField, scratch); AMD64Call.directCall(tasm, asm, config.unwindExceptionStub, null); AMD64Call.shouldNotReachHere(tasm, asm); tasm.recordMark(MARK_EXCEPTION_HANDLER_ENTRY); AMD64Call.directCall(tasm, asm, config.handleExceptionStub, null); AMD64Call.shouldNotReachHere(tasm, asm); tasm.recordMark(MARK_DEOPT_HANDLER_ENTRY); AMD64Call.directCall(tasm, asm, config.handleDeoptStub, null); AMD64Call.shouldNotReachHere(tasm, asm); if (!isStatic) { asm.bind(unverifiedStub); AMD64Call.directJmp(tasm, asm, config.inlineCacheMissStub); } for (int i = 0; i < GraalOptions.MethodEndBreakpointGuards; ++i) { asm.int3(); } } }