# HG changeset patch # User Doug Simon # Date 1349219883 -7200 # Node ID 75f130f2b30f26d497609606eba9ed3d584593b0 # Parent df02fa2bce58ea9fcdc2170f5c32589a57acf328 moved AMD64 specific HotSpot code in com.oracle.graal.hotspot.amd64 project diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64BreakpointOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64BreakpointOp.java Wed Oct 03 01:18:03 2012 +0200 @@ -0,0 +1,52 @@ +/* + * 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.hotspot.amd64; + +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.max.asm.amd64.*; + +/** + * Emits a breakpoint. + */ +@Opcode("BREAKPOINT") +public class AMD64BreakpointOp extends AMD64LIRInstruction { + + /** + * A set of values loaded into the Java ABI parameter locations (for inspection by a debugger). + */ + @Use({REG, STACK}) protected Value[] parameters; + + public AMD64BreakpointOp(Value[] parameters) { + this.parameters = parameters; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler asm) { + asm.int3(); + } +} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DirectCallOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DirectCallOp.java Wed Oct 03 01:18:03 2012 +0200 @@ -0,0 +1,105 @@ +/* + * 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.nodes.java.MethodCallTargetNode.InvokeKind.*; + +import com.oracle.graal.api.code.CompilationResult.Mark; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.bridge.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.*; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; +import com.oracle.max.asm.*; +import com.oracle.max.asm.amd64.*; + +/** + * A direct call that complies with the conventions for such calls in HotSpot. + * In particular, for calls using an inline cache, a MOVE instruction is + * emitted just prior to the aligned direct call. This instruction + * (which moves null in RAX) is patched by the C++ Graal code to replace the + * null constant with Universe::non_oop_word(), a special sentinel + * used for the initial value of the klassOop in an inline cache. + *

