# HG changeset patch # User Doug Simon # Date 1349216730 -7200 # Node ID df02fa2bce58ea9fcdc2170f5c32589a57acf328 # Parent 85c1b84f8fd98cd05389040eaca021c969725928 refactored all AMD64 specific HotSpot code in com.oracle.graal.hotspot.target.amd64 package diff -r 85c1b84f8fd9 -r df02fa2bce58 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Tue Oct 02 22:22:06 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Wed Oct 03 00:25:30 2012 +0200 @@ -35,7 +35,7 @@ */ public abstract class Backend { - public final CodeCacheProvider runtime; + private final CodeCacheProvider runtime; public final TargetDescription target; protected Backend(CodeCacheProvider runtime, TargetDescription target) { @@ -43,6 +43,10 @@ this.target = target; } + public CodeCacheProvider runtime() { + return runtime; + } + public FrameMap newFrameMap(RegisterConfig registerConfig) { return new FrameMap(runtime, target, registerConfig); } diff -r 85c1b84f8fd9 -r df02fa2bce58 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 Tue Oct 02 22:22:06 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Wed Oct 03 00:25:30 2012 +0200 @@ -29,20 +29,21 @@ import com.oracle.graal.api.interpreter.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.*; -import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.logging.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.target.amd64.*; +import com.oracle.graal.hotspot.target.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.max.asm.amd64.*; /** - * Singleton class holding the instance of the GraalCompiler. + * Singleton class holding the instance of the {@link GraalRuntime}. + * + * The platform specific subclass is created by a call from + * the native HotSpot code. */ -public final class HotSpotGraalRuntime implements GraalRuntime { +public abstract class HotSpotGraalRuntime implements GraalRuntime { - private static final HotSpotGraalRuntime instance = new HotSpotGraalRuntime(); + private static HotSpotGraalRuntime instance; public static HotSpotGraalRuntime getInstance() { return instance; @@ -51,19 +52,21 @@ private final CompilerToVM compilerToVm; private final VMToCompiler vmToCompiler; - private HotSpotRuntime runtime; - private GraalCompiler compiler; - private TargetDescription target; + protected final HotSpotRuntime runtime; + protected final GraalCompiler compiler; + protected final TargetDescription target; private HotSpotRuntimeInterpreterInterface runtimeInterpreterInterface; private volatile HotSpotGraphCache cache; - private final HotSpotVMConfig config; + protected final HotSpotVMConfig config; public HotSpotVMConfig getConfig() { return config; } - private HotSpotGraalRuntime() { + public HotSpotGraalRuntime() { + assert instance == null; + instance = this; CompilerToVM toVM = new CompilerToVMImpl(); @@ -90,6 +93,16 @@ if (Boolean.valueOf(System.getProperty("graal.printconfig"))) { printConfig(config); } + + target = createTarget(); + runtime = createRuntime(); + + HotSpotBackend backend = createBackend(); + GraalOptions.StackShadowPages = config.stackShadowPages; + compiler = new GraalCompiler(getRuntime(), getTarget(), backend); + if (GraalOptions.CacheGraphs) { + cache = new HotSpotGraphCache(); + } } private static void printConfig(HotSpotVMConfig config) { @@ -103,28 +116,15 @@ } } + protected abstract TargetDescription createTarget(); + protected abstract HotSpotBackend createBackend(); + protected abstract HotSpotRuntime createRuntime(); + public TargetDescription getTarget() { - if (target == null) { - final int wordSize = 8; - final int stackFrameAlignment = 16; - target = new TargetDescription(new AMD64(), true, stackFrameAlignment, config.vmPageSize, wordSize, true, true); - } - return target; } public GraalCompiler getCompiler() { - if (compiler == null) { - // these options are important - graal will not generate correct code without them - GraalOptions.StackShadowPages = config.stackShadowPages; - - Backend backend = new HotSpotAMD64Backend(getRuntime(), getTarget()); - - compiler = new GraalCompiler(getRuntime(), getTarget(), backend); - if (GraalOptions.CacheGraphs) { - cache = new HotSpotGraphCache(); - } - } return compiler; } @@ -182,9 +182,6 @@ } public HotSpotRuntime getRuntime() { - if (runtime == null) { - runtime = new HotSpotRuntime(config, this); - } return runtime; } diff -r 85c1b84f8fd9 -r df02fa2bce58 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Oct 02 22:22:06 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Wed Oct 03 00:25:30 2012 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.hotspot; -import com.oracle.graal.api.code.*; -import com.oracle.max.asm.amd64.*; /** * Used to communicate configuration details, runtime offsets, etc. to graal upon compileMethod. @@ -180,9 +178,6 @@ public long verifyOopStub; public long vmErrorStub; - // special registers - public final Register threadRegister = AMD64.r15; - public void check() { assert vmPageSize >= 16; assert codeEntryAlignment > 0; diff -r 85c1b84f8fd9 -r df02fa2bce58 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRegisterConfig.java Tue Oct 02 22:22:06 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.meta; - -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 HotSpotRegisterConfig 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 HotSpotRegisterConfig(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 85c1b84f8fd9 -r df02fa2bce58 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Tue Oct 02 22:22:06 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Wed Oct 03 00:25:30 2012 +0200 @@ -52,12 +52,12 @@ import com.oracle.max.criutils.*; /** - * CRI runtime implementation for the HotSpot VM. + * HotSpot implementation of {@link GraalCodeCacheProvider}. */ -public class HotSpotRuntime implements GraalCodeCacheProvider { +public abstract class HotSpotRuntime implements GraalCodeCacheProvider { public final HotSpotVMConfig config; - final HotSpotRegisterConfig regConfig; - private final HotSpotRegisterConfig globalStubRegConfig; + private final RegisterConfig regConfig; + private final RegisterConfig globalStubRegConfig; private final HotSpotGraalRuntime graalRuntime; private CheckCastSnippets.Templates checkcastSnippets; private InstanceOfSnippets.Templates instanceofSnippets; @@ -67,10 +67,12 @@ public HotSpotRuntime(HotSpotVMConfig config, HotSpotGraalRuntime graalRuntime) { this.config = config; this.graalRuntime = graalRuntime; - regConfig = new HotSpotRegisterConfig(config, false); - globalStubRegConfig = new HotSpotRegisterConfig(config, true); + regConfig = createRegisterConfig(false); + globalStubRegConfig = createRegisterConfig(true); } + protected abstract RegisterConfig createRegisterConfig(boolean globalStubConfig); + public void installSnippets(SnippetInstaller installer) { installer.install(SystemSnippets.class); installer.install(UnsafeSnippets.class); @@ -92,6 +94,16 @@ return graalRuntime; } + /** + * Gets the register holding the current thread. + */ + public abstract Register threadRegister(); + + /** + * Gets the stack pointer register. + */ + public abstract Register stackPointerRegister(); + @Override public String disassemble(CodeInfo info, CompilationResult tm) { byte[] code = info.code(); diff -r 85c1b84f8fd9 -r df02fa2bce58 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentThread.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentThread.java Tue Oct 02 22:22:06 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentThread.java Wed Oct 03 00:25:30 2012 +0200 @@ -40,7 +40,7 @@ @Override public void generate(LIRGeneratorTool gen) { - Register thread = HotSpotGraalRuntime.getInstance().getConfig().threadRegister; + Register thread = HotSpotGraalRuntime.getInstance().getRuntime().threadRegister(); gen.setResult(this, gen.emitLoad(new Address(Kind.Object, thread.asValue(gen.target().wordKind), threadObjectOffset), false)); } diff -r 85c1b84f8fd9 -r df02fa2bce58 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java Tue Oct 02 22:22:06 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/HotSpotSnippetUtils.java Wed Oct 03 00:25:30 2012 +0200 @@ -32,7 +32,6 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.snippets.Snippet.Fold; import com.oracle.graal.snippets.*; -import com.oracle.max.asm.amd64.*; //JaCoCo Exclude @@ -63,12 +62,12 @@ @Fold static Register threadRegister() { - return HotSpotGraalRuntime.getInstance().getConfig().threadRegister; + return HotSpotGraalRuntime.getInstance().getRuntime().threadRegister(); } @Fold static Register stackPointerRegister() { - return AMD64.rsp; + return HotSpotGraalRuntime.getInstance().getRuntime().stackPointerRegister(); } @Fold diff -r 85c1b84f8fd9 -r df02fa2bce58 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 Tue Oct 02 22:22:06 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/HotSpotBackend.java Wed Oct 03 00:25:30 2012 +0200 @@ -28,6 +28,7 @@ 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. @@ -45,10 +46,15 @@ private final Map stubsMap = new HashMap<>(); - public HotSpotBackend(CodeCacheProvider runtime, TargetDescription target) { + 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. */ diff -r 85c1b84f8fd9 -r df02fa2bce58 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64HotSpotBackend.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64HotSpotBackend.java Wed Oct 03 00:25:30 2012 +0200 @@ -0,0 +1,350 @@ +/* + * 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 85c1b84f8fd9 -r df02fa2bce58 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64HotSpotGraalRuntime.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64HotSpotGraalRuntime.java Wed Oct 03 00:25:30 2012 +0200 @@ -0,0 +1,65 @@ +/* + * 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 85c1b84f8fd9 -r df02fa2bce58 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64HotSpotRegisterConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64HotSpotRegisterConfig.java Wed Oct 03 00:25:30 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.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 85c1b84f8fd9 -r df02fa2bce58 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64HotSpotRuntime.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/AMD64HotSpotRuntime.java Wed Oct 03 00:25:30 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.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 85c1b84f8fd9 -r df02fa2bce58 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java Tue Oct 02 22:22:06 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,347 +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 HotSpotAMD64Backend extends HotSpotBackend { - - public HotSpotAMD64Backend(CodeCacheProvider runtime, TargetDescription target) { - super(runtime, target); - HotSpotRuntime hs = (HotSpotRuntime) runtime; - HotSpotVMConfig c = hs.config; - Kind word = target.wordKind; - - Register[] jargs = hs.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 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, ((HotSpotRuntime) 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 = ((HotSpotRuntime) runtime).config; - RegisterValue thread = config.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 = ((HotSpotRuntime) runtime).config; - - // If at the return point, then the frame has already been popped - // so deoptimization cannot be performed here. The HotSpot runtime - // detects this case - see the definition of frame::should_be_deoptimized() - - 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 = ((HotSpotRuntime) 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 85c1b84f8fd9 -r df02fa2bce58 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Tue Oct 02 22:22:06 2012 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Wed Oct 03 00:25:30 2012 +0200 @@ -288,7 +288,8 @@ 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") \ - /* graal.api.meta */ \ + AMD64_ONLY(template(com_oracle_graal_hotspot_target_amd64_AMD64HotSpotGraalRuntime,"com/oracle/graal/hotspot/target/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") \ template(com_oracle_graal_api_meta_ExceptionHandler, "com/oracle/graal/api/meta/ExceptionHandler") \ @@ -297,7 +298,7 @@ template(com_oracle_graal_api_meta_Kind, "com/oracle/graal/api/meta/Kind") \ template(com_oracle_graal_api_meta_ResolvedJavaField, "com/oracle/graal/api/meta/ResolvedJavaField") \ template(com_oracle_graal_api_meta_Value, "com/oracle/graal/api/meta/Value") \ - /* graal.api.code */ \ + /* graal.api.code */ \ template(com_oracle_graal_api_code_Assumptions, "com/oracle/graal/api/code/Assumptions") \ template(com_oracle_graal_api_code_Assumptions_MethodContents, "com/oracle/graal/api/code/Assumptions$MethodContents") \ template(com_oracle_graal_api_code_Assumptions_ConcreteSubtype, "com/oracle/graal/api/code/Assumptions$ConcreteSubtype") \ diff -r 85c1b84f8fd9 -r df02fa2bce58 src/share/vm/graal/graalVMToCompiler.cpp --- a/src/share/vm/graal/graalVMToCompiler.cpp Tue Oct 02 22:22:06 2012 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.cpp Wed Oct 03 00:25:30 2012 +0200 @@ -40,12 +40,15 @@ Handle VMToCompiler::compilerInstance() { if (JNIHandles::resolve(_compilerPermObject) == NULL) { - KlassHandle compilerImplKlass = SystemDictionary::resolve_or_null(vmSymbols::com_oracle_graal_hotspot_HotSpotGraalRuntime(), SystemDictionary::java_system_loader(), NULL, Thread::current()); +#ifdef AMD64 + Symbol* compilerImplKlassName = vmSymbols::com_oracle_graal_hotspot_target_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"); JavaValue result(T_OBJECT); - JavaCalls::call_static(&result, compilerImplKlass, vmSymbols::getInstance_name(), vmSymbols::getInstance_signature(), Thread::current()); - check_pending_exception("Couldn't get Compiler"); + JavaCalls::call_static(&result, compilerImplKlass, vmSymbols::initialize_name(), vmSymbols::getInstance_signature(), Thread::current()); + check_pending_exception("Couldn't initialize HotSpotGraalRuntime"); _compilerPermObject = JNIHandles::make_global((oop) result.get_jobject()); } return Handle(JNIHandles::resolve_non_null(_compilerPermObject));