# HG changeset patch # User Michael Van De Vanter # Date 1427854545 25200 # Node ID 2c65cac3d9403994050fa0bf0c8f65084659bd86 # Parent 2e3cc2a277110851a6079fa35b4c5910e9d2d06a# Parent 7815c4d4a07f92d10d27a180f32e0dbc8ca15d44 Merge with 7815c4d4a07f92d10d27a180f32e0dbc8ca15d44 diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/TriState.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/TriState.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/TriState.java Tue Mar 31 19:15:45 2015 -0700 @@ -23,7 +23,7 @@ package com.oracle.graal.api.meta; /** - * Represents the three possibilities that an exception was seen at a specific BCI. + * Represents a logic value that can be either {@link #TRUE}, {@link #FALSE}, or {@link #UNKNOWN}. */ public enum TriState { TRUE, diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/IncrementDecrementMacroTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/IncrementDecrementMacroTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2015, 2015, 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.asm.amd64.test; + +import static com.oracle.graal.api.code.ValueUtil.*; +import static com.oracle.graal.compiler.common.UnsafeAccess.*; +import static org.junit.Assume.*; + +import java.lang.reflect.*; + +import org.junit.*; + +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.asm.test.*; + +public class IncrementDecrementMacroTest extends AssemblerTest { + + @Before + public void checkAMD64() { + assumeTrue("skipping AMD64 specific test", codeCache.getTarget().arch instanceof AMD64); + } + + public static class LongField { + public long x; + + LongField(long x) { + this.x = x; + } + } + + private static class IncrementCodeGenTest implements CodeGenTest { + final int value; + + public IncrementCodeGenTest(int value) { + this.value = value; + } + + @Override + public byte[] generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) { + AMD64MacroAssembler asm = new AMD64MacroAssembler(target, registerConfig); + Register ret = registerConfig.getReturnRegister(Kind.Int); + try { + Field f = LongField.class.getDeclaredField("x"); + AMD64Address arg = new AMD64Address(asRegister(cc.getArgument(0)), (int) unsafe.objectFieldOffset(f)); + asm.incrementq(arg, value); + asm.movq(ret, arg); + asm.ret(0); + return asm.close(true); + } catch (Exception e) { + throw new RuntimeException("exception while trying to generate field access:", e); + } + } + } + + private void assertIncrement(long initValue, int increment) { + assertReturn("longFieldStubIncrement", new IncrementCodeGenTest(increment), initValue + increment, new LongField(initValue)); + } + + private void assertIncrements(int increment) { + assertIncrement(0x4242_4242_4242_4242L, increment); + } + + @SuppressWarnings("unused") + public static long longFieldStubIncrement(LongField arg) { + return 0; + } + + private static class DecrementCodeGenTest implements CodeGenTest { + final int value; + + public DecrementCodeGenTest(int value) { + this.value = value; + } + + @Override + public byte[] generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) { + AMD64MacroAssembler asm = new AMD64MacroAssembler(target, registerConfig); + Register ret = registerConfig.getReturnRegister(Kind.Int); + try { + Field f = LongField.class.getDeclaredField("x"); + AMD64Address arg = new AMD64Address(asRegister(cc.getArgument(0)), (int) unsafe.objectFieldOffset(f)); + asm.decrementq(arg, value); + asm.movq(ret, arg); + asm.ret(0); + return asm.close(true); + } catch (Exception e) { + throw new RuntimeException("exception while trying to generate field access:", e); + } + } + } + + private void assertDecrement(long initValue, int increment) { + assertReturn("longFieldStubDecrement", new DecrementCodeGenTest(increment), initValue - increment, new LongField(initValue)); + } + + private void assertDecrements(int increment) { + assertDecrement(0x4242_4242_4242_4242L, increment); + } + + @SuppressWarnings("unused") + public static long longFieldStubDecrement(LongField arg) { + return 0; + } + + @Test + public void incrementMemTest0() { + int increment = 0; + assertIncrements(increment); + } + + @Test + public void incrementMemTest1() { + int increment = 1; + assertIncrements(increment); + } + + @Test + public void incrementMemTest2() { + int increment = 2; + assertIncrements(increment); + } + + @Test + public void incrementMemTest3() { + int increment = Integer.MAX_VALUE; + assertIncrements(increment); + } + + @Test + public void incrementMemTest4() { + int increment = Integer.MIN_VALUE; + assertIncrements(increment); + } + + @Test + public void incrementMemTest5() { + int increment = -1; + assertIncrements(increment); + } + + @Test + public void incrementMemTest6() { + int increment = -2; + assertIncrements(increment); + } + + @Test + public void incrementMemTest7() { + int increment = -0x1000_0000; + assertIncrements(increment); + } + + @Test + public void decrementMemTest0() { + int decrement = 0; + assertDecrements(decrement); + } + + @Test + public void decrementMemTest1() { + int decrement = 1; + assertDecrements(decrement); + } + + @Test + public void decrementMemTest2() { + int decrement = 2; + assertDecrements(decrement); + } + + @Test + public void decrementMemTest3() { + int decrement = Integer.MAX_VALUE; + assertDecrements(decrement); + } + + @Test + public void decrementMemTest4() { + int decrement = Integer.MIN_VALUE; + assertDecrements(decrement); + } + + @Test + public void decrementMemTest5() { + int decrement = -1; + assertDecrements(decrement); + } + + @Test + public void decrementMemTest6() { + int decrement = -2; + assertDecrements(decrement); + } + + @Test + public void decrementMemTest7() { + int decrement = -0x1000_0000; + assertDecrements(decrement); + } + +} diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java Tue Mar 31 19:15:45 2015 -0700 @@ -27,6 +27,7 @@ import static com.oracle.graal.asm.NumUtil.*; import static com.oracle.graal.asm.amd64.AMD64AsmOptions.*; import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.*; +import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp.*; import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.*; import com.oracle.graal.amd64.*; @@ -729,6 +730,7 @@ public static final AMD64MOp DIV = new AMD64MOp("DIV", 0xF7, 6); public static final AMD64MOp IDIV = new AMD64MOp("IDIV", 0xF7, 7); public static final AMD64MOp INC = new AMD64MOp("INC", 0xFF, 0); + public static final AMD64MOp DEC = new AMD64MOp("DEC", 0xFF, 1); // @formatter:on private final int ext; @@ -1961,6 +1963,10 @@ ADD.getMIOpcode(QWORD, isByte(imm32)).emit(this, QWORD, dst, imm32); } + public final void addq(AMD64Address dst, int imm32) { + ADD.getMIOpcode(QWORD, isByte(imm32)).emit(this, QWORD, dst, imm32); + } + public final void addq(Register dst, Register src) { ADD.rmOp.emit(this, QWORD, dst, src); } @@ -2024,6 +2030,10 @@ emitByte(0xC8 | encode); } + public final void decq(AMD64Address dst) { + DEC.emit(this, QWORD, dst); + } + public final void incq(Register dst) { // Don't use it directly. Use Macroincrementq() instead. // Use two-byte form (one-byte from is a REX prefix in 64-bit mode) @@ -2032,6 +2042,10 @@ emitByte(0xC0 | encode); } + public final void incq(AMD64Address dst) { + INC.emit(this, QWORD, dst); + } + public final void movq(Register dst, long imm64) { int encode = prefixqAndEncode(dst.encoding); emitByte(0xB8 | encode); @@ -2130,6 +2144,10 @@ SUB.getMIOpcode(QWORD, isByte(imm32)).emit(this, QWORD, dst, imm32); } + public final void subq(AMD64Address dst, int imm32) { + SUB.getMIOpcode(QWORD, isByte(imm32)).emit(this, QWORD, dst, imm32); + } + public final void subqWide(Register dst, int imm32) { // don't use the sign-extending version, forcing a 32-bit immediate SUB.getMIOpcode(QWORD, false).emit(this, QWORD, dst, imm32); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java Tue Mar 31 19:15:45 2015 -0700 @@ -56,6 +56,25 @@ } } + public final void decrementq(AMD64Address dst, int value) { + if (value == Integer.MIN_VALUE) { + subq(dst, value); + return; + } + if (value < 0) { + incrementq(dst, -value); + return; + } + if (value == 0) { + return; + } + if (value == 1 && UseIncDec) { + decq(dst); + } else { + subq(dst, value); + } + } + public void incrementq(Register reg, int value) { if (value == Integer.MIN_VALUE) { addq(reg, value); @@ -75,6 +94,25 @@ } } + public final void incrementq(AMD64Address dst, int value) { + if (value == Integer.MIN_VALUE) { + addq(dst, value); + return; + } + if (value < 0) { + decrementq(dst, -value); + return; + } + if (value == 0) { + return; + } + if (value == 1 && UseIncDec) { + incq(dst); + } else { + addq(dst, value); + } + } + public final void movptr(Register dst, AMD64Address src) { movq(dst, src); } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java --- a/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -29,6 +29,8 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.phases.util.*; import com.oracle.graal.runtime.*; import com.oracle.graal.test.*; @@ -54,21 +56,25 @@ protected InstalledCode assembleMethod(Method m, CodeGenTest test) { ResolvedJavaMethod method = getMetaAccess().lookupJavaMethod(m); - RegisterConfig registerConfig = codeCache.getRegisterConfig(); - CallingConvention cc = CodeUtil.getCallingConvention(codeCache, CallingConvention.Type.JavaCallee, method, false); + try (Scope s = Debug.scope("assembleMethod", method, codeCache)) { + RegisterConfig registerConfig = codeCache.getRegisterConfig(); + CallingConvention cc = CodeUtil.getCallingConvention(codeCache, CallingConvention.Type.JavaCallee, method, false); - CompilationResult compResult = new CompilationResult(); - byte[] targetCode = test.generateCode(compResult, codeCache.getTarget(), registerConfig, cc); - compResult.setTargetCode(targetCode, targetCode.length); + CompilationResult compResult = new CompilationResult(); + byte[] targetCode = test.generateCode(compResult, codeCache.getTarget(), registerConfig, cc); + compResult.setTargetCode(targetCode, targetCode.length); + + InstalledCode code = codeCache.addMethod(method, compResult, null, null); - InstalledCode code = codeCache.addMethod(method, compResult, null, null); - - DisassemblerProvider dis = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getDisassembler(); - if (dis != null) { - String disasm = dis.disassemble(code); - Assert.assertTrue(code.toString(), disasm == null || disasm.length() > 0); + DisassemblerProvider dis = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getDisassembler(); + if (dis != null) { + String disasm = dis.disassemble(code); + Assert.assertTrue(code.toString(), disasm == null || disasm.length() > 0); + } + return code; + } catch (Throwable e) { + throw Debug.handle(e); } - return code; } protected Object runTest(String methodName, CodeGenTest test, Object... args) { diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java Tue Mar 31 19:15:45 2015 -0700 @@ -51,9 +51,6 @@ @Option(help = "Maximum level of recursive inlining.", type = OptionType.Expert) public static final OptionValue MaximumRecursiveInlining = new OptionValue<>(5); - @Option(help = "", type = OptionType.Debug) - public static final OptionValue IterativeInlining = new OptionValue<>(false); - @Option(help = "Graphs with less than this number of nodes are trivial and therefore always inlined.", type = OptionType.Expert) public static final OptionValue TrivialInliningSize = new OptionValue<>(10); @@ -94,9 +91,6 @@ @Option(help = "", type = OptionType.Expert) public static final OptionValue DeoptsToDisableOptimisticOptimization = new OptionValue<>(40); - @Option(help = "", type = OptionType.Expert) - public static final OptionValue CacheGraphs = new OptionValue<>(false); - @Option(help = "", type = OptionType.Debug) public static final OptionValue LoopPeeling = new OptionValue<>(true); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -27,7 +27,6 @@ import com.oracle.graal.loop.phases.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.tiers.*; @@ -306,7 +305,7 @@ private void processMethod(final String snippet) { graph = parseEager(snippet, AllowAssumptions.NO); - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = getDefaultHighTierContext(); new InliningPhase(new CanonicalizerPhase()).apply(graph, context); new PartialEscapePhase(false, new CanonicalizerPhase()).apply(graph, context); } @@ -317,7 +316,7 @@ private void compareGraphs(final String snippet, final String referenceSnippet, final boolean loopPeeling, final boolean excludeVirtual) { graph = parseEager(snippet, AllowAssumptions.NO); - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = getDefaultHighTierContext(); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); canonicalizer.apply(graph, context); new InliningPhase(new CanonicalizerPhase()).apply(graph, context); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Tue Mar 31 19:15:45 2015 -0700 @@ -72,7 +72,7 @@ PhaseSuite graphBuilderSuite = new PhaseSuite<>(); GraphBuilderConfiguration config = GraphBuilderConfiguration.getEagerDefault(new Plugins(new InvocationPlugins(metaAccess))); graphBuilderSuite.appendPhase(new GraphBuilderPhase(config)); - HighTierContext context = new HighTierContext(providers, null, graphBuilderSuite, OptimisticOptimizations.NONE); + HighTierContext context = new HighTierContext(providers, graphBuilderSuite, OptimisticOptimizations.NONE); Assume.assumeTrue(VerifyPhase.class.desiredAssertionStatus()); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest1.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest1.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest1.java Tue Mar 31 19:15:45 2015 -0700 @@ -45,7 +45,7 @@ @Test public void test1() { - test("test1Snippet", REFERENCE_SNIPPET); + testConditionalElimination("test1Snippet", REFERENCE_SNIPPET); } @SuppressWarnings("all") @@ -68,7 +68,7 @@ @Test public void test2() { - test("test2Snippet", REFERENCE_SNIPPET); + testConditionalElimination("test2Snippet", REFERENCE_SNIPPET); } @SuppressWarnings("all") @@ -88,7 +88,7 @@ @Test public void test3() { - test("test3Snippet", REFERENCE_SNIPPET); + testConditionalElimination("test3Snippet", REFERENCE_SNIPPET); } @SuppressWarnings("all") @@ -128,7 +128,7 @@ @Test public void test4() { - test("test4Snippet", "test4Snippet"); + testConditionalElimination("test4Snippet", "test4Snippet"); } @SuppressWarnings("all") @@ -151,6 +151,6 @@ @Test public void test5() { - test("test5Snippet", "test5Snippet"); + testConditionalElimination("test5Snippet", "test5Snippet"); } } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest3.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest3.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest3.java Tue Mar 31 19:15:45 2015 -0700 @@ -54,7 +54,7 @@ @Test public void test1() { - test("test1Snippet", REFERENCE_SNIPPET); + testConditionalElimination("test1Snippet", REFERENCE_SNIPPET); } @SuppressWarnings("all") @@ -81,7 +81,7 @@ @Test public void test2() { - test("test2Snippet", REFERENCE_SNIPPET); + testConditionalElimination("test2Snippet", REFERENCE_SNIPPET); } @SuppressWarnings("all") diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest4.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest4.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest4.java Tue Mar 31 19:15:45 2015 -0700 @@ -51,7 +51,7 @@ @Test public void test1() { - test("test1Snippet", "reference1Snippet"); + testConditionalElimination("test1Snippet", "reference1Snippet"); } @SuppressWarnings("all") @@ -74,6 +74,6 @@ @Test public void test2() { - test("test2Snippet", "reference2Snippet"); + testConditionalElimination("test2Snippet", "reference2Snippet"); } } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest5.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest5.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest5.java Tue Mar 31 19:15:45 2015 -0700 @@ -63,7 +63,7 @@ @Test public void test1() { - test("test1Snippet", "reference1Snippet"); + testConditionalElimination("test1Snippet", "reference1Snippet"); } public static int reference2Snippet(A a) { @@ -85,7 +85,7 @@ @Test public void test2() { - test("test2Snippet", "reference2Snippet"); + testConditionalElimination("test2Snippet", "reference2Snippet"); } @SuppressWarnings("unused") @@ -115,6 +115,6 @@ @Test public void test3() { - test("test3Snippet", "reference3Snippet", true); + testConditionalElimination("test3Snippet", "reference3Snippet", true); } } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest6.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest6.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest6.java Tue Mar 31 19:15:45 2015 -0700 @@ -62,7 +62,7 @@ @Test public void test1() { - test("test1Snippet", "reference1Snippet"); + testConditionalElimination("test1Snippet", "reference1Snippet"); } @SuppressWarnings("all") @@ -79,7 +79,7 @@ @Test public void test2() { - test("test2Snippet", "reference1Snippet"); + testConditionalElimination("test2Snippet", "reference1Snippet"); } @SuppressWarnings("all") @@ -96,6 +96,6 @@ @Test public void test3() { - test("test3Snippet", "reference1Snippet"); + testConditionalElimination("test3Snippet", "reference1Snippet"); } } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest9.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest9.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest9.java Tue Mar 31 19:15:45 2015 -0700 @@ -45,7 +45,7 @@ @Test public void test1() { - test("test1Snippet", REFERENCE_SNIPPET); + testConditionalElimination("test1Snippet", REFERENCE_SNIPPET); } @SuppressWarnings("all") diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTestBase.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTestBase.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTestBase.java Tue Mar 31 19:15:45 2015 -0700 @@ -39,11 +39,11 @@ */ public class ConditionalEliminationTestBase extends GraalCompilerTest { - protected void test(String snippet, String referenceSnippet) { - test(snippet, referenceSnippet, false); + protected void testConditionalElimination(String snippet, String referenceSnippet) { + testConditionalElimination(snippet, referenceSnippet, false); } - protected void test(String snippet, String referenceSnippet, boolean applyConditionalEliminationOnReference) { + protected void testConditionalElimination(String snippet, String referenceSnippet, boolean applyConditionalEliminationOnReference) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); Debug.dump(graph, "Graph"); PhaseContext context = new PhaseContext(getProviders()); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -28,7 +28,6 @@ import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.tiers.*; @@ -82,7 +81,7 @@ private void test(final String snippet) { try (Scope s = Debug.scope("DegeneratedLoopsTest", new DebugDumpScope(snippet))) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = getDefaultHighTierContext(); new InliningPhase(new CanonicalizerPhase()).apply(graph, context); new CanonicalizerPhase().apply(graph, context); Debug.dump(graph, "Graph"); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -69,7 +69,7 @@ GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault(getDefaultGraphBuilderPlugins()); new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), getProviders().getConstantReflection(), conf, OptimisticOptimizations.ALL, null).apply(graph); - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase()).apply(graph, context); new CanonicalizerPhase().apply(graph, context); return graph; diff -r 2e3cc2a27711 -r 2c65cac3d940 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 Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -376,6 +376,10 @@ return providers; } + protected HighTierContext getDefaultHighTierContext() { + return new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + } + protected SnippetReflectionProvider getSnippetReflection() { return Graal.getRequiredCapability(SnippetReflectionProvider.class); } @@ -718,7 +722,7 @@ StructuredGraph graphToCompile = graph == null ? parseForCompile(installedCodeOwner) : graph; lastCompiledGraph = graphToCompile; CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graphToCompile.method(), false); - Request request = new Request<>(graphToCompile, cc, installedCodeOwner, getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultGraphBuilderSuite(), + Request request = new Request<>(graphToCompile, cc, installedCodeOwner, getProviders(), getBackend(), getCodeCache().getTarget(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graphToCompile), getSpeculationLog(), getSuites(), getLIRSuites(), new CompilationResult(), CompilationResultBuilderFactory.Default); return GraalCompiler.compile(request); @@ -822,7 +826,7 @@ assert javaMethod.getAnnotation(Test.class) == null : "shouldn't parse method with @Test annotation: " + javaMethod; try (Scope ds = Debug.scope("Parsing", javaMethod)) { StructuredGraph graph = new StructuredGraph(javaMethod, allowAssumptions); - graphBuilderSuite.apply(graph, new HighTierContext(providers, null, graphBuilderSuite, OptimisticOptimizations.ALL)); + graphBuilderSuite.apply(graph, getDefaultHighTierContext()); return graph; } catch (Throwable e) { throw Debug.handle(e); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GuardEliminationCornerCasesTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GuardEliminationCornerCasesTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GuardEliminationCornerCasesTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -31,7 +31,6 @@ import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.schedule.*; import com.oracle.graal.phases.tiers.*; @@ -75,7 +74,7 @@ @Test public void testFloatingGuards() { - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = getDefaultHighTierContext(); StructuredGraph graph = parseEager("testMethod", AllowAssumptions.YES); new ConvertDeoptimizeToGuardPhase().apply(graph, context); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); diff -r 2e3cc2a27711 -r 2c65cac3d940 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 Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -62,8 +62,8 @@ final ResolvedJavaMethod method = getResolvedJavaMethod("testMethod"); final StructuredGraph graph = parseEager(method, AllowAssumptions.YES); CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); - final CompilationResult cr = compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultGraphBuilderSuite(), - OptimisticOptimizations.ALL, getProfilingInfo(graph), null, getSuites(), getLIRSuites(), new CompilationResult(), CompilationResultBuilderFactory.Default); + final CompilationResult cr = compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, + getProfilingInfo(graph), null, getSuites(), getLIRSuites(), new CompilationResult(), CompilationResultBuilderFactory.Default); for (Infopoint sp : cr.getInfopoints()) { assertNotNull(sp.reason); if (sp instanceof Call) { @@ -85,7 +85,7 @@ assertTrue(graphLineSPs > 0); CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); PhaseSuite graphBuilderSuite = getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault(getDefaultGraphBuilderPlugins())); - final CompilationResult cr = compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, + final CompilationResult cr = compileGraph(graph, cc, graph.method(), getProviders(), getBackend(), getCodeCache().getTarget(), graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), getSpeculationLog(), getSuites(), getLIRSuites(), new CompilationResult(), CompilationResultBuilderFactory.Default); int lineSPs = 0; for (Infopoint sp : cr.getInfopoints()) { diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -28,7 +28,6 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.tiers.*; @@ -66,7 +65,7 @@ for (Invoke invoke : graph.getInvokes()) { hints.put(invoke, 1000d); } - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = getDefaultHighTierContext(); new InliningPhase(hints, new CanonicalizerPhase()).apply(graph, context); new CanonicalizerPhase().apply(graph, context); new DeadCodeEliminationPhase().apply(graph); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -28,7 +28,6 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.tiers.*; @@ -77,7 +76,7 @@ hints.put(invoke, 1000d); } - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = getDefaultHighTierContext(); new InliningPhase(hints, new CanonicalizerPhase()).apply(graph, context); new CanonicalizerPhase().apply(graph, context); new DeadCodeEliminationPhase().apply(graph); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -29,7 +29,6 @@ import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.tiers.*; @@ -89,7 +88,7 @@ private StructuredGraph getGraph(String snippet) { ResolvedJavaMethod method = getResolvedJavaMethod(snippet); StructuredGraph graph = parseEager(method, AllowAssumptions.YES); - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = getDefaultHighTierContext(); new CanonicalizerPhase().apply(graph, context); new InliningPhase(new CanonicalizerPhase()).apply(graph, context); new CanonicalizerPhase().apply(graph, context); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LongNodeChainTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LongNodeChainTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LongNodeChainTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -29,7 +29,6 @@ import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.debug.*; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.schedule.*; import com.oracle.graal.phases.schedule.SchedulePhase.SchedulingStrategy; @@ -48,7 +47,7 @@ } private void longAddChain(boolean reverse) { - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = getDefaultHighTierContext(); StructuredGraph graph = new StructuredGraph(AllowAssumptions.NO); ValueNode constant = graph.unique(ConstantNode.forPrimitive(JavaConstant.INT_1)); ValueNode value = null; diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -688,7 +688,7 @@ final StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO); try (Scope d = Debug.scope("FloatingReadTest", graph)) { try (OverrideScope s = OptionValue.override(OptScheduleOutOfLoops, schedulingStrategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS, OptImplicitNullChecks, false)) { - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = getDefaultHighTierContext(); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); canonicalizer.apply(graph, context); if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -33,7 +33,6 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.tiers.*; @@ -96,7 +95,7 @@ for (Invoke invoke : graph.getInvokes()) { hints.put(invoke, 1000d); } - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = getDefaultHighTierContext(); new InliningPhase(hints, new CanonicalizerPhase()).apply(graph, context); new CanonicalizerPhase().apply(graph, context); new DeadCodeEliminationPhase().apply(graph); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/BackendTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/BackendTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/BackendTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -48,8 +48,8 @@ protected LIRGenerationResult getLIRGenerationResult(final StructuredGraph graph) { SchedulePhase schedule = null; try (Scope s = Debug.scope("FrontEnd")) { - schedule = GraalCompiler.emitFrontEnd(getProviders(), getBackend().getTarget(), graph, null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE, - graph.method().getProfilingInfo(), null, getSuites()); + schedule = GraalCompiler.emitFrontEnd(getProviders(), getBackend().getTarget(), graph, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE, graph.method().getProfilingInfo(), + null, getSuites()); } catch (Throwable e) { throw Debug.handle(e); } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java Tue Mar 31 19:15:45 2015 -0700 @@ -34,7 +34,6 @@ import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.virtual.*; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.tiers.*; @@ -150,7 +149,7 @@ ResolvedJavaMethod method = getResolvedJavaMethod(snippet); try (Scope s = Debug.scope(getClass(), method, getCodeCache())) { graph = parseEager(method, AllowAssumptions.YES); - context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + context = getDefaultHighTierContext(); new InliningPhase(new CanonicalizerPhase()).apply(graph, context); new DeadCodeEliminationPhase().apply(graph); new CanonicalizerPhase().apply(graph, context); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -25,7 +25,6 @@ import org.junit.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.tiers.*; @@ -41,7 +40,7 @@ @Override protected void processMethod(final String snippet) { graph = parseEager(getResolvedJavaMethod(snippet), AllowAssumptions.NO); - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = getDefaultHighTierContext(); new InliningPhase(new CanonicalizerPhase()).apply(graph, context); new EarlyReadEliminationPhase(new CanonicalizerPhase()).apply(graph, context); } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java Tue Mar 31 19:01:07 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +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.test.ea; - -import java.util.concurrent.*; - -import org.junit.*; - -import com.oracle.graal.compiler.test.*; -import com.oracle.graal.compiler.test.ea.EATestBase.TestClassInt; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.phases.*; -import com.oracle.graal.phases.common.*; -import com.oracle.graal.phases.tiers.*; -import com.oracle.graal.virtual.phases.ea.*; - -public class IterativeInliningTest extends GraalCompilerTest { - - private StructuredGraph graph; - - public static class TestObject { - - public Callable callable; - - public TestObject(Callable callable) { - this.callable = callable; - } - } - - public static class TestInt extends TestClassInt implements Callable { - - public TestInt(int x, int y) { - super(x, y); - } - - @Override - public Integer call() throws Exception { - return new Integer(x); - } - } - - @SuppressWarnings("all") - public static int testSimpleSnippet(int b) throws Exception { - TestObject a = new TestObject(null); - a.callable = new TestInt(b, 9); - return a.callable.call(); - } - - @Test - public void testSimple() { - ValueNode result = getReturn("testSimpleSnippet").result(); - assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty()); - assertDeepEquals(graph.getParameter(0), result); - } - - final ReturnNode getReturn(String snippet) { - processMethod(snippet); - assertDeepEquals(1, graph.getNodes(ReturnNode.TYPE).count()); - return graph.getNodes(ReturnNode.TYPE).first(); - } - - private void processMethod(final String snippet) { - graph = parseEager(snippet, AllowAssumptions.YES); - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); - new IterativeInliningPhase(new CanonicalizerPhase()).apply(graph, context); - } -} diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -30,7 +30,6 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.tiers.*; @@ -243,7 +242,7 @@ protected void processMethod(final String snippet) { graph = parseEager(snippet, AllowAssumptions.NO); - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = getDefaultHighTierContext(); new InliningPhase(new CanonicalizerPhase()).apply(graph, context); new PartialEscapePhase(false, true, new CanonicalizerPhase(), null).apply(graph, context); } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -23,17 +23,15 @@ package com.oracle.graal.compiler.test.ea; import java.lang.ref.*; -import java.util.function.*; - import org.junit.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.common.*; -import com.oracle.graal.phases.graph.*; /** * The PartialEscapeAnalysisPhase is expected to remove all allocations and return the correct @@ -186,11 +184,11 @@ Assert.assertTrue("partial escape analysis should have removed all NewInstanceNode allocations", graph.getNodes().filter(NewInstanceNode.class).isEmpty()); Assert.assertTrue("partial escape analysis should have removed all NewArrayNode allocations", graph.getNodes().filter(NewArrayNode.class).isEmpty()); - ToDoubleFunction nodeProbabilities = new FixedNodeProbabilityCache(); + ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, false, false); double probabilitySum = 0; int materializeCount = 0; for (CommitAllocationNode materialize : graph.getNodes().filter(CommitAllocationNode.class)) { - probabilitySum += nodeProbabilities.applyAsDouble(materialize) * materialize.getVirtualObjects().size(); + probabilitySum += cfg.blockFor(materialize).probability() * materialize.getVirtualObjects().size(); materializeCount += materialize.getVirtualObjects().size(); } Assert.assertEquals("unexpected number of MaterializeObjectNodes", expectedCount, materializeCount); @@ -205,5 +203,4 @@ throw e; } } - } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PoorMansEATest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PoorMansEATest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PoorMansEATest.java Tue Mar 31 19:15:45 2015 -0700 @@ -32,7 +32,6 @@ import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.tiers.*; @@ -60,7 +59,7 @@ private void test(final String snippet) { try (Scope s = Debug.scope("PoorMansEATest", new DebugDumpScope(snippet))) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO); - HighTierContext highTierContext = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext highTierContext = getDefaultHighTierContext(); new InliningPhase(new CanonicalizerPhase()).apply(graph, highTierContext); PhaseContext context = new PhaseContext(getProviders()); new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -233,7 +233,7 @@ StructuredGraph graph = eagerInfopointMode ? parseDebug(method, AllowAssumptions.YES) : parseEager(method, AllowAssumptions.YES); PhaseSuite graphBuilderSuite = eagerInfopointMode ? getCustomGraphBuilderSuite(GraphBuilderConfiguration.getFullDebugDefault(getDefaultGraphBuilderPlugins())) : getDefaultGraphBuilderSuite(); - HighTierContext context = new HighTierContext(getProviders(), null, graphBuilderSuite, OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), graphBuilderSuite, OptimisticOptimizations.ALL); Debug.dump(graph, "Graph"); new CanonicalizerPhase().apply(graph, context); new InliningPhase(new CanonicalizerPhase()).apply(graph, context); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/InvokeGraal.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/InvokeGraal.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/tutorial/InvokeGraal.java Tue Mar 31 19:15:45 2015 -0700 @@ -23,7 +23,6 @@ package com.oracle.graal.compiler.test.tutorial; import java.lang.reflect.*; -import java.util.*; import java.util.concurrent.atomic.*; import com.oracle.graal.api.code.*; @@ -122,11 +121,10 @@ CompilationResultBuilderFactory factory = CompilationResultBuilderFactory.Default; /* Advanced configuration objects that are not mandatory. */ - Map cache = null; SpeculationLog speculationLog = null; /* Invoke the whole Graal compilation pipeline. */ - GraalCompiler.compileGraph(graph, callingConvention, method, providers, backend, target, cache, graphBuilderSuite, optimisticOpts, profilingInfo, speculationLog, suites, lirSuites, + GraalCompiler.compileGraph(graph, callingConvention, method, providers, backend, target, graphBuilderSuite, optimisticOpts, profilingInfo, speculationLog, suites, lirSuites, compilationResult, factory); /* diff -r 2e3cc2a27711 -r 2c65cac3d940 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 Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Tue Mar 31 19:15:45 2015 -0700 @@ -141,7 +141,6 @@ public final Providers providers; public final Backend backend; public final TargetDescription target; - public final Map cache; public final PhaseSuite graphBuilderSuite; public final OptimisticOptimizations optimisticOpts; public final ProfilingInfo profilingInfo; @@ -159,7 +158,6 @@ * @param providers * @param backend * @param target - * @param cache * @param graphBuilderSuite * @param optimisticOpts * @param profilingInfo @@ -170,15 +168,14 @@ * @param factory */ public Request(StructuredGraph graph, CallingConvention cc, ResolvedJavaMethod installedCodeOwner, Providers providers, Backend backend, TargetDescription target, - Map cache, PhaseSuite graphBuilderSuite, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, - SpeculationLog speculationLog, Suites suites, LIRSuites lirSuites, T compilationResult, CompilationResultBuilderFactory factory) { + PhaseSuite graphBuilderSuite, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, SpeculationLog speculationLog, Suites suites, + LIRSuites lirSuites, T compilationResult, CompilationResultBuilderFactory factory) { this.graph = graph; this.cc = cc; this.installedCodeOwner = installedCodeOwner; this.providers = providers; this.backend = backend; this.target = target; - this.cache = cache; this.graphBuilderSuite = graphBuilderSuite; this.optimisticOpts = optimisticOpts; this.profilingInfo = profilingInfo; @@ -209,10 +206,10 @@ * @return the result of the compilation */ public static T compileGraph(StructuredGraph graph, CallingConvention cc, ResolvedJavaMethod installedCodeOwner, Providers providers, Backend backend, - TargetDescription target, Map cache, PhaseSuite graphBuilderSuite, OptimisticOptimizations optimisticOpts, - ProfilingInfo profilingInfo, SpeculationLog speculationLog, Suites suites, LIRSuites lirSuites, T compilationResult, CompilationResultBuilderFactory factory) { - return compile(new Request<>(graph, cc, installedCodeOwner, providers, backend, target, cache, graphBuilderSuite, optimisticOpts, profilingInfo, speculationLog, suites, lirSuites, - compilationResult, factory)); + TargetDescription target, PhaseSuite graphBuilderSuite, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, SpeculationLog speculationLog, + Suites suites, LIRSuites lirSuites, T compilationResult, CompilationResultBuilderFactory factory) { + return compile(new Request<>(graph, cc, installedCodeOwner, providers, backend, target, graphBuilderSuite, optimisticOpts, profilingInfo, speculationLog, suites, lirSuites, compilationResult, + factory)); } /** @@ -223,7 +220,7 @@ public static T compile(Request r) { assert !r.graph.isFrozen(); try (Scope s0 = Debug.scope("GraalCompiler", r.graph, r.providers.getCodeCache())) { - SchedulePhase schedule = emitFrontEnd(r.providers, r.target, r.graph, r.cache, r.graphBuilderSuite, r.optimisticOpts, r.profilingInfo, r.speculationLog, r.suites); + SchedulePhase schedule = emitFrontEnd(r.providers, r.target, r.graph, r.graphBuilderSuite, r.optimisticOpts, r.profilingInfo, r.speculationLog, r.suites); emitBackEnd(r.graph, null, r.cc, r.installedCodeOwner, r.backend, r.target, r.compilationResult, r.factory, schedule, null, r.lirSuites); } catch (Throwable e) { throw Debug.handle(e); @@ -242,14 +239,14 @@ /** * Builds the graph, optimizes it. */ - public static SchedulePhase emitFrontEnd(Providers providers, TargetDescription target, StructuredGraph graph, Map cache, - PhaseSuite graphBuilderSuite, OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, SpeculationLog speculationLog, Suites suites) { + public static SchedulePhase emitFrontEnd(Providers providers, TargetDescription target, StructuredGraph graph, PhaseSuite graphBuilderSuite, + OptimisticOptimizations optimisticOpts, ProfilingInfo profilingInfo, SpeculationLog speculationLog, Suites suites) { try (Scope s = Debug.scope("FrontEnd"); DebugCloseable a = FrontEnd.start()) { if (speculationLog != null) { speculationLog.collectFailedSpeculations(); } - HighTierContext highTierContext = new HighTierContext(providers, cache, graphBuilderSuite, optimisticOpts); + HighTierContext highTierContext = new HighTierContext(providers, graphBuilderSuite, optimisticOpts); if (graph.start().next() == null) { graphBuilderSuite.apply(graph, highTierContext); new DeadCodeEliminationPhase(Optional).apply(graph); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EconomyHighTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EconomyHighTier.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EconomyHighTier.java Tue Mar 31 19:15:45 2015 -0700 @@ -36,6 +36,11 @@ if (ImmutableCode.getValue()) { canonicalizer.disableReadCanonicalization(); } + + if (OptCanonicalizer.getValue()) { + appendPhase(canonicalizer); + } + appendPhase(new CleanTypeProfileProxyPhase(canonicalizer)); appendPhase(new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER)); } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Tue Mar 31 19:15:45 2015 -0700 @@ -56,16 +56,12 @@ } if (Inline.getValue()) { - if (IterativeInlining.getValue()) { - appendPhase(new IterativeInliningPhase(canonicalizer)); - } else { - appendPhase(new InliningPhase(canonicalizer)); - appendPhase(new DeadCodeEliminationPhase(Optional)); + appendPhase(new InliningPhase(canonicalizer)); + appendPhase(new DeadCodeEliminationPhase(Optional)); - if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { - appendPhase(canonicalizer); - appendPhase(new IterativeConditionalEliminationPhase(canonicalizer, false)); - } + if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { + appendPhase(canonicalizer); + appendPhase(new IterativeConditionalEliminationPhase(canonicalizer, false)); } } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java --- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java Tue Mar 31 19:15:45 2015 -0700 @@ -213,7 +213,6 @@ protected final MetaAccessProvider metaAccess; private final List registrations; - private final Thread registrationThread; /** * The minimum {@linkplain InvocationPluginIdHolder#getInvocationPluginId() id} for a method @@ -234,7 +233,6 @@ private InvocationPlugins parent; private InvocationPlugins(InvocationPlugins parent, MetaAccessProvider metaAccess) { - this.registrationThread = Thread.currentThread(); this.metaAccess = metaAccess; this.registrations = new ArrayList<>(INITIAL_PLUGIN_CAPACITY); InvocationPlugins p = parent; @@ -263,7 +261,6 @@ * registered for {@code method}. */ public void register(InvocationPlugin plugin, Class declaringClass, String name, Class... argumentTypes) { - assert Thread.currentThread() == registrationThread : "invocation plugin registration must be single threaded"; MethodInfo methodInfo = new MethodInfo(plugin, declaringClass, name, argumentTypes); assert Checker.check(this, methodInfo, plugin); assert plugins == null : "invocation plugin registration is closed"; diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Tue Mar 31 19:15:45 2015 -0700 @@ -31,7 +31,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; -import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.word.*; @@ -171,7 +171,7 @@ wordTypes = new HotSpotWordTypes(metaAccess, target.wordKind); } try (InitTimer rt = timer("create GraphBuilderPhase plugins")) { - plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch); + plugins = createGraphBuilderPlugins(runtime, target, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes, stampProvider); replacements.setGraphBuilderPlugins(plugins); } try (InitTimer rt = timer("create Suites provider")) { @@ -184,6 +184,12 @@ } } + protected Plugins createGraphBuilderPlugins(HotSpotGraalRuntimeProvider runtime, TargetDescription target, HotSpotConstantReflectionProvider constantReflection, + HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, + HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) { + return HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch); + } + protected AMD64HotSpotBackend createBackend(HotSpotGraalRuntimeProvider runtime, HotSpotProviders providers) { return new AMD64HotSpotBackend(runtime, providers); } @@ -260,15 +266,15 @@ } 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 diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCounterOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCounterOp.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCounterOp.java Tue Mar 31 19:15:45 2015 -0700 @@ -24,10 +24,6 @@ import static com.oracle.graal.amd64.AMD64.*; import static com.oracle.graal.api.code.ValueUtil.*; -import static com.oracle.graal.asm.NumUtil.*; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.*; -import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp.*; -import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.*; import static com.oracle.graal.compiler.common.GraalInternalError.*; import com.oracle.graal.api.code.*; @@ -107,11 +103,7 @@ // increment counter (in memory) if (isConstant(incrementValue)) { int increment = asInt(asConstant(incrementValue)); - if (increment == 1) { - INC.emit(masm, QWORD, counterAddr); - } else { - ADD.getMIOpcode(QWORD, isByte(increment)).emit(masm, QWORD, counterAddr, increment); - } + masm.incrementq(counterAddr, increment); } else { masm.addq(counterAddr, asRegister(incrementValue)); } diff -r 2e3cc2a27711 -r 2c65cac3d940 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 Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Tue Mar 31 19:15:45 2015 -0700 @@ -122,6 +122,11 @@ SaveRbp saveRbp; + /** + * Helper instruction to reserve a stack slot for the whole method. Note that the actual users + * of the stack slot might be inserted after stack slot allocation. This dummy instruction + * ensures that the stack slot is alive and gets a real stack slot assigned. + */ private static final class RescueSlotDummyOp extends LIRInstruction { public static final LIRInstructionClass TYPE = LIRInstructionClass.create(RescueSlotDummyOp.class); @@ -144,17 +149,16 @@ private RescueSlotDummyOp rescueSlotOp; private StackSlotValue getOrInitRescueSlot() { + RescueSlotDummyOp op = getOrInitRescueSlotOp(); + return op.getSlot(); + } + + private RescueSlotDummyOp getOrInitRescueSlotOp() { if (rescueSlotOp == null) { // create dummy instruction to keep the rescue slot alive rescueSlotOp = new RescueSlotDummyOp(getResult().getFrameMapBuilder(), getLIRKindTool().getWordKind()); - // insert dummy instruction into the start block - LIR lir = getResult().getLIR(); - List instructions = lir.getLIRforBlock(lir.getControlFlowGraph().getStartBlock()); - // Note: we do not insert at position 1 to avoid interference with the save rpb op - instructions.add(instructions.size() - 1, rescueSlotOp); - Debug.dump(lir, "created rescue dummy op"); } - return rescueSlotOp.getSlot(); + return rescueSlotOp; } /** @@ -481,7 +485,12 @@ } if (BenchmarkCounters.enabled) { // ensure that the rescue slot is available - getOrInitRescueSlot(); + LIRInstruction op = getOrInitRescueSlotOp(); + // insert dummy instruction into the start block + LIR lir = getResult().getLIR(); + List instructions = lir.getLIRforBlock(lir.getControlFlowGraph().getStartBlock()); + instructions.add(1, op); + Debug.dump(lir, "created rescue dummy op"); } } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Tue Mar 31 19:15:45 2015 -0700 @@ -27,7 +27,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; -import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.*; +import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.word.*; @@ -68,7 +68,7 @@ HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, snippetReflection, runtime.getConfig(), target); HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(runtime); HotSpotWordTypes wordTypes = new HotSpotWordTypes(metaAccess, target.wordKind); - Plugins plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch); + Plugins plugins = createGraphBuilderPlugins(runtime, target, metaAccess, constantReflection, foreignCalls, stampProvider, snippetReflection, replacements, wordTypes); replacements.setGraphBuilderPlugins(plugins); HotSpotSuitesProvider suites = createSuites(runtime, plugins); HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers, snippetReflection, @@ -77,6 +77,12 @@ return createBackend(runtime, providers); } + protected Plugins createGraphBuilderPlugins(HotSpotGraalRuntimeProvider runtime, TargetDescription target, HotSpotMetaAccessProvider metaAccess, + HotSpotConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls, HotSpotStampProvider stampProvider, + HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes) { + return HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch); + } + protected HotSpotSuitesProvider createSuites(HotSpotGraalRuntimeProvider runtime, Plugins plugins) { return new HotSpotSuitesProvider(runtime, plugins); } diff -r 2e3cc2a27711 -r 2c65cac3d940 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 Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -205,20 +205,18 @@ } private StructuredGraph compile(String test, boolean compileAOT) { - StructuredGraph graph = parseEager(test, AllowAssumptions.YES); - ResolvedJavaMethod method = graph.method(); - try (OverrideScope s = OptionValue.override(ImmutableCode, compileAOT)) { + StructuredGraph graph = parseEager(test, AllowAssumptions.YES); + ResolvedJavaMethod method = graph.method(); CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); // create suites everytime, as we modify options for the compiler SuitesProvider suitesProvider = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getSuites(); final Suites suitesLocal = suitesProvider.createSuites(); final LIRSuites lirSuitesLocal = suitesProvider.createLIRSuites(); - final CompilationResult compResult = compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultGraphBuilderSuite(), - OptimisticOptimizations.ALL, getProfilingInfo(graph), getSpeculationLog(), suitesLocal, lirSuitesLocal, new CompilationResult(), CompilationResultBuilderFactory.Default); + final CompilationResult compResult = compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, + getProfilingInfo(graph), getSpeculationLog(), suitesLocal, lirSuitesLocal, new CompilationResult(), CompilationResultBuilderFactory.Default); addMethod(method, compResult); + return graph; } - - return graph; } } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -249,7 +249,7 @@ ResolvedJavaMethod snippet = getResolvedJavaMethod(snippetName); try (Scope s = Debug.scope("WriteBarrierAdditionTest", snippet)) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO); - HighTierContext highContext = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext highContext = getDefaultHighTierContext(); MidTierContext midContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null); new NodeIntrinsificationPhase(getMetaAccess(), getConstantReflection(), getSnippetReflection(), getProviders().getForeignCalls(), getProviders().getStampProvider()).apply(graph); new InliningPhase(new InlineEverythingPolicy(), new CanonicalizerPhase()).apply(graph, highContext); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -627,7 +627,7 @@ private void testPredicate(final String snippet, final GraphPredicate expectedBarriers, final int... removedBarrierIndices) { try (Scope d = Debug.scope("WriteBarrierVerificationTest", new DebugDumpScope(snippet))) { final StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); - HighTierContext highTierContext = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext highTierContext = getDefaultHighTierContext(); new InliningPhase(new CanonicalizerPhase()).apply(graph, highTierContext); MidTierContext midTierContext = new MidTierContext(getProviders(), getCodeCache().getTarget(), OptimisticOptimizations.ALL, graph.method().getProfilingInfo(), null); diff -r 2e3cc2a27711 -r 2c65cac3d940 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 Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Tue Mar 31 19:15:45 2015 -0700 @@ -35,14 +35,12 @@ import static com.oracle.graal.phases.common.inlining.InliningUtil.*; import java.lang.management.*; -import java.util.*; import java.util.concurrent.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; -import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.debug.internal.*; @@ -195,11 +193,6 @@ // Begin the compilation event. compilationEvent.begin(); - Map graphCache = null; - if (GraalOptions.CacheGraphs.getValue()) { - graphCache = new HashMap<>(); - } - boolean recordEvolMethodDeps = graalEnv == 0 || unsafe.getByte(graalEnv + config.graalEnvJvmtiCanHotswapOrPostBreakpointOffset) != 0; HotSpotProviders providers = backend.getProviders(); @@ -225,8 +218,8 @@ // all code after the OSR loop is never executed. optimisticOpts.remove(Optimization.RemoveNeverExecutedCode); } - result = compileGraph(graph, cc, method, providers, backend, backend.getTarget(), graphCache, getGraphBuilderSuite(providers), optimisticOpts, profilingInfo, - method.getSpeculationLog(), suites, lirSuites, new CompilationResult(), CompilationResultBuilderFactory.Default); + result = compileGraph(graph, cc, method, providers, backend, backend.getTarget(), getGraphBuilderSuite(providers), optimisticOpts, profilingInfo, method.getSpeculationLog(), suites, + lirSuites, new CompilationResult(), CompilationResultBuilderFactory.Default); result.setId(getId()); result.setEntryBCI(entryBCI); } catch (Throwable e) { diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Tue Mar 31 19:15:45 2015 -0700 @@ -47,6 +47,7 @@ import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.util.*; import com.oracle.graal.options.*; import com.oracle.graal.replacements.*; import com.oracle.graal.word.*; @@ -124,7 +125,7 @@ r.register1(query.name(), Receiver.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { ValueNode javaClass = receiver.get(); - ValueNode folded = ClassQueryNode.tryFold(javaClass, query, b.getMetaAccess(), b.getConstantReflection()); + ValueNode folded = ClassQueryNode.tryFold(GraphUtil.originalValue(javaClass), query, b.getMetaAccess(), b.getConstantReflection()); if (folded != null) { b.addPush(query.returnKind, folded); } else { @@ -137,7 +138,7 @@ r.register2("cast", Receiver.class, Object.class, new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) { ValueNode javaClass = receiver.get(); - ValueNode folded = ClassCastNode.tryFold(javaClass, object, b.getConstantReflection(), b.getAssumptions()); + ValueNode folded = ClassCastNode.tryFold(GraphUtil.originalValue(javaClass), object, b.getConstantReflection(), b.getAssumptions()); if (folded != null) { b.addPush(Kind.Object, folded); } else { @@ -151,7 +152,7 @@ private static void registerCallSitePlugins(InvocationPlugins plugins) { InvocationPlugin plugin = new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { - ValueNode callSite = receiver.get(); + ValueNode callSite = GraphUtil.originalValue(receiver.get()); ValueNode folded = CallSiteTargetNode.tryFold(callSite, b.getMetaAccess(), b.getAssumptions()); if (folded != null) { b.addPush(Kind.Object, folded); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoadFieldPlugin.java Tue Mar 31 19:15:45 2015 -0700 @@ -23,7 +23,6 @@ package com.oracle.graal.hotspot.meta; import static com.oracle.graal.compiler.common.GraalOptions.*; -import static com.oracle.graal.java.AbstractBytecodeParser.Options.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; @@ -42,7 +41,7 @@ static final ThreadLocal FieldReadEnabledInImmutableCode = new ThreadLocal<>(); public boolean apply(GraphBuilderContext b, ValueNode receiver, ResolvedJavaField field) { - if ((InlineDuringParsing.getValue() && !ImmutableCode.getValue()) || b.parsingReplacement()) { + if (!ImmutableCode.getValue() || b.parsingReplacement()) { if (receiver.isConstant()) { JavaConstant asJavaConstant = receiver.asJavaConstant(); return tryReadField(b, field, asJavaConstant); @@ -65,7 +64,7 @@ } public boolean apply(GraphBuilderContext b, ResolvedJavaField staticField) { - if ((InlineDuringParsing.getValue() && !ImmutableCode.getValue()) || b.parsingReplacement()) { + if (!ImmutableCode.getValue() || b.parsingReplacement()) { // Javac does not allow use of "$assertionsDisabled" for a field name but // Eclipse does in which case a suffix is added to the generated field. if (b.parsingReplacement() && staticField.isSynthetic() && staticField.getName().startsWith("$assertionsDisabled")) { diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaFieldImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaFieldImpl.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaFieldImpl.java Tue Mar 31 19:15:45 2015 -0700 @@ -51,7 +51,7 @@ private final LocationIdentity locationIdentity = new FieldLocationIdentity(this); public static class FieldLocationIdentity extends LocationIdentity { - HotSpotResolvedJavaFieldImpl inner; + HotSpotResolvedJavaField inner; public FieldLocationIdentity(HotSpotResolvedJavaFieldImpl inner) { super(false); @@ -78,7 +78,7 @@ @Override public String toString() { - return inner.name; + return inner.getName(); } } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java Tue Mar 31 19:15:45 2015 -0700 @@ -164,7 +164,7 @@ LIRSuites lirSuites = providers.getSuites().createLIRSuites(); PhaseSuite phaseSuite = backend.getSuites().getDefaultGraphBuilderSuite().copy(); CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, g.method(), false); - CompilationResult compResult = GraalCompiler.compileGraph(g, cc, g.method(), providers, backend, backend.getTarget(), null, phaseSuite, OptimisticOptimizations.ALL, + CompilationResult compResult = GraalCompiler.compileGraph(g, cc, g.method(), providers, backend, backend.getTarget(), phaseSuite, OptimisticOptimizations.ALL, DefaultProfilingInfo.get(TriState.UNKNOWN), null, suites, lirSuites, new CompilationResult(), CompilationResultBuilderFactory.Default); InstalledCode installedCode; try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache(), g.method())) { diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java Tue Mar 31 19:15:45 2015 -0700 @@ -29,7 +29,6 @@ import com.oracle.graal.nodes.CallTargetNode.InvokeKind; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.util.*; import com.oracle.graal.replacements.nodes.*; /** @@ -67,9 +66,8 @@ } public static ValueNode tryFold(ValueNode javaClass, ValueNode object, ConstantReflectionProvider constantReflection, Assumptions assumptions) { - ValueNode value = GraphUtil.originalValue(javaClass); - if (value.isConstant()) { - ResolvedJavaType type = constantReflection.asJavaType(value.asConstant()); + if (javaClass != null && javaClass.isConstant()) { + ResolvedJavaType type = constantReflection.asJavaType(javaClass.asConstant()); if (type != null && !type.isPrimitive()) { return CheckCastNode.create(type, object, null, false, assumptions); } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassQueryNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassQueryNode.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassQueryNode.java Tue Mar 31 19:15:45 2015 -0700 @@ -30,7 +30,6 @@ import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.CallTargetNode.InvokeKind; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.util.*; import com.oracle.graal.replacements.nodes.*; /** @@ -79,13 +78,12 @@ } public static ValueNode tryFold(ValueNode javaClass, Query query, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) { - ValueNode value = GraphUtil.originalValue(javaClass); - if (value != null && value.isConstant()) { + if (javaClass != null && javaClass.isConstant()) { if (query.returnKind == Kind.Object) { if (GraalOptions.ImmutableCode.getValue()) { return null; } - HotSpotObjectConstant c = (HotSpotObjectConstant) value.asConstant(); + HotSpotObjectConstant c = (HotSpotObjectConstant) javaClass.asConstant(); JavaConstant answer; switch (query) { case getClassLoader0: @@ -105,7 +103,7 @@ return ConstantNode.forConstant(answer, metaAccess); } } else { - ResolvedJavaType type = constantReflection.asJavaType(value.asConstant()); + ResolvedJavaType type = constantReflection.asJavaType(javaClass.asConstant()); if (type != null) { switch (query) { case isArray: diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ResolvedMethodHandleCallTargetNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ResolvedMethodHandleCallTargetNode.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ResolvedMethodHandleCallTargetNode.java Tue Mar 31 19:15:45 2015 -0700 @@ -22,6 +22,8 @@ */ package com.oracle.graal.hotspot.nodes; +import static sun.misc.Version.*; + import java.lang.invoke.*; import com.oracle.graal.api.meta.*; @@ -35,24 +37,39 @@ /** * A call target that replaces itself in the graph when being lowered by restoring the original - * {@link MethodHandle} invocation target. This is required for when a {@link MethodHandle} call was - * resolved to a constant target but the target was not inlined. In that case, the original - * invocation must be restored with all of its original arguments. Why? HotSpot linkage for - * {@link MethodHandle} intrinsics (see {@code MethodHandles::generate_method_handle_dispatch}) - * expects certain implicit arguments to be on the stack such as the MemberName suffix argument for - * a call to one of the MethodHandle.linkTo* methods. An - * {@linkplain MethodHandleNode#tryResolveTargetInvoke resolved} {@link MethodHandle} invocation - * drops these arguments which means the interpreter won't find them. + * {@link MethodHandle} invocation target. Prior to + * https://bugs.openjdk.java.net/browse/JDK-8072008, this is required for when a + * {@link MethodHandle} call is resolved to a constant target but the target was not inlined. In + * that case, the original invocation must be restored with all of its original arguments. Why? + * HotSpot linkage for {@link MethodHandle} intrinsics (see + * {@code MethodHandles::generate_method_handle_dispatch}) expects certain implicit arguments to be + * on the stack such as the MemberName suffix argument for a call to one of the MethodHandle.linkTo* + * methods. An {@linkplain MethodHandleNode#tryResolveTargetInvoke resolved} {@link MethodHandle} + * invocation drops these arguments which means the interpreter won't find them. */ @NodeInfo public final class ResolvedMethodHandleCallTargetNode extends MethodCallTargetNode implements Lowerable { public static final NodeClass TYPE = NodeClass.create(ResolvedMethodHandleCallTargetNode.class); + + /** + * Creates a call target for an invocation on a direct target derived by resolving a constant + * {@link MethodHandle}. + */ + public static MethodCallTargetNode create(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType, ResolvedJavaMethod originalTargetMethod, + ValueNode[] originalArguments, JavaType originalReturnType) { + if (jdkMajorVersion() >= 1 && jdkMinorVersion() >= 8 && jdkMicroVersion() >= 0 && jdkUpdateVersion() >= 60) { + // https://bugs.openjdk.java.net/browse/JDK-8072008 is targeted for 8u60 + return new MethodCallTargetNode(invokeKind, targetMethod, arguments, returnType); + } + return new ResolvedMethodHandleCallTargetNode(invokeKind, targetMethod, arguments, returnType, originalTargetMethod, originalArguments, originalReturnType); + } + protected final ResolvedJavaMethod originalTargetMethod; protected final JavaType originalReturnType; @Input NodeInputList originalArguments; - public ResolvedMethodHandleCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType, ResolvedJavaMethod originalTargetMethod, + protected ResolvedMethodHandleCallTargetNode(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] arguments, JavaType returnType, ResolvedJavaMethod originalTargetMethod, ValueNode[] originalArguments, JavaType originalReturnType) { super(TYPE, invokeKind, targetMethod, arguments, returnType); this.originalTargetMethod = originalTargetMethod; diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java Tue Mar 31 19:15:45 2015 -0700 @@ -30,7 +30,6 @@ import com.oracle.graal.nodes.CallTargetNode.InvokeKind; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.util.*; import com.oracle.graal.replacements.nodes.*; @NodeInfo @@ -46,9 +45,8 @@ return arguments.get(0); } - public static ConstantNode tryFold(ValueNode initialCallSite, MetaAccessProvider metaAccess, Assumptions assumptions) { - ValueNode callSite = GraphUtil.originalValue(initialCallSite); - if (callSite.isConstant() && !callSite.isNullConstant()) { + public static ConstantNode tryFold(ValueNode callSite, MetaAccessProvider metaAccess, Assumptions assumptions) { + if (callSite != null && callSite.isConstant() && !callSite.isNullConstant()) { HotSpotObjectConstant c = (HotSpotObjectConstant) callSite.asConstant(); JavaConstant target = c.getCallSiteTarget(assumptions); if (target != null) { diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java Tue Mar 31 19:15:45 2015 -0700 @@ -256,7 +256,7 @@ throw GraalInternalError.shouldNotReachHere(); } - MethodCallTargetNode callTarget = new ResolvedMethodHandleCallTargetNode(targetInvokeKind, target, targetArguments, targetReturnType, original, arguments, returnType); + MethodCallTargetNode callTarget = ResolvedMethodHandleCallTargetNode.create(targetInvokeKind, target, targetArguments, targetReturnType, original, arguments, returnType); // The call target can have a different return type than the invoker, // e.g. the target returns an Object but the invoker void. In this case diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Tue Mar 31 19:15:45 2015 -0700 @@ -180,8 +180,8 @@ try (Scope s0 = Debug.scope("StubCompilation", graph, providers.getCodeCache())) { Suites defaultSuites = providers.getSuites().getDefaultSuites(); Suites suites = new Suites(new PhaseSuite<>(), defaultSuites.getMidTier(), defaultSuites.getLowTier()); - SchedulePhase schedule = emitFrontEnd(providers, target, graph, null, providers.getSuites().getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graph), - null, suites); + SchedulePhase schedule = emitFrontEnd(providers, target, graph, providers.getSuites().getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graph), null, + suites); LIRSuites lirSuites = createLIRSuites(); emitBackEnd(graph, Stub.this, incomingCc, getInstalledCodeOwner(), backend, target, compResult, CompilationResultBuilderFactory.Default, schedule, getRegisterConfig(), lirSuites); } catch (Throwable e) { diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Tue Mar 31 19:15:45 2015 -0700 @@ -58,6 +58,9 @@ @Option(help = "Inlines trivial methods during bytecode parsing.", type = OptionType.Expert) public static final StableOptionValue InlineDuringParsing = new StableOptionValue<>(false); + @Option(help = "Inlines intrinsic methods during bytecode parsing.", type = OptionType.Expert) + public static final StableOptionValue InlineIntrinsicsDuringParsing = new StableOptionValue<>(true); + @Option(help = "Traces inlining performed during bytecode parsing.", type = OptionType.Debug) public static final StableOptionValue TraceInlineDuringParsing = new StableOptionValue<>(false); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Tue Mar 31 19:15:45 2015 -0700 @@ -206,7 +206,9 @@ } public void replace(LIR lir, LIRInstruction replacement) { - lir.getLIRforBlock(block).set(index, replacement); + List instructions = lir.getLIRforBlock(block); + assert instructions.get(index).equals(this) : String.format("Replacing the wrong instruction: %s instead of %s", instructions.get(index), this); + instructions.set(index, replacement); } @Override diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/Interval.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/Interval.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/Interval.java Tue Mar 31 19:15:45 2015 -0700 @@ -414,7 +414,7 @@ } public void setRegisterPriority(int index, RegisterPriority registerPriority) { - list.set(index * 2, registerPriority.ordinal()); + list.set((index << 1) + 1, registerPriority.ordinal()); } @Override diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java Tue Mar 31 19:15:45 2015 -0700 @@ -259,7 +259,7 @@ Collection blocks = new LinkedList<>(); Collection exits = new LinkedList<>(); Queue work = new LinkedList<>(); - ControlFlowGraph cfg = loopsData().controlFlowGraph(); + ControlFlowGraph cfg = loopsData().getCFG(); work.add(cfg.blockFor(branch)); while (!work.isEmpty()) { Block b = work.remove(); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java Tue Mar 31 19:15:45 2015 -0700 @@ -25,7 +25,6 @@ import static com.oracle.graal.compiler.common.GraalOptions.*; import java.util.*; -import java.util.function.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; @@ -49,12 +48,12 @@ } // TODO (gd) change when inversion is available - public static boolean shouldPeel(LoopEx loop, ToDoubleFunction probabilities) { + public static boolean shouldPeel(LoopEx loop, ControlFlowGraph cfg) { if (loop.detectCounted()) { return false; } LoopBeginNode loopBegin = loop.loopBegin(); - double entryProbability = probabilities.applyAsDouble(loopBegin.forwardEnd()); + double entryProbability = cfg.blockFor(loopBegin.forwardEnd()).probability(); if (entryProbability > MinimumPeelProbability.getValue() && loop.size() + loopBegin.graph().getNodeCount() < MaximumDesiredSize.getValue()) { // check whether we're allowed to peel this loop for (Node node : loop.inside().nodes()) { @@ -120,7 +119,7 @@ // this may count twice because of fall-through in switches inBranchTotal += loop.nodesInLoopBranch(branch).count(); } - Block postDomBlock = loop.loopsData().controlFlowGraph().blockFor(controlSplit).getPostdominator(); + Block postDomBlock = loop.loopsData().getCFG().blockFor(controlSplit).getPostdominator(); if (postDomBlock != null) { IsolatedInitialization.UNSWITCH_SPLIT_WITH_PHIS.increment(); phis += ((MergeNode) postDomBlock.getBeginNode()).phis().count(); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java Tue Mar 31 19:15:45 2015 -0700 @@ -104,7 +104,7 @@ } } - public ControlFlowGraph controlFlowGraph() { + public ControlFlowGraph getCFG() { return cfg; } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopPeelingPhase.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopPeelingPhase.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopPeelingPhase.java Tue Mar 31 19:15:45 2015 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, 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 @@ -22,23 +22,19 @@ */ package com.oracle.graal.loop.phases; -import java.util.function.*; - import com.oracle.graal.debug.*; import com.oracle.graal.loop.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; -import com.oracle.graal.phases.graph.*; public class LoopPeelingPhase extends Phase { @Override protected void run(StructuredGraph graph) { if (graph.hasLoops()) { - ToDoubleFunction probabilities = new FixedNodeProbabilityCache(); LoopsData data = new LoopsData(graph); for (LoopEx loop : data.outerFirst()) { - if (LoopPolicies.shouldPeel(loop, probabilities)) { + if (LoopPolicies.shouldPeel(loop, data.getCFG())) { Debug.log("Peeling %s", loop); LoopTransformations.peel(loop); Debug.dump(graph, "After peeling %s", loop); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopSafepointEliminationPhase.java Tue Mar 31 19:15:45 2015 -0700 @@ -53,7 +53,7 @@ } for (LoopEx loop : loops.countedLoops()) { for (LoopEndNode loopEnd : loop.loopBegin().loopEnds()) { - Block b = loops.controlFlowGraph().blockFor(loopEnd); + Block b = loops.getCFG().blockFor(loopEnd); blocks: while (b != loop.loop().getHeader()) { assert b != null; for (FixedNode node : b.getNodes()) { diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Tue Mar 31 19:15:45 2015 -0700 @@ -304,7 +304,7 @@ */ JavaConstant positive = lessThan2.getX().asJavaConstant(); if (positive != null && positive.asLong() > 0 && positive.asLong() < positive.getKind().getMaxValue()) { - ConstantNode newLimit = ConstantNode.forIntegerKind(positive.getKind(), positive.asLong() + 1, graph()); + ConstantNode newLimit = ConstantNode.forIntegerStamp(lessThan2.getX().stamp(), positive.asLong() + 1, graph()); below = graph().unique(new IntegerBelowNode(lessThan.getX(), newLimit)); } } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowNode.java Tue Mar 31 19:15:45 2015 -0700 @@ -115,15 +115,12 @@ } } else { // x < y - if (yStamp.isPositive()) { + if (yStamp.isStrictlyPositive()) { // x >= 0 && x < y long xUpperBound = xStamp.upperBound(); long yUpperBound = yStamp.upperBound(); if (yUpperBound <= xUpperBound || !xStamp.isPositive()) { - if (yUpperBound != 0) { - yUpperBound--; - } - return new IntegerStamp(bits, Math.max(0, xStamp.lowerBound()), Math.min(xUpperBound, yUpperBound), xStamp.downMask(), xStamp.upMask()); + return new IntegerStamp(bits, Math.max(0, xStamp.lowerBound()), Math.min(xUpperBound, yUpperBound - 1), xStamp.downMask(), xStamp.upMask()); } } } @@ -156,11 +153,11 @@ if (xStamp.isPositive() && yStamp.isPositive()) { long xLowerBound = xStamp.lowerBound(); long yLowerBound = yStamp.lowerBound(); - if (xLowerBound >= yLowerBound) { - if (xLowerBound != CodeUtil.maxValue(bits)) { - xLowerBound++; - } - return new IntegerStamp(bits, xLowerBound, yStamp.upperBound(), yStamp.downMask(), yStamp.upMask()); + if (xLowerBound == CodeUtil.maxValue(bits)) { + return null; + } else if (xLowerBound >= yLowerBound) { + assert xLowerBound != CodeUtil.maxValue(bits); + return new IntegerStamp(bits, xLowerBound + 1, yStamp.upperBound(), yStamp.downMask(), yStamp.upMask()); } } } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java Tue Mar 31 19:15:45 2015 -0700 @@ -137,11 +137,11 @@ // x < y long xUpperBound = xStamp.upperBound(); long yUpperBound = yStamp.upperBound(); - if (yUpperBound <= xUpperBound) { - if (yUpperBound != CodeUtil.minValue(bits)) { - yUpperBound--; - } - return new IntegerStamp(bits, xStamp.lowerBound(), yUpperBound, xStamp.downMask(), xStamp.upMask()); + if (yUpperBound == CodeUtil.minValue(bits)) { + return null; + } else if (yUpperBound <= xUpperBound) { + assert yUpperBound != CodeUtil.minValue(bits); + return new IntegerStamp(bits, xStamp.lowerBound(), yUpperBound - 1, xStamp.downMask(), xStamp.upMask()); } } } @@ -170,11 +170,11 @@ // y > x long xLowerBound = xStamp.lowerBound(); long yLowerBound = yStamp.lowerBound(); - if (xLowerBound >= yLowerBound) { - if (xLowerBound != CodeUtil.maxValue(bits)) { - xLowerBound++; - } - return new IntegerStamp(bits, xLowerBound, yStamp.upperBound(), yStamp.downMask(), yStamp.upMask()); + if (xLowerBound == CodeUtil.maxValue(bits)) { + return null; + } else if (xLowerBound >= yLowerBound) { + assert xLowerBound != CodeUtil.maxValue(bits); + return new IntegerStamp(bits, xLowerBound + 1, yStamp.upperBound(), yStamp.downMask(), yStamp.upMask()); } } } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Tue Mar 31 19:15:45 2015 -0700 @@ -118,6 +118,10 @@ return nodeToBlock.get(node); } + public double frequencyFor(FixedNode node) { + return blockFor(node).probability(); + } + public List> getLoops() { return loops; } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Tue Mar 31 19:15:45 2015 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2015, 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 @@ -85,8 +85,7 @@ @Override public boolean verify() { MemoryNode lla = getLastLocationAccess(); - assert lla == null || lla instanceof MemoryCheckpoint || lla instanceof MemoryProxy || lla instanceof MemoryPhiNode : "lastLocationAccess of " + this + - " should be a MemoryCheckpoint, but is " + lla; + assert lla != null || getLocationIdentity().isImmutable() : "lastLocationAccess of " + this + " shouldn't be null for mutable location identity " + getLocationIdentity(); return super.verify(); } } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java Tue Mar 31 19:15:45 2015 -0700 @@ -29,6 +29,7 @@ import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; @NodeInfo public final class UnboxNode extends FixedWithNextNode implements Virtualizable, Lowerable, Canonicalizable.Unary { @@ -78,6 +79,9 @@ @Override public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) { + if (hasNoUsages() && StampTool.isPointerNonNull(forValue)) { + return null; + } ValueNode synonym = findSynonym(tool.getMetaAccess(), tool.getConstantReflection(), forValue, boxingKind); if (synonym != null) { return synonym; diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java Tue Mar 31 19:15:45 2015 -0700 @@ -122,7 +122,7 @@ /** * Checks whether this {@link Stamp} represents a {@linkplain Stamp#isLegal() legal} pointer - * stamp whose values known to be always null. + * stamp whose values are known to never be null. * * @param stamp the stamp to check * @return true if this stamp represents a legal object stamp whose values are known to be diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Tue Mar 31 19:15:45 2015 -0700 @@ -289,9 +289,8 @@ MemoryAccess access = (MemoryAccess) node; if (access.getLastLocationAccess() == anchor) { MemoryNode lastLocationAccess = state.getLastLocationAccess(access.getLocationIdentity()); - if (lastLocationAccess != null) { - access.setLastLocationAccess(lastLocationAccess); - } + assert lastLocationAccess != null; + access.setLastLocationAccess(lastLocationAccess); } } } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ProfileCompiledMethodsPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ProfileCompiledMethodsPhase.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ProfileCompiledMethodsPhase.java Tue Mar 31 19:15:45 2015 -0700 @@ -23,7 +23,6 @@ package com.oracle.graal.phases.common; import java.util.*; -import java.util.function.*; import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.graph.*; @@ -36,7 +35,6 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.*; -import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.schedule.*; /** @@ -63,15 +61,14 @@ @Override protected void run(StructuredGraph graph) { - ToDoubleFunction probabilities = new FixedNodeProbabilityCache(); SchedulePhase schedule = new SchedulePhase(); schedule.apply(graph, false); ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true); for (Loop loop : cfg.getLoops()) { - double loopProbability = probabilities.applyAsDouble(loop.getHeader().getBeginNode()); + double loopProbability = cfg.blockFor(loop.getHeader().getBeginNode()).probability(); if (loopProbability > (1D / Integer.MAX_VALUE)) { - addSectionCounters(loop.getHeader().getBeginNode(), loop.getBlocks(), loop.getChildren(), schedule, probabilities); + addSectionCounters(loop.getHeader().getBeginNode(), loop.getBlocks(), loop.getChildren(), schedule, cfg); } } // don't put the counter increase directly after the start (problems with OSR) @@ -79,7 +76,7 @@ while (current.next() instanceof FixedWithNextNode) { current = (FixedWithNextNode) current.next(); } - addSectionCounters(current, cfg.getBlocks(), cfg.getLoops(), schedule, probabilities); + addSectionCounters(current, cfg.getBlocks(), cfg.getLoops(), schedule, cfg); if (WITH_INVOKES) { for (Node node : graph.getNodes()) { @@ -92,13 +89,12 @@ } } - private static void addSectionCounters(FixedWithNextNode start, Collection sectionBlocks, Collection> childLoops, SchedulePhase schedule, - ToDoubleFunction probabilities) { + private static void addSectionCounters(FixedWithNextNode start, Collection sectionBlocks, Collection> childLoops, SchedulePhase schedule, ControlFlowGraph cfg) { HashSet blocks = new HashSet<>(sectionBlocks); for (Loop loop : childLoops) { blocks.removeAll(loop.getBlocks()); } - double weight = getSectionWeight(schedule, probabilities, blocks) / probabilities.applyAsDouble(start); + double weight = getSectionWeight(schedule, blocks) / cfg.blockFor(start).probability(); DynamicCounterNode.addCounterBefore(GROUP_NAME, sectionHead(start), (long) weight, true, start.next()); if (WITH_INVOKE_FREE_SECTIONS && !hasInvoke(blocks)) { DynamicCounterNode.addCounterBefore(GROUP_NAME_WITHOUT, sectionHead(start), (long) weight, true, start.next()); @@ -113,10 +109,10 @@ } } - private static double getSectionWeight(SchedulePhase schedule, ToDoubleFunction probabilities, Collection blocks) { + private static double getSectionWeight(SchedulePhase schedule, Collection blocks) { double count = 0; for (Block block : blocks) { - double blockProbability = probabilities.applyAsDouble(block.getBeginNode()); + double blockProbability = block.probability(); for (Node node : schedule.getBlockToNodesMap().get(block)) { count += blockProbability * getNodeWeight(node); } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java Tue Mar 31 19:15:45 2015 -0700 @@ -75,10 +75,6 @@ if (result != null) { return result; } - result = getCachedGraph(method, context); - if (result != null) { - return result; - } return parseBytecodes(method, context, canonicalizer, caller); } @@ -181,18 +177,6 @@ return result; } - private static StructuredGraph getCachedGraph(ResolvedJavaMethod method, HighTierContext context) { - if (context.getGraphCache() != null) { - StructuredGraph cachedGraph = context.getGraphCache().get(method); - if (cachedGraph != null) { - // TODO: check that cachedGraph.getAssumptions() are still valid - // instead of waiting for code installation to do it. - return cachedGraph; - } - } - return null; - } - /** * This method builds the IR nodes for the given method and canonicalizes them. * Provided profiling info is mature, the resulting graph is cached. The caller is responsible @@ -219,9 +203,6 @@ canonicalizer.apply(newGraph, context); } - if (context.getGraphCache() != null) { - context.getGraphCache().put(newGraph.method(), newGraph); - } return newGraph; } catch (Throwable e) { throw Debug.handle(e); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/FixedNodeProbabilityCache.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/FixedNodeProbabilityCache.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/FixedNodeProbabilityCache.java Tue Mar 31 19:15:45 2015 -0700 @@ -73,6 +73,53 @@ assert node != null; metricComputeNodeProbability.increment(); + FixedNode current = findBegin(node); + if (current == null) { + // this should only appear for dead code + return 1D; + } + + assert current instanceof AbstractBeginNode; + Double cachedValue = cache.get(current); + if (cachedValue != null) { + return cachedValue; + } + + double probability = 0.0; + if (current.predecessor() == null) { + if (current instanceof AbstractMergeNode) { + probability = handleMerge(current, probability); + } else { + assert current instanceof StartNode; + probability = 1D; + } + } else { + ControlSplitNode split = (ControlSplitNode) current.predecessor(); + probability = split.probability((AbstractBeginNode) current) * applyAsDouble(split); + } + assert !Double.isNaN(probability) && !Double.isInfinite(probability) : current + " " + probability; + cache.put(current, probability); + return probability; + } + + private double handleMerge(FixedNode current, double probability) { + double result = probability; + AbstractMergeNode currentMerge = (AbstractMergeNode) current; + NodeInputList currentForwardEnds = currentMerge.forwardEnds(); + /* + * Use simple iteration instead of streams, since the stream infrastructure adds many frames + * which causes the recursion to overflow the stack earlier than it would otherwise. + */ + for (AbstractEndNode endNode : currentForwardEnds) { + result += applyAsDouble(endNode); + } + if (current instanceof LoopBeginNode) { + result *= ((LoopBeginNode) current).loopFrequency(); + } + return result; + } + + private static FixedNode findBegin(FixedNode node) { FixedNode current = node; while (true) { assert current != null; @@ -85,44 +132,11 @@ break; } } else if (predecessor == null) { - // this should only appear for dead code - return 1D; + current = null; + break; } current = (FixedNode) predecessor; } - - assert current instanceof AbstractBeginNode; - Double cachedValue = cache.get(current); - if (cachedValue != null) { - return cachedValue; - } - - double probability = 0.0; - if (current.predecessor() == null) { - if (current instanceof AbstractMergeNode) { - AbstractMergeNode currentMerge = (AbstractMergeNode) current; - NodeInputList currentForwardEnds = currentMerge.forwardEnds(); - /* - * Use simple iteration instead of streams, since the stream infrastructure adds - * many frames which causes the recursion to overflow the stack earlier than it - * would otherwise. - */ - for (AbstractEndNode endNode : currentForwardEnds) { - probability += applyAsDouble(endNode); - } - if (current instanceof LoopBeginNode) { - probability *= ((LoopBeginNode) current).loopFrequency(); - } - } else { - assert current instanceof StartNode; - probability = 1D; - } - } else { - ControlSplitNode split = (ControlSplitNode) current.predecessor(); - probability = split.probability((AbstractBeginNode) current) * applyAsDouble(split); - } - assert !Double.isNaN(probability) && !Double.isInfinite(probability) : current + " " + probability; - cache.put(current, probability); - return probability; + return current; } } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/MemoryScheduleVerification.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/MemoryScheduleVerification.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/MemoryScheduleVerification.java Tue Mar 31 19:15:45 2015 -0700 @@ -31,7 +31,6 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure; @@ -78,7 +77,7 @@ } addFloatingReadUsages(currentState, n); - } else if (n instanceof MemoryProxy) { + } else if (n instanceof MemoryNode) { addFloatingReadUsages(currentState, n); } else if (n instanceof FloatingReadNode) { FloatingReadNode floatingReadNode = (FloatingReadNode) n; diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java Tue Mar 31 19:15:45 2015 -0700 @@ -22,10 +22,6 @@ */ package com.oracle.graal.phases.tiers; -import java.util.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.util.*; @@ -33,12 +29,10 @@ private final PhaseSuite graphBuilderSuite; - private final Map cache; private final OptimisticOptimizations optimisticOpts; - public HighTierContext(Providers providers, Map cache, PhaseSuite graphBuilderSuite, OptimisticOptimizations optimisticOpts) { + public HighTierContext(Providers providers, PhaseSuite graphBuilderSuite, OptimisticOptimizations optimisticOpts) { super(providers); - this.cache = cache; this.graphBuilderSuite = graphBuilderSuite; this.optimisticOpts = optimisticOpts; } @@ -47,10 +41,6 @@ return graphBuilderSuite; } - public Map getGraphCache() { - return cache; - } - public OptimisticOptimizations getOptimisticOptimizations() { return optimisticOpts; } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Tue Mar 31 19:15:45 2015 -0700 @@ -30,15 +30,12 @@ import java.nio.channels.*; import java.util.*; import java.util.Map.Entry; -import java.util.function.*; - import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; -import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.schedule.*; public class BinaryGraphPrinter implements GraphPrinter { @@ -143,7 +140,7 @@ BlockMap> blockToNodes = schedule == null ? null : schedule.getBlockToNodesMap(); NodeMap nodeToBlocks = schedule == null ? null : schedule.getNodeToBlockMap(); List blocks = cfg == null ? null : cfg.getBlocks(); - writeNodes(graph, nodeToBlocks); + writeNodes(graph, nodeToBlocks, cfg); writeBlocks(blocks, blockToNodes); } @@ -400,14 +397,7 @@ return node.getId(); } - private void writeNodes(Graph graph, NodeMap nodeToBlocks) throws IOException { - ToDoubleFunction probabilities = null; - if (PrintGraphProbabilities.getValue()) { - try { - probabilities = new FixedNodeProbabilityCache(); - } catch (Throwable t) { - } - } + private void writeNodes(Graph graph, NodeMap nodeToBlocks, ControlFlowGraph cfg) throws IOException { Map props = new HashMap<>(); writeInt(graph.getNodeCount()); @@ -415,9 +405,9 @@ for (Node node : graph.getNodes()) { NodeClass nodeClass = node.getNodeClass(); node.getDebugProperties(props); - if (probabilities != null && node instanceof FixedNode) { + if (cfg != null && PrintGraphProbabilities.getValue() && node instanceof FixedNode) { try { - props.put("probability", probabilities.applyAsDouble((FixedNode) node)); + props.put("probability", cfg.blockFor(node).probability()); } catch (Throwable t) { props.put("probability", t); } @@ -432,6 +422,29 @@ } } } + + if (node instanceof ControlSinkNode) { + props.put("category", "controlSink"); + } else if (node instanceof ControlSplitNode) { + props.put("category", "controlSplit"); + } else if (node instanceof AbstractMergeNode) { + props.put("category", "merge"); + } else if (node instanceof AbstractBeginNode) { + props.put("category", "begin"); + } else if (node instanceof AbstractEndNode) { + props.put("category", "end"); + } else if (node instanceof FixedNode) { + props.put("category", "fixed"); + } else if (node instanceof VirtualState) { + props.put("category", "state"); + } else if (node instanceof PhiNode) { + props.put("category", "phi"); + } else if (node instanceof ProxyNode) { + props.put("category", "proxy"); + } else { + props.put("category", "floating"); + } + writeInt(getNodeId(node)); writePoolObject(nodeClass); writeByte(node.predecessor() == null ? 0 : 1); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -331,7 +331,7 @@ @Test public void testCanonicalLength() { StructuredGraph graph = parseEager("testCanonicalLengthSnippet", AllowAssumptions.NO); - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase()).apply(graph, context); new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); @@ -347,7 +347,7 @@ @Test public void testCanonicalEqual() { StructuredGraph graph = parseEager("testCanonicalEqualSnippet", AllowAssumptions.NO); - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase()).apply(graph, context); new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); @@ -361,7 +361,7 @@ @Test public void testVirtualEqual() { StructuredGraph graph = parseEager("testVirtualEqualSnippet", AllowAssumptions.NO); - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); new InliningPhase(new CanonicalizerPhase()).apply(graph, context); new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); new PartialEscapePhase(false, new CanonicalizerPhase()).apply(graph, context); @@ -379,7 +379,7 @@ @Test public void testVirtualNotEqual() { StructuredGraph graph = parseEager("testVirtualNotEqualSnippet", AllowAssumptions.NO); - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = getDefaultHighTierContext(); new InliningPhase(new CanonicalizerPhase()).apply(graph, context); new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); new PartialEscapePhase(false, new CanonicalizerPhase()).apply(graph, context); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/BitOpNodesTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/BitOpNodesTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/BitOpNodesTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -29,7 +29,6 @@ import com.oracle.graal.compiler.test.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.tiers.*; @@ -248,7 +247,7 @@ */ private ValueNode parseAndInline(String name, Class expectedClass) { StructuredGraph graph = parseEager(name, AllowAssumptions.YES); - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.NONE); + HighTierContext context = getDefaultHighTierContext(); CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); canonicalizer.apply(graph, context); new InliningPhase(canonicalizer).apply(graph, context); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/EdgesTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -34,7 +34,6 @@ import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.common.inlining.policy.*; @@ -115,7 +114,7 @@ ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method); StructuredGraph g = parseProfiled(javaMethod, AllowAssumptions.NO); - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = getDefaultHighTierContext(); new InliningPhase(new InlineMethodSubstitutionsPolicy(), new CanonicalizerPhase()).apply(g, context); new CanonicalizerPhase().apply(g, context); Assert.assertTrue(g.getNodes().filter(CheckCastNode.class).isEmpty()); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -33,7 +33,6 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.tiers.*; @@ -48,7 +47,7 @@ protected StructuredGraph testGraph(final String snippet) { try (Scope s = Debug.scope("MethodSubstitutionTest", getResolvedJavaMethod(snippet))) { StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); - HighTierContext context = new HighTierContext(getProviders(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL); + HighTierContext context = getDefaultHighTierContext(); Debug.dump(graph, "Graph"); new InliningPhase(new CanonicalizerPhase()).apply(graph, context); Debug.dump(graph, "Graph"); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Tue Mar 31 19:15:45 2015 -0700 @@ -397,7 +397,7 @@ } private void assertNumWordCasts(String snippetName, int expectedWordCasts) { - HighTierContext context = new HighTierContext(getProviders(), null, null, OptimisticOptimizations.ALL); + HighTierContext context = new HighTierContext(getProviders(), null, OptimisticOptimizations.ALL); StructuredGraph graph = parseEager(snippetName, AllowAssumptions.YES); new CanonicalizerPhase().apply(graph, context); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Tue Mar 31 19:15:45 2015 -0700 @@ -208,7 +208,7 @@ } @Override - public void replace(ValueNode oldNode, ValueNode newNode, MemoryMap mmap) { + public void replace(ValueNode oldNode, ValueNode newNode) { assert newNode instanceof PhiNode; assert oldNode == instanceOf; newNode.inferStamp(); @@ -239,7 +239,7 @@ } @Override - public void replace(ValueNode oldNode, ValueNode newNode, MemoryMap mmap) { + public void replace(ValueNode oldNode, ValueNode newNode) { assert newNode instanceof PhiNode; assert oldNode == instanceOf; newNode.inferStamp(); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Tue Mar 31 19:15:45 2015 -0700 @@ -97,7 +97,7 @@ public InlineInfo getInlineInfo(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) { ResolvedJavaMethod subst = getMethodSubstitutionMethod(method); if (subst != null) { - if (b.parsingReplacement() || InlineDuringParsing.getValue()) { + if (b.parsingReplacement() || InlineDuringParsing.getValue() || InlineIntrinsicsDuringParsing.getValue()) { // Forced inlining of intrinsics return new InlineInfo(subst, true, true); } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Mar 31 19:15:45 2015 -0700 @@ -722,18 +722,20 @@ new FloatingReadPhase(false, true).apply(snippetCopy); - MemoryAnchorNode memoryAnchor = snippetCopy.add(new MemoryAnchorNode()); - snippetCopy.start().replaceAtUsages(InputType.Memory, memoryAnchor); + MemoryAnchorNode anchor = snippetCopy.add(new MemoryAnchorNode()); + snippetCopy.start().replaceAtUsages(InputType.Memory, anchor); this.snippet = snippetCopy; Debug.dump(snippet, "SnippetTemplate after fixing memory anchoring"); StartNode entryPointNode = snippet.start(); - if (memoryAnchor.hasNoUsages()) { - memoryAnchor.safeDelete(); + if (anchor.hasNoUsages()) { + anchor.safeDelete(); + this.memoryAnchor = null; } else { - snippetCopy.addAfterFixed(snippetCopy.start(), memoryAnchor); + snippetCopy.addAfterFixed(snippetCopy.start(), anchor); + this.memoryAnchor = anchor; } List returnNodes = snippet.getNodes(ReturnNode.TYPE).snapshot(); if (returnNodes.isEmpty()) { @@ -832,6 +834,11 @@ private final ReturnNode returnNode; /** + * The memory anchor (if any) of the snippet. + */ + private final MemoryAnchorNode memoryAnchor; + + /** * Nodes that inherit the {@link StateSplit#stateAfter()} from the replacee during * instantiation. */ @@ -948,7 +955,7 @@ /** * Replaces all usages of {@code oldNode} with direct or indirect usages of {@code newNode}. */ - void replace(ValueNode oldNode, ValueNode newNode, MemoryMap mmap); + void replace(ValueNode oldNode, ValueNode newNode); } /** @@ -957,48 +964,8 @@ */ public static final UsageReplacer DEFAULT_REPLACER = new UsageReplacer() { - private LocationIdentity getLocationIdentity(Node node) { - if (node instanceof MemoryAccess) { - return ((MemoryAccess) node).getLocationIdentity(); - } else if (node instanceof MemoryProxy) { - return ((MemoryProxy) node).getLocationIdentity(); - } else if (node instanceof MemoryPhiNode) { - return ((MemoryPhiNode) node).getLocationIdentity(); - } else { - return null; - } - } - @Override - public void replace(ValueNode oldNode, ValueNode newNode, MemoryMap mmap) { - if (mmap != null) { - for (Node usage : oldNode.usages().snapshot()) { - LocationIdentity identity = getLocationIdentity(usage); - boolean usageReplaced = false; - if (identity != null && !identity.isImmutable()) { - // lastLocationAccess points into the snippet graph. find a proper - // MemoryCheckPoint inside the snippet graph - MemoryNode lastAccess = mmap.getLastLocationAccess(identity); - - assert lastAccess != null : "no mapping found for lowerable node " + oldNode + ". (No node in the snippet kills the same location as the lowerable node?)"; - if (usage instanceof MemoryAccess) { - MemoryAccess access = (MemoryAccess) usage; - if (access.getLastLocationAccess() == oldNode) { - assert oldNode.graph().isAfterFloatingReadPhase(); - access.setLastLocationAccess(lastAccess); - usageReplaced = true; - } - } else { - assert usage instanceof MemoryProxy || usage instanceof MemoryPhiNode; - usage.replaceFirstInput(oldNode, lastAccess.asNode()); - usageReplaced = true; - } - } - if (!usageReplaced) { - assert newNode != null : "this branch is only valid if we have a newNode for replacement"; - } - } - } + public void replace(ValueNode oldNode, ValueNode newNode) { if (newNode == null) { assert oldNode.hasNoUsages(); } else { @@ -1066,14 +1033,48 @@ return true; } - private class DuplicateMapper implements MemoryMap { + private static class MemoryInputMap implements MemoryMap { + + private final LocationIdentity locationIdentity; + private final MemoryNode lastLocationAccess; + + public MemoryInputMap(ValueNode replacee) { + if (replacee instanceof MemoryAccess) { + MemoryAccess access = (MemoryAccess) replacee; + locationIdentity = access.getLocationIdentity(); + lastLocationAccess = access.getLastLocationAccess(); + } else { + locationIdentity = null; + lastLocationAccess = null; + } + } + + @Override + public MemoryNode getLastLocationAccess(LocationIdentity location) { + if (locationIdentity != null && locationIdentity.equals(location)) { + return lastLocationAccess; + } else { + return null; + } + } + + @Override + public Collection getLocations() { + if (locationIdentity == null) { + return Collections.emptySet(); + } else { + return Collections.singleton(locationIdentity); + } + } + } + + private class MemoryOutputMap extends MemoryInputMap { private final Map duplicates; - private StartNode replaceeStart; - public DuplicateMapper(Map duplicates, StartNode replaceeStart) { + public MemoryOutputMap(ValueNode replacee, Map duplicates) { + super(replacee); this.duplicates = duplicates; - this.replaceeStart = replaceeStart; } @Override @@ -1081,9 +1082,9 @@ MemoryMapNode memoryMap = returnNode.getMemoryMap(); assert memoryMap != null : "no memory map stored for this snippet graph (snippet doesn't have a ReturnNode?)"; MemoryNode lastLocationAccess = memoryMap.getLastLocationAccess(locationIdentity); - assert lastLocationAccess != null; - if (lastLocationAccess instanceof StartNode) { - return replaceeStart; + assert lastLocationAccess != null : locationIdentity; + if (lastLocationAccess == memoryAnchor) { + return super.getLastLocationAccess(locationIdentity); } else { return (MemoryNode) duplicates.get(ValueNodeUtil.asNode(lastLocationAccess)); } @@ -1095,6 +1096,60 @@ } } + private void rewireMemoryGraph(ValueNode replacee, Map duplicates) { + // rewire outgoing memory edges + replaceMemoryUsages(replacee, new MemoryOutputMap(replacee, duplicates)); + + ReturnNode ret = (ReturnNode) duplicates.get(returnNode); + MemoryMapNode memoryMap = ret.getMemoryMap(); + ret.setMemoryMap(null); + memoryMap.safeDelete(); + + if (memoryAnchor != null) { + // rewire incoming memory edges + MemoryAnchorNode memoryDuplicate = (MemoryAnchorNode) duplicates.get(memoryAnchor); + replaceMemoryUsages(memoryDuplicate, new MemoryInputMap(replacee)); + + if (memoryDuplicate.hasNoUsages()) { + memoryDuplicate.graph().removeFixed(memoryDuplicate); + } + } + } + + private static LocationIdentity getLocationIdentity(Node node) { + if (node instanceof MemoryAccess) { + return ((MemoryAccess) node).getLocationIdentity(); + } else if (node instanceof MemoryProxy) { + return ((MemoryProxy) node).getLocationIdentity(); + } else if (node instanceof MemoryPhiNode) { + return ((MemoryPhiNode) node).getLocationIdentity(); + } else { + return null; + } + } + + private static void replaceMemoryUsages(ValueNode node, MemoryMap map) { + for (Node usage : node.usages().snapshot()) { + if (usage instanceof MemoryMapNode) { + continue; + } + + LocationIdentity location = getLocationIdentity(usage); + if (location != null) { + NodePosIterator iter = usage.inputs().iterator(); + while (iter.hasNext()) { + Position pos = iter.nextPosition(); + if (pos.getInputType() == InputType.Memory && pos.get(usage) == node) { + MemoryNode replacement = map.getLastLocationAccess(location); + if (replacement != null) { + pos.set(usage, replacement.asNode()); + } + } + } + } + } + } + /** * Replaces a given fixed node with this specialized snippet. * @@ -1181,17 +1236,18 @@ updateStamps(replacee, duplicates); + rewireMemoryGraph(replacee, duplicates); + // Replace all usages of the replacee with the value returned by the snippet ValueNode returnValue = null; if (returnNode != null && !(replacee instanceof ControlSinkNode)) { ReturnNode returnDuplicate = (ReturnNode) duplicates.get(returnNode); returnValue = returnDuplicate.result(); - MemoryMap mmap = new DuplicateMapper(duplicates, replaceeGraph.start()); if (returnValue == null && replacee.usages().isNotEmpty() && replacee instanceof MemoryCheckpoint) { - replacer.replace(replacee, null, mmap); + replacer.replace(replacee, null); } else { assert returnValue != null || replacee.hasNoUsages(); - replacer.replace(replacee, returnValue, mmap); + replacer.replace(replacee, returnValue); } if (returnDuplicate.isAlive()) { FixedNode next = null; @@ -1284,11 +1340,13 @@ } updateStamps(replacee, duplicates); + rewireMemoryGraph(replacee, duplicates); + // Replace all usages of the replacee with the value returned by the snippet ReturnNode returnDuplicate = (ReturnNode) duplicates.get(returnNode); ValueNode returnValue = returnDuplicate.result(); assert returnValue != null || replacee.hasNoUsages(); - replacer.replace(replacee, returnValue, new DuplicateMapper(duplicates, replaceeGraph.start())); + replacer.replace(replacee, returnValue); if (returnDuplicate.isAlive()) { returnDuplicate.replaceAndDelete(next); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java Tue Mar 31 19:15:45 2015 -0700 @@ -80,7 +80,7 @@ if (state1.getVirtualObject() == state2.getVirtualObject()) { // the same virtual objects will always have the same contents tool.replaceWithValue(ConstantNode.forBoolean(true, graph())); - } else if (state1.getVirtualObject().entryCount() == state2.getVirtualObject().entryCount()) { + } else if (state1.getVirtualObject().entryCount() == state2.getVirtualObject().entryCount() && state1.getState() == EscapeState.Virtual && state2.getState() == EscapeState.Virtual) { int entryCount = state1.getVirtualObject().entryCount(); boolean allEqual = true; for (int i = 0; i < entryCount; i++) { diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/AssertionNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/AssertionNode.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/AssertionNode.java Tue Mar 31 19:15:45 2015 -0700 @@ -79,8 +79,10 @@ public void generate(NodeLIRBuilderTool generator) { assert compileTimeAssertion; - if (value.isConstant() && value.asJavaConstant().asInt() == 0) { - throw new GraalInternalError("%s: failed compile-time assertion: %s", this, message); + if (value.isConstant()) { + if (value.asJavaConstant().asInt() == 0) { + throw new GraalInternalError("%s: failed compile-time assertion: %s", this, message); + } } else { throw new GraalInternalError("%s: failed compile-time assertion (value %s): %s", this, value, message); } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleReplacements.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleReplacements.java Tue Mar 31 19:01:07 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +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.truffle.hotspot; - -import com.oracle.graal.api.replacements.*; -import com.oracle.graal.api.runtime.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.util.*; -import com.oracle.graal.runtime.*; -import com.oracle.graal.truffle.*; - -public final class HotSpotTruffleReplacements extends TruffleReplacements { - - private HotSpotTruffleReplacements(Providers providers, SnippetReflectionProvider snippetReflection) { - super(providers, snippetReflection); - } - - public static Replacements makeInstance() { - Providers providers = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders(); - SnippetReflectionProvider snippetReflection = Graal.getRequiredCapability(SnippetReflectionProvider.class); - return new HotSpotTruffleReplacements(providers, snippetReflection); - } -} diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Tue Mar 31 19:15:45 2015 -0700 @@ -50,7 +50,6 @@ import com.oracle.graal.lir.phases.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.tiers.*; @@ -74,7 +73,6 @@ } private TruffleCompilerImpl truffleCompiler; - private Replacements truffleReplacements; private Map> compilations = newIdentityMap(); private final ThreadPoolExecutor compileQueue; @@ -83,7 +81,6 @@ private HotSpotTruffleRuntime() { installOptimizedCallTargetCallMethod(); - installOptimizedCallTargetCallDirect(); lookupCallMethods(getGraalProviders().getMetaAccess()); installDefaultListeners(); @@ -115,12 +112,6 @@ } - private static void installOptimizedCallTargetCallDirect() { - if (TruffleCompilerOptions.TruffleFunctionInlining.getValue() && !TruffleCompilerOptions.FastPE.getValue()) { - ((HotSpotResolvedJavaMethod) getGraalProviders().getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallDirectMethod())).setNotInlineable(); - } - } - @Override public String getName() { return "Graal Truffle Runtime"; @@ -150,14 +141,6 @@ return createCallTargetImpl(source, root); } - @Override - public Replacements getReplacements() { - if (truffleReplacements == null) { - truffleReplacements = HotSpotTruffleReplacements.makeInstance(); - } - return truffleReplacements; - } - public static void installOptimizedCallTargetCallMethod() { Providers providers = getGraalProviders(); MetaAccessProvider metaAccess = providers.getMetaAccess(); @@ -203,8 +186,8 @@ CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); Backend backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend(); CompilationResultBuilderFactory factory = getOptimizedCallTargetInstrumentationFactory(backend.getTarget().arch.getName(), javaMethod); - return compileGraph(graph, cc, javaMethod, providers, backend, providers.getCodeCache().getTarget(), null, graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), null, - suites, lirSuites, new CompilationResult(), factory); + return compileGraph(graph, cc, javaMethod, providers, backend, providers.getCodeCache().getTarget(), graphBuilderSuite, OptimisticOptimizations.ALL, getProfilingInfo(graph), null, suites, + lirSuites, new CompilationResult(), factory); } private static HotSpotProviders getGraalProviders() { @@ -232,11 +215,15 @@ Runnable r = new Runnable() { @Override public void run() { + boolean success = true; try (Scope s = Debug.scope("Truffle", new TruffleDebugJavaMethod(optimizedCallTarget))) { truffleCompiler.compileMethod(optimizedCallTarget); - optimizedCallTarget.notifyCompilationFinished(); } catch (Throwable e) { optimizedCallTarget.notifyCompilationFailed(e); + success = false; + } finally { + optimizedCallTarget.notifyCompilationFinished(success); + } } }; @@ -265,7 +252,10 @@ if (codeTask != null && isCompiling(optimizedCallTarget)) { this.compilations.remove(optimizedCallTarget); boolean result = codeTask.cancel(true); - getCompilationNotify().notifyCompilationDequeued(optimizedCallTarget, source, reason); + if (result) { + optimizedCallTarget.notifyCompilationFinished(false); + getCompilationNotify().notifyCompilationDequeued(optimizedCallTarget, source, reason); + } return result; } return false; diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.truffle.test/sl/TestOSR.sl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/sl/TestOSR.sl Tue Mar 31 19:15:45 2015 -0700 @@ -0,0 +1,13 @@ +function test() { + i = 0; + sum = 0; + while (i < 300000) { + sum = sum + i; + i = i + 1; + } + return sum; +} + +function main() { + test(); +} diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ConditionAnchoringTest.java diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultLoopNodeFactory.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultLoopNodeFactory.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultLoopNodeFactory.java Tue Mar 31 19:15:45 2015 -0700 @@ -29,7 +29,7 @@ public class DefaultLoopNodeFactory implements LoopNodeFactory { public LoopNode create(RepeatingNode repeatingNode) { - return new OptimizedLoopNode(repeatingNode); + return OptimizedOSRLoopNode.create(repeatingNode); } } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Tue Mar 31 19:15:45 2015 -0700 @@ -32,7 +32,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.truffle.debug.*; import com.oracle.graal.truffle.unsafe.*; import com.oracle.truffle.api.*; @@ -270,8 +269,6 @@ public abstract Collection getQueuedCallTargets(); - public abstract Replacements getReplacements(); - public abstract void compile(OptimizedCallTarget optimizedCallTarget, boolean mayBeAsynchronous); public abstract boolean cancelInstalledTask(OptimizedCallTarget optimizedCallTarget, Object source, CharSequence reason); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Tue Mar 31 19:15:45 2015 -0700 @@ -27,7 +27,6 @@ import java.io.*; import java.lang.reflect.*; import java.util.*; -import java.util.concurrent.*; import java.util.concurrent.atomic.*; import java.util.stream.*; @@ -72,6 +71,7 @@ private TruffleInlining inlining; private int cachedNonTrivialNodeCount = -1; + private boolean compiling; /** * When this call target is inlined, the inlining {@link InstalledCode} registers this @@ -102,6 +102,10 @@ this.nodeRewritingAssumption = new CyclicAssumption("nodeRewritingAssumption of " + rootNode.toString()); } + public final boolean isCompiling() { + return compiling; + } + private static RootNode cloneRootNode(RootNode root) { if (root == null || !root.isCloningAllowed()) { return null; @@ -174,7 +178,7 @@ } @ExplodeLoop - private void profileArguments(Object[] args) { + void profileArguments(Object[] args) { if (profiledArgumentTypesAssumption == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); initializeProfiledArgumentTypes(args); @@ -272,7 +276,12 @@ VirtualFrame frame = createFrame(getRootNode().getFrameDescriptor(), args); Object result = callProxy(frame); - // Profile call return type + profileReturnType(result); + + return result; + } + + void profileReturnType(Object result) { if (profiledReturnTypeAssumption == null) { if (TruffleReturnTypeSpeculation.getValue()) { CompilerDirectives.transferToInterpreterAndInvalidate(); @@ -286,8 +295,6 @@ profiledReturnTypeAssumption.invalidate(); } } - - return result; } @Override @@ -321,25 +328,16 @@ this.runtime.reinstallStubs(); } else { compilationProfile.reportInterpreterCall(); - if (compilationPolicy.shouldCompile(compilationProfile, getCompilerOptions())) { + if (!isCompiling() && compilationPolicy.shouldCompile(compilationProfile, getCompilerOptions())) { compile(); } } } public void compile() { - compile(TruffleBackgroundCompilation.getValue() && !TruffleCompilationExceptionsAreThrown.getValue()); - } - - public void compile(boolean mayBeAsynchronous) { - if (!runtime.isCompiling(this)) { - runtime.compile(this, mayBeAsynchronous); - } else if (!mayBeAsynchronous && runtime.isCompiling(this)) { - try { - runtime.waitForCompilation(this, 20000); - } catch (ExecutionException | TimeoutException e) { - Debug.log(3, e.getMessage()); - } + if (!isCompiling()) { + compiling = true; + runtime.compile(this, TruffleBackgroundCompilation.getValue() && !TruffleCompilationExceptionsAreThrown.getValue()); } } @@ -363,11 +361,11 @@ } } - public void notifyCompilationFinished() { - // Compilation was successful. - if (inlining != null) { + public void notifyCompilationFinished(boolean successful) { + if (successful && inlining != null) { dequeueInlinedCallSites(inlining); } + compiling = false; } private void dequeueInlinedCallSites(TruffleInlining parentDecision) { diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedOSRLoopNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedOSRLoopNode.java Tue Mar 31 19:15:45 2015 -0700 @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2015, 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.truffle; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; + +public final class OptimizedOSRLoopNode extends LoopNode implements ReplaceObserver { + + private static final int OSR_THRESHOLD = TruffleCompilerOptions.TruffleOSRCompilationThreshold.getValue(); + + private int interpreterLoopCount; + private OptimizedCallTarget compiledTarget; + + @Child private RepeatingNode repeatableNode; + + private OptimizedOSRLoopNode(RepeatingNode repeatableNode) { + this.repeatableNode = repeatableNode; + } + + @Override + public Node copy() { + OptimizedOSRLoopNode copy = (OptimizedOSRLoopNode) super.copy(); + copy.compiledTarget = null; + copy.interpreterLoopCount = 0; + return copy; + } + + @Override + public RepeatingNode getRepeatingNode() { + return repeatableNode; + } + + @Override + public void executeLoop(VirtualFrame frame) { + if (CompilerDirectives.inInterpreter()) { + boolean done = false; + while (!done) { + if (compiledTarget == null) { + done = profilingLoop(frame); + } else { + done = compilingLoop(frame); + } + } + } else { + while (repeatableNode.executeRepeating(frame)) { + if (CompilerDirectives.inInterpreter()) { + // compiled method got invalidated. We might need OSR again. + executeLoop(frame); + return; + } + } + } + } + + private boolean profilingLoop(VirtualFrame frame) { + int overflowLoopCount = Integer.MAX_VALUE - OSR_THRESHOLD + interpreterLoopCount; + try { + while (repeatableNode.executeRepeating(frame)) { + try { + overflowLoopCount = Math.incrementExact(overflowLoopCount); + } catch (ArithmeticException e) { + compileLoop(frame); + return false; + } + } + } finally { + reportLoopCount(overflowLoopCount - Integer.MAX_VALUE + OSR_THRESHOLD - interpreterLoopCount); + } + return true; + } + + private boolean compilingLoop(VirtualFrame frame) { + int iterations = 0; + try { + do { + OptimizedCallTarget target = compiledTarget; + if (target == null) { + return false; + } else if (target.isValid()) { + Object result = target.callDirect(new Object[]{frame}); + if (result == Boolean.TRUE) { + // loop is done. No further repetitions necessary. + return true; + } else { + invalidate(this, "OSR compilation got invalidated"); + return false; + } + } else if (!target.isCompiling()) { + invalidate(this, "OSR compilation failed or cancelled"); + return false; + } + iterations++; + } while (repeatableNode.executeRepeating(frame)); + } finally { + reportLoopCount(iterations); + } + return true; + } + + private void compileLoop(VirtualFrame frame) { + atomic(new Runnable() { + public void run() { + /* + * Compilations need to run atomically as they may be scheduled by multiple threads + * at the same time. This strategy lets the first thread win. Later threads will not + * issue compiles. + */ + if (compiledTarget == null) { + compiledTarget = compileImpl(frame); + if (compiledTarget == null) { + interpreterLoopCount = 0; + } + } + } + }); + } + + private OptimizedCallTarget compileImpl(VirtualFrame frame) { + Node parent = getParent(); + OptimizedCallTarget target = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(new OSRRootNode(this)); + // to avoid a deopt on first call we provide some profiling information + target.profileReturnType(Boolean.TRUE); + target.profileReturnType(Boolean.FALSE); + target.profileArguments(new Object[]{frame}); + // let the old parent re-adopt the children + parent.adoptChildren(); + target.compile(); + return target; + } + + private void reportLoopCount(int reportIterations) { + if (reportIterations != 0) { + interpreterLoopCount += reportIterations; + getRootNode().reportLoopCount(reportIterations); + } + } + + public void nodeReplaced(Node oldNode, Node newNode, CharSequence reason) { + invalidate(newNode, reason); + } + + private void invalidate(Object source, CharSequence reason) { + OptimizedCallTarget target = this.compiledTarget; + if (target != null) { + target.invalidate(source, reason); + compiledTarget = null; + interpreterLoopCount = 0; + } + } + + public static LoopNode create(RepeatingNode repeat) { + if (TruffleCompilerOptions.TruffleOSR.getValue()) { + return new OptimizedOSRLoopNode(repeat); + } else { + return new OptimizedLoopNode(repeat); + } + } + + private static class OSRRootNode extends RootNode { + + @Child private OptimizedOSRLoopNode loopNode; + + public OSRRootNode(OptimizedOSRLoopNode loop) { + super(loop.getSourceSection(), loop.getRootNode().getFrameDescriptor()); + this.loopNode = loop; + } + + @Override + public Object execute(VirtualFrame frame) { + VirtualFrame parentFrame = (VirtualFrame) frame.getArguments()[0]; + while (loopNode.getRepeatingNode().executeRepeating(parentFrame)) { + if (CompilerDirectives.inInterpreter()) { + return Boolean.FALSE; + } + } + return Boolean.TRUE; + } + + @Override + public boolean isCloningAllowed() { + return false; + } + + @Override + public String toString() { + return loopNode.getRepeatingNode().toString() + ""; + } + + } + +} diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Mar 31 19:15:45 2015 -0700 @@ -22,41 +22,28 @@ */ package com.oracle.graal.truffle; -import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.truffle.TruffleCompilerOptions.*; import java.util.*; -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.Assumptions.AssumptionResult; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.MethodHandleAccessProvider.IntrinsicMethod; import com.oracle.graal.api.replacements.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; -import com.oracle.graal.debug.internal.*; -import com.oracle.graal.graph.Graph.Mark; -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.Node; import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins; import com.oracle.graal.java.*; -import com.oracle.graal.loop.*; -import com.oracle.graal.nodes.CallTargetNode.InvokeKind; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.nodes.util.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.inlining.*; -import com.oracle.graal.phases.common.inlining.info.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.truffle.debug.*; @@ -77,20 +64,17 @@ private final Providers providers; private final CanonicalizerPhase canonicalizer; - private Set constantReceivers; - private final TruffleCache truffleCache; private final SnippetReflectionProvider snippetReflection; private final ResolvedJavaMethod callDirectMethod; private final ResolvedJavaMethod callInlinedMethod; private final ResolvedJavaMethod callSiteProxyMethod; - protected final ResolvedJavaMethod callRootMethod; + private final ResolvedJavaMethod callRootMethod; private final GraphBuilderConfiguration configForRoot; - public PartialEvaluator(Providers providers, GraphBuilderConfiguration configForRoot, TruffleCache truffleCache, SnippetReflectionProvider snippetReflection) { + public PartialEvaluator(Providers providers, GraphBuilderConfiguration configForRoot, SnippetReflectionProvider snippetReflection) { this.providers = providers; this.canonicalizer = new CanonicalizerPhase(); this.snippetReflection = snippetReflection; - this.truffleCache = truffleCache; this.callDirectMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallDirectMethod()); this.callInlinedMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.getCallInlinedMethod()); this.callSiteProxyMethod = providers.getMetaAccess().lookupJavaMethod(GraalFrameInstance.CallNodeFrame.METHOD); @@ -104,10 +88,6 @@ } public StructuredGraph createGraph(final OptimizedCallTarget callTarget, AllowAssumptions allowAssumptions) { - if (TraceTruffleCompilationHistogram.getValue() || TraceTruffleCompilationDetails.getValue()) { - constantReceivers = new HashSet<>(); - } - try (Scope c = Debug.scope("TruffleTree")) { Debug.dump(callTarget, "truffle tree"); } catch (Throwable e) { @@ -119,28 +99,16 @@ try (Scope s = Debug.scope("CreateGraph", graph); Indent indent = Debug.logAndIndent("createGraph %s", graph)) { - Map graphCache = null; - if (CacheGraphs.getValue()) { - graphCache = new HashMap<>(); - } PhaseContext baseContext = new PhaseContext(providers); - HighTierContext tierContext = new HighTierContext(providers, graphCache, new PhaseSuite(), OptimisticOptimizations.NONE); + HighTierContext tierContext = new HighTierContext(providers, new PhaseSuite(), OptimisticOptimizations.NONE); - if (TruffleCompilerOptions.FastPE.getValue()) { - fastPartialEvaluation(callTarget, graph, baseContext, tierContext); - } else { - createRootGraph(graph); - partialEvaluation(callTarget, graph, baseContext, tierContext); - } + fastPartialEvaluation(callTarget, graph, baseContext, tierContext); if (Thread.currentThread().isInterrupted()) { return null; } new VerifyFrameDoesNotEscapePhase().apply(graph, false); - if (TraceTruffleCompilationHistogram.getValue() && constantReceivers != null) { - createHistogram(); - } postPartialEvaluation(graph); } catch (Throwable e) { @@ -202,13 +170,6 @@ if (original.getAnnotation(TruffleBoundary.class) != null) { return null; } - IntrinsicMethod intrinsicMethod = builder.getConstantReflection().getMethodHandleAccess().lookupMethodHandleIntrinsic(original); - if (intrinsicMethod != null) { - InlineInfo inlineInfo = getMethodHandleIntrinsicInlineInfo(builder, arguments, intrinsicMethod); - if (inlineInfo != null) { - return inlineInfo; - } - } if (replacements != null && replacements.getMethodSubstitutionMethod(original) != null) { return null; } @@ -243,59 +204,6 @@ inlining.pop(); } } - - private InlineInfo getMethodHandleIntrinsicInlineInfo(GraphBuilderContext builder, ValueNode[] arguments, IntrinsicMethod intrinsicMethod) { - ResolvedJavaMethod targetMethod = null; - switch (intrinsicMethod) { - case INVOKE_BASIC: - ValueNode methodHandleNode = arguments[0]; - if (methodHandleNode.isConstant()) { - targetMethod = builder.getConstantReflection().getMethodHandleAccess().resolveInvokeBasicTarget(methodHandleNode.asJavaConstant(), true); - } - break; - case LINK_TO_STATIC: - case LINK_TO_SPECIAL: - case LINK_TO_VIRTUAL: - case LINK_TO_INTERFACE: - ValueNode memberNameNode = arguments[arguments.length - 1]; - if (memberNameNode.isConstant()) { - targetMethod = builder.getConstantReflection().getMethodHandleAccess().resolveLinkToTarget(memberNameNode.asJavaConstant()); - } - break; - default: - throw GraalInternalError.shouldNotReachHere(); - } - if (targetMethod != null) { - // TODO maybe cast arguments - - if (!targetMethod.canBeInlined()) { - return null; - } - if (targetMethod.canBeStaticallyBound()) { - return new InlineInfo(targetMethod, false, false); - } - - // Try to get the most accurate receiver type - if (intrinsicMethod == IntrinsicMethod.LINK_TO_VIRTUAL || intrinsicMethod == IntrinsicMethod.LINK_TO_INTERFACE) { - ResolvedJavaType receiverType = StampTool.typeOrNull(arguments[0].stamp()); - if (receiverType != null) { - AssumptionResult concreteMethod = receiverType.findUniqueConcreteMethod(targetMethod); - if (concreteMethod != null) { - builder.getAssumptions().record(concreteMethod); - return new InlineInfo(concreteMethod.getResult(), false, false); - } - } - } else { - AssumptionResult concreteMethod = targetMethod.getDeclaringClass().findUniqueConcreteMethod(targetMethod); - if (concreteMethod != null) { - builder.getAssumptions().record(concreteMethod); - return new InlineInfo(concreteMethod.getResult(), false, false); - } - } - } - - return null; - } } private class PELoopExplosionPlugin implements LoopExplosionPlugin { @@ -362,48 +270,6 @@ ComputeLoopFrequenciesClosure.compute(graph); } - private void partialEvaluation(final OptimizedCallTarget callTarget, final StructuredGraph graph, PhaseContext baseContext, HighTierContext tierContext) { - injectConstantCallTarget(graph, callTarget, baseContext); - - Debug.dump(graph, "Before expansion"); - - TruffleExpansionLogger expansionLogger = null; - if (TraceTruffleExpansion.getValue()) { - expansionLogger = new TruffleExpansionLogger(providers, graph); - } - - expandTree(graph, expansionLogger); - - TruffleInliningCache inliningCache = null; - if (TruffleFunctionInlining.getValue()) { - callTarget.setInlining(new TruffleInlining(callTarget, new DefaultInliningPolicy())); - if (TruffleFunctionInliningCache.getValue()) { - inliningCache = new TruffleInliningCache(); - } - } - - expandDirectCalls(graph, expansionLogger, callTarget.getInlining(), inliningCache); - - if (Thread.currentThread().isInterrupted()) { - return; - } - - canonicalizer.apply(graph, baseContext); - // EA frame and clean up. - do { - try (Scope pe = Debug.scope("TrufflePartialEscape", graph)) { - new PartialEscapePhase(true, canonicalizer).apply(graph, tierContext); - new IncrementalCanonicalizerPhase<>(canonicalizer, new ConditionalEliminationPhase()).apply(graph, tierContext); - } catch (Throwable t) { - Debug.handle(t); - } - } while (expandTree(graph, expansionLogger)); - - if (expansionLogger != null) { - expansionLogger.print(callTarget); - } - } - public StructuredGraph createRootGraph(StructuredGraph graph) { new GraphBuilderPhase.Instance(providers.getMetaAccess(), providers.getStampProvider(), providers.getConstantReflection(), configForRoot, TruffleCompilerImpl.Optimizations, null).apply(graph); return graph; @@ -442,223 +308,6 @@ } } - private void injectConstantCallTarget(final StructuredGraph graph, final OptimizedCallTarget constantCallTarget, PhaseContext baseContext) { - ParameterNode thisNode = graph.getParameter(0); - - /* - * Converting the call target to a Constant using the SnippetReflectionProvider is a - * workaround, we should think about a better solution. Since object constants are - * VM-specific, only the hosting VM knows how to do the conversion. - */ - thisNode.replaceAndDelete(ConstantNode.forConstant(snippetReflection.forObject(constantCallTarget), providers.getMetaAccess(), graph)); - - canonicalizer.apply(graph, baseContext); - - new IncrementalCanonicalizerPhase<>(canonicalizer, new ReplaceIntrinsicsPhase(providers.getReplacements())).apply(graph, baseContext); - } - - private void createHistogram() { - DebugHistogram histogram = Debug.createHistogram("Expanded Truffle Nodes"); - for (JavaConstant c : constantReceivers) { - String javaName = providers.getMetaAccess().lookupJavaType(c).toJavaName(false); - - // The DSL uses nested classes with redundant names - only show the inner class - int index = javaName.indexOf('$'); - if (index != -1) { - javaName = javaName.substring(index + 1); - } - - histogram.add(javaName); - - } - new DebugHistogramAsciiPrinter(TTY.out().out()).print(histogram); - } - - private boolean expandTree(StructuredGraph graph, TruffleExpansionLogger expansionLogger) { - PhaseContext phaseContext = new PhaseContext(providers); - boolean changed = false; - boolean changedInIteration; - ArrayDeque queue = new ArrayDeque<>(); - MetaAccessProvider metaAccess = providers.getMetaAccess(); - ResolvedJavaType profileClass = metaAccess.lookupJavaType(NodeCloneable.class); - do { - changedInIteration = false; - - Mark mark = null; - while (true) { - - for (MethodCallTargetNode methodCallTargetNode : graph.getNewNodes(mark).filter(MethodCallTargetNode.class)) { - if (methodCallTargetNode.invokeKind().isDirect()) { - ValueNode receiver = methodCallTargetNode.receiver(); - if (receiver != null && receiver.isConstant() && profileClass.isAssignableFrom(receiver.stamp().javaType(metaAccess))) { - queue.addFirst(methodCallTargetNode); - } else { - queue.addLast(methodCallTargetNode); - } - } - } - mark = graph.getMark(); - - if (queue.isEmpty()) { - break; - } - MethodCallTargetNode methodCallTargetNode = queue.removeFirst(); - if (!methodCallTargetNode.isAlive()) { - continue; - } - InvokeKind kind = methodCallTargetNode.invokeKind(); - try (Indent id1 = Debug.logAndIndent("try inlining %s, kind = %s", methodCallTargetNode.targetMethod(), kind)) { - if (kind.isDirect()) { - if ((TraceTruffleCompilationHistogram.getValue() || TraceTruffleCompilationDetails.getValue()) && kind == InvokeKind.Special && methodCallTargetNode.receiver().isConstant()) { - constantReceivers.add(methodCallTargetNode.receiver().asJavaConstant()); - } - - Replacements replacements = providers.getReplacements(); - StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTargetNode.targetMethod()); - - ResolvedJavaMethod targetMethod = methodCallTargetNode.targetMethod(); - if (inlineGraph == null && targetMethod.hasBytecodes() && targetMethod.canBeInlined()) { - inlineGraph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), phaseContext); - } - - if (inlineGraph != null) { - expandTreeInline(graph, phaseContext, expansionLogger, methodCallTargetNode, inlineGraph); - changed = changedInIteration = true; - } - } - } - - if (graph.getNodeCount() > TruffleCompilerOptions.TruffleGraphMaxNodes.getValue()) { - throw new BailoutException("Truffle compilation is exceeding maximum node count: %d", graph.getNodeCount()); - } - } - - } while (changedInIteration); - - return changed; - } - - private void expandTreeInline(StructuredGraph graph, PhaseContext phaseContext, TruffleExpansionLogger expansionLogger, MethodCallTargetNode methodCallTargetNode, StructuredGraph inlineGraph) { - try (Indent indent = Debug.logAndIndent("expand graph %s", methodCallTargetNode.targetMethod())) { - int nodeCountBefore = graph.getNodeCount(); - if (expansionLogger != null) { - expansionLogger.preExpand(methodCallTargetNode, inlineGraph); - } - List canonicalizedNodes = methodCallTargetNode.invoke().asNode().usages().snapshot(); - - Map inlined = InliningUtil.inline(methodCallTargetNode.invoke(), inlineGraph, false, canonicalizedNodes); - if (expansionLogger != null) { - expansionLogger.postExpand(inlined); - } - if (Debug.isDumpEnabled()) { - int nodeCountAfter = graph.getNodeCount(); - Debug.dump(graph, "After expand %s %+d (%d)", methodCallTargetNode.targetMethod().toString(), nodeCountAfter - nodeCountBefore, nodeCountAfter); - } - AbstractInlineInfo.getInlinedParameterUsages(canonicalizedNodes, inlineGraph, inlined); - canonicalizer.applyIncremental(graph, phaseContext, canonicalizedNodes); - } - } - - private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList arguments, final PhaseContext phaseContext) { - StructuredGraph graph = truffleCache.lookup(targetMethod, arguments, canonicalizer); - - if (graph != null && targetMethod.getAnnotation(ExplodeLoop.class) != null) { - assert graph.hasLoops() : graph + " does not contain a loop"; - final StructuredGraph graphCopy = graph.copy(); - final List modifiedNodes = new ArrayList<>(); - for (ParameterNode param : graphCopy.getNodes(ParameterNode.TYPE).snapshot()) { - ValueNode arg = arguments.get(param.index()); - if (arg.isConstant()) { - Constant constant = arg.asConstant(); - param.usages().snapshotTo(modifiedNodes); - param.replaceAndDelete(ConstantNode.forConstant(arg.stamp(), constant, phaseContext.getMetaAccess(), graphCopy)); - } else { - ValueNode length = GraphUtil.arrayLength(arg); - if (length != null && length.isConstant()) { - param.usages().snapshotTo(modifiedNodes); - ParameterNode newParam = graphCopy.addWithoutUnique(new ParameterNode(param.index(), param.stamp())); - param.replaceAndDelete(graphCopy.addWithoutUnique(new PiArrayNode(newParam, ConstantNode.forInt(length.asJavaConstant().asInt(), graphCopy), param.stamp()))); - } - } - } - try (Scope s = Debug.scope("TruffleUnrollLoop", targetMethod)) { - - canonicalizer.applyIncremental(graphCopy, phaseContext, modifiedNodes); - boolean unrolled; - do { - unrolled = false; - LoopsData loopsData = new LoopsData(graphCopy); - loopsData.detectedCountedLoops(); - for (LoopEx ex : innerLoopsFirst(loopsData.countedLoops())) { - if (ex.counted().isConstantMaxTripCount()) { - long constant = ex.counted().constantMaxTripCount(); - LoopTransformations.fullUnroll(ex, phaseContext, canonicalizer); - Debug.dump(graphCopy, "After loop unrolling %d times", constant); - unrolled = true; - break; - } - } - loopsData.deleteUnusedNodes(); - } while (unrolled); - } catch (Throwable e) { - throw Debug.handle(e); - } - - return graphCopy; - } else { - return graph; - } - } - - private void expandDirectCalls(StructuredGraph graph, TruffleExpansionLogger expansionLogger, TruffleInlining inlining, TruffleInliningCache inliningCache) { - PhaseContext phaseContext = new PhaseContext(providers); - - for (MethodCallTargetNode methodCallTargetNode : graph.getNodes(MethodCallTargetNode.TYPE).snapshot()) { - StructuredGraph inlineGraph = parseDirectCallGraph(phaseContext, graph, inlining, inliningCache, methodCallTargetNode); - - if (inlineGraph != null) { - expandTreeInline(graph, phaseContext, expansionLogger, methodCallTargetNode, inlineGraph); - } - } - // non inlined direct calls need to be expanded until TruffleCallBoundary. - expandTree(graph, expansionLogger); - assert noDirectCallsLeft(graph); - } - - private boolean noDirectCallsLeft(StructuredGraph graph) { - for (MethodCallTargetNode methodCallTargetNode : graph.getNodes(MethodCallTargetNode.TYPE).snapshot()) { - if (methodCallTargetNode.targetMethod().equals(callDirectMethod)) { - return false; - } - } - return true; - } - - private StructuredGraph parseDirectCallGraph(PhaseContext phaseContext, StructuredGraph caller, TruffleInlining inlining, TruffleInliningCache inliningCache, - MethodCallTargetNode methodCallTargetNode) { - OptimizedDirectCallNode callNode = resolveConstantCallNode(methodCallTargetNode); - if (callNode == null) { - return null; - } - - TruffleInliningDecision decision = getDecision(inlining, callNode); - - StructuredGraph graph; - if (decision != null && decision.isInline()) { - if (inliningCache == null) { - graph = createInlineGraph(phaseContext, caller, null, decision); - } else { - graph = inliningCache.getCachedGraph(phaseContext, caller, decision); - } - caller.getAssumptions().record(new AssumptionValidAssumption((OptimizedAssumption) decision.getTarget().getNodeRewritingAssumption())); - } else { - // we continue expansion of callDirect until we reach the callBoundary. - graph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), phaseContext); - } - - return graph; - } - private static TruffleInliningDecision getDecision(TruffleInlining inlining, OptimizedDirectCallNode callNode) { TruffleInliningDecision decision = inlining.findByCall(callNode); if (decision == null) { @@ -680,125 +329,4 @@ } return decision; } - - private OptimizedDirectCallNode resolveConstantCallNode(MethodCallTargetNode methodCallTargetNode) { - if (!methodCallTargetNode.targetMethod().equals(callDirectMethod)) { - return null; - } - - Invoke invoke = methodCallTargetNode.invoke(); - if (invoke == null) { - return null; - } - - FrameState directCallState = invoke.stateAfter(); - while (directCallState != null && !directCallState.method().equals(callSiteProxyMethod)) { - directCallState = directCallState.outerFrameState(); - } - - if (directCallState == null) { - // not a direct call. May be indirect call. - return null; - } - - if (directCallState.values().isEmpty()) { - throw new AssertionError(String.format("Frame state of method '%s' is invalid.", callDirectMethod.toString())); - } - - ValueNode node = directCallState.values().get(0); - if (!node.isConstant()) { - throw new AssertionError(String.format("Method argument for method '%s' is not constant.", callDirectMethod.toString())); - } - - JavaConstant constantCallNode = node.asJavaConstant(); - Object value = snippetReflection.asObject(Object.class, constantCallNode); - - if (!(value instanceof OptimizedDirectCallNode)) { - // might be an indirect call. - return null; - } - - return (OptimizedDirectCallNode) value; - } - - private StructuredGraph createInlineGraph(PhaseContext phaseContext, StructuredGraph caller, TruffleInliningCache cache, TruffleInliningDecision decision) { - try (Scope s = Debug.scope("GuestLanguageInlinedGraph", new DebugDumpScope(decision.getTarget().toString()))) { - OptimizedCallTarget target = decision.getTarget(); - StructuredGraph inlineGraph = createInlineGraph(target.toString(), caller); - injectConstantCallTarget(inlineGraph, decision.getTarget(), phaseContext); - TruffleExpansionLogger expansionLogger = null; - if (TraceTruffleExpansion.getValue()) { - expansionLogger = new TruffleExpansionLogger(providers, inlineGraph); - } - expandTree(inlineGraph, expansionLogger); - expandDirectCalls(inlineGraph, expansionLogger, decision, cache); - - if (expansionLogger != null) { - expansionLogger.print(target); - } - return inlineGraph; - } catch (Throwable e) { - throw Debug.handle(e); - } - } - - private static List innerLoopsFirst(Collection loops) { - ArrayList sortedLoops = new ArrayList<>(loops); - Collections.sort(sortedLoops, new Comparator() { - - @Override - public int compare(LoopEx o1, LoopEx o2) { - return o2.loop().getDepth() - o1.loop().getDepth(); - } - }); - return sortedLoops; - } - - private final class TruffleInliningCache { - - private final Map cache; - - public TruffleInliningCache() { - this.cache = new HashMap<>(); - } - - public StructuredGraph getCachedGraph(PhaseContext phaseContext, StructuredGraph caller, TruffleInliningDecision decision) { - CacheKey cacheKey = new CacheKey(decision); - StructuredGraph inlineGraph = cache.get(cacheKey); - if (inlineGraph == null) { - inlineGraph = createInlineGraph(phaseContext, caller, this, decision); - cache.put(cacheKey, inlineGraph); - } - return inlineGraph; - } - - private final class CacheKey { - - public final TruffleInliningDecision decision; - - public CacheKey(TruffleInliningDecision decision) { - this.decision = decision; - /* - * If decision.isInline() is not true CacheKey#hashCode does not match - * CacheKey#equals - */ - assert decision.isInline(); - } - - @Override - public int hashCode() { - return decision.getTarget().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof CacheKey)) { - return false; - } - CacheKey other = (CacheKey) obj; - return decision.isSameAs(other.decision); - } - } - } - } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Tue Mar 31 19:01:07 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +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.truffle; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.phases.common.*; - -public interface TruffleCache { - - /** - * Returns a cached graph for a method with given arguments. - */ - StructuredGraph lookup(final ResolvedJavaMethod method, final NodeInputList arguments, final CanonicalizerPhase finalCanonicalizer); -} diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Tue Mar 31 19:01:07 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,314 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle; - -import java.util.*; -import java.util.Map.Entry; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.debug.*; -import com.oracle.graal.debug.Debug.Scope; -import com.oracle.graal.graph.Graph.Mark; -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.Node; -import com.oracle.graal.graph.spi.*; -import com.oracle.graal.graphbuilderconf.*; -import com.oracle.graal.java.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.nodes.util.*; -import com.oracle.graal.phases.*; -import com.oracle.graal.phases.common.*; -import com.oracle.graal.phases.common.inlining.*; -import com.oracle.graal.phases.tiers.*; -import com.oracle.graal.phases.util.*; -import com.oracle.graal.truffle.debug.*; -import com.oracle.graal.truffle.phases.*; -import com.oracle.graal.virtual.phases.ea.*; -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.nodes.*; - -/** - * Implementation of a cache for Truffle graphs for improving partial evaluation time. - */ -public class TruffleCacheImpl implements TruffleCache { - - private final Providers providers; - private final GraphBuilderConfiguration config; - private final OptimisticOptimizations optimisticOptimizations; - - private final HashMap, StructuredGraph> cache = new HashMap<>(); - private final HashMap, Long> lastUsed = new HashMap<>(); - private final StructuredGraph markerGraph = new StructuredGraph(AllowAssumptions.NO); - - private final ResolvedJavaType stringBuilderClass; - private final ResolvedJavaType runtimeExceptionClass; - private final ResolvedJavaType errorClass; - private final ResolvedJavaType controlFlowExceptionClass; - - private long counter; - - public TruffleCacheImpl(Providers providers, GraphBuilderConfiguration config, OptimisticOptimizations optimisticOptimizations) { - this.providers = providers; - this.config = config; - this.optimisticOptimizations = optimisticOptimizations; - - this.stringBuilderClass = providers.getMetaAccess().lookupJavaType(StringBuilder.class); - this.runtimeExceptionClass = providers.getMetaAccess().lookupJavaType(RuntimeException.class); - this.errorClass = providers.getMetaAccess().lookupJavaType(Error.class); - this.controlFlowExceptionClass = providers.getMetaAccess().lookupJavaType(ControlFlowException.class); - } - - private static List computeCacheKey(ResolvedJavaMethod method, NodeInputList arguments) { - List key = new ArrayList<>(arguments.size() + 1); - key.add(method); - for (ValueNode v : arguments) { - if (v.getKind() == Kind.Object) { - key.add(v.stamp()); - } - } - return key; - } - - public StructuredGraph lookup(ResolvedJavaMethod method, NodeInputList arguments, CanonicalizerPhase canonicalizer) { - List key = computeCacheKey(method, arguments); - StructuredGraph resultGraph = cache.get(key); - if (resultGraph == markerGraph) { - // compilation failed previously, don't try again - return null; - } - StructuredGraph graph = cacheLookup(method, arguments, canonicalizer); - assert graph != markerGraph : "markerGraph should not leak out"; - return graph; - } - - private StructuredGraph cacheLookup(ResolvedJavaMethod method, NodeInputList arguments, CanonicalizerPhase canonicalizer) { - if (method.getAnnotation(CompilerDirectives.TruffleBoundary.class) != null) { - return null; - } - - List key = computeCacheKey(method, arguments); - StructuredGraph resultGraph = cache.get(key); - if (resultGraph != null) { - lastUsed.put(key, counter++); - return resultGraph; - } - - if (lastUsed.values().size() >= TruffleCompilerOptions.TruffleMaxCompilationCacheSize.getValue()) { - lookupExceedsMaxSize(); - } - - StructuredGraph graph = new StructuredGraph(method, AllowAssumptions.NO); - PhaseContext phaseContext = new PhaseContext(providers); - try (Scope s = Debug.scope("TruffleCache", providers.getMetaAccess(), method)) { - - graph = parseGraph(graph, phaseContext); - if (graph == null) { - return null; - } - } catch (Throwable e) { - throw Debug.handle(e); - } - - try (Scope s = Debug.scope("TruffleCache", providers.getMetaAccess(), method, graph)) { - - lastUsed.put(key, counter++); - cache.put(key, markerGraph); - - for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) { - if (param.getKind() == Kind.Object) { - ValueNode actualArgument = arguments.get(param.index()); - param.setStamp(param.stamp().join(actualArgument.stamp())); - } - } - - // Intrinsify methods. - new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph); - - // Convert deopt to guards. - new ConvertDeoptimizeToGuardPhase().apply(graph, phaseContext); - - PartialEscapePhase partialEscapePhase = new PartialEscapePhase(false, canonicalizer); - - Mark mark = null; - while (true) { - - partialEscapePhase.apply(graph, phaseContext); - - // Conditional elimination. - ConditionalEliminationPhase conditionalEliminationPhase = new ConditionalEliminationPhase(); - conditionalEliminationPhase.apply(graph); - - // Canonicalize / constant propagate. - canonicalizer.apply(graph, phaseContext); - - boolean inliningProgress = false; - for (MethodCallTargetNode methodCallTarget : graph.getNodes(MethodCallTargetNode.TYPE)) { - if (!graph.getMark().equals(mark)) { - mark = lookupProcessMacroSubstitutions(graph, mark); - } - if (methodCallTarget.isAlive() && methodCallTarget.invoke() != null && shouldInline(methodCallTarget)) { - inliningProgress = true; - lookupDoInline(graph, phaseContext, canonicalizer, methodCallTarget); - } - } - - // Convert deopt to guards. - new ConvertDeoptimizeToGuardPhase().apply(graph, phaseContext); - - new EarlyReadEliminationPhase(canonicalizer).apply(graph, phaseContext); - - if (!inliningProgress) { - break; - } - } - - if (TruffleCompilerOptions.TraceTrufflePerformanceWarnings.getValue()) { - int warnNodeCount = TruffleCompilerOptions.TrufflePerformanceWarningGraalNodeCount.getValue(); - if (graph.getNodeCount() > warnNodeCount) { - Map map = new LinkedHashMap<>(); - map.put("nodeCount", graph.getNodeCount()); - map.put("method", method.toString()); - TracePerformanceWarningsListener.logPerformanceWarning(String.format("Method on fast path contains more than %d graal nodes.", warnNodeCount), map); - - try (Scope s2 = Debug.scope("TrufflePerformanceWarnings")) { - Debug.dump(graph, "performance warning"); - } - } - } - - cache.put(key, graph); - if (TruffleCompilerOptions.TraceTruffleCacheDetails.getValue()) { - TTY.println(String.format("[truffle] added to graph cache method %s with %d nodes.", method, graph.getNodeCount())); - } - return graph; - } catch (Throwable e) { - throw Debug.handle(e); - } - } - - private void lookupExceedsMaxSize() { - List lastUsedList = new ArrayList<>(); - for (long l : lastUsed.values()) { - lastUsedList.add(l); - } - Collections.sort(lastUsedList); - long mid = lastUsedList.get(lastUsedList.size() / 2); - - List> toRemoveList = new ArrayList<>(); - for (Entry, Long> entry : lastUsed.entrySet()) { - if (entry.getValue() < mid) { - toRemoveList.add(entry.getKey()); - } - } - - for (List entry : toRemoveList) { - cache.remove(entry); - lastUsed.remove(entry); - } - } - - private Mark lookupProcessMacroSubstitutions(StructuredGraph graph, Mark mark) { - // Make sure macro substitutions such as - // CompilerDirectives.transferToInterpreter get processed first. - for (Node newNode : graph.getNewNodes(mark)) { - if (newNode instanceof MethodCallTargetNode) { - MethodCallTargetNode methodCallTargetNode = (MethodCallTargetNode) newNode; - tryCutOffRuntimeExceptionsAndErrors(methodCallTargetNode); - } - } - return graph.getMark(); - } - - private void lookupDoInline(StructuredGraph graph, PhaseContext phaseContext, CanonicalizerPhase canonicalizer, MethodCallTargetNode methodCallTarget) { - List canonicalizerUsages = new ArrayList<>(); - for (Node n : methodCallTarget.invoke().asNode().usages()) { - if (n instanceof Canonicalizable) { - canonicalizerUsages.add(n); - } - } - List argumentSnapshot = methodCallTarget.arguments().snapshot(); - Mark beforeInvokeMark = graph.getMark(); - expandInvoke(methodCallTarget, canonicalizer); - for (Node arg : argumentSnapshot) { - if (arg != null) { - for (Node argUsage : arg.usages()) { - if (graph.isNew(beforeInvokeMark, argUsage) && argUsage instanceof Canonicalizable) { - canonicalizerUsages.add(argUsage); - } - } - } - } - canonicalizer.applyIncremental(graph, phaseContext, canonicalizerUsages); - } - - protected StructuredGraph parseGraph(StructuredGraph graph, final PhaseContext phaseContext) { - new GraphBuilderPhase.Instance(phaseContext.getMetaAccess(), phaseContext.getStampProvider(), null, config, optimisticOptimizations, null).apply(graph); - return graph; - } - - private void expandInvoke(MethodCallTargetNode methodCallTargetNode, CanonicalizerPhase canonicalizer) { - StructuredGraph inlineGraph = providers.getReplacements().getMethodSubstitution(methodCallTargetNode.targetMethod()); - if (inlineGraph == null) { - inlineGraph = cacheLookup(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), canonicalizer); - } - if (inlineGraph == null) { - return; - } - if (inlineGraph == this.markerGraph) { - // Can happen for recursive calls. - throw GraphUtil.approxSourceException(methodCallTargetNode, new IllegalStateException("Found illegal recursive call to " + methodCallTargetNode.targetMethod() + - ", must annotate such calls with @TruffleBoundary!")); - } - Invoke invoke = methodCallTargetNode.invoke(); - InliningUtil.inline(invoke, inlineGraph, true, null); - } - - private boolean tryCutOffRuntimeExceptionsAndErrors(MethodCallTargetNode methodCallTargetNode) { - if (methodCallTargetNode.targetMethod().isConstructor()) { - ResolvedJavaType declaringClass = methodCallTargetNode.targetMethod().getDeclaringClass(); - ResolvedJavaType exceptionType = Objects.requireNonNull(StampTool.typeOrNull(methodCallTargetNode.receiver().stamp())); - - boolean removeAllocation = runtimeExceptionClass.isAssignableFrom(declaringClass) || errorClass.isAssignableFrom(declaringClass); - boolean isControlFlowException = controlFlowExceptionClass.isAssignableFrom(exceptionType); - if (removeAllocation && !isControlFlowException) { - DeoptimizeNode deoptNode = methodCallTargetNode.graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.UnreachedCode)); - FixedNode invokeNode = methodCallTargetNode.invoke().asNode(); - invokeNode.replaceAtPredecessor(deoptNode); - GraphUtil.killCFG(invokeNode); - return true; - } - } - return false; - } - - protected boolean shouldInline(MethodCallTargetNode methodCallTargetNode) { - boolean result = methodCallTargetNode.invokeKind().isDirect() && methodCallTargetNode.targetMethod().hasBytecodes() && methodCallTargetNode.targetMethod().canBeInlined() && - methodCallTargetNode.targetMethod().getAnnotation(ExplodeLoop.class) == null && - methodCallTargetNode.targetMethod().getAnnotation(CompilerDirectives.TruffleBoundary.class) == null && - !methodCallTargetNode.targetMethod().getDeclaringClass().equals(stringBuilderClass); - return result; - } -} diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Tue Mar 31 19:15:45 2015 -0700 @@ -43,7 +43,6 @@ import com.oracle.graal.lir.phases.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; @@ -66,7 +65,6 @@ private final Backend backend; private final GraphBuilderConfiguration config; private final RuntimeProvider runtime; - private final TruffleCache truffleCache; private final GraalTruffleCompilationListener compilationNotify; // @formatter:off @@ -89,34 +87,22 @@ this.runtime = Graal.getRequiredCapability(RuntimeProvider.class); this.compilationNotify = graalTruffleRuntime.getCompilationNotify(); this.backend = runtime.getHostBackend(); - Replacements truffleReplacements = graalTruffleRuntime.getReplacements(); Providers backendProviders = backend.getProviders(); ConstantReflectionProvider constantReflection = new TruffleConstantReflectionProvider(backendProviders.getConstantReflection(), backendProviders.getMetaAccess()); - if (!TruffleCompilerOptions.FastPE.getValue()) { - backendProviders = backendProviders.copyWith(truffleReplacements); - } this.providers = backendProviders.copyWith(constantReflection); this.suites = backend.getSuites().getDefaultSuites(); this.lirSuites = backend.getSuites().getDefaultLIRSuites(); ResolvedJavaType[] skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess()); - Plugins plugins; - if (TruffleCompilerOptions.FastPE.getValue()) { - GraphBuilderPhase phase = (GraphBuilderPhase) backend.getSuites().getDefaultGraphBuilderSuite().findPhase(GraphBuilderPhase.class).previous(); - InvocationPlugins invocationPlugins = new InvocationPlugins(phase.getGraphBuilderConfig().getPlugins().getInvocationPlugins()); - plugins = new Plugins(invocationPlugins); - TruffleGraphBuilderPlugins.registerInvocationPlugins(providers.getMetaAccess(), invocationPlugins); - } else { - plugins = new Plugins(new InvocationPlugins(backendProviders.getMetaAccess())); - } + GraphBuilderPhase phase = (GraphBuilderPhase) backend.getSuites().getDefaultGraphBuilderSuite().findPhase(GraphBuilderPhase.class).previous(); + InvocationPlugins invocationPlugins = new InvocationPlugins(phase.getGraphBuilderConfig().getPlugins().getInvocationPlugins()); + Plugins plugins = new Plugins(invocationPlugins); + TruffleGraphBuilderPlugins.registerInvocationPlugins(providers.getMetaAccess(), invocationPlugins); this.config = GraphBuilderConfiguration.getDefault(plugins).withSkippedExceptionTypes(skippedExceptionTypes); - GraphBuilderConfiguration eagerConfig = GraphBuilderConfiguration.getEagerDefault(plugins).withSkippedExceptionTypes(skippedExceptionTypes); - this.truffleCache = new TruffleCacheImpl(providers, eagerConfig, TruffleCompilerImpl.Optimizations); - - this.partialEvaluator = new PartialEvaluator(providers, config, truffleCache, Graal.getRequiredCapability(SnippetReflectionProvider.class)); + this.partialEvaluator = new PartialEvaluator(providers, config, Graal.getRequiredCapability(SnippetReflectionProvider.class)); if (Debug.isEnabled()) { DebugEnvironment.initialize(System.out); @@ -177,7 +163,7 @@ CodeCacheProvider codeCache = providers.getCodeCache(); CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false); CompilationResult compilationResult = new CompilationResult(name); - result = compileGraph(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, graphBuilderSuite, Optimizations, getProfilingInfo(graph), speculationLog, suites, + result = compileGraph(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), graphBuilderSuite, Optimizations, getProfilingInfo(graph), speculationLog, suites, lirSuites, compilationResult, CompilationResultBuilderFactory.Default); } catch (Throwable e) { throw Debug.handle(e); diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Tue Mar 31 19:15:45 2015 -0700 @@ -98,6 +98,12 @@ @Option(help = "Experimental. New splitting only: Split everything aggressively. ", type = OptionType.Debug) public static final OptionValue TruffleSplittingAggressive = new OptionValue<>(false); + @Option(help = "Enable on stack replacement for Truffle loops.", type = OptionType.Debug) + public static final OptionValue TruffleOSR = new OptionValue<>(true); + + @Option(help = "Number of loop iterations until on-stack-replacement compilation is triggered.", type = OptionType.Debug) + public static final OptionValue TruffleOSRCompilationThreshold = new OptionValue<>(10000); + @Option(help = "Disable call target splitting if tree size exceeds this limit", type = OptionType.Debug) public static final OptionValue TruffleSplittingMaxCalleeSize = new OptionValue<>(100); @@ -138,9 +144,6 @@ @Option(help = "Print information for compilation queuing", type = OptionType.Debug) public static final OptionValue TraceTruffleCompilationDetails = new OptionValue<>(false); - @Option(help = "Print a node count histogram after each compilation", type = OptionType.Debug) - public static final OptionValue TraceTruffleCompilationHistogram = new OptionValue<>(false); - @Option(help = "Print all polymorphic and generic nodes after each compilation", type = OptionType.Debug) public static final OptionValue TraceTruffleCompilationPolymorphism = new OptionValue<>(false); @@ -191,8 +194,5 @@ @Option(help = "Print additional more verbose Truffle compilation statistics at the end of a run.", type = OptionType.Debug) public static final OptionValue TruffleCompilationStatisticDetails = new OptionValue<>(false); - - @Option(help = "Experimental new version of the partial evaluator.", type = OptionType.Debug) - public static final OptionValue FastPE = new OptionValue<>(true); // @formatter:on } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java Tue Mar 31 19:01:07 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +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.truffle; - -import java.util.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.replacements.*; -import com.oracle.graal.compiler.common.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.phases.util.*; -import com.oracle.graal.replacements.*; - -/** - * Custom {@link Replacements} for Truffle compilation. - */ -public abstract class TruffleReplacements extends ReplacementsImpl { - - private final Replacements graalReplacements; - - protected TruffleReplacements(Providers providers, SnippetReflectionProvider snippetReflection) { - super(providers, snippetReflection, providers.getCodeCache().getTarget()); - this.graalReplacements = providers.getReplacements(); - } - - @Override - public StructuredGraph getSnippet(ResolvedJavaMethod method, Object[] args) { - return graalReplacements.getSnippet(method, null, args); - } - - @Override - public StructuredGraph getMethodSubstitution(ResolvedJavaMethod method) { - StructuredGraph graph = graalReplacements.getMethodSubstitution(method); - if (graph == null) { - return super.getMethodSubstitution(method); - } - return graph; - } - - @Override - public Collection getAllReplacements() { - throw GraalInternalError.shouldNotReachHere(); - } - - @Override - public boolean isForcedSubstitution(ResolvedJavaMethod method) { - return graalReplacements.isForcedSubstitution(method) || super.isForcedSubstitution(method); - } - - @Override - public void registerSnippetTemplateCache(SnippetTemplateCache templates) { - throw GraalInternalError.shouldNotReachHere(); - } - - @Override - public T getSnippetTemplateCache(Class templatesClass) { - return graalReplacements.getSnippetTemplateCache(templatesClass); - } -} diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Tue Mar 31 19:01:07 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +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.virtual.phases.ea; - -import static com.oracle.graal.compiler.common.GraalOptions.*; -import static com.oracle.graal.debug.Debug.*; -import static com.oracle.graal.phases.common.DeadCodeEliminationPhase.Optionality.*; - -import java.util.*; - -import com.oracle.graal.debug.*; -import com.oracle.graal.debug.Debug.Scope; -import com.oracle.graal.nodes.*; -import com.oracle.graal.phases.common.*; -import com.oracle.graal.phases.common.inlining.*; -import com.oracle.graal.phases.tiers.*; - -public class IterativeInliningPhase extends AbstractInliningPhase { - - private final CanonicalizerPhase canonicalizer; - - public IterativeInliningPhase(CanonicalizerPhase canonicalizer) { - this.canonicalizer = canonicalizer; - } - - public static final void trace(String format, Object... obj) { - if (TraceEscapeAnalysis.getValue() && Debug.isLogEnabled()) { - Debug.logv(format, obj); - } - } - - @Override - protected void run(final StructuredGraph graph, final HighTierContext context) { - runIterations(graph, true, context); - runIterations(graph, false, context); - } - - private void runIterations(final StructuredGraph graph, final boolean simple, final HighTierContext context) { - for (int iteration = 0; iteration < EscapeAnalysisIterations.getValue(); iteration++) { - try (Scope s = Debug.scope(isEnabled() ? "iteration " + iteration : null)) { - boolean progress = false; - PartialEscapePhase ea = new PartialEscapePhase(false, canonicalizer); - boolean eaResult = ea.runAnalysis(graph, context); - progress |= eaResult; - - Map hints = PEAInliningHints.getValue() ? PartialEscapePhase.getHints(graph) : null; - - InliningPhase inlining = new InliningPhase(hints, new CanonicalizerPhase()); - inlining.setMaxMethodsPerInlining(simple ? 1 : Integer.MAX_VALUE); - inlining.apply(graph, context); - progress |= inlining.getInliningCount() > 0; - - new DeadCodeEliminationPhase(Optional).apply(graph); - - if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { - canonicalizer.apply(graph, context); - new IterativeConditionalEliminationPhase(canonicalizer, false).apply(graph, context); - } - if (!progress) { - break; - } - } catch (Throwable e) { - throw Debug.handle(e); - } - } - } -} diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationBlockState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationBlockState.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationBlockState.java Tue Mar 31 19:15:45 2015 -0700 @@ -33,20 +33,23 @@ final HashMap readCache; - static class ReadCacheEntry { + static final class ReadCacheEntry { public final LocationIdentity identity; public final ValueNode object; + public final int index; - public ReadCacheEntry(LocationIdentity identity, ValueNode object) { + public ReadCacheEntry(LocationIdentity identity, ValueNode object, int index) { this.identity = identity; this.object = object; + this.index = index; } @Override public int hashCode() { int result = 31 + ((identity == null) ? 0 : identity.hashCode()); - return 31 * result + ((object == null) ? 0 : object.hashCode()); + result = 31 * result + ((object == null) ? 0 : object.hashCode()); + return result * 31 + index; } @Override @@ -60,7 +63,7 @@ @Override public String toString() { - return object + ":" + identity; + return index == -1 ? (object + ":" + identity) : (object + "[" + index + "]:" + identity); } } @@ -83,7 +86,7 @@ if (virtual instanceof VirtualInstanceNode) { VirtualInstanceNode instance = (VirtualInstanceNode) virtual; for (int i = 0; i < instance.entryCount(); i++) { - readCache.put(new ReadCacheEntry(instance.field(i).getLocationIdentity(), representation), values.get(i)); + readCache.put(new ReadCacheEntry(instance.field(i).getLocationIdentity(), representation, -1), values.get(i)); } } } @@ -96,7 +99,7 @@ return super.equivalentTo(other); } - public void addReadCache(ValueNode object, LocationIdentity identity, ValueNode value, PartialEscapeClosure closure) { + public void addReadCache(ValueNode object, LocationIdentity identity, int index, ValueNode value, PartialEscapeClosure closure) { ValueNode cacheObject; ObjectState obj = closure.getObjectState(this, object); if (obj != null) { @@ -105,10 +108,10 @@ } else { cacheObject = object; } - readCache.put(new ReadCacheEntry(identity, cacheObject), value); + readCache.put(new ReadCacheEntry(identity, cacheObject, index), value); } - public ValueNode getReadCache(ValueNode object, LocationIdentity identity, PartialEscapeClosure closure) { + public ValueNode getReadCache(ValueNode object, LocationIdentity identity, int index, PartialEscapeClosure closure) { ValueNode cacheObject; ObjectState obj = closure.getObjectState(this, object); if (obj != null) { @@ -117,7 +120,7 @@ } else { cacheObject = object; } - ValueNode cacheValue = readCache.get(new ReadCacheEntry(identity, cacheObject)); + ValueNode cacheValue = readCache.get(new ReadCacheEntry(identity, cacheObject, index)); obj = closure.getObjectState(this, cacheValue); if (obj != null) { assert !obj.isVirtual(); @@ -133,11 +136,11 @@ readCache.clear(); } - public void killReadCache(LocationIdentity identity) { + public void killReadCache(LocationIdentity identity, int index) { Iterator> iter = readCache.entrySet().iterator(); while (iter.hasNext()) { - Map.Entry entry = iter.next(); - if (entry.getKey().identity.equals(identity)) { + ReadCacheEntry entry = iter.next().getKey(); + if (entry.identity.equals(identity) && (index == -1 || entry.index == -1 || index == entry.index)) { iter.remove(); } } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Tue Mar 31 19:15:45 2015 -0700 @@ -38,6 +38,14 @@ public class PEReadEliminationClosure extends PartialEscapeClosure { + private static final EnumMap UNBOX_LOCATIONS; + static { + UNBOX_LOCATIONS = new EnumMap<>(Kind.class); + for (Kind kind : Kind.values()) { + UNBOX_LOCATIONS.put(kind, NamedLocationIdentity.immutable("PEA unbox " + kind.getJavaName())); + } + } + public PEReadEliminationClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) { super(schedule, metaAccess, constantReflection); } @@ -57,8 +65,14 @@ return processLoadField((LoadFieldNode) node, state, effects); } else if (node instanceof StoreFieldNode) { return processStoreField((StoreFieldNode) node, state, effects); + } else if (node instanceof LoadIndexedNode) { + return processLoadIndexed((LoadIndexedNode) node, state, effects); + } else if (node instanceof StoreIndexedNode) { + return processStoreIndexed((StoreIndexedNode) node, state, effects); } else if (node instanceof ArrayLengthNode) { return processArrayLength((ArrayLengthNode) node, state, effects); + } else if (node instanceof UnboxNode) { + return processUnbox((UnboxNode) node, state, effects); } else if (node instanceof MemoryCheckpoint.Single) { METRIC_MEMORYCHECKPOINT.increment(); LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity(); @@ -75,13 +89,13 @@ private boolean processArrayLength(ArrayLengthNode length, PEReadEliminationBlockState state, GraphEffectList effects) { ValueNode array = GraphUtil.unproxify(length.array()); - ValueNode cachedValue = state.getReadCache(array, ARRAY_LENGTH_LOCATION, this); + ValueNode cachedValue = state.getReadCache(array, ARRAY_LENGTH_LOCATION, -1, this); if (cachedValue != null) { effects.replaceAtUsages(length, cachedValue); addScalarAlias(length, cachedValue); return true; } else { - state.addReadCache(array, ARRAY_LENGTH_LOCATION, length, this); + state.addReadCache(array, ARRAY_LENGTH_LOCATION, -1, length, this); } return false; } @@ -89,7 +103,7 @@ private boolean processStoreField(StoreFieldNode store, PEReadEliminationBlockState state, GraphEffectList effects) { if (!store.isVolatile()) { ValueNode object = GraphUtil.unproxify(store.object()); - ValueNode cachedValue = state.getReadCache(object, store.field().getLocationIdentity(), this); + ValueNode cachedValue = state.getReadCache(object, store.field().getLocationIdentity(), -1, this); ValueNode value = getScalarAlias(store.value()); boolean result = false; @@ -97,8 +111,8 @@ effects.deleteNode(store); result = true; } - state.killReadCache(store.field().getLocationIdentity()); - state.addReadCache(object, store.field().getLocationIdentity(), value, this); + state.killReadCache(store.field().getLocationIdentity(), -1); + state.addReadCache(object, store.field().getLocationIdentity(), -1, value, this); return result; } else { processIdentity(state, any()); @@ -111,14 +125,67 @@ processIdentity(state, any()); } else { ValueNode object = GraphUtil.unproxify(load.object()); - ValueNode cachedValue = state.getReadCache(object, load.field().getLocationIdentity(), this); + ValueNode cachedValue = state.getReadCache(object, load.field().getLocationIdentity(), -1, this); if (cachedValue != null) { effects.replaceAtUsages(load, cachedValue); addScalarAlias(load, cachedValue); return true; } else { - state.addReadCache(object, load.field().getLocationIdentity(), load, this); + state.addReadCache(object, load.field().getLocationIdentity(), -1, load, this); + } + } + return false; + } + + private boolean processStoreIndexed(StoreIndexedNode store, PEReadEliminationBlockState state, GraphEffectList effects) { + LocationIdentity arrayLocation = NamedLocationIdentity.getArrayLocation(store.elementKind()); + if (store.index().isConstant()) { + int index = ((JavaConstant) store.index().asConstant()).asInt(); + ValueNode object = GraphUtil.unproxify(store.array()); + ValueNode cachedValue = state.getReadCache(object, arrayLocation, index, this); + + ValueNode value = getScalarAlias(store.value()); + boolean result = false; + if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) { + effects.deleteNode(store); + result = true; } + state.killReadCache(arrayLocation, index); + state.addReadCache(object, arrayLocation, index, value, this); + return result; + } else { + state.killReadCache(arrayLocation, -1); + } + return false; + } + + private boolean processLoadIndexed(LoadIndexedNode load, PEReadEliminationBlockState state, GraphEffectList effects) { + if (load.index().isConstant()) { + int index = ((JavaConstant) load.index().asConstant()).asInt(); + LocationIdentity arrayLocation = NamedLocationIdentity.getArrayLocation(load.elementKind()); + ValueNode object = GraphUtil.unproxify(load.array()); + ValueNode cachedValue = state.getReadCache(object, arrayLocation, index, this); + if (cachedValue != null) { + effects.replaceAtUsages(load, cachedValue); + addScalarAlias(load, cachedValue); + return true; + } else { + state.addReadCache(object, arrayLocation, index, load, this); + } + } + return false; + } + + private boolean processUnbox(UnboxNode unbox, PEReadEliminationBlockState state, GraphEffectList effects) { + ValueNode object = GraphUtil.unproxify(unbox.getValue()); + LocationIdentity identity = UNBOX_LOCATIONS.get(unbox.getBoxingKind()); + ValueNode cachedValue = state.getReadCache(object, identity, -1, this); + if (cachedValue != null) { + effects.replaceAtUsages(unbox, cachedValue); + addScalarAlias(unbox, cachedValue); + return true; + } else { + state.addReadCache(object, identity, -1, unbox, this); } return false; } @@ -127,7 +194,7 @@ if (identity.isAny()) { state.killReadCache(); } else { - state.killReadCache(identity); + state.killReadCache(identity, -1); } } @@ -138,7 +205,7 @@ if (exitNode.graph().hasValueProxies()) { for (Map.Entry entry : exitState.getReadCache().entrySet()) { if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) { - ValueNode value = exitState.getReadCache(entry.getKey().object, entry.getKey().identity, this); + ValueNode value = exitState.getReadCache(entry.getKey().object, entry.getKey().identity, entry.getKey().index, this); if (!(value instanceof ProxyNode) || ((ProxyNode) value).proxyPoint() != exitNode) { ProxyNode proxy = new ValueProxyNode(value, exitNode); effects.addFloatingNode(proxy, "readCacheProxy"); @@ -192,7 +259,7 @@ PhiNode phiNode = getPhi(entry, value.stamp().unrestricted()); mergeEffects.addFloatingNode(phiNode, "mergeReadCache"); for (int i = 0; i < states.size(); i++) { - afterMergeEffects.addPhiInput(phiNode, states.get(i).getReadCache(key.object, key.identity, PEReadEliminationClosure.this)); + afterMergeEffects.addPhiInput(phiNode, states.get(i).getReadCache(key.object, key.identity, key.index, PEReadEliminationClosure.this)); } newState.readCache.put(key, phiNode); } else if (value != null) { @@ -203,7 +270,7 @@ if (phi.getKind() == Kind.Object) { for (Map.Entry entry : states.get(0).readCache.entrySet()) { if (entry.getKey().object == phi.valueAt(0)) { - mergeReadCachePhi(phi, entry.getKey().identity, states); + mergeReadCachePhi(phi, entry.getKey().identity, entry.getKey().index, states); } } @@ -211,22 +278,22 @@ } } - private void mergeReadCachePhi(PhiNode phi, LocationIdentity identity, List states) { + private void mergeReadCachePhi(PhiNode phi, LocationIdentity identity, int index, List states) { ValueNode[] values = new ValueNode[phi.valueCount()]; for (int i = 0; i < phi.valueCount(); i++) { - ValueNode value = states.get(i).getReadCache(phi.valueAt(i), identity, PEReadEliminationClosure.this); + ValueNode value = states.get(i).getReadCache(phi.valueAt(i), identity, index, PEReadEliminationClosure.this); if (value == null) { return; } values[i] = value; } - PhiNode phiNode = getPhi(new ReadCacheEntry(identity, phi), values[0].stamp().unrestricted()); + PhiNode phiNode = getPhi(new ReadCacheEntry(identity, phi, index), values[0].stamp().unrestricted()); mergeEffects.addFloatingNode(phiNode, "mergeReadCachePhi"); for (int i = 0; i < values.length; i++) { afterMergeEffects.addPhiInput(phiNode, values[i]); } - newState.readCache.put(new ReadCacheEntry(identity, phi), phiNode); + newState.readCache.put(new ReadCacheEntry(identity, phi, index), phiNode); } } } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java Tue Mar 31 19:15:45 2015 -0700 @@ -26,19 +26,14 @@ import static com.oracle.graal.virtual.phases.ea.PartialEscapePhase.Options.*; import java.util.*; -import java.util.function.*; -import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; -import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.options.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; -import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.schedule.*; import com.oracle.graal.phases.tiers.*; @@ -94,44 +89,4 @@ return new PartialEscapeClosure.Final(schedule, context.getMetaAccess(), context.getConstantReflection()); } } - - public static Map getHints(StructuredGraph graph) { - ToDoubleFunction probabilities = new FixedNodeProbabilityCache(); - Map hints = null; - for (CommitAllocationNode commit : graph.getNodes().filter(CommitAllocationNode.class)) { - double sum = 0; - double invokeSum = 0; - for (Node commitUsage : commit.usages()) { - for (Node usage : commitUsage.usages()) { - if (usage instanceof FixedNode) { - sum += probabilities.applyAsDouble((FixedNode) usage); - } else { - if (usage instanceof MethodCallTargetNode) { - invokeSum += probabilities.applyAsDouble(((MethodCallTargetNode) usage).invoke().asNode()); - } - for (Node secondLevelUage : usage.usages()) { - if (secondLevelUage instanceof FixedNode) { - sum += probabilities.applyAsDouble(((FixedNode) secondLevelUage)); - } - } - } - } - } - // TODO(lstadler) get rid of this magic number - if (sum > 100 && invokeSum > 0) { - for (Node commitUsage : commit.usages()) { - for (Node usage : commitUsage.usages()) { - if (usage instanceof MethodCallTargetNode) { - if (hints == null) { - hints = CollectionsFactory.newMap(); - } - Invoke invoke = ((MethodCallTargetNode) usage).invoke(); - hints.put(invoke, sum / invokeSum); - } - } - } - } - } - return hints; - } } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ExactClassValueProfile.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ExactClassValueProfile.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ExactClassValueProfile.java Tue Mar 31 19:15:45 2015 -0700 @@ -40,14 +40,16 @@ @SuppressWarnings("unchecked") @Override public T profile(T value) { - if (cachedClass != null && cachedClass.isInstance(value)) { - return (T) cachedClass.cast(value); - } else { - CompilerDirectives.transferToInterpreterAndInvalidate(); - if (cachedClass == null && value != null) { - cachedClass = value.getClass(); + if (cachedClass != Object.class) { + if (cachedClass != null && cachedClass.isInstance(value)) { + return (T) cachedClass.cast(value); } else { - cachedClass = Object.class; + CompilerDirectives.transferToInterpreterAndInvalidate(); + if (cachedClass == null && value != null) { + cachedClass = value.getClass(); + } else { + cachedClass = Object.class; + } } } return value; diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java Tue Mar 31 19:15:45 2015 -0700 @@ -53,27 +53,42 @@ public Object profile(Object value) { Object snapshot = this.cachedValue; if (snapshot != GENERIC) { - if (snapshot instanceof Byte && value instanceof Byte && (byte) snapshot == (byte) value) { - return snapshot; - } else if (snapshot instanceof Short && value instanceof Short && (short) snapshot == (short) value) { - return snapshot; - } else if (snapshot instanceof Integer && value instanceof Integer && (int) snapshot == (int) value) { - return snapshot; - } else if (snapshot instanceof Long && value instanceof Long && (long) snapshot == (long) value) { - return snapshot; - } else if (snapshot instanceof Float && value instanceof Float && exactCompare((float) snapshot, (float) value)) { - return snapshot; - } else if (snapshot instanceof Double && value instanceof Double && exactCompare((double) snapshot, (double) value)) { - return snapshot; - } else if (snapshot instanceof Boolean && value instanceof Boolean && (boolean) snapshot == (boolean) value) { - return snapshot; - } else if (snapshot instanceof Character && value instanceof Character && (char) snapshot == (char) value) { - return snapshot; + if (snapshot instanceof Byte) { + if (value instanceof Byte && (byte) snapshot == (byte) value) { + return snapshot; + } + } else if (snapshot instanceof Short) { + if (value instanceof Short && (short) snapshot == (short) value) { + return snapshot; + } + } else if (snapshot instanceof Integer) { + if (value instanceof Integer && (int) snapshot == (int) value) { + return snapshot; + } + } else if (snapshot instanceof Long) { + if (value instanceof Long && (long) snapshot == (long) value) { + return snapshot; + } + } else if (snapshot instanceof Float) { + if (value instanceof Float && exactCompare((float) snapshot, (float) value)) { + return snapshot; + } + } else if (snapshot instanceof Double) { + if (value instanceof Double && exactCompare((double) snapshot, (double) value)) { + return snapshot; + } + } else if (snapshot instanceof Boolean) { + if (value instanceof Boolean && (boolean) snapshot == (boolean) value) { + return snapshot; + } + } else if (snapshot instanceof Character) { + if (value instanceof Character && (char) snapshot == (char) value) { + return snapshot; + } } else if (snapshot == value) { return snapshot; - } else { - cacheMiss(value); } + cacheMiss(value); } return value; } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java Tue Mar 31 19:15:45 2015 -0700 @@ -64,7 +64,7 @@ * @param node the node to format. * @return a formatted source section string */ - private static String formatSourceSection(Node node) { + public static String formatSourceSection(Node node) { if (node == null) { return ""; } diff -r 2e3cc2a27711 -r 2c65cac3d940 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLRepeatingNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLRepeatingNode.java Tue Mar 31 19:01:07 2015 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLRepeatingNode.java Tue Mar 31 19:15:45 2015 -0700 @@ -93,4 +93,9 @@ } } + @Override + public String toString() { + return SLStatementNode.formatSourceSection(this); + } + } diff -r 2e3cc2a27711 -r 2c65cac3d940 mx/mx_graal.py --- a/mx/mx_graal.py Tue Mar 31 19:01:07 2015 -0700 +++ b/mx/mx_graal.py Tue Mar 31 19:15:45 2015 -0700 @@ -83,6 +83,9 @@ _minVersion = mx.VersionSpec('1.8') +# max version (first _unsupported_ version) +_untilVersion = mx.VersionSpec('1.8.0_40') + class JDKDeployedDist: def __init__(self, name, isExtension): self.name = name @@ -2527,7 +2530,9 @@ def mx_post_parse_cmd_line(opts): # # TODO _minVersion check could probably be part of a Suite in mx? if mx.java().version < _minVersion: - mx.abort('Requires Java version ' + str(_minVersion) + ' or greater, got version ' + str(mx.java().version)) + mx.abort('Requires Java version ' + str(_minVersion) + ' or greater for JAVA_HOME, got version ' + str(mx.java().version)) + if mx.java().version >= _untilVersion: + mx.abort('Requires Java version strictly before ' + str(_untilVersion) + ' for JAVA_HOME, got version ' + str(mx.java().version)) if _vmSourcesAvailable: if hasattr(opts, 'vm') and opts.vm is not None: diff -r 2e3cc2a27711 -r 2c65cac3d940 mx/suite.py diff -r 2e3cc2a27711 -r 2c65cac3d940 mxtool/mx.py --- a/mxtool/mx.py Tue Mar 31 19:01:07 2015 -0700 +++ b/mxtool/mx.py Tue Mar 31 19:15:45 2015 -0700 @@ -1660,6 +1660,8 @@ elif get_os() == 'linux': base = '/usr/lib/jvm' candidateJdks = [join(base, n) for n in os.listdir(base) if exists(join(base, n, 'jre/lib/rt.jar'))] + base = '/usr/java' + candidateJdks += [join(base, n) for n in os.listdir(base) if exists(join(base, n, 'jre/lib/rt.jar'))] elif get_os() == 'solaris': base = '/usr/jdk/instances' candidateJdks = [join(base, n) for n in os.listdir(base) if exists(join(base, n, 'jre/lib/rt.jar'))] @@ -5331,7 +5333,7 @@ if opts.extra_java_homes: for java_home in opts.extra_java_homes.split(os.pathsep): extraJdk = JavaConfig(java_home, opts.java_dbg_port) - if extraJdk > defaultJdk: + if extraJdk.javaCompliance > defaultJdk.javaCompliance: abort('Secondary JDK ' + extraJdk.jdk + ' has higher compliance level than default JDK ' + defaultJdk.jdk) _java_homes.append(extraJdk) diff -r 2e3cc2a27711 -r 2c65cac3d940 src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/cfg.filter --- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/cfg.filter Tue Mar 31 19:01:07 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -var f = new com.sun.hotspot.igv.graal.filters.GraalCFGFilter(); -f.apply(graph); diff -r 2e3cc2a27711 -r 2c65cac3d940 src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/color.filter --- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/color.filter Tue Mar 31 19:01:07 2015 -0700 +++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/color.filter Tue Mar 31 19:15:45 2015 -0700 @@ -1,11 +1,28 @@ -colorize("name", ".*", white); -colorize("name", "Begin|KillingBegin|EndNode|LoopBegin|LoopEnd|LoopExit|Return", orange); -colorize("class", "FrameState", new java.awt.Color(0.5, 0.8, 1.0)); -colorize("name", "If|Merge|(Integer|Type)Switch", pink); -colorize("name", "\\+|-|\\*|/|&|\\||<<|>>|>>>", cyan); -colorize("name", "Virtual.*", green); -colorize("name", "(Φ|Proxy)\(.*\)", magenta); -colorize("name", "(Φ|Proxy)\(.*\) Identity\(.*\)", green); -colorize("name", "C\(.*\)", new java.awt.Color(0.7, 0.7, 0.7)); -colorize("name", "P\(.*\)", new java.awt.Color(0.85, 0.85, 0.85)); -colorize("name", "==|<|InstanceOf", yellow); +var red = new java.awt.Color(240, 59, 32); +var orange = new java.awt.Color(254, 178, 76); +var yellow = new java.awt.Color(255, 237, 160); +var middleBlue = new java.awt.Color(100, 147, 224); +var lightGreen = new java.awt.Color(173, 221, 142); +var lightBlue = new java.awt.Color(200, 200, 250); +var gray = new java.awt.Color(220, 220, 220); +var violet = new java.awt.Color(201, 148, 199); +colorize("category", "controlSink", red); +colorize("category", "controlSplit", red); +colorize("category", "merge", red); +colorize("category", "begin", orange); +colorize("category", "end", orange); +colorize("category", "fixed", yellow); +colorize("category", "state", lightGreen); +colorize("category", "phi", middleBlue); +colorize("category", "proxy", middleBlue); +colorize("category", "floating", lightBlue); +colorize("class", "ConstantLocationNode", gray); +colorize("class", "ParameterNode", gray); +colorize("class", "ConstantNode", gray); +colorize("class", "GuardNode", violet); + +var f = new com.sun.hotspot.igv.graal.filters.GraalEdgeColorFilter(); +f.setUsageColor("Successor", red); +f.setUsageColor("Value", blue); +f.setUsageColor("Memory", new Color(0.0, 0.5, 0.0)); +f.apply(graph); diff -r 2e3cc2a27711 -r 2c65cac3d940 src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/edgeColor.filter --- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/edgeColor.filter Tue Mar 31 19:01:07 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -var f = new com.sun.hotspot.igv.graal.filters.GraalEdgeColorFilter(); -f.setUsageColor("Successor", red); -f.setUsageColor("Value", blue); -f.setUsageColor("Memory", new Color(0.0, 0.5, 0.0)); -f.apply(graph); diff -r 2e3cc2a27711 -r 2c65cac3d940 src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/noframestate.filter --- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/noframestate.filter Tue Mar 31 19:01:07 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -remove("class", "FrameState"); -remove("class", "Virtual.*"); \ No newline at end of file diff -r 2e3cc2a27711 -r 2c65cac3d940 src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/removeFloating.filter --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/removeFloating.filter Tue Mar 31 19:15:45 2015 -0700 @@ -0,0 +1,4 @@ +remove("category", "floating"); +remove("category", "state"); +remove("category", "phi"); +remove("category", "proxy"); \ No newline at end of file diff -r 2e3cc2a27711 -r 2c65cac3d940 src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/removeState.filter --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/removeState.filter Tue Mar 31 19:15:45 2015 -0700 @@ -0,0 +1,1 @@ +remove("category", "state"); \ No newline at end of file diff -r 2e3cc2a27711 -r 2c65cac3d940 src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/slots.filter --- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/slots.filter Tue Mar 31 19:01:07 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -removeUnconnectedSlots(true, true); diff -r 2e3cc2a27711 -r 2c65cac3d940 src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/stampColor.filter --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/stampColor.filter Tue Mar 31 19:15:45 2015 -0700 @@ -0,0 +1,16 @@ +var red = new java.awt.Color(240, 59, 32); +var orange = new java.awt.Color(254, 178, 76); +var yellow = new java.awt.Color(255, 237, 160); +var middleBlue = new java.awt.Color(100, 147, 224); +var lightGreen = new java.awt.Color(173, 221, 142); +var lightBlue = new java.awt.Color(200, 200, 250); +var gray = new java.awt.Color(220, 220, 220); +var violet = new java.awt.Color(201, 148, 199); + +colorize("stamp", ".*", white); +colorize("stamp", "void", gray); +colorize("stamp", "a.*", yellow); +colorize("stamp", "a#.*", orange); +colorize("stamp", "a!.*", red); +colorize("stamp", "i.*", middleBlue); +colorize("stamp", "f.*", lightGreen); \ No newline at end of file diff -r 2e3cc2a27711 -r 2c65cac3d940 src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/layer.xml --- a/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/layer.xml Tue Mar 31 19:01:07 2015 -0700 +++ b/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/layer.xml Tue Mar 31 19:15:45 2015 -0700 @@ -2,35 +2,32 @@ - - + + - + + - - + + - - - - - + - + + + + + - - - - - + diff -r 2e3cc2a27711 -r 2c65cac3d940 src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java --- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java Tue Mar 31 19:01:07 2015 -0700 +++ b/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java Tue Mar 31 19:15:45 2015 -0700 @@ -538,15 +538,9 @@ if (n2.vertex == null) { return 0; } - if (n1.preds.size() == 1 && n1.preds.get(0).from.vertex != null) { - return 1; - } return -1; } if (n2.vertex == null) { - if (n2.preds.size() == 1 && n2.preds.get(0).from.vertex != null) { - return -1; - } return 1; } return n1.preds.size() - n2.preds.size(); @@ -568,24 +562,18 @@ n2VIP++; } } + if (n1VIP != n2VIP) { + return n2VIP - n1VIP; + } if (n1.vertex == null) { if (n2.vertex == null) { return 0; } - if (n1.succs.size() == 1 && n1.succs.get(0).to.vertex != null) { - return 1; - } return -1; } if (n2.vertex == null) { - if (n2.succs.size() == 1 && n2.succs.get(0).to.vertex != null) { - return -1; - } return 1; } - if (n1VIP != n2VIP) { - return n2VIP - n1VIP; - } return n1.succs.size() - n2.succs.size(); } }; @@ -634,11 +622,13 @@ for (int i = 0; i < SWEEP_ITERATIONS; i++) { sweepDown(); adjustSpace(); - sweepUp(); + sweepUp(false); adjustSpace(); } sweepDown(); + adjustSpace(); + sweepUp(true); } private void adjustSpace() { @@ -730,7 +720,7 @@ } } - private void sweepUp() { + private void sweepUp(boolean onlyDummies) { for (int i = layers.length - 1; i >= 0; i--) { NodeRow r = new NodeRow(space[i]); for (LayoutNode n : upProcessingOrder[i]) { diff -r 2e3cc2a27711 -r 2c65cac3d940 src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/layer.xml --- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/layer.xml Tue Mar 31 19:01:07 2015 -0700 +++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/layer.xml Tue Mar 31 19:15:45 2015 -0700 @@ -2,6 +2,7 @@ +