+ * For non-inline cache calls, a static call stub is emitted. + */ +@Opcode("CALL_DIRECT") +final class AMD64DirectCallOp extends DirectCallOp { + + /** + * The mark emitted at the position of the direct call instruction. + * This is only recorded for calls that have an associated static + * call stub (i.e., {@code invokeKind == Static || invokeKind == Special}). + */ + Mark callsiteMark; + + private final InvokeKind invokeKind; + + AMD64DirectCallOp(Object targetMethod, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind, LIR lir) { + super(targetMethod, result, parameters, temps, state); + this.invokeKind = invokeKind; + + if (invokeKind == Static || invokeKind == Special) { + lir.stubs.add(new AMD64Code() { + public String description() { + return "static call stub for Invoke" + AMD64DirectCallOp.this.invokeKind; + } + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + assert callsiteMark != null : "static call site has not yet been emitted"; + tasm.recordMark(Marks.MARK_STATIC_CALL_STUB, callsiteMark); + masm.movq(AMD64.rbx, 0L); + Label dummy = new Label(); + masm.jmp(dummy); + masm.bind(dummy); + } + }); + } + + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + if (invokeKind == Static || invokeKind == Special) { + tasm.recordMark(invokeKind == Static ? Marks.MARK_INVOKESTATIC : Marks.MARK_INVOKESPECIAL); + } else { + assert invokeKind == Virtual || invokeKind == Interface; + // The mark for an invocation that uses an inline cache must be placed at the instruction + // that loads the klassOop from the inline cache so that the C++ code can find it + // and replace the inline null value with Universe::non_oop_word() + tasm.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE); + AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Object), Constant.NULL_OBJECT); + } + + emitAlignmentForDirectCall(tasm, masm); + + if (invokeKind == Static || invokeKind == Special) { + callsiteMark = tasm.recordMark(null); + } + + AMD64Call.directCall(tasm, masm, targetMethod, state); + } +} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Wed Oct 03 01:18:03 2012 +0200 @@ -0,0 +1,349 @@ +/* + * 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.api.code.CallingConvention.Type.*; +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.api.meta.Value.*; +import static com.oracle.max.asm.amd64.AMD64.*; + +import java.lang.reflect.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.Register.RegisterFlag; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.*; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.target.amd64.*; +import com.oracle.graal.graph.*; +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.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.max.asm.*; +import com.oracle.max.asm.amd64.*; +import com.oracle.max.asm.amd64.AMD64Assembler.*; + +/** + * HotSpot AMD64 specific backend. + */ +public class AMD64HotSpotBackend extends HotSpotBackend { + + public AMD64HotSpotBackend(HotSpotRuntime runtime, TargetDescription target) { + super(runtime, target); + HotSpotVMConfig c = runtime.config; + Kind word = target.wordKind; + + Register[] jargs = runtime.getGlobalStubRegisterConfig().getCallingConventionRegisters(RuntimeCall, RegisterFlag.CPU); + Register jarg0 = jargs[0]; + Register jarg1 = jargs[1]; + Register jarg2 = jargs[2]; + + addStub(MONITORENTER_STUB_NAME, c.fastMonitorEnterStub, + /* temps */ new Register[] {rax, rbx}, + /* ret */ IllegalValue, + /* arg0: object */ jarg0.asValue(Kind.Object), + /* arg1: lock */ jarg1.asValue(word)); + + addStub(MONITOREXIT_STUB_NAME, c.fastMonitorExitStub, + /* temps */ new Register[] {rax, rbx}, + /* ret */ IllegalValue, + /* arg0: object */ jarg0.asValue(Kind.Object), + /* arg1: lock */ jarg1.asValue(word)); + + addStub(NEW_OBJECT_ARRAY_STUB_NAME, c.newObjectArrayStub, + /* temps */ new Register[] {rcx, rdi, rsi}, + /* ret */ rax.asValue(Kind.Object), + /* arg0: hub */ rdx.asValue(Kind.Object), + /* arg1: length */ rbx.asValue(Kind.Int)); + + addStub(NEW_TYPE_ARRAY_STUB_NAME, c.newTypeArrayStub, + /* temps */ new Register[] {rcx, rdi, rsi}, + /* ret */ rax.asValue(Kind.Object), + /* arg0: hub */ rdx.asValue(Kind.Object), + /* arg1: length */ rbx.asValue(Kind.Int)); + + addStub(NEW_INSTANCE_STUB_NAME, c.newInstanceStub, + /* temps */ null, + /* ret */ rax.asValue(Kind.Object), + /* arg0: hub */ rdx.asValue(Kind.Object)); + + addStub(NEW_MULTI_ARRAY_STUB_NAME, c.newMultiArrayStub, + /* temps */ null, + /* ret */ rax.asValue(Kind.Object), + /* arg0: hub */ rax.asValue(Kind.Object), + /* arg1: rank */ rbx.asValue(Kind.Int), + /* arg2: dims */ rcx.asValue(word)); + + addStub(VERIFY_OOP_STUB_NAME, c.verifyOopStub, + /* temps */ null, + /* ret */ IllegalValue, + /* arg0: object */ r13.asValue(Kind.Object)); + + addStub(VM_ERROR_STUB_NAME, c.vmErrorStub, + /* temps */ null, + /* ret */ IllegalValue, + /* arg0: where */ jarg0.asValue(Kind.Object), + /* arg1: format */ jarg1.asValue(Kind.Object), + /* arg2: value */ jarg2.asValue(Kind.Object)); + } + + @Override + public LIRGenerator newLIRGenerator(Graph graph, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) { + 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(Graph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) { + super(graph, runtime, target, frameMap, method, lir); + } + + @Override + public void visitSafepointNode(SafepointNode i) { + LIRFrameState info = state(); + append(new AMD64SafepointOp(info, runtime().config)); + } + + @Override + public void visitBreakpointNode(BreakpointNode i) { + Kind[] sig = new Kind[i.arguments.size()]; + int pos = 0; + for (ValueNode arg : i.arguments) { + sig[pos++] = arg.kind(); + } + + CallingConvention cc = frameMap.registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, Kind.Void, sig, target(), false); + Value[] parameters = visitInvokeArguments(cc, i.arguments); + append(new AMD64BreakpointOp(parameters)); + } + + @Override + public void visitExceptionObject(ExceptionObjectNode x) { + HotSpotVMConfig config = runtime().config; + RegisterValue thread = runtime().threadRegister().asValue(); + Address exceptionAddress = new Address(Kind.Object, thread, config.threadExceptionOopOffset); + Address pcAddress = new Address(Kind.Long, thread, config.threadExceptionPcOffset); + Value exception = emitLoad(exceptionAddress, false); + emitStore(exceptionAddress, Constant.NULL_OBJECT, false); + emitStore(pcAddress, 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; + Address address; + Value index = operand(x.offset()); + if (ValueUtil.isConstant(index) && NumUtil.isInt(ValueUtil.asConstant(index).asLong() + disp)) { + disp += (int) ValueUtil.asConstant(index).asLong(); + address = new Address(kind, load(operand(x.object())), disp); + } else { + address = new Address(kind, load(operand(x.object())), load(index), Address.Scale.Times1, disp); + } + + RegisterValue rax = AMD64.rax.asValue(kind); + emitMove(expected, rax); + append(new CompareAndSwapOp(rax, address, rax, newVal)); + + Variable result = newVariable(x.kind()); + emitMove(rax, result); + 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) { + append(new AMD64DirectCallOp(callTarget.target(), result, parameters, temps, callState, ((HotSpotDirectCallTargetNode) callTarget).invokeKind(), lir)); + } + + @Override + protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { + Value methodOop = AMD64.rbx.asValue(); + emitMove(operand(((HotSpotIndirectCallTargetNode) callTarget).methodOop()), methodOop); + Value targetAddress = AMD64.rax.asValue(); + emitMove(operand(callTarget.computedAddress()), targetAddress); + append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, temps, methodOop, targetAddress, callState)); + } + } + + class HotSpotFrameContext implements FrameContext { + + @Override + public void enter(TargetMethodAssembler tasm) { + FrameMap frameMap = tasm.frameMap; + int frameSize = frameMap.frameSize(); + + AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm; + emitStackOverflowCheck(tasm, 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 Address(Kind.Int, rsp.asValue(), i * intSize), 0xC1C1C1C1); + } + } + CalleeSaveLayout csl = frameMap.registerConfig.getCalleeSaveLayout(); + if (csl != null && csl.size != 0) { + int frameToCSA = frameMap.offsetToCalleeSaveArea(); + assert frameToCSA >= 0; + asm.save(csl, frameToCSA); + } + } + + @Override + public void leave(TargetMethodAssembler tasm) { + int frameSize = tasm.frameMap.frameSize(); + AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm; + CalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout(); + RegisterConfig 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 = 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() + + Register scratch = regConfig.getScratchRegister(); + if (config.isPollingPageFar) { + asm.movq(scratch, config.safepointPollingAddress); + tasm.recordMark(Marks.MARK_POLL_RETURN_FAR); + asm.movq(scratch, new Address(tasm.target.wordKind, scratch.asValue())); + } else { + tasm.recordMark(Marks.MARK_POLL_RETURN_NEAR); + asm.movq(scratch, new Address(tasm.target.wordKind, rip.asValue())); + } + } + } + } + + @Override + public TargetMethodAssembler newAssembler(FrameMap frameMap, LIR lir) { + // 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 canOmitFrame = + frameMap.frameSize() == frameMap.initialFrameSize && + frameMap.registerConfig.getCalleeSaveLayout().registers.length == 0 && + !lir.hasArgInCallerFrame() && + !lir.hasDebugInfo(); + + AbstractAssembler masm = new AMD64MacroAssembler(target, frameMap.registerConfig); + HotSpotFrameContext frameContext = canOmitFrame ? null : new HotSpotFrameContext(); + TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, lir.stubs); + tasm.setFrameSize(frameMap.frameSize()); + tasm.targetMethod.setCustomStackAreaOffset(frameMap.offsetToCustomArea()); + return tasm; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, ResolvedJavaMethod method, LIR lir) { + AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm; + FrameMap frameMap = tasm.frameMap; + RegisterConfig regConfig = frameMap.registerConfig; + HotSpotVMConfig config = runtime().config; + Label unverifiedStub = new Label(); + + // Emit the prefix + tasm.recordMark(Marks.MARK_OSR_ENTRY); + + boolean isStatic = Modifier.isStatic(method.accessFlags()); + if (!isStatic) { + tasm.recordMark(Marks.MARK_UNVERIFIED_ENTRY); + CallingConvention cc = regConfig.getCallingConvention(JavaCallee, Kind.Void, new Kind[] {Kind.Object}, target, false); + Register inlineCacheKlass = rax; // see definition of IC_Klass in c1_LIRAssembler_x86.cpp + Register receiver = asRegister(cc.getArgument(0)); + Address src = new Address(target.wordKind, receiver.asValue(), config.hubOffset); + + asm.cmpq(inlineCacheKlass, src); + asm.jcc(ConditionFlag.notEqual, unverifiedStub); + } + + asm.align(config.codeEntryAlignment); + tasm.recordMark(Marks.MARK_VERIFIED_ENTRY); + + // Emit code for the LIR + lir.emitCode(tasm); + + boolean frameOmitted = tasm.frameContext == null; + if (!frameOmitted) { + tasm.recordMark(Marks.MARK_EXCEPTION_HANDLER_ENTRY); + AMD64Call.directCall(tasm, asm, config.handleExceptionStub, null); + AMD64Call.shouldNotReachHere(tasm, asm); + + tasm.recordMark(Marks.MARK_DEOPT_HANDLER_ENTRY); + AMD64Call.directCall(tasm, asm, config.handleDeoptStub, null); + AMD64Call.shouldNotReachHere(tasm, asm); + } 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(); + } + + if (!isStatic) { + asm.bind(unverifiedStub); + AMD64Call.directJmp(tasm, asm, config.inlineCacheMissStub); + } + + for (int i = 0; i < GraalOptions.MethodEndBreakpointGuards; ++i) { + asm.int3(); + } + } +} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java Wed Oct 03 01:18:03 2012 +0200 @@ -0,0 +1,64 @@ +/* + * 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 com.oracle.graal.api.code.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.max.asm.amd64.*; + +/** + * AMD64 specific implementation of {@link HotSpotGraalRuntime}. + */ +final class AMD64HotSpotGraalRuntime extends HotSpotGraalRuntime { + + private AMD64HotSpotGraalRuntime() { + } + + /** + * Called from native code. + */ + @SuppressWarnings("unused") + private static HotSpotGraalRuntime initialize() { + return new AMD64HotSpotGraalRuntime(); + } + + @Override + protected TargetDescription createTarget() { + final int wordSize = 8; + final int stackFrameAlignment = 16; + return new TargetDescription(new AMD64(), true, stackFrameAlignment, config.vmPageSize, wordSize, true, true); + } + + @Override + protected HotSpotBackend createBackend() { + return new AMD64HotSpotBackend(getRuntime(), getTarget()); + } + + @Override + protected HotSpotRuntime createRuntime() { + return new AMD64HotSpotRuntime(config, this); + } + + +} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Wed Oct 03 01:18:03 2012 +0200 @@ -0,0 +1,211 @@ +/* + * 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.hotspot.amd64; + +import static com.oracle.max.asm.amd64.AMD64.*; + +import java.util.*; + +import com.oracle.max.asm.amd64.*; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CallingConvention.*; +import com.oracle.graal.api.code.Register.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.*; + +public class AMD64HotSpotRegisterConfig implements RegisterConfig { + + // be careful - the contents of this array are duplicated in graal_CodeInstaller.cpp + private final Register[] allocatable = { + rax, rbx, rcx, rdx, rsi, rdi, r8, r9, /* r10, */r11, r12, r13, r14, /*r15*/ + xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, + xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 + }; + + private final EnumMap categorized = Register.categorize(allocatable); + + private final RegisterAttributes[] attributesMap; + + @Override + public Register[] getAllocatableRegisters() { + return allocatable; + } + + @Override + public EnumMap getCategorizedAllocatableRegisters() { + return categorized; + } + + @Override + public RegisterAttributes[] getAttributesMap() { + return attributesMap; + } + + private final Register[] generalParameterRegisters; + private final Register[] xmmParameterRegisters = {xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7}; + private final Register[] allParameterRegisters; + + private final CalleeSaveLayout csl; + + public AMD64HotSpotRegisterConfig(HotSpotVMConfig config, boolean globalStubConfig) { + if (config.windowsOs) { + generalParameterRegisters = new Register[] {rdx, r8, r9, rdi, rsi, rcx}; + } else { + generalParameterRegisters = new Register[] {rsi, rdx, rcx, r8, r9, rdi}; + } + + if (globalStubConfig) { + Register[] regs = { + rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, + r8, r9, r10, r11, r12, r13, r14, r15, + xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, + xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 + }; + 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); + } + + attributesMap = RegisterAttributes.createMap(this, AMD64.allRegisters); + allParameterRegisters = Arrays.copyOf(generalParameterRegisters, generalParameterRegisters.length + xmmParameterRegisters.length); + System.arraycopy(xmmParameterRegisters, 0, allParameterRegisters, generalParameterRegisters.length, xmmParameterRegisters.length); + } + + @Override + public Register[] getCallerSaveRegisters() { + return getAllocatableRegisters(); + } + + @Override + public Register getRegisterForRole(int index) { + throw new UnsupportedOperationException(); + } + + @Override + public CallingConvention getCallingConvention(Type type, Kind returnKind, Kind[] parameters, TargetDescription target, boolean stackOnly) { + if (type == Type.NativeCall) { + throw new UnsupportedOperationException(); + } + return callingConvention(returnKind, parameters, type, target, stackOnly); + } + + public Register[] getCallingConventionRegisters(Type type, RegisterFlag flag) { + return allParameterRegisters; + } + + private CallingConvention callingConvention(Kind returnKind, Kind[] kinds, Type type, TargetDescription target, boolean stackOnly) { + Value[] locations = new Value[kinds.length]; + + int currentGeneral = 0; + int currentXMM = 0; + int currentStackOffset = 0; + + for (int i = 0; i < kinds.length; i++) { + final Kind kind = kinds[i]; + + switch (kind) { + case Byte: + case Boolean: + case Short: + case Char: + case Int: + case Long: + case Object: + if (!stackOnly && currentGeneral < generalParameterRegisters.length) { + Register register = generalParameterRegisters[currentGeneral++]; + locations[i] = register.asValue(kind); + } + break; + case Float: + case Double: + if (!stackOnly && currentXMM < xmmParameterRegisters.length) { + Register register = xmmParameterRegisters[currentXMM++]; + locations[i] = register.asValue(kind); + } + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + + if (locations[i] == null) { + locations[i] = StackSlot.get(kind.stackKind(), currentStackOffset, !type.out); + currentStackOffset += Math.max(target.sizeInBytes(kind), target.wordSize); + } + } + + Value returnLocation = returnKind.isVoid() ? Value.IllegalValue : getReturnRegister(returnKind).asValue(returnKind); + return new CallingConvention(currentStackOffset, returnLocation, locations); + } + + @Override + public Register getReturnRegister(Kind kind) { + switch (kind) { + case Boolean: + case Byte: + case Char: + case Short: + case Int: + case Long: + case Object: + return rax; + case Float: + case Double: + return xmm0; + case Void: + case Illegal: + return null; + default: + throw new UnsupportedOperationException("no return register for type " + kind); + } + } + + @Override + public Register getScratchRegister() { + return r10; + } + + @Override + public Register getFrameRegister() { + return rsp; + } + + public CalleeSaveLayout getCalleeSaveLayout() { + return csl; + } + + @Override + public String toString() { + String res = String.format( + "Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" + + "CallerSave: " + Arrays.toString(getCallerSaveRegisters()) + "%n" + + "CalleeSave: " + getCalleeSaveLayout() + "%n" + + "Scratch: " + getScratchRegister() + "%n"); + return res; + } +} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Wed Oct 03 01:18:03 2012 +0200 @@ -0,0 +1,52 @@ +/* + * 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.max.asm.amd64.AMD64.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; + +public class AMD64HotSpotRuntime extends HotSpotRuntime { + + public AMD64HotSpotRuntime(HotSpotVMConfig config, HotSpotGraalRuntime graalRuntime) { + super(config, graalRuntime); + } + + @Override + public Register threadRegister() { + return r15; + } + + @Override + public Register stackPointerRegister() { + return rsp; + } + + @Override + protected RegisterConfig createRegisterConfig(boolean globalStubConfig) { + return new AMD64HotSpotRegisterConfig(config, globalStubConfig); + } + +} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java Wed Oct 03 01:18:03 2012 +0200 @@ -0,0 +1,72 @@ +/* + * 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.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.hotspot.bridge.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.amd64.AMD64Call.IndirectCallOp; +import com.oracle.graal.lir.asm.*; +import com.oracle.max.asm.amd64.*; + +/** + * A register indirect call that complies with the extra conventions for such calls in HotSpot. + * In particular, the methodOop of the callee must be in RBX for the case where a vtable entry's + * _from_compiled_entry is the address of an C2I adapter. Such adapters expect the target + * method to be in RBX. + */ +@Opcode("CALL_INDIRECT") +final class AMD64IndirectCallOp extends IndirectCallOp { + + /** + * Vtable stubs expect the methodOop in RBX. + */ + public static final Register METHOD_OOP = AMD64.rbx; + + @Use({REG}) protected Value methodOop; + + AMD64IndirectCallOp(Object targetMethod, Value result, Value[] parameters, Value[] temps, Value methodOop, Value targetAddress, LIRFrameState state) { + super(targetMethod, result, parameters, temps, targetAddress, state); + this.methodOop = methodOop; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + tasm.recordMark(Marks.MARK_INLINE_INVOKEVIRTUAL); + Register callReg = asRegister(targetAddress); + assert callReg != METHOD_OOP; + AMD64Call.indirectCall(tasm, masm, callReg, targetMethod, state); + } + + @Override + protected void verify() { + super.verify(); + assert asRegister(methodOop) == METHOD_OOP; + } +} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64SafepointOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64SafepointOp.java Wed Oct 03 01:18:03 2012 +0200 @@ -0,0 +1,65 @@ +/* + * 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.hotspot.amd64; + +import static com.oracle.max.asm.amd64.AMD64.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.bridge.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.max.asm.amd64.*; + +/** + * Emits a safepoint poll. + */ +@Opcode("SAFEPOINT") +public class AMD64SafepointOp extends AMD64LIRInstruction { + @State protected LIRFrameState state; + + private final HotSpotVMConfig config; + + public AMD64SafepointOp(LIRFrameState state, HotSpotVMConfig config) { + this.state = state; + this.config = config; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler asm) { + Register scratch = tasm.frameMap.registerConfig.getScratchRegister(); + int pos = asm.codeBuffer.position(); + if (config.isPollingPageFar) { + asm.movq(scratch, config.safepointPollingAddress); + tasm.recordMark(Marks.MARK_POLL_FAR); + tasm.recordSafepoint(pos, state); + asm.movq(scratch, new Address(tasm.target.wordKind, scratch.asValue())); + } else { + tasm.recordMark(Marks.MARK_POLL_NEAR); + tasm.recordSafepoint(pos, state); + asm.movq(scratch, new Address(tasm.target.wordKind, rip.asValue())); + } + } +} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64TailcallOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64TailcallOp.java Wed Oct 03 01:18:03 2012 +0200 @@ -0,0 +1,56 @@ +/* + * 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.hotspot.amd64; + +import static com.oracle.graal.api.code.ValueUtil.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.lir.LIRInstruction.Opcode; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.max.asm.amd64.*; + +/** + * Performs a hard-coded tail call to the specified target, which normally should be an {@link InstalledCode} instance. + */ +@Opcode("TAILCALL") +public class AMD64TailcallOp extends AMD64LIRInstruction { + @Use protected Value target; + @Alive protected Value[] parameters; + + public AMD64TailcallOp(Value[] parameters, Value target) { + this.target = target; + this.parameters = parameters; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + // destroy the current frame (now the return address is the top of stack) + masm.leave(); + + // jump to the target method + masm.jmp(asRegister(target)); + masm.ensureUniquePC(); + } +} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java Wed Oct 03 01:18:03 2012 +0200 @@ -0,0 +1,83 @@ +/* + * 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; + +import java.util.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.hotspot.meta.*; + +/** + * HotSpot specific backend. + */ +public abstract class HotSpotBackend extends Backend { + + public static final String VM_ERROR_STUB_NAME = "vm_error"; + public static final String VERIFY_OOP_STUB_NAME = "verify_oop"; + public static final String NEW_MULTI_ARRAY_STUB_NAME = "new_multi_array"; + public static final String NEW_INSTANCE_STUB_NAME = "new_instance"; + public static final String NEW_TYPE_ARRAY_STUB_NAME = "new_type_array"; + public static final String NEW_OBJECT_ARRAY_STUB_NAME = "new_object_array"; + public static final String MONITOREXIT_STUB_NAME = "monitorexit"; + public static final String MONITORENTER_STUB_NAME = "monitorenter"; + + private final Map stubsMap = new HashMap<>(); + + public HotSpotBackend(HotSpotRuntime runtime, TargetDescription target) { + super(runtime, target); + } + + @Override + public HotSpotRuntime runtime() { + return (HotSpotRuntime) super.runtime(); + } + + /** + * Gets the linkage information for a global stub. + */ + public HotSpotStub getStub(String name) { + HotSpotStub stub = stubsMap.get(name); + assert stub != null : "no stub named " + name; + return stub; + } + + /** + * Registers the details for linking a global stub. + * + * @param name name of the stub + * @param address address of the stub + * @param tempRegs temporary registers used (and killed) by the stub (null if none) + * @param ret where the stub returns its result + * @param args where arguments are passed to the stub + */ + protected void addStub(String name, long address, Register[] tempRegs, Value ret, Value... args) { + Value[] temps = tempRegs == null || tempRegs.length == 0 ? Value.NONE : new Value[tempRegs.length]; + for (int i = 0; i < temps.length; i++) { + temps[i] = tempRegs[i].asValue(); + } + HotSpotStub stub = new HotSpotStub(name, address, new CallingConvention(temps, 0, ret, args)); + stubsMap.put(name, stub); + } +} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Wed Oct 03 00:25:30 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Wed Oct 03 01:18:03 2012 +0200 @@ -32,7 +32,6 @@ import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.logging.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.target.*; import com.oracle.graal.nodes.spi.*; /** diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java Wed Oct 03 01:18:03 2012 +0200 @@ -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; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.nodes.spi.*; + +/** + * This interface defines the contract a HotSpot backend LIR generator needs to fulfill + * in addition to abstract methods from {@link LIRGenerator} and {@link LIRGeneratorTool}. + */ +public interface HotSpotLIRGenerator { + + /** + * Emits an operation to make a tail call. + * + * @param args the arguments of the call + * @param address the target address of the call + */ + void emitTailcall(Value[] args, Value address); + + void visitDirectCompareAndSwap(DirectCompareAndSwapNode x); +} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java Wed Oct 03 00:25:30 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java Wed Oct 03 01:18:03 2012 +0200 @@ -24,7 +24,7 @@ import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; -import com.oracle.graal.hotspot.target.*; +import com.oracle.graal.hotspot.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorEnterStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorEnterStubCall.java Wed Oct 03 00:25:30 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorEnterStubCall.java Wed Oct 03 01:18:03 2012 +0200 @@ -22,12 +22,11 @@ */ package com.oracle.graal.hotspot.nodes; -import static com.oracle.graal.hotspot.target.HotSpotBackend.*; +import static com.oracle.graal.hotspot.HotSpotBackend.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.target.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.snippets.*; diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorExitStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorExitStubCall.java Wed Oct 03 00:25:30 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorExitStubCall.java Wed Oct 03 01:18:03 2012 +0200 @@ -22,12 +22,11 @@ */ package com.oracle.graal.hotspot.nodes; -import static com.oracle.graal.hotspot.target.HotSpotBackend.*; +import static com.oracle.graal.hotspot.HotSpotBackend.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.target.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java Wed Oct 03 00:25:30 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java Wed Oct 03 01:18:03 2012 +0200 @@ -22,12 +22,11 @@ */ package com.oracle.graal.hotspot.nodes; -import static com.oracle.graal.hotspot.target.HotSpotBackend.*; +import static com.oracle.graal.hotspot.HotSpotBackend.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.target.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java Wed Oct 03 00:25:30 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java Wed Oct 03 01:18:03 2012 +0200 @@ -22,12 +22,11 @@ */ package com.oracle.graal.hotspot.nodes; -import static com.oracle.graal.hotspot.target.HotSpotBackend.*; +import static com.oracle.graal.hotspot.HotSpotBackend.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.target.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java Wed Oct 03 00:25:30 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java Wed Oct 03 01:18:03 2012 +0200 @@ -22,13 +22,12 @@ */ package com.oracle.graal.hotspot.nodes; -import static com.oracle.graal.hotspot.target.HotSpotBackend.*; +import static com.oracle.graal.hotspot.HotSpotBackend.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.target.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java Wed Oct 03 00:25:30 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java Wed Oct 03 01:18:03 2012 +0200 @@ -29,7 +29,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.target.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Wed Oct 03 00:25:30 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Wed Oct 03 01:18:03 2012 +0200 @@ -22,14 +22,13 @@ */ package com.oracle.graal.hotspot.nodes; -import static com.oracle.graal.hotspot.target.HotSpotBackend.*; +import static com.oracle.graal.hotspot.HotSpotBackend.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.target.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java Wed Oct 03 00:25:30 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java Wed Oct 03 01:18:03 2012 +0200 @@ -22,12 +22,11 @@ */ package com.oracle.graal.hotspot.nodes; -import static com.oracle.graal.hotspot.target.HotSpotBackend.*; +import static com.oracle.graal.hotspot.HotSpotBackend.*; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.target.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/HotSpotBackend.java Wed Oct 03 00:25:30 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -/* - * 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; - -import java.util.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.target.*; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.meta.*; - -/** - * HotSpot specific backend. - */ -public abstract class HotSpotBackend extends Backend { - - public static final String VM_ERROR_STUB_NAME = "vm_error"; - public static final String VERIFY_OOP_STUB_NAME = "verify_oop"; - public static final String NEW_MULTI_ARRAY_STUB_NAME = "new_multi_array"; - public static final String NEW_INSTANCE_STUB_NAME = "new_instance"; - public static final String NEW_TYPE_ARRAY_STUB_NAME = "new_type_array"; - public static final String NEW_OBJECT_ARRAY_STUB_NAME = "new_object_array"; - public static final String MONITOREXIT_STUB_NAME = "monitorexit"; - public static final String MONITORENTER_STUB_NAME = "monitorenter"; - - private final Map stubsMap = new HashMap<>(); - - public HotSpotBackend(HotSpotRuntime runtime, TargetDescription target) { - super(runtime, target); - } - - @Override - public HotSpotRuntime runtime() { - return (HotSpotRuntime) super.runtime(); - } - - /** - * Gets the linkage information for a global stub. - */ - public HotSpotStub getStub(String name) { - HotSpotStub stub = stubsMap.get(name); - assert stub != null : "no stub named " + name; - return stub; - } - - /** - * Registers the details for linking a global stub. - * - * @param name name of the stub - * @param address address of the stub - * @param tempRegs temporary registers used (and killed) by the stub (null if none) - * @param ret where the stub returns its result - * @param args where arguments are passed to the stub - */ - protected void addStub(String name, long address, Register[] tempRegs, Value ret, Value... args) { - Value[] temps = tempRegs == null || tempRegs.length == 0 ? Value.NONE : new Value[tempRegs.length]; - for (int i = 0; i < temps.length; i++) { - temps[i] = tempRegs[i].asValue(); - } - HotSpotStub stub = new HotSpotStub(name, address, new CallingConvention(temps, 0, ret, args)); - stubsMap.put(name, stub); - } -} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/HotSpotLIRGenerator.java Wed Oct 03 00:25:30 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * 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; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.hotspot.nodes.*; -import com.oracle.graal.nodes.spi.*; - -/** - * This interface defines the contract a HotSpot backend LIR generator needs to fulfill - * in addition to abstract methods from {@link LIRGenerator} and {@link LIRGeneratorTool}. - */ -public interface HotSpotLIRGenerator { - - /** - * Emits an operation to make a tail call. - * - * @param args the arguments of the call - * @param address the target address of the call - */ - void emitTailcall(Value[] args, Value address); - - void visitDirectCompareAndSwap(DirectCompareAndSwapNode x); -} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64BreakpointOp.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64BreakpointOp.java Wed Oct 03 00:25:30 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +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.hotspot.target.amd64; - -import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; -import com.oracle.graal.lir.amd64.*; -import com.oracle.graal.lir.asm.*; -import com.oracle.max.asm.amd64.*; - -/** - * Emits a breakpoint. - */ -@Opcode("BREAKPOINT") -public class AMD64BreakpointOp extends AMD64LIRInstruction { - - /** - * A set of values loaded into the Java ABI parameter locations (for inspection by a debugger). - */ - @Use({REG, STACK}) protected Value[] parameters; - - public AMD64BreakpointOp(Value[] parameters) { - this.parameters = parameters; - } - - @Override - public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler asm) { - asm.int3(); - } -} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64DirectCallOp.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64DirectCallOp.java Wed Oct 03 00:25:30 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,105 +0,0 @@ -/* - * 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.nodes.java.MethodCallTargetNode.InvokeKind.*; - -import com.oracle.graal.api.code.CompilationResult.Mark; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.hotspot.bridge.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.*; -import com.oracle.graal.lir.amd64.*; -import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp; -import com.oracle.graal.lir.asm.*; -import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; -import com.oracle.max.asm.*; -import com.oracle.max.asm.amd64.*; - -/** - * A direct call that complies with the conventions for such calls in HotSpot. - * In particular, for calls using an inline cache, a MOVE instruction is - * emitted just prior to the aligned direct call. This instruction - * (which moves null in RAX) is patched by the C++ Graal code to replace the - * null constant with Universe::non_oop_word(), a special sentinel - * used for the initial value of the klassOop in an inline cache. - *

- * For non-inline cache calls, a static call stub is emitted. - */ -@Opcode("CALL_DIRECT") -final class AMD64DirectCallOp extends DirectCallOp { - - /** - * The mark emitted at the position of the direct call instruction. - * This is only recorded for calls that have an associated static - * call stub (i.e., {@code invokeKind == Static || invokeKind == Special}). - */ - Mark callsiteMark; - - private final InvokeKind invokeKind; - - AMD64DirectCallOp(Object targetMethod, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind, LIR lir) { - super(targetMethod, result, parameters, temps, state); - this.invokeKind = invokeKind; - - if (invokeKind == Static || invokeKind == Special) { - lir.stubs.add(new AMD64Code() { - public String description() { - return "static call stub for Invoke" + AMD64DirectCallOp.this.invokeKind; - } - @Override - public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - assert callsiteMark != null : "static call site has not yet been emitted"; - tasm.recordMark(Marks.MARK_STATIC_CALL_STUB, callsiteMark); - masm.movq(AMD64.rbx, 0L); - Label dummy = new Label(); - masm.jmp(dummy); - masm.bind(dummy); - } - }); - } - - } - - @Override - public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - if (invokeKind == Static || invokeKind == Special) { - tasm.recordMark(invokeKind == Static ? Marks.MARK_INVOKESTATIC : Marks.MARK_INVOKESPECIAL); - } else { - assert invokeKind == Virtual || invokeKind == Interface; - // The mark for an invocation that uses an inline cache must be placed at the instruction - // that loads the klassOop from the inline cache so that the C++ code can find it - // and replace the inline null value with Universe::non_oop_word() - tasm.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE); - AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Object), Constant.NULL_OBJECT); - } - - emitAlignmentForDirectCall(tasm, masm); - - if (invokeKind == Static || invokeKind == Special) { - callsiteMark = tasm.recordMark(null); - } - - AMD64Call.directCall(tasm, masm, targetMethod, state); - } -} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64HotSpotBackend.java Wed Oct 03 00:25:30 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,350 +0,0 @@ -/* - * 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.api.code.CallingConvention.Type.*; -import static com.oracle.graal.api.code.ValueUtil.*; -import static com.oracle.graal.api.meta.Value.*; -import static com.oracle.max.asm.amd64.AMD64.*; - -import java.lang.reflect.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.Register.RegisterFlag; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.*; -import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.compiler.target.amd64.*; -import com.oracle.graal.graph.*; -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.target.*; -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.max.asm.*; -import com.oracle.max.asm.amd64.*; -import com.oracle.max.asm.amd64.AMD64Assembler.*; - -/** - * HotSpot AMD64 specific backend. - */ -public class AMD64HotSpotBackend extends HotSpotBackend { - - public AMD64HotSpotBackend(HotSpotRuntime runtime, TargetDescription target) { - super(runtime, target); - HotSpotVMConfig c = runtime.config; - Kind word = target.wordKind; - - Register[] jargs = runtime.getGlobalStubRegisterConfig().getCallingConventionRegisters(RuntimeCall, RegisterFlag.CPU); - Register jarg0 = jargs[0]; - Register jarg1 = jargs[1]; - Register jarg2 = jargs[2]; - - addStub(MONITORENTER_STUB_NAME, c.fastMonitorEnterStub, - /* temps */ new Register[] {rax, rbx}, - /* ret */ IllegalValue, - /* arg0: object */ jarg0.asValue(Kind.Object), - /* arg1: lock */ jarg1.asValue(word)); - - addStub(MONITOREXIT_STUB_NAME, c.fastMonitorExitStub, - /* temps */ new Register[] {rax, rbx}, - /* ret */ IllegalValue, - /* arg0: object */ jarg0.asValue(Kind.Object), - /* arg1: lock */ jarg1.asValue(word)); - - addStub(NEW_OBJECT_ARRAY_STUB_NAME, c.newObjectArrayStub, - /* temps */ new Register[] {rcx, rdi, rsi}, - /* ret */ rax.asValue(Kind.Object), - /* arg0: hub */ rdx.asValue(Kind.Object), - /* arg1: length */ rbx.asValue(Kind.Int)); - - addStub(NEW_TYPE_ARRAY_STUB_NAME, c.newTypeArrayStub, - /* temps */ new Register[] {rcx, rdi, rsi}, - /* ret */ rax.asValue(Kind.Object), - /* arg0: hub */ rdx.asValue(Kind.Object), - /* arg1: length */ rbx.asValue(Kind.Int)); - - addStub(NEW_INSTANCE_STUB_NAME, c.newInstanceStub, - /* temps */ null, - /* ret */ rax.asValue(Kind.Object), - /* arg0: hub */ rdx.asValue(Kind.Object)); - - addStub(NEW_MULTI_ARRAY_STUB_NAME, c.newMultiArrayStub, - /* temps */ null, - /* ret */ rax.asValue(Kind.Object), - /* arg0: hub */ rax.asValue(Kind.Object), - /* arg1: rank */ rbx.asValue(Kind.Int), - /* arg2: dims */ rcx.asValue(word)); - - addStub(VERIFY_OOP_STUB_NAME, c.verifyOopStub, - /* temps */ null, - /* ret */ IllegalValue, - /* arg0: object */ r13.asValue(Kind.Object)); - - addStub(VM_ERROR_STUB_NAME, c.vmErrorStub, - /* temps */ null, - /* ret */ IllegalValue, - /* arg0: where */ jarg0.asValue(Kind.Object), - /* arg1: format */ jarg1.asValue(Kind.Object), - /* arg2: value */ jarg2.asValue(Kind.Object)); - } - - @Override - public LIRGenerator newLIRGenerator(Graph graph, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) { - 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(Graph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, ResolvedJavaMethod method, LIR lir) { - super(graph, runtime, target, frameMap, method, lir); - } - - @Override - public void visitSafepointNode(SafepointNode i) { - LIRFrameState info = state(); - append(new AMD64SafepointOp(info, runtime().config)); - } - - @Override - public void visitBreakpointNode(BreakpointNode i) { - Kind[] sig = new Kind[i.arguments.size()]; - int pos = 0; - for (ValueNode arg : i.arguments) { - sig[pos++] = arg.kind(); - } - - CallingConvention cc = frameMap.registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, Kind.Void, sig, target(), false); - Value[] parameters = visitInvokeArguments(cc, i.arguments); - append(new AMD64BreakpointOp(parameters)); - } - - @Override - public void visitExceptionObject(ExceptionObjectNode x) { - HotSpotVMConfig config = runtime().config; - RegisterValue thread = runtime().threadRegister().asValue(); - Address exceptionAddress = new Address(Kind.Object, thread, config.threadExceptionOopOffset); - Address pcAddress = new Address(Kind.Long, thread, config.threadExceptionPcOffset); - Value exception = emitLoad(exceptionAddress, false); - emitStore(exceptionAddress, Constant.NULL_OBJECT, false); - emitStore(pcAddress, 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; - Address address; - Value index = operand(x.offset()); - if (ValueUtil.isConstant(index) && NumUtil.isInt(ValueUtil.asConstant(index).asLong() + disp)) { - disp += (int) ValueUtil.asConstant(index).asLong(); - address = new Address(kind, load(operand(x.object())), disp); - } else { - address = new Address(kind, load(operand(x.object())), load(index), Address.Scale.Times1, disp); - } - - RegisterValue rax = AMD64.rax.asValue(kind); - emitMove(expected, rax); - append(new CompareAndSwapOp(rax, address, rax, newVal)); - - Variable result = newVariable(x.kind()); - emitMove(rax, result); - 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) { - append(new AMD64DirectCallOp(callTarget.target(), result, parameters, temps, callState, ((HotSpotDirectCallTargetNode) callTarget).invokeKind(), lir)); - } - - @Override - protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { - Value methodOop = AMD64.rbx.asValue(); - emitMove(operand(((HotSpotIndirectCallTargetNode) callTarget).methodOop()), methodOop); - Value targetAddress = AMD64.rax.asValue(); - emitMove(operand(callTarget.computedAddress()), targetAddress); - append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, temps, methodOop, targetAddress, callState)); - } - } - - class HotSpotFrameContext implements FrameContext { - - @Override - public void enter(TargetMethodAssembler tasm) { - FrameMap frameMap = tasm.frameMap; - int frameSize = frameMap.frameSize(); - - AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm; - emitStackOverflowCheck(tasm, 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 Address(Kind.Int, rsp.asValue(), i * intSize), 0xC1C1C1C1); - } - } - CalleeSaveLayout csl = frameMap.registerConfig.getCalleeSaveLayout(); - if (csl != null && csl.size != 0) { - int frameToCSA = frameMap.offsetToCalleeSaveArea(); - assert frameToCSA >= 0; - asm.save(csl, frameToCSA); - } - } - - @Override - public void leave(TargetMethodAssembler tasm) { - int frameSize = tasm.frameMap.frameSize(); - AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm; - CalleeSaveLayout csl = tasm.frameMap.registerConfig.getCalleeSaveLayout(); - RegisterConfig 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 = 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() - - Register scratch = regConfig.getScratchRegister(); - if (config.isPollingPageFar) { - asm.movq(scratch, config.safepointPollingAddress); - tasm.recordMark(Marks.MARK_POLL_RETURN_FAR); - asm.movq(scratch, new Address(tasm.target.wordKind, scratch.asValue())); - } else { - tasm.recordMark(Marks.MARK_POLL_RETURN_NEAR); - asm.movq(scratch, new Address(tasm.target.wordKind, rip.asValue())); - } - } - } - } - - @Override - public TargetMethodAssembler newAssembler(FrameMap frameMap, LIR lir) { - // 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 canOmitFrame = - frameMap.frameSize() == frameMap.initialFrameSize && - frameMap.registerConfig.getCalleeSaveLayout().registers.length == 0 && - !lir.hasArgInCallerFrame() && - !lir.hasDebugInfo(); - - AbstractAssembler masm = new AMD64MacroAssembler(target, frameMap.registerConfig); - HotSpotFrameContext frameContext = canOmitFrame ? null : new HotSpotFrameContext(); - TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, lir.stubs); - tasm.setFrameSize(frameMap.frameSize()); - tasm.targetMethod.setCustomStackAreaOffset(frameMap.offsetToCustomArea()); - return tasm; - } - - @Override - public void emitCode(TargetMethodAssembler tasm, ResolvedJavaMethod method, LIR lir) { - AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm; - FrameMap frameMap = tasm.frameMap; - RegisterConfig regConfig = frameMap.registerConfig; - HotSpotVMConfig config = runtime().config; - Label unverifiedStub = new Label(); - - // Emit the prefix - tasm.recordMark(Marks.MARK_OSR_ENTRY); - - boolean isStatic = Modifier.isStatic(method.accessFlags()); - if (!isStatic) { - tasm.recordMark(Marks.MARK_UNVERIFIED_ENTRY); - CallingConvention cc = regConfig.getCallingConvention(JavaCallee, Kind.Void, new Kind[] {Kind.Object}, target, false); - Register inlineCacheKlass = rax; // see definition of IC_Klass in c1_LIRAssembler_x86.cpp - Register receiver = asRegister(cc.getArgument(0)); - Address src = new Address(target.wordKind, receiver.asValue(), config.hubOffset); - - asm.cmpq(inlineCacheKlass, src); - asm.jcc(ConditionFlag.notEqual, unverifiedStub); - } - - asm.align(config.codeEntryAlignment); - tasm.recordMark(Marks.MARK_VERIFIED_ENTRY); - - // Emit code for the LIR - lir.emitCode(tasm); - - boolean frameOmitted = tasm.frameContext == null; - if (!frameOmitted) { - tasm.recordMark(Marks.MARK_EXCEPTION_HANDLER_ENTRY); - AMD64Call.directCall(tasm, asm, config.handleExceptionStub, null); - AMD64Call.shouldNotReachHere(tasm, asm); - - tasm.recordMark(Marks.MARK_DEOPT_HANDLER_ENTRY); - AMD64Call.directCall(tasm, asm, config.handleDeoptStub, null); - AMD64Call.shouldNotReachHere(tasm, asm); - } 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(); - } - - if (!isStatic) { - asm.bind(unverifiedStub); - AMD64Call.directJmp(tasm, asm, config.inlineCacheMissStub); - } - - for (int i = 0; i < GraalOptions.MethodEndBreakpointGuards; ++i) { - asm.int3(); - } - } -} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64HotSpotGraalRuntime.java Wed Oct 03 00:25:30 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * 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 com.oracle.graal.api.code.*; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.target.*; -import com.oracle.max.asm.amd64.*; - -/** - * AMD64 specific implementation of {@link HotSpotGraalRuntime}. - */ -final class AMD64HotSpotGraalRuntime extends HotSpotGraalRuntime { - - private AMD64HotSpotGraalRuntime() { - } - - /** - * Called from native code. - */ - @SuppressWarnings("unused") - private static HotSpotGraalRuntime initialize() { - return new AMD64HotSpotGraalRuntime(); - } - - @Override - protected TargetDescription createTarget() { - final int wordSize = 8; - final int stackFrameAlignment = 16; - return new TargetDescription(new AMD64(), true, stackFrameAlignment, config.vmPageSize, wordSize, true, true); - } - - @Override - protected HotSpotBackend createBackend() { - return new AMD64HotSpotBackend(getRuntime(), getTarget()); - } - - @Override - protected HotSpotRuntime createRuntime() { - return new AMD64HotSpotRuntime(config, this); - } - - -} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64HotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64HotSpotRegisterConfig.java Wed Oct 03 00:25:30 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,211 +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.hotspot.target.amd64; - -import static com.oracle.max.asm.amd64.AMD64.*; - -import java.util.*; - -import com.oracle.max.asm.amd64.*; -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.CallingConvention.*; -import com.oracle.graal.api.code.Register.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.hotspot.*; - -public class AMD64HotSpotRegisterConfig implements RegisterConfig { - - // be careful - the contents of this array are duplicated in graal_CodeInstaller.cpp - private final Register[] allocatable = { - rax, rbx, rcx, rdx, rsi, rdi, r8, r9, /* r10, */r11, r12, r13, r14, /*r15*/ - xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, - xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 - }; - - private final EnumMap categorized = Register.categorize(allocatable); - - private final RegisterAttributes[] attributesMap; - - @Override - public Register[] getAllocatableRegisters() { - return allocatable; - } - - @Override - public EnumMap getCategorizedAllocatableRegisters() { - return categorized; - } - - @Override - public RegisterAttributes[] getAttributesMap() { - return attributesMap; - } - - private final Register[] generalParameterRegisters; - private final Register[] xmmParameterRegisters = {xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7}; - private final Register[] allParameterRegisters; - - private final CalleeSaveLayout csl; - - public AMD64HotSpotRegisterConfig(HotSpotVMConfig config, boolean globalStubConfig) { - if (config.windowsOs) { - generalParameterRegisters = new Register[] {rdx, r8, r9, rdi, rsi, rcx}; - } else { - generalParameterRegisters = new Register[] {rsi, rdx, rcx, r8, r9, rdi}; - } - - if (globalStubConfig) { - Register[] regs = { - rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, - r8, r9, r10, r11, r12, r13, r14, r15, - xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, - xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 - }; - 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); - } - - attributesMap = RegisterAttributes.createMap(this, AMD64.allRegisters); - allParameterRegisters = Arrays.copyOf(generalParameterRegisters, generalParameterRegisters.length + xmmParameterRegisters.length); - System.arraycopy(xmmParameterRegisters, 0, allParameterRegisters, generalParameterRegisters.length, xmmParameterRegisters.length); - } - - @Override - public Register[] getCallerSaveRegisters() { - return getAllocatableRegisters(); - } - - @Override - public Register getRegisterForRole(int index) { - throw new UnsupportedOperationException(); - } - - @Override - public CallingConvention getCallingConvention(Type type, Kind returnKind, Kind[] parameters, TargetDescription target, boolean stackOnly) { - if (type == Type.NativeCall) { - throw new UnsupportedOperationException(); - } - return callingConvention(returnKind, parameters, type, target, stackOnly); - } - - public Register[] getCallingConventionRegisters(Type type, RegisterFlag flag) { - return allParameterRegisters; - } - - private CallingConvention callingConvention(Kind returnKind, Kind[] kinds, Type type, TargetDescription target, boolean stackOnly) { - Value[] locations = new Value[kinds.length]; - - int currentGeneral = 0; - int currentXMM = 0; - int currentStackOffset = 0; - - for (int i = 0; i < kinds.length; i++) { - final Kind kind = kinds[i]; - - switch (kind) { - case Byte: - case Boolean: - case Short: - case Char: - case Int: - case Long: - case Object: - if (!stackOnly && currentGeneral < generalParameterRegisters.length) { - Register register = generalParameterRegisters[currentGeneral++]; - locations[i] = register.asValue(kind); - } - break; - case Float: - case Double: - if (!stackOnly && currentXMM < xmmParameterRegisters.length) { - Register register = xmmParameterRegisters[currentXMM++]; - locations[i] = register.asValue(kind); - } - break; - default: - throw GraalInternalError.shouldNotReachHere(); - } - - if (locations[i] == null) { - locations[i] = StackSlot.get(kind.stackKind(), currentStackOffset, !type.out); - currentStackOffset += Math.max(target.sizeInBytes(kind), target.wordSize); - } - } - - Value returnLocation = returnKind.isVoid() ? Value.IllegalValue : getReturnRegister(returnKind).asValue(returnKind); - return new CallingConvention(currentStackOffset, returnLocation, locations); - } - - @Override - public Register getReturnRegister(Kind kind) { - switch (kind) { - case Boolean: - case Byte: - case Char: - case Short: - case Int: - case Long: - case Object: - return rax; - case Float: - case Double: - return xmm0; - case Void: - case Illegal: - return null; - default: - throw new UnsupportedOperationException("no return register for type " + kind); - } - } - - @Override - public Register getScratchRegister() { - return r10; - } - - @Override - public Register getFrameRegister() { - return rsp; - } - - public CalleeSaveLayout getCalleeSaveLayout() { - return csl; - } - - @Override - public String toString() { - String res = String.format( - "Allocatable: " + Arrays.toString(getAllocatableRegisters()) + "%n" + - "CallerSave: " + Arrays.toString(getCallerSaveRegisters()) + "%n" + - "CalleeSave: " + getCalleeSaveLayout() + "%n" + - "Scratch: " + getScratchRegister() + "%n"); - return res; - } -} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64HotSpotRuntime.java Wed Oct 03 00:25:30 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * 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.max.asm.amd64.AMD64.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.meta.*; - -public class AMD64HotSpotRuntime extends HotSpotRuntime { - - public AMD64HotSpotRuntime(HotSpotVMConfig config, HotSpotGraalRuntime graalRuntime) { - super(config, graalRuntime); - } - - @Override - public Register threadRegister() { - return r15; - } - - @Override - public Register stackPointerRegister() { - return rsp; - } - - @Override - protected RegisterConfig createRegisterConfig(boolean globalStubConfig) { - return new AMD64HotSpotRegisterConfig(config, globalStubConfig); - } - -} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64IndirectCallOp.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64IndirectCallOp.java Wed Oct 03 00:25:30 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* - * 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.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.hotspot.bridge.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; -import com.oracle.graal.lir.amd64.*; -import com.oracle.graal.lir.amd64.AMD64Call.IndirectCallOp; -import com.oracle.graal.lir.asm.*; -import com.oracle.max.asm.amd64.*; - -/** - * A register indirect call that complies with the extra conventions for such calls in HotSpot. - * In particular, the methodOop of the callee must be in RBX for the case where a vtable entry's - * _from_compiled_entry is the address of an C2I adapter. Such adapters expect the target - * method to be in RBX. - */ -@Opcode("CALL_INDIRECT") -final class AMD64IndirectCallOp extends IndirectCallOp { - - /** - * Vtable stubs expect the methodOop in RBX. - */ - public static final Register METHOD_OOP = AMD64.rbx; - - @Use({REG}) protected Value methodOop; - - AMD64IndirectCallOp(Object targetMethod, Value result, Value[] parameters, Value[] temps, Value methodOop, Value targetAddress, LIRFrameState state) { - super(targetMethod, result, parameters, temps, targetAddress, state); - this.methodOop = methodOop; - } - - @Override - public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - tasm.recordMark(Marks.MARK_INLINE_INVOKEVIRTUAL); - Register callReg = asRegister(targetAddress); - assert callReg != METHOD_OOP; - AMD64Call.indirectCall(tasm, masm, callReg, targetMethod, state); - } - - @Override - protected void verify() { - super.verify(); - assert asRegister(methodOop) == METHOD_OOP; - } -} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64SafepointOp.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64SafepointOp.java Wed Oct 03 00:25:30 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +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.hotspot.target.amd64; - -import static com.oracle.max.asm.amd64.AMD64.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.bridge.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; -import com.oracle.graal.lir.amd64.*; -import com.oracle.graal.lir.asm.*; -import com.oracle.max.asm.amd64.*; - -/** - * Emits a safepoint poll. - */ -@Opcode("SAFEPOINT") -public class AMD64SafepointOp extends AMD64LIRInstruction { - @State protected LIRFrameState state; - - private final HotSpotVMConfig config; - - public AMD64SafepointOp(LIRFrameState state, HotSpotVMConfig config) { - this.state = state; - this.config = config; - } - - @Override - public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler asm) { - Register scratch = tasm.frameMap.registerConfig.getScratchRegister(); - int pos = asm.codeBuffer.position(); - if (config.isPollingPageFar) { - asm.movq(scratch, config.safepointPollingAddress); - tasm.recordMark(Marks.MARK_POLL_FAR); - tasm.recordSafepoint(pos, state); - asm.movq(scratch, new Address(tasm.target.wordKind, scratch.asValue())); - } else { - tasm.recordMark(Marks.MARK_POLL_NEAR); - tasm.recordSafepoint(pos, state); - asm.movq(scratch, new Address(tasm.target.wordKind, rip.asValue())); - } - } -} diff -r df02fa2bce58 -r 75f130f2b30f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64TailcallOp.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64TailcallOp.java Wed Oct 03 00:25:30 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +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.hotspot.target.amd64; - -import static com.oracle.graal.api.code.ValueUtil.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.lir.LIRInstruction.Opcode; -import com.oracle.graal.lir.amd64.*; -import com.oracle.graal.lir.asm.*; -import com.oracle.max.asm.amd64.*; - -/** - * Performs a hard-coded tail call to the specified target, which normally should be an {@link InstalledCode} instance. - */ -@Opcode("TAILCALL") -public class AMD64TailcallOp extends AMD64LIRInstruction { - @Use protected Value target; - @Alive protected Value[] parameters; - - public AMD64TailcallOp(Value[] parameters, Value target) { - this.target = target; - this.parameters = parameters; - } - - @Override - public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - // destroy the current frame (now the return address is the top of stack) - masm.leave(); - - // jump to the target method - masm.jmp(asRegister(target)); - masm.ensureUniquePC(); - } -} diff -r df02fa2bce58 -r 75f130f2b30f mx/commands.py --- a/mx/commands.py Wed Oct 03 00:25:30 2012 +0200 +++ b/mx/commands.py Wed Oct 03 01:18:03 2012 +0200 @@ -274,6 +274,12 @@ if len(failed) != 0: mx.abort('Scala DaCapo failures: ' + str(failed)) +def _arch(): + machine = os.uname()[4] + if machine in ['amd64', 'x86_64']: + return 'amd64' + mx.abort('unsupported or unknown machine type: ' + machine) + def _vmLibDirInJdk(jdk): """ Get the directory within a JDK where the server and client @@ -283,14 +289,14 @@ return join(jdk, 'jre', 'lib') if platform.system() == 'Windows': return join(jdk, 'jre', 'bin') - return join(jdk, 'jre', 'lib', 'amd64') + return join(jdk, 'jre', 'lib', _arch()) def _vmCfgInJdk(jdk): """ Get the jvm.cfg file. """ if platform.system() == 'Windows': - return join(jdk, 'jre', 'lib', 'amd64', 'jvm.cfg') + return join(jdk, 'jre', 'lib', _arch(), 'jvm.cfg') return join(_vmLibDirInJdk(jdk), 'jvm.cfg') def _jdk(build='product', create=False): @@ -464,14 +470,14 @@ assert start != -1, 'Could not find "' + decl + '" in ' + fp.name end = source.find('};', start) assert end != -1, 'Could not find "' + decl + '" ... "};" in ' + fp.name - actual = frozenset([a.strip().strip('"') for a in source[start + len(decl):end].split(',')]) - expected = frozenset([p.name for p in mx.project('com.oracle.graal.hotspot').all_deps([], False)]) + actual = frozenset(re.findall(r'"([^"]+)"', source[start + len(decl):end])) + expected = frozenset([p.name for p in mx.project('com.oracle.graal.hotspot.' + _arch()).all_deps([], False)]) missing = expected - actual extra = actual - expected if len(missing) != 0: - mx.abort(fp.name + ':' + str(source[:start].count('\n') + 1) + ': add missing projects to declaration:\n ' + '\n '.join(missing)) + mx.abort(fp.name + ':' + str(source[:start].count('\n') + 1) + ': add missing project(s) to declaration:\n ' + '\n '.join(missing)) if len(extra) != 0: - mx.abort(fp.name + ':' + str(source[:start].count('\n') + 1) + ': remove projects from declaration:\n ' + '\n '.join(extra)) + mx.abort(fp.name + ':' + str(source[:start].count('\n') + 1) + ': remove project(s) from declaration:\n ' + '\n '.join(extra)) # Check if a build really needs to be done timestampFile = join(vmDir, '.build-timestamp') @@ -956,7 +962,7 @@ flavor = 'intel' if 'att' in args: flavor = 'att' - lib = mx.lib_suffix('hsdis-amd64') + lib = mx.lib_suffix('hsdis-' + _arch()) path = join(_graal_home, 'lib', lib) if not exists(path): mx.download(path, ['http://lafo.ssw.uni-linz.ac.at/hsdis/' + flavor + "/" + lib]) diff -r df02fa2bce58 -r 75f130f2b30f mx/projects --- a/mx/projects Wed Oct 03 00:25:30 2012 +0200 +++ b/mx/projects Wed Oct 03 01:18:03 2012 +0200 @@ -62,6 +62,13 @@ project@com.oracle.graal.hotspot@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hotspot@javaCompliance=1.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 +project@com.oracle.graal.hotspot.amd64@checkstyle=com.oracle.graal.graph +project@com.oracle.graal.hotspot.amd64@javaCompliance=1.7 + # graal.hotspot.server project@com.oracle.graal.hotspot.server@subDir=graal project@com.oracle.graal.hotspot.server@sourceDirs=src diff -r df02fa2bce58 -r 75f130f2b30f src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Wed Oct 03 00:25:30 2012 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Wed Oct 03 01:18:03 2012 +0200 @@ -288,7 +288,7 @@ template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaField, "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField") \ template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod, "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod") \ template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaType, "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType") \ - AMD64_ONLY(template(com_oracle_graal_hotspot_target_amd64_AMD64HotSpotGraalRuntime,"com/oracle/graal/hotspot/target/amd64/AMD64HotSpotGraalRuntime"))\ + AMD64_ONLY(template(com_oracle_graal_hotspot_amd64_AMD64HotSpotGraalRuntime,"com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime"))\ /* graal.api.meta */ \ template(com_oracle_graal_api_meta_Constant, "com/oracle/graal/api/meta/Constant") \ template(com_oracle_graal_api_meta_ConstantPool, "com/oracle/graal/api/meta/ConstantPool") \ diff -r df02fa2bce58 -r 75f130f2b30f src/share/vm/graal/graalVMToCompiler.cpp --- a/src/share/vm/graal/graalVMToCompiler.cpp Wed Oct 03 00:25:30 2012 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.cpp Wed Oct 03 01:18:03 2012 +0200 @@ -41,7 +41,7 @@ Handle VMToCompiler::compilerInstance() { if (JNIHandles::resolve(_compilerPermObject) == NULL) { #ifdef AMD64 - Symbol* compilerImplKlassName = vmSymbols::com_oracle_graal_hotspot_target_amd64_AMD64HotSpotGraalRuntime(); + Symbol* compilerImplKlassName = vmSymbols::com_oracle_graal_hotspot_amd64_AMD64HotSpotGraalRuntime(); #endif KlassHandle compilerImplKlass = SystemDictionary::resolve_or_null(compilerImplKlassName, SystemDictionary::java_system_loader(), NULL, Thread::current()); check_not_null(compilerImplKlass(), "Couldn't find class com.sun.hotspot.graal.HotSpotGraalRuntime"); diff -r df02fa2bce58 -r 75f130f2b30f src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Wed Oct 03 00:25:30 2012 +0200 +++ b/src/share/vm/runtime/arguments.cpp Wed Oct 03 01:18:03 2012 +0200 @@ -2147,6 +2147,11 @@ // this declaration is checked for correctness by 'mx build' - only // modify its entries, not its name or shape const char* graal_projects[] = { +#ifdef AMD64 + "com.oracle.max.asm.amd64", + "com.oracle.graal.lir.amd64", + "com.oracle.graal.hotspot.amd64", +#endif "com.oracle.graal.api", "com.oracle.graal.api.meta", "com.oracle.graal.api.code", @@ -2154,7 +2159,6 @@ "com.oracle.max.criutils", "com.oracle.graal.hotspot", "com.oracle.max.asm", - "com.oracle.max.asm.amd64", "com.oracle.graal.alloc", "com.oracle.graal.snippets", "com.oracle.graal.compiler", @@ -2166,7 +2170,6 @@ "com.oracle.graal.debug", "com.oracle.graal.graph", "com.oracle.graal.lir", - "com.oracle.graal.lir.amd64", "com.oracle.graal.bytecode", "com.oracle.graal.java" };