# HG changeset patch # User Thomas Wuerthinger # Date 1382018464 -7200 # Node ID 890bea7925fd7df0819d27ca82863c6d43a014f4 # Parent 561217cf2ac5b7e4d810588d9d8890a5b4fc556c# Parent 237aff48d57eb24518df030ae07513d8fd432116 Merge. diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Graal.java --- a/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Graal.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Graal.java Thu Oct 17 16:01:04 2013 +0200 @@ -69,5 +69,10 @@ public T getCapability(Class clazz) { return null; } + + @Override + public T getCapability(Class clazz, String selector) { + return null; + } } } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/GraalRuntime.java --- a/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/GraalRuntime.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/GraalRuntime.java Thu Oct 17 16:01:04 2013 +0200 @@ -27,4 +27,14 @@ String getName(); T getCapability(Class clazz); + + /** + * Requests a capability represented by a given class. + * + * @param selector a value the runtime will use to refine the capability returned (if any). An + * example may be the name of an architecture when asking for a capability + * representing a compiler backend. + */ + T getCapability(Class clazz, String selector); + } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Thu Oct 17 16:01:04 2013 +0200 @@ -22,12 +22,12 @@ */ package com.oracle.graal.asm.sparc; +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.sparc.SPARC.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; -import com.oracle.graal.hotspot.*; import com.oracle.graal.sparc.*; /** @@ -1269,7 +1269,7 @@ Icc(0b00, "icc"), Xcc(0b10, "xcc"), - Ptrcc(HotSpotGraalRuntime.wordKind() == Kind.Long ? Xcc.getValue() : Icc.getValue(), "ptrcc"), + Ptrcc(getHostWordKind() == Kind.Long ? Xcc.getValue() : Icc.getValue(), "ptrcc"), Fcc0(0b00, "fcc0"), Fcc1(0b01, "fcc1"), Fcc2(0b10, "fcc2"), diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Buffer.java --- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Buffer.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Buffer.java Thu Oct 17 16:01:04 2013 +0200 @@ -60,6 +60,9 @@ } public byte[] copyData(int start, int end) { + if (data == null) { + return null; + } return Arrays.copyOfRange(data, start, end); } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java Thu Oct 17 16:01:04 2013 +0200 @@ -24,15 +24,19 @@ import org.junit.*; -import com.oracle.graal.compiler.test.GraalCompilerTest; +import com.oracle.graal.compiler.test.*; import com.oracle.graal.hotspot.hsail.*; -import com.oracle.graal.nodes.StructuredGraph; +import com.oracle.graal.nodes.*; /** * Test class for small Java methods compiled to HSAIL kernels. */ public class BasicHSAILTest extends GraalCompilerTest { + public BasicHSAILTest() { + super("HSAIL"); + } + public void testAdd() { test("testAddSnippet"); } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FloatSqrtTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FloatSqrtTest.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FloatSqrtTest.java Thu Oct 17 16:01:04 2013 +0200 @@ -24,8 +24,12 @@ package com.oracle.graal.compiler.hsail.test; import java.util.*; + import org.junit.*; -import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; + +import com.oracle.graal.compiler.hsail.*; +import com.oracle.graal.compiler.hsail.test.infra.*; +import com.oracle.graal.graph.*; /** * Tests floating point square root. @@ -54,7 +58,10 @@ dispatchMethodKernel(64, input, output); } - @Test + /** + * Requires {@link HSAILLIRGenerator#emitDirectCall} to be implemented. + */ + @Test(expected = GraalInternalError.class) public void test() { testGeneratedHsail(); } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodySpillTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodySpillTest.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodySpillTest.java Thu Oct 17 16:01:04 2013 +0200 @@ -27,7 +27,9 @@ import org.junit.*; -import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import com.oracle.graal.compiler.hsail.*; +import com.oracle.graal.compiler.hsail.test.infra.*; +import com.oracle.graal.graph.*; /** * This version of NBody causes Graal to generate register spilling code. @@ -96,9 +98,11 @@ } // Marked to only run on hardware until simulator spill bug is fixed. - @Test + /** + * Requires {@link HSAILLIRGenerator#emitDirectCall} to be implemented. + */ + @Test(expected = GraalInternalError.class) public void test() { testGeneratedHsail(); } - } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodyTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodyTest.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodyTest.java Thu Oct 17 16:01:04 2013 +0200 @@ -26,7 +26,10 @@ import java.util.*; import org.junit.*; -import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; + +import com.oracle.graal.compiler.hsail.*; +import com.oracle.graal.compiler.hsail.test.infra.*; +import com.oracle.graal.graph.*; /** * Unit test of NBody demo app. @@ -94,7 +97,10 @@ dispatchMethodKernel(bodies, inxyz, outxyz, invxyz, outvxyz); } - @Test + /** + * Requires {@link HSAILLIRGenerator#emitDirectCall} to be implemented. + */ + @Test(expected = GraalInternalError.class) public void test() { testGeneratedHsail(); } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StringContainsTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StringContainsTest.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StringContainsTest.java Thu Oct 17 16:01:04 2013 +0200 @@ -24,6 +24,9 @@ package com.oracle.graal.compiler.hsail.test; import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.hsail.*; + import org.junit.Test; /** @@ -56,7 +59,10 @@ dispatchMethodKernel(NUM, base); } - @Test + /** + * Requires {@link HSAILHotSpotForeignCallsProvider#lookupForeignCall} to be implemented. + */ + @Test(expected = GraalInternalError.class) public void test() { testGeneratedHsail(); } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StringIndexOfTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StringIndexOfTest.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StringIndexOfTest.java Thu Oct 17 16:01:04 2013 +0200 @@ -24,6 +24,9 @@ package com.oracle.graal.compiler.hsail.test; import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.hsail.*; + import org.junit.Test; /** @@ -56,7 +59,10 @@ dispatchMethodKernel(NUM, base); } - @Test + /** + * Requires {@link HSAILHotSpotForeignCallsProvider#lookupForeignCall} to be implemented. + */ + @Test(expected = GraalInternalError.class) public void test() { testGeneratedHsail(); } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java --- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Thu Oct 17 16:01:04 2013 +0200 @@ -164,7 +164,7 @@ @Override public Variable emitAddress(StackSlot address) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override @@ -212,12 +212,12 @@ @Override public void emitOverflowCheckBranch(LabelRef label, boolean negated) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override @@ -243,7 +243,7 @@ @Override public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override @@ -435,12 +435,12 @@ @Override public Variable emitUDiv(Value a, Value b, DeoptimizingNode deopting) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override public Variable emitURem(Value a, Value b, DeoptimizingNode deopting) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override @@ -461,12 +461,12 @@ @Override public Variable emitOr(Value a, Value b) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override public Variable emitXor(Value a, Value b) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override @@ -487,7 +487,7 @@ @Override public Variable emitShr(Value a, Value b) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override @@ -545,17 +545,17 @@ @Override public void emitMembar(int barriers) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override @@ -571,11 +571,11 @@ append(new ForeignCall1ArgOp(callName, result, arguments[0])); break; default: - throw new InternalError("NYI emitForeignCall"); + throw GraalInternalError.unimplemented(); } } else { - throw new InternalError("NYI emitForeignCall"); + throw GraalInternalError.unimplemented(); } } @@ -590,17 +590,17 @@ @Override public void emitBitScanForward(Variable result, Value value) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override public void emitBitScanReverse(Variable result, Value value) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override public Value emitMathAbs(Value input) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override @@ -612,27 +612,27 @@ @Override public Value emitMathLog(Value input, boolean base10) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override public Value emitMathCos(Value input) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override public Value emitMathSin(Value input) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override public Value emitMathTan(Value input) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override public void emitByteSwap(Variable result, Value input) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override @@ -642,27 +642,27 @@ @Override protected void emitSequentialSwitch(Constant[] keyConstants, LabelRef[] keyTargets, LabelRef defaultTarget, Value key) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override protected void emitSwitchRanges(int[] lowKeys, int[] highKeys, LabelRef[] targets, LabelRef defaultTarget, Value key) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override protected void emitTableSwitch(int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value key) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override public void visitCompareAndSwap(LoweredCompareAndSwapNode node, Value address) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override public void visitBreakpointNode(BreakpointNode node) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override @@ -672,7 +672,7 @@ @Override public void emitUnwind(Value operand) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } @Override @@ -685,6 +685,6 @@ @Override public void visitInfopointNode(InfopointNode i) { - throw new InternalError("NYI"); + throw GraalInternalError.unimplemented(); } } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java Thu Oct 17 16:01:04 2013 +0200 @@ -31,6 +31,7 @@ import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.ptx.*; +import com.oracle.graal.compiler.target.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.debug.*; import com.oracle.graal.hotspot.meta.*; @@ -41,7 +42,6 @@ import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.tiers.*; -import com.oracle.graal.ptx.*; public abstract class PTXTestBase extends GraalCompilerTest { @@ -54,13 +54,17 @@ } + public PTXTestBase() { + super("PTX"); + } + protected CompilationResult compile(String test) { - if (getCodeCache() instanceof PTXHotSpotCodeCacheProvider) { + if (getBackend() instanceof PTXHotSpotBackend) { StructuredGraph graph = parse(test); sg = graph; Debug.dump(graph, "Graph"); - TargetDescription target = new TargetDescription(new PTX(), true, 1, 0, true); - PTXBackend ptxBackend = new PTXBackend(getProviders()); + Backend ptxBackend = getBackend(); + TargetDescription target = ptxBackend.getTarget(); PhasePlan phasePlan = new PhasePlan(); GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.NONE); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); @@ -76,8 +80,9 @@ * Ultimately we might want to have both the kernel and the code natively compiled for * GPU fallback to CPU in cases of ECC failure on kernel invocation. */ + Suites suites = Suites.createDefaultSuites(); CompilationResult result = GraalCompiler.compileGraph(graph, cc, graph.method(), getProviders(), ptxBackend, target, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), - Suites.createDefaultSuites(), new ExternalCompilationResult()); + suites, new ExternalCompilationResult()); return result; } else { return null; diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java Thu Oct 17 15:59:12 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,273 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.compiler.ptx; - -import static com.oracle.graal.lir.LIRValueUtil.*; - -import java.util.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.asm.*; -import com.oracle.graal.asm.ptx.*; -import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.compiler.target.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.LIRInstruction.OperandFlag; -import com.oracle.graal.lir.LIRInstruction.OperandMode; -import com.oracle.graal.lir.LIRInstruction.ValueProcedure; -import com.oracle.graal.lir.StandardOp.LabelOp; -import com.oracle.graal.lir.asm.*; -import com.oracle.graal.lir.ptx.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.cfg.*; -import com.oracle.graal.phases.util.*; - -/** - * PTX specific backend. - */ -public class PTXBackend extends Backend { - - public PTXBackend(Providers providers) { - super(providers); - } - - @Override - public boolean shouldAllocateRegisters() { - return false; - } - - @Override - public FrameMap newFrameMap() { - return new PTXFrameMap(getCodeCache()); - } - - @Override - public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) { - return new PTXLIRGenerator(graph, getProviders(), frameMap, cc, lir); - } - - class PTXFrameContext implements FrameContext { - - @Override - public void enter(TargetMethodAssembler tasm) { - // codeBuffer.emitString(".address_size 32"); // PTX ISA version 2.3 - } - - @Override - public void leave(TargetMethodAssembler tasm) { - } - } - - @Override - protected AbstractAssembler createAssembler(FrameMap frameMap) { - return new PTXAssembler(getTarget(), frameMap.registerConfig); - } - - @Override - public TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult) { - // Omit the frame of 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 - FrameMap frameMap = lirGen.frameMap; - AbstractAssembler masm = createAssembler(frameMap); - PTXFrameContext frameContext = new PTXFrameContext(); - TargetMethodAssembler tasm = new PTXTargetMethodAssembler(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult); - tasm.setFrameSize(0); - return tasm; - } - - private static void emitKernelEntry(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) { - // Emit PTX kernel entry text based on PTXParameterOp - // instructions in the start block. Remove the instructions - // once kernel entry text and directives are emitted to - // facilitate seemless PTX code generation subsequently. - assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method"; - final String name = codeCacheOwner.getName(); - Buffer codeBuffer = tasm.asm.codeBuffer; - - // Emit initial boiler-plate directives. - codeBuffer.emitString(".version 3.0"); - codeBuffer.emitString(".target sm_30"); - codeBuffer.emitString0(".entry " + name + " ("); - codeBuffer.emitString(""); - - // Get the start block - Block startBlock = lirGen.lir.cfg.getStartBlock(); - // Keep a list of ParameterOp instructions to delete from the - // list of instructions in the block. - ArrayList deleteOps = new ArrayList<>(); - - // Emit .param arguments to kernel entry based on ParameterOp - // instruction. - for (LIRInstruction op : lirGen.lir.lir(startBlock)) { - if (op instanceof PTXParameterOp) { - op.emitCode(tasm); - deleteOps.add(op); - } - } - - // Delete ParameterOp instructions. - for (LIRInstruction op : deleteOps) { - lirGen.lir.lir(startBlock).remove(op); - } - - // Start emiting body of the PTX kernel. - codeBuffer.emitString0(") {"); - codeBuffer.emitString(""); - } - - // Emit .reg space declarations - private static void emitRegisterDecl(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) { - - assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method"; - - Buffer codeBuffer = tasm.asm.codeBuffer; - - final SortedSet signed32 = new TreeSet<>(); - final SortedSet signed64 = new TreeSet<>(); - final SortedSet unsigned64 = new TreeSet<>(); - final SortedSet float32 = new TreeSet<>(); - final SortedSet float64 = new TreeSet<>(); - - ValueProcedure trackRegisterKind = new ValueProcedure() { - - @Override - public Value doValue(Value value, OperandMode mode, EnumSet flags) { - if (isVariable(value)) { - Variable regVal = (Variable) value; - Kind regKind = regVal.getKind(); - switch (regKind) { - case Int: - // If the register was used as a wider signed type - // do not add it here - if (!signed64.contains(regVal.index)) { - signed32.add(regVal.index); - } - break; - case Long: - // If the register was used as a narrower signed type - // remove it from there and add it to wider type. - if (signed32.contains(regVal.index)) { - signed32.remove(regVal.index); - } - signed64.add(regVal.index); - break; - case Float: - // If the register was used as a wider signed type - // do not add it here - if (!float64.contains(regVal.index)) { - float32.add(regVal.index); - } - break; - case Double: - // If the register was used as a narrower signed type - // remove it from there and add it to wider type. - if (float32.contains(regVal.index)) { - float32.remove(regVal.index); - } - float64.add(regVal.index); - break; - case Object: - unsigned64.add(regVal.index); - break; - default: - throw GraalInternalError.shouldNotReachHere("unhandled register type " + value.toString()); - } - } - return value; - } - }; - - for (Block b : lirGen.lir.codeEmittingOrder()) { - for (LIRInstruction op : lirGen.lir.lir(b)) { - if (op instanceof LabelOp) { - // Don't consider this as a definition - } else { - op.forEachTemp(trackRegisterKind); - op.forEachOutput(trackRegisterKind); - } - } - } - - for (Integer i : signed32) { - codeBuffer.emitString(".reg .s32 %r" + i.intValue() + ";"); - } - for (Integer i : signed64) { - codeBuffer.emitString(".reg .s64 %r" + i.intValue() + ";"); - } - for (Integer i : unsigned64) { - codeBuffer.emitString(".reg .u64 %r" + i.intValue() + ";"); - } - for (Integer i : float32) { - codeBuffer.emitString(".reg .f32 %r" + i.intValue() + ";"); - } - for (Integer i : float64) { - codeBuffer.emitString(".reg .f64 %r" + i.intValue() + ";"); - } - // emit predicate register declaration - int maxPredRegNum = ((PTXLIRGenerator) lirGen).getNextPredRegNumber(); - if (maxPredRegNum > 0) { - codeBuffer.emitString(".reg .pred %p<" + maxPredRegNum + ">;"); - } - codeBuffer.emitString(".reg .pred %r;"); // used for setp bool - } - - @Override - public void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) { - assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method"; - Buffer codeBuffer = tasm.asm.codeBuffer; - // Emit the prologue - emitKernelEntry(tasm, lirGen, codeCacheOwner); - - // Emit register declarations - try { - emitRegisterDecl(tasm, lirGen, codeCacheOwner); - } catch (GraalInternalError e) { - e.printStackTrace(); - // TODO : Better error handling needs to be done once - // all types of parameters are handled. - codeBuffer.setPosition(0); - codeBuffer.close(false); - return; - } - // Emit code for the LIR - try { - lirGen.lir.emitCode(tasm); - } catch (GraalInternalError e) { - e.printStackTrace(); - // TODO : Better error handling needs to be done once - // all types of parameters are handled. - codeBuffer.setPosition(0); - codeBuffer.close(false); - return; - } - - // Emit the epilogue - codeBuffer.emitString0("}"); - codeBuffer.emitString(""); - } -} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Thu Oct 17 16:01:04 2013 +0200 @@ -78,12 +78,30 @@ public abstract class GraalCompilerTest extends GraalTest { private final Providers providers; - protected final Backend backend; - protected final Suites suites; + private final Backend backend; + private final Suites suites; public GraalCompilerTest() { - this.providers = GraalCompiler.getGraalProviders(); this.backend = Graal.getRequiredCapability(Backend.class); + this.providers = getBackend().getProviders(); + this.suites = Graal.getRequiredCapability(SuitesProvider.class).createSuites(); + } + + /** + * Set up a test for a non-default backend. The test should check (via {@link #getBackend()} ) + * whether the desired backend is available. + * + * @param arch the name of the desired backend architecture + */ + public GraalCompilerTest(String arch) { + Backend b = Graal.getRuntime().getCapability(Backend.class, arch); + if (b != null) { + this.backend = b; + } else { + // Fall back to the default/host backend + this.backend = Graal.getRuntime().getCapability(Backend.class); + } + this.providers = backend.getProviders(); this.suites = Graal.getRequiredCapability(SuitesProvider.class).createSuites(); } @@ -157,6 +175,14 @@ return result.toString(); } + protected Backend getBackend() { + return backend; + } + + protected Suites getSuites() { + return suites; + } + protected Providers getProviders() { return providers; } @@ -487,8 +513,8 @@ GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); - final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, getProviders(), backend, getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, - new SpeculationLog(), suites, new CompilationResult()); + final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), null, phasePlan, + OptimisticOptimizations.ALL, new SpeculationLog(), getSuites(), new CompilationResult()); if (printCompilation) { TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize())); } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java Thu Oct 17 16:01:04 2013 +0200 @@ -59,8 +59,8 @@ final Method method = getMethod("testMethod"); final StructuredGraph graph = parse(method); CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); - final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), getProviders(), backend, getCodeCache().getTarget(), null, getDefaultPhasePlan(), - OptimisticOptimizations.ALL, new SpeculationLog(), suites, new CompilationResult()); + final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultPhasePlan(), + OptimisticOptimizations.ALL, new SpeculationLog(), getSuites(), new CompilationResult()); for (Infopoint sp : cr.getInfopoints()) { assertNotNull(sp.reason); if (sp instanceof Call) { @@ -81,8 +81,8 @@ } assertTrue(graphLineSPs > 0); CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); - final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), getProviders(), backend, getCodeCache().getTarget(), null, getDefaultPhasePlan(true), - OptimisticOptimizations.ALL, new SpeculationLog(), suites, new CompilationResult()); + final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultPhasePlan(true), + OptimisticOptimizations.ALL, new SpeculationLog(), getSuites(), new CompilationResult()); int lineSPs = 0; for (Infopoint sp : cr.getInfopoints()) { assertNotNull(sp.reason); diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Thu Oct 17 16:01:04 2013 +0200 @@ -119,7 +119,7 @@ @Override public LIR call() { - return GraalCompiler.emitHIR(getProviders(), backend.getTarget(), graph, assumptions, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), suites); + return GraalCompiler.emitHIR(getProviders(), getBackend().getTarget(), graph, assumptions, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), getSuites()); } }); @@ -128,7 +128,7 @@ @Override public RegisterStats call() { CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); - GraalCompiler.emitLIR(backend, backend.getTarget(), lir, graph, cc); + GraalCompiler.emitLIR(getBackend(), getBackend().getTarget(), lir, graph, cc); return new RegisterStats(lir); } }); diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Thu Oct 17 16:01:04 2013 +0200 @@ -284,6 +284,10 @@ } result.setLeafGraphIds(leafGraphIds); + if (Debug.isLogEnabled()) { + Debug.log("%s", backend.getProviders().getCodeCache().disassemble(result, null)); + } + Debug.dump(result, "After code generation"); } diff -r 561217cf2ac5 -r 890bea7925fd 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 Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Thu Oct 17 16:01:04 2013 +0200 @@ -32,7 +32,7 @@ import com.oracle.graal.phases.util.*; /** - * The {@code Backend} class represents a compiler backend for Graal. + * Represents a compiler backend for Graal. */ public abstract class Backend { diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Thu Oct 17 16:01:04 2013 +0200 @@ -0,0 +1,141 @@ +/* + * 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 java.util.*; + +import com.oracle.graal.amd64.*; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.runtime.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.phases.util.*; + +@ServiceProvider(HotSpotBackendFactory.class) +public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory { + + protected Architecture createArchitecture(HotSpotVMConfig config) { + return new AMD64(config.useSSE, config.useAVX); + } + + protected TargetDescription createTarget(HotSpotVMConfig config) { + final int stackFrameAlignment = 16; + final int implicitNullCheckLimit = 4096; + final boolean inlineObjects = true; + return new TargetDescription(createArchitecture(config), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); + } + + @Override + public HotSpotBackend createBackend(HotSpotGraalRuntime runtime, HotSpotBackend host) { + assert host == null; + TargetDescription target = createTarget(runtime.getConfig()); + + HotSpotMetaAccessProvider metaAccess = new HotSpotMetaAccessProvider(runtime); + HotSpotCodeCacheProvider codeCache = new AMD64HotSpotCodeCacheProvider(runtime, target); + HotSpotConstantReflectionProvider constantReflection = new HotSpotConstantReflectionProvider(runtime); + Value[] nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(runtime.getConfig(), codeCache.getRegisterConfig()); + HotSpotForeignCallsProvider foreignCalls = new AMD64HotSpotForeignCallsProvider(runtime, metaAccess, codeCache, nativeABICallerSaveRegisters); + HotSpotLoweringProvider lowerer = new AMD64HotSpotLoweringProvider(runtime, metaAccess, foreignCalls); + // Replacements cannot have speculative optimizations since they have + // to be valid for the entire run of the VM. + Assumptions assumptions = new Assumptions(false); + Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null); + HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, runtime.getConfig(), assumptions); + HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(runtime); + HotSpotSuitesProvider suites = new HotSpotSuitesProvider(runtime); + HotSpotRegisters registers = new HotSpotRegisters(AMD64.r15, AMD64.r12, AMD64.rsp); + HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); + + return new AMD64HotSpotBackend(runtime, providers); + } + + private static Value[] createNativeABICallerSaveRegisters(HotSpotVMConfig config, RegisterConfig regConfig) { + List callerSave = new ArrayList<>(Arrays.asList(regConfig.getAllocatableRegisters())); + if (config.windowsOs) { + // http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx + callerSave.remove(AMD64.rdi); + callerSave.remove(AMD64.rsi); + callerSave.remove(AMD64.rbx); + callerSave.remove(AMD64.rbp); + callerSave.remove(AMD64.rsp); + callerSave.remove(AMD64.r12); + callerSave.remove(AMD64.r13); + callerSave.remove(AMD64.r14); + callerSave.remove(AMD64.r15); + callerSave.remove(AMD64.xmm6); + callerSave.remove(AMD64.xmm7); + callerSave.remove(AMD64.xmm8); + callerSave.remove(AMD64.xmm9); + callerSave.remove(AMD64.xmm10); + callerSave.remove(AMD64.xmm11); + callerSave.remove(AMD64.xmm12); + callerSave.remove(AMD64.xmm13); + callerSave.remove(AMD64.xmm14); + callerSave.remove(AMD64.xmm15); + } else { + /* + * System V Application Binary Interface, AMD64 Architecture Processor Supplement + * + * Draft Version 0.96 + * + * http://www.uclibc.org/docs/psABI-x86_64.pdf + * + * 3.2.1 + * + * ... + * + * This subsection discusses usage of each register. Registers %rbp, %rbx and %r12 + * through %r15 "belong" to the calling function and the called function is required to + * preserve their values. In other words, a called function must preserve these + * registers' values for its caller. Remaining registers "belong" to the called + * function. If a calling function wants to preserve such a register value across a + * function call, it must save the value in its local stack frame. + */ + callerSave.remove(AMD64.rbp); + callerSave.remove(AMD64.rbx); + callerSave.remove(AMD64.r12); + callerSave.remove(AMD64.r13); + callerSave.remove(AMD64.r14); + callerSave.remove(AMD64.r15); + } + Value[] nativeABICallerSaveRegisters = new Value[callerSave.size()]; + for (int i = 0; i < callerSave.size(); i++) { + nativeABICallerSaveRegisters[i] = callerSave.get(i).asValue(); + } + return nativeABICallerSaveRegisters; + } + + public String getArchitecture() { + return "AMD64"; + } + + public String getGraalRuntimeName() { + return "basic"; + } + + @Override + public String toString() { + return getGraalRuntimeName() + ":" + getArchitecture(); + } +} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallEpilogueOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallEpilogueOp.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallEpilogueOp.java Thu Oct 17 16:01:04 2013 +0200 @@ -22,11 +22,8 @@ */ package com.oracle.graal.hotspot.amd64; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; - import com.oracle.graal.api.code.*; import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.hotspot.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; @@ -34,13 +31,20 @@ @Opcode("CRUNTIME_CALL_EPILOGUE") final class AMD64HotSpotCRuntimeCallEpilogueOp extends AMD64LIRInstruction { + private final int threadLastJavaSpOffset; + private final int threadLastJavaFpOffset; + private final Register thread; + + public AMD64HotSpotCRuntimeCallEpilogueOp(int threadLastJavaSpOffset, int threadLastJavaFpOffset, Register thread) { + this.threadLastJavaSpOffset = threadLastJavaSpOffset; + this.threadLastJavaFpOffset = threadLastJavaFpOffset; + this.thread = thread; + } + @Override public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { // reset last Java frame: - HotSpotVMConfig config = runtime().getConfig(); - Register thread = runtime().getProviders().getRegisters().getThreadRegister(); - - masm.movslq(new AMD64Address(thread, config.threadLastJavaSpOffset), 0); - masm.movslq(new AMD64Address(thread, config.threadLastJavaFpOffset), 0); + masm.movslq(new AMD64Address(thread, threadLastJavaSpOffset), 0); + masm.movslq(new AMD64Address(thread, threadLastJavaFpOffset), 0); } } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallPrologueOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallPrologueOp.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCRuntimeCallPrologueOp.java Thu Oct 17 16:01:04 2013 +0200 @@ -23,7 +23,6 @@ package com.oracle.graal.hotspot.amd64; import static com.oracle.graal.amd64.AMD64.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import com.oracle.graal.api.code.*; import com.oracle.graal.asm.amd64.*; @@ -34,11 +33,17 @@ @Opcode final class AMD64HotSpotCRuntimeCallPrologueOp extends AMD64LIRInstruction { + private final int threadLastJavaSpOffset; + private final Register thread; + + public AMD64HotSpotCRuntimeCallPrologueOp(int threadLastJavaSpOffset, Register thread) { + this.threadLastJavaSpOffset = threadLastJavaSpOffset; + this.thread = thread; + } + @Override public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { - // save last Java frame - Register thread = runtime().getProviders().getRegisters().getThreadRegister(); - masm.movq(new AMD64Address(thread, runtime().getConfig().threadLastJavaSpOffset), rsp); + masm.movq(new AMD64Address(thread, threadLastJavaSpOffset), rsp); } } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCodeCacheProvider.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCodeCacheProvider.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCodeCacheProvider.java Thu Oct 17 16:01:04 2013 +0200 @@ -28,13 +28,12 @@ public class AMD64HotSpotCodeCacheProvider extends HotSpotCodeCacheProvider { - public AMD64HotSpotCodeCacheProvider(HotSpotGraalRuntime runtime) { - super(runtime); - + public AMD64HotSpotCodeCacheProvider(HotSpotGraalRuntime runtime, TargetDescription target) { + super(runtime, target); } @Override protected RegisterConfig createRegisterConfig() { - return new AMD64HotSpotRegisterConfig(runtime.getTarget().arch, runtime.getConfig()); + return new AMD64HotSpotRegisterConfig(getTarget().arch, runtime.getConfig()); } } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java Thu Oct 17 16:01:04 2013 +0200 @@ -39,16 +39,18 @@ import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; -public class AMD64HotSpotForeignCallsProvider extends HotSpotForeignCallsProvider { +public class AMD64HotSpotForeignCallsProvider extends HotSpotHostForeignCallsProvider { + + private final Value[] nativeABICallerSaveRegisters; - public AMD64HotSpotForeignCallsProvider(HotSpotGraalRuntime runtime) { - super(runtime); + public AMD64HotSpotForeignCallsProvider(HotSpotGraalRuntime runtime, MetaAccessProvider metaAccess, CodeCacheProvider codeCache, Value[] nativeABICallerSaveRegisters) { + super(runtime, metaAccess, codeCache); + this.nativeABICallerSaveRegisters = nativeABICallerSaveRegisters; } @Override - public void initialize(HotSpotProviders providers) { - Kind word = runtime.getTarget().wordKind; - HotSpotVMConfig config = runtime.getConfig(); + public void initialize(HotSpotProviders providers, HotSpotVMConfig config) { + Kind word = providers.getCodeCache().getTarget().wordKind; // The calling convention for the exception handler stub is (only?) defined in // TemplateInterpreterGenerator::generate_throw_exception() @@ -66,6 +68,12 @@ registerForeignCall(DECRYPT, config.cipherBlockChainingDecryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); - super.initialize(providers); + super.initialize(providers, config); } + + @Override + public Value[] getNativeABICallerSaveRegisters() { + return nativeABICallerSaveRegisters; + } + } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java Thu Oct 17 15:59:12 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,155 +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.amd64; - -import java.util.*; - -import com.oracle.graal.amd64.*; -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.phases.util.*; - -/** - * AMD64 specific implementation of {@link HotSpotGraalRuntime}. - */ -public class AMD64HotSpotGraalRuntime extends HotSpotGraalRuntime { - - private Value[] nativeABICallerSaveRegisters; - - protected AMD64HotSpotGraalRuntime() { - } - - /** - * Called from C++ code to retrieve the singleton instance, creating it first if necessary. - */ - public static HotSpotGraalRuntime makeInstance() { - HotSpotGraalRuntime runtime = runtime(); - if (runtime == null) { - HotSpotGraalRuntimeFactory factory = findFactory("AMD64"); - if (factory != null) { - runtime = factory.createRuntime(); - } else { - runtime = new AMD64HotSpotGraalRuntime(); - } - runtime.completeInitialization(); - } - return runtime; - } - - protected Architecture createArchitecture() { - return new AMD64(config.useSSE, config.useAVX); - } - - @Override - protected HotSpotProviders createProviders() { - HotSpotMetaAccessProvider metaAccess = new HotSpotMetaAccessProvider(this); - HotSpotCodeCacheProvider codeCache = new AMD64HotSpotCodeCacheProvider(this); - HotSpotConstantReflectionProvider constantReflection = new HotSpotConstantReflectionProvider(this); - HotSpotForeignCallsProvider foreignCalls = new AMD64HotSpotForeignCallsProvider(this); - HotSpotLoweringProvider lowerer = new AMD64HotSpotLoweringProvider(this, metaAccess, foreignCalls); - // Replacements cannot have speculative optimizations since they have - // to be valid for the entire run of the VM. - Assumptions assumptions = new Assumptions(false); - Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null); - HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, getConfig(), assumptions); - HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(this); - HotSpotSuitesProvider suites = new HotSpotSuitesProvider(this); - HotSpotRegisters registers = new HotSpotRegisters(AMD64.r15, AMD64.r12, AMD64.rsp); - return new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); - } - - @Override - protected TargetDescription createTarget() { - final int stackFrameAlignment = 16; - final int implicitNullCheckLimit = 4096; - final boolean inlineObjects = true; - return new TargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); - } - - @Override - protected HotSpotBackend createBackend() { - return new AMD64HotSpotBackend(this, getProviders()); - } - - @Override - protected Value[] getNativeABICallerSaveRegisters() { - if (nativeABICallerSaveRegisters == null) { - List callerSave = new ArrayList<>(Arrays.asList(getProviders().getCodeCache().getRegisterConfig().getAllocatableRegisters())); - if (getConfig().windowsOs) { - // http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx - callerSave.remove(AMD64.rdi); - callerSave.remove(AMD64.rsi); - callerSave.remove(AMD64.rbx); - callerSave.remove(AMD64.rbp); - callerSave.remove(AMD64.rsp); - callerSave.remove(AMD64.r12); - callerSave.remove(AMD64.r13); - callerSave.remove(AMD64.r14); - callerSave.remove(AMD64.r15); - callerSave.remove(AMD64.xmm6); - callerSave.remove(AMD64.xmm7); - callerSave.remove(AMD64.xmm8); - callerSave.remove(AMD64.xmm9); - callerSave.remove(AMD64.xmm10); - callerSave.remove(AMD64.xmm11); - callerSave.remove(AMD64.xmm12); - callerSave.remove(AMD64.xmm13); - callerSave.remove(AMD64.xmm14); - callerSave.remove(AMD64.xmm15); - } else { - /* - * System V Application Binary Interface, AMD64 Architecture Processor Supplement - * - * Draft Version 0.96 - * - * http://www.uclibc.org/docs/psABI-x86_64.pdf - * - * 3.2.1 - * - * ... - * - * This subsection discusses usage of each register. Registers %rbp, %rbx and %r12 - * through %r15 "belong" to the calling function and the called function is required - * to preserve their values. In other words, a called function must preserve these - * registers' values for its caller. Remaining registers "belong" to the called - * function. If a calling function wants to preserve such a register value across a - * function call, it must save the value in its local stack frame. - */ - callerSave.remove(AMD64.rbp); - callerSave.remove(AMD64.rbx); - callerSave.remove(AMD64.r12); - callerSave.remove(AMD64.r13); - callerSave.remove(AMD64.r14); - callerSave.remove(AMD64.r15); - } - nativeABICallerSaveRegisters = new Value[callerSave.size()]; - for (int i = 0; i < callerSave.size(); i++) { - nativeABICallerSaveRegisters[i] = callerSave.get(i).asValue(); - } - } - - return nativeABICallerSaveRegisters; - } -} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntimeFactory.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntimeFactory.java Thu Oct 17 15:59:12 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.hotspot.amd64; - -import com.oracle.graal.api.runtime.*; -import com.oracle.graal.hotspot.*; - -@ServiceProvider(HotSpotGraalRuntimeFactory.class) -public class AMD64HotSpotGraalRuntimeFactory implements HotSpotGraalRuntimeFactory { - - @Override - public HotSpotGraalRuntime createRuntime() { - return new AMD64HotSpotGraalRuntime(); - } - - @Override - public String getArchitecture() { - return "AMD64"; - } - - @Override - public String getName() { - return "basic"; - } -} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotJumpToExceptionHandlerInCallerOp.java Thu Oct 17 16:01:04 2013 +0200 @@ -24,7 +24,6 @@ import static com.oracle.graal.amd64.AMD64.*; import static com.oracle.graal.api.code.ValueUtil.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import com.oracle.graal.api.code.*; @@ -44,11 +43,15 @@ @Use(REG) AllocatableValue handlerInCallerPc; @Use(REG) AllocatableValue exception; @Use(REG) AllocatableValue exceptionPc; + private final Register thread; + private final int isMethodHandleReturnOffset; - AMD64HotSpotJumpToExceptionHandlerInCallerOp(AllocatableValue handlerInCallerPc, AllocatableValue exception, AllocatableValue exceptionPc) { + AMD64HotSpotJumpToExceptionHandlerInCallerOp(AllocatableValue handlerInCallerPc, AllocatableValue exception, AllocatableValue exceptionPc, int isMethodHandleReturnOffset, Register thread) { this.handlerInCallerPc = handlerInCallerPc; this.exception = exception; this.exceptionPc = exceptionPc; + this.isMethodHandleReturnOffset = isMethodHandleReturnOffset; + this.thread = thread; } @Override @@ -59,8 +62,6 @@ masm.incrementq(rsp, 8); // Restore rsp from rbp if the exception PC is a method handle call site. - Register thread = runtime().getProviders().getRegisters().getThreadRegister(); - int isMethodHandleReturnOffset = runtime().getConfig().threadIsMethodHandleReturnOffset; AMD64Address dst = new AMD64Address(thread, isMethodHandleReturnOffset); masm.cmpl(dst, 0); masm.cmovq(ConditionFlag.NotEqual, rsp, rbp); diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Thu Oct 17 16:01:04 2013 +0200 @@ -180,9 +180,24 @@ } } + private Register findPollOnReturnScratchRegister() { + RegisterConfig regConfig = getProviders().getCodeCache().getRegisterConfig(); + for (Register r : regConfig.getAllocatableRegisters(Kind.Long)) { + if (r != regConfig.getReturnRegister(Kind.Long) && r != AMD64.rbp) { + return r; + } + } + throw GraalInternalError.shouldNotReachHere(); + } + + private Register pollOnReturnScratchRegister; + @Override protected void emitReturn(Value input) { - append(new AMD64HotSpotReturnOp(input, getStub() != null)); + if (pollOnReturnScratchRegister == null) { + pollOnReturnScratchRegister = findPollOnReturnScratchRegister(); + } + append(new AMD64HotSpotReturnOp(input, getStub() != null, pollOnReturnScratchRegister)); } @Override @@ -249,9 +264,10 @@ if (linkage.canDeoptimize()) { assert info != null || stub != null; - append(new AMD64HotSpotCRuntimeCallPrologueOp()); + Register thread = getProviders().getRegisters().getThreadRegister(); + append(new AMD64HotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset, thread)); result = super.emitForeignCall(linkage, info, args); - append(new AMD64HotSpotCRuntimeCallEpilogueOp()); + append(new AMD64HotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset, config.threadLastJavaFpOffset, thread)); } else { result = super.emitForeignCall(linkage, null, args); } @@ -408,7 +424,8 @@ RegisterValue exceptionPcFixed = (RegisterValue) outgoingCc.getArgument(1); emitMove(exceptionFixed, operand(exception)); emitMove(exceptionPcFixed, operand(exceptionPc)); - AMD64HotSpotJumpToExceptionHandlerInCallerOp op = new AMD64HotSpotJumpToExceptionHandlerInCallerOp(handler, exceptionFixed, exceptionPcFixed); + Register thread = getProviders().getRegisters().getThreadRegister(); + AMD64HotSpotJumpToExceptionHandlerInCallerOp op = new AMD64HotSpotJumpToExceptionHandlerInCallerOp(handler, exceptionFixed, exceptionPcFixed, config.threadIsMethodHandleReturnOffset, thread); append(op); } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLoweringProvider.java Thu Oct 17 16:01:04 2013 +0200 @@ -31,7 +31,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.amd64.*; -public class AMD64HotSpotLoweringProvider extends HotSpotLoweringProvider { +public class AMD64HotSpotLoweringProvider extends HotSpotHostLoweringProvider { private AMD64ConvertSnippets.Templates convertSnippets; @@ -40,10 +40,9 @@ } @Override - public void initialize() { - HotSpotProviders providers = runtime.getProviders(); - convertSnippets = new AMD64ConvertSnippets.Templates(providers, runtime.getTarget()); - super.initialize(); + public void initialize(HotSpotProviders providers, HotSpotVMConfig config) { + convertSnippets = new AMD64ConvertSnippets.Templates(providers, providers.getCodeCache().getTarget()); + super.initialize(providers, config); } @Override diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java Thu Oct 17 16:01:04 2013 +0200 @@ -26,12 +26,9 @@ import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static com.oracle.graal.phases.GraalOptions.*; -import com.oracle.graal.amd64.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.hotspot.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; @@ -43,24 +40,14 @@ @Use({REG, ILLEGAL}) protected Value value; private final boolean isStub; + private final Register scratchForSafepointOnReturn; - AMD64HotSpotReturnOp(Value value, boolean isStub) { + AMD64HotSpotReturnOp(Value value, boolean isStub, Register scratchForSafepointOnReturn) { this.value = value; this.isStub = isStub; + this.scratchForSafepointOnReturn = scratchForSafepointOnReturn; } - private static Register findPollOnReturnScratchRegister() { - RegisterConfig config = HotSpotGraalRuntime.runtime().getProviders().getCodeCache().getRegisterConfig(); - for (Register r : config.getAllocatableRegisters(Kind.Long)) { - if (r != config.getReturnRegister(Kind.Long) && r != AMD64.rbp) { - return r; - } - } - throw GraalInternalError.shouldNotReachHere(); - } - - private static final Register scratchForSafepointOnReturn = findPollOnReturnScratchRegister(); - @Override public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { leaveFrameAndRestoreRbp(tasm, masm); diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/ForEachToGraal.java Thu Oct 17 16:01:04 2013 +0200 @@ -32,7 +32,6 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; -import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; @@ -57,8 +56,7 @@ acceptMethod = m; } } - HotSpotGraalRuntime runtime = HotSpotGraalRuntime.runtime(); - HotSpotProviders providers = runtime.getProviders(); + HotSpotProviders providers = HSAILCompilationResult.backend.getProviders(); MetaAccessProvider metaAccess = providers.getMetaAccess(); ResolvedJavaMethod method = metaAccess.lookupJavaMethod(acceptMethod); StructuredGraph graph = new StructuredGraph(method); diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILCompilationResult.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILCompilationResult.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILCompilationResult.java Thu Oct 17 16:01:04 2013 +0200 @@ -23,6 +23,8 @@ package com.oracle.graal.hotspot.hsail; +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; + import java.lang.reflect.*; import java.util.logging.*; @@ -31,9 +33,9 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.*; +import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; -import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; @@ -73,17 +75,26 @@ consoleHandler.setLevel(logLevel); } - private static final HotSpotGraalRuntime runtime = new HSAILHotSpotGraalRuntime(); + static final HSAILHotSpotBackend backend; + static { + // Look for installed HSAIL backend + HSAILHotSpotBackend b = (HSAILHotSpotBackend) Graal.getRuntime().getCapability(Backend.class, "HSAIL"); + if (b == null) { + // Fall back to a new instance + b = new HSAILHotSpotBackendFactory().createBackend(runtime(), runtime().getHostBackend()); + } + backend = b; + } public static HSAILCompilationResult getHSAILCompilationResult(Method meth) { - HotSpotMetaAccessProvider metaAccess = runtime.getProviders().getMetaAccess(); + HotSpotMetaAccessProvider metaAccess = backend.getProviders().getMetaAccess(); ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(meth); return getHSAILCompilationResult(javaMethod); } public static HSAILCompilationResult getHSAILCompilationResult(ResolvedJavaMethod javaMethod) { - HotSpotMetaAccessProvider metaAccess = runtime.getProviders().getMetaAccess(); - ForeignCallsProvider foreignCalls = runtime.getProviders().getForeignCalls(); + HotSpotMetaAccessProvider metaAccess = backend.getProviders().getMetaAccess(); + ForeignCallsProvider foreignCalls = backend.getProviders().getForeignCalls(); StructuredGraph graph = new StructuredGraph(javaMethod); new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); return getHSAILCompilationResult(graph); @@ -112,15 +123,14 @@ argTypes[argIndex++] = sig.getParameterType(i, null); } - RegisterConfig registerConfig = runtime.getProviders().getCodeCache().getRegisterConfig(); + RegisterConfig registerConfig = backend.getProviders().getCodeCache().getRegisterConfig(); return registerConfig.getCallingConvention(type, retType, argTypes, target, stackOnly); } public static HSAILCompilationResult getHSAILCompilationResult(StructuredGraph graph) { Debug.dump(graph, "Graph"); - Providers providers = runtime.getProviders(); + Providers providers = backend.getProviders(); TargetDescription target = providers.getCodeCache().getTarget(); - HSAILHotSpotBackend hsailBackend = (HSAILHotSpotBackend) runtime.getBackend(); PhasePlan phasePlan = new PhasePlan(); GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(providers.getMetaAccess(), providers.getForeignCalls(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.NONE); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); @@ -129,11 +139,11 @@ CallingConvention cc = getHSAILCallingConvention(Type.JavaCallee, target, graph.method(), false); SuitesProvider suitesProvider = Graal.getRequiredCapability(SuitesProvider.class); try { - CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, graph.method(), providers, hsailBackend, target, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), + CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, graph.method(), providers, backend, target, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), suitesProvider.getDefaultSuites(), new CompilationResult()); return new HSAILCompilationResult(compResult); } catch (GraalInternalError e) { - String partialCode = hsailBackend.getPartialCodeString(); + String partialCode = backend.getPartialCodeString(); if (partialCode != null && !partialCode.equals("")) { logger.fine("-------------------\nPartial Code Generation:\n--------------------"); logger.fine(partialCode); diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Thu Oct 17 16:01:04 2013 +0200 @@ -78,7 +78,11 @@ } public String getPartialCodeString() { - return (codeBuffer == null ? "" : new String(codeBuffer.copyData(0, codeBuffer.position()))); + if (codeBuffer == null) { + return ""; + } + byte[] data = codeBuffer.copyData(0, codeBuffer.position()); + return (data == null ? "" : new String(data)); } class HotSpotFrameContext implements FrameContext { diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java Thu Oct 17 16:01:04 2013 +0200 @@ -0,0 +1,78 @@ +/* + * 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.hsail; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.runtime.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hsail.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.util.*; + +@ServiceProvider(HotSpotBackendFactory.class) +public class HSAILHotSpotBackendFactory implements HotSpotBackendFactory { + + @Override + public HSAILHotSpotBackend createBackend(HotSpotGraalRuntime runtime, HotSpotBackend hostBackend) { + HotSpotProviders host = hostBackend.getProviders(); + + HotSpotMetaAccessProvider metaAccess = host.getMetaAccess(); + HSAILHotSpotCodeCacheProvider codeCache = new HSAILHotSpotCodeCacheProvider(runtime, createTarget()); + ConstantReflectionProvider constantReflection = host.getConstantReflection(); + HotSpotForeignCallsProvider foreignCalls = new HSAILHotSpotForeignCallsProvider(host.getForeignCalls()); + LoweringProvider lowerer = new HSAILHotSpotLoweringProvider(host.getLowerer()); + // Replacements cannot have speculative optimizations since they have + // to be valid for the entire run of the VM. + Assumptions assumptions = new Assumptions(false); + Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null); + Replacements replacements = new HSAILHotSpotReplacementsImpl(p, assumptions); + HotSpotDisassemblerProvider disassembler = host.getDisassembler(); + HotSpotSuitesProvider suites = host.getSuites(); + HotSpotRegisters registers = new HotSpotRegisters(Register.None, Register.None, Register.None); + HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); + + return new HSAILHotSpotBackend(runtime, providers); + } + + protected TargetDescription createTarget() { + final int stackFrameAlignment = 8; + final int implicitNullCheckLimit = 0; + final boolean inlineObjects = true; + return new TargetDescription(new HSAIL(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); + } + + public String getArchitecture() { + return "HSAIL"; + } + + public String getGraalRuntimeName() { + return "basic"; + } + + @Override + public String toString() { + return getGraalRuntimeName() + ":" + getArchitecture(); + } +} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotCodeCacheProvider.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotCodeCacheProvider.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotCodeCacheProvider.java Thu Oct 17 16:01:04 2013 +0200 @@ -29,8 +29,8 @@ public class HSAILHotSpotCodeCacheProvider extends HotSpotCodeCacheProvider { - public HSAILHotSpotCodeCacheProvider(HotSpotGraalRuntime runtime) { - super(runtime); + public HSAILHotSpotCodeCacheProvider(HotSpotGraalRuntime runtime, TargetDescription target) { + super(runtime, target); } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotForeignCallsProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotForeignCallsProvider.java Thu Oct 17 16:01:04 2013 +0200 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.hsail; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; + +public class HSAILHotSpotForeignCallsProvider implements HotSpotForeignCallsProvider { + + private final ForeignCallsProvider host; + + public HSAILHotSpotForeignCallsProvider(ForeignCallsProvider host) { + this.host = host; + } + + public boolean isReexecutable(ForeignCallDescriptor descriptor) { + return host.isReexecutable(descriptor); + } + + public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) { + return host.getKilledLocations(descriptor); + } + + public boolean canDeoptimize(ForeignCallDescriptor descriptor) { + return host.canDeoptimize(descriptor); + } + + public ForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) { + throw GraalInternalError.unimplemented(); + } + + public Value[] getNativeABICallerSaveRegisters() { + throw GraalInternalError.unimplemented(); + } + + public void initialize(HotSpotProviders providers, HotSpotVMConfig config) { + } +} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotGraalRuntime.java Thu Oct 17 15:59:12 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +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.hsail; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hsail.*; -import com.oracle.graal.nodes.spi.*; - -/** - * HSAIL specific implementation of {@link HotSpotGraalRuntime}. - */ -public class HSAILHotSpotGraalRuntime extends HotSpotGraalRuntime { - - @Override - protected HotSpotProviders createProviders() { - HotSpotProviders host = HotSpotGraalRuntime.runtime().getProviders(); - - HotSpotMetaAccessProvider metaAccess = host.getMetaAccess(); - HSAILHotSpotCodeCacheProvider codeCache = new HSAILHotSpotCodeCacheProvider(this); - ConstantReflectionProvider constantReflection = host.getConstantReflection(); - HotSpotForeignCallsProvider foreignCalls = host.getForeignCalls(); - LoweringProvider lowerer = new HSAILHotSpotLoweringProvider(host.getLowerer()); - Replacements replacements = host.getReplacements(); - HotSpotDisassemblerProvider disassembler = host.getDisassembler(); - HotSpotSuitesProvider suites = host.getSuites(); - HotSpotRegisters registers = new HotSpotRegisters(Register.None, Register.None, Register.None); - return new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); - } - - @Override - protected TargetDescription createTarget() { - final int stackFrameAlignment = 8; - final int implicitNullCheckLimit = 0; - final boolean inlineObjects = true; - return new TargetDescription(new HSAIL(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); - } - - @Override - protected HotSpotBackend createBackend() { - return new HSAILHotSpotBackend(this, getProviders()); - } - - @Override - protected Value[] getNativeABICallerSaveRegisters() { - throw new InternalError("NYI"); - } -} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLoweringProvider.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLoweringProvider.java Thu Oct 17 16:01:04 2013 +0200 @@ -22,18 +22,21 @@ */ package com.oracle.graal.hotspot.hsail; +import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -public class HSAILHotSpotLoweringProvider implements LoweringProvider { +public class HSAILHotSpotLoweringProvider implements HotSpotLoweringProvider { - private LoweringProvider hostLowerer; + private LoweringProvider host; - public HSAILHotSpotLoweringProvider(LoweringProvider hostLowerer) { - this.hostLowerer = hostLowerer; + public HSAILHotSpotLoweringProvider(LoweringProvider host) { + this.host = host; } public void lower(Node n, LoweringTool tool) { @@ -41,11 +44,18 @@ // TODO return; } else { - hostLowerer.lower(n, tool); + host.lower(n, tool); } } public ValueNode reconstructArrayIndex(LocationNode location) { - return hostLowerer.reconstructArrayIndex(location); + throw GraalInternalError.unimplemented(); + } + + public void initialize(HotSpotProviders providers, HotSpotVMConfig config) { + } + + public int getScalingFactor(Kind elementKind) { + throw GraalInternalError.unimplemented(); } } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java Thu Oct 17 16:01:04 2013 +0200 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.hsail; + +import java.lang.reflect.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.phases.util.*; +import com.oracle.graal.replacements.*; + +/** + * Filters the substitutions and snippets supported by HSAIL. + */ +public class HSAILHotSpotReplacementsImpl extends ReplacementsImpl { + + public HSAILHotSpotReplacementsImpl(Providers providers, Assumptions assumptions) { + super(providers, assumptions); + } + + @Override + protected ResolvedJavaMethod registerMethodSubstitution(Member originalMethod, Method substituteMethod) { + // TODO decide here what methods substitutions are supported + return null; + } + + @Override + public Class getMacroSubstitution(ResolvedJavaMethod method) { + // TODO decide here what macro substitutions are supported + return null; + } + + @Override + public StructuredGraph getSnippet(ResolvedJavaMethod method) { + // TODO must work in cooperation with HSAILHotSpotLoweringProvider + return null; + } +} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java Thu Oct 17 16:01:04 2013 +0200 @@ -22,15 +22,28 @@ */ package com.oracle.graal.hotspot.ptx; +import static com.oracle.graal.lir.LIRValueUtil.*; + +import java.util.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; +import com.oracle.graal.asm.ptx.*; import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.ptx.*; +import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.OperandFlag; +import com.oracle.graal.lir.LIRInstruction.OperandMode; +import com.oracle.graal.lir.LIRInstruction.ValueProcedure; +import com.oracle.graal.lir.StandardOp.LabelOp; import com.oracle.graal.lir.asm.*; +import com.oracle.graal.lir.ptx.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.cfg.*; /** * HotSpot PTX specific backend. @@ -43,31 +56,219 @@ @Override public boolean shouldAllocateRegisters() { - throw new InternalError("NYI"); + return false; } @Override public FrameMap newFrameMap() { - throw new InternalError("NYI"); + return new PTXFrameMap(getCodeCache()); + } + + class PTXFrameContext implements FrameContext { + + @Override + public void enter(TargetMethodAssembler tasm) { + // codeBuffer.emitString(".address_size 32"); // PTX ISA version 2.3 + } + + @Override + public void leave(TargetMethodAssembler tasm) { + } } @Override public TargetMethodAssembler newAssembler(LIRGenerator lirGen, CompilationResult compilationResult) { - throw new InternalError("NYI"); - } - - @Override - public void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod installedCodeOwner) { - throw new InternalError("NYI"); + // Omit the frame of 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 + FrameMap frameMap = lirGen.frameMap; + AbstractAssembler masm = createAssembler(frameMap); + PTXFrameContext frameContext = new PTXFrameContext(); + TargetMethodAssembler tasm = new PTXTargetMethodAssembler(getCodeCache(), getForeignCalls(), frameMap, masm, frameContext, compilationResult); + tasm.setFrameSize(0); + return tasm; } @Override protected AbstractAssembler createAssembler(FrameMap frameMap) { - throw new InternalError("NYI"); + return new PTXAssembler(getTarget(), frameMap.registerConfig); } @Override public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) { - throw new InternalError("NYI"); + return new PTXLIRGenerator(graph, getProviders(), frameMap, cc, lir); + } + + private static void emitKernelEntry(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) { + // Emit PTX kernel entry text based on PTXParameterOp + // instructions in the start block. Remove the instructions + // once kernel entry text and directives are emitted to + // facilitate seemless PTX code generation subsequently. + assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method"; + final String name = codeCacheOwner.getName(); + Buffer codeBuffer = tasm.asm.codeBuffer; + + // Emit initial boiler-plate directives. + codeBuffer.emitString(".version 3.0"); + codeBuffer.emitString(".target sm_30"); + codeBuffer.emitString0(".entry " + name + " ("); + codeBuffer.emitString(""); + + // Get the start block + Block startBlock = lirGen.lir.cfg.getStartBlock(); + // Keep a list of ParameterOp instructions to delete from the + // list of instructions in the block. + ArrayList deleteOps = new ArrayList<>(); + + // Emit .param arguments to kernel entry based on ParameterOp + // instruction. + for (LIRInstruction op : lirGen.lir.lir(startBlock)) { + if (op instanceof PTXParameterOp) { + op.emitCode(tasm); + deleteOps.add(op); + } + } + + // Delete ParameterOp instructions. + for (LIRInstruction op : deleteOps) { + lirGen.lir.lir(startBlock).remove(op); + } + + // Start emiting body of the PTX kernel. + codeBuffer.emitString0(") {"); + codeBuffer.emitString(""); + } + + // Emit .reg space declarations + private static void emitRegisterDecl(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) { + + assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method"; + + Buffer codeBuffer = tasm.asm.codeBuffer; + + final SortedSet signed32 = new TreeSet<>(); + final SortedSet signed64 = new TreeSet<>(); + final SortedSet unsigned64 = new TreeSet<>(); + final SortedSet float32 = new TreeSet<>(); + final SortedSet float64 = new TreeSet<>(); + + ValueProcedure trackRegisterKind = new ValueProcedure() { + + @Override + public Value doValue(Value value, OperandMode mode, EnumSet flags) { + if (isVariable(value)) { + Variable regVal = (Variable) value; + Kind regKind = regVal.getKind(); + switch (regKind) { + case Int: + // If the register was used as a wider signed type + // do not add it here + if (!signed64.contains(regVal.index)) { + signed32.add(regVal.index); + } + break; + case Long: + // If the register was used as a narrower signed type + // remove it from there and add it to wider type. + if (signed32.contains(regVal.index)) { + signed32.remove(regVal.index); + } + signed64.add(regVal.index); + break; + case Float: + // If the register was used as a wider signed type + // do not add it here + if (!float64.contains(regVal.index)) { + float32.add(regVal.index); + } + break; + case Double: + // If the register was used as a narrower signed type + // remove it from there and add it to wider type. + if (float32.contains(regVal.index)) { + float32.remove(regVal.index); + } + float64.add(regVal.index); + break; + case Object: + unsigned64.add(regVal.index); + break; + default: + throw GraalInternalError.shouldNotReachHere("unhandled register type " + value.toString()); + } + } + return value; + } + }; + + for (Block b : lirGen.lir.codeEmittingOrder()) { + for (LIRInstruction op : lirGen.lir.lir(b)) { + if (op instanceof LabelOp) { + // Don't consider this as a definition + } else { + op.forEachTemp(trackRegisterKind); + op.forEachOutput(trackRegisterKind); + } + } + } + + for (Integer i : signed32) { + codeBuffer.emitString(".reg .s32 %r" + i.intValue() + ";"); + } + for (Integer i : signed64) { + codeBuffer.emitString(".reg .s64 %r" + i.intValue() + ";"); + } + for (Integer i : unsigned64) { + codeBuffer.emitString(".reg .u64 %r" + i.intValue() + ";"); + } + for (Integer i : float32) { + codeBuffer.emitString(".reg .f32 %r" + i.intValue() + ";"); + } + for (Integer i : float64) { + codeBuffer.emitString(".reg .f64 %r" + i.intValue() + ";"); + } + // emit predicate register declaration + int maxPredRegNum = ((PTXLIRGenerator) lirGen).getNextPredRegNumber(); + if (maxPredRegNum > 0) { + codeBuffer.emitString(".reg .pred %p<" + maxPredRegNum + ">;"); + } + codeBuffer.emitString(".reg .pred %r;"); // used for setp bool + } + + @Override + public void emitCode(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) { + assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method"; + Buffer codeBuffer = tasm.asm.codeBuffer; + // Emit the prologue + emitKernelEntry(tasm, lirGen, codeCacheOwner); + + // Emit register declarations + try { + emitRegisterDecl(tasm, lirGen, codeCacheOwner); + } catch (GraalInternalError e) { + e.printStackTrace(); + // TODO : Better error handling needs to be done once + // all types of parameters are handled. + codeBuffer.setPosition(0); + codeBuffer.close(false); + return; + } + // Emit code for the LIR + try { + lirGen.lir.emitCode(tasm); + } catch (GraalInternalError e) { + e.printStackTrace(); + // TODO : Better error handling needs to be done once + // all types of parameters are handled. + codeBuffer.setPosition(0); + codeBuffer.close(false); + return; + } + + // Emit the epilogue + codeBuffer.emitString0("}"); + codeBuffer.emitString(""); } } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java Thu Oct 17 16:01:04 2013 +0200 @@ -0,0 +1,75 @@ +/* + * 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.ptx; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.runtime.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.ptx.*; + +@ServiceProvider(HotSpotBackendFactory.class) +public class PTXHotSpotBackendFactory implements HotSpotBackendFactory { + + public HotSpotBackend createBackend(HotSpotGraalRuntime runtime, HotSpotBackend hostBackend) { + HotSpotProviders host = hostBackend.getProviders(); + + HotSpotMetaAccessProvider metaAccess = host.getMetaAccess(); + PTXHotSpotCodeCacheProvider codeCache = new PTXHotSpotCodeCacheProvider(runtime, createTarget()); + ConstantReflectionProvider constantReflection = host.getConstantReflection(); + HotSpotForeignCallsProvider foreignCalls = new PTXHotSpotForeignCallsProvider(); + HotSpotLoweringProvider lowerer = new PTXHotSpotLoweringProvider(host.getLowerer()); + Replacements replacements = host.getReplacements(); + HotSpotDisassemblerProvider disassembler = host.getDisassembler(); + HotSpotSuitesProvider suites = host.getSuites(); + HotSpotRegistersProvider registers = new HotSpotRegisters(PTX.tid, Register.None, Register.None); + HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); + return new PTXHotSpotBackend(runtime, providers); + } + + protected Architecture createArchitecture() { + return new PTX(); + } + + protected TargetDescription createTarget() { + final int stackFrameAlignment = 1; + final int implicitNullCheckLimit = 0; + final boolean inlineObjects = true; + return new TargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); + } + + public String getArchitecture() { + return "PTX"; + } + + public String getGraalRuntimeName() { + return "basic"; + } + + @Override + public String toString() { + return getGraalRuntimeName() + ":" + getArchitecture(); + } +} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotCodeCacheProvider.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotCodeCacheProvider.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotCodeCacheProvider.java Thu Oct 17 16:01:04 2013 +0200 @@ -28,8 +28,8 @@ public class PTXHotSpotCodeCacheProvider extends HotSpotCodeCacheProvider { - public PTXHotSpotCodeCacheProvider(HotSpotGraalRuntime runtime) { - super(runtime); + public PTXHotSpotCodeCacheProvider(HotSpotGraalRuntime runtime, TargetDescription target) { + super(runtime, target); } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotForeignCallsProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotForeignCallsProvider.java Thu Oct 17 16:01:04 2013 +0200 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.ptx; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; + +public class PTXHotSpotForeignCallsProvider implements HotSpotForeignCallsProvider { + + public boolean isReexecutable(ForeignCallDescriptor descriptor) { + throw GraalInternalError.unimplemented(); + } + + public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) { + throw GraalInternalError.unimplemented(); + } + + public boolean canDeoptimize(ForeignCallDescriptor descriptor) { + throw GraalInternalError.unimplemented(); + } + + public ForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) { + throw GraalInternalError.unimplemented(); + } + + public Value[] getNativeABICallerSaveRegisters() { + throw GraalInternalError.unimplemented(); + } + + public void initialize(HotSpotProviders providers, HotSpotVMConfig config) { + } +} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotGraalRuntime.java Thu Oct 17 15:59:12 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +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.ptx; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.phases.util.*; -import com.oracle.graal.ptx.*; - -/** - * PTX specific implementation of {@link HotSpotGraalRuntime}. - */ -public class PTXHotSpotGraalRuntime extends HotSpotGraalRuntime { - - protected PTXHotSpotGraalRuntime() { - } - - /** - * Called from C++ code to retrieve the singleton instance, creating it first if necessary. - */ - public static HotSpotGraalRuntime makeInstance() { - HotSpotGraalRuntime runtime = runtime(); - if (runtime == null) { - HotSpotGraalRuntimeFactory factory = findFactory("PTX"); - if (factory != null) { - runtime = factory.createRuntime(); - } else { - runtime = new PTXHotSpotGraalRuntime(); - } - runtime.completeInitialization(); - } - return runtime; - } - - @Override - protected HotSpotProviders createProviders() { - HotSpotMetaAccessProvider metaAccess = new HotSpotMetaAccessProvider(this); - PTXHotSpotCodeCacheProvider codeCache = new PTXHotSpotCodeCacheProvider(this); - HotSpotConstantReflectionProvider constantReflection = new HotSpotConstantReflectionProvider(this); - HotSpotForeignCallsProvider foreignCalls = new HotSpotForeignCallsProvider(this); - HotSpotLoweringProvider lowerer = new PTXHotSpotLoweringProvider(this, metaAccess, foreignCalls); - // Replacements cannot have speculative optimizations since they have - // to be valid for the entire run of the VM. - Assumptions assumptions = new Assumptions(false); - Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null); - HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, getConfig(), assumptions); - HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(this); - HotSpotSuitesProvider suites = new HotSpotSuitesProvider(this); - HotSpotRegistersProvider registers = new HotSpotRegisters(PTX.tid, Register.None, Register.None); - return new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); - } - - protected Architecture createArchitecture() { - return new PTX(); - } - - @Override - protected TargetDescription createTarget() { - final int stackFrameAlignment = 16; - final int implicitNullCheckLimit = 4096; - final boolean inlineObjects = true; - return new TargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); - } - - @Override - protected HotSpotBackend createBackend() { - return new PTXHotSpotBackend(this, getProviders()); - } - - @Override - protected Value[] getNativeABICallerSaveRegisters() { - throw new InternalError("NYI"); - } -} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLoweringProvider.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLoweringProvider.java Thu Oct 17 16:01:04 2013 +0200 @@ -22,18 +22,21 @@ */ package com.oracle.graal.hotspot.ptx; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -public class PTXHotSpotLoweringProvider extends HotSpotLoweringProvider { +public class PTXHotSpotLoweringProvider implements HotSpotLoweringProvider { - public PTXHotSpotLoweringProvider(HotSpotGraalRuntime runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) { - super(runtime, metaAccess, foreignCalls); + private final LoweringProvider host; + + public PTXHotSpotLoweringProvider(LoweringProvider host) { + this.host = host; } @Override @@ -46,7 +49,18 @@ // So, there is no need to lower the operation. return; } else { - super.lower(n, tool); + host.lower(n, tool); } } + + public ValueNode reconstructArrayIndex(LocationNode location) { + throw GraalInternalError.unimplemented(); + } + + public void initialize(HotSpotProviders providers, HotSpotVMConfig config) { + } + + public int getScalingFactor(Kind elementKind) { + throw GraalInternalError.unimplemented(); + } } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Thu Oct 17 16:01:04 2013 +0200 @@ -0,0 +1,88 @@ +/* + * 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.sparc; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.runtime.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.phases.util.*; +import com.oracle.graal.sparc.*; + +@ServiceProvider(HotSpotBackendFactory.class) +public class SPARCHotSpotBackendFactory implements HotSpotBackendFactory { + + protected static Architecture createArchitecture() { + return new SPARC(); + } + + protected TargetDescription createTarget() { + final int stackFrameAlignment = 16; + final int implicitNullCheckLimit = 4096; + final boolean inlineObjects = true; + return new TargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); + } + + public HotSpotBackend createBackend(HotSpotGraalRuntime runtime, HotSpotBackend host) { + assert host == null; + TargetDescription target = createTarget(); + + HotSpotMetaAccessProvider metaAccess = new HotSpotMetaAccessProvider(runtime); + HotSpotCodeCacheProvider codeCache = new SPARCHotSpotCodeCacheProvider(runtime, target); + HotSpotConstantReflectionProvider constantReflection = new HotSpotConstantReflectionProvider(runtime); + Value[] nativeABICallerSaveRegisters = createNativeABICallerSaveRegisters(runtime.getConfig(), codeCache.getRegisterConfig()); + HotSpotForeignCallsProvider foreignCalls = new SPARCHotSpotForeignCallsProvider(runtime, metaAccess, codeCache, nativeABICallerSaveRegisters); + HotSpotLoweringProvider lowerer = new SPARCHotSpotLoweringProvider(runtime, metaAccess, foreignCalls); + // Replacements cannot have speculative optimizations since they have + // to be valid for the entire run of the VM. + Assumptions assumptions = new Assumptions(false); + Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null); + HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, runtime.getConfig(), assumptions); + HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(runtime); + HotSpotSuitesProvider suites = new HotSpotSuitesProvider(runtime); + HotSpotRegisters registers = new HotSpotRegisters(Register.None, Register.None, Register.None); // FIXME + HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); + + return new SPARCHotSpotBackend(runtime, providers); + } + + @SuppressWarnings("unused") + private static Value[] createNativeABICallerSaveRegisters(HotSpotVMConfig config, RegisterConfig regConfig) { + throw GraalInternalError.unimplemented(); + } + + public String getArchitecture() { + return "SPARC"; + } + + public String getGraalRuntimeName() { + return "basic"; + } + + @Override + public String toString() { + return getGraalRuntimeName() + ":" + getArchitecture(); + } +} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallEpilogueOp.java Thu Oct 17 16:01:04 2013 +0200 @@ -23,30 +23,40 @@ package com.oracle.graal.hotspot.sparc; import static com.oracle.graal.sparc.SPARC.*; -import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import com.oracle.graal.api.code.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.hotspot.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stw; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stx; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; -import com.oracle.graal.lir.asm.*; @Opcode("CRUNTIME_CALL_EPILOGUE") final class SPARCHotSpotCRuntimeCallEpilogueOp extends SPARCLIRInstruction { + private final int threadLastJavaSpOffset; + private final int threadLastJavaPcOffset; + private final int threadJavaFrameAnchorFlagsOffset; + private final Register thread; + + public SPARCHotSpotCRuntimeCallEpilogueOp(int threadLastJavaSpOffset, int threadLastJavaPcOffset, int threadJavaFrameAnchorFlagsOffset, Register thread) { + this.threadLastJavaSpOffset = threadLastJavaSpOffset; + this.threadLastJavaPcOffset = threadLastJavaPcOffset; + this.threadJavaFrameAnchorFlagsOffset = threadJavaFrameAnchorFlagsOffset; + this.thread = thread; + } + @Override public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { - Register thread = runtime().getProviders().getRegisters().getThreadRegister(); - HotSpotVMConfig config = runtime().getConfig(); // Restore the thread register when coming back from the runtime. new Mov(l7, thread).emit(masm); // Reset last Java frame, last Java PC and flags. - new Stx(g0, new SPARCAddress(thread, config.threadLastJavaSpOffset)).emit(masm); - new Stx(g0, new SPARCAddress(thread, config.threadLastJavaPcOffset)).emit(masm); - new Stw(g0, new SPARCAddress(thread, config.threadJavaFrameAnchorFlagsOffset)).emit(masm); + new Stx(g0, new SPARCAddress(thread, threadLastJavaSpOffset)).emit(masm); + new Stx(g0, new SPARCAddress(thread, threadLastJavaPcOffset)).emit(masm); + new Stw(g0, new SPARCAddress(thread, threadJavaFrameAnchorFlagsOffset)).emit(masm); } } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCRuntimeCallPrologueOp.java Thu Oct 17 16:01:04 2013 +0200 @@ -23,30 +23,35 @@ package com.oracle.graal.hotspot.sparc; import static com.oracle.graal.sparc.SPARC.*; -import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import com.oracle.graal.api.code.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.Add; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stx; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.*; -import com.oracle.graal.lir.asm.*; @Opcode("CRUNTIME_CALL_PROLOGUE") final class SPARCHotSpotCRuntimeCallPrologueOp extends SPARCLIRInstruction { + private final int threadLastJavaSpOffset; + private final Register thread; + private final Register stackPointer; + + public SPARCHotSpotCRuntimeCallPrologueOp(int threadLastJavaSpOffset, Register thread, Register stackPointer) { + this.threadLastJavaSpOffset = threadLastJavaSpOffset; + this.thread = thread; + this.stackPointer = stackPointer; + } + @Override public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) { - HotSpotRegistersProvider registers = runtime().getProviders().getRegisters(); - HotSpotVMConfig config = runtime().getConfig(); - Register thread = registers.getThreadRegister(); - Register stackPointer = registers.getStackPointerRegister(); // Save last Java frame. new Add(stackPointer, new SPARCAddress(stackPointer, 0).getDisplacement(), g4).emit(masm); - new Stx(g4, new SPARCAddress(thread, config.threadLastJavaSpOffset)).emit(masm); + new Stx(g4, new SPARCAddress(thread, threadLastJavaSpOffset)).emit(masm); // Save the thread register when calling out to the runtime. new Mov(thread, l7).emit(masm); diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCodeCacheProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCodeCacheProvider.java Thu Oct 17 16:01:04 2013 +0200 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.sparc; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; + +public class SPARCHotSpotCodeCacheProvider extends HotSpotCodeCacheProvider { + + public SPARCHotSpotCodeCacheProvider(HotSpotGraalRuntime runtime, TargetDescription target) { + super(runtime, target); + } + + @Override + protected RegisterConfig createRegisterConfig() { + throw GraalInternalError.unimplemented(); + } + +} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotForeignCallsProvider.java Thu Oct 17 16:01:04 2013 +0200 @@ -35,15 +35,18 @@ import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; -public class SPARCHotSpotForeignCallsProvider extends HotSpotForeignCallsProvider { +public class SPARCHotSpotForeignCallsProvider extends HotSpotHostForeignCallsProvider { + + private final Value[] nativeABICallerSaveRegisters; - public SPARCHotSpotForeignCallsProvider(HotSpotGraalRuntime runtime) { - super(runtime); + public SPARCHotSpotForeignCallsProvider(HotSpotGraalRuntime runtime, MetaAccessProvider metaAccess, CodeCacheProvider codeCache, Value[] nativeABICallerSaveRegisters) { + super(runtime, metaAccess, codeCache); + this.nativeABICallerSaveRegisters = nativeABICallerSaveRegisters; } @Override - public void initialize(HotSpotProviders providers) { - Kind word = runtime.getTarget().wordKind; + public void initialize(HotSpotProviders providers, HotSpotVMConfig config) { + Kind word = providers.getCodeCache().getTarget().wordKind; // The calling convention for the exception handler stub is (only?) defined in // TemplateInterpreterGenerator::generate_throw_exception() @@ -56,5 +59,12 @@ CallingConvention incomingExceptionCc = new CallingConvention(0, ILLEGAL, incomingException, incomingExceptionPc); register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, outgoingExceptionCc, incomingExceptionCc, NOT_REEXECUTABLE, ANY_LOCATION)); register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, outgoingExceptionCc, incomingExceptionCc, NOT_REEXECUTABLE, ANY_LOCATION)); + + super.initialize(providers, config); + } + + @Override + public Value[] getNativeABICallerSaveRegisters() { + return nativeABICallerSaveRegisters; } } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime.java Thu Oct 17 15:59:12 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +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.sparc; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.sparc.*; - -/** - * SPARC specific implementation of {@link HotSpotGraalRuntime}. - */ -final class SPARCHotSpotGraalRuntime extends HotSpotGraalRuntime { - - private SPARCHotSpotGraalRuntime() { - } - - /** - * Called from C++ code to retrieve the singleton instance, creating it first if necessary. - */ - public static HotSpotGraalRuntime makeInstance() { - HotSpotGraalRuntime runtime = runtime(); - if (runtime == null) { - runtime = new SPARCHotSpotGraalRuntime(); - runtime.completeInitialization(); - } - return runtime; - } - - @Override - protected HotSpotProviders createProviders() { - // TODO Auto-generated method stub - return null; - } - - protected static Architecture createArchitecture() { - return new SPARC(); - } - - @Override - protected TargetDescription createTarget() { - final int stackFrameAlignment = 16; - final int implicitNullCheckLimit = 4096; - final boolean inlineObjects = true; - return new TargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); - } - - @Override - protected HotSpotBackend createBackend() { - return new SPARCHotSpotBackend(this, getProviders()); - } - - @Override - protected Value[] getNativeABICallerSaveRegisters() { - throw GraalInternalError.unimplemented(); - } -} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotJumpToExceptionHandlerInCallerOp.java Thu Oct 17 16:01:04 2013 +0200 @@ -22,15 +22,19 @@ */ package com.oracle.graal.hotspot.sparc; -import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static com.oracle.graal.sparc.SPARC.*; -import static com.oracle.graal.api.code.ValueUtil.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.CC; +import com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag; +import com.oracle.graal.asm.sparc.SPARCAssembler.Jmpl; +import com.oracle.graal.asm.sparc.SPARCAssembler.Lduw; +import com.oracle.graal.asm.sparc.SPARCAssembler.Movcc; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cmp; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; @@ -44,11 +48,15 @@ @Use(REG) AllocatableValue handlerInCallerPc; @Use(REG) AllocatableValue exception; @Use(REG) AllocatableValue exceptionPc; + private final Register thread; + private final int isMethodHandleReturnOffset; - SPARCHotSpotJumpToExceptionHandlerInCallerOp(AllocatableValue handlerInCallerPc, AllocatableValue exception, AllocatableValue exceptionPc) { + SPARCHotSpotJumpToExceptionHandlerInCallerOp(AllocatableValue handlerInCallerPc, AllocatableValue exception, AllocatableValue exceptionPc, int isMethodHandleReturnOffset, Register thread) { this.handlerInCallerPc = handlerInCallerPc; this.exception = exception; this.exceptionPc = exceptionPc; + this.isMethodHandleReturnOffset = isMethodHandleReturnOffset; + this.thread = thread; } @Override @@ -56,8 +64,6 @@ leaveFrame(tasm); // Restore SP from L7 if the exception PC is a method handle call site. - Register thread = runtime().getProviders().getRegisters().getThreadRegister(); - int isMethodHandleReturnOffset = runtime().getConfig().threadIsMethodHandleReturnOffset; SPARCAddress dst = new SPARCAddress(thread, isMethodHandleReturnOffset); new Lduw(dst, o7).emit(masm); new Cmp(o7, o7).emit(masm); diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java Thu Oct 17 16:01:04 2013 +0200 @@ -100,9 +100,12 @@ if (linkage.canDeoptimize()) { assert info != null; - append(new SPARCHotSpotCRuntimeCallPrologueOp()); + HotSpotRegistersProvider registers = getProviders().getRegisters(); + Register thread = registers.getThreadRegister(); + Register stackPointer = registers.getStackPointerRegister(); + append(new SPARCHotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset, thread, stackPointer)); result = super.emitForeignCall(linkage, info, args); - append(new SPARCHotSpotCRuntimeCallEpilogueOp()); + append(new SPARCHotSpotCRuntimeCallEpilogueOp(config.threadLastJavaSpOffset, config.threadLastJavaPcOffset, config.threadJavaFrameAnchorFlagsOffset, thread)); } else { result = super.emitForeignCall(linkage, null, args); } @@ -223,7 +226,8 @@ RegisterValue exceptionPcFixed = (RegisterValue) linkageCc.getArgument(1); emitMove(exceptionFixed, operand(exception)); emitMove(exceptionPcFixed, operand(exceptionPc)); - SPARCHotSpotJumpToExceptionHandlerInCallerOp op = new SPARCHotSpotJumpToExceptionHandlerInCallerOp(handler, exceptionFixed, exceptionPcFixed); + Register thread = getProviders().getRegisters().getThreadRegister(); + SPARCHotSpotJumpToExceptionHandlerInCallerOp op = new SPARCHotSpotJumpToExceptionHandlerInCallerOp(handler, exceptionFixed, exceptionPcFixed, config.threadIsMethodHandleReturnOffset, thread); append(op); } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLoweringProvider.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLoweringProvider.java Thu Oct 17 16:01:04 2013 +0200 @@ -30,7 +30,7 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; -public class SPARCHotSpotLoweringProvider extends HotSpotLoweringProvider { +public class SPARCHotSpotLoweringProvider extends HotSpotHostLoweringProvider { public SPARCHotSpotLoweringProvider(HotSpotGraalRuntime runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) { super(runtime, metaAccess, foreignCalls); diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Thu Oct 17 16:01:04 2013 +0200 @@ -205,7 +205,7 @@ CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); // create suites everytime, as we modify options for the compiler final Suites suitesLocal = Graal.getRequiredCapability(SuitesProvider.class).createSuites(); - final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, getProviders(), backend, getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, + final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog(), suitesLocal, new CompilationResult()); addMethod(method, compResult); diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Thu Oct 17 16:01:04 2013 +0200 @@ -42,7 +42,6 @@ import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; -import com.oracle.graal.phases.util.*; public final class CompilationTask implements Runnable { @@ -58,9 +57,8 @@ Queued, Running } - private final HotSpotGraalRuntime runtime; + private final HotSpotBackend backend; private final PhasePlan plan; - private final SuitesProvider suitesProvider; private final OptimisticOptimizations optimisticOpts; private final HotSpotResolvedJavaMethod method; private final int entryBCI; @@ -69,15 +67,14 @@ private StructuredGraph graph; - public static CompilationTask create(HotSpotGraalRuntime runtime, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotResolvedJavaMethod method, int entryBCI, int id) { - return new CompilationTask(runtime, plan, optimisticOpts, method, entryBCI, id); + public static CompilationTask create(HotSpotBackend backend, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotResolvedJavaMethod method, int entryBCI, int id) { + return new CompilationTask(backend, plan, optimisticOpts, method, entryBCI, id); } - private CompilationTask(HotSpotGraalRuntime runtime, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotResolvedJavaMethod method, int entryBCI, int id) { + private CompilationTask(HotSpotBackend backend, PhasePlan plan, OptimisticOptimizations optimisticOpts, HotSpotResolvedJavaMethod method, int entryBCI, int id) { assert id >= 0; - this.runtime = runtime; + this.backend = backend; this.plan = plan; - this.suitesProvider = runtime.getCapability(SuitesProvider.class); this.method = method; this.optimisticOpts = optimisticOpts; this.entryBCI = entryBCI; @@ -143,8 +140,8 @@ @Override public CompilationResult call() throws Exception { - runtime.evictDeoptedGraphs(); - Providers providers = runtime.getProviders(); + backend.getRuntime().evictDeoptedGraphs(); + HotSpotProviders providers = backend.getProviders(); Replacements replacements = providers.getReplacements(); graph = replacements.getMethodSubstitution(method); if (graph == null || entryBCI != INVOCATION_ENTRY_BCI) { @@ -155,8 +152,9 @@ } InliningUtil.InlinedBytecodes.add(method.getCodeSize()); CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); - return GraalCompiler.compileGraph(graph, cc, method, providers, runtime.getBackend(), runtime.getTarget(), runtime.getCache(), plan, optimisticOpts, - method.getSpeculationLog(), suitesProvider.getDefaultSuites(), new CompilationResult()); + Suites suites = providers.getSuites().getDefaultSuites(); + return GraalCompiler.compileGraph(graph, cc, method, providers, backend, backend.getTarget(), backend.getRuntime().getCache(), plan, optimisticOpts, + method.getSpeculationLog(), suites, new CompilationResult()); } }); } finally { @@ -212,7 +210,7 @@ } private void installMethod(final CompilationResult compResult) { - final HotSpotCodeCacheProvider codeCache = runtime.getProviders().getCodeCache(); + final HotSpotCodeCacheProvider codeCache = backend.getProviders().getCodeCache(); Debug.scope("CodeInstall", new Object[]{new DebugDumpScope(String.valueOf(id), true), codeCache, method}, new Runnable() { @Override @@ -222,7 +220,7 @@ Debug.dump(new Object[]{compResult, installedCode}, "After code installation"); } if (Debug.isLogEnabled()) { - Debug.log("%s", runtime.getProviders().getDisassembler().disassemble(installedCode)); + Debug.log("%s", backend.getProviders().getDisassembler().disassemble(installedCode)); } } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Thu Oct 17 16:01:04 2013 +0200 @@ -182,7 +182,7 @@ } // Are we compiling this class? - HotSpotMetaAccessProvider metaAccess = runtime.getProviders().getMetaAccess(); + HotSpotMetaAccessProvider metaAccess = runtime.getHostProviders().getMetaAccess(); if (classFileCounter >= startAt) { TTY.println("CompileTheWorld (%d) : %s", classFileCounter, className); diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackendFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackendFactory.java Thu Oct 17 16:01:04 2013 +0200 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot; + +import com.oracle.graal.hotspot.HotSpotGraalRuntime.Options; + +public interface HotSpotBackendFactory { + + HotSpotBackend createBackend(HotSpotGraalRuntime runtime, HotSpotBackend host); + + /** + * Gets the CPU architecture of this backend. + */ + String getArchitecture(); + + /** + * Gets the name of the {@link Options#GraalRuntime GraalRuntime} in which the backend created + * by this factory should be used. + */ + String getGraalRuntimeName(); + +} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java Thu Oct 17 16:01:04 2013 +0200 @@ -31,6 +31,7 @@ import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.target.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.word.*; @@ -119,13 +120,13 @@ * re-executed. * @param killedLocations the memory locations killed by the call */ - public static HotSpotForeignCallLinkage create(ForeignCallDescriptor descriptor, long address, RegisterEffect effect, Type outgoingCcType, Type incomingCcType, Transition transition, - boolean reexecutable, LocationIdentity... killedLocations) { - CallingConvention outgoingCc = createCallingConvention(descriptor, outgoingCcType); - CallingConvention incomingCc = incomingCcType == null ? null : createCallingConvention(descriptor, incomingCcType); + public static HotSpotForeignCallLinkage create(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, HotSpotForeignCallsProvider foreignCalls, ForeignCallDescriptor descriptor, + long address, RegisterEffect effect, Type outgoingCcType, Type incomingCcType, Transition transition, boolean reexecutable, LocationIdentity... killedLocations) { + CallingConvention outgoingCc = createCallingConvention(metaAccess, codeCache, descriptor, outgoingCcType); + CallingConvention incomingCc = incomingCcType == null ? null : createCallingConvention(metaAccess, codeCache, descriptor, incomingCcType); HotSpotForeignCallLinkage linkage = new HotSpotForeignCallLinkage(descriptor, address, effect, transition, outgoingCc, incomingCc, reexecutable, killedLocations); if (outgoingCcType == Type.NativeCall) { - linkage.temporaries = runtime().getNativeABICallerSaveRegisters(); + linkage.temporaries = foreignCalls.getNativeABICallerSaveRegisters(); } return linkage; } @@ -133,23 +134,22 @@ /** * Gets a calling convention for a given descriptor and call type. */ - public static CallingConvention createCallingConvention(ForeignCallDescriptor descriptor, Type ccType) { + public static CallingConvention createCallingConvention(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, ForeignCallDescriptor descriptor, Type ccType) { assert ccType != null; - MetaAccessProvider metaAccess = runtime().getProviders().getMetaAccess(); Class[] argumentTypes = descriptor.getArgumentTypes(); JavaType[] parameterTypes = new JavaType[argumentTypes.length]; for (int i = 0; i < parameterTypes.length; ++i) { parameterTypes[i] = asJavaType(argumentTypes[i], metaAccess); } - TargetDescription target = runtime().getTarget(); + TargetDescription target = codeCache.getTarget(); JavaType returnType = asJavaType(descriptor.getResultType(), metaAccess); - RegisterConfig regConfig = runtime().getProviders().getCodeCache().getRegisterConfig(); + RegisterConfig regConfig = codeCache.getRegisterConfig(); return regConfig.getCallingConvention(ccType, returnType, parameterTypes, target, false); } private static JavaType asJavaType(Class type, MetaAccessProvider metaAccess) { if (WordBase.class.isAssignableFrom(type)) { - return metaAccess.lookupJavaType(wordKind().toJavaClass()); + return metaAccess.lookupJavaType(getHostWordKind().toJavaClass()); } else { return metaAccess.lookupJavaType(type); } diff -r 561217cf2ac5 -r 890bea7925fd 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 Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Thu Oct 17 16:01:04 2013 +0200 @@ -45,17 +45,19 @@ /** * Singleton class holding the instance of the {@link GraalRuntime}. - * - * The platform specific subclass is created by a call from the C++ HotSpot code. */ -public abstract class HotSpotGraalRuntime implements GraalRuntime { +public final class HotSpotGraalRuntime implements GraalRuntime { - private static final HotSpotGraalRuntime instance = (HotSpotGraalRuntime) Graal.getRuntime(); + private static final HotSpotGraalRuntime instance = new HotSpotGraalRuntime(); + static { + instance.completeInitialization(); + } /** * Gets the singleton {@link HotSpotGraalRuntime} object. */ public static HotSpotGraalRuntime runtime() { + assert instance != null; return instance; } @@ -86,7 +88,7 @@ this.compilerToVm = toVM; } - // Options must not be directly declared in HotSpotGraalRuntime - see VerifyHotSpotOptionsPhase + // Options must not be directly declared in HotSpotGraalRuntime - see VerifyOptionsPhase static class Options { // @formatter:off @@ -95,19 +97,19 @@ // @formatter:on } - protected static HotSpotGraalRuntimeFactory findFactory(String architecture) { - HotSpotGraalRuntimeFactory basic = null; - HotSpotGraalRuntimeFactory selected = null; - HotSpotGraalRuntimeFactory nonBasic = null; + private static HotSpotBackendFactory findFactory(String architecture) { + HotSpotBackendFactory basic = null; + HotSpotBackendFactory selected = null; + HotSpotBackendFactory nonBasic = null; int nonBasicCount = 0; - for (HotSpotGraalRuntimeFactory factory : ServiceLoader.loadInstalled(HotSpotGraalRuntimeFactory.class)) { - if (factory.getArchitecture().equals(architecture)) { - if (factory.getName().equals(GraalRuntime.getValue())) { + for (HotSpotBackendFactory factory : ServiceLoader.loadInstalled(HotSpotBackendFactory.class)) { + if (factory.getArchitecture().equalsIgnoreCase(architecture)) { + if (factory.getGraalRuntimeName().equals(GraalRuntime.getValue())) { assert selected == null; selected = factory; } - if (factory.getName().equals("basic")) { + if (factory.getGraalRuntimeName().equals("basic")) { assert basic == null; basic = factory; } else { @@ -133,21 +135,18 @@ } } - private static Kind wordKind; - /** - * Gets the kind of a word value. + * Gets the kind of a word value on the {@linkplain #getHostBackend() host} backend. */ - public static Kind wordKind() { - assert wordKind != null; - return wordKind; + public static Kind getHostWordKind() { + return instance.getHostBackend().getTarget().wordKind; } /** * Reads a word value from a given address. */ public static long unsafeReadWord(long address) { - if (wordKind == Kind.Long) { + if (getHostWordKind() == Kind.Long) { return unsafe.getLong(address); } return unsafe.getInt(address); @@ -164,7 +163,7 @@ * Reads a word value from a given object. */ public static long unsafeReadWord(Object object, long offset) { - if (wordKind == Kind.Long) { + if (getHostWordKind() == Kind.Long) { return unsafe.getLong(object, offset); } return unsafe.getInt(object, offset); @@ -174,21 +173,19 @@ protected/* final */CompilerToGPU compilerToGpu; protected/* final */VMToCompiler vmToCompiler; - protected final HotSpotProviders providers; - - protected final TargetDescription target; + protected final HotSpotProviders hostProviders; private HotSpotRuntimeInterpreterInterface runtimeInterpreterInterface; private volatile HotSpotGraphCache cache; protected final HotSpotVMConfig config; - private final HotSpotBackend backend; + private final HotSpotBackend hostBackend; - protected HotSpotGraalRuntime() { + private final Map backends = new HashMap<>(); + + private HotSpotGraalRuntime() { CompilerToVM toVM = new CompilerToVMImpl(); CompilerToGPU toGPU = new CompilerToGPUImpl(); - - // initialize VmToCompiler VMToCompiler toCompiler = new VMToCompilerImpl(this); compilerToVm = toVM; @@ -213,18 +210,58 @@ printConfig(config); } - target = createTarget(); - providers = createProviders(); - assert wordKind == null || wordKind.equals(target.wordKind); - wordKind = target.wordKind; + String hostArchitecture = getHostArchitecture(); + hostBackend = findFactory(hostArchitecture).createBackend(this, null); + hostProviders = hostBackend.getProviders(); + backends.put(hostArchitecture, hostBackend); - backend = createBackend(); + String[] gpuArchitectures = getGPUArchitectures(); + for (String arch : gpuArchitectures) { + HotSpotBackendFactory factory = findFactory(arch); + if (factory == null) { + throw new GraalInternalError("No backend available for specified GPU architecture \"%s\"", arch); + } + backends.put(factory.getArchitecture(), factory.createBackend(this, hostBackend)); + } + GraalOptions.StackShadowPages.setValue(config.stackShadowPages); if (GraalOptions.CacheGraphs.getValue()) { cache = new HotSpotGraphCache(); } } + /** + * Gets the host architecture name for the purpose of finding the corresponding + * {@linkplain HotSpotBackendFactory backend}. + */ + private static String getHostArchitecture() { + String arch = System.getProperty("os.arch"); + switch (arch) { + case "x86_64": + // This is what Mac OS X reports; + arch = "amd64"; + break; + } + return arch; + } + + public static final String GRAAL_GPU_ISALIST_PROPERTY_NAME = "graal.gpu.isalist"; + + /** + * Gets the names of the supported GPU architectures for the purpose of finding the + * corresponding {@linkplain HotSpotBackendFactory backend} objects. This method first looks for + * a comma separated list of names in the {@value #GRAAL_GPU_ISALIST_PROPERTY_NAME} system + * property. If this property is not set, then the GPU native support code is queried. + */ + private String[] getGPUArchitectures() { + String gpuList = System.getProperty(GRAAL_GPU_ISALIST_PROPERTY_NAME); + if (gpuList != null) { + String[] gpus = gpuList.split(","); + return gpus; + } + return compilerToGpu.getAvailableGPUArchitectures(); + } + private static void printConfig(HotSpotVMConfig config) { Field[] fields = config.getClass().getDeclaredFields(); Map sortedFields = new TreeMap<>(); @@ -240,23 +277,12 @@ } } - protected abstract HotSpotProviders createProviders(); - - protected abstract TargetDescription createTarget(); - - protected abstract HotSpotBackend createBackend(); - - /** - * Gets the registers that must be saved across a foreign call into the runtime. - */ - protected abstract Value[] getNativeABICallerSaveRegisters(); - public HotSpotVMConfig getConfig() { return config; } public TargetDescription getTarget() { - return target; + return hostBackend.getTarget(); } public HotSpotGraphCache getCache() { @@ -309,13 +335,13 @@ public HotSpotRuntimeInterpreterInterface getRuntimeInterpreterInterface() { if (runtimeInterpreterInterface == null) { - runtimeInterpreterInterface = new HotSpotRuntimeInterpreterInterface(providers.getMetaAccess()); + runtimeInterpreterInterface = new HotSpotRuntimeInterpreterInterface(hostProviders.getMetaAccess()); } return runtimeInterpreterInterface; } - public HotSpotProviders getProviders() { - return providers; + public HotSpotProviders getHostProviders() { + return hostProviders; } public void evictDeoptedGraphs() { @@ -337,8 +363,8 @@ } @SuppressWarnings("unchecked") - @Override - public T getCapability(Class clazz) { + public static T getCapability(HotSpotBackend backend, Class clazz) { + HotSpotProviders providers = backend.getProviders(); if (clazz == LoweringProvider.class) { return (T) providers.getLowerer(); } @@ -370,13 +396,28 @@ return (T) providers.getRegisters(); } if (clazz == Backend.class) { - return (T) getBackend(); + return (T) backend; } return null; } - public HotSpotBackend getBackend() { - return backend; + @Override + public T getCapability(Class clazz) { + return getCapability(clazz, null); + } + + @Override + public T getCapability(Class clazz, String selector) { + HotSpotBackend backend = selector == null ? hostBackend : backends.get(selector); + return backend == null ? null : getCapability(backend, clazz); + } + + public HotSpotBackend getHostBackend() { + return hostBackend; + } + + public Map getBackends() { + return Collections.unmodifiableMap(backends); } /** diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntimeFactory.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntimeFactory.java Thu Oct 17 15:59:12 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +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; - -public interface HotSpotGraalRuntimeFactory { - - HotSpotGraalRuntime createRuntime(); - - String getArchitecture(); - - String getName(); -} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPU.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPU.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPU.java Thu Oct 17 16:01:04 2013 +0200 @@ -48,8 +48,12 @@ int availableProcessors(); /** - * Attempts to generate and return a bound function to the - * loaded method kernel on the GPU. + * Gets the architecture names of the available GPUs. + */ + String[] getAvailableGPUArchitectures(); + + /** + * Attempts to generate and return a bound function to the loaded method kernel on the GPU. * * @param code the text or binary values for a method kernel * @return the value of the bound kernel in GPU space. @@ -58,7 +62,5 @@ Object executeExternalMethodVarargs(Object[] args, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; - - Object executeParallelMethodVarargs(int dimX, int dimY, int dimZ, - Object[] args, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; + Object executeParallelMethodVarargs(int dimX, int dimY, int dimZ, Object[] args, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPUImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPUImpl.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPUImpl.java Thu Oct 17 16:01:04 2013 +0200 @@ -26,7 +26,6 @@ import com.oracle.graal.api.code.InvalidInstalledCodeException; import com.oracle.graal.hotspot.meta.HotSpotInstalledCode; - /** * Entries into the HotSpot GPU interface from Java code. */ @@ -40,10 +39,9 @@ public native int availableProcessors(); - public native Object executeExternalMethodVarargs(Object[] args, - HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; + public native String[] getAvailableGPUArchitectures(); - public native Object executeParallelMethodVarargs(int dimX, int dimY, int dimZ, - Object[] args, - HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; + public native Object executeExternalMethodVarargs(Object[] args, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; + + public native Object executeParallelMethodVarargs(int dimX, int dimY, int dimZ, Object[] args, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Thu Oct 17 16:01:04 2013 +0200 @@ -128,7 +128,7 @@ bootstrapRunning = bootstrapEnabled; - HotSpotVMConfig config = runtime.getConfig(); + final HotSpotVMConfig config = runtime.getConfig(); long offset = config.graalMirrorInClassOffset; initMirror(typeBoolean, offset); initMirror(typeChar, offset); @@ -180,9 +180,8 @@ } } - final HotSpotProviders providers = runtime.getProviders(); - final MetaAccessProvider metaAccess = providers.getMetaAccess(); - assert VerifyOptionsPhase.checkOptions(metaAccess, providers.getForeignCalls()); + final HotSpotProviders hostProviders = runtime.getHostProviders(); + assert VerifyOptionsPhase.checkOptions(hostProviders.getMetaAccess(), hostProviders.getForeignCalls()); // Install intrinsics. if (Intrinsify.getValue()) { @@ -190,15 +189,35 @@ @Override public void run() { + + List initializedLowerers = new ArrayList<>(); + List initializedForeignCalls = new ArrayList<>(); + + for (Map.Entry e : runtime.getBackends().entrySet()) { + HotSpotBackend backend = e.getValue(); + HotSpotProviders providers = backend.getProviders(); + + HotSpotForeignCallsProvider foreignCalls = providers.getForeignCalls(); + if (!initializedForeignCalls.contains(foreignCalls)) { + initializedForeignCalls.add(foreignCalls); + foreignCalls.initialize(providers, config); + } + HotSpotLoweringProvider lowerer = (HotSpotLoweringProvider) providers.getLowerer(); + if (!initializedLowerers.contains(lowerer)) { + initializedLowerers.add(lowerer); + initializeLowerer(providers, lowerer); + } + } + } + + private void initializeLowerer(HotSpotProviders providers, HotSpotLoweringProvider lowerer) { final Replacements replacements = providers.getReplacements(); - ServiceLoader serviceLoader = ServiceLoader.loadInstalled(ReplacementsProvider.class); + ServiceLoader sl = ServiceLoader.loadInstalled(ReplacementsProvider.class); TargetDescription target = providers.getCodeCache().getTarget(); - HotSpotLoweringProvider lowerer = (HotSpotLoweringProvider) providers.getLowerer(); - for (ReplacementsProvider provider : serviceLoader) { - provider.registerReplacements(metaAccess, lowerer, replacements, target); + for (ReplacementsProvider replacementsProvider : sl) { + replacementsProvider.registerReplacements(providers.getMetaAccess(), lowerer, replacements, target); } - providers.getForeignCalls().initialize(providers); - lowerer.initialize(); + lowerer.initialize(providers, config); if (BootstrapReplacements.getValue()) { for (ResolvedJavaMethod method : replacements.getAllReplacements()) { replacements.getMacroSubstitution(method); @@ -326,6 +345,14 @@ TTY.print("."); TTY.flush(); } + + // Are we out of time? + final int timedBootstrap = TimedBootstrap.getValue(); + if (timedBootstrap != -1) { + if ((System.currentTimeMillis() - startTime) > timedBootstrap) { + break; + } + } } } while ((System.currentTimeMillis() - startTime) <= TimedBootstrap.getValue()); @@ -350,7 +377,7 @@ private MetricRateInPhase inlinedBytecodesPerSecond; private void enqueue(Method m) throws Throwable { - JavaMethod javaMethod = runtime.getProviders().getMetaAccess().lookupJavaMethod(m); + JavaMethod javaMethod = runtime.getHostProviders().getMetaAccess().lookupJavaMethod(m); assert !Modifier.isAbstract(((HotSpotResolvedJavaMethod) javaMethod).getModifiers()) && !Modifier.isNative(((HotSpotResolvedJavaMethod) javaMethod).getModifiers()) : javaMethod; compileMethod((HotSpotResolvedJavaMethod) javaMethod, StructuredGraph.INVOCATION_ENTRY_BCI, false); } @@ -557,7 +584,8 @@ final OptimisticOptimizations optimisticOpts = new OptimisticOptimizations(method); int id = compileTaskIds.incrementAndGet(); - CompilationTask task = CompilationTask.create(runtime, createPhasePlan(optimisticOpts, osrCompilation), optimisticOpts, method, entryBCI, id); + HotSpotBackend backend = runtime.getHostBackend(); + CompilationTask task = CompilationTask.create(backend, createPhasePlan(backend.getProviders(), optimisticOpts, osrCompilation), optimisticOpts, method, entryBCI, id); if (blocking) { task.runCompilation(); @@ -690,10 +718,10 @@ return new LocalImpl(name, type, holder, bciStart, bciEnd, slot); } - public PhasePlan createPhasePlan(OptimisticOptimizations optimisticOpts, boolean onStackReplacement) { + public PhasePlan createPhasePlan(HotSpotProviders providers, OptimisticOptimizations optimisticOpts, boolean onStackReplacement) { PhasePlan phasePlan = new PhasePlan(); - MetaAccessProvider metaAccess = runtime.getProviders().getMetaAccess(); - ForeignCallsProvider foreignCalls = runtime.getProviders().getForeignCalls(); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + ForeignCallsProvider foreignCalls = providers.getForeignCalls(); phasePlan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getDefault(), optimisticOpts)); if (onStackReplacement) { phasePlan.addPhase(PhasePosition.AFTER_PARSING, new OnStackReplacementPhase()); diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Thu Oct 17 16:01:04 2013 +0200 @@ -44,10 +44,12 @@ public abstract class HotSpotCodeCacheProvider implements CodeCacheProvider { protected final HotSpotGraalRuntime runtime; + protected final TargetDescription target; protected final RegisterConfig regConfig; - public HotSpotCodeCacheProvider(HotSpotGraalRuntime runtime) { + public HotSpotCodeCacheProvider(HotSpotGraalRuntime runtime, TargetDescription target) { this.runtime = runtime; + this.target = target; regConfig = createRegisterConfig(); } @@ -57,7 +59,6 @@ public String disassemble(CompilationResult compResult, InstalledCode installedCode) { byte[] code = installedCode == null ? Arrays.copyOf(compResult.getTargetCode(), compResult.getTargetCodeSize()) : installedCode.getCode(); long start = installedCode == null ? 0L : installedCode.getStart(); - TargetDescription target = runtime.getTarget(); HexCodeFile hcf = new HexCodeFile(code, start, target.arch.getName(), target.wordSize * 8); if (compResult != null) { HexCodeFile.addAnnotations(hcf, compResult.getAnnotations()); @@ -191,7 +192,7 @@ @Override public TargetDescription getTarget() { - return runtime.getTarget(); + return target; } public String disassemble(InstalledCode code) { diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotForeignCallsProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotForeignCallsProvider.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotForeignCallsProvider.java Thu Oct 17 16:01:04 2013 +0200 @@ -22,202 +22,19 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.api.code.CallingConvention.Type.*; -import static com.oracle.graal.api.meta.LocationIdentity.*; -import static com.oracle.graal.hotspot.HotSpotBackend.*; -import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*; -import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*; -import static com.oracle.graal.hotspot.nodes.MonitorExitStubCall.*; -import static com.oracle.graal.hotspot.nodes.NewArrayStubCall.*; -import static com.oracle.graal.hotspot.nodes.NewInstanceStubCall.*; -import static com.oracle.graal.hotspot.nodes.NewMultiArrayStubCall.*; -import static com.oracle.graal.hotspot.nodes.VMErrorNode.*; -import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; -import static com.oracle.graal.hotspot.replacements.MonitorSnippets.*; -import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.*; -import static com.oracle.graal.hotspot.replacements.SystemSubstitutions.*; -import static com.oracle.graal.hotspot.replacements.ThreadSubstitutions.*; -import static com.oracle.graal.hotspot.replacements.WriteBarrierSnippets.*; -import static com.oracle.graal.hotspot.stubs.ExceptionHandlerStub.*; -import static com.oracle.graal.hotspot.stubs.NewArrayStub.*; -import static com.oracle.graal.hotspot.stubs.NewInstanceStub.*; -import static com.oracle.graal.hotspot.stubs.StubUtil.*; -import static com.oracle.graal.hotspot.stubs.UnwindExceptionToCallerStub.*; -import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*; -import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*; -import static com.oracle.graal.replacements.Log.*; -import static com.oracle.graal.replacements.MathSubstitutionsX86.*; - -import java.util.*; - import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect; -import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition; -import com.oracle.graal.hotspot.stubs.*; -import com.oracle.graal.word.*; /** - * HotSpot implementation of {@link ForeignCallsProvider}. + * HotSpot extension of {@link ForeignCallsProvider}. */ -public class HotSpotForeignCallsProvider implements ForeignCallsProvider { - - public static final ForeignCallDescriptor OSR_MIGRATION_END = new ForeignCallDescriptor("OSR_migration_end", void.class, long.class); - public static final ForeignCallDescriptor IDENTITY_HASHCODE = new ForeignCallDescriptor("identity_hashcode", int.class, Object.class); - public static final ForeignCallDescriptor VERIFY_OOP = new ForeignCallDescriptor("verify_oop", Object.class, Object.class); - public static final ForeignCallDescriptor LOAD_AND_CLEAR_EXCEPTION = new ForeignCallDescriptor("load_and_clear_exception", Object.class, Word.class); - - protected final HotSpotGraalRuntime runtime; - - private final Map foreignCalls = new HashMap<>(); - - public HotSpotForeignCallsProvider(HotSpotGraalRuntime runtime) { - this.runtime = runtime; - } - - /** - * Registers the linkage for a foreign call. - */ - protected HotSpotForeignCallLinkage register(HotSpotForeignCallLinkage linkage) { - assert !foreignCalls.containsKey(linkage.getDescriptor()) : "already registered linkage for " + linkage.getDescriptor(); - foreignCalls.put(linkage.getDescriptor(), linkage); - return linkage; - } +public interface HotSpotForeignCallsProvider extends ForeignCallsProvider { - /** - * Creates and registers the details for linking a foreign call to a {@link Stub}. - * - * @param descriptor the signature of the call to the stub - * @param reexecutable specifies if the stub call can be re-executed without (meaningful) side - * effects. Deoptimization will not return to a point before a stub call that cannot - * be re-executed. - * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call - * @param killedLocations the memory locations killed by the stub call - */ - protected HotSpotForeignCallLinkage registerStubCall(ForeignCallDescriptor descriptor, boolean reexecutable, Transition transition, LocationIdentity... killedLocations) { - return register(HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations)); - } - - /** - * Creates and registers the linkage for a foreign call. - * - * @param descriptor the signature of the foreign call - * @param address the address of the code to call - * @param outgoingCcType outgoing (caller) calling convention type - * @param effect specifies if the call destroys or preserves all registers (apart from - * temporaries which are always destroyed) - * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call - * @param reexecutable specifies if the foreign call can be re-executed without (meaningful) - * side effects. Deoptimization will not return to a point before a foreign call that - * cannot be re-executed. - * @param killedLocations the memory locations killed by the foreign call - */ - protected HotSpotForeignCallLinkage registerForeignCall(ForeignCallDescriptor descriptor, long address, CallingConvention.Type outgoingCcType, RegisterEffect effect, Transition transition, - boolean reexecutable, LocationIdentity... killedLocations) { - Class resultType = descriptor.getResultType(); - assert transition == LEAF || resultType.isPrimitive() || Word.class.isAssignableFrom(resultType) : "non-leaf foreign calls must return objects in thread local storage: " + descriptor; - return register(HotSpotForeignCallLinkage.create(descriptor, address, effect, outgoingCcType, null, transition, reexecutable, killedLocations)); - } - - private static void link(Stub stub) { - stub.getLinkage().setCompiledStub(stub); - } + void initialize(HotSpotProviders providers, HotSpotVMConfig config); /** - * Creates a {@linkplain ForeignCallStub stub} for a foreign call. - * - * @param descriptor the signature of the call to the stub - * @param address the address of the foreign code to call - * @param prependThread true if the JavaThread value for the current thread is to be prepended - * to the arguments for the call to {@code address} - * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call - * @param reexecutable specifies if the foreign call can be re-executed without (meaningful) - * side effects. Deoptimization will not return to a point before a foreign call that - * cannot be re-executed. - * @param killedLocations the memory locations killed by the foreign call + * Gets the registers that must be saved across a foreign call into the runtime. */ - private void linkForeignCall(HotSpotProviders providers, ForeignCallDescriptor descriptor, long address, boolean prependThread, Transition transition, boolean reexecutable, - LocationIdentity... killedLocations) { - ForeignCallStub stub = new ForeignCallStub(providers, address, descriptor, prependThread, transition, reexecutable, killedLocations); - HotSpotForeignCallLinkage linkage = stub.getLinkage(); - HotSpotForeignCallLinkage targetLinkage = stub.getTargetLinkage(); - linkage.setCompiledStub(stub); - register(linkage); - register(targetLinkage); - } - - public static final boolean PREPEND_THREAD = true; - public static final boolean DONT_PREPEND_THREAD = !PREPEND_THREAD; - - public static final boolean REEXECUTABLE = true; - public static final boolean NOT_REEXECUTABLE = !REEXECUTABLE; - - public static final LocationIdentity[] NO_LOCATIONS = {}; - - public void initialize(HotSpotProviders providers) { - HotSpotVMConfig c = runtime.getConfig(); - TargetDescription target = providers.getCodeCache().getTarget(); - - registerForeignCall(UNCOMMON_TRAP, c.uncommonTrapStub, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); - registerForeignCall(DEOPT_HANDLER, c.handleDeoptStub, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); - registerForeignCall(IC_MISS_HANDLER, c.inlineCacheMissStub, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); - - registerForeignCall(JAVA_TIME_MILLIS, c.javaTimeMillisAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); - registerForeignCall(JAVA_TIME_NANOS, c.javaTimeNanosAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); - registerForeignCall(ARITHMETIC_SIN, c.arithmeticSinAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); - registerForeignCall(ARITHMETIC_COS, c.arithmeticCosAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); - registerForeignCall(ARITHMETIC_TAN, c.arithmeticTanAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); - registerForeignCall(LOAD_AND_CLEAR_EXCEPTION, c.loadAndClearExceptionAddress, NativeCall, DESTROYS_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); - - registerForeignCall(EXCEPTION_HANDLER_FOR_PC, c.exceptionHandlerForPcAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); - registerForeignCall(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, c.exceptionHandlerForReturnAddressAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); - registerForeignCall(NEW_ARRAY_C, c.newArrayAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); - registerForeignCall(NEW_INSTANCE_C, c.newInstanceAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); - registerForeignCall(VM_MESSAGE_C, c.vmMessageAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS); - - link(new NewInstanceStub(providers, target, registerStubCall(NEW_INSTANCE, REEXECUTABLE, NOT_LEAF, ANY_LOCATION))); - link(new NewArrayStub(providers, target, registerStubCall(NEW_ARRAY, REEXECUTABLE, NOT_LEAF, INIT_LOCATION))); - link(new ExceptionHandlerStub(providers, target, foreignCalls.get(EXCEPTION_HANDLER))); - link(new UnwindExceptionToCallerStub(providers, target, registerStubCall(UNWIND_EXCEPTION_TO_CALLER, NOT_REEXECUTABLE, NOT_LEAF, ANY_LOCATION))); - link(new VerifyOopStub(providers, target, registerStubCall(VERIFY_OOP, REEXECUTABLE, LEAF, NO_LOCATIONS))); - - linkForeignCall(providers, IDENTITY_HASHCODE, c.identityHashCodeAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, MARK_WORD_LOCATION); - linkForeignCall(providers, REGISTER_FINALIZER, c.registerFinalizerAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION); - linkForeignCall(providers, CREATE_NULL_POINTER_EXCEPTION, c.createNullPointerExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); - linkForeignCall(providers, CREATE_OUT_OF_BOUNDS_EXCEPTION, c.createOutOfBoundsExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); - linkForeignCall(providers, MONITORENTER, c.monitorenterAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION); - linkForeignCall(providers, MONITOREXIT, c.monitorexitAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION); - linkForeignCall(providers, NEW_MULTI_ARRAY, c.newMultiArrayAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION); - linkForeignCall(providers, DYNAMIC_NEW_ARRAY, c.dynamicNewArrayAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION); - linkForeignCall(providers, LOG_PRINTF, c.logPrintfAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); - linkForeignCall(providers, LOG_OBJECT, c.logObjectAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS); - linkForeignCall(providers, LOG_PRIMITIVE, c.logPrimitiveAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS); - linkForeignCall(providers, THREAD_IS_INTERRUPTED, c.threadIsInterruptedAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION); - linkForeignCall(providers, VM_ERROR, c.vmErrorAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); - linkForeignCall(providers, OSR_MIGRATION_END, c.osrMigrationEndAddress, DONT_PREPEND_THREAD, LEAF, NOT_REEXECUTABLE, NO_LOCATIONS); - linkForeignCall(providers, G1WBPRECALL, c.writeBarrierPreAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); - linkForeignCall(providers, G1WBPOSTCALL, c.writeBarrierPostAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); - linkForeignCall(providers, VALIDATE_OBJECT, c.validateObject, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); - } - - public HotSpotForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) { - HotSpotForeignCallLinkage callTarget = foreignCalls.get(descriptor); - assert foreignCalls != null : descriptor; - callTarget.finalizeAddress(runtime.getBackend()); - return callTarget; - } - - @Override - public boolean isReexecutable(ForeignCallDescriptor descriptor) { - return foreignCalls.get(descriptor).isReexecutable(); - } - - public boolean canDeoptimize(ForeignCallDescriptor descriptor) { - return foreignCalls.get(descriptor).canDeoptimize(); - } - - public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) { - return foreignCalls.get(descriptor).getKilledLocations(); - } + Value[] getNativeABICallerSaveRegisters(); } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java Thu Oct 17 16:01:04 2013 +0200 @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.meta; + +import static com.oracle.graal.api.code.CallingConvention.Type.*; +import static com.oracle.graal.api.meta.LocationIdentity.*; +import static com.oracle.graal.hotspot.HotSpotBackend.*; +import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*; +import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*; +import static com.oracle.graal.hotspot.nodes.MonitorExitStubCall.*; +import static com.oracle.graal.hotspot.nodes.NewArrayStubCall.*; +import static com.oracle.graal.hotspot.nodes.NewInstanceStubCall.*; +import static com.oracle.graal.hotspot.nodes.NewMultiArrayStubCall.*; +import static com.oracle.graal.hotspot.nodes.VMErrorNode.*; +import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import static com.oracle.graal.hotspot.replacements.MonitorSnippets.*; +import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.*; +import static com.oracle.graal.hotspot.replacements.SystemSubstitutions.*; +import static com.oracle.graal.hotspot.replacements.ThreadSubstitutions.*; +import static com.oracle.graal.hotspot.replacements.WriteBarrierSnippets.*; +import static com.oracle.graal.hotspot.stubs.ExceptionHandlerStub.*; +import static com.oracle.graal.hotspot.stubs.NewArrayStub.*; +import static com.oracle.graal.hotspot.stubs.NewInstanceStub.*; +import static com.oracle.graal.hotspot.stubs.StubUtil.*; +import static com.oracle.graal.hotspot.stubs.UnwindExceptionToCallerStub.*; +import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*; +import static com.oracle.graal.nodes.java.RegisterFinalizerNode.*; +import static com.oracle.graal.replacements.Log.*; +import static com.oracle.graal.replacements.MathSubstitutionsX86.*; + +import java.util.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect; +import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition; +import com.oracle.graal.hotspot.stubs.*; +import com.oracle.graal.word.*; + +/** + * HotSpot implementation of {@link ForeignCallsProvider}. + */ +public abstract class HotSpotHostForeignCallsProvider implements HotSpotForeignCallsProvider { + + public static final ForeignCallDescriptor OSR_MIGRATION_END = new ForeignCallDescriptor("OSR_migration_end", void.class, long.class); + public static final ForeignCallDescriptor IDENTITY_HASHCODE = new ForeignCallDescriptor("identity_hashcode", int.class, Object.class); + public static final ForeignCallDescriptor VERIFY_OOP = new ForeignCallDescriptor("verify_oop", Object.class, Object.class); + public static final ForeignCallDescriptor LOAD_AND_CLEAR_EXCEPTION = new ForeignCallDescriptor("load_and_clear_exception", Object.class, Word.class); + + protected final HotSpotGraalRuntime runtime; + + private final Map foreignCalls = new HashMap<>(); + private final MetaAccessProvider metaAccess; + private final CodeCacheProvider codeCache; + + public HotSpotHostForeignCallsProvider(HotSpotGraalRuntime runtime, MetaAccessProvider metaAccess, CodeCacheProvider codeCache) { + this.runtime = runtime; + this.metaAccess = metaAccess; + this.codeCache = codeCache; + } + + /** + * Registers the linkage for a foreign call. + */ + protected HotSpotForeignCallLinkage register(HotSpotForeignCallLinkage linkage) { + assert !foreignCalls.containsKey(linkage.getDescriptor()) : "already registered linkage for " + linkage.getDescriptor(); + foreignCalls.put(linkage.getDescriptor(), linkage); + return linkage; + } + + /** + * Creates and registers the details for linking a foreign call to a {@link Stub}. + * + * @param descriptor the signature of the call to the stub + * @param reexecutable specifies if the stub call can be re-executed without (meaningful) side + * effects. Deoptimization will not return to a point before a stub call that cannot + * be re-executed. + * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call + * @param killedLocations the memory locations killed by the stub call + */ + protected HotSpotForeignCallLinkage registerStubCall(ForeignCallDescriptor descriptor, boolean reexecutable, Transition transition, LocationIdentity... killedLocations) { + return register(HotSpotForeignCallLinkage.create(metaAccess, codeCache, this, descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations)); + } + + /** + * Creates and registers the linkage for a foreign call. + * + * @param descriptor the signature of the foreign call + * @param address the address of the code to call + * @param outgoingCcType outgoing (caller) calling convention type + * @param effect specifies if the call destroys or preserves all registers (apart from + * temporaries which are always destroyed) + * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call + * @param reexecutable specifies if the foreign call can be re-executed without (meaningful) + * side effects. Deoptimization will not return to a point before a foreign call that + * cannot be re-executed. + * @param killedLocations the memory locations killed by the foreign call + */ + protected HotSpotForeignCallLinkage registerForeignCall(ForeignCallDescriptor descriptor, long address, CallingConvention.Type outgoingCcType, RegisterEffect effect, Transition transition, + boolean reexecutable, LocationIdentity... killedLocations) { + Class resultType = descriptor.getResultType(); + assert transition == LEAF || resultType.isPrimitive() || Word.class.isAssignableFrom(resultType) : "non-leaf foreign calls must return objects in thread local storage: " + descriptor; + return register(HotSpotForeignCallLinkage.create(metaAccess, codeCache, this, descriptor, address, effect, outgoingCcType, null, transition, reexecutable, killedLocations)); + } + + private static void link(Stub stub) { + stub.getLinkage().setCompiledStub(stub); + } + + /** + * Creates a {@linkplain ForeignCallStub stub} for a foreign call. + * + * @param descriptor the signature of the call to the stub + * @param address the address of the foreign code to call + * @param prependThread true if the JavaThread value for the current thread is to be prepended + * to the arguments for the call to {@code address} + * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call + * @param reexecutable specifies if the foreign call can be re-executed without (meaningful) + * side effects. Deoptimization will not return to a point before a foreign call that + * cannot be re-executed. + * @param killedLocations the memory locations killed by the foreign call + */ + private void linkForeignCall(HotSpotProviders providers, ForeignCallDescriptor descriptor, long address, boolean prependThread, Transition transition, boolean reexecutable, + LocationIdentity... killedLocations) { + ForeignCallStub stub = new ForeignCallStub(providers, address, descriptor, prependThread, transition, reexecutable, killedLocations); + HotSpotForeignCallLinkage linkage = stub.getLinkage(); + HotSpotForeignCallLinkage targetLinkage = stub.getTargetLinkage(); + linkage.setCompiledStub(stub); + register(linkage); + register(targetLinkage); + } + + public static final boolean PREPEND_THREAD = true; + public static final boolean DONT_PREPEND_THREAD = !PREPEND_THREAD; + + public static final boolean REEXECUTABLE = true; + public static final boolean NOT_REEXECUTABLE = !REEXECUTABLE; + + public static final LocationIdentity[] NO_LOCATIONS = {}; + + public void initialize(HotSpotProviders providers, HotSpotVMConfig c) { + TargetDescription target = providers.getCodeCache().getTarget(); + + registerForeignCall(UNCOMMON_TRAP, c.uncommonTrapStub, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); + registerForeignCall(DEOPT_HANDLER, c.handleDeoptStub, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); + registerForeignCall(IC_MISS_HANDLER, c.inlineCacheMissStub, NativeCall, PRESERVES_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); + + registerForeignCall(JAVA_TIME_MILLIS, c.javaTimeMillisAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); + registerForeignCall(JAVA_TIME_NANOS, c.javaTimeNanosAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); + registerForeignCall(ARITHMETIC_SIN, c.arithmeticSinAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); + registerForeignCall(ARITHMETIC_COS, c.arithmeticCosAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); + registerForeignCall(ARITHMETIC_TAN, c.arithmeticTanAddress, NativeCall, DESTROYS_REGISTERS, LEAF, REEXECUTABLE, NO_LOCATIONS); + registerForeignCall(LOAD_AND_CLEAR_EXCEPTION, c.loadAndClearExceptionAddress, NativeCall, DESTROYS_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); + + registerForeignCall(EXCEPTION_HANDLER_FOR_PC, c.exceptionHandlerForPcAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); + registerForeignCall(EXCEPTION_HANDLER_FOR_RETURN_ADDRESS, c.exceptionHandlerForReturnAddressAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); + registerForeignCall(NEW_ARRAY_C, c.newArrayAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); + registerForeignCall(NEW_INSTANCE_C, c.newInstanceAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); + registerForeignCall(VM_MESSAGE_C, c.vmMessageAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS); + + link(new NewInstanceStub(providers, target, registerStubCall(NEW_INSTANCE, REEXECUTABLE, NOT_LEAF, ANY_LOCATION))); + link(new NewArrayStub(providers, target, registerStubCall(NEW_ARRAY, REEXECUTABLE, NOT_LEAF, INIT_LOCATION))); + link(new ExceptionHandlerStub(providers, target, foreignCalls.get(EXCEPTION_HANDLER))); + link(new UnwindExceptionToCallerStub(providers, target, registerStubCall(UNWIND_EXCEPTION_TO_CALLER, NOT_REEXECUTABLE, NOT_LEAF, ANY_LOCATION))); + link(new VerifyOopStub(providers, target, registerStubCall(VERIFY_OOP, REEXECUTABLE, LEAF, NO_LOCATIONS))); + + linkForeignCall(providers, IDENTITY_HASHCODE, c.identityHashCodeAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, MARK_WORD_LOCATION); + linkForeignCall(providers, REGISTER_FINALIZER, c.registerFinalizerAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION); + linkForeignCall(providers, CREATE_NULL_POINTER_EXCEPTION, c.createNullPointerExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); + linkForeignCall(providers, CREATE_OUT_OF_BOUNDS_EXCEPTION, c.createOutOfBoundsExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION); + linkForeignCall(providers, MONITORENTER, c.monitorenterAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION); + linkForeignCall(providers, MONITOREXIT, c.monitorexitAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION); + linkForeignCall(providers, NEW_MULTI_ARRAY, c.newMultiArrayAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION); + linkForeignCall(providers, DYNAMIC_NEW_ARRAY, c.dynamicNewArrayAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION); + linkForeignCall(providers, LOG_PRINTF, c.logPrintfAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(providers, LOG_OBJECT, c.logObjectAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(providers, LOG_PRIMITIVE, c.logPrimitiveAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(providers, THREAD_IS_INTERRUPTED, c.threadIsInterruptedAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION); + linkForeignCall(providers, VM_ERROR, c.vmErrorAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(providers, OSR_MIGRATION_END, c.osrMigrationEndAddress, DONT_PREPEND_THREAD, LEAF, NOT_REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(providers, G1WBPRECALL, c.writeBarrierPreAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(providers, G1WBPOSTCALL, c.writeBarrierPostAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); + linkForeignCall(providers, VALIDATE_OBJECT, c.validateObject, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS); + } + + public HotSpotForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) { + HotSpotForeignCallLinkage callTarget = foreignCalls.get(descriptor); + assert foreignCalls != null : descriptor; + callTarget.finalizeAddress(runtime.getHostBackend()); + return callTarget; + } + + @Override + public boolean isReexecutable(ForeignCallDescriptor descriptor) { + return foreignCalls.get(descriptor).isReexecutable(); + } + + public boolean canDeoptimize(ForeignCallDescriptor descriptor) { + return foreignCalls.get(descriptor).canDeoptimize(); + } + + public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) { + return foreignCalls.get(descriptor).getKilledLocations(); + } + + /** + * Gets the registers that must be saved across a foreign call into the runtime. + */ + public abstract Value[] getNativeABICallerSaveRegisters(); +} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostLoweringProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostLoweringProvider.java Thu Oct 17 16:01:04 2013 +0200 @@ -0,0 +1,681 @@ +/* + * 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.graal.api.code.MemoryBarriers.*; +import static com.oracle.graal.api.meta.DeoptimizationAction.*; +import static com.oracle.graal.api.meta.DeoptimizationReason.*; +import static com.oracle.graal.api.meta.LocationIdentity.*; +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +import static com.oracle.graal.hotspot.meta.HotSpotHostForeignCallsProvider.*; +import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.*; +import static com.oracle.graal.nodes.java.ArrayLengthNode.*; +import static com.oracle.graal.phases.GraalOptions.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.debug.*; +import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.hotspot.replacements.*; +import com.oracle.graal.java.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.HeapAccess.BarrierType; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.debug.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; +import com.oracle.graal.replacements.*; + +/** + * HotSpot implementation of {@link LoweringProvider}. + */ +public class HotSpotHostLoweringProvider implements HotSpotLoweringProvider { + + protected final HotSpotGraalRuntime runtime; + protected final MetaAccessProvider metaAccess; + protected final ForeignCallsProvider foreignCalls; + + private CheckCastDynamicSnippets.Templates checkcastDynamicSnippets; + private InstanceOfSnippets.Templates instanceofSnippets; + private NewObjectSnippets.Templates newObjectSnippets; + private MonitorSnippets.Templates monitorSnippets; + protected WriteBarrierSnippets.Templates writeBarrierSnippets; + private BoxingSnippets.Templates boxingSnippets; + private LoadExceptionObjectSnippets.Templates exceptionObjectSnippets; + private UnsafeLoadSnippets.Templates unsafeLoadSnippets; + + public HotSpotHostLoweringProvider(HotSpotGraalRuntime runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) { + this.runtime = runtime; + this.metaAccess = metaAccess; + this.foreignCalls = foreignCalls; + } + + public void initialize(HotSpotProviders providers, HotSpotVMConfig config) { + Replacements r = providers.getReplacements(); + + r.registerSubstitutions(ObjectSubstitutions.class); + r.registerSubstitutions(SystemSubstitutions.class); + r.registerSubstitutions(ThreadSubstitutions.class); + r.registerSubstitutions(UnsafeSubstitutions.class); + r.registerSubstitutions(ClassSubstitutions.class); + r.registerSubstitutions(AESCryptSubstitutions.class); + r.registerSubstitutions(CipherBlockChainingSubstitutions.class); + r.registerSubstitutions(CRC32Substitutions.class); + r.registerSubstitutions(ReflectionSubstitutions.class); + + TargetDescription target = providers.getCodeCache().getTarget(); + checkcastDynamicSnippets = new CheckCastDynamicSnippets.Templates(providers, target); + instanceofSnippets = new InstanceOfSnippets.Templates(providers, target); + newObjectSnippets = new NewObjectSnippets.Templates(providers, target); + monitorSnippets = new MonitorSnippets.Templates(providers, target, config.useFastLocking); + writeBarrierSnippets = new WriteBarrierSnippets.Templates(providers, target); + boxingSnippets = new BoxingSnippets.Templates(providers, target); + exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(providers, target); + unsafeLoadSnippets = new UnsafeLoadSnippets.Templates(providers, target); + + r.registerSnippetTemplateCache(new UnsafeArrayCopySnippets.Templates(providers, target)); + } + + @Override + public void lower(Node n, LoweringTool tool) { + HotSpotVMConfig config = runtime.getConfig(); + StructuredGraph graph = (StructuredGraph) n.graph(); + + Kind wordKind = runtime.getTarget().wordKind; + if (n instanceof ArrayLengthNode) { + ArrayLengthNode arrayLengthNode = (ArrayLengthNode) n; + ValueNode array = arrayLengthNode.array(); + ReadNode arrayLengthRead = graph.add(new ReadNode(array, ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, config.arrayLengthOffset, graph), StampFactory.positiveInt(), + BarrierType.NONE, false)); + tool.createNullCheckGuard(arrayLengthRead, array); + graph.replaceFixedWithFixed(arrayLengthNode, arrayLengthRead); + } else if (n instanceof Invoke) { + Invoke invoke = (Invoke) n; + if (invoke.callTarget() instanceof MethodCallTargetNode) { + + MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget(); + NodeInputList parameters = callTarget.arguments(); + ValueNode receiver = parameters.size() <= 0 ? null : parameters.get(0); + GuardingNode receiverNullCheck = null; + if (!callTarget.isStatic() && receiver.stamp() instanceof ObjectStamp && !ObjectStamp.isObjectNonNull(receiver)) { + receiverNullCheck = tool.createNullCheckGuard(invoke, receiver); + } + JavaType[] signature = MetaUtil.signatureToTypes(callTarget.targetMethod().getSignature(), callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass()); + + LoweredCallTargetNode loweredCallTarget = null; + if (callTarget.invokeKind() == InvokeKind.Virtual && InlineVTableStubs.getValue() && (AlwaysInlineVTableStubs.getValue() || invoke.isPolymorphic())) { + + HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod(); + if (!hsMethod.getDeclaringClass().isInterface()) { + if (hsMethod.isInVirtualMethodTable()) { + int vtableEntryOffset = hsMethod.vtableEntryOffset(); + assert vtableEntryOffset > 0; + FloatingReadNode hub = createReadHub(graph, wordKind, receiver, receiverNullCheck); + + ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, hub, hsMethod); + // We use LocationNode.ANY_LOCATION for the reads that access the + // compiled code entry as HotSpot does not guarantee they are final + // values. + ReadNode compiledEntry = graph.add(new ReadNode(metaspaceMethod, ConstantLocationNode.create(ANY_LOCATION, wordKind, config.methodCompiledEntryOffset, graph), + StampFactory.forKind(wordKind), BarrierType.NONE, false)); + + loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(metaspaceMethod, compiledEntry, parameters, invoke.asNode().stamp(), signature, callTarget.targetMethod(), + CallingConvention.Type.JavaCall)); + + graph.addBeforeFixed(invoke.asNode(), metaspaceMethod); + graph.addAfterFixed(metaspaceMethod, compiledEntry); + } + } + } + + if (loweredCallTarget == null) { + loweredCallTarget = graph.add(new HotSpotDirectCallTargetNode(parameters, invoke.asNode().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall, + callTarget.invokeKind())); + } + callTarget.replaceAndDelete(loweredCallTarget); + } + } else if (n instanceof LoadFieldNode) { + LoadFieldNode loadField = (LoadFieldNode) n; + HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) loadField.field(); + ValueNode object = loadField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), metaAccess, graph) : loadField.object(); + assert loadField.kind() != Kind.Illegal; + BarrierType barrierType = getFieldLoadBarrierType(field); + ReadNode memoryRead = graph.add(new ReadNode(object, createFieldLocation(graph, field, false), loadField.stamp(), barrierType, (loadField.kind() == Kind.Object))); + graph.replaceFixedWithFixed(loadField, memoryRead); + tool.createNullCheckGuard(memoryRead, object); + + if (loadField.isVolatile()) { + MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_READ)); + graph.addBeforeFixed(memoryRead, preMembar); + MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_READ)); + graph.addAfterFixed(memoryRead, postMembar); + } + } else if (n instanceof StoreFieldNode) { + StoreFieldNode storeField = (StoreFieldNode) n; + HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field(); + ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), metaAccess, graph) : storeField.object(); + BarrierType barrierType = getFieldStoreBarrierType(storeField); + WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), createFieldLocation(graph, field, false), barrierType, storeField.field().getKind() == Kind.Object)); + tool.createNullCheckGuard(memoryWrite, object); + memoryWrite.setStateAfter(storeField.stateAfter()); + graph.replaceFixedWithFixed(storeField, memoryWrite); + FixedWithNextNode last = memoryWrite; + FixedWithNextNode first = memoryWrite; + + if (storeField.isVolatile()) { + MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_WRITE)); + graph.addBeforeFixed(first, preMembar); + MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_WRITE)); + graph.addAfterFixed(last, postMembar); + } + } else if (n instanceof CompareAndSwapNode) { + // Separate out GC barrier semantics + CompareAndSwapNode cas = (CompareAndSwapNode) n; + LocationNode location = IndexedLocationNode.create(ANY_LOCATION, cas.expected().kind(), cas.displacement(), cas.offset(), graph, 1); + LoweredCompareAndSwapNode atomicNode = graph.add(new LoweredCompareAndSwapNode(cas.object(), location, cas.expected(), cas.newValue(), getCompareAndSwapBarrier(cas), + cas.expected().kind() == Kind.Object)); + atomicNode.setStateAfter(cas.stateAfter()); + graph.replaceFixedWithFixed(cas, atomicNode); + } else if (n instanceof LoadIndexedNode) { + LoadIndexedNode loadIndexed = (LoadIndexedNode) n; + GuardingNode boundsCheck = createBoundsCheck(loadIndexed, tool); + Kind elementKind = loadIndexed.elementKind(); + LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index(), false); + ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), arrayLocation, loadIndexed.stamp(), BarrierType.NONE, elementKind == Kind.Object)); + memoryRead.setGuard(boundsCheck); + graph.replaceFixedWithFixed(loadIndexed, memoryRead); + } else if (n instanceof StoreIndexedNode) { + StoreIndexedNode storeIndexed = (StoreIndexedNode) n; + GuardingNode boundsCheck = createBoundsCheck(storeIndexed, tool); + Kind elementKind = storeIndexed.elementKind(); + LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index(), false); + ValueNode value = storeIndexed.value(); + ValueNode array = storeIndexed.array(); + + CheckCastNode checkcastNode = null; + CheckCastDynamicNode checkcastDynamicNode = null; + if (elementKind == Kind.Object && !ObjectStamp.isObjectAlwaysNull(value)) { + // Store check! + ResolvedJavaType arrayType = ObjectStamp.typeOrNull(array); + if (arrayType != null && ObjectStamp.isExactType(array)) { + ResolvedJavaType elementType = arrayType.getComponentType(); + if (!MetaUtil.isJavaLangObject(elementType)) { + checkcastNode = graph.add(new CheckCastNode(elementType, value, null, true)); + graph.addBeforeFixed(storeIndexed, checkcastNode); + value = checkcastNode; + } + } else { + FloatingReadNode arrayClass = createReadHub(graph, wordKind, array, boundsCheck); + LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, config.arrayClassElementOffset, graph); + /* + * Anchor the read of the element klass to the cfg, because it is only valid + * when arrayClass is an object class, which might not be the case in other + * parts of the compiled method. + */ + FloatingReadNode arrayElementKlass = graph.unique(new FloatingReadNode(arrayClass, location, null, StampFactory.forKind(wordKind), BeginNode.prevBegin(storeIndexed))); + checkcastDynamicNode = graph.add(new CheckCastDynamicNode(arrayElementKlass, value, true)); + graph.addBeforeFixed(storeIndexed, checkcastDynamicNode); + value = checkcastDynamicNode; + } + } + BarrierType barrierType = getArrayStoreBarrierType(storeIndexed); + WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation, barrierType, elementKind == Kind.Object)); + memoryWrite.setGuard(boundsCheck); + memoryWrite.setStateAfter(storeIndexed.stateAfter()); + graph.replaceFixedWithFixed(storeIndexed, memoryWrite); + + // Lower the associated checkcast node. + if (checkcastNode != null) { + checkcastNode.lower(tool); + } else if (checkcastDynamicNode != null) { + checkcastDynamicSnippets.lower(checkcastDynamicNode); + } + } else if (n instanceof UnsafeLoadNode) { + UnsafeLoadNode load = (UnsafeLoadNode) n; + if (load.getGuardingCondition() != null) { + boolean compressible = (!load.object().isNullConstant() && load.accessKind() == Kind.Object); + ConditionAnchorNode valueAnchorNode = graph.add(new ConditionAnchorNode(load.getGuardingCondition())); + LocationNode location = createLocation(load); + ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp(), valueAnchorNode, BarrierType.NONE, compressible)); + load.replaceAtUsages(memoryRead); + graph.replaceFixedWithFixed(load, valueAnchorNode); + graph.addAfterFixed(valueAnchorNode, memoryRead); + } else if (graph.getGuardsStage().ordinal() > StructuredGraph.GuardsStage.FLOATING_GUARDS.ordinal()) { + assert load.kind() != Kind.Illegal; + boolean compressible = (!load.object().isNullConstant() && load.accessKind() == Kind.Object); + if (addReadBarrier(load)) { + unsafeLoadSnippets.lower(load, tool); + } else { + LocationNode location = createLocation(load); + ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp(), BarrierType.NONE, compressible)); + // An unsafe read must not float outside its block otherwise + // it may float above an explicit null check on its object. + memoryRead.setGuard(AbstractBeginNode.prevBegin(load)); + graph.replaceFixedWithFixed(load, memoryRead); + } + } + } else if (n instanceof UnsafeStoreNode) { + UnsafeStoreNode store = (UnsafeStoreNode) n; + LocationNode location = createLocation(store); + ValueNode object = store.object(); + BarrierType barrierType = getUnsafeStoreBarrierType(store); + WriteNode write = graph.add(new WriteNode(object, store.value(), location, barrierType, store.value().kind() == Kind.Object)); + write.setStateAfter(store.stateAfter()); + graph.replaceFixedWithFixed(store, write); + } else if (n instanceof LoadHubNode) { + LoadHubNode loadHub = (LoadHubNode) n; + assert loadHub.kind() == wordKind; + ValueNode object = loadHub.object(); + GuardingNode guard = loadHub.getGuard(); + FloatingReadNode hub = createReadHub(graph, wordKind, object, guard); + graph.replaceFloating(loadHub, hub); + } else if (n instanceof LoadMethodNode) { + LoadMethodNode loadMethodNode = (LoadMethodNode) n; + ResolvedJavaMethod method = loadMethodNode.getMethod(); + ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, loadMethodNode.getHub(), method); + graph.replaceFixed(loadMethodNode, metaspaceMethod); + } else if (n instanceof StoreHubNode) { + StoreHubNode storeHub = (StoreHubNode) n; + WriteNode hub = createWriteHub(graph, wordKind, storeHub.getObject(), storeHub.getValue()); + graph.replaceFixed(storeHub, hub); + } else if (n instanceof CommitAllocationNode) { + if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { + CommitAllocationNode commit = (CommitAllocationNode) n; + + ValueNode[] allocations = new ValueNode[commit.getVirtualObjects().size()]; + for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) { + VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex); + int entryCount = virtual.entryCount(); + + FixedWithNextNode newObject; + if (virtual instanceof VirtualInstanceNode) { + newObject = graph.add(new NewInstanceNode(virtual.type(), true)); + } else { + ResolvedJavaType element = ((VirtualArrayNode) virtual).componentType(); + newObject = graph.add(new NewArrayNode(element, ConstantNode.forInt(entryCount, graph), true)); + } + graph.addBeforeFixed(commit, newObject); + allocations[objIndex] = newObject; + } + int valuePos = 0; + for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) { + VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex); + int entryCount = virtual.entryCount(); + + ValueNode newObject = allocations[objIndex]; + if (virtual instanceof VirtualInstanceNode) { + VirtualInstanceNode virtualInstance = (VirtualInstanceNode) virtual; + for (int i = 0; i < entryCount; i++) { + ValueNode value = commit.getValues().get(valuePos++); + if (value instanceof VirtualObjectNode) { + value = allocations[commit.getVirtualObjects().indexOf(value)]; + } + if (!(value.isConstant() && value.asConstant().isDefaultForKind())) { + WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) virtualInstance.field(i), true), + (virtualInstance.field(i).getKind() == Kind.Object && !deferInitBarrier(newObject)) ? BarrierType.IMPRECISE : BarrierType.NONE, + virtualInstance.field(i).getKind() == Kind.Object); + graph.addBeforeFixed(commit, graph.add(write)); + } + } + + } else { + VirtualArrayNode array = (VirtualArrayNode) virtual; + ResolvedJavaType element = array.componentType(); + for (int i = 0; i < entryCount; i++) { + ValueNode value = commit.getValues().get(valuePos++); + if (value instanceof VirtualObjectNode) { + int indexOf = commit.getVirtualObjects().indexOf(value); + assert indexOf != -1 : commit + " " + value; + value = allocations[indexOf]; + } + if (!(value.isConstant() && value.asConstant().isDefaultForKind())) { + WriteNode write = new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph), true), + (value.kind() == Kind.Object && !deferInitBarrier(newObject)) ? BarrierType.PRECISE : BarrierType.NONE, value.kind() == Kind.Object); + graph.addBeforeFixed(commit, graph.add(write)); + } + } + } + } + for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) { + FixedValueAnchorNode anchor = graph.add(new FixedValueAnchorNode(allocations[objIndex])); + allocations[objIndex] = anchor; + graph.addBeforeFixed(commit, anchor); + } + for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) { + for (int lockDepth : commit.getLocks().get(objIndex)) { + MonitorEnterNode enter = graph.add(new MonitorEnterNode(allocations[objIndex], lockDepth)); + graph.addBeforeFixed(commit, enter); + enter.lower(tool); + } + } + for (Node usage : commit.usages().snapshot()) { + AllocatedObjectNode addObject = (AllocatedObjectNode) usage; + int index = commit.getVirtualObjects().indexOf(addObject.getVirtualObject()); + graph.replaceFloating(addObject, allocations[index]); + } + graph.removeFixed(commit); + } + } else if (n instanceof OSRStartNode) { + if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { + OSRStartNode osrStart = (OSRStartNode) n; + StartNode newStart = graph.add(new StartNode()); + LocalNode buffer = graph.unique(new LocalNode(0, StampFactory.forKind(wordKind))); + ForeignCallNode migrationEnd = graph.add(new ForeignCallNode(foreignCalls, OSR_MIGRATION_END, buffer)); + migrationEnd.setStateAfter(osrStart.stateAfter()); + + newStart.setNext(migrationEnd); + FixedNode next = osrStart.next(); + osrStart.setNext(null); + migrationEnd.setNext(next); + graph.setStart(newStart); + + // mirroring the calculations in c1_GraphBuilder.cpp (setup_osr_entry_block) + int localsOffset = (graph.method().getMaxLocals() - 1) * 8; + for (OSRLocalNode osrLocal : graph.getNodes(OSRLocalNode.class)) { + int size = FrameStateBuilder.stackSlots(osrLocal.kind()); + int offset = localsOffset - (osrLocal.index() + size - 1) * 8; + IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, osrLocal.kind(), offset, ConstantNode.forLong(0, graph), graph, 1); + ReadNode load = graph.add(new ReadNode(buffer, location, osrLocal.stamp(), BarrierType.NONE, false)); + osrLocal.replaceAndDelete(load); + graph.addBeforeFixed(migrationEnd, load); + } + osrStart.replaceAtUsages(newStart); + osrStart.safeDelete(); + } + } else if (n instanceof DynamicCounterNode) { + if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + BenchmarkCounters.lower((DynamicCounterNode) n, runtime.getHostProviders().getRegisters(), runtime.getConfig(), wordKind); + } + } else if (n instanceof CheckCastDynamicNode) { + checkcastDynamicSnippets.lower((CheckCastDynamicNode) n); + } else if (n instanceof InstanceOfNode) { + if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { + instanceofSnippets.lower((InstanceOfNode) n, tool); + } + } else if (n instanceof InstanceOfDynamicNode) { + if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { + instanceofSnippets.lower((InstanceOfDynamicNode) n, tool); + } + } else if (n instanceof NewInstanceNode) { + if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + newObjectSnippets.lower((NewInstanceNode) n); + } + } else if (n instanceof NewArrayNode) { + if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + newObjectSnippets.lower((NewArrayNode) n); + } + } else if (n instanceof DynamicNewArrayNode) { + if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + newObjectSnippets.lower((DynamicNewArrayNode) n); + } + } else if (n instanceof MonitorEnterNode) { + if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { + monitorSnippets.lower((MonitorEnterNode) n, tool); + } + } else if (n instanceof MonitorExitNode) { + if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { + monitorSnippets.lower((MonitorExitNode) n, tool); + } + } else if (n instanceof G1PreWriteBarrier) { + writeBarrierSnippets.lower((G1PreWriteBarrier) n, tool); + } else if (n instanceof G1PostWriteBarrier) { + writeBarrierSnippets.lower((G1PostWriteBarrier) n, tool); + } else if (n instanceof G1ReferentFieldReadBarrier) { + writeBarrierSnippets.lower((G1ReferentFieldReadBarrier) n, tool); + } else if (n instanceof SerialWriteBarrier) { + writeBarrierSnippets.lower((SerialWriteBarrier) n, tool); + } else if (n instanceof SerialArrayRangeWriteBarrier) { + writeBarrierSnippets.lower((SerialArrayRangeWriteBarrier) n, tool); + } else if (n instanceof G1ArrayRangePreWriteBarrier) { + writeBarrierSnippets.lower((G1ArrayRangePreWriteBarrier) n, tool); + } else if (n instanceof G1ArrayRangePostWriteBarrier) { + writeBarrierSnippets.lower((G1ArrayRangePostWriteBarrier) n, tool); + } else if (n instanceof NewMultiArrayNode) { + if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + newObjectSnippets.lower((NewMultiArrayNode) n); + } + } else if (n instanceof LoadExceptionObjectNode) { + exceptionObjectSnippets.lower((LoadExceptionObjectNode) n); + } else if (n instanceof IntegerDivNode || n instanceof IntegerRemNode || n instanceof UnsignedDivNode || n instanceof UnsignedRemNode) { + // Nothing to do for division nodes. The HotSpot signal handler catches divisions by + // zero and the MIN_VALUE / -1 cases. + } else if (n instanceof BoxNode) { + boxingSnippets.lower((BoxNode) n, tool); + } else if (n instanceof UnboxNode) { + boxingSnippets.lower((UnboxNode) n, tool); + } else { + assert false : "Node implementing Lowerable not handled: " + n; + throw GraalInternalError.shouldNotReachHere(); + } + } + + private static LocationNode createLocation(UnsafeAccessNode access) { + ValueNode offset = access.offset(); + if (offset.isConstant()) { + long offsetValue = offset.asConstant().asLong(); + return ConstantLocationNode.create(access.getLocationIdentity(), access.accessKind(), offsetValue, access.graph()); + } + + long displacement = 0; + int indexScaling = 1; + if (offset instanceof IntegerAddNode) { + IntegerAddNode integerAddNode = (IntegerAddNode) offset; + if (integerAddNode.y() instanceof ConstantNode) { + displacement = integerAddNode.y().asConstant().asLong(); + offset = integerAddNode.x(); + } + } + + if (offset instanceof LeftShiftNode) { + LeftShiftNode leftShiftNode = (LeftShiftNode) offset; + if (leftShiftNode.y() instanceof ConstantNode) { + long shift = leftShiftNode.y().asConstant().asLong(); + if (shift >= 1 && shift <= 3) { + if (shift == 1) { + indexScaling = 2; + } else if (shift == 2) { + indexScaling = 4; + } else { + indexScaling = 8; + } + offset = leftShiftNode.x(); + } + } + } + + return IndexedLocationNode.create(access.getLocationIdentity(), access.accessKind(), displacement, offset, access.graph(), indexScaling); + } + + private static boolean addReadBarrier(UnsafeLoadNode load) { + if (useG1GC() && load.graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS && load.object().kind() == Kind.Object && load.accessKind() == Kind.Object && + !ObjectStamp.isObjectAlwaysNull(load.object())) { + ResolvedJavaType type = ObjectStamp.typeOrNull(load.object()); + if (type != null && !type.isArray()) { + return true; + } + } + return false; + } + + private static ReadNode createReadVirtualMethod(StructuredGraph graph, Kind wordKind, ValueNode hub, ResolvedJavaMethod method) { + HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method; + assert !hsMethod.getDeclaringClass().isInterface(); + assert hsMethod.isInVirtualMethodTable(); + + int vtableEntryOffset = hsMethod.vtableEntryOffset(); + assert vtableEntryOffset > 0; + // We use LocationNode.ANY_LOCATION for the reads that access the vtable + // entry as HotSpot does not guarantee that this is a final value. + ReadNode metaspaceMethod = graph.add(new ReadNode(hub, ConstantLocationNode.create(ANY_LOCATION, wordKind, vtableEntryOffset, graph), StampFactory.forKind(wordKind), BarrierType.NONE, false)); + return metaspaceMethod; + } + + private FloatingReadNode createReadHub(StructuredGraph graph, Kind wordKind, ValueNode object, GuardingNode guard) { + HotSpotVMConfig config = runtime.getConfig(); + LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, config.hubOffset, graph); + assert !object.isConstant() || object.asConstant().isNull(); + return graph.unique(new FloatingReadNode(object, location, null, StampFactory.forKind(wordKind), guard, BarrierType.NONE, config.useCompressedClassPointers)); + } + + private WriteNode createWriteHub(StructuredGraph graph, Kind wordKind, ValueNode object, ValueNode value) { + HotSpotVMConfig config = runtime.getConfig(); + LocationNode location = ConstantLocationNode.create(HUB_LOCATION, wordKind, config.hubOffset, graph); + assert !object.isConstant() || object.asConstant().isNull(); + return graph.add(new WriteNode(object, value, location, BarrierType.NONE, config.useCompressedClassPointers)); + } + + private static BarrierType getFieldLoadBarrierType(HotSpotResolvedJavaField loadField) { + BarrierType barrierType = BarrierType.NONE; + if (config().useG1GC && loadField.getKind() == Kind.Object && loadField.getDeclaringClass().mirror() == java.lang.ref.Reference.class && loadField.getName().equals("referent")) { + barrierType = BarrierType.PRECISE; + } + return barrierType; + } + + private static BarrierType getFieldStoreBarrierType(StoreFieldNode storeField) { + BarrierType barrierType = BarrierType.NONE; + if (storeField.field().getKind() == Kind.Object && !deferInitBarrier(storeField.object())) { + barrierType = BarrierType.IMPRECISE; + } + return barrierType; + } + + private static BarrierType getArrayStoreBarrierType(StoreIndexedNode store) { + BarrierType barrierType = BarrierType.NONE; + if (store.elementKind() == Kind.Object && !deferInitBarrier(store.array())) { + barrierType = BarrierType.PRECISE; + } + return barrierType; + } + + private static boolean deferInitBarrier(ValueNode object) { + return useDeferredInitBarriers() && (object instanceof NewInstanceNode || object instanceof NewArrayNode); + } + + private static BarrierType getUnsafeStoreBarrierType(UnsafeStoreNode store) { + BarrierType barrierType = BarrierType.NONE; + if (store.value().kind() == Kind.Object) { + ResolvedJavaType type = ObjectStamp.typeOrNull(store.object()); + if (type != null && !type.isArray()) { + barrierType = BarrierType.IMPRECISE; + } else { + barrierType = BarrierType.PRECISE; + } + } + return barrierType; + } + + private static BarrierType getCompareAndSwapBarrier(CompareAndSwapNode cas) { + BarrierType barrierType = BarrierType.NONE; + if (cas.expected().kind() == Kind.Object) { + ResolvedJavaType type = ObjectStamp.typeOrNull(cas.object()); + if (type != null && !type.isArray()) { + barrierType = BarrierType.IMPRECISE; + } else { + barrierType = BarrierType.PRECISE; + } + } + return barrierType; + } + + protected static ConstantLocationNode createFieldLocation(StructuredGraph graph, HotSpotResolvedJavaField field, boolean initialization) { + LocationIdentity loc = initialization ? INIT_LOCATION : field; + return ConstantLocationNode.create(loc, field.getKind(), field.offset(), graph); + } + + public int getScalingFactor(Kind kind) { + if (useCompressedOops() && kind == Kind.Object) { + return this.runtime.getTarget().arch.getSizeInBytes(Kind.Int); + } else { + return this.runtime.getTarget().arch.getSizeInBytes(kind); + } + } + + protected IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index, boolean initialization) { + LocationIdentity loc = initialization ? INIT_LOCATION : NamedLocationIdentity.getArrayLocation(elementKind); + int scale = getScalingFactor(elementKind); + return IndexedLocationNode.create(loc, elementKind, getArrayBaseOffset(elementKind), index, graph, scale); + } + + @Override + public ValueNode reconstructArrayIndex(LocationNode location) { + Kind elementKind = location.getValueKind(); + assert location.getLocationIdentity().equals(NamedLocationIdentity.getArrayLocation(elementKind)); + + long base; + ValueNode index; + int scale = getScalingFactor(elementKind); + + if (location instanceof ConstantLocationNode) { + base = ((ConstantLocationNode) location).getDisplacement(); + index = null; + } else if (location instanceof IndexedLocationNode) { + IndexedLocationNode indexedLocation = (IndexedLocationNode) location; + assert indexedLocation.getIndexScaling() == scale; + base = indexedLocation.getDisplacement(); + index = indexedLocation.getIndex(); + } else { + throw GraalInternalError.shouldNotReachHere(); + } + + base -= getArrayBaseOffset(elementKind); + assert base >= 0 && base % scale == 0; + + base /= scale; + assert NumUtil.isInt(base); + + if (index == null) { + return ConstantNode.forInt((int) base, location.graph()); + } else { + if (base == 0) { + return index; + } else { + return IntegerArithmeticNode.add(ConstantNode.forInt((int) base, location.graph()), index); + } + } + } + + private GuardingNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) { + StructuredGraph g = n.graph(); + ValueNode array = n.array(); + ValueNode arrayLength = readArrayLength(array, tool.getConstantReflection()); + if (arrayLength == null) { + Stamp stamp = StampFactory.positiveInt(); + ReadNode readArrayLength = g.add(new ReadNode(array, ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, runtime.getConfig().arrayLengthOffset, g), stamp, BarrierType.NONE, false)); + g.addBeforeFixed(n, readArrayLength); + tool.createNullCheckGuard(readArrayLength, array); + arrayLength = readArrayLength; + } + + return tool.createGuard(g.unique(new IntegerBelowThanNode(n.index(), arrayLength)), BoundsCheckException, InvalidateReprofile); + } + +} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Thu Oct 17 16:01:04 2013 +0200 @@ -22,661 +22,16 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.api.code.MemoryBarriers.*; -import static com.oracle.graal.api.meta.DeoptimizationAction.*; -import static com.oracle.graal.api.meta.DeoptimizationReason.*; -import static com.oracle.graal.api.meta.LocationIdentity.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import static com.oracle.graal.hotspot.meta.HotSpotForeignCallsProvider.*; -import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; -import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.*; -import static com.oracle.graal.nodes.java.ArrayLengthNode.*; -import static com.oracle.graal.phases.GraalOptions.*; - -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.asm.*; -import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.debug.*; -import com.oracle.graal.hotspot.nodes.*; -import com.oracle.graal.hotspot.replacements.*; -import com.oracle.graal.java.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.HeapAccess.BarrierType; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.debug.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.nodes.virtual.*; -import com.oracle.graal.replacements.*; /** - * HotSpot implementation of {@link LoweringProvider}. + * HotSpot extension of {@link LoweringProvider}. */ -public class HotSpotLoweringProvider implements LoweringProvider { - - protected final HotSpotGraalRuntime runtime; - protected final MetaAccessProvider metaAccess; - protected final ForeignCallsProvider foreignCalls; - - private CheckCastDynamicSnippets.Templates checkcastDynamicSnippets; - private InstanceOfSnippets.Templates instanceofSnippets; - private NewObjectSnippets.Templates newObjectSnippets; - private MonitorSnippets.Templates monitorSnippets; - protected WriteBarrierSnippets.Templates writeBarrierSnippets; - private BoxingSnippets.Templates boxingSnippets; - private LoadExceptionObjectSnippets.Templates exceptionObjectSnippets; - private UnsafeLoadSnippets.Templates unsafeLoadSnippets; - - public HotSpotLoweringProvider(HotSpotGraalRuntime runtime, MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls) { - this.runtime = runtime; - this.metaAccess = metaAccess; - this.foreignCalls = foreignCalls; - } - - public void initialize() { - HotSpotVMConfig c = runtime.getConfig(); - HotSpotProviders providers = runtime.getProviders(); - Replacements r = providers.getReplacements(); - - r.registerSubstitutions(ObjectSubstitutions.class); - r.registerSubstitutions(SystemSubstitutions.class); - r.registerSubstitutions(ThreadSubstitutions.class); - r.registerSubstitutions(UnsafeSubstitutions.class); - r.registerSubstitutions(ClassSubstitutions.class); - r.registerSubstitutions(AESCryptSubstitutions.class); - r.registerSubstitutions(CipherBlockChainingSubstitutions.class); - r.registerSubstitutions(CRC32Substitutions.class); - r.registerSubstitutions(ReflectionSubstitutions.class); - - checkcastDynamicSnippets = new CheckCastDynamicSnippets.Templates(providers, runtime.getTarget()); - instanceofSnippets = new InstanceOfSnippets.Templates(providers, runtime.getTarget()); - newObjectSnippets = new NewObjectSnippets.Templates(providers, runtime.getTarget()); - monitorSnippets = new MonitorSnippets.Templates(providers, runtime.getTarget(), c.useFastLocking); - writeBarrierSnippets = new WriteBarrierSnippets.Templates(providers, runtime.getTarget()); - boxingSnippets = new BoxingSnippets.Templates(providers, runtime.getTarget()); - exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(providers, runtime.getTarget()); - unsafeLoadSnippets = new UnsafeLoadSnippets.Templates(providers, runtime.getTarget()); - - r.registerSnippetTemplateCache(new UnsafeArrayCopySnippets.Templates(providers, runtime.getTarget())); - } - - @Override - public void lower(Node n, LoweringTool tool) { - HotSpotVMConfig config = runtime.getConfig(); - StructuredGraph graph = (StructuredGraph) n.graph(); - - Kind wordKind = runtime.getTarget().wordKind; - if (n instanceof ArrayLengthNode) { - ArrayLengthNode arrayLengthNode = (ArrayLengthNode) n; - ValueNode array = arrayLengthNode.array(); - ReadNode arrayLengthRead = graph.add(new ReadNode(array, ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, config.arrayLengthOffset, graph), StampFactory.positiveInt(), - BarrierType.NONE, false)); - tool.createNullCheckGuard(arrayLengthRead, array); - graph.replaceFixedWithFixed(arrayLengthNode, arrayLengthRead); - } else if (n instanceof Invoke) { - Invoke invoke = (Invoke) n; - if (invoke.callTarget() instanceof MethodCallTargetNode) { - - MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget(); - NodeInputList parameters = callTarget.arguments(); - ValueNode receiver = parameters.size() <= 0 ? null : parameters.get(0); - GuardingNode receiverNullCheck = null; - if (!callTarget.isStatic() && receiver.stamp() instanceof ObjectStamp && !ObjectStamp.isObjectNonNull(receiver)) { - receiverNullCheck = tool.createNullCheckGuard(invoke, receiver); - } - JavaType[] signature = MetaUtil.signatureToTypes(callTarget.targetMethod().getSignature(), callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass()); - - LoweredCallTargetNode loweredCallTarget = null; - if (callTarget.invokeKind() == InvokeKind.Virtual && InlineVTableStubs.getValue() && (AlwaysInlineVTableStubs.getValue() || invoke.isPolymorphic())) { - - HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) callTarget.targetMethod(); - if (!hsMethod.getDeclaringClass().isInterface()) { - if (hsMethod.isInVirtualMethodTable()) { - int vtableEntryOffset = hsMethod.vtableEntryOffset(); - assert vtableEntryOffset > 0; - FloatingReadNode hub = createReadHub(graph, wordKind, receiver, receiverNullCheck); - - ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, hub, hsMethod); - // We use LocationNode.ANY_LOCATION for the reads that access the - // compiled code entry as HotSpot does not guarantee they are final - // values. - ReadNode compiledEntry = graph.add(new ReadNode(metaspaceMethod, ConstantLocationNode.create(ANY_LOCATION, wordKind, config.methodCompiledEntryOffset, graph), - StampFactory.forKind(wordKind), BarrierType.NONE, false)); - - loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(metaspaceMethod, compiledEntry, parameters, invoke.asNode().stamp(), signature, callTarget.targetMethod(), - CallingConvention.Type.JavaCall)); - - graph.addBeforeFixed(invoke.asNode(), metaspaceMethod); - graph.addAfterFixed(metaspaceMethod, compiledEntry); - } - } - } - - if (loweredCallTarget == null) { - loweredCallTarget = graph.add(new HotSpotDirectCallTargetNode(parameters, invoke.asNode().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall, - callTarget.invokeKind())); - } - callTarget.replaceAndDelete(loweredCallTarget); - } - } else if (n instanceof LoadFieldNode) { - LoadFieldNode loadField = (LoadFieldNode) n; - HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) loadField.field(); - ValueNode object = loadField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), metaAccess, graph) : loadField.object(); - assert loadField.kind() != Kind.Illegal; - BarrierType barrierType = getFieldLoadBarrierType(field); - ReadNode memoryRead = graph.add(new ReadNode(object, createFieldLocation(graph, field, false), loadField.stamp(), barrierType, (loadField.kind() == Kind.Object))); - graph.replaceFixedWithFixed(loadField, memoryRead); - tool.createNullCheckGuard(memoryRead, object); - - if (loadField.isVolatile()) { - MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_READ)); - graph.addBeforeFixed(memoryRead, preMembar); - MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_READ)); - graph.addAfterFixed(memoryRead, postMembar); - } - } else if (n instanceof StoreFieldNode) { - StoreFieldNode storeField = (StoreFieldNode) n; - HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field(); - ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), metaAccess, graph) : storeField.object(); - BarrierType barrierType = getFieldStoreBarrierType(storeField); - WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), createFieldLocation(graph, field, false), barrierType, storeField.field().getKind() == Kind.Object)); - tool.createNullCheckGuard(memoryWrite, object); - memoryWrite.setStateAfter(storeField.stateAfter()); - graph.replaceFixedWithFixed(storeField, memoryWrite); - FixedWithNextNode last = memoryWrite; - FixedWithNextNode first = memoryWrite; - - if (storeField.isVolatile()) { - MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_WRITE)); - graph.addBeforeFixed(first, preMembar); - MembarNode postMembar = graph.add(new MembarNode(JMM_POST_VOLATILE_WRITE)); - graph.addAfterFixed(last, postMembar); - } - } else if (n instanceof CompareAndSwapNode) { - // Separate out GC barrier semantics - CompareAndSwapNode cas = (CompareAndSwapNode) n; - LocationNode location = IndexedLocationNode.create(ANY_LOCATION, cas.expected().kind(), cas.displacement(), cas.offset(), graph, 1); - LoweredCompareAndSwapNode atomicNode = graph.add(new LoweredCompareAndSwapNode(cas.object(), location, cas.expected(), cas.newValue(), getCompareAndSwapBarrier(cas), - cas.expected().kind() == Kind.Object)); - atomicNode.setStateAfter(cas.stateAfter()); - graph.replaceFixedWithFixed(cas, atomicNode); - } else if (n instanceof LoadIndexedNode) { - LoadIndexedNode loadIndexed = (LoadIndexedNode) n; - GuardingNode boundsCheck = createBoundsCheck(loadIndexed, tool); - Kind elementKind = loadIndexed.elementKind(); - LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index(), false); - ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), arrayLocation, loadIndexed.stamp(), BarrierType.NONE, elementKind == Kind.Object)); - memoryRead.setGuard(boundsCheck); - graph.replaceFixedWithFixed(loadIndexed, memoryRead); - } else if (n instanceof StoreIndexedNode) { - StoreIndexedNode storeIndexed = (StoreIndexedNode) n; - GuardingNode boundsCheck = createBoundsCheck(storeIndexed, tool); - Kind elementKind = storeIndexed.elementKind(); - LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index(), false); - ValueNode value = storeIndexed.value(); - ValueNode array = storeIndexed.array(); - - CheckCastNode checkcastNode = null; - CheckCastDynamicNode checkcastDynamicNode = null; - if (elementKind == Kind.Object && !ObjectStamp.isObjectAlwaysNull(value)) { - // Store check! - ResolvedJavaType arrayType = ObjectStamp.typeOrNull(array); - if (arrayType != null && ObjectStamp.isExactType(array)) { - ResolvedJavaType elementType = arrayType.getComponentType(); - if (!MetaUtil.isJavaLangObject(elementType)) { - checkcastNode = graph.add(new CheckCastNode(elementType, value, null, true)); - graph.addBeforeFixed(storeIndexed, checkcastNode); - value = checkcastNode; - } - } else { - FloatingReadNode arrayClass = createReadHub(graph, wordKind, array, boundsCheck); - LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, config.arrayClassElementOffset, graph); - /* - * Anchor the read of the element klass to the cfg, because it is only valid - * when arrayClass is an object class, which might not be the case in other - * parts of the compiled method. - */ - FloatingReadNode arrayElementKlass = graph.unique(new FloatingReadNode(arrayClass, location, null, StampFactory.forKind(wordKind), BeginNode.prevBegin(storeIndexed))); - checkcastDynamicNode = graph.add(new CheckCastDynamicNode(arrayElementKlass, value, true)); - graph.addBeforeFixed(storeIndexed, checkcastDynamicNode); - value = checkcastDynamicNode; - } - } - BarrierType barrierType = getArrayStoreBarrierType(storeIndexed); - WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation, barrierType, elementKind == Kind.Object)); - memoryWrite.setGuard(boundsCheck); - memoryWrite.setStateAfter(storeIndexed.stateAfter()); - graph.replaceFixedWithFixed(storeIndexed, memoryWrite); - - // Lower the associated checkcast node. - if (checkcastNode != null) { - checkcastNode.lower(tool); - } else if (checkcastDynamicNode != null) { - checkcastDynamicSnippets.lower(checkcastDynamicNode); - } - } else if (n instanceof UnsafeLoadNode) { - UnsafeLoadNode load = (UnsafeLoadNode) n; - if (load.getGuardingCondition() != null) { - boolean compressible = (!load.object().isNullConstant() && load.accessKind() == Kind.Object); - ConditionAnchorNode valueAnchorNode = graph.add(new ConditionAnchorNode(load.getGuardingCondition())); - LocationNode location = createLocation(load); - ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp(), valueAnchorNode, BarrierType.NONE, compressible)); - load.replaceAtUsages(memoryRead); - graph.replaceFixedWithFixed(load, valueAnchorNode); - graph.addAfterFixed(valueAnchorNode, memoryRead); - } else if (graph.getGuardsStage().ordinal() > StructuredGraph.GuardsStage.FLOATING_GUARDS.ordinal()) { - assert load.kind() != Kind.Illegal; - boolean compressible = (!load.object().isNullConstant() && load.accessKind() == Kind.Object); - if (addReadBarrier(load)) { - unsafeLoadSnippets.lower(load, tool); - } else { - LocationNode location = createLocation(load); - ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp(), BarrierType.NONE, compressible)); - // An unsafe read must not float outside its block otherwise - // it may float above an explicit null check on its object. - memoryRead.setGuard(AbstractBeginNode.prevBegin(load)); - graph.replaceFixedWithFixed(load, memoryRead); - } - } - } else if (n instanceof UnsafeStoreNode) { - UnsafeStoreNode store = (UnsafeStoreNode) n; - LocationNode location = createLocation(store); - ValueNode object = store.object(); - BarrierType barrierType = getUnsafeStoreBarrierType(store); - WriteNode write = graph.add(new WriteNode(object, store.value(), location, barrierType, store.value().kind() == Kind.Object)); - write.setStateAfter(store.stateAfter()); - graph.replaceFixedWithFixed(store, write); - } else if (n instanceof LoadHubNode) { - LoadHubNode loadHub = (LoadHubNode) n; - assert loadHub.kind() == wordKind; - ValueNode object = loadHub.object(); - GuardingNode guard = loadHub.getGuard(); - FloatingReadNode hub = createReadHub(graph, wordKind, object, guard); - graph.replaceFloating(loadHub, hub); - } else if (n instanceof LoadMethodNode) { - LoadMethodNode loadMethodNode = (LoadMethodNode) n; - ResolvedJavaMethod method = loadMethodNode.getMethod(); - ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, loadMethodNode.getHub(), method); - graph.replaceFixed(loadMethodNode, metaspaceMethod); - } else if (n instanceof StoreHubNode) { - StoreHubNode storeHub = (StoreHubNode) n; - WriteNode hub = createWriteHub(graph, wordKind, storeHub.getObject(), storeHub.getValue()); - graph.replaceFixed(storeHub, hub); - } else if (n instanceof CommitAllocationNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { - CommitAllocationNode commit = (CommitAllocationNode) n; - - ValueNode[] allocations = new ValueNode[commit.getVirtualObjects().size()]; - for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) { - VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex); - int entryCount = virtual.entryCount(); - - FixedWithNextNode newObject; - if (virtual instanceof VirtualInstanceNode) { - newObject = graph.add(new NewInstanceNode(virtual.type(), true)); - } else { - ResolvedJavaType element = ((VirtualArrayNode) virtual).componentType(); - newObject = graph.add(new NewArrayNode(element, ConstantNode.forInt(entryCount, graph), true)); - } - graph.addBeforeFixed(commit, newObject); - allocations[objIndex] = newObject; - } - int valuePos = 0; - for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) { - VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex); - int entryCount = virtual.entryCount(); - - ValueNode newObject = allocations[objIndex]; - if (virtual instanceof VirtualInstanceNode) { - VirtualInstanceNode virtualInstance = (VirtualInstanceNode) virtual; - for (int i = 0; i < entryCount; i++) { - ValueNode value = commit.getValues().get(valuePos++); - if (value instanceof VirtualObjectNode) { - value = allocations[commit.getVirtualObjects().indexOf(value)]; - } - if (!(value.isConstant() && value.asConstant().isDefaultForKind())) { - WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) virtualInstance.field(i), true), - (virtualInstance.field(i).getKind() == Kind.Object && !deferInitBarrier(newObject)) ? BarrierType.IMPRECISE : BarrierType.NONE, - virtualInstance.field(i).getKind() == Kind.Object); - graph.addBeforeFixed(commit, graph.add(write)); - } - } +public interface HotSpotLoweringProvider extends LoweringProvider { - } else { - VirtualArrayNode array = (VirtualArrayNode) virtual; - ResolvedJavaType element = array.componentType(); - for (int i = 0; i < entryCount; i++) { - ValueNode value = commit.getValues().get(valuePos++); - if (value instanceof VirtualObjectNode) { - int indexOf = commit.getVirtualObjects().indexOf(value); - assert indexOf != -1 : commit + " " + value; - value = allocations[indexOf]; - } - if (!(value.isConstant() && value.asConstant().isDefaultForKind())) { - WriteNode write = new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph), true), - (value.kind() == Kind.Object && !deferInitBarrier(newObject)) ? BarrierType.PRECISE : BarrierType.NONE, value.kind() == Kind.Object); - graph.addBeforeFixed(commit, graph.add(write)); - } - } - } - } - for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) { - FixedValueAnchorNode anchor = graph.add(new FixedValueAnchorNode(allocations[objIndex])); - allocations[objIndex] = anchor; - graph.addBeforeFixed(commit, anchor); - } - for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) { - for (int lockDepth : commit.getLocks().get(objIndex)) { - MonitorEnterNode enter = graph.add(new MonitorEnterNode(allocations[objIndex], lockDepth)); - graph.addBeforeFixed(commit, enter); - enter.lower(tool); - } - } - for (Node usage : commit.usages().snapshot()) { - AllocatedObjectNode addObject = (AllocatedObjectNode) usage; - int index = commit.getVirtualObjects().indexOf(addObject.getVirtualObject()); - graph.replaceFloating(addObject, allocations[index]); - } - graph.removeFixed(commit); - } - } else if (n instanceof OSRStartNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { - OSRStartNode osrStart = (OSRStartNode) n; - StartNode newStart = graph.add(new StartNode()); - LocalNode buffer = graph.unique(new LocalNode(0, StampFactory.forKind(wordKind))); - ForeignCallNode migrationEnd = graph.add(new ForeignCallNode(foreignCalls, OSR_MIGRATION_END, buffer)); - migrationEnd.setStateAfter(osrStart.stateAfter()); - - newStart.setNext(migrationEnd); - FixedNode next = osrStart.next(); - osrStart.setNext(null); - migrationEnd.setNext(next); - graph.setStart(newStart); - - // mirroring the calculations in c1_GraphBuilder.cpp (setup_osr_entry_block) - int localsOffset = (graph.method().getMaxLocals() - 1) * 8; - for (OSRLocalNode osrLocal : graph.getNodes(OSRLocalNode.class)) { - int size = FrameStateBuilder.stackSlots(osrLocal.kind()); - int offset = localsOffset - (osrLocal.index() + size - 1) * 8; - IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, osrLocal.kind(), offset, ConstantNode.forLong(0, graph), graph, 1); - ReadNode load = graph.add(new ReadNode(buffer, location, osrLocal.stamp(), BarrierType.NONE, false)); - osrLocal.replaceAndDelete(load); - graph.addBeforeFixed(migrationEnd, load); - } - osrStart.replaceAtUsages(newStart); - osrStart.safeDelete(); - } - } else if (n instanceof DynamicCounterNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { - BenchmarkCounters.lower((DynamicCounterNode) n, runtime.getProviders().getRegisters(), runtime.getConfig(), wordKind); - } - } else if (n instanceof CheckCastDynamicNode) { - checkcastDynamicSnippets.lower((CheckCastDynamicNode) n); - } else if (n instanceof InstanceOfNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { - instanceofSnippets.lower((InstanceOfNode) n, tool); - } - } else if (n instanceof InstanceOfDynamicNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { - instanceofSnippets.lower((InstanceOfDynamicNode) n, tool); - } - } else if (n instanceof NewInstanceNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { - newObjectSnippets.lower((NewInstanceNode) n); - } - } else if (n instanceof NewArrayNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { - newObjectSnippets.lower((NewArrayNode) n); - } - } else if (n instanceof DynamicNewArrayNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { - newObjectSnippets.lower((DynamicNewArrayNode) n); - } - } else if (n instanceof MonitorEnterNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { - monitorSnippets.lower((MonitorEnterNode) n, tool); - } - } else if (n instanceof MonitorExitNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { - monitorSnippets.lower((MonitorExitNode) n, tool); - } - } else if (n instanceof G1PreWriteBarrier) { - writeBarrierSnippets.lower((G1PreWriteBarrier) n, tool); - } else if (n instanceof G1PostWriteBarrier) { - writeBarrierSnippets.lower((G1PostWriteBarrier) n, tool); - } else if (n instanceof G1ReferentFieldReadBarrier) { - writeBarrierSnippets.lower((G1ReferentFieldReadBarrier) n, tool); - } else if (n instanceof SerialWriteBarrier) { - writeBarrierSnippets.lower((SerialWriteBarrier) n, tool); - } else if (n instanceof SerialArrayRangeWriteBarrier) { - writeBarrierSnippets.lower((SerialArrayRangeWriteBarrier) n, tool); - } else if (n instanceof G1ArrayRangePreWriteBarrier) { - writeBarrierSnippets.lower((G1ArrayRangePreWriteBarrier) n, tool); - } else if (n instanceof G1ArrayRangePostWriteBarrier) { - writeBarrierSnippets.lower((G1ArrayRangePostWriteBarrier) n, tool); - } else if (n instanceof NewMultiArrayNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { - newObjectSnippets.lower((NewMultiArrayNode) n); - } - } else if (n instanceof LoadExceptionObjectNode) { - exceptionObjectSnippets.lower((LoadExceptionObjectNode) n); - } else if (n instanceof IntegerDivNode || n instanceof IntegerRemNode || n instanceof UnsignedDivNode || n instanceof UnsignedRemNode) { - // Nothing to do for division nodes. The HotSpot signal handler catches divisions by - // zero and the MIN_VALUE / -1 cases. - } else if (n instanceof BoxNode) { - boxingSnippets.lower((BoxNode) n, tool); - } else if (n instanceof UnboxNode) { - boxingSnippets.lower((UnboxNode) n, tool); - } else { - assert false : "Node implementing Lowerable not handled: " + n; - throw GraalInternalError.shouldNotReachHere(); - } - } - - private static LocationNode createLocation(UnsafeAccessNode access) { - ValueNode offset = access.offset(); - if (offset.isConstant()) { - long offsetValue = offset.asConstant().asLong(); - return ConstantLocationNode.create(access.getLocationIdentity(), access.accessKind(), offsetValue, access.graph()); - } - - long displacement = 0; - int indexScaling = 1; - if (offset instanceof IntegerAddNode) { - IntegerAddNode integerAddNode = (IntegerAddNode) offset; - if (integerAddNode.y() instanceof ConstantNode) { - displacement = integerAddNode.y().asConstant().asLong(); - offset = integerAddNode.x(); - } - } - - if (offset instanceof LeftShiftNode) { - LeftShiftNode leftShiftNode = (LeftShiftNode) offset; - if (leftShiftNode.y() instanceof ConstantNode) { - long shift = leftShiftNode.y().asConstant().asLong(); - if (shift >= 1 && shift <= 3) { - if (shift == 1) { - indexScaling = 2; - } else if (shift == 2) { - indexScaling = 4; - } else { - indexScaling = 8; - } - offset = leftShiftNode.x(); - } - } - } + void initialize(HotSpotProviders providers, HotSpotVMConfig config); - return IndexedLocationNode.create(access.getLocationIdentity(), access.accessKind(), displacement, offset, access.graph(), indexScaling); - } - - private static boolean addReadBarrier(UnsafeLoadNode load) { - if (useG1GC() && load.graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS && load.object().kind() == Kind.Object && load.accessKind() == Kind.Object && - !ObjectStamp.isObjectAlwaysNull(load.object())) { - ResolvedJavaType type = ObjectStamp.typeOrNull(load.object()); - if (type != null && !type.isArray()) { - return true; - } - } - return false; - } - - private static ReadNode createReadVirtualMethod(StructuredGraph graph, Kind wordKind, ValueNode hub, ResolvedJavaMethod method) { - HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method; - assert !hsMethod.getDeclaringClass().isInterface(); - assert hsMethod.isInVirtualMethodTable(); - - int vtableEntryOffset = hsMethod.vtableEntryOffset(); - assert vtableEntryOffset > 0; - // We use LocationNode.ANY_LOCATION for the reads that access the vtable - // entry as HotSpot does not guarantee that this is a final value. - ReadNode metaspaceMethod = graph.add(new ReadNode(hub, ConstantLocationNode.create(ANY_LOCATION, wordKind, vtableEntryOffset, graph), StampFactory.forKind(wordKind), BarrierType.NONE, false)); - return metaspaceMethod; - } - - private FloatingReadNode createReadHub(StructuredGraph graph, Kind wordKind, ValueNode object, GuardingNode guard) { - HotSpotVMConfig config = runtime.getConfig(); - LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, config.hubOffset, graph); - assert !object.isConstant() || object.asConstant().isNull(); - return graph.unique(new FloatingReadNode(object, location, null, StampFactory.forKind(wordKind), guard, BarrierType.NONE, config.useCompressedClassPointers)); - } - - private WriteNode createWriteHub(StructuredGraph graph, Kind wordKind, ValueNode object, ValueNode value) { - HotSpotVMConfig config = runtime.getConfig(); - LocationNode location = ConstantLocationNode.create(HUB_LOCATION, wordKind, config.hubOffset, graph); - assert !object.isConstant() || object.asConstant().isNull(); - return graph.add(new WriteNode(object, value, location, BarrierType.NONE, config.useCompressedClassPointers)); - } - - private static BarrierType getFieldLoadBarrierType(HotSpotResolvedJavaField loadField) { - BarrierType barrierType = BarrierType.NONE; - if (config().useG1GC && loadField.getKind() == Kind.Object && loadField.getDeclaringClass().mirror() == java.lang.ref.Reference.class && loadField.getName().equals("referent")) { - barrierType = BarrierType.PRECISE; - } - return barrierType; - } - - private static BarrierType getFieldStoreBarrierType(StoreFieldNode storeField) { - BarrierType barrierType = BarrierType.NONE; - if (storeField.field().getKind() == Kind.Object && !deferInitBarrier(storeField.object())) { - barrierType = BarrierType.IMPRECISE; - } - return barrierType; - } - - private static BarrierType getArrayStoreBarrierType(StoreIndexedNode store) { - BarrierType barrierType = BarrierType.NONE; - if (store.elementKind() == Kind.Object && !deferInitBarrier(store.array())) { - barrierType = BarrierType.PRECISE; - } - return barrierType; - } - - private static boolean deferInitBarrier(ValueNode object) { - return useDeferredInitBarriers() && (object instanceof NewInstanceNode || object instanceof NewArrayNode); - } - - private static BarrierType getUnsafeStoreBarrierType(UnsafeStoreNode store) { - BarrierType barrierType = BarrierType.NONE; - if (store.value().kind() == Kind.Object) { - ResolvedJavaType type = ObjectStamp.typeOrNull(store.object()); - if (type != null && !type.isArray()) { - barrierType = BarrierType.IMPRECISE; - } else { - barrierType = BarrierType.PRECISE; - } - } - return barrierType; - } - - private static BarrierType getCompareAndSwapBarrier(CompareAndSwapNode cas) { - BarrierType barrierType = BarrierType.NONE; - if (cas.expected().kind() == Kind.Object) { - ResolvedJavaType type = ObjectStamp.typeOrNull(cas.object()); - if (type != null && !type.isArray()) { - barrierType = BarrierType.IMPRECISE; - } else { - barrierType = BarrierType.PRECISE; - } - } - return barrierType; - } - - protected static ConstantLocationNode createFieldLocation(StructuredGraph graph, HotSpotResolvedJavaField field, boolean initialization) { - LocationIdentity loc = initialization ? INIT_LOCATION : field; - return ConstantLocationNode.create(loc, field.getKind(), field.offset(), graph); - } - - public int getScalingFactor(Kind kind) { - if (useCompressedOops() && kind == Kind.Object) { - return this.runtime.getTarget().arch.getSizeInBytes(Kind.Int); - } else { - return this.runtime.getTarget().arch.getSizeInBytes(kind); - } - } - - protected IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index, boolean initialization) { - LocationIdentity loc = initialization ? INIT_LOCATION : NamedLocationIdentity.getArrayLocation(elementKind); - int scale = getScalingFactor(elementKind); - return IndexedLocationNode.create(loc, elementKind, getArrayBaseOffset(elementKind), index, graph, scale); - } - - @Override - public ValueNode reconstructArrayIndex(LocationNode location) { - Kind elementKind = location.getValueKind(); - assert location.getLocationIdentity().equals(NamedLocationIdentity.getArrayLocation(elementKind)); - - long base; - ValueNode index; - int scale = getScalingFactor(elementKind); - - if (location instanceof ConstantLocationNode) { - base = ((ConstantLocationNode) location).getDisplacement(); - index = null; - } else if (location instanceof IndexedLocationNode) { - IndexedLocationNode indexedLocation = (IndexedLocationNode) location; - assert indexedLocation.getIndexScaling() == scale; - base = indexedLocation.getDisplacement(); - index = indexedLocation.getIndex(); - } else { - throw GraalInternalError.shouldNotReachHere(); - } - - base -= getArrayBaseOffset(elementKind); - assert base >= 0 && base % scale == 0; - - base /= scale; - assert NumUtil.isInt(base); - - if (index == null) { - return ConstantNode.forInt((int) base, location.graph()); - } else { - if (base == 0) { - return index; - } else { - return IntegerArithmeticNode.add(ConstantNode.forInt((int) base, location.graph()), index); - } - } - } - - private GuardingNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) { - StructuredGraph g = n.graph(); - ValueNode array = n.array(); - ValueNode arrayLength = readArrayLength(array, tool.getConstantReflection()); - if (arrayLength == null) { - Stamp stamp = StampFactory.positiveInt(); - ReadNode readArrayLength = g.add(new ReadNode(array, ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, runtime.getConfig().arrayLengthOffset, g), stamp, BarrierType.NONE, false)); - g.addBeforeFixed(n, readArrayLength); - tool.createNullCheckGuard(readArrayLength, array); - arrayLength = readArrayLength; - } - - return tool.createGuard(g.unique(new IntegerBelowThanNode(n.index(), arrayLength)), BoundsCheckException, InvalidateReprofile); - } - + int getScalingFactor(Kind elementKind); } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Thu Oct 17 16:01:04 2013 +0200 @@ -78,7 +78,7 @@ } public int getDeoptimizationCount(DeoptimizationReason reason) { - int reasonIndex = runtime().getProviders().getMetaAccess().convertDeoptReason(reason); + int reasonIndex = runtime().getHostProviders().getMetaAccess().convertDeoptReason(reason); return unsafe.getByte(metaspaceMethodData + config.methodDataOopTrapHistoryOffset + reasonIndex) & 0xFF; } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Thu Oct 17 16:01:04 2013 +0200 @@ -92,7 +92,7 @@ * only called for snippets or replacements. */ private static boolean isCalledForSnippets() { - MetaAccessProvider metaAccess = runtime().getProviders().getMetaAccess(); + MetaAccessProvider metaAccess = runtime().getHostProviders().getMetaAccess(); ResolvedJavaMethod makeGraphMethod = null; ResolvedJavaMethod initMethod = null; try { @@ -119,7 +119,7 @@ private static final Set notEmbeddable = new HashSet<>(); private static void addResolvedToSet(Field field) { - MetaAccessProvider metaAccess = runtime().getProviders().getMetaAccess(); + MetaAccessProvider metaAccess = runtime().getHostProviders().getMetaAccess(); notEmbeddable.add(metaAccess.lookupJavaField(field)); } @@ -216,12 +216,12 @@ if (receiver == null) { assert Modifier.isStatic(flags); if (holder.isInitialized()) { - return runtime().getProviders().getConstantReflection().readUnsafeConstant(getKind(), holder.mirror(), offset, getKind() == Kind.Object); + return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), holder.mirror(), offset, getKind() == Kind.Object); } return null; } else { assert !Modifier.isStatic(flags); - return runtime().getProviders().getConstantReflection().readUnsafeConstant(getKind(), receiver.asObject(), offset, getKind() == Kind.Object); + return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), receiver.asObject(), offset, getKind() == Kind.Object); } } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Thu Oct 17 16:01:04 2013 +0200 @@ -113,7 +113,7 @@ * Gets the address of the C++ Method object for this method. */ public Constant getMetaspaceMethodConstant() { - return Constant.forIntegerKind(runtime().getTarget().wordKind, metaspaceMethod, this); + return Constant.forIntegerKind(getHostWordKind(), metaspaceMethod, this); } @Override @@ -343,7 +343,7 @@ // Cannot use toJava() as it ignores the return type HotSpotSignature sig = getSignature(); JavaType[] sigTypes = MetaUtil.signatureToTypes(sig, null); - MetaAccessProvider metaAccess = runtime().getProviders().getMetaAccess(); + MetaAccessProvider metaAccess = runtime().getHostProviders().getMetaAccess(); for (Method method : holder.mirror().getDeclaredMethods()) { if (method.getName().equals(name)) { if (metaAccess.lookupJavaType(method.getReturnType()).equals(sig.getReturnType(holder))) { diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Thu Oct 17 16:01:04 2013 +0200 @@ -544,7 +544,7 @@ Constructor[] constructors = javaMirror.getDeclaredConstructors(); ResolvedJavaMethod[] result = new ResolvedJavaMethod[constructors.length]; for (int i = 0; i < constructors.length; i++) { - result[i] = runtime().getProviders().getMetaAccess().lookupJavaConstructor(constructors[i]); + result[i] = runtime().getHostProviders().getMetaAccess().lookupJavaConstructor(constructors[i]); assert result[i].isConstructor(); } return result; @@ -555,7 +555,7 @@ Method[] methods = javaMirror.getDeclaredMethods(); ResolvedJavaMethod[] result = new ResolvedJavaMethod[methods.length]; for (int i = 0; i < methods.length; i++) { - result[i] = runtime().getProviders().getMetaAccess().lookupJavaMethod(methods[i]); + result[i] = runtime().getHostProviders().getMetaAccess().lookupJavaMethod(methods[i]); assert !result[i].isConstructor(); } return result; diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentJavaThreadNode.java Thu Oct 17 16:01:04 2013 +0200 @@ -41,7 +41,7 @@ @Override public void generate(LIRGeneratorTool gen) { - Register rawThread = runtime().getProviders().getRegisters().getThreadRegister(); + Register rawThread = runtime().getHostProviders().getRegisters().getThreadRegister(); gen.setResult(this, rawThread.asValue(this.kind())); } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Thu Oct 17 16:01:04 2013 +0200 @@ -24,7 +24,7 @@ import static com.oracle.graal.graph.UnsafeAccess.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import static com.oracle.graal.hotspot.meta.HotSpotForeignCallsProvider.*; +import static com.oracle.graal.hotspot.meta.HotSpotHostForeignCallsProvider.*; import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import sun.misc.*; @@ -203,12 +203,12 @@ @Fold public static Register threadRegister() { - return runtime().getProviders().getRegisters().getThreadRegister(); + return runtime().getHostProviders().getRegisters().getThreadRegister(); } @Fold public static Register stackPointerRegister() { - return runtime().getProviders().getRegisters().getStackPointerRegister(); + return runtime().getHostProviders().getRegisters().getStackPointerRegister(); } @Fold diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java Thu Oct 17 16:01:04 2013 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.replacements; -import static com.oracle.graal.hotspot.meta.HotSpotForeignCallsProvider.*; +import static com.oracle.graal.hotspot.meta.HotSpotHostForeignCallsProvider.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.nodes.PiNode.*; import static com.oracle.graal.replacements.SnippetTemplate.*; diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Thu Oct 17 16:01:04 2013 +0200 @@ -84,11 +84,13 @@ */ public ForeignCallStub(HotSpotProviders providers, long address, ForeignCallDescriptor descriptor, boolean prependThread, Transition transition, boolean reexecutable, LocationIdentity... killedLocations) { - super(providers, HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations)); + super(providers, HotSpotForeignCallLinkage.create(providers.getMetaAccess(), providers.getCodeCache(), providers.getForeignCalls(), descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, + transition, reexecutable, killedLocations)); this.prependThread = prependThread; Class[] targetParameterTypes = createTargetParameters(descriptor); ForeignCallDescriptor targetSig = new ForeignCallDescriptor(descriptor.getName() + ":C", descriptor.getResultType(), targetParameterTypes); - target = HotSpotForeignCallLinkage.create(targetSig, address, DESTROYS_REGISTERS, NativeCall, NativeCall, transition, reexecutable, killedLocations); + target = HotSpotForeignCallLinkage.create(providers.getMetaAccess(), providers.getCodeCache(), providers.getForeignCalls(), targetSig, address, DESTROYS_REGISTERS, NativeCall, NativeCall, + transition, reexecutable, killedLocations); } /** diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java Thu Oct 17 16:01:04 2013 +0200 @@ -30,7 +30,7 @@ import com.oracle.graal.replacements.*; /** - * Stub called via {@link HotSpotForeignCallsProvider#VERIFY_OOP}. + * Stub called via {@link HotSpotHostForeignCallsProvider#VERIFY_OOP}. */ public class VerifyOopStub extends SnippetStub { diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/NegateNodeCanonicalizationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/NegateNodeCanonicalizationTest.java Thu Oct 17 16:01:04 2013 +0200 @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes.test; + +import static org.junit.Assert.*; + +import org.junit.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; + +/** + * This class tests that the canonicalization for constant negate nodes cover all cases. + */ +public class NegateNodeCanonicalizationTest { + + private StructuredGraph graph; + + @Before + public void before() { + graph = new StructuredGraph(); + } + + @Test + public void testByte() { + byte[] a = new byte[]{Byte.MIN_VALUE, Byte.MIN_VALUE + 1, -1, 0, 1, Byte.MAX_VALUE - 1, Byte.MAX_VALUE}; + for (byte i : a) { + ConstantNode node = ConstantNode.forByte(i, graph); + Constant expected = Constant.forInt(-i); + assertEquals(expected, new NegateNode(node).evalConst(node.asConstant())); + } + } + + @Test + public void testChar() { + char[] a = new char[]{Character.MIN_VALUE, Character.MIN_VALUE + 1, 0, 1, Character.MAX_VALUE - 1, Character.MAX_VALUE}; + for (char i : a) { + ConstantNode node = ConstantNode.forChar(i, graph); + Constant expected = Constant.forInt(-i); + assertEquals(expected, new NegateNode(node).evalConst(node.asConstant())); + } + } + + @Test + public void testShort() { + short[] a = new short[]{Short.MIN_VALUE, Short.MIN_VALUE + 1, -1, 0, 1, Short.MAX_VALUE - 1, Short.MAX_VALUE}; + for (short i : a) { + ConstantNode node = ConstantNode.forShort(i, graph); + Constant expected = Constant.forInt(-i); + assertEquals(expected, new NegateNode(node).evalConst(node.asConstant())); + } + } + + @Test + public void testInt() { + int[] a = new int[]{Integer.MIN_VALUE, Integer.MIN_VALUE + 1, -1, 0, 1, Integer.MAX_VALUE - 1, Integer.MAX_VALUE}; + for (int i : a) { + ConstantNode node = ConstantNode.forInt(i, graph); + Constant expected = Constant.forInt(-i); + assertEquals(expected, new NegateNode(node).evalConst(node.asConstant())); + } + } + + @Test + public void testLong() { + long[] a = new long[]{Long.MIN_VALUE, Long.MIN_VALUE + 1, -1, 0, 1, Long.MAX_VALUE - 1, Long.MAX_VALUE}; + for (long i : a) { + ConstantNode node = ConstantNode.forLong(i, graph); + Constant expected = Constant.forLong(-i); + assertEquals(expected, new NegateNode(node).evalConst(node.asConstant())); + } + } + + @Test + public void testFloat() { + float[] a = new float[]{Float.MIN_VALUE, Float.MIN_VALUE + 1, -1, 0, 1, Float.MAX_VALUE - 1, Float.MAX_VALUE}; + for (float i : a) { + ConstantNode node = ConstantNode.forFloat(i, graph); + Constant expected = Constant.forFloat(-i); + assertEquals(expected, new NegateNode(node).evalConst(node.asConstant())); + } + } + + @Test + public void testDouble() { + double[] a = new double[]{Double.MIN_VALUE, Double.MIN_VALUE + 1, -1, 0, 1, Double.MAX_VALUE - 1, Double.MAX_VALUE}; + for (double i : a) { + ConstantNode node = ConstantNode.forDouble(i, graph); + Constant expected = Constant.forDouble(-i); + assertEquals(expected, new NegateNode(node).evalConst(node.asConstant())); + } + } + +} diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java Thu Oct 17 16:01:04 2013 +0200 @@ -57,17 +57,18 @@ public Constant evalConst(Constant... inputs) { assert inputs.length == 1; - switch (inputs[0].getKind()) { + Constant constant = inputs[0]; + switch (constant.getKind()) { case Int: - return Constant.forInt(-inputs[0].asInt()); + return Constant.forInt(-(constant.asInt())); case Long: - return Constant.forLong(-inputs[0].asLong()); + return Constant.forLong(-(constant.asLong())); case Float: - return Constant.forFloat(-inputs[0].asFloat()); + return Constant.forFloat(-(constant.asFloat())); case Double: - return Constant.forDouble(-inputs[0].asDouble()); + return Constant.forDouble(-(constant.asDouble())); default: - throw GraalInternalError.shouldNotReachHere(); + throw GraalInternalError.shouldNotReachHere("unknown kind " + constant.getKind()); } } diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/EscapeObjectState.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/EscapeObjectState.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/EscapeObjectState.java Thu Oct 17 16:01:04 2013 +0200 @@ -22,9 +22,10 @@ */ package com.oracle.graal.nodes.virtual; +import com.oracle.graal.graph.Node.*; import com.oracle.graal.nodes.*; -public abstract class EscapeObjectState extends VirtualState { +public abstract class EscapeObjectState extends VirtualState implements ValueNumberable { @Input private VirtualObjectNode object; diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/CompiledExceptionHandlerTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/CompiledExceptionHandlerTest.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/CompiledExceptionHandlerTest.java Thu Oct 17 16:01:04 2013 +0200 @@ -37,7 +37,7 @@ public class CompiledExceptionHandlerTest extends GraalCompilerTest { public CompiledExceptionHandlerTest() { - suites.getHighTier().findPhase(AbstractInliningPhase.class).remove(); + getSuites().getHighTier().findPhase(AbstractInliningPhase.class).remove(); } @Override diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DeoptimizeOnExceptionTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DeoptimizeOnExceptionTest.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/DeoptimizeOnExceptionTest.java Thu Oct 17 16:01:04 2013 +0200 @@ -33,7 +33,7 @@ public class DeoptimizeOnExceptionTest extends GraalCompilerTest { public DeoptimizeOnExceptionTest() { - suites.getHighTier().findPhase(AbstractInliningPhase.class).remove(); + getSuites().getHighTier().findPhase(AbstractInliningPhase.class).remove(); } private static void raiseException(String m1, String m2, String m3, String m4, String m5) { diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InstanceOfTest.java Thu Oct 17 16:01:04 2013 +0200 @@ -42,7 +42,7 @@ public class InstanceOfTest extends TypeCheckTest { public InstanceOfTest() { - suites.getHighTier().findPhase(AbstractInliningPhase.class).remove(); + getSuites().getHighTier().findPhase(AbstractInliningPhase.class).remove(); } @Override diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InvokeTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InvokeTest.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/InvokeTest.java Thu Oct 17 16:01:04 2013 +0200 @@ -33,7 +33,7 @@ public class InvokeTest extends GraalCompilerTest { public InvokeTest() { - suites.getHighTier().findPhase(AbstractInliningPhase.class).remove(); + getSuites().getHighTier().findPhase(AbstractInliningPhase.class).remove(); } public interface I { diff -r 561217cf2ac5 -r 890bea7925fd graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Thu Oct 17 15:59:12 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Thu Oct 17 16:01:04 2013 +0200 @@ -178,7 +178,7 @@ stateAfter.virtualObjectMappings().remove(i); } } - stateAfter.addVirtualObjectMapping(graph.addWithoutUnique(state)); + stateAfter.addVirtualObjectMapping(graph.unique(state)); } @Override diff -r 561217cf2ac5 -r 890bea7925fd mx/projects --- a/mx/projects Thu Oct 17 15:59:12 2013 +0200 +++ b/mx/projects Thu Oct 17 16:01:04 2013 +0200 @@ -28,7 +28,13 @@ library@OKRA@urls=http://cr.openjdk.java.net/~tdeneau/okra-1.2.jar distribution@GRAAL@path=graal.jar -distribution@GRAAL@dependencies=com.oracle.graal.hotspot.amd64,com.oracle.graal.hotspot.ptx,com.oracle.graal.truffle,com.oracle.graal.hotspot.sparc,com.oracle.graal.hotspot,com.oracle.graal.compiler.hsail +distribution@GRAAL@dependencies=\ +com.oracle.graal.hotspot.amd64,\ +com.oracle.graal.hotspot.ptx,\ +com.oracle.graal.truffle,\ +com.oracle.graal.hotspot.sparc,\ +com.oracle.graal.hotspot,\ +com.oracle.graal.hotspot.hsail # graal.api.runtime project@com.oracle.graal.api.runtime@subDir=graal @@ -137,7 +143,7 @@ # graal.hotspot.ptx project@com.oracle.graal.hotspot.ptx@subDir=graal project@com.oracle.graal.hotspot.ptx@sourceDirs=src -project@com.oracle.graal.hotspot.ptx@dependencies=com.oracle.graal.hotspot,com.oracle.graal.ptx +project@com.oracle.graal.hotspot.ptx@dependencies=com.oracle.graal.ptx,com.oracle.graal.compiler.ptx project@com.oracle.graal.hotspot.ptx@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hotspot.ptx@annotationProcessors=com.oracle.graal.service.processor project@com.oracle.graal.hotspot.ptx@javaCompliance=1.7 @@ -387,7 +393,7 @@ # graal.compiler.ptx.test project@com.oracle.graal.compiler.ptx.test@subDir=graal project@com.oracle.graal.compiler.ptx.test@sourceDirs=src -project@com.oracle.graal.compiler.ptx.test@dependencies=com.oracle.graal.hotspot.ptx,com.oracle.graal.compiler.ptx,com.oracle.graal.compiler.test +project@com.oracle.graal.compiler.ptx.test@dependencies=com.oracle.graal.hotspot.ptx,com.oracle.graal.compiler.test project@com.oracle.graal.compiler.ptx.test@checkstyle=com.oracle.graal.graph project@com.oracle.graal.compiler.ptx.test@javaCompliance=1.7 project@com.oracle.graal.compiler.ptx.test@workingSets=Graal,PTX,Test diff -r 561217cf2ac5 -r 890bea7925fd mxtool/mx.py --- a/mxtool/mx.py Thu Oct 17 15:59:12 2013 +0200 +++ b/mxtool/mx.py Thu Oct 17 16:01:04 2013 +0200 @@ -526,8 +526,15 @@ raise KeyError with open(projectsFile) as f: + prefix = '' for line in f: line = line.strip() + if line.endswith('\\'): + prefix = prefix + line[:-1] + continue + if len(prefix) != 0: + line = prefix + line + prefix = '' if len(line) != 0 and line[0] != '#': key, value = line.split('=', 1) diff -r 561217cf2ac5 -r 890bea7925fd src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Thu Oct 17 15:59:12 2013 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Thu Oct 17 16:01:04 2013 +0200 @@ -314,9 +314,6 @@ template(com_oracle_graal_hotspot_meta_HotSpotMonitorValue, "com/oracle/graal/hotspot/meta/HotSpotMonitorValue") \ template(com_oracle_graal_hotspot_debug_LocalImpl, "com/oracle/graal/hotspot/debug/LocalImpl") \ template(com_oracle_graal_hotspot_CompilerThread, "com/oracle/graal/hotspot/CompilerThread") \ - template(com_oracle_graal_hotspot_ptx_PTXHotSpotGraalRuntime, "com/oracle/graal/hotspot/ptx/PTXHotSpotGraalRuntime")\ - AMD64_ONLY(template(com_oracle_graal_hotspot_amd64_AMD64HotSpotGraalRuntime,"com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime"))\ - SPARC_ONLY(template(com_oracle_graal_hotspot_sparc_SPARCHotSpotGraalRuntime,"com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime"))\ /* 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") \ @@ -387,11 +384,11 @@ template(createConstantObject_signature, "(Ljava/lang/Object;)Lcom/oracle/graal/api/meta/Constant;") \ template(getVMToCompiler_name, "getVMToCompiler") \ template(getVMToCompiler_signature, "()Lcom/oracle/graal/hotspot/bridge/VMToCompiler;") \ - template(getInstance_name, "getInstance") \ - template(getTruffleRuntimeInstance_signature, "()Lcom/oracle/graal/truffle/GraalTruffleRuntime;") \ + template(runtime_name, "runtime") \ + template(runtime_signature, "()Lcom/oracle/graal/hotspot/HotSpotGraalRuntime;") \ template(makeInstance_name, "makeInstance") \ + template(makeInstance_signature, "()Lcom/oracle/graal/truffle/GraalTruffleRuntime;") \ template(initialize_name, "initialize") \ - template(getInstance_signature, "()Lcom/oracle/graal/hotspot/HotSpotGraalRuntime;") \ template(forObject_name, "forObject") \ template(callbackInternal_name, "callbackInternal") \ template(callback_signature, "(Ljava/lang/Object;)Ljava/lang/Object;") \ diff -r 561217cf2ac5 -r 890bea7925fd src/share/vm/graal/graalCompilerToGPU.cpp --- a/src/share/vm/graal/graalCompilerToGPU.cpp Thu Oct 17 15:59:12 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToGPU.cpp Thu Oct 17 16:01:04 2013 +0200 @@ -23,6 +23,7 @@ #include "precompiled.hpp" +#include "memory/oopFactory.hpp" #include "graal/graalCompiler.hpp" #include "graal/graalEnv.hpp" #include "graal/graalJavaAccess.hpp" @@ -189,6 +190,29 @@ return gpu::available_processors(); C2V_END +static objArrayHandle newSingletonStringArray(const char* value, TRAPS) { + objArrayHandle nullRes; + objArrayOop res = oopFactory::new_objArray(SystemDictionary::String_klass(), 1, CHECK_(nullRes)); + objArrayHandle res_h = objArrayHandle(THREAD, res); + Handle valueString = java_lang_String::create_from_str(value, CHECK_(nullRes)); + res_h->obj_at_put(0, valueString()); + return res_h; +} + +C2V_VMENTRY(jobject, getAvailableGPUArchitectures, (JNIEnv *env, jobject)) + if (UseGPU) { + if (gpu::is_available() && gpu::has_gpu_linkage()) { + if (gpu::get_target_il_type() == gpu::PTX) { + return JNIHandles::make_local(newSingletonStringArray("PTX", THREAD)()); + } + if (gpu::get_target_il_type() == gpu::HSAIL) { + return JNIHandles::make_local(newSingletonStringArray("HSAIL", THREAD)()); + } + } + } + return JNIHandles::make_local(oopFactory::new_objArray(SystemDictionary::String_klass(), 0, THREAD)); +C2V_END + C2V_VMENTRY(jboolean, deviceDetach, (JNIEnv *env, jobject)) return true; C2V_END @@ -205,7 +229,7 @@ #define CONSTANT_POOL "Lcom/oracle/graal/api/meta/ConstantPool;" #define CONSTANT "Lcom/oracle/graal/api/meta/Constant;" #define KIND "Lcom/oracle/graal/api/meta/Kind;" -#define LOCAL "Lcom/oracle/graal/api/meta/Local;" +#define LOCAL "Lcom/oracle/graal/api/meta/Local;" #define RUNTIME_CALL "Lcom/oracle/graal/api/code/RuntimeCall;" #define EXCEPTION_HANDLERS "[Lcom/oracle/graal/api/meta/ExceptionHandler;" #define REFLECT_METHOD "Ljava/lang/reflect/Method;" @@ -234,6 +258,7 @@ {CC"deviceInit", CC"()Z", FN_PTR(deviceInit)}, {CC"deviceDetach", CC"()Z", FN_PTR(deviceDetach)}, {CC"availableProcessors", CC"()I", FN_PTR(availableProcessors)}, + {CC"getAvailableGPUArchitectures", CC"()["STRING, FN_PTR(getAvailableGPUArchitectures)}, {CC"executeExternalMethodVarargs", CC"(["OBJECT HS_INSTALLED_CODE")"OBJECT, FN_PTR(executeExternalMethodVarargs)}, {CC"executeParallelMethodVarargs", CC"(III["OBJECT HS_INSTALLED_CODE")"OBJECT, FN_PTR(executeParallelMethodVarargs)}, }; diff -r 561217cf2ac5 -r 890bea7925fd src/share/vm/graal/graalVMToCompiler.cpp --- a/src/share/vm/graal/graalVMToCompiler.cpp Thu Oct 17 15:59:12 2013 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.cpp Thu Oct 17 16:01:04 2013 +0200 @@ -53,32 +53,16 @@ KlassHandle klass = loadClass(name); JavaValue result(T_OBJECT); - JavaCalls::call_static(&result, klass, vmSymbols::makeInstance_name(), vmSymbols::getTruffleRuntimeInstance_signature(), Thread::current()); + JavaCalls::call_static(&result, klass, vmSymbols::makeInstance_name(), vmSymbols::makeInstance_signature(), Thread::current()); check_pending_exception("Couldn't initialize GraalTruffleRuntime"); return Handle((oop) result.get_jobject()); } Handle VMToCompiler::graalRuntime() { if (JNIHandles::resolve(_graalRuntimePermObject) == NULL) { -#ifdef AMD64 - Symbol* name = NULL; - // Set name to PTXHotSpotRuntime if nVidia GPU was detected. - if (UseGPU && (gpu::get_target_il_type() == gpu::PTX) && - gpu::is_available() && gpu::has_gpu_linkage()) { - name = vmSymbols::com_oracle_graal_hotspot_ptx_PTXHotSpotGraalRuntime(); - } - - if (name == NULL) { - name = vmSymbols::com_oracle_graal_hotspot_amd64_AMD64HotSpotGraalRuntime(); - } -#endif -#ifdef SPARC - Symbol* name = vmSymbols::com_oracle_graal_hotspot_sparc_SPARCHotSpotGraalRuntime(); -#endif - KlassHandle klass = loadClass(name); - + KlassHandle klass = loadClass(vmSymbols::com_oracle_graal_hotspot_HotSpotGraalRuntime()); JavaValue result(T_OBJECT); - JavaCalls::call_static(&result, klass, vmSymbols::makeInstance_name(), vmSymbols::getInstance_signature(), Thread::current()); + JavaCalls::call_static(&result, klass, vmSymbols::runtime_name(), vmSymbols::runtime_signature(), Thread::current()); check_pending_exception("Couldn't initialize HotSpotGraalRuntime"); _graalRuntimePermObject = JNIHandles::make_global((oop) result.get_jobject()); }