# HG changeset patch # User Christian Humer # Date 1385834744 -3600 # Node ID 8b14bab157575f8bec079629fba07add74c96909 # Parent 833f8e96d0a557dd652958ee476a77a5bf9fd429# Parent ebdc13d9845d00fd119107b571c25825f6ed8469 Merge. diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.api.meta.jdk8.test/src/com/oracle/graal/api/meta/jdk8/test/TestResolvedJavaMethodJDK8.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta.jdk8.test/src/com/oracle/graal/api/meta/jdk8/test/TestResolvedJavaMethodJDK8.java Sat Nov 30 19:05:44 2013 +0100 @@ -0,0 +1,54 @@ +/* + * 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.api.meta.jdk8.test; + +import static org.junit.Assert.*; + +import java.lang.reflect.*; +import java.util.*; + +import org.junit.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.meta.test.*; + +/** + * Tests for {@link ResolvedJavaMethod} that require JDK >= 8. + */ +public class TestResolvedJavaMethodJDK8 extends MethodUniverse { + + public TestResolvedJavaMethodJDK8() { + } + + @Test + public void isDefaultTest() { + for (Map.Entry e : methods.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + assertEquals(e.getKey().isDefault(), m.isDefault()); + } + for (Map.Entry e : constructors.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + assertFalse(m.isDefault()); + } + } +} diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java Sat Nov 30 19:05:44 2013 +0100 @@ -292,7 +292,8 @@ "canBeInlined", "getLineNumberTable", "getLocalVariableTable", - "isInVirtualMethodTable" + "isInVirtualMethodTable", + "isDefault" // tested in TestResolvedJavaMethodJDK8 }; // @formatter:on diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Sat Nov 30 19:05:44 2013 +0100 @@ -443,8 +443,14 @@ if (c.isInterface() || c.isPrimitive()) { ResolvedJavaType type = metaAccess.lookupJavaType(c); for (Method m : c.getDeclaredMethods()) { - ResolvedJavaMethod impl = type.resolveMethod(metaAccess.lookupJavaMethod(m)); - assertEquals(m.toString(), null, impl); + if (JAVA_VERSION <= 1.7D || (!isStatic(m.getModifiers()) && !isPrivate(m.getModifiers()))) { + ResolvedJavaMethod resolved = metaAccess.lookupJavaMethod(m); + ResolvedJavaMethod impl = type.resolveMethod(resolved); + ResolvedJavaMethod expected = resolved.isDefault() ? resolved : null; + assertEquals(m.toString(), expected, impl); + } else { + // As of JDK 8, interfaces can have static and private methods + } } } else { ResolvedJavaType type = metaAccess.lookupJavaType(c); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java Sat Nov 30 19:05:44 2013 +0100 @@ -42,6 +42,7 @@ public class TypeUniverse { public final Unsafe unsafe; + public static final double JAVA_VERSION = Double.valueOf(System.getProperty("java.specification.version")); public final MetaAccessProvider metaAccess; public final ConstantReflectionProvider constantReflection; diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Sat Nov 30 19:05:44 2013 +0100 @@ -250,7 +250,7 @@ if (getKind() == Kind.Object) { return System.identityHashCode(object); } - return (int) primitive; + return (int) primitive * getKind().ordinal(); } /** diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DeoptimizationReason.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DeoptimizationReason.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DeoptimizationReason.java Sat Nov 30 19:05:44 2013 +0100 @@ -40,4 +40,5 @@ ArithmeticException, RuntimeConstraint, LoopLimitCheck, + Aliasing, } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaMethodProfile.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaMethodProfile.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaMethodProfile.java Sat Nov 30 19:05:44 2013 +0100 @@ -45,8 +45,8 @@ private static final long serialVersionUID = 5418813647187024693L; - public ProfiledMethod(ResolvedJavaMethod item, double probability) { - super(item, probability); + public ProfiledMethod(ResolvedJavaMethod method, double probability) { + super(method, probability); } /** diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java Sat Nov 30 19:05:44 2013 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.api.meta; +import static java.lang.reflect.Modifier.*; + import java.util.*; import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType; @@ -116,7 +118,7 @@ probabilitySum += newNotRecorded; double factor = 1.0 / probabilitySum; // Normalize to 1.0 - assert factor > 1.0; + assert factor >= 1.0; ProfiledType[] newResult = new ProfiledType[result.size()]; for (int i = 0; i < newResult.length; ++i) { ProfiledType curType = result.get(i); @@ -142,8 +144,9 @@ private static final long serialVersionUID = 1481773321889860837L; - public ProfiledType(ResolvedJavaType item, double probability) { - super(item, probability); + public ProfiledType(ResolvedJavaType type, double probability) { + super(type, probability); + assert type.isArray() || !isAbstract(type.getModifiers()) : type; } /** diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Sat Nov 30 19:05:44 2013 +0100 @@ -91,6 +91,17 @@ boolean isSynthetic(); /** + * Returns {@code true} if this method is a default method; returns {@code false} otherwise. + * + * A default method is a public non-abstract instance method, that is, a non-static method with + * a body, declared in an interface type. + * + * @return true if and only if this method is a default method as defined by the Java Language + * Specification. + */ + boolean isDefault(); + + /** * Checks whether this method is a class initializer. * * @return {@code true} if the method is a class initializer diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Address.java Sat Nov 30 19:05:44 2013 +0100 @@ -70,6 +70,8 @@ this.index = index; this.scale = scale; this.displacement = displacement; + + assert scale != null; } /** @@ -104,7 +106,7 @@ case 8: return Times8; default: - throw new IllegalArgumentException(String.valueOf(scale)); + return null; } } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Sat Nov 30 19:05:44 2013 +0100 @@ -164,6 +164,17 @@ if (isConstant(index)) { finalDisp += asConstant(index).asLong() * scale; indexRegister = Value.ILLEGAL; + + } else if (scaleEnum == null) { + /* Scale value that architecture cannot handle, so scale manually. */ + Value longIndex = index.getKind().getStackKind() == Kind.Int ? emitConvert(Kind.Int, Kind.Long, index) : index; + if (CodeUtil.isPowerOf2(scale)) { + indexRegister = emitShl(longIndex, Constant.forLong(CodeUtil.log2(scale))); + } else { + indexRegister = emitMul(longIndex, Constant.forLong(scale)); + } + scaleEnum = Scale.Times1; + } else { indexRegister = asAllocatable(index); } @@ -812,7 +823,10 @@ Kind from = inputVal.getKind(); AllocatableValue input = asAllocatable(inputVal); - // These cases require a move between CPU and FPU registers: + /* + * Conversions between integer to floating point types require moves between CPU and FPU + * registers. + */ switch (to) { case Int: switch (from) { @@ -826,6 +840,19 @@ case Float: case Double: return emitConvert2Op(to, MOV_D2L, input); + case Int: + /* + * Unsigned int-to-long conversion: In theory, instructions that move or + * generate 32-bit register values also set the upper 32 bits of the + * register to zero. However, we cannot rely that the value was really + * generated by an instruction, it could come from an untrusted source such + * as native code. Therefore, make sure the high bits are really cleared. + */ + Variable temp = newVariable(Kind.Int); + Variable result = newVariable(Kind.Long); + append(new BinaryRegConst(AMD64Arithmetic.IAND, temp, input, Constant.forInt(0xFFFFFFFF))); + emitMove(result, temp); + return result; } break; case Float: @@ -843,12 +870,7 @@ } break; } - - // Otherwise, just emit an ordinary move instruction. - // Instructions that move or generate 32-bit register values also set the upper 32 - // bits of the register to zero. - // Consequently, there is no need for a special zero-extension move. - return emitConvertMove(to, input); + throw GraalInternalError.shouldNotReachHere(); } @Override diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java --- a/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java Sat Nov 30 19:05:44 2013 +0100 @@ -88,7 +88,7 @@ static { logger = Logger.getLogger(propPkgName); - logLevel = Level.parse(System.getProperty("kerneltester.logLevel", "SEVERE")); + logLevel = Level.parse(System.getProperty("kerneltester.logLevel", "OFF")); // This block configure the logger with handler and formatter. consoleHandler = new ConsoleHandler(); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/BasicHSAILTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.compiler.test.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.hotspot.hsail.*; import com.oracle.graal.hsail.*; import com.oracle.graal.nodes.*; @@ -331,10 +332,14 @@ out[gid] = val; } - private void test(String snippet) { - StructuredGraph graph = parse(snippet); - HSAILCompilationResult compResult = HSAILCompilationResult.getHSAILCompilationResult(graph); - TTY.println("code generated for " + snippet + ":\n" + compResult.getHSAILCode()); + private void test(final String snippet) { + try (Scope s = Debug.scope("HSAILCodeGen")) { + StructuredGraph graph = parse(snippet); + HSAILCompilationResult compResult = HSAILCompilationResult.getHSAILCompilationResult(graph); + Debug.log("HSAIL code generated for %s:%n%s", snippet, compResult.getHSAILCode()); + } catch (Throwable e) { + throw Debug.handle(e); + } } public static void nBodySpill(float[] inxyz, float[] outxyz, float[] invxyz, float[] outvxyz, int gid) { diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethod16InArraysTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethod16InArraysTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMethod16InArraysTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -23,7 +23,10 @@ package com.oracle.graal.compiler.hsail.test; -import org.junit.Test; +import org.junit.*; + +import com.oracle.graal.debug.*; +import com.oracle.graal.debug.internal.*; /** * Tests the addition of elements from sixteen input arrays. @@ -60,7 +63,17 @@ */ @Test(expected = java.lang.ClassCastException.class) public void test() { - testGeneratedHsail(); + DebugConfig debugConfig = DebugScope.getConfig(); + DebugConfig noInterceptConfig = new DelegatingDebugConfig(debugConfig) { + @Override + public RuntimeException interceptException(Throwable e) { + return null; + } + }; + + try (DebugConfigScope s = Debug.setConfig(noInterceptConfig)) { + testGeneratedHsail(); + } } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayPTXTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayPTXTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -24,12 +24,12 @@ import static com.oracle.graal.lir.ptx.ThreadDimension.*; -import com.oracle.graal.lir.ptx.ParallelOver; -import com.oracle.graal.lir.ptx.Warp; +import java.lang.reflect.*; +import java.util.*; -import java.lang.reflect.Method; -import java.util.Arrays; -import org.junit.Test; +import org.junit.*; + +import com.oracle.graal.lir.ptx.*; public class ArrayPTXTest extends PTXTestBase { @@ -71,9 +71,7 @@ for (Method m : ArrayPTXTest.class.getMethods()) { String name = m.getName(); if (m.getAnnotation(Test.class) == null && name.startsWith("test")) { - // CheckStyle: stop system..print check - System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode())); - // CheckStyle: resume system..print check + printReport(name + ": \n" + new String(test.compile(name).getTargetCode())); } } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -22,9 +22,9 @@ */ package com.oracle.graal.compiler.ptx.test; -import java.lang.reflect.Method; +import java.lang.reflect.*; -import org.junit.Test; +import org.junit.*; /** * Test class for small Java methods compiled to PTX kernels. @@ -51,9 +51,7 @@ for (Method m : methods) { String name = m.getName(); if (m.getAnnotation(Test.class) == null && name.startsWith("test")) { - // CheckStyle: stop system..print check - System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode())); - // CheckStyle: resume system..print check + printReport(name + ": \n" + new String(test.compile(name).getTargetCode())); } } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -22,9 +22,9 @@ */ package com.oracle.graal.compiler.ptx.test; -import org.junit.*; +import java.lang.reflect.*; -import java.lang.reflect.Method; +import org.junit.*; public class ControlPTXTest extends PTXTestBase { @@ -214,9 +214,7 @@ for (Method m : ControlPTXTest.class.getMethods()) { String name = m.getName(); if (m.getAnnotation(Test.class) == null && name.startsWith("test")) { - // CheckStyle: stop system..print check - System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode())); - // CheckStyle: resume system..print check + printReport(name + ": \n" + new String(test.compile(name).getTargetCode())); } } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/FloatPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/FloatPTXTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/FloatPTXTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -366,9 +366,7 @@ for (Method m : FloatPTXTest.class.getMethods()) { String name = m.getName(); if (m.getAnnotation(Test.class) == null && name.startsWith("test") && name.startsWith("testRem") == false) { - // CheckStyle: stop system..print check - System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode())); - // CheckStyle: resume system..print check + printReport(name + ": \n" + new String(test.compile(name).getTargetCode())); } } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -352,9 +352,7 @@ for (Method m : IntegerPTXTest.class.getMethods()) { String name = m.getName(); if (m.getAnnotation(Test.class) == null && name.startsWith("test")) { - // CheckStyle: stop system..print check - System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode())); - // CheckStyle: resume system..print check + printReport(name + ": \n" + new String(test.compile(name).getTargetCode())); } } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/LogicPTXTest.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/LogicPTXTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/LogicPTXTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -128,9 +128,7 @@ for (Method m : LogicPTXTest.class.getMethods()) { String name = m.getName(); if (m.getAnnotation(Test.class) == null && name.startsWith("test")) { - // CheckStyle: stop system..print check - System.out.println(name + ": \n" + new String(test.compile(name).getTargetCode())); - // CheckStyle: resume system..print check + printReport(name + ": \n" + new String(test.compile(name).getTargetCode())); } } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java --- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java Sat Nov 30 19:05:44 2013 +0100 @@ -48,11 +48,9 @@ private StructuredGraph sg; - public void printReport(String message) { - // CheckStyle: stop system..print check - System.out.println(message); - // CheckStyle: resume system..print check - + public static void printReport(String message) { + // Use -G:Log=Test to see these messages on the console + Debug.log(message); } public PTXTestBase() { diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -25,7 +25,6 @@ import org.junit.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.debug.*; import com.oracle.graal.loop.phases.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; @@ -317,33 +316,27 @@ } private void compareGraphs(final String snippet, final String referenceSnippet, final boolean loopPeeling, final boolean excludeVirtual) { - Debug.scope("BoxingEliminationTest " + snippet, new DebugDumpScope(snippet), new Runnable() { - - @Override - public void run() { - graph = parse(snippet); + graph = parse(snippet); - Assumptions assumptions = new Assumptions(false); - HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - if (loopPeeling) { - new LoopTransformHighPhase().apply(graph); - } - new DeadCodeEliminationPhase().apply(graph); - canonicalizer.apply(graph, context); - new PartialEscapePhase(false, canonicalizer).apply(graph, context); + Assumptions assumptions = new Assumptions(false); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); + if (loopPeeling) { + new LoopTransformHighPhase().apply(graph); + } + new DeadCodeEliminationPhase().apply(graph); + canonicalizer.apply(graph, context); + new PartialEscapePhase(false, canonicalizer).apply(graph, context); - new DeadCodeEliminationPhase().apply(graph); - canonicalizer.apply(graph, context); + new DeadCodeEliminationPhase().apply(graph); + canonicalizer.apply(graph, context); - StructuredGraph referenceGraph = parse(referenceSnippet); - new InliningPhase(new CanonicalizerPhase(true)).apply(referenceGraph, context); - new DeadCodeEliminationPhase().apply(referenceGraph); - new CanonicalizerPhase(true).apply(referenceGraph, context); + StructuredGraph referenceGraph = parse(referenceSnippet); + new InliningPhase(new CanonicalizerPhase(true)).apply(referenceGraph, context); + new DeadCodeEliminationPhase().apply(referenceGraph); + new CanonicalizerPhase(true).apply(referenceGraph, context); - assertEquals(referenceGraph, graph, excludeVirtual); - } - }); + assertEquals(referenceGraph, graph, excludeVirtual); } } diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; @@ -78,18 +79,17 @@ } private void test(final String snippet) { - Debug.scope("DegeneratedLoopsTest", new DebugDumpScope(snippet), new Runnable() { - - public void run() { - StructuredGraph graph = parse(snippet); - HighTierContext context = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new CanonicalizerPhase(true).apply(graph, context); - Debug.dump(graph, "Graph"); - StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); - Debug.dump(referenceGraph, "ReferenceGraph"); - assertEquals(referenceGraph, graph); - } - }); + try (Scope s = Debug.scope("DegeneratedLoopsTest", new DebugDumpScope(snippet))) { + StructuredGraph graph = parse(snippet); + HighTierContext context = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); + new CanonicalizerPhase(true).apply(graph, context); + Debug.dump(graph, "Graph"); + StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); + Debug.dump(referenceGraph, "ReferenceGraph"); + assertEquals(referenceGraph, graph); + } catch (Throwable e) { + throw Debug.handle(e); + } } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -22,12 +22,11 @@ */ package com.oracle.graal.compiler.test; -import java.util.concurrent.*; - import org.junit.*; import com.oracle.graal.api.code.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.common.*; @@ -108,18 +107,16 @@ private StructuredGraph compileSnippet(final String snippet, final int checkcasts, final int afterCanon) { final StructuredGraph graph = parse(snippet); - return Debug.scope("NestedCheckCastsTest", graph, new Callable() { + try (Scope s = Debug.scope("NestedCheckCastsTest", graph)) { + Debug.dump(graph, "After parsing: " + snippet); + Assert.assertEquals(checkcasts, graph.getNodes().filter(CheckCastNode.class).count()); + new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false))); + Assert.assertEquals(afterCanon, graph.getNodes().filter(CheckCastNode.class).count()); + return graph; + } catch (Throwable e) { + throw Debug.handle(e); + } - @Override - public StructuredGraph call() throws Exception { - Debug.dump(graph, "After parsing: " + snippet); - Assert.assertEquals(checkcasts, graph.getNodes().filter(CheckCastNode.class).count()); - new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false))); - Assert.assertEquals(afterCanon, graph.getNodes().filter(CheckCastNode.class).count()); - return graph; - } - - }); } public static class A1 { diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -25,7 +25,6 @@ import java.io.*; import java.lang.reflect.*; import java.util.*; -import java.util.concurrent.*; import org.junit.*; @@ -119,46 +118,40 @@ @Override protected Class findClass(final String name) throws ClassNotFoundException { - return Debug.scope("FinalizableSubclassTest", new Callable>() { + String nameReplaced = name.replaceAll("AAAA", replaceTo); + if (cache.containsKey(nameReplaced)) { + return cache.get(nameReplaced); + } - @Override - public Class call() throws Exception { - String nameReplaced = name.replaceAll("AAAA", replaceTo); - if (cache.containsKey(nameReplaced)) { - return cache.get(nameReplaced); - } - - // copy classfile to byte array - byte[] classData = null; - try { - InputStream is = FinalizableSubclassTest.class.getResourceAsStream("FinalizableSubclassTest$" + name + ".class"); - assert is != null; - ByteArrayOutputStream baos = new ByteArrayOutputStream(); + // copy classfile to byte array + byte[] classData = null; + try { + InputStream is = FinalizableSubclassTest.class.getResourceAsStream("FinalizableSubclassTest$" + name + ".class"); + assert is != null; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte[] buf = new byte[1024]; - int size; - while ((size = is.read(buf, 0, buf.length)) != -1) { - baos.write(buf, 0, size); - } - baos.flush(); - classData = baos.toByteArray(); - } catch (IOException e) { - Assert.fail("can't access class: " + name); - } - dumpStringsInByteArray(classData); + byte[] buf = new byte[1024]; + int size; + while ((size = is.read(buf, 0, buf.length)) != -1) { + baos.write(buf, 0, size); + } + baos.flush(); + classData = baos.toByteArray(); + } catch (IOException e) { + Assert.fail("can't access class: " + name); + } + dumpStringsInByteArray(classData); - // replace all occurrences of "AAAA" in classfile - int index = -1; - while ((index = indexOfAAAA(classData, index + 1)) != -1) { - replaceAAAA(classData, index, replaceTo); - } - dumpStringsInByteArray(classData); + // replace all occurrences of "AAAA" in classfile + int index = -1; + while ((index = indexOfAAAA(classData, index + 1)) != -1) { + replaceAAAA(classData, index, replaceTo); + } + dumpStringsInByteArray(classData); - Class c = defineClass(null, classData, 0, classData.length); - cache.put(nameReplaced, c); - return c; - } - }); + Class c = defineClass(null, classData, 0, classData.length); + cache.put(nameReplaced, c); + return c; } private static int indexOfAAAA(byte[] b, int index) { diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; @@ -54,35 +55,35 @@ } private void test(final String snippet) { - Debug.scope("FloatingReadTest", new DebugDumpScope(snippet), new Runnable() { + try (Scope s = Debug.scope("FloatingReadTest", new DebugDumpScope(snippet))) { - public void run() { - StructuredGraph graph = parse(snippet); - PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false)); - new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context); - new FloatingReadPhase().apply(graph); + StructuredGraph graph = parse(snippet); + PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false)); + new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context); + new FloatingReadPhase().apply(graph); - ReturnNode returnNode = null; - MonitorExit monitorexit = null; + ReturnNode returnNode = null; + MonitorExit monitorexit = null; - for (Node n : graph.getNodes()) { - if (n instanceof ReturnNode) { - returnNode = (ReturnNode) n; - } else if (n instanceof MonitorExit) { - monitorexit = (MonitorExit) n; - } + for (Node n : graph.getNodes()) { + if (n instanceof ReturnNode) { + returnNode = (ReturnNode) n; + } else if (n instanceof MonitorExit) { + monitorexit = (MonitorExit) n; } + } - Debug.dump(graph, "After lowering"); + Debug.dump(graph, "After lowering"); - Assert.assertNotNull(returnNode); - Assert.assertNotNull(monitorexit); - Assert.assertTrue(returnNode.result() instanceof FloatingReadNode); + Assert.assertNotNull(returnNode); + Assert.assertNotNull(monitorexit); + Assert.assertTrue(returnNode.result() instanceof FloatingReadNode); - FloatingReadNode read = (FloatingReadNode) returnNode.result(); + FloatingReadNode read = (FloatingReadNode) returnNode.result(); - assertOrderedAfterSchedule(graph, read, (Node) monitorexit); - } - }); + assertOrderedAfterSchedule(graph, read, (Node) monitorexit); + } catch (Throwable e) { + throw Debug.handle(e); + } } } diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -29,7 +29,6 @@ import java.io.*; import java.lang.reflect.*; import java.util.*; -import java.util.concurrent.*; import java.util.concurrent.atomic.*; import org.junit.*; @@ -42,6 +41,7 @@ import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.Verbosity; import com.oracle.graal.java.*; @@ -113,6 +113,20 @@ DebugEnvironment.initialize(System.out); } + private Scope debugScope; + + @Before + public void beforeTest() { + assert debugScope == null; + debugScope = Debug.scope(getClass().getSimpleName()); + } + + @After + public void afterTest() { + debugScope.close(); + debugScope = null; + } + protected void assertEquals(StructuredGraph expected, StructuredGraph graph) { assertEquals(expected, graph, false); } @@ -212,6 +226,10 @@ return providers; } + protected TargetDescription getTarget() { + return getProviders().getCodeCache().getTarget(); + } + protected CodeCacheProvider getCodeCache() { return getProviders().getCodeCache(); } @@ -525,49 +543,48 @@ final int id = compilationId.incrementAndGet(); - InstalledCode installedCode = Debug.scope("Compiling", new Object[]{new DebugDumpScope(String.valueOf(id), true)}, new Callable() { - - public InstalledCode call() throws Exception { - final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed(); - if (printCompilation) { - TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s ...", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature())); - } - long start = System.currentTimeMillis(); - PhasePlan phasePlan = new PhasePlan(); - GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); - phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); - CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); - final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), null, phasePlan, - OptimisticOptimizations.ALL, new SpeculationLog(), getSuites(), new CompilationResult()); - if (printCompilation) { - TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize())); - } - return Debug.scope("CodeInstall", new Object[]{getCodeCache(), method}, new Callable() { + InstalledCode installedCode = null; + try (Scope ds = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true))) { + final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed(); + if (printCompilation) { + TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s ...", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature())); + } + long start = System.currentTimeMillis(); + PhasePlan phasePlan = new PhasePlan(); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); + phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); + CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); + final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, getProviders(), getBackend(), getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, + new SpeculationLog(), getSuites(), new CompilationResult()); + if (printCompilation) { + TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize())); + } - @Override - public InstalledCode call() throws Exception { - InstalledCode code = addMethod(method, compResult); - if (code == null) { - throw new GraalInternalError("Could not install code for " + MetaUtil.format("%H.%n(%p)", method)); - } - if (Debug.isDumpEnabled()) { - Debug.dump(new Object[]{compResult, code}, "After code installation"); + try (Scope s = Debug.scope("CodeInstall", getCodeCache(), method)) { + InstalledCode code = addMethod(method, compResult); + if (code == null) { + throw new GraalInternalError("Could not install code for " + MetaUtil.format("%H.%n(%p)", method)); + } + if (Debug.isDumpEnabled()) { + Debug.dump(new Object[]{compResult, code}, "After code installation"); + } + if (Debug.isLogEnabled()) { + DisassemblerProvider dis = backend.getDisassembler(); + if (dis != null) { + String text = dis.disassemble(code); + if (text != null) { + Debug.log("Code installed for %s%n%s", method, text); } - if (Debug.isLogEnabled()) { - DisassemblerProvider dis = backend.getDisassembler(); - if (dis != null) { - String text = dis.disassemble(code); - if (text != null) { - Debug.log("Code installed for %s%n%s", method, text); - } - } - } + } + } - return code; - } - }); + installedCode = code; + } catch (Throwable e) { + throw Debug.handle(e); } - }); + } catch (Throwable e) { + throw Debug.handle(e); + } if (!forceCompile) { cache.put(method, installedCode); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -26,6 +26,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.loop.phases.*; import com.oracle.graal.nodes.*; @@ -136,12 +137,10 @@ Assumptions assumptions = new Assumptions(false); new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions)); new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders(), assumptions)); - Debug.scope("Test", new DebugDumpScope("Test:" + snippet), new Runnable() { - - @Override - public void run() { - assertEquals(referenceGraph, graph); - } - }); + try (Scope s = Debug.scope("Test", new DebugDumpScope("Test:" + snippet))) { + assertEquals(referenceGraph, graph); + } catch (Throwable e) { + throw Debug.handle(e); + } } } diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -26,12 +26,12 @@ import static org.junit.Assert.*; import java.util.*; -import java.util.concurrent.*; import org.junit.*; import com.oracle.graal.api.code.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.nodes.*; @@ -579,47 +579,44 @@ private SchedulePhase getFinalSchedule(final String snippet, final TestMode mode, final MemoryScheduling memsched, final SchedulingStrategy schedulingStrategy) { final StructuredGraph graph = parse(snippet); - return Debug.scope("FloatingReadTest", graph, new Callable() { - - @Override - public SchedulePhase call() throws Exception { - - try (OverrideScope s = OptionValue.override(OptScheduleOutOfLoops, schedulingStrategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS)) { - Assumptions assumptions = new Assumptions(false); - HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); - canonicalizer.apply(graph, context); - if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { - new InliningPhase(canonicalizer).apply(graph, context); - } - new LoweringPhase(canonicalizer).apply(graph, context); - if (mode == TestMode.WITHOUT_FRAMESTATES || mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { - for (Node node : graph.getNodes()) { - if (node instanceof StateSplit) { - FrameState stateAfter = ((StateSplit) node).stateAfter(); - if (stateAfter != null) { - ((StateSplit) node).setStateAfter(null); - GraphUtil.killWithUnusedFloatingInputs(stateAfter); - } + try (Scope d = Debug.scope("FloatingReadTest", graph)) { + try (OverrideScope s = OptionValue.override(OptScheduleOutOfLoops, schedulingStrategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS)) { + Assumptions assumptions = new Assumptions(false); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + canonicalizer.apply(graph, context); + if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { + new InliningPhase(canonicalizer).apply(graph, context); + } + new LoweringPhase(canonicalizer).apply(graph, context); + if (mode == TestMode.WITHOUT_FRAMESTATES || mode == TestMode.INLINED_WITHOUT_FRAMESTATES) { + for (Node node : graph.getNodes()) { + if (node instanceof StateSplit) { + FrameState stateAfter = ((StateSplit) node).stateAfter(); + if (stateAfter != null) { + ((StateSplit) node).setStateAfter(null); + GraphUtil.killWithUnusedFloatingInputs(stateAfter); } } } - Debug.dump(graph, "after removal of framestates"); + } + Debug.dump(graph, "after removal of framestates"); - new FloatingReadPhase().apply(graph); - new RemoveValueProxyPhase().apply(graph); + new FloatingReadPhase().apply(graph); + new RemoveValueProxyPhase().apply(graph); - MidTierContext midContext = new MidTierContext(getProviders(), assumptions, getCodeCache().getTarget(), OptimisticOptimizations.ALL); - new GuardLoweringPhase().apply(graph, midContext); - new LoweringPhase(canonicalizer).apply(graph, midContext); - new LoweringPhase(canonicalizer).apply(graph, midContext); + MidTierContext midContext = new MidTierContext(getProviders(), assumptions, getCodeCache().getTarget(), OptimisticOptimizations.ALL); + new GuardLoweringPhase().apply(graph, midContext); + new LoweringPhase(canonicalizer).apply(graph, midContext); + new LoweringPhase(canonicalizer).apply(graph, midContext); - SchedulePhase schedule = new SchedulePhase(schedulingStrategy, memsched); - schedule.apply(graph); - assertEquals(1, graph.getNodes().filter(StartNode.class).count()); - return schedule; - } + SchedulePhase schedule = new SchedulePhase(schedulingStrategy, memsched); + schedule.apply(graph); + assertEquals(1, graph.getNodes().filter(StartNode.class).count()); + return schedule; } - }); + } catch (Throwable e) { + throw Debug.handle(e); + } } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -27,6 +27,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; @@ -64,29 +65,27 @@ @Test public void test1() { final String snippet = "test1Snippet"; - Debug.scope("PushThroughPi", new DebugDumpScope(snippet), new Runnable() { - - public void run() { - StructuredGraph graph = compileTestSnippet(snippet); + try (Scope s = Debug.scope("PushThroughPi", new DebugDumpScope(snippet))) { + StructuredGraph graph = compileTestSnippet(snippet); + for (ReadNode rn : graph.getNodes().filter(ReadNode.class)) { + if (rn.location() instanceof ConstantLocationNode && rn.object().stamp() instanceof ObjectStamp) { + long disp = ((ConstantLocationNode) rn.location()).getDisplacement(); + ResolvedJavaType receiverType = ObjectStamp.typeOrNull(rn.object()); + ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(disp); - for (ReadNode rn : graph.getNodes().filter(ReadNode.class)) { - if (rn.location() instanceof ConstantLocationNode && rn.object().stamp() instanceof ObjectStamp) { - long disp = ((ConstantLocationNode) rn.location()).getDisplacement(); - ResolvedJavaType receiverType = ObjectStamp.typeOrNull(rn.object()); - ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(disp); - - assert field != null : "Node " + rn + " tries to access a field which doesn't exists for this type"; - if (field.getName().equals("x")) { - Assert.assertTrue(rn.object() instanceof LocalNode); - } else { - Assert.assertTrue(rn.object().toString(), rn.object() instanceof PiNode); - } + assert field != null : "Node " + rn + " tries to access a field which doesn't exists for this type"; + if (field.getName().equals("x")) { + Assert.assertTrue(rn.object() instanceof LocalNode); + } else { + Assert.assertTrue(rn.object().toString(), rn.object() instanceof PiNode); } } + } - Assert.assertTrue(graph.getNodes().filter(IsNullNode.class).count() == 1); - } - }); + Assert.assertTrue(graph.getNodes().filter(IsNullNode.class).count() == 1); + } catch (Throwable e) { + throw Debug.handle(e); + } } private StructuredGraph compileTestSnippet(final String snippet) { diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -27,6 +27,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.phases.common.*; @@ -77,27 +78,26 @@ } private void test(final String snippet) { - Debug.scope("FloatingReadTest", new DebugDumpScope(snippet), new Runnable() { - + try (Scope s = Debug.scope("ReadAfterCheckCastTest", new DebugDumpScope(snippet))) { // check shape of graph, with lots of assumptions. will probably fail if graph // structure changes significantly - public void run() { - StructuredGraph graph = parse(snippet); - PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false)); - new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context); - new FloatingReadPhase().apply(graph); - new OptimizeGuardAnchors().apply(graph); - new ReadEliminationPhase().apply(graph); - new CanonicalizerPhase(true).apply(graph, context); + StructuredGraph graph = parse(snippet); + PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false)); + new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context); + new FloatingReadPhase().apply(graph); + new OptimizeGuardAnchors().apply(graph); + new ReadEliminationPhase().apply(graph); + new CanonicalizerPhase(true).apply(graph, context); - Debug.dump(graph, "After lowering"); + Debug.dump(graph, "After lowering"); - for (FloatingReadNode node : graph.getNodes(LocalNode.class).first().usages().filter(FloatingReadNode.class)) { - // Checking that the parameter a is not directly used for the access to field - // x10 (because x10 must be guarded by the checkcast). - Assert.assertTrue(node.location().getLocationIdentity() == LocationIdentity.FINAL_LOCATION); - } + for (FloatingReadNode node : graph.getNodes(LocalNode.class).first().usages().filter(FloatingReadNode.class)) { + // Checking that the parameter a is not directly used for the access to field + // x10 (because x10 must be guarded by the checkcast). + Assert.assertTrue(node.location().getLocationIdentity() == LocationIdentity.FINAL_LOCATION); } - }); + } catch (Throwable e) { + throw Debug.handle(e); + } } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/SimpleCFGTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -31,13 +31,7 @@ public class SimpleCFGTest extends GraalCompilerTest { private static void dumpGraph(final StructuredGraph graph) { - Debug.scope("SimpleCFGTest", new Runnable() { - - @Override - public void run() { - Debug.dump(graph, "Graph"); - } - }); + Debug.dump(graph, "Graph"); } @Test diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -26,7 +26,6 @@ import static com.oracle.graal.phases.GraalOptions.*; import java.util.*; -import java.util.concurrent.*; import org.junit.*; @@ -36,6 +35,7 @@ import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.lir.*; import com.oracle.graal.lir.LIRInstruction.ValueProcedure; import com.oracle.graal.lir.StandardOp.MoveOp; @@ -47,23 +47,18 @@ protected void test(String snippet, final int expectedRegisters, final int expectedRegRegMoves, final int expectedSpillMoves) { final StructuredGraph graph = parse(snippet); - Debug.scope("AllocatorTest", new Object[]{graph, graph.method(), getCodeCache()}, new Runnable() { - - @Override - public void run() { - final RegisterStats stats = getRegisterStats(graph); - - Debug.scope("Assertions", stats.lir, new Runnable() { - - @Override - public void run() { - Assert.assertEquals("register count", expectedRegisters, stats.registers.size()); - Assert.assertEquals("reg-reg moves", expectedRegRegMoves, stats.regRegMoves); - Assert.assertEquals("spill moves", expectedSpillMoves, stats.spillMoves); - } - }); + try (Scope s = Debug.scope("AllocatorTest", graph, graph.method(), getCodeCache())) { + final RegisterStats stats = getRegisterStats(graph); + try (Scope s2 = Debug.scope("Assertions", stats.lir)) { + Assert.assertEquals("register count", expectedRegisters, stats.registers.size()); + Assert.assertEquals("reg-reg moves", expectedRegRegMoves, stats.regRegMoves); + Assert.assertEquals("spill moves", expectedSpillMoves, stats.spillMoves); + } catch (Throwable e) { + throw Debug.handle(e); } - }); + } catch (Throwable e) { + throw Debug.handle(e); + } } private class RegisterStats { @@ -115,22 +110,19 @@ final PhasePlan phasePlan = getDefaultPhasePlan(); final Assumptions assumptions = new Assumptions(OptAssumptions.getValue()); - final LIR lir = Debug.scope("FrontEnd", new Callable() { - - @Override - public LIR call() { - return GraalCompiler.emitHIR(getProviders(), getBackend().getTarget(), graph, assumptions, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), getSuites()); - } - }); + LIR lir = null; + try (Scope s = Debug.scope("FrontEnd")) { + lir = GraalCompiler.emitHIR(getProviders(), getBackend().getTarget(), graph, assumptions, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), getSuites()); + } catch (Throwable e) { + throw Debug.handle(e); + } - return Debug.scope("BackEnd", lir, new Callable() { - - @Override - public RegisterStats call() { - CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); - GraalCompiler.emitLIR(getBackend(), getBackend().getTarget(), lir, graph, cc); - return new RegisterStats(lir); - } - }); + try (Scope s = Debug.scope("BackEnd", lir)) { + CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false); + GraalCompiler.emitLIR(getBackend(), getBackend().getTarget(), lir, graph, cc); + return new RegisterStats(lir); + } catch (Throwable e) { + throw Debug.handle(e); + } } } diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EATestBase.java Sat Nov 30 19:05:44 2013 +0100 @@ -28,6 +28,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; @@ -144,19 +145,18 @@ protected void prepareGraph(String snippet, final boolean iterativeEscapeAnalysis) { ResolvedJavaMethod method = getMetaAccess().lookupJavaMethod(getMethod(snippet)); graph = new StructuredGraph(method); - Debug.scope(getClass().getSimpleName(), new Object[]{graph, method, getCodeCache()}, new Runnable() { - - public void run() { - new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); - Assumptions assumptions = new Assumptions(false); - context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - new DeadCodeEliminationPhase().apply(graph); - new CanonicalizerPhase(true).apply(graph, context); - new PartialEscapePhase(iterativeEscapeAnalysis, false, new CanonicalizerPhase(true)).apply(graph, context); - Assert.assertEquals(1, graph.getNodes().filter(ReturnNode.class).count()); - returnNode = graph.getNodes().filter(ReturnNode.class).first(); - } - }); + try (Scope s = Debug.scope(getClass().getSimpleName(), graph, method, getCodeCache())) { + new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph); + Assumptions assumptions = new Assumptions(false); + context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); + new DeadCodeEliminationPhase().apply(graph); + new CanonicalizerPhase(true).apply(graph, context); + new PartialEscapePhase(iterativeEscapeAnalysis, false, new CanonicalizerPhase(true)).apply(graph, context); + Assert.assertEquals(1, graph.getNodes().filter(ReturnNode.class).count()); + returnNode = graph.getNodes().filter(ReturnNode.class).first(); + } catch (Throwable e) { + throw Debug.handle(e); + } } } diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -25,13 +25,13 @@ import static org.junit.Assert.*; import java.lang.reflect.*; -import java.util.concurrent.*; import org.junit.*; import com.oracle.graal.api.code.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; @@ -229,24 +229,22 @@ } private StructuredGraph getGraph(final String snippet, final boolean eagerInfopointMode) { - return Debug.scope("InliningTest", new DebugDumpScope(snippet), new Callable() { - - @Override - public StructuredGraph call() { - Method method = getMethod(snippet); - StructuredGraph graph = eagerInfopointMode ? parseDebug(method) : parse(method); - PhasePlan phasePlan = getDefaultPhasePlan(eagerInfopointMode); - Assumptions assumptions = new Assumptions(true); - HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan, OptimisticOptimizations.ALL); - Debug.dump(graph, "Graph"); - new CanonicalizerPhase(true).apply(graph, context); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - Debug.dump(graph, "Graph"); - new CanonicalizerPhase(true).apply(graph, context); - new DeadCodeEliminationPhase().apply(graph); - return graph; - } - }); + try (Scope s = Debug.scope("InliningTest", new DebugDumpScope(snippet))) { + Method method = getMethod(snippet); + StructuredGraph graph = eagerInfopointMode ? parseDebug(method) : parse(method); + PhasePlan phasePlan = getDefaultPhasePlan(eagerInfopointMode); + Assumptions assumptions = new Assumptions(true); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan, OptimisticOptimizations.ALL); + Debug.dump(graph, "Graph"); + new CanonicalizerPhase(true).apply(graph, context); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); + Debug.dump(graph, "Graph"); + new CanonicalizerPhase(true).apply(graph, context); + new DeadCodeEliminationPhase().apply(graph); + return graph; + } catch (Throwable e) { + throw Debug.handle(e); + } } private static StructuredGraph assertInlined(StructuredGraph graph) { diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Sat Nov 30 19:05:44 2013 +0100 @@ -27,7 +27,6 @@ import static com.oracle.graal.phases.GraalOptions.*; import java.util.*; -import java.util.concurrent.*; import com.oracle.graal.alloc.*; import com.oracle.graal.api.code.*; @@ -36,6 +35,7 @@ import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.debug.internal.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; @@ -132,49 +132,44 @@ * argument can be null. * @return the result of the compilation */ - public static T compileGraph(final StructuredGraph graph, final CallingConvention cc, final ResolvedJavaMethod installedCodeOwner, final Providers providers, - final Backend backend, final TargetDescription target, final GraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts, - final SpeculationLog speculationLog, final Suites suites, final T compilationResult) { - Debug.scope("GraalCompiler", new Object[]{graph, providers.getCodeCache()}, new Runnable() { - - public void run() { - compileGraphNoScope(graph, cc, installedCodeOwner, providers, backend, target, cache, plan, optimisticOpts, speculationLog, suites, compilationResult); - } - }); - + public static T compileGraph(StructuredGraph graph, CallingConvention cc, ResolvedJavaMethod installedCodeOwner, Providers providers, Backend backend, + TargetDescription target, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts, SpeculationLog speculationLog, Suites suites, T compilationResult) { + try (Scope s = Debug.scope("GraalCompiler", graph, providers.getCodeCache())) { + compileGraphNoScope(graph, cc, installedCodeOwner, providers, backend, target, cache, plan, optimisticOpts, speculationLog, suites, compilationResult); + } catch (Throwable e) { + throw Debug.handle(e); + } return compilationResult; } /** * Same as {@link #compileGraph} but without entering a - * {@linkplain Debug#scope(String, Object[], Runnable) debug scope}. + * {@linkplain Debug#scope(String, Object...) debug scope}. */ - public static T compileGraphNoScope(final StructuredGraph graph, final CallingConvention cc, final ResolvedJavaMethod installedCodeOwner, final Providers providers, - final Backend backend, final TargetDescription target, final GraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts, - final SpeculationLog speculationLog, final Suites suites, final T compilationResult) { - final Assumptions assumptions = new Assumptions(OptAssumptions.getValue()); - final LIR lir = Debug.scope("FrontEnd", new Callable() { + public static T compileGraphNoScope(StructuredGraph graph, CallingConvention cc, ResolvedJavaMethod installedCodeOwner, Providers providers, Backend backend, + TargetDescription target, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts, SpeculationLog speculationLog, Suites suites, T compilationResult) { + Assumptions assumptions = new Assumptions(OptAssumptions.getValue()); - public LIR call() { - try (TimerCloseable a = FrontEnd.start()) { - return emitHIR(providers, target, graph, assumptions, cache, plan, optimisticOpts, speculationLog, suites); - } + LIR lir = null; + try (Scope s = Debug.scope("FrontEnd"); TimerCloseable a = FrontEnd.start()) { + lir = emitHIR(providers, target, graph, assumptions, cache, plan, optimisticOpts, speculationLog, suites); + } catch (Throwable e) { + throw Debug.handle(e); + } + try (TimerCloseable a = BackEnd.start()) { + LIRGenerator lirGen = null; + try (Scope s = Debug.scope("BackEnd", lir)) { + lirGen = emitLIR(backend, target, lir, graph, cc); + } catch (Throwable e) { + throw Debug.handle(e); } - }); - try (TimerCloseable a = BackEnd.start()) { - final LIRGenerator lirGen = Debug.scope("BackEnd", lir, new Callable() { - - public LIRGenerator call() { - return emitLIR(backend, target, lir, graph, cc); - } - }); - Debug.scope("CodeGen", lirGen, new Runnable() { - - public void run() { - emitCode(backend, getLeafGraphIdArray(graph), assumptions, lirGen, compilationResult, installedCodeOwner); - } - - }); + try (Scope s = Debug.scope("CodeGen", lirGen)) { + emitCode(backend, getLeafGraphIdArray(graph), assumptions, lirGen, compilationResult, installedCodeOwner); + } catch (Throwable e) { + throw Debug.handle(e); + } + } catch (Throwable e) { + throw Debug.handle(e); } return compilationResult; @@ -193,8 +188,8 @@ /** * Builds the graph, optimizes it. */ - public static LIR emitHIR(Providers providers, TargetDescription target, final StructuredGraph graph, Assumptions assumptions, GraphCache cache, PhasePlan plan, - OptimisticOptimizations optimisticOpts, final SpeculationLog speculationLog, final Suites suites) { + public static LIR emitHIR(Providers providers, TargetDescription target, StructuredGraph graph, Assumptions assumptions, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts, + SpeculationLog speculationLog, Suites suites) { if (speculationLog != null) { speculationLog.snapshot(); @@ -224,68 +219,63 @@ InliningPhase.storeStatisticsAfterLowTier(graph); } - final SchedulePhase schedule = new SchedulePhase(); + SchedulePhase schedule = new SchedulePhase(); schedule.apply(graph); Debug.dump(schedule, "final schedule"); - final Block[] blocks = schedule.getCFG().getBlocks(); - final Block startBlock = schedule.getCFG().getStartBlock(); + Block[] blocks = schedule.getCFG().getBlocks(); + Block startBlock = schedule.getCFG().getStartBlock(); assert startBlock != null; assert startBlock.getPredecessorCount() == 0; - return Debug.scope("ComputeLinearScanOrder", new Callable() { + try (Scope s = Debug.scope("ComputeLinearScanOrder")) { + NodesToDoubles nodeProbabilities = new ComputeProbabilityClosure(graph).apply(); + List codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.length, startBlock, nodeProbabilities); + List linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.length, startBlock, nodeProbabilities); - @Override - public LIR call() { - NodesToDoubles nodeProbabilities = new ComputeProbabilityClosure(graph).apply(); - List codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.length, startBlock, nodeProbabilities); - List linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.length, startBlock, nodeProbabilities); - - LIR lir = new LIR(schedule.getCFG(), schedule.getBlockToNodesMap(), linearScanOrder, codeEmittingOrder); - Debug.dump(lir, "After linear scan order"); - return lir; - - } - }); + LIR lir = new LIR(schedule.getCFG(), schedule.getBlockToNodesMap(), linearScanOrder, codeEmittingOrder); + Debug.dump(lir, "After linear scan order"); + return lir; + } catch (Throwable e) { + throw Debug.handle(e); + } } - public static LIRGenerator emitLIR(final Backend backend, final TargetDescription target, final LIR lir, StructuredGraph graph, CallingConvention cc) { - final FrameMap frameMap = backend.newFrameMap(); - final LIRGenerator lirGen = backend.newLIRGenerator(graph, frameMap, cc, lir); - - Debug.scope("LIRGen", lirGen, new Runnable() { + private static void emitBlock(LIRGenerator lirGen, Block b) { + if (lirGen.lir.lir(b) == null) { + for (Block pred : b.getPredecessors()) { + if (!b.isLoopHeader() || !pred.isLoopEnd()) { + emitBlock(lirGen, pred); + } + } + lirGen.doBlock(b); + } + } - public void run() { - for (Block b : lir.linearScanOrder()) { - emitBlock(b); - } + public static LIRGenerator emitLIR(Backend backend, TargetDescription target, LIR lir, StructuredGraph graph, CallingConvention cc) { + FrameMap frameMap = backend.newFrameMap(); + LIRGenerator lirGen = backend.newLIRGenerator(graph, frameMap, cc, lir); - Debug.dump(lir, "After LIR generation"); + try (Scope s = Debug.scope("LIRGen", lirGen)) { + for (Block b : lir.linearScanOrder()) { + emitBlock(lirGen, b); } - private void emitBlock(Block b) { - if (lir.lir(b) == null) { - for (Block pred : b.getPredecessors()) { - if (!b.isLoopHeader() || !pred.isLoopEnd()) { - emitBlock(pred); - } - } - lirGen.doBlock(b); - } - } - }); + Debug.dump(lir, "After LIR generation"); + } catch (Throwable e) { + throw Debug.handle(e); + } lirGen.beforeRegisterAllocation(); - Debug.scope("Allocator", new Runnable() { - - public void run() { - if (backend.shouldAllocateRegisters()) { - new LinearScan(target, lir, lirGen, frameMap).allocate(); - } + try (Scope s = Debug.scope("Allocator")) { + if (backend.shouldAllocateRegisters()) { + new LinearScan(target, lir, lirGen, frameMap).allocate(); } - }); + } catch (Throwable e) { + throw Debug.handle(e); + } return lirGen; } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Sat Nov 30 19:05:44 2013 +0100 @@ -37,6 +37,7 @@ import com.oracle.graal.compiler.alloc.Interval.SpillState; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.LIRInstruction.OperandFlag; @@ -1818,66 +1819,61 @@ public void allocate() { - Debug.scope("LifetimeAnalysis", new Runnable() { - - public void run() { - numberInstructions(); - printLir("Before register allocation", true); - computeLocalLiveSets(); - computeGlobalLiveSets(); - buildIntervals(); - sortIntervalsBeforeAllocation(); - } - }); - - Debug.scope("RegisterAllocation", new Runnable() { + try (Scope s = Debug.scope("LifetimeAnalysis")) { + numberInstructions(); + printLir("Before register allocation", true); + computeLocalLiveSets(); + computeGlobalLiveSets(); + buildIntervals(); + sortIntervalsBeforeAllocation(); + } catch (Throwable e) { + throw Debug.handle(e); + } - public void run() { - printIntervals("Before register allocation"); - allocateRegisters(); - } - }); + try (Scope s = Debug.scope("RegisterAllocation")) { + printIntervals("Before register allocation"); + allocateRegisters(); + } catch (Throwable e) { + throw Debug.handle(e); + } - Debug.scope("ResolveDataFlow", new Runnable() { + try (Scope s = Debug.scope("ResolveDataFlow")) { + resolveDataFlow(); + } catch (Throwable e) { + throw Debug.handle(e); + } - public void run() { - resolveDataFlow(); - } - }); - - Debug.scope("DebugInfo", new Runnable() { + try (Scope s = Debug.scope("DebugInfo")) { + frameMap.finish(); - public void run() { - frameMap.finish(); + printIntervals("After register allocation"); + printLir("After register allocation", true); - printIntervals("After register allocation"); - printLir("After register allocation", true); + sortIntervalsAfterAllocation(); - sortIntervalsAfterAllocation(); + if (DetailedAsserts.getValue()) { + verify(); + } - if (DetailedAsserts.getValue()) { - verify(); - } - - eliminateSpillMoves(); - assignLocations(); + eliminateSpillMoves(); + assignLocations(); - if (DetailedAsserts.getValue()) { - verifyIntervals(); - } + if (DetailedAsserts.getValue()) { + verifyIntervals(); } - }); - - Debug.scope("ControlFlowOptimizations", new Runnable() { + } catch (Throwable e) { + throw Debug.handle(e); + } - public void run() { - printLir("After register number assignment", true); - EdgeMoveOptimizer.optimize(ir); - ControlFlowOptimizer.optimize(ir); - NullCheckOptimizer.optimize(ir, target.implicitNullCheckLimit); - printLir("After control flow optimization", false); - } - }); + try (Scope s = Debug.scope("ControlFlowOptimizations")) { + printLir("After register number assignment", true); + EdgeMoveOptimizer.optimize(ir); + ControlFlowOptimizer.optimize(ir); + NullCheckOptimizer.optimize(ir, target.implicitNullCheckLimit); + printLir("After control flow optimization", false); + } catch (Throwable e) { + throw Debug.handle(e); + } } void printIntervals(String label) { diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Sat Nov 30 19:05:44 2013 +0100 @@ -37,7 +37,7 @@ public class HighTier extends PhaseSuite { - static class Options { + public static class Options { // @formatter:off @Option(help = "") diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Sat Nov 30 19:05:44 2013 +0100 @@ -89,7 +89,9 @@ appendPhase(new FrameStateAssignmentPhase()); - appendPhase(new DeoptimizationGroupingPhase()); + if (OptDeoptimizationGrouping.getValue()) { + appendPhase(new DeoptimizationGroupingPhase()); + } if (OptCanonicalizer.getValue()) { appendPhase(canonicalizer); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Sat Nov 30 19:05:44 2013 +0100 @@ -105,68 +105,10 @@ return callable; } - public static void sandbox(String name, DebugConfig config, Runnable runnable) { - if (ENABLED) { - DebugScope.getInstance().scope(name, runnable, null, true, config, new Object[0]); - } else { - runnable.run(); - } - } - /** - * Creates a new debug scope that is unrelated to the current scope and runs a given task in the - * new scope. - * - * @param name new scope name - * @param context the context objects of the new scope - * @param config the debug configuration to use for the new scope - * @param runnable the task to run in the new scope + * Gets a string composed of the names in the current nesting of debug + * {@linkplain #scope(String, Object...) scopes} separated by {@code '.'}. */ - public static void sandbox(String name, Object[] context, DebugConfig config, Runnable runnable) { - if (ENABLED) { - DebugScope.getInstance().scope(name, runnable, null, true, config, context); - } else { - runnable.run(); - } - } - - /** - * Creates a new debug scope that is unrelated to the current scope and runs a given task in the - * new scope. - * - * @param name new scope name - * @param context the context objects of the new scope - * @param config the debug configuration to use for the new scope - * @param callable the task to run in the new scope - */ - public static T sandbox(String name, Object[] context, DebugConfig config, Callable callable) { - if (ENABLED) { - return DebugScope.getInstance().scope(name, null, callable, true, config, context); - } else { - return DebugScope.call(callable); - } - } - - public static void scope(String name, Runnable runnable) { - scope(name, new Object[0], runnable); - } - - public static T scope(String name, Callable callable) { - return scope(name, new Object[0], callable); - } - - public static void scope(String name, Object context, Runnable runnable) { - scope(name, new Object[]{context}, runnable); - } - - public static void scope(String name, Object[] context, Runnable runnable) { - if (ENABLED) { - DebugScope.getInstance().scope(name, runnable, null, false, null, context); - } else { - runnable.run(); - } - } - public static String currentScope() { if (ENABLED) { return DebugScope.getInstance().getQualifiedName(); @@ -175,20 +117,97 @@ } } - public static T scope(String name, Object context, Callable callable) { - return scope(name, new Object[]{context}, callable); + /** + * Represents a debug scope entered by {@link Debug#scope(String, Object...)} or + * {@link Debug#sandbox(String, DebugConfig, Object...)}. Leaving the scope is achieved via + * {@link #close()}. + */ + public interface Scope extends AutoCloseable { + void close(); } - public static T scope(String name, Object[] context, Callable callable) { + /** + * Creates and enters a new debug scope which will be a child of the current debug scope. + *

+ * It is recommended to use the try-with-resource statement for managing entering and leaving + * debug scopes. For example: + * + *

+     * try (Scope s = Debug.scope("InliningGraph", inlineeGraph)) {
+     *     ...
+     * } catch (Throwable e) {
+     *     throw Debug.handle(e);
+     * }
+     * 
+ * + * @param name the name of the new scope + * @param context objects to be appended to the {@linkplain #context() current} debug context + * @return the scope entered by this method which will be exited when its {@link Scope#close()} + * method is called + */ + public static Scope scope(String name, Object... context) { if (ENABLED) { - return DebugScope.getInstance().scope(name, null, callable, false, null, context); + return DebugScope.getInstance().scope(name, false, null, context); } else { - return DebugScope.call(callable); + return null; } } /** - * Prints an indented message to the current DebugLevel's logging stream if logging is enabled. + * Creates and enters a new debug scope which will be disjoint from the current debug scope. + *

+ * It is recommended to use the try-with-resource statement for managing entering and leaving + * debug scopes. For example: + * + *

+     * try (Scope s = Debug.sandbox("CompilingStub", null, stubGraph)) {
+     *     ...
+     * } catch (Throwable e) {
+     *     throw Debug.handle(e);
+     * }
+     * 
+ * + * @param name the name of the new scope + * @param config the debug configuration to use for the new scope + * @param context objects to be appended to the {@linkplain #context() current} debug context + * @return the scope entered by this method which will be exited when its {@link Scope#close()} + * method is called + */ + public static Scope sandbox(String name, DebugConfig config, Object... context) { + if (ENABLED) { + DebugConfig sandboxConfig = config == null ? silentConfig() : config; + return DebugScope.getInstance().scope(name, true, sandboxConfig, context); + } else { + return null; + } + } + + /** + * Handles an exception in the context of the debug scope just exited. The just exited scope + * must have the current scope as its parent which will be the case if the try-with-resource + * pattern recommended by {@link #scope(String, Object...)} and + * {@link #sandbox(String, DebugConfig, Object...)} is used + * + * @see #scope(String, Object...) + * @see #sandbox(String, DebugConfig, Object...) + */ + public static RuntimeException handle(Throwable exception) { + if (ENABLED) { + return DebugScope.getInstance().handle(exception); + } else { + if (exception instanceof Error) { + throw (Error) exception; + } + if (exception instanceof RuntimeException) { + throw (RuntimeException) exception; + } + throw new RuntimeException(exception); + } + } + + /** + * Prints an indented message to the current debug scopes's logging stream if logging is enabled + * in the scope. * * @param msg The format string of the log message * @param args The arguments referenced by the log message string @@ -231,7 +250,7 @@ } @Override - public Indent logIndent(String msg, Object... args) { + public Indent logAndIndent(String msg, Object... args) { return this; } @@ -240,6 +259,9 @@ return this; } + @Override + public void close() { + } } private static final NoLogger noLoggerInstance = new NoLogger(); @@ -281,9 +303,9 @@ * @param msg The format string of the log message * @param args The arguments referenced by the log message string * @return The new indentation level - * @see Indent#logIndent + * @see Indent#logAndIndent */ - public static Indent logIndent(String msg, Object... args) { + public static Indent logAndIndent(String msg, Object... args) { if (ENABLED) { DebugScope scope = DebugScope.getInstance(); scope.log(msg, args); @@ -300,7 +322,7 @@ * @param args The arguments referenced by the log message string * @return The new indentation level */ - public static Indent logIndent(boolean enabled, String msg, Object... args) { + public static Indent logAndIndent(boolean enabled, String msg, Object... args) { if (ENABLED) { DebugScope scope = DebugScope.getInstance(); boolean saveLogEnabled = scope.isLogEnabled(); @@ -373,9 +395,19 @@ } } - public static void setConfig(DebugConfig config) { + /** + * Changes the debug configuration for the current thread. + * + * @param config new configuration to use for the current thread + * @return an object that when {@linkplain DebugConfigScope#close() closed} will restore the + * debug configuration for the current thread to what it was before this method was + * called + */ + public static DebugConfigScope setConfig(DebugConfig config) { if (ENABLED) { - DebugScope.getInstance().setConfig(config); + return new DebugConfigScope(config); + } else { + return null; } } @@ -386,6 +418,10 @@ return new DebugHistogramImpl(name); } + public static DebugConfig silentConfig() { + return fixedConfig(false, false, false, false, Collections. emptyList(), System.out); + } + public static DebugConfig fixedConfig(final boolean isLogEnabled, final boolean isDumpEnabled, final boolean isMeterEnabled, final boolean isTimerEnabled, final Collection dumpHandlers, final PrintStream output) { return new DebugConfig() { diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfigScope.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfigScope.java Sat Nov 30 19:05:44 2013 +0100 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.debug; + +import com.oracle.graal.debug.internal.*; + +/** + * A utility for scoping a change to the current debug + * {@linkplain DebugScope#setConfig(DebugConfig) configuration}. For example: + * + *
+ *     DebugConfig config = ...;
+ *     try (DebugConfigScope s = new DebugConfigScope(config)) {
+ *         // ...
+ *     }
+ * 
+ */ +public class DebugConfigScope implements AutoCloseable { + + private final DebugConfig current; + + /** + * Sets the current debug {@linkplain DebugScope#setConfig(DebugConfig) configuration} to a + * given value and creates an object that when {@linkplain #close() closed} resets the + * configuration to the {@linkplain DebugScope#getConfig() current} configuration. + */ + public DebugConfigScope(DebugConfig config) { + this.current = DebugScope.getConfig(); + DebugScope.getInstance().setConfig(config); + } + + public void close() { + DebugScope.getInstance().setConfig(current); + } +} diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java Sat Nov 30 19:05:44 2013 +0100 @@ -0,0 +1,80 @@ +/* + * 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.debug; + +import java.io.*; +import java.util.*; + +public class DelegatingDebugConfig implements DebugConfig { + + protected final DebugConfig delegate; + + public DelegatingDebugConfig(DebugConfig delegate) { + this.delegate = delegate; + } + + @Override + public boolean isLogEnabled() { + return delegate.isLogEnabled(); + } + + @Override + public boolean isMeterEnabled() { + return delegate.isMeterEnabled(); + } + + @Override + public boolean isDumpEnabled() { + return delegate.isDumpEnabled(); + } + + @Override + public boolean isTimeEnabled() { + return delegate.isTimeEnabled(); + } + + @Override + public RuntimeException interceptException(Throwable e) { + return delegate.interceptException(e); + } + + @Override + public Collection dumpHandlers() { + return delegate.dumpHandlers(); + } + + @Override + public PrintStream output() { + return delegate.output(); + } + + @Override + public void addToContext(Object o) { + delegate.addToContext(o); + } + + @Override + public void removeFromContext(Object o) { + delegate.removeFromContext(o); + } +} diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Indent.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Indent.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Indent.java Sat Nov 30 19:05:44 2013 +0100 @@ -48,8 +48,20 @@ * in.outdent(); * } * + * + * Example usage with try-with-resources: + * + *
+ * 
+ *      try (Indent in = Debug.logIndent("header message")) {
+ *          ...
+ *          in.log("message");
+ *          ...
+ *      }
+ * 
+ * 
*/ -public interface Indent { +public interface Indent extends AutoCloseable { /** * Prints an indented message to the DebugLevel's logging stream if logging is enabled. @@ -81,9 +93,9 @@ * @param msg The format string of the log message * @param args The arguments referenced by the log message string * @return The new indentation level - * @see Debug#logIndent + * @see Debug#logAndIndent */ - Indent logIndent(String msg, Object... args); + Indent logAndIndent(String msg, Object... args); /** * Restores the previous indent level. Calling this method is important to restore the correct @@ -92,4 +104,6 @@ * @return The indent level from which this Indent was created. */ Indent outdent(); + + void close(); } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java Sat Nov 30 19:05:44 2013 +0100 @@ -28,7 +28,7 @@ import com.oracle.graal.debug.*; -public final class DebugScope { +public final class DebugScope implements Debug.Scope { private final class IndentImpl implements Indent { @@ -75,7 +75,7 @@ } @Override - public Indent logIndent(String msg, Object... args) { + public Indent logAndIndent(String msg, Object... args) { log(msg, args); return indent(); } @@ -87,17 +87,25 @@ } return lastUsedIndent; } + + @Override + public void close() { + outdent(); + } } private static ThreadLocal instanceTL = new ThreadLocal<>(); + private static ThreadLocal lastClosedTL = new ThreadLocal<>(); private static ThreadLocal configTL = new ThreadLocal<>(); private static ThreadLocal lastExceptionThrownTL = new ThreadLocal<>(); private final DebugScope parent; + private final DebugConfig parentConfig; + private final boolean sandbox; private IndentImpl lastUsedIndent; private boolean logScopeName; - private Object[] context; + private final Object[] context; private final DebugValueMap valueMap; private final String qualifiedName; @@ -113,7 +121,7 @@ public static DebugScope getInstance() { DebugScope result = instanceTL.get(); if (result == null) { - DebugScope topLevelDebugScope = new DebugScope(Thread.currentThread().getName(), "", null); + DebugScope topLevelDebugScope = new DebugScope(Thread.currentThread().getName(), "", null, false); instanceTL.set(topLevelDebugScope); DebugValueMap.registerTopLevel(topLevelDebugScope.getValueMap()); return topLevelDebugScope; @@ -126,8 +134,10 @@ return configTL.get(); } - private DebugScope(String name, String qualifiedName, DebugScope parent, Object... context) { + private DebugScope(String name, String qualifiedName, DebugScope parent, boolean sandbox, Object... context) { this.parent = parent; + this.sandbox = sandbox; + this.parentConfig = getConfig(); this.context = context; this.qualifiedName = qualifiedName; if (parent != null) { @@ -157,6 +167,12 @@ } } + public void close() { + instanceTL.set(parent); + setConfig(parentConfig); + lastClosedTL.set(this); + } + public boolean isDumpEnabled() { return dumpEnabled; } @@ -216,65 +232,56 @@ } /** - * Runs a task in a new debug scope which is either a child of the current scope or a disjoint - * top level scope. + * Creates and enters a new debug scope which is either a child of the current scope or a + * disjoint top level scope. * - * @param newName the name of the new scope - * @param runnable the task to run (must be null iff {@code callable} is not null) - * @param callable the task to run (must be null iff {@code runnable} is not null) + * @param name the name of the new scope * @param sandbox specifies if the scope is a child of the current scope or a top level scope - * @param sandboxConfig the config to use of a new top level scope (ignored if + * @param sandboxConfig the configuration to use for a new top level scope (ignored if * {@code sandbox == false}) - * @param newContext context objects of the new scope - * @return the value returned by the task + * @param context objects to be appended to the debug context + * @return the new scope which will be exited when its {@link #close()} method is called */ - public T scope(String newName, Runnable runnable, Callable callable, boolean sandbox, DebugConfig sandboxConfig, Object[] newContext) { - DebugScope oldContext = getInstance(); - DebugConfig oldConfig = getConfig(); - boolean oldLogEnabled = oldContext.isLogEnabled(); - DebugScope newChild = null; + @SuppressWarnings("hiding") + public DebugScope scope(String name, boolean sandbox, DebugConfig sandboxConfig, Object... context) { + DebugScope newScope = null; if (sandbox) { - newChild = new DebugScope(newName, newName, null, newContext); + newScope = new DebugScope(name, name, this, true, context); setConfig(sandboxConfig); } else { - newChild = oldContext.createChild(newName, newContext); + newScope = this.createChild(name, context); } - instanceTL.set(newChild); - newChild.updateFlags(); - try { - return executeScope(runnable, callable); - } finally { - newChild.context = null; - instanceTL.set(oldContext); - setConfig(oldConfig); - setLogEnabled(oldLogEnabled); - } + instanceTL.set(newScope); + newScope.setLogEnabled(this.isLogEnabled()); + newScope.updateFlags(); + return newScope; } - private T executeScope(Runnable runnable, Callable callable) { - - try { - if (runnable != null) { - runnable.run(); - } - if (callable != null) { - return call(callable); + public RuntimeException handle(Throwable e) { + DebugScope lastClosed = lastClosedTL.get(); + assert lastClosed.parent == this : "Debug.handle() used with no matching Debug.scope(...) or Debug.sandbox(...)"; + if (e != lastExceptionThrownTL.get()) { + RuntimeException newException = null; + instanceTL.set(lastClosed); + try (DebugScope s = lastClosed) { + newException = s.interceptException(e); } - } catch (Throwable e) { - if (e == lastExceptionThrownTL.get()) { - throw e; + assert instanceTL.get() == this; + assert lastClosed == lastClosedTL.get(); + if (newException == null) { + lastExceptionThrownTL.set(e); } else { - RuntimeException newException = interceptException(e); - if (newException == null) { - lastExceptionThrownTL.set(e); - throw e; - } else { - lastExceptionThrownTL.set(newException); - throw newException; - } + lastExceptionThrownTL.set(newException); + throw newException; } } - return null; + if (e instanceof Error) { + throw (Error) e; + } + if (e instanceof RuntimeException) { + throw (RuntimeException) e; + } + throw new RuntimeException(e); } private void updateFlags() { @@ -283,7 +290,6 @@ meterEnabled = false; timeEnabled = false; dumpEnabled = false; - setLogEnabled(false); // Be pragmatic: provide a default log stream to prevent a crash if the stream is not // set while logging @@ -293,24 +299,20 @@ timeEnabled = config.isTimeEnabled(); dumpEnabled = config.isDumpEnabled(); output = config.output(); - setLogEnabled(config.isLogEnabled()); + if (config.isLogEnabled()) { + setLogEnabled(true); + } } } private RuntimeException interceptException(final Throwable e) { final DebugConfig config = getConfig(); if (config != null) { - return scope("InterceptException", null, new Callable() { - - @Override - public RuntimeException call() throws Exception { - try { - return config.interceptException(e); - } catch (Throwable t) { - return new RuntimeException("Exception while intercepting exception", t); - } - } - }, false, null, new Object[]{e}); + try (DebugScope s = scope("InterceptException", false, null, e)) { + return config.interceptException(e); + } catch (Throwable t) { + return new RuntimeException("Exception while intercepting exception", t); + } } return null; } @@ -332,7 +334,7 @@ if (this.qualifiedName.length() > 0) { newQualifiedName = this.qualifiedName + SCOPE_SEP + newName; } - DebugScope result = new DebugScope(newName, newQualifiedName, this, newContext); + DebugScope result = new DebugScope(newName, newQualifiedName, this, false, newContext); return result; } @@ -355,7 +357,7 @@ private void selectScope() { while (currentScope != null && currentScope.context.length <= objectIndex) { - currentScope = currentScope.parent; + currentScope = currentScope.sandbox ? null : currentScope.parent; objectIndex = 0; } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Sat Nov 30 19:05:44 2013 +0100 @@ -75,6 +75,11 @@ NodeChangedListener usagesDroppedToZeroListener; private final HashMap cachedNodes = new HashMap<>(); + /** + * Determines if external nodes will use {@link Graph}'s canonicalization cache. + */ + public static final boolean CacheExternalNodesInGraph = Boolean.parseBoolean(System.getProperty("graal.cacheExternalNodesInGraph", "false")); + private static final class CacheEntry { private final Node node; @@ -343,7 +348,7 @@ } /** - * Looks for a node similar to {@code node}. If not found, {@code node} is added to the + * Looks for a node similar to {@code node}. If not found, {@code node} is added to a * cache in this graph used to canonicalize nodes. *

* Note that node must implement {@link ValueNumberable} and must be an @@ -351,9 +356,12 @@ * * @return a node similar to {@code node} if one exists, otherwise {@code node} */ - public T uniqueWithoutAdd(T node) { + public T uniqueExternal(T node) { assert node.isExternal() : node; assert node instanceof ValueNumberable : node; + if (!CacheExternalNodesInGraph) { + return node; + } return uniqueHelper(node, false); } @@ -380,6 +388,7 @@ } Node findNodeInCache(Node node) { + assert !node.isExternal() || CacheExternalNodesInGraph; CacheEntry key = new CacheEntry(node); Node result = cachedNodes.get(key); if (result != null && result.isDeleted()) { diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Sat Nov 30 19:05:44 2013 +0100 @@ -712,7 +712,7 @@ } /** - * Determines if a given node is {@linkplain Graph#uniqueWithoutAdd(Node) unique} within a given + * Determines if a given node is {@linkplain Graph#uniqueExternal(Node) unique} within a given * graph if the node is non-null and {@linkplain #isExternal() external}. * * @param node node to check @@ -721,7 +721,7 @@ * {@link VerificationError} */ public static boolean verifyUniqueIfExternal(Node node, Graph graph) { - if (node != null && node.isExternal()) { + if (node != null && node.isExternal() && Graph.CacheExternalNodesInGraph) { Node cached = graph.findNodeInCache(node); node.assertTrue(cached == node, "external node does not match canonical node %s", cached); } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Sat Nov 30 19:05:44 2013 +0100 @@ -158,13 +158,17 @@ */ private final boolean isSimplifiable; - private NodeClass(Class clazz) { + public NodeClass(Class clazz) { + this(clazz, new DefaultCalcOffset(), null, 0); + } + + public NodeClass(Class clazz, CalcOffset calcOffset, int[] presetIterableIds, int presetIterableId) { super(clazz); assert NODE_CLASS.isAssignableFrom(clazz); this.isCanonicalizable = Canonicalizable.class.isAssignableFrom(clazz); this.isSimplifiable = Simplifiable.class.isAssignableFrom(clazz); - FieldScanner scanner = new FieldScanner(new DefaultCalcOffset()); + FieldScanner scanner = new FieldScanner(calcOffset); scanner.scan(clazz); directInputCount = scanner.inputOffsets.size(); @@ -200,7 +204,10 @@ } this.nameTemplate = newNameTemplate == null ? newShortName : newNameTemplate; this.shortName = newShortName; - if (IterableNodeType.class.isAssignableFrom(clazz)) { + if (presetIterableIds != null) { + this.iterableIds = presetIterableIds; + this.iterableId = presetIterableId; + } else if (IterableNodeType.class.isAssignableFrom(clazz)) { ITERABLE_NODE_TYPES.increment(); this.iterableId = nextIterableId++; List existingClasses = new LinkedList<>(); @@ -931,6 +938,8 @@ Node newInput = duplicationReplacement.replacement(input, true); node.updateUsages(null, newInput); assert Node.verifyUniqueIfExternal(newInput, node.graph()); + assert newInput == null || fieldTypes.get(inputOffsets[index]).isAssignableFrom(newInput.getClass()) : "Can not assign " + newInput.getClass() + " to " + + fieldTypes.get(inputOffsets[index]) + " in " + node; putNode(node, inputOffsets[index], newInput); } index++; @@ -946,6 +955,8 @@ if (successor != null) { Node newSucc = duplicationReplacement.replacement(successor, false); node.updatePredecessor(null, newSucc); + assert newSucc == null || fieldTypes.get(successorOffsets[index]).isAssignableFrom(newSucc.getClass()) : fieldTypes.get(successorOffsets[index]) + " is not compatible with " + + newSucc.getClass(); putNode(node, successorOffsets[index], newSucc); } index++; @@ -1374,7 +1385,7 @@ public Node replacement(Node node, boolean isInput) { if (node.isExternal() && node instanceof ValueNumberable) { - return graph.uniqueWithoutAdd(node); + return graph.uniqueExternal(node); } Node target = newNodes.get(node); if (target == null) { diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Sat Nov 30 19:05:44 2013 +0100 @@ -84,7 +84,7 @@ } protected Replacements createReplacements(HotSpotGraalRuntime runtime, Assumptions assumptions, Providers p) { - return new HotSpotReplacementsImpl(p, runtime.getConfig(), assumptions); + return new HotSpotReplacementsImpl(p, runtime.getConfig(), assumptions, p.getCodeCache().getTarget()); } protected AMD64HotSpotForeignCallsProvider createForeignCalls(HotSpotGraalRuntime runtime, HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java Sat Nov 30 19:05:44 2013 +0100 @@ -36,6 +36,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; @@ -61,11 +62,29 @@ register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER, 0L, PRESERVES_REGISTERS, LEAF, null, exceptionCc, NOT_REEXECUTABLE, ANY_LOCATION)); register(new HotSpotForeignCallLinkage(EXCEPTION_HANDLER_IN_CALLER, JUMP_ADDRESS, PRESERVES_REGISTERS, LEAF, exceptionCc, null, NOT_REEXECUTABLE, ANY_LOCATION)); + // When the java.ext.dirs property is modified then the crypto classes might not be found. + // If that's the case we ignore the ClassNotFoundException and continue since we cannot + // replace a non-existing method anyway. + try { + // These stubs do callee saving + registerForeignCall(ENCRYPT_BLOCK, config.aescryptEncryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); + registerForeignCall(DECRYPT_BLOCK, config.aescryptDecryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); + } catch (GraalInternalError e) { + if (!(e.getCause() instanceof ClassNotFoundException)) { + throw e; + } + } + try { + // These stubs do callee saving + registerForeignCall(ENCRYPT, config.cipherBlockChainingEncryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); + registerForeignCall(DECRYPT, config.cipherBlockChainingDecryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); + } catch (GraalInternalError e) { + if (!(e.getCause() instanceof ClassNotFoundException)) { + throw e; + } + } + // These stubs do callee saving - registerForeignCall(ENCRYPT_BLOCK, config.aescryptEncryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); - registerForeignCall(DECRYPT_BLOCK, config.aescryptDecryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); - registerForeignCall(ENCRYPT, config.cipherBlockChainingEncryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); - registerForeignCall(DECRYPT, config.cipherBlockChainingDecryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); super.initialize(providers, config); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java Sat Nov 30 19:05:44 2013 +0100 @@ -48,7 +48,7 @@ // to be valid for the entire run of the VM. Assumptions assumptions = new Assumptions(false); Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null); - Replacements replacements = new HSAILHotSpotReplacementsImpl(p, assumptions, host.getReplacements()); + Replacements replacements = new HSAILHotSpotReplacementsImpl(p, assumptions, codeCache.getTarget(), host.getReplacements()); HotSpotDisassemblerProvider disassembler = host.getDisassembler(); HotSpotSuitesProvider suites = host.getSuites(); HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java Sat Nov 30 19:05:44 2013 +0100 @@ -38,8 +38,8 @@ private final Replacements host; - public HSAILHotSpotReplacementsImpl(Providers providers, Assumptions assumptions, Replacements host) { - super(providers, assumptions); + public HSAILHotSpotReplacementsImpl(Providers providers, Assumptions assumptions, TargetDescription target, Replacements host) { + super(providers, assumptions, target); this.host = host; } diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Sat Nov 30 19:05:44 2013 +0100 @@ -61,7 +61,7 @@ // to be valid for the entire run of the VM. Assumptions assumptions = new Assumptions(false); Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null); - HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, runtime.getConfig(), assumptions); + HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(p, runtime.getConfig(), assumptions, target); HotSpotDisassemblerProvider disassembler = new HotSpotDisassemblerProvider(runtime); HotSpotSuitesProvider suites = new HotSpotSuitesProvider(runtime); HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements, disassembler, suites, registers); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -39,7 +39,7 @@ boolean originalSetting = ExitVMOnException.getValue(); // Compile a couple classes in rt.jar String file = System.getProperty("java.home") + "/lib/rt.jar"; - new CompileTheWorld(file, 1, 5).compile(); + new CompileTheWorld(file, 1, 5, false).compile(); ExitVMOnException.setValue(originalSetting); } diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -34,6 +34,7 @@ import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.phases.*; @@ -243,54 +244,53 @@ } private void test(final String snippet, final int expectedBarriers) throws Exception, SecurityException { - Debug.scope("WriteBarrierAditionTest", new DebugDumpScope(snippet), new Runnable() { + try (Scope s = Debug.scope("WriteBarrierAdditionTest", new DebugDumpScope(snippet))) { + StructuredGraph graph = parse(snippet); + HighTierContext highContext = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + MidTierContext midContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL); + new InliningPhase(new InliningPhase.InlineEverythingPolicy(), new CanonicalizerPhase(true)).apply(graph, highContext); + new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highContext); + new GuardLoweringPhase().apply(graph, midContext); + new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, midContext); + new WriteBarrierAdditionPhase().apply(graph); + Debug.dump(graph, "After Write Barrier Addition"); - public void run() { - StructuredGraph graph = parse(snippet); - HighTierContext highContext = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); - MidTierContext midContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL); - new InliningPhase(new InliningPhase.InlineEverythingPolicy(), new CanonicalizerPhase(true)).apply(graph, highContext); - new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highContext); - new GuardLoweringPhase().apply(graph, midContext); - new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, midContext); - new WriteBarrierAdditionPhase().apply(graph); - Debug.dump(graph, "After Write Barrier Addition"); - - int barriers = 0; + int barriers = 0; + if (useG1GC()) { + barriers = graph.getNodes().filter(G1ReferentFieldReadBarrier.class).count() + graph.getNodes().filter(G1PreWriteBarrier.class).count() + + graph.getNodes().filter(G1PostWriteBarrier.class).count(); + } else { + barriers = graph.getNodes().filter(SerialWriteBarrier.class).count(); + } + Assert.assertEquals(expectedBarriers, barriers); + for (WriteNode write : graph.getNodes().filter(WriteNode.class)) { if (useG1GC()) { - barriers = graph.getNodes().filter(G1ReferentFieldReadBarrier.class).count() + graph.getNodes().filter(G1PreWriteBarrier.class).count() + - graph.getNodes().filter(G1PostWriteBarrier.class).count(); + if (write.getBarrierType() != BarrierType.NONE) { + Assert.assertEquals(1, write.successors().count()); + Assert.assertTrue(write.next() instanceof G1PostWriteBarrier); + Assert.assertTrue(write.predecessor() instanceof G1PreWriteBarrier); + } } else { - barriers = graph.getNodes().filter(SerialWriteBarrier.class).count(); - } - Assert.assertEquals(expectedBarriers, barriers); - for (WriteNode write : graph.getNodes().filter(WriteNode.class)) { - if (useG1GC()) { - if (write.getBarrierType() != BarrierType.NONE) { - Assert.assertEquals(1, write.successors().count()); - Assert.assertTrue(write.next() instanceof G1PostWriteBarrier); - Assert.assertTrue(write.predecessor() instanceof G1PreWriteBarrier); - } - } else { - if (write.getBarrierType() != BarrierType.NONE) { - Assert.assertEquals(1, write.successors().count()); - Assert.assertTrue(write.next() instanceof SerialWriteBarrier); - } - } - } - - for (ReadNode read : graph.getNodes().filter(ReadNode.class)) { - if (read.getBarrierType() != BarrierType.NONE) { - if (read.location() instanceof ConstantLocationNode) { - Assert.assertEquals(referentOffset(), ((ConstantLocationNode) (read.location())).getDisplacement()); - } - Assert.assertTrue(useG1GC()); - Assert.assertEquals(BarrierType.PRECISE, read.getBarrierType()); - Assert.assertTrue(read.next() instanceof G1ReferentFieldReadBarrier); + if (write.getBarrierType() != BarrierType.NONE) { + Assert.assertEquals(1, write.successors().count()); + Assert.assertTrue(write.next() instanceof SerialWriteBarrier); } } } - }); + + for (ReadNode read : graph.getNodes().filter(ReadNode.class)) { + if (read.getBarrierType() != BarrierType.NONE) { + if (read.location() instanceof ConstantLocationNode) { + Assert.assertEquals(referentOffset(), ((ConstantLocationNode) (read.location())).getDisplacement()); + } + Assert.assertTrue(useG1GC()); + Assert.assertEquals(BarrierType.PRECISE, read.getBarrierType()); + Assert.assertTrue(read.next() instanceof G1ReferentFieldReadBarrier); + } + } + } catch (Throwable e) { + throw Debug.handle(e); + } } private void test2(final String snippet, Object a, Object b, Object c) throws Exception { diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -23,7 +23,6 @@ package com.oracle.graal.hotspot.test; import java.util.*; -import java.util.concurrent.*; import org.junit.*; @@ -31,6 +30,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.debug.internal.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.nodes.*; @@ -610,108 +610,100 @@ } private void test(final String snippet, final int expectedBarriers, final int... removedBarrierIndices) { - - AssertionError expectedError = Debug.scope("WriteBarrierVerificationTest", new DebugDumpScope(snippet), new Callable() { + try (Scope d = Debug.scope("WriteBarrierVerificationTest", new DebugDumpScope(snippet))) { + final StructuredGraph graph = parse(snippet); + HighTierContext highTierContext = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext); - public AssertionError call() { - final StructuredGraph graph = parse(snippet); - HighTierContext highTierContext = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext); + MidTierContext midTierContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL); - MidTierContext midTierContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL); + new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext); + new GuardLoweringPhase().apply(graph, midTierContext); + new LoopSafepointInsertionPhase().apply(graph); + new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext); - new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext); - new GuardLoweringPhase().apply(graph, midTierContext); - new LoopSafepointInsertionPhase().apply(graph); - new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext); - - new WriteBarrierAdditionPhase().apply(graph); + new WriteBarrierAdditionPhase().apply(graph); - int barriers = 0; - // First, the total number of expected barriers is checked. - HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig(); - if (config.useG1GC) { - barriers = graph.getNodes().filter(G1PreWriteBarrier.class).count() + graph.getNodes().filter(G1PostWriteBarrier.class).count() + - graph.getNodes().filter(G1ArrayRangePreWriteBarrier.class).count() + graph.getNodes().filter(G1ArrayRangePostWriteBarrier.class).count(); - Assert.assertTrue(expectedBarriers * 2 == barriers); - } else { - barriers = graph.getNodes().filter(SerialWriteBarrier.class).count() + graph.getNodes().filter(SerialArrayRangeWriteBarrier.class).count(); - Assert.assertTrue(expectedBarriers == barriers); - } - // Iterate over all write nodes and remove barriers according to input indices. - NodeIteratorClosure closure = new NodeIteratorClosure() { + int barriers = 0; + // First, the total number of expected barriers is checked. + HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig(); + if (config.useG1GC) { + barriers = graph.getNodes().filter(G1PreWriteBarrier.class).count() + graph.getNodes().filter(G1PostWriteBarrier.class).count() + + graph.getNodes().filter(G1ArrayRangePreWriteBarrier.class).count() + graph.getNodes().filter(G1ArrayRangePostWriteBarrier.class).count(); + Assert.assertTrue(expectedBarriers * 2 == barriers); + } else { + barriers = graph.getNodes().filter(SerialWriteBarrier.class).count() + graph.getNodes().filter(SerialArrayRangeWriteBarrier.class).count(); + Assert.assertTrue(expectedBarriers == barriers); + } + // Iterate over all write nodes and remove barriers according to input indices. + NodeIteratorClosure closure = new NodeIteratorClosure() { - @Override - protected Boolean processNode(FixedNode node, Boolean currentState) { - if (node instanceof WriteNode) { - WriteNode write = (WriteNode) node; - LocationIdentity obj = write.getLocationIdentity(); - if (obj instanceof ResolvedJavaField) { - if (((ResolvedJavaField) obj).getName().equals("barrierIndex")) { - /* - * A "barrierIndex" variable was found and is checked against - * the input barrier array. - */ - if (eliminateBarrier(write.value().asConstant().asInt(), removedBarrierIndices)) { - return true; - } + @Override + protected Boolean processNode(FixedNode node, Boolean currentState) { + if (node instanceof WriteNode) { + WriteNode write = (WriteNode) node; + LocationIdentity obj = write.getLocationIdentity(); + if (obj instanceof ResolvedJavaField) { + if (((ResolvedJavaField) obj).getName().equals("barrierIndex")) { + /* + * A "barrierIndex" variable was found and is checked against the + * input barrier array. + */ + if (eliminateBarrier(write.value().asConstant().asInt(), removedBarrierIndices)) { + return true; } } - } else if (node instanceof SerialWriteBarrier || node instanceof G1PostWriteBarrier) { - // Remove flagged write barriers. - if (currentState) { - graph.removeFixed(((FixedWithNextNode) node)); - return false; - } } - return currentState; + } else if (node instanceof SerialWriteBarrier || node instanceof G1PostWriteBarrier) { + // Remove flagged write barriers. + if (currentState) { + graph.removeFixed(((FixedWithNextNode) node)); + return false; + } } + return currentState; + } - private boolean eliminateBarrier(int index, int[] map) { - for (int i = 0; i < map.length; i++) { - if (map[i] == index) { - return true; - } + private boolean eliminateBarrier(int index, int[] map) { + for (int i = 0; i < map.length; i++) { + if (map[i] == index) { + return true; } - return false; - } - - @Override - protected Map processLoop(LoopBeginNode loop, Boolean initialState) { - return ReentrantNodeIterator.processLoop(this, loop, initialState).exitStates; - } - - @Override - protected Boolean merge(MergeNode merge, List states) { - return false; } + return false; + } - @Override - protected Boolean afterSplit(AbstractBeginNode node, Boolean oldState) { - return false; - } - }; + @Override + protected Map processLoop(LoopBeginNode loop, Boolean initialState) { + return ReentrantNodeIterator.processLoop(this, loop, initialState).exitStates; + } + + @Override + protected Boolean merge(MergeNode merge, List states) { + return false; + } - DebugConfig debugConfig = DebugScope.getConfig(); - try { - ReentrantNodeIterator.apply(closure, graph.start(), false, null); - Debug.setConfig(Debug.fixedConfig(false, false, false, false, debugConfig.dumpHandlers(), debugConfig.output())); - new WriteBarrierVerificationPhase().apply(graph); - } catch (AssertionError error) { - /* - * Catch assertion, test for expected one and re-throw in order to validate unit - * test. - */ - Assert.assertTrue(error.getMessage().contains("Write barrier must be present")); - return error; - } finally { - Debug.setConfig(debugConfig); + @Override + protected Boolean afterSplit(AbstractBeginNode node, Boolean oldState) { + return false; } - return null; + }; + + DebugConfig debugConfig = DebugScope.getConfig(); + DebugConfig fixedConfig = Debug.fixedConfig(false, false, false, false, debugConfig.dumpHandlers(), debugConfig.output()); + try (DebugConfigScope s = Debug.setConfig(fixedConfig)) { + ReentrantNodeIterator.apply(closure, graph.start(), false, null); + new WriteBarrierVerificationPhase().apply(graph); + } catch (AssertionError error) { + /* + * Catch assertion, test for expected one and re-throw in order to validate unit + * test. + */ + Assert.assertTrue(error.getMessage().contains("Write barrier must be present")); + throw error; } - }); - if (expectedError != null) { - throw expectedError; + } catch (Throwable e) { + throw Debug.handle(e); } } } diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Sat Nov 30 19:05:44 2013 +0100 @@ -37,6 +37,7 @@ import com.oracle.graal.compiler.CompilerThreadFactory.CompilerThread; import com.oracle.graal.compiler.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.debug.internal.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; @@ -142,32 +143,29 @@ CompilationResult result = null; TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method); long start = System.currentTimeMillis(); - try { - result = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true), new Callable() { - - @Override - public CompilationResult call() throws Exception { - GraphCache graphCache = backend.getRuntime().getGraphCache(); - if (graphCache != null) { - graphCache.removeStaleGraphs(); - } + try (Scope s = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true))) { + GraphCache graphCache = backend.getRuntime().getGraphCache(); + if (graphCache != null) { + graphCache.removeStaleGraphs(); + } - HotSpotProviders providers = backend.getProviders(); - Replacements replacements = providers.getReplacements(); - graph = replacements.getMethodSubstitution(method); - if (graph == null || entryBCI != INVOCATION_ENTRY_BCI) { - graph = new StructuredGraph(method, entryBCI); - } else { - // Compiling method substitution - must clone the graph - graph = graph.copy(); - } - InlinedBytecodes.add(method.getCodeSize()); - CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); - Suites suites = providers.getSuites().getDefaultSuites(); - return GraalCompiler.compileGraph(graph, cc, method, providers, backend, backend.getTarget(), graphCache, plan, optimisticOpts, method.getSpeculationLog(), suites, - new CompilationResult()); - } - }); + HotSpotProviders providers = backend.getProviders(); + Replacements replacements = providers.getReplacements(); + graph = replacements.getMethodSubstitution(method); + if (graph == null || entryBCI != INVOCATION_ENTRY_BCI) { + graph = new StructuredGraph(method, entryBCI); + } else { + // Compiling method substitution - must clone the graph + graph = graph.copy(); + } + InlinedBytecodes.add(method.getCodeSize()); + CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); + Suites suites = providers.getSuites().getDefaultSuites(); + result = GraalCompiler.compileGraph(graph, cc, method, providers, backend, backend.getTarget(), graphCache, plan, optimisticOpts, method.getSpeculationLog(), suites, + new CompilationResult()); + + } catch (Throwable e) { + throw Debug.handle(e); } finally { filter.remove(); final boolean printAfterCompilation = PrintAfterCompilation.getValue() && !TTY.isSuppressed(); @@ -231,21 +229,19 @@ private HotSpotInstalledCode installMethod(final CompilationResult compResult) { final HotSpotCodeCacheProvider codeCache = backend.getProviders().getCodeCache(); - return Debug.scope("CodeInstall", new Object[]{new DebugDumpScope(String.valueOf(id), true), codeCache, method}, new Callable() { - - @Override - public HotSpotInstalledCode call() { - HotSpotInstalledCode installedCode = codeCache.installMethod(method, entryBCI, compResult); - if (Debug.isDumpEnabled()) { - Debug.dump(new Object[]{compResult, installedCode}, "After code installation"); - } - if (Debug.isLogEnabled()) { - Debug.log("%s", backend.getProviders().getDisassembler().disassemble(installedCode)); - } - return installedCode; + HotSpotInstalledCode installedCode = null; + try (Scope s = Debug.scope("CodeInstall", new DebugDumpScope(String.valueOf(id), true), codeCache, method)) { + installedCode = codeCache.installMethod(method, entryBCI, compResult); + if (Debug.isDumpEnabled()) { + Debug.dump(new Object[]{compResult, installedCode}, "After code installation"); } - - }); + if (Debug.isLogEnabled()) { + Debug.log("%s", backend.getProviders().getDisassembler().disassemble(installedCode)); + } + } catch (Throwable e) { + throw Debug.handle(e); + } + return installedCode; } private boolean tryToChangeStatus(CompilationStatus from, CompilationStatus to) { diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Sat Nov 30 19:05:44 2013 +0100 @@ -68,13 +68,15 @@ private int compiledMethodsCounter = 0; private long compileTime = 0; + private boolean verbose; + /** * Create a compile-the-world instance with default values from * {@link GraalOptions#CompileTheWorld}, {@link GraalOptions#CompileTheWorldStartAt} and * {@link GraalOptions#CompileTheWorldStopAt}. */ public CompileTheWorld() { - this(CompileTheWorld.getValue(), CompileTheWorldStartAt.getValue(), CompileTheWorldStopAt.getValue()); + this(CompileTheWorld.getValue(), CompileTheWorldStartAt.getValue(), CompileTheWorldStopAt.getValue(), true); } /** @@ -84,13 +86,18 @@ * @param startAt index of the class file to start compilation at * @param stopAt index of the class file to stop compilation at */ - public CompileTheWorld(String files, int startAt, int stopAt) { + public CompileTheWorld(String files, int startAt, int stopAt, boolean verbose) { this.files = files; this.startAt = startAt; this.stopAt = stopAt; + this.verbose = verbose; - // We don't want the VM to exit when a method fails to compile. + // We don't want the VM to exit when a method fails to compile... ExitVMOnException.setValue(false); + + // ...but we want to see exceptions. + PrintBailout.setValue(true); + PrintStackTraceOnException.setValue(true); } /** @@ -123,6 +130,20 @@ } } + public void println() { + println(""); + } + + public void println(String format, Object... args) { + println(String.format(format, args)); + } + + public void println(String s) { + if (verbose) { + TTY.println(s); + } + } + /** * Compile all methods in all classes in the Zip/Jar files passed. * @@ -137,13 +158,13 @@ // For now we only compile all methods in all classes in zip/jar files. if (!entry.endsWith(".zip") && !entry.endsWith(".jar")) { - TTY.println("CompileTheWorld : Skipped classes in " + entry); - TTY.println(); + println("CompileTheWorld : Skipped classes in " + entry); + println(); continue; } - TTY.println("CompileTheWorld : Compiling all classes in " + entry); - TTY.println(); + println("CompileTheWorld : Compiling all classes in " + entry); + println(); URL url = new URL("jar", "", "file:" + entry + "!/"); ClassLoader loader = new URLClassLoader(new URL[]{url}); @@ -178,13 +199,13 @@ } } catch (Throwable t) { // If something went wrong during pre-loading we just ignore it. - TTY.println("Preloading failed for (%d) %s", classFileCounter, className); + println("Preloading failed for (%d) %s", classFileCounter, className); } // Are we compiling this class? HotSpotMetaAccessProvider metaAccess = runtime.getHostProviders().getMetaAccess(); if (classFileCounter >= startAt) { - TTY.println("CompileTheWorld (%d) : %s", classFileCounter, className); + println("CompileTheWorld (%d) : %s", classFileCounter, className); // Enqueue each constructor/method in the class for compilation. for (Constructor constructor : javaClass.getDeclaredConstructors()) { @@ -201,14 +222,14 @@ } } } catch (Throwable t) { - TTY.println("CompileTheWorld (%d) : Skipping %s", classFileCounter, className); + println("CompileTheWorld (%d) : Skipping %s", classFileCounter, className); } } jarFile.close(); } - TTY.println(); - TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms)", classFileCounter, compiledMethodsCounter, compileTime); + println(); + println("CompileTheWorld : Done (%d classes, %d methods, %d ms)", classFileCounter, compiledMethodsCounter, compileTime); } /** @@ -223,7 +244,7 @@ method.reprofile(); // makes the method also not-entrant } catch (Throwable t) { // Catch everything and print a message - TTY.println("CompileTheWorld (%d) : Error compiling method: %s", classFileCounter, MetaUtil.format("%H.%n(%p):%r", method)); + println("CompileTheWorld (%d) : Error compiling method: %s", classFileCounter, MetaUtil.format("%H.%n(%p):%r", method)); t.printStackTrace(TTY.cachedOut); } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Sat Nov 30 19:05:44 2013 +0100 @@ -209,8 +209,15 @@ if (config.compileTheWorldStopAt != Integer.MAX_VALUE) { GraalOptions.CompileTheWorldStopAt.setValue(config.compileTheWorldStopAt); } - GraalOptions.HotSpotPrintCompilation.setValue(config.printCompilation); - GraalOptions.HotSpotPrintInlining.setValue(config.printInlining); + + // Only set HotSpotPrintCompilation and HotSpotPrintInlining if they still have their + // default value (false). + if (GraalOptions.HotSpotPrintCompilation.getValue() == false) { + GraalOptions.HotSpotPrintCompilation.setValue(config.printCompilation); + } + if (GraalOptions.HotSpotPrintInlining.getValue() == false) { + GraalOptions.HotSpotPrintInlining.setValue(config.printInlining); + } if (Boolean.valueOf(System.getProperty("graal.printconfig"))) { printConfig(config); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java Sat Nov 30 19:05:44 2013 +0100 @@ -28,6 +28,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.spi.*; @@ -51,24 +52,21 @@ // Install intrinsics. if (Intrinsify.getValue()) { - Debug.scope("RegisterReplacements", new Object[]{new DebugDumpScope("RegisterReplacements")}, new Runnable() { - - @Override - public void run() { - - Replacements replacements = providers.getReplacements(); - ServiceLoader sl = ServiceLoader.loadInstalled(ReplacementsProvider.class); - for (ReplacementsProvider replacementsProvider : sl) { - replacementsProvider.registerReplacements(providers.getMetaAccess(), lowerer, replacements, providers.getCodeCache().getTarget()); - } - if (BootstrapReplacements.getValue()) { - for (ResolvedJavaMethod method : replacements.getAllReplacements()) { - replacements.getMacroSubstitution(method); - replacements.getMethodSubstitution(method); - } + try (Scope s = Debug.scope("RegisterReplacements", new DebugDumpScope("RegisterReplacements"))) { + Replacements replacements = providers.getReplacements(); + ServiceLoader sl = ServiceLoader.loadInstalled(ReplacementsProvider.class); + for (ReplacementsProvider replacementsProvider : sl) { + replacementsProvider.registerReplacements(providers.getMetaAccess(), lowerer, replacements, providers.getCodeCache().getTarget()); + } + if (BootstrapReplacements.getValue()) { + for (ResolvedJavaMethod method : replacements.getAllReplacements()) { + replacements.getMacroSubstitution(method); + replacements.getMethodSubstitution(method); } } - }); + } catch (Throwable e) { + throw Debug.handle(e); + } } } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java Sat Nov 30 19:05:44 2013 +0100 @@ -40,8 +40,8 @@ private final HotSpotVMConfig config; - public HotSpotReplacementsImpl(Providers providers, HotSpotVMConfig config, Assumptions assumptions) { - super(providers, assumptions); + public HotSpotReplacementsImpl(Providers providers, HotSpotVMConfig config, Assumptions assumptions, TargetDescription target) { + super(providers, assumptions, target); this.config = config; } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Sat Nov 30 19:05:44 2013 +0100 @@ -1046,6 +1046,20 @@ @HotSpotVMField(name = "DataLayout::_cells[0]", get = HotSpotVMField.Type.OFFSET) @Stable public int dataLayoutCellsOffset; @HotSpotVMConstant(name = "DataLayout::cell_size") @Stable public int dataLayoutCellSize; + @HotSpotVMConstant(name = "DataLayout::no_tag") @Stable public int dataLayoutNoTag; + @HotSpotVMConstant(name = "DataLayout::bit_data_tag") @Stable public int dataLayoutBitDataTag; + @HotSpotVMConstant(name = "DataLayout::counter_data_tag") @Stable public int dataLayoutCounterDataTag; + @HotSpotVMConstant(name = "DataLayout::jump_data_tag") @Stable public int dataLayoutJumpDataTag; + @HotSpotVMConstant(name = "DataLayout::receiver_type_data_tag") @Stable public int dataLayoutReceiverTypeDataTag; + @HotSpotVMConstant(name = "DataLayout::virtual_call_data_tag") @Stable public int dataLayoutVirtualCallDataTag; + @HotSpotVMConstant(name = "DataLayout::ret_data_tag") @Stable public int dataLayoutRetDataTag; + @HotSpotVMConstant(name = "DataLayout::branch_data_tag") @Stable public int dataLayoutBranchDataTag; + @HotSpotVMConstant(name = "DataLayout::multi_branch_data_tag") @Stable public int dataLayoutMultiBranchDataTag; + @HotSpotVMConstant(name = "DataLayout::arg_info_data_tag") @Stable public int dataLayoutArgInfoDataTag; + @HotSpotVMConstant(name = "DataLayout::call_type_data_tag") @Stable public int dataLayoutCallTypeDataTag; + @HotSpotVMConstant(name = "DataLayout::virtual_call_type_data_tag") @Stable public int dataLayoutVirtualCallTypeDataTag; + @HotSpotVMConstant(name = "DataLayout::parameters_type_data_tag") @Stable public int dataLayoutParametersTypeDataTag; + @HotSpotVMFlag(name = "BciProfileWidth") @Stable public int bciProfileWidth; @HotSpotVMFlag(name = "TypeProfileWidth") @Stable public int typeProfileWidth; @HotSpotVMFlag(name = "MethodProfileWidth") @Stable public int methodProfileWidth; @@ -1129,6 +1143,7 @@ @HotSpotVMConstant(name = "Deoptimization::Reason_div0_check") @Stable public int deoptReasonDiv0Check; @HotSpotVMConstant(name = "Deoptimization::Reason_constraint") @Stable public int deoptReasonConstraint; @HotSpotVMConstant(name = "Deoptimization::Reason_loop_limit_check") @Stable public int deoptReasonLoopLimitCheck; + @HotSpotVMConstant(name = "Deoptimization::Reason_aliasing") @Stable public int deoptReasonAliasing; @HotSpotVMConstant(name = "Deoptimization::Action_none") @Stable public int deoptActionNone; @HotSpotVMConstant(name = "Deoptimization::Action_maybe_recompile") @Stable public int deoptActionMaybeRecompile; @@ -1142,6 +1157,11 @@ @HotSpotVMConstant(name = "vmIntrinsics::_linkToSpecial") @Stable public int vmIntrinsicLinkToSpecial; @HotSpotVMConstant(name = "vmIntrinsics::_linkToInterface") @Stable public int vmIntrinsicLinkToInterface; + @HotSpotVMConstant(name = "GraalEnv::ok") @Stable public int codeInstallResultOk; + @HotSpotVMConstant(name = "GraalEnv::dependencies_failed") @Stable public int codeInstallResultDependenciesFailed; + @HotSpotVMConstant(name = "GraalEnv::cache_full") @Stable public int codeInstallResultCacheFull; + @HotSpotVMConstant(name = "GraalEnv::code_too_large") @Stable public int codeInstallResultCodeTooLarge; + public boolean check() { for (Field f : getClass().getDeclaredFields()) { int modifiers = f.getModifiers(); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Sat Nov 30 19:05:44 2013 +0100 @@ -27,6 +27,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; @@ -132,9 +133,49 @@ Object lookupAppendixInPool(HotSpotResolvedObjectType pool, int cpi, byte opcode); - // Must be kept in sync with enum in graalEnv.hpp public enum CodeInstallResult { - OK, DEPENDENCIES_FAILED, CACHE_FULL, CODE_TOO_LARGE + OK("ok"), DEPENDENCIES_FAILED("dependencies failed"), CACHE_FULL("code cache is full"), CODE_TOO_LARGE("code is too large"); + + private int value; + private String message; + + private CodeInstallResult(String name) { + HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig(); + switch (name) { + case "ok": + this.value = config.codeInstallResultOk; + break; + case "dependencies failed": + this.value = config.codeInstallResultDependenciesFailed; + break; + case "code cache is full": + this.value = config.codeInstallResultCacheFull; + break; + case "code is too large": + this.value = config.codeInstallResultCodeTooLarge; + break; + default: + throw GraalInternalError.shouldNotReachHere("unknown enum name " + name); + } + this.message = name; + } + + /** + * Returns the enum object for the given value. + */ + public static CodeInstallResult getEnum(int value) { + for (CodeInstallResult e : values()) { + if (e.value == value) { + return e; + } + } + throw GraalInternalError.shouldNotReachHere("unknown enum value " + value); + } + + @Override + public String toString() { + return message; + } } /** @@ -203,13 +244,6 @@ String disassembleCodeBlob(long codeBlob); - /** - * Gets a copy of the machine code for a CodeBlob. - * - * @return the machine code for {@code codeBlob} if it is valid, null otherwise - */ - byte[] getCode(long codeBlob); - StackTraceElement getStackTraceElement(long metaspaceMethod, int bci); Object executeCompiledMethod(Object arg1, Object arg2, Object arg3, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException; diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Sat Nov 30 19:05:44 2013 +0100 @@ -39,7 +39,7 @@ @Override public CodeInstallResult installCode(HotSpotCompiledCode compiledCode, HotSpotInstalledCode code, SpeculationLog speculationLog) { - return CodeInstallResult.values()[installCode0(compiledCode, code, (speculationLog == null) ? null : speculationLog.getRawMap())]; + return CodeInstallResult.getEnum(installCode0(compiledCode, code, (speculationLog == null) ? null : speculationLog.getRawMap())); } @Override @@ -133,9 +133,6 @@ public synchronized native String disassembleCodeBlob(long codeBlob); @Override - public native byte[] getCode(long codeBlob); - - @Override public native StackTraceElement getStackTraceElement(long metaspaceMethod, int bci); @Override diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Sat Nov 30 19:05:44 2013 +0100 @@ -520,6 +520,8 @@ boxingSnippets.lower((BoxNode) n, tool); } else if (n instanceof UnboxNode) { boxingSnippets.lower((UnboxNode) n, tool); + } else if (n instanceof DeoptimizeNode || n instanceof UnwindNode) { + /* No lowering, we generate LIR directly for these nodes. */ } else { assert false : "Node implementing Lowerable not handled: " + n; throw GraalInternalError.shouldNotReachHere(); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Sat Nov 30 19:05:44 2013 +0100 @@ -187,6 +187,8 @@ return runtime.getConfig().deoptReasonConstraint; case LoopLimitCheck: return runtime.getConfig().deoptReasonLoopLimitCheck; + case Aliasing: + return runtime.getConfig().deoptReasonAliasing; default: throw GraalInternalError.shouldNotReachHere(); } @@ -221,6 +223,8 @@ return DeoptimizationReason.RuntimeConstraint; } else if (reason == runtime.getConfig().deoptReasonLoopLimitCheck) { return DeoptimizationReason.LoopLimitCheck; + } else if (reason == runtime.getConfig().deoptReasonAliasing) { + return DeoptimizationReason.Aliasing; } else { throw GraalInternalError.shouldNotReachHere(Integer.toHexString(reason)); } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Sat Nov 30 19:05:44 2013 +0100 @@ -24,6 +24,7 @@ import static com.oracle.graal.graph.UnsafeAccess.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +import static java.lang.String.*; import java.util.*; @@ -45,8 +46,20 @@ private static final HotSpotMethodDataAccessor NO_DATA_EXCEPTION_POSSIBLY_NOT_RECORDED_ACCESSOR = new NoMethodData(TriState.UNKNOWN); // sorted by tag - private static final HotSpotMethodDataAccessor[] PROFILE_DATA_ACCESSORS = {null, new BitData(), new CounterData(), new JumpData(), new TypeCheckData(), new VirtualCallData(), new RetData(), - new BranchData(), new MultiBranchData(), new ArgInfoData()}; + // @formatter:off + private static final HotSpotMethodDataAccessor[] PROFILE_DATA_ACCESSORS = { + null, + new BitData(), + new CounterData(), + new JumpData(), + new TypeCheckData(), + new VirtualCallData(), + new RetData(), + new BranchData(), + new MultiBranchData(), + new ArgInfoData() + }; + // @formatter:on /** * Reference to the C++ MethodData object. @@ -96,7 +109,11 @@ if (position >= normalDataSize + extraDataSize) { return null; } - return getData(position); + HotSpotMethodDataAccessor data = getData(position); + if (data != null) { + return data; + } + return data; } public static HotSpotMethodDataAccessor getNoDataAccessor(boolean exceptionPossiblyNotRecorded) { @@ -170,10 +187,46 @@ return cells * config.dataLayoutCellSize; } + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + String nl = String.format("%n"); + String nlIndent = String.format("%n%38s", ""); + if (hasNormalData()) { + int pos = 0; + HotSpotMethodDataAccessor data; + while ((data = getNormalData(pos)) != null) { + if (pos != 0) { + sb.append(nl); + } + int bci = data.getBCI(this, pos); + sb.append(String.format("%-6d bci: %-6d%-20s", pos, bci, data.getClass().getSimpleName())); + sb.append(data.appendTo(new StringBuilder(), this, pos).toString().replace(nl, nlIndent)); + pos = pos + data.getSize(this, pos); + } + } + + if (hasExtraData()) { + int pos = getExtraDataBeginOffset(); + HotSpotMethodDataAccessor data; + while ((data = getExtraData(pos)) != null) { + if (pos == getExtraDataBeginOffset()) { + sb.append(nl).append("--- Extra data:"); + } + int bci = data.getBCI(this, pos); + sb.append(String.format("%n%-6d bci: %-6d%-20s", pos, bci, data.getClass().getSimpleName())); + sb.append(data.appendTo(new StringBuilder(), this, pos).toString().replace(nl, nlIndent)); + pos = pos + data.getSize(this, pos); + } + + } + return sb.toString(); + } + private abstract static class AbstractMethodData implements HotSpotMethodDataAccessor { /** - * Corresponds to DS_RECOMPILE_BIT defined in deoptimization.cpp. + * Corresponds to {@code exception_seen_flag}. */ private static final int EXCEPTIONS_MASK = 0x2; @@ -245,17 +298,18 @@ protected int getDynamicSize(@SuppressWarnings("unused") HotSpotMethodData data, @SuppressWarnings("unused") int position) { return 0; } + + public abstract StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos); } private static class NoMethodData extends AbstractMethodData { - private static final int NO_DATA_TAG = 0; private static final int NO_DATA_SIZE = cellIndexToOffset(0); private final TriState exceptionSeen; protected NoMethodData(TriState exceptionSeen) { - super(NO_DATA_TAG, NO_DATA_SIZE); + super(runtime().getConfig().dataLayoutNoTag, NO_DATA_SIZE); this.exceptionSeen = exceptionSeen; } @@ -268,16 +322,20 @@ public TriState getExceptionSeen(HotSpotMethodData data, int position) { return exceptionSeen; } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + return sb; + } } private static class BitData extends AbstractMethodData { - private static final int BIT_DATA_TAG = 1; private static final int BIT_DATA_SIZE = cellIndexToOffset(0); private static final int BIT_DATA_NULL_SEEN_FLAG = 0x01; private BitData() { - super(BIT_DATA_TAG, BIT_DATA_SIZE); + super(runtime().getConfig().dataLayoutBitDataTag, BIT_DATA_SIZE); } protected BitData(int tag, int staticSize) { @@ -288,16 +346,20 @@ public TriState getNullSeen(HotSpotMethodData data, int position) { return TriState.get((getFlags(data, position) & BIT_DATA_NULL_SEEN_FLAG) != 0); } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + return sb.append(format("exception_seen(%s)", getExceptionSeen(data, pos))); + } } private static class CounterData extends BitData { - private static final int COUNTER_DATA_TAG = 2; private static final int COUNTER_DATA_SIZE = cellIndexToOffset(1); private static final int COUNTER_DATA_COUNT_OFFSET = cellIndexToOffset(0); public CounterData() { - super(COUNTER_DATA_TAG, COUNTER_DATA_SIZE); + super(runtime().getConfig().dataLayoutCounterDataTag, COUNTER_DATA_SIZE); } protected CounterData(int tag, int staticSize) { @@ -312,17 +374,21 @@ protected int getCounterValue(HotSpotMethodData data, int position) { return data.readUnsignedIntAsSignedInt(position, COUNTER_DATA_COUNT_OFFSET); } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + return sb.append(format("count(%d)", getCounterValue(data, pos))); + } } private static class JumpData extends AbstractMethodData { - private static final int JUMP_DATA_TAG = 3; private static final int JUMP_DATA_SIZE = cellIndexToOffset(2); protected static final int TAKEN_COUNT_OFFSET = cellIndexToOffset(0); protected static final int TAKEN_DISPLACEMENT_OFFSET = cellIndexToOffset(1); public JumpData() { - super(JUMP_DATA_TAG, JUMP_DATA_SIZE); + super(runtime().getConfig().dataLayoutJumpDataTag, JUMP_DATA_SIZE); } protected JumpData(int tag, int staticSize) { @@ -339,10 +405,28 @@ return data.readUnsignedIntAsSignedInt(position, TAKEN_COUNT_OFFSET); } - @SuppressWarnings("unused") public int getTakenDisplacement(HotSpotMethodData data, int position) { return data.readInt(position, TAKEN_DISPLACEMENT_OFFSET); } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + return sb.append(format("taken(%d) displacement(%d)", getExecutionCount(data, pos), getTakenDisplacement(data, pos))); + } + } + + static class RawItemProfile { + final int entries; + final T[] items; + final long[] counts; + final long totalCount; + + public RawItemProfile(int entries, T[] items, long[] counts, long totalCount) { + this.entries = entries; + this.items = items; + this.counts = counts; + this.totalCount = totalCount; + } } private abstract static class AbstractTypeData extends CounterData { @@ -359,6 +443,10 @@ @Override public JavaTypeProfile getTypeProfile(HotSpotMethodData data, int position) { + return createTypeProfile(getNullSeen(data, position), getRawTypeProfile(data, position)); + } + + private RawItemProfile getRawTypeProfile(HotSpotMethodData data, int position) { int typeProfileWidth = config.typeProfileWidth; ResolvedJavaType[] types = new ResolvedJavaType[typeProfileWidth]; @@ -373,35 +461,34 @@ long count = data.readUnsignedInt(position, getTypeCountOffset(i)); totalCount += count; counts[entries] = count; - entries++; } } totalCount += getTypesNotRecordedExecutionCount(data, position); - return createTypeProfile(getNullSeen(data, position), types, counts, totalCount, entries); + return new RawItemProfile<>(entries, types, counts, totalCount); } protected abstract long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position); - private static JavaTypeProfile createTypeProfile(TriState nullSeen, ResolvedJavaType[] types, long[] counts, long totalCount, int entries) { - if (entries <= 0 || totalCount <= 0) { + private static JavaTypeProfile createTypeProfile(TriState nullSeen, RawItemProfile profile) { + if (profile.entries <= 0 || profile.totalCount <= 0) { return null; } - ProfiledType[] ptypes = new ProfiledType[entries]; + ProfiledType[] ptypes = new ProfiledType[profile.entries]; double totalProbability = 0.0; - for (int i = 0; i < entries; i++) { - double p = counts[i]; - p = p / totalCount; + for (int i = 0; i < profile.entries; i++) { + double p = profile.counts[i]; + p = p / profile.totalCount; totalProbability += p; - ptypes[i] = new ProfiledType(types[i], p); + ptypes[i] = new ProfiledType(profile.items[i], p); } Arrays.sort(ptypes); - double notRecordedTypeProbability = entries < config.typeProfileWidth ? 0.0 : Math.min(1.0, Math.max(0.0, 1.0 - totalProbability)); - assert notRecordedTypeProbability == 0 || entries == config.typeProfileWidth; + double notRecordedTypeProbability = profile.entries < config.typeProfileWidth ? 0.0 : Math.min(1.0, Math.max(0.0, 1.0 - totalProbability)); + assert notRecordedTypeProbability == 0 || profile.entries == config.typeProfileWidth; return new JavaTypeProfile(nullSeen, notRecordedTypeProbability, ptypes); } @@ -412,15 +499,26 @@ protected static int getTypeCountOffset(int row) { return TYPE_DATA_FIRST_TYPE_COUNT_OFFSET + row * TYPE_DATA_ROW_SIZE; } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + RawItemProfile profile = getRawTypeProfile(data, pos); + TriState nullSeen = getNullSeen(data, pos); + sb.append(format("count(%d) null_seen(%s) nonprofiled_count(%d) entries(%d)", getCounterValue(data, pos), nullSeen, getTypesNotRecordedExecutionCount(data, pos), profile.entries)); + for (int i = 0; i < profile.entries; i++) { + long count = profile.counts[i]; + sb.append(format("%n %s (%d, %4.2f)", MetaUtil.toJavaName(profile.items[i]), count, (double) count / profile.totalCount)); + } + return sb; + } } private static class TypeCheckData extends AbstractTypeData { - private static final int TYPE_CHECK_DATA_TAG = 4; private static final int TYPE_CHECK_DATA_SIZE = cellIndexToOffset(2) + TYPE_DATA_ROW_SIZE * config.typeProfileWidth; public TypeCheckData() { - super(TYPE_CHECK_DATA_TAG, TYPE_CHECK_DATA_SIZE); + super(runtime().getConfig().dataLayoutReceiverTypeDataTag, TYPE_CHECK_DATA_SIZE); } @Override @@ -436,13 +534,12 @@ private static class VirtualCallData extends AbstractTypeData { - private static final int VIRTUAL_CALL_DATA_TAG = 5; private static final int VIRTUAL_CALL_DATA_SIZE = cellIndexToOffset(2) + TYPE_DATA_ROW_SIZE * (config.typeProfileWidth + config.methodProfileWidth); private static final int VIRTUAL_CALL_DATA_FIRST_METHOD_OFFSET = TYPE_DATA_FIRST_TYPE_OFFSET + TYPE_DATA_ROW_SIZE * config.typeProfileWidth; private static final int VIRTUAL_CALL_DATA_FIRST_METHOD_COUNT_OFFSET = TYPE_DATA_FIRST_TYPE_COUNT_OFFSET + TYPE_DATA_ROW_SIZE * config.typeProfileWidth; public VirtualCallData() { - super(VIRTUAL_CALL_DATA_TAG, VIRTUAL_CALL_DATA_SIZE); + super(runtime().getConfig().dataLayoutVirtualCallDataTag, VIRTUAL_CALL_DATA_SIZE); } @Override @@ -469,6 +566,10 @@ @Override public JavaMethodProfile getMethodProfile(HotSpotMethodData data, int position) { + return createMethodProfile(getRawMethodProfile(data, position)); + } + + private static RawItemProfile getRawMethodProfile(HotSpotMethodData data, int position) { int profileWidth = config.methodProfileWidth; ResolvedJavaMethod[] methods = new ResolvedJavaMethod[profileWidth]; @@ -489,27 +590,27 @@ } totalCount += getMethodsNotRecordedExecutionCount(data, position); - return createMethodProfile(methods, counts, totalCount, entries); + return new RawItemProfile<>(entries, methods, counts, totalCount); } - private static JavaMethodProfile createMethodProfile(ResolvedJavaMethod[] methods, long[] counts, long totalCount, int entries) { - if (entries <= 0 || totalCount <= 0) { + private static JavaMethodProfile createMethodProfile(RawItemProfile profile) { + if (profile.entries <= 0 || profile.totalCount <= 0) { return null; } - ProfiledMethod[] pmethods = new ProfiledMethod[entries]; + ProfiledMethod[] pmethods = new ProfiledMethod[profile.entries]; double totalProbability = 0.0; - for (int i = 0; i < entries; i++) { - double p = counts[i]; - p = p / totalCount; + for (int i = 0; i < profile.entries; i++) { + double p = profile.counts[i]; + p = p / profile.totalCount; totalProbability += p; - pmethods[i] = new ProfiledMethod(methods[i], p); + pmethods[i] = new ProfiledMethod(profile.items[i], p); } Arrays.sort(pmethods); - double notRecordedMethodProbability = entries < config.methodProfileWidth ? 0.0 : Math.min(1.0, Math.max(0.0, 1.0 - totalProbability)); - assert notRecordedMethodProbability == 0 || entries == config.methodProfileWidth; + double notRecordedMethodProbability = profile.entries < config.methodProfileWidth ? 0.0 : Math.min(1.0, Math.max(0.0, 1.0 - totalProbability)); + assert notRecordedMethodProbability == 0 || profile.entries == config.methodProfileWidth; return new JavaMethodProfile(notRecordedMethodProbability, pmethods); } @@ -520,27 +621,36 @@ private static int getMethodCountOffset(int row) { return VIRTUAL_CALL_DATA_FIRST_METHOD_COUNT_OFFSET + row * TYPE_DATA_ROW_SIZE; } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + RawItemProfile profile = getRawMethodProfile(data, pos); + super.appendTo(sb.append(format("exception_seen(%s) ", getExceptionSeen(data, pos))), data, pos).append(format("%nmethod_entries(%d)", profile.entries)); + for (int i = 0; i < profile.entries; i++) { + long count = profile.counts[i]; + sb.append(format("%n %s (%d, %4.2f)", MetaUtil.format("%H.%n(%p)", profile.items[i]), count, (double) count / profile.totalCount)); + } + return sb; + } } private static class RetData extends CounterData { - private static final int RET_DATA_TAG = 6; private static final int RET_DATA_ROW_SIZE = cellsToBytes(3); private static final int RET_DATA_SIZE = cellIndexToOffset(1) + RET_DATA_ROW_SIZE * config.bciProfileWidth; public RetData() { - super(RET_DATA_TAG, RET_DATA_SIZE); + super(runtime().getConfig().dataLayoutRetDataTag, RET_DATA_SIZE); } } private static class BranchData extends JumpData { - private static final int BRANCH_DATA_TAG = 7; private static final int BRANCH_DATA_SIZE = cellIndexToOffset(3); private static final int NOT_TAKEN_COUNT_OFFSET = cellIndexToOffset(2); public BranchData() { - super(BRANCH_DATA_TAG, BRANCH_DATA_SIZE); + super(runtime().getConfig().dataLayoutBranchDataTag, BRANCH_DATA_SIZE); } @Override @@ -557,6 +667,14 @@ long count = data.readUnsignedInt(position, TAKEN_COUNT_OFFSET) + data.readUnsignedInt(position, NOT_TAKEN_COUNT_OFFSET); return truncateLongToInt(count); } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + long taken = data.readUnsignedInt(pos, TAKEN_COUNT_OFFSET); + long notTaken = data.readUnsignedInt(pos, NOT_TAKEN_COUNT_OFFSET); + double takenProbability = getBranchTakenProbability(data, pos); + return sb.append(format("taken(%d, %4.2f) not_taken(%d, %4.2f) displacement(%d)", taken, takenProbability, notTaken, 1.0D - takenProbability, getTakenDisplacement(data, pos))); + } } private static class ArrayData extends AbstractMethodData { @@ -576,11 +694,15 @@ protected static int getLength(HotSpotMethodData data, int position) { return data.readInt(position, ARRAY_DATA_LENGTH_OFFSET); } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + return sb.append(format("length(%d)", getLength(data, pos))); + } } private static class MultiBranchData extends ArrayData { - private static final int MULTI_BRANCH_DATA_TAG = 8; private static final int MULTI_BRANCH_DATA_SIZE = cellIndexToOffset(1); private static final int MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS = 2; private static final int MULTI_BRANCH_DATA_ROW_SIZE = cellsToBytes(MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS); @@ -588,7 +710,7 @@ private static final int MULTI_BRANCH_DATA_FIRST_DISPLACEMENT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(1); public MultiBranchData() { - super(MULTI_BRANCH_DATA_TAG, MULTI_BRANCH_DATA_SIZE); + super(runtime().getConfig().dataLayoutMultiBranchDataTag, MULTI_BRANCH_DATA_SIZE); } @Override @@ -650,19 +772,27 @@ return MULTI_BRANCH_DATA_FIRST_COUNT_OFFSET + index * MULTI_BRANCH_DATA_ROW_SIZE; } - @SuppressWarnings("unused") private static int getDisplacementOffset(int index) { return MULTI_BRANCH_DATA_FIRST_DISPLACEMENT_OFFSET + index * MULTI_BRANCH_DATA_ROW_SIZE; } + + @Override + public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) { + int entries = getLength(data, pos) / MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS; + sb.append(format("entries(%d)", entries)); + for (int i = 0; i < entries; i++) { + sb.append(format("%n %d: count(%d) displacement(%d)", i, data.readUnsignedInt(pos, getCountOffset(i)), data.readUnsignedInt(pos, getDisplacementOffset(i)))); + } + return sb; + } } private static class ArgInfoData extends ArrayData { - private static final int ARG_INFO_DATA_TAG = 9; private static final int ARG_INFO_DATA_SIZE = cellIndexToOffset(1); public ArgInfoData() { - super(ARG_INFO_DATA_TAG, ARG_INFO_DATA_SIZE); + super(runtime().getConfig().dataLayoutArgInfoDataTag, ARG_INFO_DATA_SIZE); } } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodDataAccessor.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodDataAccessor.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodDataAccessor.java Sat Nov 30 19:05:44 2013 +0100 @@ -66,4 +66,6 @@ TriState getNullSeen(HotSpotMethodData data, int position); int getExecutionCount(HotSpotMethodData data, int position); + + StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos); } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Sat Nov 30 19:05:44 2013 +0100 @@ -34,6 +34,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ProfilingInfo.TriState; +import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.debug.*; @@ -282,6 +283,8 @@ return getCompiledCodeSize() > 0; } + private static final String TraceMethodDataFilter = System.getProperty("graal.traceMethodDataFilter"); + @Override public ProfilingInfo getProfilingInfo() { ProfilingInfo info; @@ -290,6 +293,10 @@ long metaspaceMethodData = unsafeReadWord(metaspaceMethod + runtime().getConfig().methodDataOffset); if (metaspaceMethodData != 0) { methodData = new HotSpotMethodData(metaspaceMethodData); + if (TraceMethodDataFilter != null && MetaUtil.format("%H.%n", this).contains(TraceMethodDataFilter)) { + TTY.println("Raw method data for " + MetaUtil.format("%H.%n(%p)", this) + ":"); + TTY.println(methodData.toString()); + } } } @@ -364,6 +371,15 @@ return false; } + public boolean isDefault() { + if (isConstructor()) { + return false; + } + // Copied from java.lang.Method.isDefault() + int mask = Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC; + return ((getModifiers() & mask) == Modifier.PUBLIC) && getDeclaringClass().isInterface(); + } + @Override public Type[] getGenericParameterTypes() { if (isConstructor()) { diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/BeginLockScopeNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -37,7 +37,7 @@ * is locked (ensuring the GC sees and updates the object) so it must come after any null pointer * check on the object. */ -public final class BeginLockScopeNode extends AbstractStateSplit implements LIRGenLowerable, MonitorEnter, MemoryCheckpoint.Single { +public final class BeginLockScopeNode extends AbstractMemoryCheckpoint implements LIRGenLowerable, MonitorEnter, MemoryCheckpoint.Single { private int lockDepth; diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -95,4 +95,12 @@ */ @NodeIntrinsic public static native Word compareAndSwap(Object object, long offset, Word expectedValue, Word newValue, @ConstantNodeParameter LocationIdentity locationIdentity); + + public MemoryCheckpoint asMemoryCheckpoint() { + return this; + } + + public MemoryPhiNode asMemoryPhi() { + return null; + } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EndLockScopeNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -33,7 +33,7 @@ * Intrinsic for closing a {@linkplain BeginLockScopeNode scope} binding a stack-based lock with an * object. */ -public final class EndLockScopeNode extends AbstractStateSplit implements LIRGenLowerable, MonitorExit, MemoryCheckpoint.Single { +public final class EndLockScopeNode extends AbstractMemoryCheckpoint implements LIRGenLowerable, MonitorExit, MemoryCheckpoint.Single { public EndLockScopeNode() { super(StampFactory.forVoid()); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -83,4 +83,12 @@ } return super.toString(verbosity); } + + public MemoryCheckpoint asMemoryCheckpoint() { + return this; + } + + public MemoryPhiNode asMemoryPhi() { + return null; + } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -24,10 +24,9 @@ import static com.oracle.graal.compiler.GraalCompiler.*; -import java.util.concurrent.*; - import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.loop.phases.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -76,14 +75,11 @@ } Kind componentKind = srcType.getComponentType().getKind(); final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(ArrayCopySnippets.getSnippetForKind(componentKind)); - return Debug.scope("ArrayCopySnippet", snippetMethod, new Callable() { - - @Override - public StructuredGraph call() throws Exception { - return replacements.getSnippet(snippetMethod); - } - }); - + try (Scope s = Debug.scope("ArrayCopySnippet", snippetMethod)) { + return replacements.getSnippet(snippetMethod); + } catch (Throwable e) { + throw Debug.handle(e); + } } private static void unrollFixedLengthLoop(StructuredGraph snippetGraph, int length, LoweringTool tool) { @@ -93,8 +89,7 @@ } // the canonicalization before loop unrolling is needed to propagate the length into // additions, etc. - PhaseContext context = new PhaseContext(tool.getMetaAccess(), tool.getCodeCache(), tool.getConstantReflection(), tool.getForeignCalls(), tool.getLowerer(), tool.assumptions(), - tool.getReplacements()); + PhaseContext context = new PhaseContext(tool.getMetaAccess(), tool.getConstantReflection(), tool.getLowerer(), tool.getReplacements(), tool.assumptions()); new CanonicalizerPhase(true).apply(snippetGraph, context); new LoopFullUnrollPhase(new CanonicalizerPhase(true)).apply(snippetGraph, context); new CanonicalizerPhase(true).apply(snippetGraph, context); @@ -110,26 +105,23 @@ StructuredGraph snippetGraph = selectSnippet(tool, replacements); if (snippetGraph == null) { final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(ArrayCopySnippets.genericArraycopySnippet); - snippetGraph = Debug.scope("ArrayCopySnippet", snippetMethod, new Callable() { - - @Override - public StructuredGraph call() throws Exception { - return replacements.getSnippet(snippetMethod).copy(); - } - }); + snippetGraph = null; + try (Scope s = Debug.scope("ArrayCopySnippet", snippetMethod)) { + snippetGraph = replacements.getSnippet(snippetMethod).copy(); + } catch (Throwable e) { + throw Debug.handle(e); + } replaceSnippetInvokes(snippetGraph); } else { assert snippetGraph != null : "ArrayCopySnippets should be installed"; snippetGraph = snippetGraph.copy(); if (getLength().isConstant() && getLength().asConstant().asInt() <= GraalOptions.MaximumEscapeAnalysisArrayLength.getValue()) { final StructuredGraph copy = snippetGraph; - Debug.scope("ArrayCopySnippetSpecialization", snippetGraph.method(), new Runnable() { - - @Override - public void run() { - unrollFixedLengthLoop(copy, getLength().asConstant().asInt(), tool); - } - }); + try (Scope s = Debug.scope("ArrayCopySnippetSpecialization", snippetGraph.method())) { + unrollFixedLengthLoop(copy, getLength().asConstant().asInt(), tool); + } catch (Throwable e) { + throw Debug.handle(e); + } } } return lowerReplacement(snippetGraph, tool); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java Sat Nov 30 19:05:44 2013 +0100 @@ -69,7 +69,7 @@ return AESCryptSubstitutions.AESCryptClass; } - @MethodSubstitution(isStatic = false) + @MethodSubstitution(isStatic = false, optional = true) static void encrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { Object embeddedCipher = UnsafeLoadNode.load(rcvr, embeddedCipherOffset, Kind.Object, embeddedCipherLocationIdentity); if (getAESCryptClass().isInstance(embeddedCipher)) { @@ -79,7 +79,7 @@ } } - @MethodSubstitution(isStatic = false) + @MethodSubstitution(isStatic = false, optional = true) static void decrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { Object embeddedCipher = UnsafeLoadNode.load(rcvr, embeddedCipherOffset, Kind.Object, embeddedCipherLocationIdentity); if (in != out && getAESCryptClass().isInstance(embeddedCipher)) { @@ -89,6 +89,28 @@ } } + @MethodSubstitution(value = "encrypt", isStatic = false, optional = true) + static int encryptInt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { + Object embeddedCipher = UnsafeLoadNode.load(rcvr, embeddedCipherOffset, Kind.Object, embeddedCipherLocationIdentity); + if (getAESCryptClass().isInstance(embeddedCipher)) { + crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, true); + return inLength; + } else { + return encryptInt(rcvr, in, inOffset, inLength, out, outOffset); + } + } + + @MethodSubstitution(value = "decrypt", isStatic = false, optional = true) + static int decryptInt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { + Object embeddedCipher = UnsafeLoadNode.load(rcvr, embeddedCipherOffset, Kind.Object, embeddedCipherLocationIdentity); + if (in != out && getAESCryptClass().isInstance(embeddedCipher)) { + crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, false); + return inLength; + } else { + return decryptInt(rcvr, in, inOffset, inLength, out, outOffset); + } + } + private static void crypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset, Object embeddedCipher, boolean encrypt) { Object kObject = UnsafeLoadNode.load(embeddedCipher, AESCryptSubstitutions.kOffset, Kind.Object, AESCryptSubstitutions.kLocationIdentity); Object rObject = UnsafeLoadNode.load(rcvr, rOffset, Kind.Object, rLocationIdentity); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Sat Nov 30 19:05:44 2013 +0100 @@ -246,12 +246,12 @@ new_seqInit.inc(); explodeLoop(); for (int offset = instanceHeaderSize(); offset < size; offset += wordSize()) { - memory.writeWord(offset, Word.zero(), INIT_LOCATION); + memory.initializeWord(offset, Word.zero(), INIT_LOCATION); } } else { new_loopInit.inc(); for (int offset = instanceHeaderSize(); offset < size; offset += wordSize()) { - memory.writeWord(offset, Word.zero(), INIT_LOCATION); + memory.initializeWord(offset, Word.zero(), INIT_LOCATION); } } } @@ -270,7 +270,7 @@ initializeObjectHeader(memory, prototypeMarkWord, hub); if (fillContents) { for (int offset = headerSize; offset < allocationSize; offset += wordSize()) { - memory.writeWord(offset, Word.zero(), INIT_LOCATION); + memory.initializeWord(offset, Word.zero(), INIT_LOCATION); } } return memory.toObject(); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -25,11 +25,11 @@ import static com.oracle.graal.compiler.GraalCompiler.*; import java.lang.reflect.*; -import java.util.concurrent.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; @@ -65,13 +65,12 @@ if (method != null) { final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(method); final Replacements replacements = tool.getReplacements(); - StructuredGraph snippetGraph = Debug.scope("ArrayCopySnippet", snippetMethod, new Callable() { - - @Override - public StructuredGraph call() throws Exception { - return replacements.getSnippet(snippetMethod); - } - }); + StructuredGraph snippetGraph = null; + try (Scope s = Debug.scope("ArrayCopySnippet", snippetMethod)) { + snippetGraph = replacements.getSnippet(snippetMethod); + } catch (Throwable e) { + throw Debug.handle(e); + } assert snippetGraph != null : "ObjectCloneSnippets should be installed"; return lowerReplacement(snippetGraph.copy(), tool); @@ -80,7 +79,7 @@ type = getConcreteType(getObject().stamp(), tool.assumptions(), tool.getMetaAccess()); if (type != null) { StructuredGraph newGraph = new StructuredGraph(); - LocalNode local = newGraph.add(new LocalNode(0, getObject().stamp())); + LocalNode local = newGraph.unique(new LocalNode(0, getObject().stamp())); NewInstanceNode newInstance = newGraph.add(new NewInstanceNode(type, true)); newGraph.addAfterFixed(newGraph.start(), newInstance); ReturnNode returnNode = newGraph.add(new ReturnNode(newInstance)); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java Sat Nov 30 19:05:44 2013 +0100 @@ -30,7 +30,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.replacements.*; @@ -122,7 +121,7 @@ } } - static Hints createHints(TypeCheckHints hints, MetaAccessProvider metaAccess, boolean positiveOnly, Graph graph) { + static Hints createHints(TypeCheckHints hints, MetaAccessProvider metaAccess, boolean positiveOnly, StructuredGraph graph) { ConstantNode[] hubs = new ConstantNode[hints.hints.length]; boolean[] isPositive = new boolean[hints.hints.length]; int index = 0; diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Sat Nov 30 19:05:44 2013 +0100 @@ -317,7 +317,7 @@ private void inline(InvokeNode invoke) { ResolvedJavaMethod method = ((MethodCallTargetNode) invoke.callTarget()).targetMethod(); - ReplacementsImpl repl = new ReplacementsImpl(providers, new Assumptions(false)); + ReplacementsImpl repl = new ReplacementsImpl(providers, new Assumptions(false), providers.getCodeCache().getTarget()); StructuredGraph calleeGraph = repl.makeGraph(method, null, null, false); InliningUtil.inline(invoke, calleeGraph, false); } diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Sat Nov 30 19:05:44 2013 +0100 @@ -25,13 +25,13 @@ import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import java.util.*; -import java.util.concurrent.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.debug.internal.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; @@ -135,53 +135,47 @@ */ public synchronized InstalledCode getCode(final Backend backend) { if (code == null) { - Debug.sandbox("CompilingStub", new Object[]{providers.getCodeCache(), debugScopeContext()}, DebugScope.getConfig(), new Runnable() { - - @Override - public void run() { + try (Scope d = Debug.sandbox("CompilingStub", DebugScope.getConfig(), providers.getCodeCache(), debugScopeContext())) { + final StructuredGraph graph = getGraph(); + if (!(graph.start() instanceof StubStartNode)) { + StubStartNode newStart = graph.add(new StubStartNode(Stub.this)); + newStart.setStateAfter(graph.start().stateAfter()); + graph.replaceFixed(graph.start(), newStart); + } - final StructuredGraph graph = getGraph(); - if (!(graph.start() instanceof StubStartNode)) { - StubStartNode newStart = graph.add(new StubStartNode(Stub.this)); - newStart.setStateAfter(graph.start().stateAfter()); - graph.replaceFixed(graph.start(), newStart); - } - - PhasePlan phasePlan = new PhasePlan(); - ForeignCallsProvider foreignCalls = providers.getForeignCalls(); - MetaAccessProvider metaAccess = providers.getMetaAccess(); - CodeCacheProvider codeCache = providers.getCodeCache(); - GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); - phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); - // The stub itself needs the incoming calling convention. - CallingConvention incomingCc = linkage.getIncomingCallingConvention(); - final CompilationResult compResult = GraalCompiler.compileGraph(graph, incomingCc, getInstalledCodeOwner(), providers, backend, codeCache.getTarget(), null, phasePlan, - OptimisticOptimizations.ALL, new SpeculationLog(), providers.getSuites().getDefaultSuites(), new CompilationResult()); + PhasePlan phasePlan = new PhasePlan(); + ForeignCallsProvider foreignCalls = providers.getForeignCalls(); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + CodeCacheProvider codeCache = providers.getCodeCache(); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); + phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); + // The stub itself needs the incoming calling convention. + CallingConvention incomingCc = linkage.getIncomingCallingConvention(); + final CompilationResult compResult = GraalCompiler.compileGraph(graph, incomingCc, getInstalledCodeOwner(), providers, backend, codeCache.getTarget(), null, phasePlan, + OptimisticOptimizations.ALL, new SpeculationLog(), providers.getSuites().getDefaultSuites(), new CompilationResult()); - assert destroyedRegisters != null; - code = Debug.scope("CodeInstall", new Callable() { - - @Override - public InstalledCode call() { - Stub stub = Stub.this; - HotSpotRuntimeStub installedCode = new HotSpotRuntimeStub(stub); - HotSpotCompiledCode hsCompResult = new HotSpotCompiledRuntimeStub(stub, compResult); - CodeInstallResult result = runtime().getCompilerToVM().installCode(hsCompResult, installedCode, null); - if (result != CodeInstallResult.OK) { - throw new GraalInternalError("Error installing stub %s: %s", Stub.this, result); - } - if (Debug.isDumpEnabled()) { - Debug.dump(new Object[]{compResult, installedCode}, "After code installation"); - } - if (Debug.isLogEnabled()) { - Debug.log("%s", providers.getDisassembler().disassemble(installedCode)); - } - return installedCode; - } - }); - + assert destroyedRegisters != null; + try (Scope s = Debug.scope("CodeInstall")) { + Stub stub = Stub.this; + HotSpotRuntimeStub installedCode = new HotSpotRuntimeStub(stub); + HotSpotCompiledCode hsCompResult = new HotSpotCompiledRuntimeStub(stub, compResult); + CodeInstallResult result = runtime().getCompilerToVM().installCode(hsCompResult, installedCode, null); + if (result != CodeInstallResult.OK) { + throw new GraalInternalError("Error installing stub %s: %s", Stub.this, result); + } + if (Debug.isDumpEnabled()) { + Debug.dump(new Object[]{compResult, installedCode}, "After code installation"); + } + if (Debug.isLogEnabled()) { + Debug.log("%s", providers.getDisassembler().disassemble(installedCode)); + } + code = installedCode; + } catch (Throwable e) { + throw Debug.handle(e); } - }); + } catch (Throwable e) { + throw Debug.handle(e); + } assert code != null : "error installing stub " + this; } return code; diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Sat Nov 30 19:05:44 2013 +0100 @@ -31,6 +31,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.bytecode.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.nodes.*; /** @@ -210,13 +211,11 @@ this.log("Before LivenessAnalysis"); } if (OptLivenessAnalysis.getValue()) { - Debug.scope("LivenessAnalysis", new Runnable() { - - @Override - public void run() { - computeLiveness(); - } - }); + try (Scope s = Debug.scope("LivenessAnalysis")) { + computeLiveness(); + } catch (Throwable e) { + throw Debug.handle(e); + } } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Sat Nov 30 19:05:44 2013 +0100 @@ -438,7 +438,7 @@ } } - private void storeStack(int i, ValueNode x) { + public void storeStack(int i, ValueNode x) { assert x == null || x.isAlive() && (stack[i] == null || x.kind() == stack[i].kind()) : "Method does not handle changes from one-slot to two-slot values or non-alive values"; stack[i] = x; } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Sat Nov 30 19:05:44 2013 +0100 @@ -159,6 +159,10 @@ return currentGraph; } + protected ResolvedJavaMethod getMethod() { + return method; + } + public GraphBuilderPhase(MetaAccessProvider metaAccess, ForeignCallsProvider foreignCalls, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) { this.graphBuilderConfig = graphBuilderConfig; this.optimisticOpts = optimisticOpts; @@ -207,12 +211,14 @@ return map; } - private void build() { + protected void build() { if (PrintProfilingInformation.getValue()) { - TTY.println("Profiling info for " + method); + TTY.println("Profiling info for " + MetaUtil.format("%H.%n(%p)", method)); TTY.println(MetaUtil.indent(MetaUtil.profileToString(profilingInfo, method, CodeUtil.NEW_LINE), " ")); } + Indent indent = Debug.logAndIndent(false, "build graph for %s", method.toString()); + // compute the block map, setup exception handlers and get the entrypoint(s) BciBlockMapping blockMap = createBlockMap(); loopHeaders = blockMap.loopHeaders; @@ -271,6 +277,7 @@ n.safeDelete(); } } + indent.outdent(); } private Block unwindBlock(int bci) { @@ -864,12 +871,16 @@ void genNewInstance(int cpi) { JavaType type = lookupType(cpi, NEW); if (type instanceof ResolvedJavaType && ((ResolvedJavaType) type).isInitialized()) { - frameState.apush(append(new NewInstanceNode((ResolvedJavaType) type, true))); + frameState.apush(append(createNewInstance((ResolvedJavaType) type, true))); } else { handleUnresolvedNewInstance(type); } } + protected NewInstanceNode createNewInstance(ResolvedJavaType type, boolean fillContents) { + return new NewInstanceNode(type, fillContents); + } + /** * Gets the kind of array elements for the array type code that appears in a * {@link Bytecodes#NEWARRAY} bytecode. @@ -905,20 +916,24 @@ private void genNewPrimitiveArray(int typeCode) { Class clazz = arrayTypeCodeToClass(typeCode); ResolvedJavaType elementType = metaAccess.lookupJavaType(clazz); - frameState.apush(append(new NewArrayNode(elementType, frameState.ipop(), true))); + frameState.apush(append(createNewArray(elementType, frameState.ipop(), true))); } private void genNewObjectArray(int cpi) { JavaType type = lookupType(cpi, ANEWARRAY); ValueNode length = frameState.ipop(); if (type instanceof ResolvedJavaType) { - frameState.apush(append(new NewArrayNode((ResolvedJavaType) type, length, true))); + frameState.apush(append(createNewArray((ResolvedJavaType) type, length, true))); } else { handleUnresolvedNewObjectArray(type, length); } } + protected NewArrayNode createNewArray(ResolvedJavaType elementType, ValueNode length, boolean fillContents) { + return new NewArrayNode(elementType, length, fillContents); + } + private void genNewMultiArray(int cpi) { JavaType type = lookupType(cpi, MULTIANEWARRAY); int rank = stream().readUByte(bci() + 3); @@ -1187,16 +1202,21 @@ args[0] = TypeProfileProxyNode.create(args[0], profile); } } - MethodCallTargetNode callTarget = currentGraph.add(new MethodCallTargetNode(invokeKind, targetMethod, args, returnType)); + MethodCallTargetNode callTarget = currentGraph.add(createMethodCallTarget(invokeKind, targetMethod, args, returnType)); createInvokeNode(callTarget, resultType); } + protected MethodCallTargetNode createMethodCallTarget(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args, JavaType returnType) { + return new MethodCallTargetNode(invokeKind, targetMethod, args, returnType); + } + protected Invoke createInvokeNode(CallTargetNode callTarget, Kind resultType) { // be conservative if information was not recorded (could result in endless recompiles // otherwise) if (graphBuilderConfig.omitAllExceptionEdges() || (optimisticOpts.useExceptionProbability() && profilingInfo.getExceptionSeen(bci()) == TriState.FALSE)) { - frameState.pushReturn(resultType, append(new InvokeNode(callTarget, bci()))); - return new InvokeNode(callTarget, bci()); + InvokeNode invoke = new InvokeNode(callTarget, bci()); + frameState.pushReturn(resultType, append(invoke)); + return invoke; } else { DispatchBeginNode exceptionEdge = handleException(null, bci()); InvokeWithExceptionNode invoke = append(new InvokeWithExceptionNode(callTarget, exceptionEdge, bci())); @@ -1573,7 +1593,7 @@ Debug.log("Ignoring block %s", block); return; } - Debug.log("Parsing block %s firstInstruction: %s loopHeader: %b", block, block.firstInstruction, block.isLoopHeader); + Indent indent = Debug.logAndIndent("Parsing block %s firstInstruction: %s loopHeader: %b", block, block.firstInstruction, block.isLoopHeader); lastInstr = block.firstInstruction; frameState = block.entryState; @@ -1600,6 +1620,7 @@ frameState.setRethrowException(false); iterateBytecodesForBlock(block); } + indent.outdent(); } private void connectLoopEndToBegin() { @@ -1636,15 +1657,15 @@ ValueNode x = returnKind == Kind.Void ? null : frameState.pop(returnKind); assert frameState.stackSize() == 0; + if (graphBuilderConfig.eagerInfopointMode()) { + append(new InfopointNode(InfopointReason.METHOD_END, frameState.create(bci()))); + } + synchronizedEpilogue(FrameState.AFTER_BCI, x); if (frameState.lockDepth() != 0) { throw new BailoutException("unbalanced monitors"); } - if (graphBuilderConfig.eagerInfopointMode()) { - append(new InfopointNode(InfopointReason.METHOD_END, frameState.create(FrameState.AFTER_BCI))); - } - append(new ReturnNode(x)); } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ConvertCompare.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ConvertCompare.java Sat Nov 30 19:05:44 2013 +0100 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2013, 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.jtt.optimize; + +import com.oracle.graal.jtt.*; +import org.junit.*; + +public class ConvertCompare extends JTTTest { + public static boolean test(int a, float d) { + return a == (double) d; + } + + @Test + public void run0() throws Throwable { + runTest("test", 0, 2.87f); + } +} diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64AddressValue.java Sat Nov 30 19:05:44 2013 +0100 @@ -51,6 +51,8 @@ this.index = index; this.scale = scale; this.displacement = displacement; + + assert scale != null; } private static Register toRegister(AllocatableValue value) { diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Sat Nov 30 19:05:44 2013 +0100 @@ -118,7 +118,7 @@ } public boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit) { - if (state == null && value.equals(address.base) && address.index == Value.ILLEGAL && address.displacement >= 0 && address.displacement < implicitNullCheckLimit) { + if (state == null && value.equals(address.base) && address.index.equals(Value.ILLEGAL) && address.displacement >= 0 && address.displacement < implicitNullCheckLimit) { state = nullCheckState; return true; } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java Sat Nov 30 19:05:44 2013 +0100 @@ -61,11 +61,15 @@ private final long[] componentOffsets; private final EnumSet[] componentFlags; + public CompositeValueClass(Class clazz) { + this(clazz, new DefaultCalcOffset()); + } + @SuppressWarnings("unchecked") - public CompositeValueClass(Class clazz) { + public CompositeValueClass(Class clazz, CalcOffset calcOffset) { super(clazz); - ValueFieldScanner scanner = new ValueFieldScanner(new DefaultCalcOffset()); + ValueFieldScanner scanner = new ValueFieldScanner(calcOffset); scanner.scan(clazz); OperandModeAnnotation mode = scanner.valueAnnotations.get(CompositeValue.Component.class); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Sat Nov 30 19:05:44 2013 +0100 @@ -73,12 +73,16 @@ private String opcodeConstant; private long opcodeOffset; + public LIRInstructionClass(Class clazz) { + this(clazz, new DefaultCalcOffset()); + } + @SuppressWarnings("unchecked") - public LIRInstructionClass(Class clazz) { + public LIRInstructionClass(Class clazz, CalcOffset calcOffset) { super(clazz); assert INSTRUCTION_CLASS.isAssignableFrom(clazz); - InstructionFieldScanner scanner = new InstructionFieldScanner(new DefaultCalcOffset()); + InstructionFieldScanner scanner = new InstructionFieldScanner(calcOffset); scanner.scan(clazz); OperandModeAnnotation mode = scanner.valueAnnotations.get(LIRInstruction.Use.class); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Sat Nov 30 19:05:44 2013 +0100 @@ -28,7 +28,6 @@ import com.oracle.graal.graph.Graph.DuplicationReplacement; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.VirtualState.NodeClosure; import com.oracle.graal.nodes.VirtualState.VirtualClosure; import com.oracle.graal.nodes.cfg.*; @@ -313,7 +312,20 @@ final ValueNode replaceWith; ProxyNode newVpn = getDuplicatedNode(vpn); if (newVpn != null) { - PhiNode phi = graph.addWithoutUnique(vpn.type() == PhiType.Value ? new PhiNode(vpn.kind(), merge) : new PhiNode(vpn.type(), merge, vpn.getIdentity())); + PhiNode phi; + switch (vpn.type()) { + case Value: + phi = graph.addWithoutUnique(new PhiNode(vpn.kind(), merge)); + break; + case Guard: + phi = graph.addWithoutUnique(new PhiNode(vpn.type(), merge)); + break; + case Memory: + phi = graph.addWithoutUnique(new MemoryPhiNode(merge, ((MemoryProxyNode) vpn).getLocationIdentity())); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } phi.addInput(vpn); phi.addInput(newVpn); replaceWith = phi; diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java Sat Nov 30 19:05:44 2013 +0100 @@ -166,6 +166,24 @@ // TODO (gd) ? } + private static PhiNode patchPhi(StructuredGraph graph, PhiNode phi, MergeNode merge) { + PhiNode ret; + switch (phi.type()) { + case Value: + ret = new PhiNode(phi.kind(), merge); + break; + case Guard: + ret = new PhiNode(PhiType.Guard, merge); + break; + case Memory: + ret = new MemoryPhiNode(merge, ((MemoryPhiNode) phi).getLocationIdentity()); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + return graph.addWithoutUnique(ret); + } + private void patchPeeling(LoopFragmentInside peel) { LoopBeginNode loopBegin = loop().loopBegin(); StructuredGraph graph = loopBegin.graph(); @@ -180,7 +198,7 @@ } // create a new phi (we don't patch the old one since some usages of the old one may // still be valid) - PhiNode newPhi = graph.addWithoutUnique(phi.type() == PhiType.Value ? new PhiNode(phi.kind(), loopBegin) : new PhiNode(phi.type(), loopBegin, phi.getIdentity())); + PhiNode newPhi = patchPhi(graph, phi, loopBegin); newPhi.addInput(first); for (LoopEndNode end : loopBegin.orderedLoopEnds()) { newPhi.addInput(phi.valueAt(end)); @@ -270,7 +288,7 @@ } for (final PhiNode phi : loopBegin.phis().snapshot()) { - final PhiNode firstPhi = graph.addWithoutUnique(phi.type() == PhiType.Value ? new PhiNode(phi.kind(), newExitMerge) : new PhiNode(phi.type(), newExitMerge, phi.getIdentity())); + final PhiNode firstPhi = patchPhi(graph, phi, newExitMerge); for (AbstractEndNode end : newExitMerge.forwardEnds()) { LoopEndNode loopEnd = reverseEnds.get(end); ValueNode prim = prim(phi.valueAt(loopEnd)); diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java Sat Nov 30 19:05:44 2013 +0100 @@ -23,9 +23,9 @@ package com.oracle.graal.loop; import java.util.*; -import java.util.concurrent.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; @@ -36,13 +36,12 @@ private ControlFlowGraph cfg; public LoopsData(final StructuredGraph graph) { - cfg = Debug.scope("ControlFlowGraph", new Callable() { + try (Scope s = Debug.scope("ControlFlowGraph")) { + cfg = ControlFlowGraph.compute(graph, true, true, true, true); + } catch (Throwable e) { + throw Debug.handle(e); + } - @Override - public ControlFlowGraph call() throws Exception { - return ControlFlowGraph.compute(graph, true, true, true, true); - } - }); for (Loop lirLoop : cfg.getLoops()) { LoopEx ex = new LoopEx(lirLoop, this); lirLoopToEx.put(lirLoop, ex); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/phases/LoopTransformLowPhase.java Sat Nov 30 19:05:44 2013 +0100 @@ -25,6 +25,7 @@ import static com.oracle.graal.phases.GraalOptions.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.NodeClass.NodeClassIterator; import com.oracle.graal.loop.*; import com.oracle.graal.nodes.*; @@ -39,15 +40,13 @@ if (graph.hasLoops()) { if (ReassociateInvariants.getValue()) { final LoopsData dataReassociate = new LoopsData(graph); - Debug.scope("ReassociateInvariants", new Runnable() { - - @Override - public void run() { - for (LoopEx loop : dataReassociate.loops()) { - loop.reassociateInvariants(); - } + try (Scope s = Debug.scope("ReassociateInvariants")) { + for (LoopEx loop : dataReassociate.loops()) { + loop.reassociateInvariants(); } - }); + } catch (Throwable e) { + throw Debug.handle(e); + } } if (LoopUnswitch.getValue()) { boolean unswitched; diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractFixedGuardNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.util.*; + +public abstract class AbstractFixedGuardNode extends DeoptimizingFixedWithNextNode implements Simplifiable, GuardingNode { + + @Input private LogicNode condition; + private final DeoptimizationReason reason; + private final DeoptimizationAction action; + private boolean negated; + + public LogicNode condition() { + return condition; + } + + public void setCondition(LogicNode x) { + updateUsages(condition, x); + condition = x; + } + + protected AbstractFixedGuardNode(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) { + super(StampFactory.dependency()); + this.action = action; + this.negated = negated; + this.condition = condition; + this.reason = deoptReason; + } + + public DeoptimizationReason getReason() { + return reason; + } + + public DeoptimizationAction getAction() { + return action; + } + + public boolean isNegated() { + return negated; + } + + @Override + public String toString(Verbosity verbosity) { + if (verbosity == Verbosity.Name && negated) { + return "!" + super.toString(verbosity); + } else { + return super.toString(verbosity); + } + } + + @Override + public void simplify(SimplifierTool tool) { + while (condition instanceof LogicNegationNode) { + LogicNegationNode negation = (LogicNegationNode) condition; + setCondition(negation.getInput()); + negated = !negated; + } + } + + public void lowerToIf() { + FixedNode next = next(); + setNext(null); + DeoptimizeNode deopt = graph().add(new DeoptimizeNode(action, reason)); + deopt.setDeoptimizationState(getDeoptimizationState()); + IfNode ifNode; + AbstractBeginNode noDeoptSuccessor; + if (negated) { + ifNode = graph().add(new IfNode(condition, deopt, next, 0)); + noDeoptSuccessor = ifNode.falseSuccessor(); + } else { + ifNode = graph().add(new IfNode(condition, next, deopt, 1)); + noDeoptSuccessor = ifNode.trueSuccessor(); + } + ((FixedWithNextNode) predecessor()).setNext(ifNode); + this.replaceAtUsages(noDeoptSuccessor); + GraphUtil.killWithUnusedFloatingInputs(this); + } + + @Override + public boolean canDeoptimize() { + return true; + } +} diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMemoryCheckpoint.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMemoryCheckpoint.java Sat Nov 30 19:05:44 2013 +0100 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes; + +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.type.*; + +/** + * Provides an implementation of {@link StateSplit}. + */ +public abstract class AbstractMemoryCheckpoint extends AbstractStateSplit implements MemoryCheckpoint { + + protected AbstractMemoryCheckpoint(Stamp stamp) { + super(stamp); + } + + protected AbstractMemoryCheckpoint(Stamp stamp, FrameState stateAfter) { + super(stamp, stateAfter); + } + + public MemoryCheckpoint asMemoryCheckpoint() { + return this; + } + + public MemoryPhiNode asMemoryPhi() { + return null; + } +} diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes; +import static com.oracle.graal.graph.Graph.*; + import java.util.*; import com.oracle.graal.api.meta.*; @@ -42,19 +44,19 @@ private final Constant value; - protected ConstantNode(Constant value) { - super(StampFactory.forConstant(value)); - this.value = value; - ConstantNodes.increment(); + private static ConstantNode createPrimitive(Constant value) { + assert value.getKind() != Kind.Object; + return new ConstantNode(value, StampFactory.forConstant(value)); } /** - * Constructs a new ConstantNode representing the specified constant. + * Constructs a new node representing the specified constant. * * @param value the constant */ - protected ConstantNode(Constant value, MetaAccessProvider metaAccess) { - super(StampFactory.forConstant(value, metaAccess)); + protected ConstantNode(Constant value, Stamp stamp) { + super(stamp); + assert stamp != null; this.value = value; ConstantNodes.increment(); } @@ -66,11 +68,13 @@ return value; } + private static boolean ConstantNodesAreExternal = Boolean.parseBoolean(System.getProperty("graal.constantNodesAreExternal", "true")); + /** * Used to measure the impact of ConstantNodes not recording their usages. This and all code * predicated on this value being true will be removed at some point. */ - public static final boolean ConstantNodeRecordsUsages = Boolean.getBoolean("graal.constantNodeRecordsUsages"); + public static final boolean ConstantNodeRecordsUsages = !ConstantNodesAreExternal && Boolean.getBoolean("graal.constantNodeRecordsUsages"); @Override public boolean recordsUsages() { @@ -79,17 +83,23 @@ @Override public boolean isDeleted() { + if (!ConstantNodesAreExternal) { + return super.isDeleted(); + } return false; } @Override public boolean isAlive() { + if (!ConstantNodesAreExternal) { + return super.isAlive(); + } return true; } @Override public boolean isExternal() { - return true; + return ConstantNodesAreExternal; } /** @@ -110,11 +120,15 @@ } /** - * Gathers all the {@link ConstantNode}s that are inputs to the {@linkplain Graph#getNodes() - * live nodes} in a given graph. This is an expensive operation that should only be used in - * test/verification/AOT code. + * Gathers all the {@link ConstantNode}s that are inputs to the + * {@linkplain StructuredGraph#getNodes() live nodes} in a given graph. This is an expensive + * operation that should only be used in test/verification/AOT code. */ public static NodeIterable getConstantNodes(StructuredGraph graph) { + if (!ConstantNodesAreExternal) { + return graph.getNodes().filter(ConstantNode.class); + } + Map result = new HashMap<>(); for (Node node : graph.getNodes()) { for (Node input : node.inputs()) { @@ -166,20 +180,25 @@ return true; } - public static ConstantNode forConstant(Constant constant, MetaAccessProvider metaAccess, Graph graph) { + public static ConstantNode forConstant(Constant constant, MetaAccessProvider metaAccess, StructuredGraph graph) { if (constant.getKind().getStackKind() == Kind.Int && constant.getKind() != Kind.Int) { return forInt(constant.asInt(), graph); - } else if (constant.getKind() == Kind.Object) { - return unique(graph, new ConstantNode(constant, metaAccess)); + } + if (ConstantNodesAreExternal && !CacheExternalNodesInGraph) { + Stamp stamp = constant.getKind() == Kind.Object ? StampFactory.forConstant(constant, metaAccess) : StampFactory.forConstant(constant); + return graph.asConstantNode(constant, stamp); + } + if (constant.getKind() == Kind.Object) { + return unique(graph, new ConstantNode(constant, StampFactory.forConstant(constant, metaAccess))); } else { - return unique(graph, new ConstantNode(constant)); + return unique(graph, createPrimitive(constant)); } } /** * Returns a node for a primitive constant. */ - public static ConstantNode forPrimitive(Constant constant, Graph graph) { + public static ConstantNode forPrimitive(Constant constant, StructuredGraph graph) { assert constant.getKind() != Kind.Object; return forConstant(constant, null, graph); } @@ -190,8 +209,11 @@ * @param d the double value for which to create the instruction * @return a node for a double constant */ - public static ConstantNode forDouble(double d, Graph graph) { - return unique(graph, new ConstantNode(Constant.forDouble(d))); + public static ConstantNode forDouble(double d, StructuredGraph graph) { + if (ConstantNodesAreExternal && !CacheExternalNodesInGraph) { + return graph.asConstantNode(Constant.forDouble(d), null); + } + return unique(graph, createPrimitive(Constant.forDouble(d))); } /** @@ -200,8 +222,11 @@ * @param f the float value for which to create the instruction * @return a node for a float constant */ - public static ConstantNode forFloat(float f, Graph graph) { - return unique(graph, new ConstantNode(Constant.forFloat(f))); + public static ConstantNode forFloat(float f, StructuredGraph graph) { + if (ConstantNodesAreExternal && !CacheExternalNodesInGraph) { + return graph.asConstantNode(Constant.forFloat(f), null); + } + return unique(graph, createPrimitive(Constant.forFloat(f))); } /** @@ -210,8 +235,11 @@ * @param i the long value for which to create the instruction * @return a node for an long constant */ - public static ConstantNode forLong(long i, Graph graph) { - return unique(graph, new ConstantNode(Constant.forLong(i))); + public static ConstantNode forLong(long i, StructuredGraph graph) { + if (ConstantNodesAreExternal && !CacheExternalNodesInGraph) { + return graph.asConstantNode(Constant.forLong(i), null); + } + return unique(graph, createPrimitive(Constant.forLong(i))); } /** @@ -220,8 +248,11 @@ * @param i the integer value for which to create the instruction * @return a node for an integer constant */ - public static ConstantNode forInt(int i, Graph graph) { - return unique(graph, new ConstantNode(Constant.forInt(i))); + public static ConstantNode forInt(int i, StructuredGraph graph) { + if (ConstantNodesAreExternal && !CacheExternalNodesInGraph) { + return graph.asConstantNode(Constant.forInt(i), null); + } + return unique(graph, createPrimitive(Constant.forInt(i))); } /** @@ -230,8 +261,11 @@ * @param i the boolean value for which to create the instruction * @return a node representing the boolean */ - public static ConstantNode forBoolean(boolean i, Graph graph) { - return unique(graph, new ConstantNode(Constant.forInt(i ? 1 : 0))); + public static ConstantNode forBoolean(boolean i, StructuredGraph graph) { + if (ConstantNodesAreExternal && !CacheExternalNodesInGraph) { + return graph.asConstantNode(i ? Constant.INT_1 : Constant.INT_0, null); + } + return unique(graph, createPrimitive(Constant.forInt(i ? 1 : 0))); } /** @@ -240,8 +274,11 @@ * @param i the byte value for which to create the instruction * @return a node representing the byte */ - public static ConstantNode forByte(byte i, Graph graph) { - return unique(graph, new ConstantNode(Constant.forInt(i))); + public static ConstantNode forByte(byte i, StructuredGraph graph) { + if (ConstantNodesAreExternal && !CacheExternalNodesInGraph) { + return graph.asConstantNode(Constant.forInt(i), null); + } + return unique(graph, createPrimitive(Constant.forInt(i))); } /** @@ -250,8 +287,11 @@ * @param i the char value for which to create the instruction * @return a node representing the char */ - public static ConstantNode forChar(char i, Graph graph) { - return unique(graph, new ConstantNode(Constant.forInt(i))); + public static ConstantNode forChar(char i, StructuredGraph graph) { + if (ConstantNodesAreExternal && !CacheExternalNodesInGraph) { + return graph.asConstantNode(Constant.forInt(i), null); + } + return unique(graph, createPrimitive(Constant.forInt(i))); } /** @@ -260,8 +300,11 @@ * @param i the short value for which to create the instruction * @return a node representing the short */ - public static ConstantNode forShort(short i, Graph graph) { - return unique(graph, new ConstantNode(Constant.forInt(i))); + public static ConstantNode forShort(short i, StructuredGraph graph) { + if (ConstantNodesAreExternal && !CacheExternalNodesInGraph) { + return graph.asConstantNode(Constant.forInt(i), null); + } + return unique(graph, createPrimitive(Constant.forInt(i))); } /** @@ -270,16 +313,24 @@ * @param o the object value for which to create the instruction * @return a node representing the object */ - public static ConstantNode forObject(Object o, MetaAccessProvider metaAccess, Graph graph) { + public static ConstantNode forObject(Object o, MetaAccessProvider metaAccess, StructuredGraph graph) { assert !(o instanceof Constant) : "wrapping a Constant into a Constant"; - return unique(graph, new ConstantNode(Constant.forObject(o), metaAccess)); + Constant constant = Constant.forObject(o); + if (ConstantNodesAreExternal && !CacheExternalNodesInGraph) { + return graph.asConstantNode(constant, StampFactory.forConstant(constant, metaAccess)); + } + return unique(graph, new ConstantNode(constant, StampFactory.forConstant(constant, metaAccess))); } - private static ConstantNode unique(Graph graph, ConstantNode node) { - return graph.uniqueWithoutAdd(node); + private static ConstantNode unique(StructuredGraph graph, ConstantNode node) { + if (!ConstantNodesAreExternal) { + return graph.unique(node); + } + assert CacheExternalNodesInGraph; + return graph.uniqueExternal(node); } - public static ConstantNode forIntegerKind(Kind kind, long value, Graph graph) { + public static ConstantNode forIntegerKind(Kind kind, long value, StructuredGraph graph) { switch (kind) { case Byte: case Short: @@ -292,7 +343,7 @@ } } - public static ConstantNode forFloatingKind(Kind kind, double value, Graph graph) { + public static ConstantNode forFloatingKind(Kind kind, double value, StructuredGraph graph) { switch (kind) { case Float: return ConstantNode.forFloat((float) value, graph); @@ -303,7 +354,7 @@ } } - public static ConstantNode defaultForKind(Kind kind, Graph graph) { + public static ConstantNode defaultForKind(Kind kind, StructuredGraph graph) { switch (kind) { case Boolean: case Byte: diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -27,7 +27,7 @@ import com.oracle.graal.nodes.spi.*; @NodeInfo(shortName = "Deopt", nameTemplate = "Deopt {p#reason/s}") -public class DeoptimizeNode extends AbstractDeoptimizeNode implements LIRLowerable { +public class DeoptimizeNode extends AbstractDeoptimizeNode implements Lowerable, LIRLowerable { private final DeoptimizationAction action; private final DeoptimizationReason reason; @@ -54,6 +54,11 @@ } @Override + public void lower(LoweringTool tool) { + tool.getLowerer().lower(this, tool); + } + + @Override public void generate(LIRGeneratorTool gen) { gen.emitDeoptimize(gen.getMetaAccess().encodeDeoptActionAndReason(action, reason, speculationId), this); } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -27,76 +27,31 @@ import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.nodes.util.*; @NodeInfo(nameTemplate = "FixedGuard(!={p#negated}) {p#reason/s}") -public final class FixedGuardNode extends DeoptimizingFixedWithNextNode implements Simplifiable, Lowerable, IterableNodeType, GuardingNode { - - @Input private LogicNode condition; - private final DeoptimizationReason reason; - private final DeoptimizationAction action; - private boolean negated; - - public LogicNode condition() { - return condition; - } - - public void setCondition(LogicNode x) { - updateUsages(condition, x); - condition = x; - } +public final class FixedGuardNode extends AbstractFixedGuardNode implements Lowerable, IterableNodeType { public FixedGuardNode(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action) { this(condition, deoptReason, action, false); } public FixedGuardNode(LogicNode condition, DeoptimizationReason deoptReason, DeoptimizationAction action, boolean negated) { - super(StampFactory.dependency()); - this.action = action; - this.negated = negated; - this.condition = condition; - this.reason = deoptReason; - } - - public DeoptimizationReason getReason() { - return reason; - } - - public DeoptimizationAction getAction() { - return action; - } - - public boolean isNegated() { - return negated; - } - - @Override - public String toString(Verbosity verbosity) { - if (verbosity == Verbosity.Name && negated) { - return "!" + super.toString(verbosity); - } else { - return super.toString(verbosity); - } + super(condition, deoptReason, action, negated); } @Override public void simplify(SimplifierTool tool) { - while (condition instanceof LogicNegationNode) { - LogicNegationNode negation = (LogicNegationNode) condition; - setCondition(negation.getInput()); - negated = !negated; - } + super.simplify(tool); - if (condition instanceof LogicConstantNode) { - LogicConstantNode c = (LogicConstantNode) condition; - if (c.getValue() == negated) { + if (condition() instanceof LogicConstantNode) { + LogicConstantNode c = (LogicConstantNode) condition(); + if (c.getValue() == isNegated()) { FixedNode next = this.next(); if (next != null) { tool.deleteBranch(next); } - DeoptimizeNode deopt = graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, reason)); + DeoptimizeNode deopt = graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, getReason())); deopt.setDeoptimizationState(getDeoptimizationState()); setNext(deopt); } @@ -113,22 +68,7 @@ ValueAnchorNode newAnchor = graph().add(new ValueAnchorNode(guard.asNode())); graph().replaceFixedWithFixed(this, newAnchor); } else { - FixedNode next = next(); - setNext(null); - DeoptimizeNode deopt = graph().add(new DeoptimizeNode(action, reason)); - deopt.setDeoptimizationState(getDeoptimizationState()); - IfNode ifNode; - AbstractBeginNode noDeoptSuccessor; - if (negated) { - ifNode = graph().add(new IfNode(condition, deopt, next, 0)); - noDeoptSuccessor = ifNode.falseSuccessor(); - } else { - ifNode = graph().add(new IfNode(condition, next, deopt, 1)); - noDeoptSuccessor = ifNode.trueSuccessor(); - } - ((FixedWithNextNode) predecessor()).setNext(ifNode); - this.replaceAtUsages(noDeoptSuccessor); - GraphUtil.killWithUnusedFloatingInputs(this); + lowerToIf(); } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -25,6 +25,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.type.*; @@ -41,7 +42,7 @@ * control flow would have reached the guarded node (without taking exceptions into account). */ @NodeInfo(nameTemplate = "Guard(!={p#negated}) {p#reason/s}") -public final class GuardNode extends FloatingGuardedNode implements Canonicalizable, IterableNodeType, GuardingNode, GuardedNode { +public class GuardNode extends FloatingGuardedNode implements Canonicalizable, IterableNodeType, GuardingNode, GuardedNode { @Input private LogicNode condition; private final DeoptimizationReason reason; @@ -104,6 +105,20 @@ return this; } + public FixedWithNextNode lowerGuard() { + if (negated() && condition() instanceof IsNullNode) { + IsNullNode isNull = (IsNullNode) condition(); + NullCheckNode nullCheck = graph().add(new NullCheckNode(isNull.object())); + setCondition(null); + if (isNull.usages().isEmpty()) { + isNull.safeDelete(); + } + return nullCheck; + } + + return null; + } + public void negate() { negated = !negated; } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -87,7 +87,7 @@ @Override public void virtualize(VirtualizerTool tool) { State state = tool.getObjectState(object); - if (state != null && state.getState() == EscapeState.Virtual && ObjectStamp.typeOrNull(this).isAssignableFrom(state.getVirtualObject().type())) { + if (state != null && state.getState() == EscapeState.Virtual && ObjectStamp.typeOrNull(this) != null && ObjectStamp.typeOrNull(this).isAssignableFrom(state.getVirtualObject().type())) { tool.replaceWithVirtual(state.getVirtualObject()); } } @@ -108,10 +108,12 @@ if (c.getValue() == negated) { // The guard always fails return graph().add(new DeoptimizeNode(action, reason)); - } - - if (c.getValue() != negated && stamp().equals(object().stamp())) { + } else if (stamp().equals(object().stamp())) { + // The guard always succeeds, and does not provide new type information return object; + } else { + // The guard always succeeds, and provides new type information + return graph().unique(new PiNode(object, stamp())); } } return this; diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -35,7 +35,7 @@ * The {@code InvokeNode} represents all kinds of method calls. */ @NodeInfo(nameTemplate = "Invoke#{p#targetMethod/s}") -public final class InvokeNode extends AbstractStateSplit implements Invoke, LIRLowerable, MemoryCheckpoint.Single { +public final class InvokeNode extends AbstractMemoryCheckpoint implements Invoke, LIRLowerable, MemoryCheckpoint.Single { @Input private CallTargetNode callTarget; @Input private FrameState deoptState; diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -253,4 +253,12 @@ return stateAfter(); } } + + public MemoryCheckpoint asMemoryCheckpoint() { + return this; + } + + public MemoryPhiNode asMemoryPhi() { + return null; + } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -46,4 +46,12 @@ public LocationIdentity getLocationIdentity() { return locationIdentity; } + + public MemoryCheckpoint asMemoryCheckpoint() { + return this; + } + + public MemoryPhiNode asMemoryPhi() { + return null; + } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -23,8 +23,8 @@ package com.oracle.graal.nodes; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.type.*; public abstract class MemoryMapNode extends FloatingNode { @@ -33,5 +33,5 @@ super(StampFactory.forVoid()); } - public abstract Node getLastLocationAccess(LocationIdentity locationIdentity); + public abstract MemoryNode getLastLocationAccess(LocationIdentity locationIdentity); } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.extended.*; + +/** + * The {@code PhiNode} represents the merging of dataflow in the memory graph. + */ +public class MemoryPhiNode extends PhiNode implements MemoryNode { + + private final LocationIdentity identity; + + public MemoryPhiNode(MergeNode merge, LocationIdentity identity) { + super(PhiType.Memory, merge); + this.identity = identity; + } + + public LocationIdentity getLocationIdentity() { + return identity; + } + + public MemoryCheckpoint asMemoryCheckpoint() { + return null; + } + + public MemoryPhiNode asMemoryPhi() { + return this; + } +} diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryProxyNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryProxyNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.PhiNode.PhiType; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; + +public class MemoryProxyNode extends ProxyNode implements MemoryProxy, LIRLowerable { + + private final LocationIdentity identity; + + public MemoryProxyNode(ValueNode value, AbstractBeginNode exit, LocationIdentity identity) { + super(value, exit, PhiType.Memory); + assert value instanceof MemoryNode; + this.identity = identity; + } + + public LocationIdentity getLocationIdentity() { + return identity; + } + + @Override + public void generate(LIRGeneratorTool generator) { + } + + @Override + public boolean verify() { + assert value() instanceof MemoryNode; + return super.verify(); + } + + public static MemoryProxyNode forMemory(MemoryNode value, AbstractBeginNode exit, LocationIdentity location, StructuredGraph graph) { + return graph.unique(new MemoryProxyNode(ValueNodeUtil.asNode(value), exit, location)); + } + + public MemoryNode getOriginalMemoryNode() { + return (MemoryNode) value(); + } + + public MemoryCheckpoint asMemoryCheckpoint() { + return getOriginalMemoryNode().asMemoryCheckpoint(); + } + + public MemoryPhiNode asMemoryPhi() { + return getOriginalMemoryNode().asMemoryPhi(); + } +} diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -51,7 +51,6 @@ @Input(notDataflow = true) private MergeNode merge; @Input private final NodeInputList values = new NodeInputList<>(this); private final PhiType type; - private final LocationIdentity identity; /** * Create a value phi ({@link PhiType#Value}) with the specified kind. @@ -68,7 +67,6 @@ assert stamp != StampFactory.forVoid(); this.type = PhiType.Value; this.merge = merge; - this.identity = null; } /** @@ -77,12 +75,11 @@ * @param type the type of the new phi * @param merge the merge that the new phi belongs to */ - public PhiNode(PhiType type, MergeNode merge, LocationIdentity identity) { + public PhiNode(PhiType type, MergeNode merge) { super(type.stamp); assert type.stamp != null : merge + " " + type; this.type = type; this.merge = merge; - this.identity = identity; } public PhiType type() { @@ -93,11 +90,6 @@ return merge; } - public LocationIdentity getIdentity() { - assert type != PhiType.Value; - return identity; - } - public void setMerge(MergeNode x) { updateUsages(merge, x); merge = x; diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -77,7 +77,7 @@ @Override public void virtualize(VirtualizerTool tool) { State state = tool.getObjectState(object); - if (state != null && state.getState() == EscapeState.Virtual && ObjectStamp.typeOrNull(this).isAssignableFrom(state.getVirtualObject().type())) { + if (state != null && state.getState() == EscapeState.Virtual && ObjectStamp.typeOrNull(this) != null && ObjectStamp.typeOrNull(this).isAssignableFrom(state.getVirtualObject().type())) { tool.replaceWithVirtual(state.getVirtualObject()); } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -22,7 +22,6 @@ */ package com.oracle.graal.nodes; -import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.ValueNumberable; import com.oracle.graal.graph.spi.*; @@ -37,17 +36,15 @@ * loop. */ @NodeInfo(nameTemplate = "{p#type/s}Proxy") -public class ProxyNode extends FloatingNode implements IterableNodeType, ValueNumberable, Canonicalizable, Virtualizable, LIRLowerable, ValueProxy, GuardingNode { +public class ProxyNode extends FloatingNode implements IterableNodeType, ValueNumberable, Canonicalizable, Virtualizable, ValueProxy, GuardingNode { @Input(notDataflow = true) private AbstractBeginNode proxyPoint; @Input private ValueNode value; private final PhiType type; - private final LocationIdentity identity; - public ProxyNode(ValueNode value, AbstractBeginNode exit, PhiType type, LocationIdentity identity) { + public ProxyNode(ValueNode value, AbstractBeginNode exit, PhiType type) { super(type == PhiType.Value ? value.stamp() : type.stamp); this.type = type; - this.identity = identity; assert exit != null; this.proxyPoint = exit; this.value = value; @@ -70,11 +67,6 @@ return type; } - public LocationIdentity getIdentity() { - assert type != PhiType.Value; - return identity; - } - @Override public boolean verify() { assert value != null; @@ -84,11 +76,6 @@ } @Override - public void generate(LIRGeneratorTool generator) { - assert type == PhiType.Memory; - } - - @Override public Node canonical(CanonicalizerTool tool) { if (type == PhiType.Value && value.isConstant()) { return value; @@ -107,15 +94,11 @@ } public static ProxyNode forGuard(ValueNode value, AbstractBeginNode exit, StructuredGraph graph) { - return graph.unique(new ProxyNode(value, exit, PhiType.Guard, null)); + return graph.unique(new ProxyNode(value, exit, PhiType.Guard)); } public static ProxyNode forValue(ValueNode value, AbstractBeginNode exit, StructuredGraph graph) { - return graph.unique(new ProxyNode(value, exit, PhiType.Value, null)); - } - - public static ProxyNode forMemory(ValueNode value, AbstractBeginNode exit, LocationIdentity location, StructuredGraph graph) { - return graph.unique(new ProxyNode(value, exit, PhiType.Memory, location)); + return graph.unique(new ProxyNode(value, exit, PhiType.Value)); } @Override diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -34,4 +34,12 @@ public LocationIdentity getLocationIdentity() { return LocationIdentity.ANY_LOCATION; } + + public MemoryCheckpoint asMemoryCheckpoint() { + return this; + } + + public MemoryPhiNode asMemoryPhi() { + return null; + } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Sat Nov 30 19:05:44 2013 +0100 @@ -29,6 +29,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; /** @@ -81,6 +82,38 @@ private boolean isAfterFloatingReadPhase = false; /** + * Used to create canonical {@link ConstantNode}s for {@link Constant}s in this graph. + */ + private Map constants; + + /** + * Gets a node for a given constant that is unique/canonical within this graph. + * + * @param stamp the stamp for an {@link Kind#Object} constant (ignored otherwise) + */ + public ConstantNode asConstantNode(Constant constant, Stamp stamp) { + ConstantNode node; + if (constants == null) { + constants = new HashMap<>(); + node = null; + } else { + node = constants.get(constant); + } + if (node == null) { + node = new ConstantNode(constant, stamp == null ? StampFactory.forConstant(constant) : stamp); + constants.put(constant, node); + } + return node; + } + + @SuppressWarnings("unchecked") + @Override + public T uniqueExternal(T node) { + ConstantNode cn = (ConstantNode) node; + return (T) asConstantNode(cn.asConstant(), cn.stamp()); + } + + /** * Creates a new Graph containing a single {@link AbstractBeginNode} as the {@link #start() * start} node. */ diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/UnwindNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -29,7 +29,7 @@ /** * Unwinds the current frame to an exception handler in the caller frame. */ -public final class UnwindNode extends ControlSinkNode implements LIRLowerable { +public final class UnwindNode extends ControlSinkNode implements Lowerable, LIRLowerable { @Input private ValueNode exception; @@ -44,6 +44,11 @@ } @Override + public void lower(LoweringTool tool) { + tool.getLowerer().lower(this, tool); + } + + @Override public void generate(LIRGeneratorTool gen) { gen.emitUnwind(gen.operand(exception())); } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNodeUtil.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNodeUtil.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNodeUtil.java Sat Nov 30 19:05:44 2013 +0100 @@ -27,6 +27,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.Verbosity; +import com.oracle.graal.nodes.extended.*; public class ValueNodeUtil { @@ -95,4 +96,12 @@ public static String valueString(ValueNode value) { return (value == null) ? "-" : ("" + value.kind().getTypeChar() + value.toString(Verbosity.Id)); } + + public static ValueNode asNode(MemoryNode node) { + if (node == null) { + return null; + } else { + return node.asNode(); + } + } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -136,7 +136,7 @@ if (x() instanceof ConvertNode && y() instanceof ConvertNode) { ConvertNode convertX = (ConvertNode) x(); ConvertNode convertY = (ConvertNode) y(); - if (convertX.isLossless() && convertY.isLossless()) { + if (convertX.isLossless() && convertY.isLossless() && convertX.getFromKind() == convertY.getFromKind()) { setX(convertX.value()); setY(convertY.value()); } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ArrayRangeWriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ArrayRangeWriteNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ArrayRangeWriteNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -28,7 +28,7 @@ /** * Base class for nodes that modify a range of an array. */ -public abstract class ArrayRangeWriteNode extends AbstractStateSplit { +public abstract class ArrayRangeWriteNode extends AbstractMemoryCheckpoint { protected ArrayRangeWriteNode(Stamp stamp) { super(stamp); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -43,7 +43,7 @@ super(object, location, stamp, barrierType, compressible); } - public abstract FloatingAccessNode asFloatingNode(ValueNode lastLocationAccess); + public abstract FloatingAccessNode asFloatingNode(MemoryNode lastLocationAccess); /** * AccessNodes can float only if their location identities are not ANY_LOCATION. Furthermore, in diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -26,7 +26,6 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -36,27 +35,27 @@ */ public final class FloatingReadNode extends FloatingAccessNode implements IterableNodeType, LIRLowerable, Canonicalizable { - @Input private Node lastLocationAccess; + @Input private MemoryNode lastLocationAccess; - public FloatingReadNode(ValueNode object, LocationNode location, Node lastLocationAccess, Stamp stamp) { + public FloatingReadNode(ValueNode object, LocationNode location, MemoryNode lastLocationAccess, Stamp stamp) { this(object, location, lastLocationAccess, stamp, null, BarrierType.NONE, false); } - public FloatingReadNode(ValueNode object, LocationNode location, Node lastLocationAccess, Stamp stamp, GuardingNode guard) { + public FloatingReadNode(ValueNode object, LocationNode location, MemoryNode lastLocationAccess, Stamp stamp, GuardingNode guard) { this(object, location, lastLocationAccess, stamp, guard, BarrierType.NONE, false); } - public FloatingReadNode(ValueNode object, LocationNode location, Node lastLocationAccess, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean compressible) { + public FloatingReadNode(ValueNode object, LocationNode location, MemoryNode lastLocationAccess, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean compressible) { super(object, location, stamp, guard, barrierType, compressible); this.lastLocationAccess = lastLocationAccess; } - public Node getLastLocationAccess() { + public MemoryNode getLastLocationAccess() { return lastLocationAccess; } - public void setLastLocationAccess(Node newlla) { - updateUsages(lastLocationAccess, newlla); + public void setLastLocationAccess(MemoryNode newlla) { + updateUsages(ValueNodeUtil.asNode(lastLocationAccess), ValueNodeUtil.asNode(newlla)); lastLocationAccess = newlla; } @@ -76,22 +75,10 @@ return graph().add(new ReadNode(object(), nullCheckLocation(), stamp(), getGuard(), getBarrierType(), isCompressible())); } - private static boolean isMemoryCheckPoint(Node n) { - return n instanceof MemoryCheckpoint.Single || n instanceof MemoryCheckpoint.Multi; - } - - private static boolean isMemoryPhi(Node n) { - return n instanceof PhiNode && ((PhiNode) n).type() == PhiType.Memory; - } - - private static boolean isMemoryProxy(Node n) { - return n instanceof ProxyNode && ((ProxyNode) n).type() == PhiType.Memory; - } - @Override public boolean verify() { - Node lla = getLastLocationAccess(); - assert lla == null || isMemoryCheckPoint(lla) || isMemoryPhi(lla) || isMemoryProxy(lla) : "lastLocationAccess of " + this + " should be a MemoryCheckpoint, but is " + lla; + MemoryNode lla = getLastLocationAccess(); + assert lla == null || lla.asMemoryCheckpoint() != null || lla.asMemoryPhi() != null : "lastLocationAccess of " + this + " should be a MemoryCheckpoint, but is " + lla; return super.verify(); } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -33,7 +33,7 @@ * Node for a {@linkplain ForeignCallDescriptor foreign} call. */ @NodeInfo(nameTemplate = "ForeignCall#{p#descriptor/s}") -public class ForeignCallNode extends AbstractStateSplit implements LIRLowerable, DeoptimizingNode, MemoryCheckpoint.Multi { +public class ForeignCallNode extends AbstractMemoryCheckpoint implements LIRLowerable, DeoptimizingNode, MemoryCheckpoint.Multi { @Input private final NodeInputList arguments; private final ForeignCallsProvider foreignCalls; diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -61,7 +61,7 @@ @Override public void lower(LoweringTool tool) { - if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { + if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS || graph().getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { tool.getLowerer().lower(this, tool); } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -60,6 +60,14 @@ generator.emitMembar(barriers); } + public MemoryCheckpoint asMemoryCheckpoint() { + return this; + } + + public MemoryPhiNode asMemoryPhi() { + return null; + } + @SuppressWarnings("unused") @NodeIntrinsic public static void memoryBarrier(@ConstantNodeParameter int barriers) { diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryAccess.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryAccess.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryAccess.java Sat Nov 30 19:05:44 2013 +0100 @@ -23,7 +23,6 @@ package com.oracle.graal.nodes.extended; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; /** * This interface marks nodes that access some memory location, and that have an edge to the last @@ -33,7 +32,7 @@ LocationIdentity getLocationIdentity(); - Node getLastLocationAccess(); + MemoryNode getLastLocationAccess(); - void setLastLocationAccess(Node lla); + void setLastLocationAccess(MemoryNode lla); } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryCheckpoint.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryCheckpoint.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryCheckpoint.java Sat Nov 30 19:05:44 2013 +0100 @@ -31,7 +31,9 @@ * represented by location identities (i.e. change a value at one or more locations that belong to * these location identities). */ -public interface MemoryCheckpoint { +public interface MemoryCheckpoint extends MemoryNode { + + FixedNode asNode(); interface Single extends MemoryCheckpoint { diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes.extended; + +import com.oracle.graal.nodes.*; + +/** + * This interface marks nodes that are part of the memory graph. + */ +public interface MemoryNode { + + ValueNode asNode(); + + MemoryCheckpoint asMemoryCheckpoint(); + + MemoryPhiNode asMemoryPhi(); +} diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -43,6 +43,15 @@ super(object, location, stamp, guard, barrierType, compressible); } + private ReadNode(ValueNode object, ValueNode location, ValueNode guard, BarrierType barrierType, boolean compressible) { + /* + * Used by node intrinsics. Really, you can trust me on that! Since the initial value for + * location is a parameter, i.e., a LocalNode, the constructor cannot use the declared type + * LocationNode. + */ + super(object, location, StampFactory.forNodeIntrinsic(), (GuardingNode) guard, barrierType, compressible); + } + @Override public void generate(LIRGeneratorTool gen) { Value address = location().generateAddress(gen, gen.operand(object())); @@ -55,7 +64,7 @@ } @Override - public FloatingAccessNode asFloatingNode(ValueNode lastLocationAccess) { + public FloatingAccessNode asFloatingNode(MemoryNode lastLocationAccess) { return graph().unique(new FloatingReadNode(object(), location(), lastLocationAccess, stamp(), getGuard(), getBarrierType(), isCompressible())); } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -34,7 +34,11 @@ * allows unsafe casts "sideways" in the type hierarchy. It does not allow to "drop" type * information, i.e., an unsafe cast is removed if the input object has a more precise or equal type * than the type this nodes casts to. + * + * @deprecated use {@link PiNode}. */ + +@Deprecated public class UnsafeCastNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, GuardingNode, IterableNodeType, Canonicalizable, ValueProxy { @Input private ValueNode object; @@ -88,7 +92,7 @@ @Override public void virtualize(VirtualizerTool tool) { State state = tool.getObjectState(object); - if (state != null && state.getState() == EscapeState.Virtual && ObjectStamp.typeOrNull(this).isAssignableFrom(state.getVirtualObject().type())) { + if (state != null && state.getState() == EscapeState.Virtual && ObjectStamp.typeOrNull(this) != null && ObjectStamp.typeOrNull(this).isAssignableFrom(state.getVirtualObject().type())) { tool.replaceWithVirtual(state.getVirtualObject()); } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -111,6 +111,14 @@ return stateAfter; } + public MemoryCheckpoint asMemoryCheckpoint() { + return this; + } + + public MemoryPhiNode asMemoryPhi() { + return null; + } + // specialized on value type until boxing/unboxing is sorted out in intrinsification @SuppressWarnings("unused") diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -45,6 +45,16 @@ return stateAfter; } + @Override + public FrameState getState() { + if (stateAfter != null) { + assert super.getState() == null; + return stateAfter; + } else { + return super.getState(); + } + } + public void setStateAfter(FrameState x) { assert x == null || x.isAlive() : "frame state must be in a graph"; updateUsages(stateAfter, x); @@ -92,13 +102,14 @@ return location().getLocationIdentity(); } - public Node getLastLocationAccess() { - return lastLocationAccess; + public MemoryNode getLastLocationAccess() { + return (MemoryNode) lastLocationAccess; } - public void setLastLocationAccess(Node lla) { - updateUsages(lastLocationAccess, lla); - lastLocationAccess = lla; + public void setLastLocationAccess(MemoryNode lla) { + Node newLla = ValueNodeUtil.asNode(lla); + updateUsages(lastLocationAccess, newLla); + lastLocationAccess = newLla; } @Override @@ -116,4 +127,12 @@ } } } + + public MemoryCheckpoint asMemoryCheckpoint() { + return this; + } + + public MemoryPhiNode asMemoryPhi() { + return null; + } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -33,7 +33,7 @@ * The Java bytecode specification allows non-balanced locking. Graal does not handle such cases and * throws a {@link BailoutException} instead during graph building. */ -public abstract class AccessMonitorNode extends AbstractStateSplit implements MemoryCheckpoint { +public abstract class AccessMonitorNode extends AbstractMemoryCheckpoint implements MemoryCheckpoint { @Input private ValueNode object; diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -34,7 +34,7 @@ * Represents an atomic compare-and-swap operation The result is a boolean that contains whether the * value matched the expected value. */ -public class CompareAndSwapNode extends AbstractStateSplit implements Lowerable, MemoryCheckpoint.Single { +public class CompareAndSwapNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single { @Input private ValueNode object; @Input private ValueNode offset; diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -101,4 +101,12 @@ assertTrue(stateAfter() != null || stamp() == StampFactory.forVoid(), "an exception handler needs a frame state"); return super.verify(); } + + public MemoryCheckpoint asMemoryCheckpoint() { + return this; + } + + public MemoryPhiNode asMemoryPhi() { + return null; + } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -75,4 +75,12 @@ public void generate(LIRGeneratorTool gen) { gen.visitCompareAndSwap(this, location().generateAddress(gen, gen.operand(object()))); } + + public MemoryCheckpoint asMemoryCheckpoint() { + return this; + } + + public MemoryPhiNode asMemoryPhi() { + return null; + } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -34,8 +34,6 @@ */ public class NewArrayNode extends AbstractNewArrayNode implements VirtualizableAllocation { - private final ResolvedJavaType elementType; - /** * Constructs a new NewArrayNode. * @@ -46,7 +44,6 @@ */ public NewArrayNode(ResolvedJavaType elementType, ValueNode length, boolean fillContents) { super(StampFactory.exactNonNull(elementType.getArrayClass()), length, fillContents); - this.elementType = elementType; } /** @@ -55,7 +52,7 @@ * @return the element type of the array */ public ResolvedJavaType elementType() { - return elementType; + return ObjectStamp.typeOrNull(this).getComponentType(); } @Override @@ -64,14 +61,19 @@ final int constantLength = length().asConstant().asInt(); if (constantLength >= 0 && constantLength < tool.getMaximumEntryCount()) { ValueNode[] state = new ValueNode[constantLength]; - ConstantNode defaultForKind = constantLength == 0 ? null : ConstantNode.defaultForKind(elementType().getKind(), graph()); + ConstantNode defaultForKind = constantLength == 0 ? null : defaultElementValue(); for (int i = 0; i < constantLength; i++) { state[i] = defaultForKind; } - VirtualObjectNode virtualObject = new VirtualArrayNode(elementType, constantLength); + VirtualObjectNode virtualObject = new VirtualArrayNode(elementType(), constantLength); tool.createVirtualObject(virtualObject, state, null); tool.replaceWithVirtual(virtualObject); } } } + + /* Factored out in a separate method so that subclasses can override it. */ + protected ConstantNode defaultElementValue() { + return ConstantNode.defaultForKind(elementType().getKind(), graph()); + } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -36,7 +36,7 @@ * The {@code NewInstanceNode} represents the allocation of an instance class object. */ @NodeInfo(nameTemplate = "New {p#instanceClass/s}") -public final class NewInstanceNode extends DeoptimizingFixedWithNextNode implements Canonicalizable, Lowerable, VirtualizableAllocation { +public class NewInstanceNode extends DeoptimizingFixedWithNextNode implements Canonicalizable, Lowerable, VirtualizableAllocation { private final ResolvedJavaType instanceClass; private final boolean fillContents; @@ -96,13 +96,18 @@ ResolvedJavaField[] fields = virtualObject.getFields(); ValueNode[] state = new ValueNode[fields.length]; for (int i = 0; i < state.length; i++) { - state[i] = ConstantNode.defaultForKind(fields[i].getType().getKind(), graph()); + state[i] = defaultFieldValue(fields[i]); } tool.createVirtualObject(virtualObject, state, null); tool.replaceWithVirtual(virtualObject); } } + /* Factored out in a separate method so that subclasses can override it. */ + protected ConstantNode defaultFieldValue(ResolvedJavaField field) { + return ConstantNode.defaultForKind(field.getType().getKind(), graph()); + } + @Override public boolean canDeoptimize() { return true; diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java Sat Nov 30 19:05:44 2013 +0100 @@ -33,14 +33,10 @@ MetaAccessProvider getMetaAccess(); - CodeCacheProvider getCodeCache(); - LoweringProvider getLowerer(); ConstantReflectionProvider getConstantReflection(); - ForeignCallsProvider getForeignCalls(); - Replacements getReplacements(); GuardingNode createNullCheckGuard(GuardedNode guardedNode, ValueNode object); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/MemoryProxy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/MemoryProxy.java Sat Nov 30 19:05:44 2013 +0100 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes.spi; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.extended.*; + +public interface MemoryProxy extends ValueProxy, MemoryNode { + + LocationIdentity getLocationIdentity(); + + MemoryNode getOriginalMemoryNode(); +} diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Replacements.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Replacements.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Replacements.java Sat Nov 30 19:05:44 2013 +0100 @@ -42,6 +42,19 @@ StructuredGraph getSnippet(ResolvedJavaMethod method); /** + * Registers a method as snippet. + */ + void registerSnippet(ResolvedJavaMethod method); + + /** + * Prepares the copy of a snippet graph immediately after instantiation. This can be used to do + * node intrinsification for example. + * + * @param snippetCopy The copy of the snippet graph. + */ + void prepareSnippetCopyAfterInstantiation(StructuredGraph snippetCopy); + + /** * Gets the graph that is a substitution for a given method. * * @return the graph, if any, that is a substitution for {@code method} diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java Sat Nov 30 19:05:44 2013 +0100 @@ -22,11 +22,10 @@ */ package com.oracle.graal.phases.common; -import java.util.concurrent.*; - import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Graph.Mark; import com.oracle.graal.graph.Graph.NodeChangedListener; @@ -243,22 +242,20 @@ if (nodeClass.isCanonicalizable()) { assert !nodeClass.isSimplifiable(); METRIC_CANONICALIZATION_CONSIDERED_NODES.increment(); - return Debug.scope("CanonicalizeNode", node, new Callable() { - - public Boolean call() { - Node canonical = node.canonical(tool); - return performReplacement(node, canonical); - } - }); + try (Scope s = Debug.scope("CanonicalizeNode", node)) { + Node canonical = node.canonical(tool); + return performReplacement(node, canonical); + } catch (Throwable e) { + throw Debug.handle(e); + } } else if (nodeClass.isSimplifiable()) { Debug.log("Canonicalizer: simplifying %s", node); METRIC_SIMPLIFICATION_CONSIDERED_NODES.increment(); - Debug.scope("SimplifyNode", node, new Runnable() { - - public void run() { - node.simplify(tool); - } - }); + try (Scope s = Debug.scope("SimplifyNode", node)) { + node.simplify(tool); + } catch (Throwable e) { + throw Debug.handle(e); + } } return node.isDeleted(); } @@ -302,9 +299,8 @@ FixedNode fixed = (FixedNode) node; if (canonical instanceof ControlSinkNode) { // case 7 - FixedWithNextNode pred = (FixedWithNextNode) node.predecessor(); + fixed.predecessor().replaceFirstSuccessor(fixed, canonical); GraphUtil.killCFG(fixed); - pred.setNext((FixedNode) canonical); return true; } else { assert fixed instanceof FixedWithNextNode; diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Sat Nov 30 19:05:44 2013 +0100 @@ -28,7 +28,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.graph.*; @@ -43,7 +42,7 @@ public static class MemoryMapImpl extends MemoryMapNode { - private IdentityHashMap lastMemorySnapshot; + private IdentityHashMap lastMemorySnapshot; public MemoryMapImpl(MemoryMapImpl memoryMap) { lastMemorySnapshot = new IdentityHashMap<>(memoryMap.lastMemorySnapshot); @@ -59,8 +58,8 @@ } @Override - public ValueNode getLastLocationAccess(LocationIdentity locationIdentity) { - ValueNode lastLocationAccess; + public MemoryNode getLastLocationAccess(LocationIdentity locationIdentity) { + MemoryNode lastLocationAccess; if (locationIdentity == FINAL_LOCATION) { return null; } else { @@ -198,7 +197,7 @@ private static void processAccess(MemoryAccess access, MemoryMapImpl state) { LocationIdentity locationIdentity = access.getLocationIdentity(); if (locationIdentity != LocationIdentity.ANY_LOCATION) { - ValueNode lastLocationAccess = state.getLastLocationAccess(locationIdentity); + MemoryNode lastLocationAccess = state.getLastLocationAccess(locationIdentity); access.setLastLocationAccess(lastLocationAccess); } } @@ -217,7 +216,7 @@ if (identity == ANY_LOCATION) { state.lastMemorySnapshot.clear(); } - state.lastMemorySnapshot.put(identity, (ValueNode) checkpoint); + state.lastMemorySnapshot.put(identity, checkpoint); } private static void processFloatable(FloatableAccessNode accessNode, MemoryMapImpl state) { @@ -225,7 +224,7 @@ assert accessNode.getNullCheck() == false; LocationIdentity locationIdentity = accessNode.location().getLocationIdentity(); if (accessNode.canFloat()) { - ValueNode lastLocationAccess = state.getLastLocationAccess(locationIdentity); + MemoryNode lastLocationAccess = state.getLastLocationAccess(locationIdentity); FloatingAccessNode floatingNode = accessNode.asFloatingNode(lastLocationAccess); floatingNode.setNullCheck(accessNode.getNullCheck()); ValueAnchorNode anchor = null; @@ -251,22 +250,22 @@ for (LocationIdentity key : keys) { int mergedStatesCount = 0; boolean isPhi = false; - ValueNode merged = null; + MemoryNode merged = null; for (MemoryMapImpl state : states) { - ValueNode last = state.getLastLocationAccess(key); + MemoryNode last = state.getLastLocationAccess(key); if (isPhi) { - ((PhiNode) merged).addInput(last); + merged.asMemoryPhi().addInput(ValueNodeUtil.asNode(last)); } else { if (merged == last) { // nothing to do } else if (merged == null) { merged = last; } else { - PhiNode phi = merge.graph().addWithoutUnique(new PhiNode(PhiType.Memory, merge, key)); + MemoryPhiNode phi = merge.graph().addWithoutUnique(new MemoryPhiNode(merge, key)); for (int j = 0; j < mergedStatesCount; j++) { - phi.addInput(merged); + phi.addInput(ValueNodeUtil.asNode(merged)); } - phi.addInput(last); + phi.addInput(ValueNodeUtil.asNode(last)); merged = phi; isPhi = true; } @@ -290,7 +289,7 @@ * side it needs to choose by putting in the location identity on both successors. */ InvokeWithExceptionNode invoke = (InvokeWithExceptionNode) node.predecessor(); - result.lastMemorySnapshot.put(invoke.getLocationIdentity(), node); + result.lastMemorySnapshot.put(invoke.getLocationIdentity(), (MemoryCheckpoint) node); } return result; } @@ -306,8 +305,8 @@ Map phis = new HashMap<>(); for (LocationIdentity location : modifiedLocations) { - PhiNode phi = loop.graph().addWithoutUnique(new PhiNode(PhiType.Memory, loop, location)); - phi.addInput(initialState.getLastLocationAccess(location)); + MemoryPhiNode phi = loop.graph().addWithoutUnique(new MemoryPhiNode(loop, location)); + phi.addInput(ValueNodeUtil.asNode(initialState.getLastLocationAccess(location))); phis.put(location, phi); initialState.lastMemorySnapshot.put(location, phi); } @@ -319,16 +318,16 @@ for (Map.Entry phiEntry : phis.entrySet()) { LocationIdentity key = phiEntry.getKey(); PhiNode phi = phiEntry.getValue(); - phi.initializeValueAt(endIndex, entry.getValue().getLastLocationAccess(key)); + phi.initializeValueAt(endIndex, ValueNodeUtil.asNode(entry.getValue().getLastLocationAccess(key))); } } for (Map.Entry entry : loopInfo.exitStates.entrySet()) { LoopExitNode exit = entry.getKey(); MemoryMapImpl state = entry.getValue(); for (LocationIdentity location : modifiedLocations) { - ValueNode lastAccessAtExit = state.lastMemorySnapshot.get(location); + MemoryNode lastAccessAtExit = state.lastMemorySnapshot.get(location); if (lastAccessAtExit != null) { - state.lastMemorySnapshot.put(location, ProxyNode.forMemory(lastAccessAtExit, exit, location, loop.graph())); + state.lastMemorySnapshot.put(location, MemoryProxyNode.forMemory(lastAccessAtExit, exit, location, loop.graph())); } } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Sat Nov 30 19:05:44 2013 +0100 @@ -142,8 +142,9 @@ protected void processNode(Node node) { if (node instanceof GuardNode) { GuardNode guard = (GuardNode) node; - if (guard.negated() && guard.condition() instanceof IsNullNode) { - lowerToNullCheck(guard); + FixedWithNextNode lowered = guard.lowerGuard(); + if (lowered != null) { + replaceCurrent(lowered); } else { lowerToIf(guard); } @@ -171,15 +172,6 @@ insert(ifNode, fastPath); } - private void lowerToNullCheck(GuardNode guard) { - IsNullNode isNull = (IsNullNode) guard.condition(); - NullCheckNode nullCheck = guard.graph().add(new NullCheckNode(isNull.object())); - replaceCurrent(nullCheck); - if (isNull.usages().isEmpty()) { - isNull.safeDelete(); - } - } - private void insertLoopExits(DeoptimizeNode deopt) { Loop loop = block.getLoop(); StructuredGraph graph = deopt.graph(); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Sat Nov 30 19:05:44 2013 +0100 @@ -26,11 +26,11 @@ import static com.oracle.graal.phases.common.InliningPhase.Options.*; import java.util.*; -import java.util.concurrent.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Graph.Mark; import com.oracle.graal.nodes.*; @@ -47,6 +47,7 @@ import com.oracle.graal.phases.common.InliningUtil.InliningPolicy; import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.phases.util.*; public class InliningPhase extends AbstractInliningPhase { @@ -123,14 +124,11 @@ if (currentInvocation.processedGraphs() == currentInvocation.totalGraphs()) { data.popInvocation(); final MethodInvocation parentInvoke = data.currentInvocation(); - Debug.scope("Inlining", data.inliningContext(), new Runnable() { - - @Override - public void run() { - tryToInline(data.currentGraph(), currentInvocation, parentInvoke, data.inliningDepth() + 1, context); - } - }); - + try (Scope s = Debug.scope("Inlining", data.inliningContext())) { + tryToInline(data.currentGraph(), currentInvocation, parentInvoke, data.inliningDepth() + 1, context); + } catch (Throwable e) { + throw Debug.handle(e); + } } } } @@ -185,7 +183,7 @@ InlineInfo callee = calleeInfo.callee(); try { List invokeUsages = callee.invoke().asNode().usages().snapshot(); - callee.inline(context, callerAssumptions); + callee.inline(new Providers(context), callerAssumptions); callerAssumptions.record(calleeInfo.assumptions()); metricInliningRuns.increment(); Debug.dump(callerGraph, "after %s", callee); @@ -245,44 +243,42 @@ } } - return Debug.scope("InlineGraph", newGraph, new Callable() { - - @Override - public StructuredGraph call() throws Exception { - if (parseBytecodes) { - parseBytecodes(newGraph, context); - } + try (Scope s = Debug.scope("InlineGraph", newGraph)) { + if (parseBytecodes) { + parseBytecodes(newGraph, context); + } - boolean callerHasMoreInformationAboutArguments = false; - NodeInputList args = invoke.callTarget().arguments(); - for (LocalNode localNode : newGraph.getNodes(LocalNode.class).snapshot()) { - ValueNode arg = args.get(localNode.index()); - if (arg.isConstant()) { - Constant constant = arg.asConstant(); - newGraph.replaceFloating(localNode, ConstantNode.forConstant(constant, context.getMetaAccess(), newGraph)); + boolean callerHasMoreInformationAboutArguments = false; + NodeInputList args = invoke.callTarget().arguments(); + for (LocalNode localNode : newGraph.getNodes(LocalNode.class).snapshot()) { + ValueNode arg = args.get(localNode.index()); + if (arg.isConstant()) { + Constant constant = arg.asConstant(); + newGraph.replaceFloating(localNode, ConstantNode.forConstant(constant, context.getMetaAccess(), newGraph)); + callerHasMoreInformationAboutArguments = true; + } else { + Stamp joinedStamp = localNode.stamp().join(arg.stamp()); + if (joinedStamp != null && !joinedStamp.equals(localNode.stamp())) { + localNode.setStamp(joinedStamp); callerHasMoreInformationAboutArguments = true; - } else { - Stamp joinedStamp = localNode.stamp().join(arg.stamp()); - if (joinedStamp != null && !joinedStamp.equals(localNode.stamp())) { - localNode.setStamp(joinedStamp); - callerHasMoreInformationAboutArguments = true; - } } } + } - if (!callerHasMoreInformationAboutArguments) { - // TODO (chaeubl): if args are not more concrete, inlining should be avoided - // in most cases or we could at least use the previous graph size + invoke - // probability to check the inlining - } + if (!callerHasMoreInformationAboutArguments) { + // TODO (chaeubl): if args are not more concrete, inlining should be avoided + // in most cases or we could at least use the previous graph size + invoke + // probability to check the inlining + } - if (OptCanonicalizer.getValue()) { - canonicalizer.apply(newGraph, context); - } + if (OptCanonicalizer.getValue()) { + canonicalizer.apply(newGraph, context); + } - return newGraph; - } - }); + return newGraph; + } catch (Throwable e) { + throw Debug.handle(e); + } } private static StructuredGraph getCachedGraph(ResolvedJavaMethod method, HighTierContext context) { diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Sat Nov 30 19:05:44 2013 +0100 @@ -26,10 +26,10 @@ import static com.oracle.graal.api.meta.DeoptimizationReason.*; import static com.oracle.graal.nodes.type.StampFactory.*; import static com.oracle.graal.phases.GraalOptions.*; +import static java.lang.reflect.Modifier.*; import java.lang.reflect.*; import java.util.*; -import java.util.concurrent.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.Assumptions.Assumption; @@ -37,6 +37,7 @@ import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType; import com.oracle.graal.api.meta.ResolvedJavaType.Representation; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Graph.DuplicationReplacement; import com.oracle.graal.graph.Node.ValueNumberable; @@ -172,12 +173,9 @@ } public static void logInliningDecision(final String msg, final Object... args) { - Debug.scope(inliningDecisionsScopeString, new Runnable() { - - public void run() { - Debug.log(msg, args); - } - }); + try (Scope s = Debug.scope(inliningDecisionsScopeString)) { + Debug.log(msg, args); + } } private static boolean logNotInlinedMethod(Invoke invoke, String msg) { @@ -219,12 +217,9 @@ } public static boolean shouldLogInliningDecision() { - return Debug.scope(inliningDecisionsScopeString, new Callable() { - - public Boolean call() { - return Debug.isLogEnabled(); - } - }); + try (Scope s = Debug.scope(inliningDecisionsScopeString)) { + return Debug.isLogEnabled(); + } } private static String methodName(ResolvedJavaMethod method, Invoke invoke) { @@ -434,6 +429,7 @@ super(invoke); this.concrete = concrete; this.type = type; + assert type.isArray() || !isAbstract(type.getModifiers()) : type; } @Override @@ -1137,6 +1133,7 @@ } ResolvedJavaType type = ptypes[0].getType(); + assert type.isArray() || !isAbstract(type.getModifiers()); ResolvedJavaMethod concrete = type.resolveMethod(targetMethod); if (!checkTargetConditions(data, replacements, invoke, concrete, optimisticOpts)) { return null; @@ -1208,6 +1205,7 @@ if (index == -1) { notRecordedTypeProbability += type.getProbability(); } else { + assert type.getType().isArray() || !isAbstract(type.getType().getModifiers()) : type + " " + concrete; usedTypes.add(type); typesToConcretes.add(index); } @@ -1438,7 +1436,7 @@ if (!returnValue.isExternal()) { returnValue = duplicates.get(returnValue); } else if (returnValue instanceof ValueNumberable) { - returnValue = graph.uniqueWithoutAdd(returnValue); + returnValue = graph.uniqueExternal(returnValue); } } invoke.asNode().replaceAtUsages(returnValue); @@ -1502,12 +1500,7 @@ InliningUtil.replaceInvokeCallTarget(invoke, graph, InvokeKind.Special, concrete); } - FixedWithNextNode macroNode; - try { - macroNode = macroNodeClass.getConstructor(Invoke.class).newInstance(invoke); - } catch (ReflectiveOperationException | IllegalArgumentException | SecurityException e) { - throw new GraalInternalError(e).addContext(invoke.asNode()).addContext("macroSubstitution", macroNodeClass); - } + FixedWithNextNode macroNode = createMacroNodeInstance(macroNodeClass, invoke); CallTargetNode callTarget = invoke.callTarget(); if (invoke instanceof InvokeNode) { @@ -1520,4 +1513,12 @@ GraphUtil.killWithUnusedFloatingInputs(callTarget); return macroNode; } + + private static FixedWithNextNode createMacroNodeInstance(Class macroNodeClass, Invoke invoke) throws GraalInternalError { + try { + return macroNodeClass.getConstructor(Invoke.class).newInstance(invoke); + } catch (ReflectiveOperationException | IllegalArgumentException | SecurityException e) { + throw new GraalInternalError(e).addContext(invoke.asNode()).addContext("macroSubstitution", macroNodeClass); + } + } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Sat Nov 30 19:05:44 2013 +0100 @@ -64,11 +64,6 @@ } @Override - public CodeCacheProvider getCodeCache() { - return context.getCodeCache(); - } - - @Override public ConstantReflectionProvider getConstantReflection() { return context.getConstantReflection(); } @@ -79,11 +74,6 @@ } @Override - public ForeignCallsProvider getForeignCalls() { - return context.getForeignCalls(); - } - - @Override public LoweringProvider getLowerer() { return context.getLowerer(); } @@ -178,7 +168,7 @@ Mark expectedMark = graph.getMark(); lower(graph, context, 1); Mark mark = graph.getMark(); - assert mark.equals(expectedMark) : graph + ": a second round in the current lowering phase introduced these new nodes: " + graph.getNewNodes(mark).snapshot(); + assert mark.equals(expectedMark) : graph + ": a second round in the current lowering phase introduced these new nodes: " + graph.getNewNodes(expectedMark).snapshot(); return true; } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchors.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchors.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/OptimizeGuardAnchors.java Sat Nov 30 19:05:44 2013 +0100 @@ -72,7 +72,7 @@ } } for (ControlSplitNode controlSplit : graph.getNodes(ControlSplitNode.class)) { - otpimizeAtControlSplit(controlSplit, cfg); + optimizeAtControlSplit(controlSplit, cfg); } } @@ -84,7 +84,7 @@ return anchor.getBeginNode(); } - private static void otpimizeAtControlSplit(ControlSplitNode controlSplit, LazyCFG cfg) { + private static void optimizeAtControlSplit(ControlSplitNode controlSplit, LazyCFG cfg) { AbstractBeginNode successor = findMinimumUsagesSuccessor(controlSplit); int successorCount = controlSplit.successors().count(); List otherGuards = new ArrayList<>(successorCount - 1); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ReadEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ReadEliminationPhase.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ReadEliminationPhase.java Sat Nov 30 19:05:44 2013 +0100 @@ -46,24 +46,24 @@ return isWrites(n, n.getLastLocationAccess(), n.graph().createNodeBitMap()); } - private static boolean isWrites(FloatingReadNode n, Node lastLocationAccess, NodeBitMap visited) { + private static boolean isWrites(FloatingReadNode n, MemoryNode lastLocationAccess, NodeBitMap visited) { if (lastLocationAccess == null) { return false; } - if (visited.isMarked(lastLocationAccess)) { + if (visited.isMarked(ValueNodeUtil.asNode(lastLocationAccess))) { return true; // dataflow loops must come from Phis assume them ok until proven wrong } if (lastLocationAccess instanceof ProxyNode) { - return isWrites(n, ((ProxyNode) lastLocationAccess).value(), visited); + return isWrites(n, (MemoryNode) ((ProxyNode) lastLocationAccess).value(), visited); } if (lastLocationAccess instanceof WriteNode) { WriteNode other = (WriteNode) lastLocationAccess; return other.object() == n.object() && other.location() == n.location(); } if (lastLocationAccess instanceof PhiNode) { - visited.mark(lastLocationAccess); + visited.mark(ValueNodeUtil.asNode(lastLocationAccess)); for (ValueNode value : ((PhiNode) lastLocationAccess).values()) { - if (!isWrites(n, value, visited)) { + if (!isWrites(n, (MemoryNode) value, visited)) { return false; } } @@ -72,15 +72,15 @@ return false; } - private static ValueNode getValue(FloatingReadNode n, Node lastLocationAccess, NodeMap nodeMap) { - ValueNode exisiting = nodeMap.get(lastLocationAccess); + private static ValueNode getValue(FloatingReadNode n, MemoryNode lastLocationAccess, NodeMap nodeMap) { + ValueNode exisiting = nodeMap.get(ValueNodeUtil.asNode(lastLocationAccess)); if (exisiting != null) { return exisiting; } - if (lastLocationAccess instanceof ProxyNode) { - ProxyNode proxy = (ProxyNode) lastLocationAccess; - ValueNode value = getValue(n, proxy.value(), nodeMap); - return ProxyNode.forValue(value, proxy.proxyPoint(), (StructuredGraph) lastLocationAccess.graph()); + if (lastLocationAccess instanceof MemoryProxyNode) { + MemoryProxyNode proxy = (MemoryProxyNode) lastLocationAccess; + ValueNode value = getValue(n, proxy.getOriginalMemoryNode(), nodeMap); + return ProxyNode.forValue(value, proxy.proxyPoint(), proxy.graph()); } if (lastLocationAccess instanceof WriteNode) { return ((WriteNode) lastLocationAccess).value(); @@ -88,9 +88,9 @@ if (lastLocationAccess instanceof PhiNode) { PhiNode phi = (PhiNode) lastLocationAccess; PhiNode newPhi = phi.graph().addWithoutUnique(new PhiNode(n.kind(), phi.merge())); - nodeMap.set(lastLocationAccess, newPhi); + nodeMap.set(phi, newPhi); for (ValueNode value : phi.values()) { - newPhi.addInput(getValue(n, value, nodeMap)); + newPhi.addInput(getValue(n, (MemoryNode) value, nodeMap)); } return newPhi; } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Sat Nov 30 19:05:44 2013 +0100 @@ -25,6 +25,7 @@ import java.util.regex.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.debug.internal.*; import com.oracle.graal.nodes.*; @@ -75,19 +76,15 @@ } public final void apply(final StructuredGraph graph, final C context, final boolean dumpGraph) { - try (TimerCloseable a = phaseTimer.start()) { - - Debug.scope(name, this, new Runnable() { - - public void run() { - BasePhase.this.run(graph, context); - phaseMetric.increment(); - if (dumpGraph) { - Debug.dump(graph, "After phase %s", name); - } - assert graph.verify(); - } - }); + try (TimerCloseable a = phaseTimer.start(); Scope s = Debug.scope(name, this)) { + BasePhase.this.run(graph, context); + phaseMetric.increment(); + if (dumpGraph) { + Debug.dump(graph, "After phase %s", name); + } + assert graph.verify(); + } catch (Throwable t) { + throw Debug.handle(t); } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Sat Nov 30 19:05:44 2013 +0100 @@ -148,9 +148,9 @@ public static final OptionValue PrintBinaryGraphs = new OptionValue<>(true); @Option(help = "Output probabilities for fixed nodes during binary graph dumping") public static final OptionValue PrintGraphProbabilities = new OptionValue<>(false); - @Option(help = "Enables dumping to the C1Visualizer. Enabling this option implies PrintBackendCFG.") + @Option(help = "Enable dumping to the C1Visualizer. Enabling this option implies PrintBackendCFG.") public static final OptionValue PrintCFG = new OptionValue<>(false); - @Option(help = "Enables dumping LIR, register allocation and code generation info to the C1Visualizer.") + @Option(help = "Enable dumping LIR, register allocation and code generation info to the C1Visualizer.") public static final OptionValue PrintBackendCFG = new OptionValue<>(true); @Option(help = "") public static final OptionValue PrintIdealGraphFile = new OptionValue<>(false); @@ -166,7 +166,7 @@ public static final OptionValue PrintCompilation = new OptionValue<>(false); @Option(help = "") public static final OptionValue PrintAfterCompilation = new OptionValue<>(false); - @Option(help = "") + @Option(help = "Print profiling information when parsing a method's bytecode") public static final OptionValue PrintProfilingInformation = new OptionValue<>(false); @Option(help = "") public static final OptionValue PrintCodeBytes = new OptionValue<>(false); @@ -180,7 +180,7 @@ public static final OptionValue ExitVMOnException = new OptionValue<>(true); @Option(help = "") public static final OptionValue PrintStackTraceOnException = new OptionValue<>(false); - @Option(help = "Sets a phase after which the decompiler dumps the graph, -G:Dump= required") + @Option(help = "Set a phase after which the decompiler dumps the graph, -G:Dump= required") public static final OptionValue DecompileAfterPhase = new OptionValue<>(null); // HotSpot command line options @@ -258,7 +258,9 @@ @Option(help = "") public static final OptionValue OptCanonicalizer = new OptionValue<>(true); @Option(help = "") - public static final OptionValue OptScheduleOutOfLoops = new OptionValue<>(true); + public static final OptionValue OptDeoptimizationGrouping = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue OptScheduleOutOfLoops = new OptionValue<>(true); @Option(help = "") public static final OptionValue OptEliminateGuards = new OptionValue<>(true); @Option(help = "") diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Sat Nov 30 19:05:44 2013 +0100 @@ -33,7 +33,6 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.Verbosity; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.extended.*; @@ -286,14 +285,12 @@ KillSet excludedLocations = new KillSet(); if (block.getBeginNode() instanceof MergeNode) { MergeNode mergeNode = (MergeNode) block.getBeginNode(); - for (PhiNode phi : mergeNode.usages().filter(PhiNode.class)) { - if (phi.type() == PhiType.Memory) { - if (foundExcludeNode) { - set.add(phi.getIdentity()); - } else { - excludedLocations.add(phi.getIdentity()); - foundExcludeNode = phi == excludeNode; - } + for (MemoryPhiNode phi : mergeNode.usages().filter(MemoryPhiNode.class)) { + if (foundExcludeNode) { + set.add(phi.getLocationIdentity()); + } else { + excludedLocations.add(phi.getLocationIdentity()); + foundExcludeNode = phi == excludeNode; } } } @@ -403,8 +400,12 @@ } } - private Block blockForFixedNode(Node n) { - Block b = cfg.getNodeToBlock().get(n); + private Block blockForMemoryNode(MemoryNode memory) { + MemoryNode current = memory; + while (current instanceof MemoryProxy) { + current = ((MemoryProxy) current).getOriginalMemoryNode(); + } + Block b = cfg.getNodeToBlock().get(current.asNode()); assert b != null : "all lastAccess locations should have a block assignment from CFG"; return b; } @@ -546,13 +547,11 @@ if (assertionEnabled()) { if (scheduleRead) { FloatingReadNode read = (FloatingReadNode) node; - Node lastLocationAccess = read.getLastLocationAccess(); - Block upperBound = blockForFixedNode(lastLocationAccess); - if (!blockForFixedNode(lastLocationAccess).dominates(block)) { - assert false : String.format("out of loop movement voilated memory semantics for %s (location %s). moved to %s but upper bound is %s (earliest: %s, latest: %s)", read, - read.getLocationIdentity(), block, upperBound, earliestBlock, latest); - } - + MemoryNode lastLocationAccess = read.getLastLocationAccess(); + Block upperBound = blockForMemoryNode(lastLocationAccess); + assert upperBound.dominates(block) : String.format( + "out of loop movement voilated memory semantics for %s (location %s). moved to %s but upper bound is %s (earliest: %s, latest: %s)", read, + read.getLocationIdentity(), block, upperBound, earliestBlock, latest); } } break; @@ -599,7 +598,7 @@ LocationIdentity locid = n.location().getLocationIdentity(); assert locid != FINAL_LOCATION; - Block upperBoundBlock = blockForFixedNode(n.getLastLocationAccess()); + Block upperBoundBlock = blockForMemoryNode(n.getLastLocationAccess()); Block earliestBlock = earliestBlock(n); assert upperBoundBlock.dominates(earliestBlock) : "upper bound (" + upperBoundBlock + ") should dominate earliest (" + earliestBlock + ")"; @@ -630,7 +629,7 @@ if (currentBlock == upperBoundBlock) { assert earliestBlock == upperBoundBlock; // don't treat lastLocationAccess node as a kill for this read. - closure = new NewMemoryScheduleClosure(n.getLastLocationAccess(), upperBoundBlock); + closure = new NewMemoryScheduleClosure(ValueNodeUtil.asNode(n.getLastLocationAccess()), upperBoundBlock); } else { closure = new NewMemoryScheduleClosure(); } @@ -646,7 +645,7 @@ } else { if (currentBlock == upperBoundBlock) { assert earliestBlock == upperBoundBlock; - KillSet ks = computeKillSet(upperBoundBlock, n.getLastLocationAccess()); + KillSet ks = computeKillSet(upperBoundBlock, ValueNodeUtil.asNode(n.getLastLocationAccess())); if (ks.isKilled(locid)) { return upperBoundBlock; } diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java Sat Nov 30 19:05:44 2013 +0100 @@ -23,6 +23,7 @@ package com.oracle.graal.phases.tiers; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.util.*; @@ -34,13 +35,18 @@ private final GraphCache cache; private final OptimisticOptimizations optimisticOpts; - public HighTierContext(Providers copyFrom, Assumptions assumptions, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts) { - super(copyFrom, assumptions); + public HighTierContext(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, LoweringProvider lowerer, Replacements replacements, Assumptions assumptions, + GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts) { + super(metaAccess, constantReflection, lowerer, replacements, assumptions); this.plan = plan; this.cache = cache; this.optimisticOpts = optimisticOpts; } + public HighTierContext(Providers providers, Assumptions assumptions, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts) { + this(providers.getMetaAccess(), providers.getConstantReflection(), providers.getLowerer(), providers.getReplacements(), assumptions, cache, plan, optimisticOpts); + } + public PhasePlan getPhasePlan() { return plan; } @@ -54,6 +60,6 @@ } public HighTierContext replaceAssumptions(Assumptions newAssumptions) { - return new HighTierContext(this, newAssumptions, getGraphCache(), getPhasePlan(), getOptimisticOptimizations()); + return new HighTierContext(getMetaAccess(), getConstantReflection(), getLowerer(), getReplacements(), newAssumptions, getGraphCache(), getPhasePlan(), getOptimisticOptimizations()); } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/PhaseContext.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/PhaseContext.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/PhaseContext.java Sat Nov 30 19:05:44 2013 +0100 @@ -27,19 +27,40 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.util.*; -public class PhaseContext extends Providers { +public class PhaseContext { + private final MetaAccessProvider metaAccess; + private final ConstantReflectionProvider constantReflection; + private final LoweringProvider lowerer; + private final Replacements replacements; private final Assumptions assumptions; - public PhaseContext(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, ForeignCallsProvider foreignCalls, LoweringProvider lowerer, - Assumptions assumptions, Replacements replacements) { - super(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, replacements); + public PhaseContext(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, LoweringProvider lowerer, Replacements replacements, Assumptions assumptions) { + this.metaAccess = metaAccess; + this.constantReflection = constantReflection; + this.lowerer = lowerer; + this.replacements = replacements; this.assumptions = assumptions; } - public PhaseContext(Providers copyFrom, Assumptions assumptions) { - super(copyFrom); - this.assumptions = assumptions; + public PhaseContext(Providers providers, Assumptions assumptions) { + this(providers.getMetaAccess(), providers.getConstantReflection(), providers.getLowerer(), providers.getReplacements(), assumptions); + } + + public MetaAccessProvider getMetaAccess() { + return metaAccess; + } + + public ConstantReflectionProvider getConstantReflection() { + return constantReflection; + } + + public LoweringProvider getLowerer() { + return lowerer; + } + + public Replacements getReplacements() { + return replacements; } public Assumptions getAssumptions() { diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/Providers.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/Providers.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/Providers.java Sat Nov 30 19:05:44 2013 +0100 @@ -25,6 +25,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.phases.tiers.*; /** * A set of providers, some of which may not be present (i.e., null). @@ -49,12 +50,11 @@ } public Providers(Providers copyFrom) { - this.metaAccess = copyFrom.metaAccess; - this.codeCache = copyFrom.codeCache; - this.constantReflection = copyFrom.constantReflection; - this.foreignCalls = copyFrom.foreignCalls; - this.lowerer = copyFrom.lowerer; - this.replacements = copyFrom.replacements; + this(copyFrom.getMetaAccess(), copyFrom.getCodeCache(), copyFrom.getConstantReflection(), copyFrom.getForeignCalls(), copyFrom.getLowerer(), copyFrom.getReplacements()); + } + + public Providers(PhaseContext copyFrom) { + this(copyFrom.getMetaAccess(), null, copyFrom.getConstantReflection(), null, copyFrom.getLowerer(), copyFrom.getReplacements()); } public MetaAccessProvider getMetaAccess() { diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BasicIdealGraphPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BasicIdealGraphPrinter.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BasicIdealGraphPrinter.java Sat Nov 30 19:05:44 2013 +0100 @@ -23,6 +23,7 @@ package com.oracle.graal.printer; import java.io.*; +import java.nio.charset.*; import java.util.*; import java.util.Map.Entry; @@ -90,7 +91,7 @@ } else { buffered = new BufferedOutputStream(stream, 256 * 1024); } - this.stream = new PrintStream(buffered, false, "US-ASCII"); + this.stream = new PrintStream(buffered, false, Charset.defaultCharset().name()); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DecompilerDebugDumpHandler.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DecompilerDebugDumpHandler.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DecompilerDebugDumpHandler.java Sat Nov 30 19:05:44 2013 +0100 @@ -22,12 +22,13 @@ */ package com.oracle.graal.printer; +import static com.oracle.graal.phases.GraalOptions.*; + import java.io.*; import java.util.concurrent.atomic.*; -import static com.oracle.graal.phases.GraalOptions.*; - import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.java.decompiler.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.schedule.*; @@ -69,18 +70,15 @@ final String currentScope = Debug.currentScope(); if (currentScope.endsWith(filter) && graph.method() != null) { final String methodName = graph.method().getName(); - Debug.sandbox("Printing Decompiler Output", null, new Runnable() { - - @Override - public void run() { - printStream.println(); - printStream.println("Object: " + methodName); - printStream.println("Message: " + message); - new Decompiler(graph, getPredefinedSchedule(), printStream, infoPrintStream, currentScope).decompile(); - printStream.flush(); - } - }); - + try (Scope s = Debug.sandbox("Printing Decompiler Output", null)) { + printStream.println(); + printStream.println("Object: " + methodName); + printStream.println("Message: " + message); + new Decompiler(graph, getPredefinedSchedule(), printStream, infoPrintStream, currentScope).decompile(); + printStream.flush(); + } catch (Throwable e) { + throw Debug.handle(e); + } } } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java Sat Nov 30 19:05:44 2013 +0100 @@ -34,6 +34,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.phases.schedule.*; @@ -44,7 +45,7 @@ */ public class GraphPrinterDumpHandler implements DebugDumpHandler { - private GraphPrinter printer; + protected GraphPrinter printer; private List previousInlineContext; private int[] dumpIds = {}; private int failuresCount; @@ -62,11 +63,15 @@ return; } previousInlineContext.clear(); - if (PrintIdealGraphFile.getValue()) { - initializeFilePrinter(); - } else { - initializeNetworkPrinter(); - } + createPrinter(); + } + } + + protected void createPrinter() { + if (PrintIdealGraphFile.getValue()) { + initializeFilePrinter(); + } else { + initializeNetworkPrinter(); } } @@ -172,19 +177,15 @@ previousInlineContext = inlineContext; final SchedulePhase predefinedSchedule = getPredefinedSchedule(); - Debug.sandbox("PrintingGraph", null, new Runnable() { - - @Override - public void run() { - // Finally, output the graph. - try { - printer.print(graph, nextDumpId() + ":" + message, predefinedSchedule); - } catch (IOException e) { - failuresCount++; - printer = null; - } - } - }); + try (Scope s = Debug.sandbox("PrintingGraph", null)) { + // Finally, output the graph. + printer.print(graph, nextDumpId() + ":" + message, predefinedSchedule); + } catch (IOException e) { + failuresCount++; + printer = null; + } catch (Throwable e) { + throw Debug.handle(e); + } } } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java Sat Nov 30 19:05:44 2013 +0100 @@ -40,7 +40,7 @@ * Generates a representation of {@link Graph Graphs} that can be visualized and inspected with the * Ideal Graph Visualizer. */ -class IdealGraphPrinter extends BasicIdealGraphPrinter implements GraphPrinter { +public class IdealGraphPrinter extends BasicIdealGraphPrinter implements GraphPrinter { /** * Creates a new {@link IdealGraphPrinter} that writes to the specified output stream. diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -24,12 +24,11 @@ import static org.junit.Assert.*; -import java.util.concurrent.*; - import com.oracle.graal.api.code.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; @@ -44,24 +43,22 @@ public abstract class MethodSubstitutionTest extends GraalCompilerTest { protected StructuredGraph test(final String snippet) { - return Debug.scope("MethodSubstitutionTest", getMetaAccess().lookupJavaMethod(getMethod(snippet)), new Callable() { + try (Scope s = Debug.scope("MethodSubstitutionTest", getMetaAccess().lookupJavaMethod(getMethod(snippet)))) { + StructuredGraph graph = parse(snippet); + PhasePlan phasePlan = getDefaultPhasePlan(); + Assumptions assumptions = new Assumptions(true); + HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan, OptimisticOptimizations.ALL); + Debug.dump(graph, "Graph"); + new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); + Debug.dump(graph, "Graph"); + new CanonicalizerPhase(true).apply(graph, context); + new DeadCodeEliminationPhase().apply(graph); - @Override - public StructuredGraph call() { - StructuredGraph graph = parse(snippet); - PhasePlan phasePlan = getDefaultPhasePlan(); - Assumptions assumptions = new Assumptions(true); - HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan, OptimisticOptimizations.ALL); - Debug.dump(graph, "Graph"); - new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context); - Debug.dump(graph, "Graph"); - new CanonicalizerPhase(true).apply(graph, context); - new DeadCodeEliminationPhase().apply(graph); - - assertNotInGraph(graph, Invoke.class); - return graph; - } - }); + assertNotInGraph(graph, Invoke.class); + return graph; + } catch (Throwable e) { + throw Debug.handle(e); + } } protected static StructuredGraph assertNotInGraph(StructuredGraph graph, Class clazz) { diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/NewMultiArrayTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/NewMultiArrayTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/NewMultiArrayTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -59,7 +59,7 @@ int rank = dimensions.length; ValueNode[] dimensionNodes = new ValueNode[rank]; for (int i = 0; i < rank; i++) { - dimensionNodes[i] = graph.unique(ConstantNode.forInt(dimensions[i], graph)); + dimensionNodes[i] = ConstantNode.forInt(dimensions[i], graph); } NewMultiArrayNode repl = graph.add(new NewMultiArrayNode(arrayType, dimensionNodes)); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -46,7 +46,7 @@ private final ReplacementsImpl installer; public ObjectAccessTest() { - installer = new ReplacementsImpl(getProviders(), new Assumptions(false)); + installer = new ReplacementsImpl(getProviders(), new Assumptions(false), getTarget()); } private static final ThreadLocal inliningPolicy = new ThreadLocal<>(); @@ -60,7 +60,7 @@ @Test public void testRead1() { for (Kind kind : KINDS) { - assertRead(parse("read" + kind.name() + "1"), kind, false, ID); + assertRead(parse("read" + kind.name() + "1"), kind, true, ID); } } @@ -74,14 +74,14 @@ @Test public void testRead3() { for (Kind kind : KINDS) { - assertRead(parse("read" + kind.name() + "3"), kind, false, LocationIdentity.ANY_LOCATION); + assertRead(parse("read" + kind.name() + "3"), kind, true, LocationIdentity.ANY_LOCATION); } } @Test public void testWrite1() { for (Kind kind : KINDS) { - assertWrite(parse("write" + kind.name() + "1"), kind, false, ID); + assertWrite(parse("write" + kind.name() + "1"), kind, true, ID); } } @@ -95,7 +95,7 @@ @Test public void testWrite3() { for (Kind kind : KINDS) { - assertWrite(parse("write" + kind.name() + "3"), kind, false, LocationIdentity.ANY_LOCATION); + assertWrite(parse("write" + kind.name() + "3"), kind, true, LocationIdentity.ANY_LOCATION); } } diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -52,7 +52,7 @@ public PointerTest() { target = getCodeCache().getTarget(); - installer = new ReplacementsImpl(getProviders(), new Assumptions(false)); + installer = new ReplacementsImpl(getProviders(), new Assumptions(false), getTarget()); } private static final ThreadLocal inliningPolicy = new ThreadLocal<>(); @@ -66,7 +66,7 @@ @Test public void testRead1() { for (Kind kind : KINDS) { - assertRead(parse("read" + kind.name() + "1"), kind, false, ID); + assertRead(parse("read" + kind.name() + "1"), kind, true, ID); } } @@ -80,14 +80,14 @@ @Test public void testRead3() { for (Kind kind : KINDS) { - assertRead(parse("read" + kind.name() + "3"), kind, false, LocationIdentity.ANY_LOCATION); + assertRead(parse("read" + kind.name() + "3"), kind, true, LocationIdentity.ANY_LOCATION); } } @Test public void testWrite1() { for (Kind kind : KINDS) { - assertWrite(parse("write" + kind.name() + "1"), kind, false, ID); + assertWrite(parse("write" + kind.name() + "1"), kind, true, ID); } } @@ -101,7 +101,7 @@ @Test public void testWrite3() { for (Kind kind : KINDS) { - assertWrite(parse("write" + kind.name() + "3"), kind, false, LocationIdentity.ANY_LOCATION); + assertWrite(parse("write" + kind.name() + "3"), kind, true, LocationIdentity.ANY_LOCATION); } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -41,7 +41,7 @@ private final ReplacementsImpl installer; public WordTest() { - installer = new ReplacementsImpl(getProviders(), new Assumptions(false)); + installer = new ReplacementsImpl(getProviders(), new Assumptions(false), getTarget()); } private static final ThreadLocal inliningPolicy = new ThreadLocal<>(); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Sat Nov 30 19:05:44 2013 +0100 @@ -380,7 +380,7 @@ } else if (usage instanceof ProxyNode) { ProxyNode proxy = (ProxyNode) usage; assert proxy.type() == PhiType.Value; - ProxyNode newProxy = graph.unique(new ProxyNode((ValueNode) intrinsifiedNode, proxy.proxyPoint(), PhiType.Value, proxy.getIdentity())); + ProxyNode newProxy = graph.unique(new ProxyNode((ValueNode) intrinsifiedNode, proxy.proxyPoint(), PhiType.Value)); for (Node proxyUsage : usage.usages().snapshot()) { checkCheckCastUsage(graph, newProxy, proxy, proxyUsage); } diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Sat Nov 30 19:05:44 2013 +0100 @@ -36,6 +36,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.debug.internal.*; import com.oracle.graal.graph.*; import com.oracle.graal.java.*; @@ -60,18 +61,18 @@ /** * The preprocessed replacement graphs. */ - private final ConcurrentMap graphs; + protected final ConcurrentMap graphs; // These data structures are all fully initialized during single-threaded // compiler startup and so do not need to be concurrent. - private final Map registeredMethodSubstitutions; + protected final Map registeredMethodSubstitutions; private final Map> registeredMacroSubstitutions; private final Set forcedSubstitutions; private final Map, SnippetTemplateCache> snippetTemplateCache; - public ReplacementsImpl(Providers providers, Assumptions assumptions) { + public ReplacementsImpl(Providers providers, Assumptions assumptions, TargetDescription target) { this.providers = providers.copyWith(this); - this.target = providers.getCodeCache().getTarget(); + this.target = target; this.assumptions = assumptions; this.graphs = new ConcurrentHashMap<>(); this.registeredMethodSubstitutions = new HashMap<>(); @@ -83,6 +84,7 @@ private static final boolean UseSnippetGraphCache = Boolean.parseBoolean(System.getProperty("graal.useSnippetGraphCache", "true")); private static final DebugTimer SnippetPreparationTime = Debug.timer("SnippetPreparationTime"); + @Override public StructuredGraph getSnippet(ResolvedJavaMethod method) { assert method.getAnnotation(Snippet.class) != null : "Snippet must be annotated with @" + Snippet.class.getSimpleName(); assert !Modifier.isAbstract(method.getModifiers()) && !Modifier.isNative(method.getModifiers()) : "Snippet must not be abstract or native"; @@ -102,6 +104,22 @@ return graph; } + @Override + public void registerSnippet(ResolvedJavaMethod method) { + // No initialization needed as snippet graphs are created on demand in getSnippet + } + + @Override + public void prepareSnippetCopyAfterInstantiation(StructuredGraph snippetCopy) { + + // Do deferred intrinsification of node intrinsics + + new NodeIntrinsificationPhase(providers).apply(snippetCopy); + new CanonicalizerPhase(true).apply(snippetCopy, new PhaseContext(providers, assumptions)); + NodeIntrinsificationVerificationPhase.verify(snippetCopy); + } + + @Override public StructuredGraph getMethodSubstitution(ResolvedJavaMethod original) { ResolvedJavaMethod substitute = registeredMethodSubstitutions.get(original); if (substitute == null) { @@ -148,8 +166,8 @@ throw new GraalInternalError("Substitution method must not be abstract or native: " + substituteMethod); } String originalName = originalName(substituteMethod, methodSubstitution.value()); - Class[] originalParameters = originalParameters(substituteMethod, methodSubstitution.signature(), methodSubstitution.isStatic()); - Member originalMethod = originalMethod(classSubstitution, methodSubstitution.optional(), originalName, originalParameters); + JavaSignature originalSignature = originalSignature(substituteMethod, methodSubstitution.signature(), methodSubstitution.isStatic()); + Member originalMethod = originalMethod(classSubstitution, methodSubstitution.optional(), originalName, originalSignature); if (originalMethod != null) { ResolvedJavaMethod original = registerMethodSubstitution(originalMethod, substituteMethod); if (original != null && methodSubstitution.forced() && shouldIntrinsify(original)) { @@ -159,8 +177,8 @@ } if (macroSubstitution != null) { String originalName = originalName(substituteMethod, macroSubstitution.value()); - Class[] originalParameters = originalParameters(substituteMethod, macroSubstitution.signature(), macroSubstitution.isStatic()); - Member originalMethod = originalMethod(classSubstitution, macroSubstitution.optional(), originalName, originalParameters); + JavaSignature originalSignature = originalSignature(substituteMethod, macroSubstitution.signature(), macroSubstitution.isStatic()); + Member originalMethod = originalMethod(classSubstitution, macroSubstitution.optional(), originalName, originalSignature); if (originalMethod != null) { ResolvedJavaMethod original = registerMacroSubstitution(originalMethod, macroSubstitution.macro()); if (original != null && macroSubstitution.forced() && shouldIntrinsify(original)) { @@ -187,7 +205,7 @@ } else { original = metaAccess.lookupJavaConstructor((Constructor) originalMember); } - Debug.log("substitution: " + MetaUtil.format("%H.%n(%p)", original) + " --> " + MetaUtil.format("%H.%n(%p)", substitute)); + Debug.log("substitution: " + MetaUtil.format("%H.%n(%p) %r", original) + " --> " + MetaUtil.format("%H.%n(%p) %r", substitute)); registeredMethodSubstitutions.put(original, substitute); return original; @@ -212,7 +230,15 @@ return originalJavaMethod; } - private SnippetInliningPolicy inliningPolicy(ResolvedJavaMethod method) { + private static SnippetInliningPolicy createPolicyClassInstance(Class policyClass) { + try { + return policyClass.getConstructor().newInstance(); + } catch (Exception e) { + throw new GraalInternalError(e); + } + } + + protected SnippetInliningPolicy inliningPolicy(ResolvedJavaMethod method) { Class policyClass = SnippetInliningPolicy.class; Snippet snippet = method.getAnnotation(Snippet.class); if (snippet != null) { @@ -221,11 +247,7 @@ if (policyClass == SnippetInliningPolicy.class) { return new DefaultSnippetInliningPolicy(providers.getMetaAccess()); } - try { - return policyClass.getConstructor().newInstance(); - } catch (Exception e) { - throw new GraalInternalError(e); - } + return createPolicyClassInstance(policyClass); } /** @@ -277,22 +299,20 @@ } public StructuredGraph makeGraph(final SnippetInliningPolicy policy, final boolean removeAllFrameStates) { - return Debug.scope("BuildSnippetGraph", new Object[]{method}, new Callable() { + try (Scope s = Debug.scope("BuildSnippetGraph", method)) { + StructuredGraph graph = parseGraph(method, policy); - @Override - public StructuredGraph call() throws Exception { - StructuredGraph graph = parseGraph(method, policy); + // Cannot have a finalized version of a graph in the cache + graph = graph.copy(); - // Cannot have a finalized version of a graph in the cache - graph = graph.copy(); + finalizeGraph(graph, removeAllFrameStates); - finalizeGraph(graph, removeAllFrameStates); + Debug.dump(graph, "%s: Final", method.getName()); - Debug.dump(graph, "%s: Final", method.getName()); - - return graph; - } - }); + return graph; + } catch (Throwable e) { + throw Debug.handle(e); + } } /** @@ -322,12 +342,12 @@ private StructuredGraph parseGraph(final ResolvedJavaMethod methodToParse, final SnippetInliningPolicy policy) { StructuredGraph graph = graphCache.get(methodToParse); if (graph == null) { - StructuredGraph newGraph = Debug.scope("ParseGraph", new Object[]{methodToParse}, new Callable() { - - public StructuredGraph call() throws Exception { - return buildGraph(methodToParse, policy == null ? inliningPolicy(methodToParse) : policy); - } - }); + StructuredGraph newGraph = null; + try (Scope s = Debug.scope("ParseGraph", methodToParse)) { + newGraph = buildGraph(methodToParse, policy == null ? inliningPolicy(methodToParse) : policy); + } catch (Throwable e) { + throw Debug.handle(e); + } graphCache.putIfAbsent(methodToParse, newGraph); graph = graphCache.get(methodToParse); @@ -341,21 +361,19 @@ */ protected StructuredGraph buildInitialGraph(final ResolvedJavaMethod methodToParse) { final StructuredGraph graph = new StructuredGraph(methodToParse); - Debug.scope("buildInitialGraph", graph, new Runnable() { + try (Scope s = Debug.scope("buildInitialGraph", graph)) { + MetaAccessProvider metaAccess = providers.getMetaAccess(); + ForeignCallsProvider foreignCalls = providers.getForeignCalls(); + new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph); + new WordTypeVerificationPhase(metaAccess, target.wordKind).apply(graph); + new WordTypeRewriterPhase(metaAccess, target.wordKind).apply(graph); - @Override - public void run() { - MetaAccessProvider metaAccess = providers.getMetaAccess(); - ForeignCallsProvider foreignCalls = providers.getForeignCalls(); - new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph); - new WordTypeVerificationPhase(metaAccess, target.wordKind).apply(graph); - new WordTypeRewriterPhase(metaAccess, target.wordKind).apply(graph); - - if (OptCanonicalizer.getValue()) { - new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions)); - } + if (OptCanonicalizer.getValue()) { + new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions)); } - }); + } catch (Throwable e) { + throw Debug.handle(e); + } return graph; } @@ -390,57 +408,56 @@ private StructuredGraph buildGraph(final ResolvedJavaMethod methodToParse, final SnippetInliningPolicy policy) { assert !Modifier.isAbstract(methodToParse.getModifiers()) && !Modifier.isNative(methodToParse.getModifiers()) : methodToParse; final StructuredGraph graph = buildInitialGraph(methodToParse); - Debug.scope("buildGraph", graph, new Runnable() { + try (Scope s = Debug.scope("buildGraph", graph)) { + + for (MethodCallTargetNode callTarget : graph.getNodes(MethodCallTargetNode.class)) { + ResolvedJavaMethod callee = callTarget.targetMethod(); + if (callee == method) { + final StructuredGraph originalGraph = new StructuredGraph(original); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + ForeignCallsProvider foreignCalls = providers.getForeignCalls(); + new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(originalGraph); + new WordTypeVerificationPhase(metaAccess, target.wordKind).apply(graph); + new WordTypeRewriterPhase(metaAccess, target.wordKind).apply(graph); + + InliningUtil.inline(callTarget.invoke(), originalGraph, true); - @Override - public void run() { - for (MethodCallTargetNode callTarget : graph.getNodes(MethodCallTargetNode.class)) { - ResolvedJavaMethod callee = callTarget.targetMethod(); - if (callee == method) { - final StructuredGraph originalGraph = new StructuredGraph(original); - MetaAccessProvider metaAccess = providers.getMetaAccess(); - ForeignCallsProvider foreignCalls = providers.getForeignCalls(); - new GraphBuilderPhase(metaAccess, foreignCalls, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(originalGraph); - new WordTypeVerificationPhase(metaAccess, target.wordKind).apply(graph); - new WordTypeRewriterPhase(metaAccess, target.wordKind).apply(graph); - - InliningUtil.inline(callTarget.invoke(), originalGraph, true); - + Debug.dump(graph, "after inlining %s", callee); + afterInline(graph, originalGraph, null); + substituteCallsOriginal = true; + } else { + StructuredGraph intrinsicGraph = InliningUtil.getIntrinsicGraph(ReplacementsImpl.this, callee); + if ((callTarget.invokeKind() == InvokeKind.Static || callTarget.invokeKind() == InvokeKind.Special) && + (policy.shouldInline(callee, methodToParse) || (intrinsicGraph != null && policy.shouldUseReplacement(callee, methodToParse)))) { + StructuredGraph targetGraph; + if (intrinsicGraph != null && policy.shouldUseReplacement(callee, methodToParse)) { + targetGraph = intrinsicGraph; + } else { + if (callee.getName().startsWith("$jacoco")) { + throw new GraalInternalError("Parsing call to JaCoCo instrumentation method " + format("%H.%n(%p)", callee) + " from " + format("%H.%n(%p)", methodToParse) + + " while preparing replacement " + format("%H.%n(%p)", method) + ". Placing \"//JaCoCo Exclude\" anywhere in " + + methodToParse.getDeclaringClass().getSourceFileName() + " should fix this."); + } + targetGraph = parseGraph(callee, policy); + } + Object beforeInlineData = beforeInline(callTarget, targetGraph); + InliningUtil.inline(callTarget.invoke(), targetGraph, true); Debug.dump(graph, "after inlining %s", callee); - afterInline(graph, originalGraph, null); - substituteCallsOriginal = true; - } else { - StructuredGraph intrinsicGraph = InliningUtil.getIntrinsicGraph(ReplacementsImpl.this, callee); - if ((callTarget.invokeKind() == InvokeKind.Static || callTarget.invokeKind() == InvokeKind.Special) && - (policy.shouldInline(callee, methodToParse) || (intrinsicGraph != null && policy.shouldUseReplacement(callee, methodToParse)))) { - StructuredGraph targetGraph; - if (intrinsicGraph != null && policy.shouldUseReplacement(callee, methodToParse)) { - targetGraph = intrinsicGraph; - } else { - if (callee.getName().startsWith("$jacoco")) { - throw new GraalInternalError("Parsing call to JaCoCo instrumentation method " + format("%H.%n(%p)", callee) + " from " + format("%H.%n(%p)", methodToParse) + - " while preparing replacement " + format("%H.%n(%p)", method) + ". Placing \"//JaCoCo Exclude\" anywhere in " + - methodToParse.getDeclaringClass().getSourceFileName() + " should fix this."); - } - targetGraph = parseGraph(callee, policy); - } - Object beforeInlineData = beforeInline(callTarget, targetGraph); - InliningUtil.inline(callTarget.invoke(), targetGraph, true); - Debug.dump(graph, "after inlining %s", callee); - afterInline(graph, targetGraph, beforeInlineData); - } + afterInline(graph, targetGraph, beforeInlineData); } } + } - afterInlining(graph); + afterInlining(graph); - for (LoopEndNode end : graph.getNodes(LoopEndNode.class)) { - end.disableSafepoint(); - } + for (LoopEndNode end : graph.getNodes(LoopEndNode.class)) { + end.disableSafepoint(); + } - new DeadCodeEliminationPhase().apply(graph); - } - }); + new DeadCodeEliminationPhase().apply(graph); + } catch (Throwable e) { + throw Debug.handle(e); + } return graph; } } @@ -486,25 +503,50 @@ return dimensions == 0 ? baseClass : Array.newInstance(baseClass, new int[dimensions]).getClass(); } - private Class[] originalParameters(Method substituteMethod, String methodSubstitution, boolean isStatic) { + static class JavaSignature { + final Class returnType; + final Class[] parameters; + + public JavaSignature(Class returnType, Class[] parameters) { + this.parameters = parameters; + this.returnType = returnType; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("("); + for (int i = 0; i < parameters.length; i++) { + if (i != 0) { + sb.append(", "); + } + sb.append(parameters[i].getName()); + } + return sb.append(") ").append(returnType.getName()).toString(); + } + } + + private JavaSignature originalSignature(Method substituteMethod, String methodSubstitution, boolean isStatic) { Class[] parameters; + Class returnType; if (methodSubstitution.isEmpty()) { parameters = substituteMethod.getParameterTypes(); if (!isStatic) { assert parameters.length > 0 : "must be a static method with the 'this' object as its first parameter"; parameters = Arrays.copyOfRange(parameters, 1, parameters.length); } + returnType = substituteMethod.getReturnType(); } else { Signature signature = providers.getMetaAccess().parseMethodDescriptor(methodSubstitution); parameters = new Class[signature.getParameterCount(false)]; for (int i = 0; i < parameters.length; i++) { parameters[i] = resolveType(signature.getParameterType(i, null)); } + returnType = resolveType(signature.getReturnType(null)); } - return parameters; + return new JavaSignature(returnType, parameters); } - private static Member originalMethod(ClassSubstitution classSubstitution, boolean optional, String name, Class[] parameters) { + private static Member originalMethod(ClassSubstitution classSubstitution, boolean optional, String name, JavaSignature signature) { Class originalClass = classSubstitution.value(); if (originalClass == ClassSubstitution.class) { originalClass = resolveType(classSubstitution.className(), classSubstitution.optional()); @@ -515,9 +557,15 @@ } try { if (name.equals("")) { - return originalClass.getDeclaredConstructor(parameters); + assert signature.returnType.equals(void.class) : signature; + Constructor original = originalClass.getDeclaredConstructor(signature.parameters); + return original; } else { - return originalClass.getDeclaredMethod(name, parameters); + Method original = originalClass.getDeclaredMethod(name, signature.parameters); + if (!original.getReturnType().equals(signature.returnType)) { + throw new NoSuchMethodException(originalClass.getName() + "." + name + signature); + } + return original; } } catch (NoSuchMethodException | SecurityException e) { if (optional) { diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Sat Nov 30 19:05:44 2013 +0100 @@ -34,6 +34,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; 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.*; @@ -398,7 +399,9 @@ } } assert found != null : "did not find @" + Snippet.class.getSimpleName() + " method in " + declaringClass + (methodName == null ? "" : " named " + methodName); - return new SnippetInfo(providers.getMetaAccess().lookupJavaMethod(found)); + ResolvedJavaMethod javaMethod = providers.getMetaAccess().lookupJavaMethod(found); + providers.getReplacements().registerSnippet(javaMethod); + return new SnippetInfo(javaMethod); } /** @@ -408,17 +411,13 @@ SnippetTemplate template = UseSnippetTemplateCache ? templates.get(args.cacheKey) : null; if (template == null) { SnippetTemplates.increment(); - try (TimerCloseable a = SnippetTemplateCreationTime.start()) { - template = Debug.scope("SnippetSpecialization", args.info.method, new Callable() { - - @Override - public SnippetTemplate call() throws Exception { - return new SnippetTemplate(providers, args); - } - }); + try (TimerCloseable a = SnippetTemplateCreationTime.start(); Scope s = Debug.scope("SnippetSpecialization", args.info.method)) { + template = new SnippetTemplate(providers, args); if (UseSnippetTemplateCache) { templates.put(args.cacheKey, template); } + } catch (Throwable e) { + throw Debug.handle(e); } } return template; @@ -512,12 +511,8 @@ Debug.dump(snippetCopy, "Before specialization"); if (!nodeReplacements.isEmpty()) { - // Do deferred intrinsification of node intrinsics - new CanonicalizerPhase(true).apply(snippetCopy, phaseContext); - new NodeIntrinsificationPhase(providers).apply(snippetCopy); - new CanonicalizerPhase(true).apply(snippetCopy, phaseContext); + providers.getReplacements().prepareSnippetCopyAfterInstantiation(snippetCopy); } - NodeIntrinsificationVerificationPhase.verify(snippetCopy); // Gather the template parameters parameters = new Object[parameterCount]; @@ -585,13 +580,12 @@ // Perform lowering on the snippet snippetCopy.setGuardsStage(args.cacheKey.guardsStage); - Debug.scope("LoweringSnippetTemplate", snippetCopy, new Runnable() { - - public void run() { - PhaseContext c = new PhaseContext(providers, new Assumptions(false)); - new LoweringPhase(new CanonicalizerPhase(true)).apply(snippetCopy, c); - } - }); + try (Scope s = Debug.scope("LoweringSnippetTemplate", snippetCopy)) { + PhaseContext c = new PhaseContext(providers, new Assumptions(false)); + new LoweringPhase(new CanonicalizerPhase(true)).apply(snippetCopy, c); + } catch (Throwable e) { + throw Debug.handle(e); + } // Remove all frame states from snippet graph. Snippets must be atomic (i.e. free // of side-effects that prevent deoptimizing to a point before the snippet). @@ -856,25 +850,43 @@ */ 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, MemoryMapNode mmap) { - oldNode.replaceAtUsages(newNode); - if (mmap == null || newNode == null) { - return; - } - for (Node usage : newNode.usages().snapshot()) { - if (usage instanceof FloatingReadNode && ((FloatingReadNode) usage).getLastLocationAccess() == newNode) { - assert newNode.graph().isAfterFloatingReadPhase(); + if (mmap != null && newNode != null) { + for (Node usage : oldNode.usages().snapshot()) { + LocationIdentity identity = getLocationIdentity(usage); + if (identity != null && identity != LocationIdentity.FINAL_LOCATION) { + // lastLocationAccess points into the snippet graph. find a proper + // MemoryCheckPoint inside the snippet graph + MemoryNode lastAccess = mmap.getLastLocationAccess(identity); - // lastLocationAccess points into the snippet graph. find a proper - // MemoryCheckPoint inside the snippet graph - FloatingReadNode read = (FloatingReadNode) usage; - Node lastAccess = mmap.getLastLocationAccess(read.location().getLocationIdentity()); - - assert lastAccess != null : "no mapping found for lowerable node " + oldNode + ". (No node in the snippet kill the same location as the lowerable node?)"; - read.setLastLocationAccess(lastAccess); + assert lastAccess != null : "no mapping found for lowerable node " + oldNode + ". (No node in the snippet kill the same location as the lowerable node?)"; + if (usage instanceof MemoryAccess) { + MemoryAccess access = (MemoryAccess) usage; + if (access.getLastLocationAccess() == oldNode) { + assert newNode.graph().isAfterFloatingReadPhase(); + access.setLastLocationAccess(lastAccess); + } + } else { + assert usage instanceof MemoryProxy || usage instanceof MemoryPhiNode; + usage.replaceFirstInput(oldNode, lastAccess.asNode()); + } + } } } + oldNode.replaceAtUsages(newNode); } }; @@ -926,8 +938,8 @@ private class DuplicateMapper extends MemoryMapNode { - Map duplicates; - StartNode replaceeStart; + private final Map duplicates; + @Input private StartNode replaceeStart; public DuplicateMapper(Map duplicates, StartNode replaceeStart) { this.duplicates = duplicates; @@ -935,14 +947,14 @@ } @Override - public Node getLastLocationAccess(LocationIdentity locationIdentity) { + public MemoryNode getLastLocationAccess(LocationIdentity locationIdentity) { assert memoryMap != null : "no memory map stored for this snippet graph (snippet doesn't have a ReturnNode?)"; - Node lastLocationAccess = memoryMap.getLastLocationAccess(locationIdentity); + MemoryNode lastLocationAccess = memoryMap.getLastLocationAccess(locationIdentity); assert lastLocationAccess != null; if (lastLocationAccess instanceof StartNode) { return replaceeStart; } else { - return duplicates.get(lastLocationAccess); + return (MemoryNode) duplicates.get(ValueNodeUtil.asNode(lastLocationAccess)); } } } @@ -1005,7 +1017,7 @@ // Replace all usages of the replacee with the value returned by the snippet ValueNode returnValue = null; - if (returnNode != null) { + if (returnNode != null && !(replacee instanceof ControlSinkNode)) { if (returnNode.result() instanceof LocalNode) { returnValue = (ValueNode) replacements.get(returnNode.result()); } else if (returnNode.result() != null) { diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Sat Nov 30 19:05:44 2013 +0100 @@ -28,6 +28,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; @@ -37,7 +38,7 @@ import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; -public class MacroNode extends AbstractStateSplit implements Lowerable, MemoryCheckpoint.Single { +public class MacroNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single { @Input protected final NodeInputList arguments; @@ -96,14 +97,12 @@ */ protected StructuredGraph lowerReplacement(final StructuredGraph replacementGraph, LoweringTool tool) { replacementGraph.setGuardsStage(graph().getGuardsStage()); - final PhaseContext c = new PhaseContext(tool.getMetaAccess(), tool.getCodeCache(), tool.getConstantReflection(), tool.getForeignCalls(), tool.getLowerer(), tool.assumptions(), - tool.getReplacements()); - Debug.scope("LoweringReplacement", replacementGraph, new Runnable() { - - public void run() { - new LoweringPhase(new CanonicalizerPhase(true)).apply(replacementGraph, c); - } - }); + final PhaseContext c = new PhaseContext(tool.getMetaAccess(), tool.getConstantReflection(), tool.getLowerer(), tool.getReplacements(), tool.assumptions()); + try (Scope s = Debug.scope("LoweringReplacement", replacementGraph)) { + new LoweringPhase(new CanonicalizerPhase(true)).apply(replacementGraph, c); + } catch (Throwable e) { + throw Debug.handle(e); + } return replacementGraph; } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Sat Nov 30 19:05:44 2013 +0100 @@ -23,7 +23,6 @@ package com.oracle.graal.truffle.test; import java.util.*; -import java.util.concurrent.*; import org.junit.*; @@ -31,6 +30,7 @@ import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.test.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.java.*; import com.oracle.graal.loop.*; import com.oracle.graal.nodes.*; @@ -102,56 +102,53 @@ compilable.call(null, arguments); } while (compilable.inline()); - StructuredGraph graph = Debug.scope("TruffleCompilation", new TruffleDebugJavaMethod(compilable), new Callable() { + try (Scope s = Debug.scope("TruffleCompilation", new TruffleDebugJavaMethod(compilable))) { + + StructuredGraph resultGraph = partialEvaluator.createGraph(compilable, assumptions); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(canonicalizeReads); + PhaseContext context = new PhaseContext(getProviders(), assumptions); + + if (resultGraph.hasLoops()) { + boolean unrolled; + do { + unrolled = false; + LoopsData loopsData = new LoopsData(resultGraph); + loopsData.detectedCountedLoops(); + for (LoopEx ex : innerLoopsFirst(loopsData.countedLoops())) { + if (ex.counted().isConstantMaxTripCount()) { + long constant = ex.counted().constantMaxTripCount(); + if (constant <= UNROLL_LIMIT) { + LoopTransformations.fullUnroll(ex, context, canonicalizer); + Debug.dump(resultGraph, "After loop unrolling %d times", constant); + + canonicalizer.apply(resultGraph, context); + unrolled = true; + break; + } + } + } + } while (unrolled); + } + + new DeadCodeEliminationPhase().apply(resultGraph); + new PartialEscapePhase(true, canonicalizer).apply(resultGraph, context); + + return resultGraph; + } 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 StructuredGraph call() { - StructuredGraph resultGraph = partialEvaluator.createGraph(compilable, assumptions); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(canonicalizeReads); - PhaseContext context = new PhaseContext(getProviders(), assumptions); - - if (resultGraph.hasLoops()) { - boolean unrolled; - do { - unrolled = false; - LoopsData loopsData = new LoopsData(resultGraph); - loopsData.detectedCountedLoops(); - for (LoopEx ex : innerLoopsFirst(loopsData.countedLoops())) { - if (ex.counted().isConstantMaxTripCount()) { - long constant = ex.counted().constantMaxTripCount(); - if (constant <= UNROLL_LIMIT) { - LoopTransformations.fullUnroll(ex, context, canonicalizer); - Debug.dump(resultGraph, "After loop unrolling %d times", constant); - - canonicalizer.apply(resultGraph, context); - unrolled = true; - break; - } - } - } - } while (unrolled); - } - - new DeadCodeEliminationPhase().apply(resultGraph); - new PartialEscapePhase(true, canonicalizer).apply(resultGraph, context); - - return resultGraph; - } - - private List innerLoopsFirst(Collection loops) { - ArrayList sortedLoops = new ArrayList<>(loops); - Collections.sort(sortedLoops, new Comparator() { - - @Override - public int compare(LoopEx o1, LoopEx o2) { - return o2.lirLoop().depth - o1.lirLoop().depth; - } - }); - return sortedLoops; + public int compare(LoopEx o1, LoopEx o2) { + return o2.lirLoop().depth - o1.lirLoop().depth; } }); - - return graph; + return sortedLoops; } protected void removeFrameStates(StructuredGraph graph) { @@ -163,44 +160,42 @@ new DeadCodeEliminationPhase().apply(graph); } + @SuppressWarnings("deprecation") protected StructuredGraph parseForComparison(final String methodName) { - StructuredGraph graphResult = Debug.scope("Truffle", new DebugDumpScope("Comparison: " + methodName), new Callable() { + try (Scope s = Debug.scope("Truffle", new DebugDumpScope("Comparison: " + methodName))) { + Assumptions assumptions = new Assumptions(false); + StructuredGraph graph = parse(methodName); + PhaseContext context = new PhaseContext(getProviders(), assumptions); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); + canonicalizer.apply(graph, context); - @SuppressWarnings("deprecation") - public StructuredGraph call() { - Assumptions assumptions = new Assumptions(false); - StructuredGraph graph = parse(methodName); - PhaseContext context = new PhaseContext(getProviders(), assumptions); - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true); - canonicalizer.apply(graph, context); - - // Additional inlining. - final PhasePlan plan = new PhasePlan(); - GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getEagerDefault(), TruffleCompilerImpl.Optimizations); - plan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); - canonicalizer.addToPhasePlan(plan, context); - plan.addPhase(PhasePosition.AFTER_PARSING, new DeadCodeEliminationPhase()); + // Additional inlining. + final PhasePlan plan = new PhasePlan(); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), getForeignCalls(), GraphBuilderConfiguration.getEagerDefault(), TruffleCompilerImpl.Optimizations); + plan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); + canonicalizer.addToPhasePlan(plan, context); + plan.addPhase(PhasePosition.AFTER_PARSING, new DeadCodeEliminationPhase()); - new ConvertDeoptimizeToGuardPhase().apply(graph); - canonicalizer.apply(graph, context); - new DeadCodeEliminationPhase().apply(graph); + new ConvertDeoptimizeToGuardPhase().apply(graph); + canonicalizer.apply(graph, context); + new DeadCodeEliminationPhase().apply(graph); - HighTierContext highTierContext = new HighTierContext(getProviders(), assumptions, null, plan, OptimisticOptimizations.NONE); - InliningPhase inliningPhase = new InliningPhase(canonicalizer); - inliningPhase.apply(graph, highTierContext); - removeFrameStates(graph); + HighTierContext highTierContext = new HighTierContext(getProviders(), assumptions, null, plan, OptimisticOptimizations.NONE); + InliningPhase inliningPhase = new InliningPhase(canonicalizer); + inliningPhase.apply(graph, highTierContext); + removeFrameStates(graph); - new ConvertDeoptimizeToGuardPhase().apply(graph); - canonicalizer.apply(graph, context); - new DeadCodeEliminationPhase().apply(graph); + new ConvertDeoptimizeToGuardPhase().apply(graph); + canonicalizer.apply(graph, context); + new DeadCodeEliminationPhase().apply(graph); - new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context); - canonicalizer.apply(graph, context); - new DeadCodeEliminationPhase().apply(graph); - return graph; - } - }); - return graphResult; + new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context); + canonicalizer.apply(graph, context); + new DeadCodeEliminationPhase().apply(graph); + return graph; + } catch (Throwable e) { + throw Debug.handle(e); + } } } diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Sat Nov 30 19:05:44 2013 +0100 @@ -32,6 +32,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.debug.internal.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Graph.Mark; @@ -105,78 +106,76 @@ final StructuredGraph graph = new StructuredGraph(executeHelperMethod); - Debug.scope("createGraph", graph, new Runnable() { + try (Scope s = Debug.scope("createGraph", graph)) { + new GraphBuilderPhase(providers.getMetaAccess(), providers.getForeignCalls(), config, TruffleCompilerImpl.Optimizations).apply(graph); - @Override - public void run() { - new GraphBuilderPhase(providers.getMetaAccess(), providers.getForeignCalls(), config, TruffleCompilerImpl.Optimizations).apply(graph); + // Replace thisNode with constant. + LocalNode thisNode = graph.getLocal(0); + thisNode.replaceAndDelete(ConstantNode.forObject(node, providers.getMetaAccess(), graph)); - // Replace thisNode with constant. - LocalNode thisNode = graph.getLocal(0); - thisNode.replaceAndDelete(ConstantNode.forObject(node, providers.getMetaAccess(), graph)); + // Canonicalize / constant propagate. + PhaseContext baseContext = new PhaseContext(providers, assumptions); + canonicalizer.apply(graph, baseContext); - // Canonicalize / constant propagate. - PhaseContext baseContext = new PhaseContext(providers, assumptions); - canonicalizer.apply(graph, baseContext); + // Intrinsify methods. + new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph); - // Intrinsify methods. - new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph); + NewFrameNode newFrameNode = graph.getNodes(NewFrameNode.class).first(); + if (newFrameNode == null) { + throw GraalInternalError.shouldNotReachHere("frame not found"); + } - NewFrameNode newFrameNode = graph.getNodes(NewFrameNode.class).first(); - if (newFrameNode == null) { - throw GraalInternalError.shouldNotReachHere("frame not found"); - } + Debug.dump(graph, "Before inlining"); - Debug.dump(graph, "Before inlining"); - - // Make sure frame does not escape. - expandTree(graph, assumptions); + // Make sure frame does not escape. + expandTree(graph, assumptions); - if (Thread.interrupted()) { - return; - } + if (Thread.interrupted()) { + return graph; + } - new VerifyFrameDoesNotEscapePhase().apply(graph, false); + new VerifyFrameDoesNotEscapePhase().apply(graph, false); - if (TraceTruffleCompilationDetails.getValue() && constantReceivers != null) { - DebugHistogram histogram = Debug.createHistogram("Expanded Truffle Nodes"); - for (Constant c : constantReceivers) { - histogram.add(c.asObject().getClass().getSimpleName()); - } - new DebugHistogramAsciiPrinter(TTY.out().out()).print(histogram); + if (TraceTruffleCompilationDetails.getValue() && constantReceivers != null) { + DebugHistogram histogram = Debug.createHistogram("Expanded Truffle Nodes"); + for (Constant c : constantReceivers) { + histogram.add(c.asObject().getClass().getSimpleName()); } + new DebugHistogramAsciiPrinter(TTY.out().out()).print(histogram); + } - // Additional inlining. - final PhasePlan plan = new PhasePlan(); - canonicalizer.apply(graph, baseContext); - HighTierContext tierContext = new HighTierContext(providers, assumptions, cache, plan, OptimisticOptimizations.NONE); - - for (NeverPartOfCompilationNode neverPartOfCompilationNode : graph.getNodes(NeverPartOfCompilationNode.class)) { - Throwable exception = new VerificationError(neverPartOfCompilationNode.getMessage()); - throw GraphUtil.approxSourceException(neverPartOfCompilationNode, exception); - } + // Additional inlining. + final PhasePlan plan = new PhasePlan(); + canonicalizer.apply(graph, baseContext); + HighTierContext tierContext = new HighTierContext(providers, assumptions, cache, plan, OptimisticOptimizations.NONE); - // EA frame and clean up. - new PartialEscapePhase(true, canonicalizer).apply(graph, tierContext); - new VerifyNoIntrinsicsLeftPhase().apply(graph, false); - for (MaterializeFrameNode materializeNode : graph.getNodes(MaterializeFrameNode.class).snapshot()) { - materializeNode.replaceAtUsages(materializeNode.getFrame()); - graph.removeFixed(materializeNode); - } - for (VirtualObjectNode virtualObjectNode : graph.getNodes(VirtualObjectNode.class)) { - if (virtualObjectNode instanceof VirtualOnlyInstanceNode) { - VirtualOnlyInstanceNode virtualOnlyInstanceNode = (VirtualOnlyInstanceNode) virtualObjectNode; - virtualOnlyInstanceNode.setAllowMaterialization(true); - } else if (virtualObjectNode instanceof VirtualInstanceNode) { - VirtualInstanceNode virtualInstanceNode = (VirtualInstanceNode) virtualObjectNode; - ResolvedJavaType type = virtualInstanceNode.type(); - if (type.getAnnotation(CompilerDirectives.ValueType.class) != null) { - virtualInstanceNode.setIdentity(false); - } + for (NeverPartOfCompilationNode neverPartOfCompilationNode : graph.getNodes(NeverPartOfCompilationNode.class)) { + Throwable exception = new VerificationError(neverPartOfCompilationNode.getMessage()); + throw GraphUtil.approxSourceException(neverPartOfCompilationNode, exception); + } + + // EA frame and clean up. + new PartialEscapePhase(true, canonicalizer).apply(graph, tierContext); + new VerifyNoIntrinsicsLeftPhase().apply(graph, false); + for (MaterializeFrameNode materializeNode : graph.getNodes(MaterializeFrameNode.class).snapshot()) { + materializeNode.replaceAtUsages(materializeNode.getFrame()); + graph.removeFixed(materializeNode); + } + for (VirtualObjectNode virtualObjectNode : graph.getNodes(VirtualObjectNode.class)) { + if (virtualObjectNode instanceof VirtualOnlyInstanceNode) { + VirtualOnlyInstanceNode virtualOnlyInstanceNode = (VirtualOnlyInstanceNode) virtualObjectNode; + virtualOnlyInstanceNode.setAllowMaterialization(true); + } else if (virtualObjectNode instanceof VirtualInstanceNode) { + VirtualInstanceNode virtualInstanceNode = (VirtualInstanceNode) virtualObjectNode; + ResolvedJavaType type = virtualInstanceNode.type(); + if (type.getAnnotation(CompilerDirectives.ValueType.class) != null) { + virtualInstanceNode.setIdentity(false); } } } - }); + } catch (Throwable e) { + throw Debug.handle(e); + } return graph; } @@ -254,44 +253,44 @@ local.replaceAndDelete(ConstantNode.forConstant(constant, phaseContext.getMetaAccess(), graphCopy)); } } - Debug.scope("TruffleUnrollLoop", targetMethod, new Runnable() { - - @Override - public void run() { + 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; - } + 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; } - } while (unrolled); - } - - private List innerLoopsFirst(Collection loops) { - ArrayList sortedLoops = new ArrayList<>(loops); - Collections.sort(sortedLoops, new Comparator() { + } + } while (unrolled); + } catch (Throwable e) { + throw Debug.handle(e); + } - @Override - public int compare(LoopEx o1, LoopEx o2) { - return o2.lirLoop().depth - o1.lirLoop().depth; - } - }); - return sortedLoops; - } - }); return graphCopy; } else { return graph; } } + + 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.lirLoop().depth - o1.lirLoop().depth; + } + }); + return sortedLoops; + } + } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java Sat Nov 30 19:05:44 2013 +0100 @@ -53,7 +53,7 @@ loadFieldNode.field().getAnnotation(CompilerDirectives.CompilationFinal.class) != null) { Constant constant = loadFieldNode.field().readValue(loadFieldNode.object().asConstant()); assert verifyFieldValue(loadFieldNode.field(), constant); - return ConstantNode.forConstant(constant, metaAccess, node.graph()); + return ConstantNode.forConstant(constant, metaAccess, loadFieldNode.graph()); } } } else if (node instanceof LoadIndexedNode) { diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java Sat Nov 30 19:05:44 2013 +0100 @@ -26,13 +26,13 @@ import java.lang.reflect.*; import java.util.*; -import java.util.concurrent.*; import com.oracle.graal.api.code.*; 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.Graph.Mark; import com.oracle.graal.graph.Node; import com.oracle.graal.graph.spi.*; import com.oracle.graal.java.*; @@ -91,102 +91,101 @@ } cache.put(key, markerGraph); - resultGraph = Debug.scope("TruffleCache", new Object[]{providers.getMetaAccess(), method}, new Callable() { + try (Scope s = Debug.scope("TruffleCache", new Object[]{providers.getMetaAccess(), method})) { + + final StructuredGraph graph = new StructuredGraph(method); + PhaseContext phaseContext = new PhaseContext(providers, new Assumptions(false)); + new GraphBuilderPhase(phaseContext.getMetaAccess(), providers.getForeignCalls(), config, optimisticOptimizations).apply(graph); + + for (LocalNode l : graph.getNodes(LocalNode.class)) { + if (l.kind() == Kind.Object) { + ValueNode actualArgument = arguments.get(l.index()); + l.setStamp(l.stamp().join(actualArgument.stamp())); + } + } + + // Intrinsify methods. + new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph); - public StructuredGraph call() { + // Convert deopt to guards. + new ConvertDeoptimizeToGuardPhase().apply(graph); + + CanonicalizerPhase canonicalizerPhase = new CanonicalizerPhase(!AOTCompilation.getValue()); + PartialEscapePhase partialEscapePhase = new PartialEscapePhase(false, canonicalizerPhase); + + Mark mark = null; + while (true) { + + partialEscapePhase.apply(graph, phaseContext); + + // Conditional elimination. + ConditionalEliminationPhase conditionalEliminationPhase = new ConditionalEliminationPhase(phaseContext.getMetaAccess()); + conditionalEliminationPhase.apply(graph); + + // Canonicalize / constant propagate. + canonicalizerPhase.apply(graph, phaseContext); - final StructuredGraph graph = new StructuredGraph(method); - PhaseContext phaseContext = new PhaseContext(providers, new Assumptions(false)); - new GraphBuilderPhase(phaseContext.getMetaAccess(), providers.getForeignCalls(), config, optimisticOptimizations).apply(graph); - - for (LocalNode l : graph.getNodes(LocalNode.class)) { - if (l.kind() == Kind.Object) { - ValueNode actualArgument = arguments.get(l.index()); - l.setStamp(l.stamp().join(actualArgument.stamp())); + boolean inliningProgress = false; + for (MethodCallTargetNode methodCallTarget : graph.getNodes(MethodCallTargetNode.class)) { + if (graph.getMark().equals(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; + Class macroSubstitution = providers.getReplacements().getMacroSubstitution(methodCallTargetNode.targetMethod()); + if (macroSubstitution != null) { + InliningUtil.inlineMacroNode(methodCallTargetNode.invoke(), methodCallTargetNode.targetMethod(), methodCallTargetNode.graph(), macroSubstitution); + } else { + tryCutOffRuntimeExceptions(methodCallTargetNode); + } + } + } + mark = graph.getMark(); + } + if (methodCallTarget.isAlive() && methodCallTarget.invoke() != null && shouldInline(methodCallTarget)) { + inliningProgress = true; + 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); + for (Node arg : argumentSnapshot) { + if (arg != null && arg.recordsUsages()) { + for (Node argUsage : arg.usages()) { + if (graph.isNew(beforeInvokeMark, argUsage) && argUsage instanceof Canonicalizable) { + canonicalizerUsages.add(argUsage); + } + } + } + } + canonicalizerPhase.applyIncremental(graph, phaseContext, canonicalizerUsages); } } - // Intrinsify methods. - new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph); - // Convert deopt to guards. new ConvertDeoptimizeToGuardPhase().apply(graph); - CanonicalizerPhase canonicalizerPhase = new CanonicalizerPhase(!AOTCompilation.getValue()); - PartialEscapePhase partialEscapePhase = new PartialEscapePhase(false, canonicalizerPhase); - - Mark mark = null; - while (true) { + new EarlyReadEliminationPhase(canonicalizerPhase).apply(graph, phaseContext); - partialEscapePhase.apply(graph, phaseContext); - - // Conditional elimination. - ConditionalEliminationPhase conditionalEliminationPhase = new ConditionalEliminationPhase(phaseContext.getMetaAccess()); - conditionalEliminationPhase.apply(graph); - - // Canonicalize / constant propagate. - canonicalizerPhase.apply(graph, phaseContext); + if (!inliningProgress) { + break; + } + } - boolean inliningProgress = false; - for (MethodCallTargetNode methodCallTarget : graph.getNodes(MethodCallTargetNode.class)) { - if (graph.getMark().equals(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; - Class macroSubstitution = providers.getReplacements().getMacroSubstitution(methodCallTargetNode.targetMethod()); - if (macroSubstitution != null) { - InliningUtil.inlineMacroNode(methodCallTargetNode.invoke(), methodCallTargetNode.targetMethod(), methodCallTargetNode.graph(), macroSubstitution); - } else { - tryCutOffRuntimeExceptions(methodCallTargetNode); - } - } - } - mark = graph.getMark(); - } - if (methodCallTarget.isAlive() && methodCallTarget.invoke() != null && shouldInline(methodCallTarget)) { - inliningProgress = true; - 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); - for (Node arg : argumentSnapshot) { - if (arg != null && arg.recordsUsages()) { - for (Node argUsage : arg.usages()) { - if (graph.isNew(beforeInvokeMark, argUsage) && argUsage instanceof Canonicalizable) { - canonicalizerUsages.add(argUsage); - } - } - } - } - canonicalizerPhase.applyIncremental(graph, phaseContext, canonicalizerUsages); - } - } + 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); + } - // Convert deopt to guards. - new ConvertDeoptimizeToGuardPhase().apply(graph); - - new EarlyReadEliminationPhase(canonicalizerPhase).apply(graph, phaseContext); - - if (!inliningProgress) { - break; - } - } - - if (TruffleCompilerOptions.TraceTruffleCacheDetails.getValue()) { - TTY.println(String.format("[truffle] added to graph cache method %s with %d nodes.", method, graph.getNodeCount())); - } - return graph; - } - }); - cache.put(key, resultGraph); - return resultGraph; } private void expandInvoke(MethodCallTargetNode methodCallTargetNode) { diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Sat Nov 30 19:05:44 2013 +0100 @@ -38,6 +38,7 @@ import com.oracle.graal.compiler.CompilerThreadFactory.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.debug.internal.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; @@ -109,21 +110,16 @@ } public Future compile(final OptimizedCallTarget compilable) { - Future future = compileQueue.submit(new Callable() { - + return compileQueue.submit(new Callable() { @Override public InstalledCode call() throws Exception { - Object[] debug = new Object[]{new TruffleDebugJavaMethod(compilable)}; - return Debug.scope("Truffle", debug, new Callable() { - - @Override - public InstalledCode call() throws Exception { - return compileMethodImpl(compilable); - } - }); + try (Scope s = Debug.scope("Truffle", new TruffleDebugJavaMethod(compilable))) { + return compileMethodImpl(compilable); + } catch (Throwable e) { + throw Debug.handle(e); + } } }); - return future; } public static final DebugTimer PartialEvaluationTime = Debug.timer("PartialEvaluationTime"); @@ -208,31 +204,22 @@ public InstalledCode compileMethodHelper(final StructuredGraph graph, final GraphBuilderConfiguration config, final Assumptions assumptions) { final PhasePlan plan = createPhasePlan(config); - Debug.scope("TruffleFinal", new Runnable() { - - @Override - public void run() { - Debug.dump(graph, "After TruffleTier"); - } - }); - - final CompilationResult result = Debug.scope("TruffleGraal", new Callable() { + try (Scope s = Debug.scope("TruffleFinal")) { + Debug.dump(graph, "After TruffleTier"); + } catch (Throwable e) { + throw Debug.handle(e); + } - @Override - public CompilationResult call() { - try (TimerCloseable a = CompilationTime.start()) { - return Debug.scope("GraalCompiler", new Object[]{graph, providers.getCodeCache()}, new Callable() { - public CompilationResult call() { - CodeCacheProvider codeCache = providers.getCodeCache(); - CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false); - CompilationResult compilationResult = new CompilationResult(graph.method().toString()); - return GraalCompiler.compileGraphNoScope(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, plan, OptimisticOptimizations.ALL, - new SpeculationLog(), suites, compilationResult); - } - }); - } - } - }); + CompilationResult result = null; + try (TimerCloseable a = CompilationTime.start(); Scope s = Debug.scope("TruffleGraal.GraalCompiler", graph, providers.getCodeCache())) { + CodeCacheProvider codeCache = providers.getCodeCache(); + CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false); + CompilationResult compilationResult = new CompilationResult(graph.method().toString()); + result = GraalCompiler.compileGraphNoScope(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, plan, OptimisticOptimizations.ALL, new SpeculationLog(), suites, + compilationResult); + } catch (Throwable e) { + throw Debug.handle(e); + } List validAssumptions = new ArrayList<>(); Assumptions newAssumptions = new Assumptions(true); @@ -250,19 +237,16 @@ result.setAssumptions(newAssumptions); - InstalledCode compiledMethod = Debug.scope("CodeInstall", new Object[]{providers.getCodeCache()}, new Callable() { - - @Override - public InstalledCode call() throws Exception { - try (TimerCloseable a = CodeInstallationTime.start()) { - InstalledCode installedCode = providers.getCodeCache().addMethod(graph.method(), result); - if (installedCode != null) { - Debug.dump(new Object[]{result, installedCode}, "After code installation"); - } - return installedCode; - } + InstalledCode compiledMethod = null; + try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache()); TimerCloseable a = CodeInstallationTime.start()) { + InstalledCode installedCode = providers.getCodeCache().addMethod(graph.method(), result); + if (installedCode != null) { + Debug.dump(new Object[]{result, installedCode}, "After code installation"); } - }); + compiledMethod = installedCode; + } catch (Throwable e) { + throw Debug.handle(e); + } for (AssumptionValidAssumption a : validAssumptions) { a.getAssumption().registerInstalledCode(compiledMethod); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java Sat Nov 30 19:05:44 2013 +0100 @@ -30,7 +30,7 @@ /** * Enables a Truffle compilable to masquerade as a {@link JavaMethod} for use as a context value in - * {@linkplain Debug#scope(String, Object[], Runnable) debug scopes}. + * {@linkplain Debug#scope(String, Object...) debug scopes}. */ public class TruffleDebugJavaMethod implements JavaMethod { private final DefaultCallTarget compilable; diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java Sat Nov 30 19:05:44 2013 +0100 @@ -43,7 +43,7 @@ private final Replacements graalReplacements; private TruffleReplacements(Providers providers) { - super(providers, providers.getReplacements().getAssumptions()); + super(providers, providers.getReplacements().getAssumptions(), providers.getCodeCache().getTarget()); this.graalReplacements = providers.getReplacements(); } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java Sat Nov 30 19:05:44 2013 +0100 @@ -24,13 +24,14 @@ import com.oracle.graal.api.replacements.*; import com.oracle.graal.truffle.*; +import com.oracle.truffle.api.frame.*; @ClassSubstitution(FrameWithoutBoxing.class) public class FrameWithoutBoxingSubstitutions { @SuppressWarnings("unused") @MethodSubstitution(isStatic = false, forced = true) - public static Object pack(FrameWithoutBoxing frame) { + public static PackedFrame pack(FrameWithoutBoxing frame) { return null; } } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java Sat Nov 30 19:05:44 2013 +0100 @@ -22,9 +22,8 @@ */ package com.oracle.graal.virtual.phases.ea; -import java.util.concurrent.*; - import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; @@ -60,45 +59,37 @@ public boolean runAnalysis(final StructuredGraph graph, final PhaseContextT context) { boolean changed = false; for (int iteration = 0; iteration < maxIterations; iteration++) { - boolean currentChanged = Debug.scope("iteration " + iteration, new Callable() { - @Override - public Boolean call() { - SchedulePhase schedule = new SchedulePhase(); - schedule.apply(graph, false); - Closure closure = createEffectsClosure(context, schedule); - ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock()); + try (Scope s = Debug.scope("iteration " + iteration)) { + SchedulePhase schedule = new SchedulePhase(); + schedule.apply(graph, false); + Closure closure = createEffectsClosure(context, schedule); + ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock()); - if (!closure.hasChanged()) { - return false; - } + if (!closure.hasChanged()) { + break; + } - // apply the effects collected during this iteration - HashSetNodeChangeListener listener = new HashSetNodeChangeListener(); - graph.trackInputChange(listener); - graph.trackUsagesDroppedZero(listener); - closure.applyEffects(); - graph.stopTrackingInputChange(); - graph.stopTrackingUsagesDroppedZero(); + // apply the effects collected during this iteration + HashSetNodeChangeListener listener = new HashSetNodeChangeListener(); + graph.trackInputChange(listener); + graph.trackUsagesDroppedZero(listener); + closure.applyEffects(); + graph.stopTrackingInputChange(); + graph.stopTrackingUsagesDroppedZero(); - Debug.dump(graph, "after " + getName() + " iteration"); - - new DeadCodeEliminationPhase().apply(graph); + Debug.dump(graph, "after " + getName() + " iteration"); - for (Node node : graph.getNodes()) { - if (node instanceof Simplifiable) { - listener.getChangedNodes().add(node); - } - } - canonicalizer.applyIncremental(graph, context, listener.getChangedNodes()); + new DeadCodeEliminationPhase().apply(graph); - return true; + for (Node node : graph.getNodes()) { + if (node instanceof Simplifiable) { + listener.getChangedNodes().add(node); + } } - }); - if (!currentChanged) { - break; + canonicalizer.applyIncremental(graph, context, listener.getChangedNodes()); } - changed |= currentChanged; + changed = true; } return changed; } diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/IterativeInliningPhase.java Sat Nov 30 19:05:44 2013 +0100 @@ -25,9 +25,9 @@ import static com.oracle.graal.phases.GraalOptions.*; import java.util.*; -import java.util.concurrent.*; 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.tiers.*; @@ -53,34 +53,32 @@ } private void runIterations(final StructuredGraph graph, final boolean simple, final HighTierContext context) { - Boolean continueIteration = true; - for (int iteration = 0; iteration < EscapeAnalysisIterations.getValue() && continueIteration; iteration++) { - continueIteration = Debug.scope("iteration " + iteration, new Callable() { + for (int iteration = 0; iteration < EscapeAnalysisIterations.getValue(); iteration++) { + try (Scope s = Debug.scope("iteration " + iteration)) { + boolean progress = false; + PartialEscapePhase ea = new PartialEscapePhase(false, canonicalizer); + boolean eaResult = ea.runAnalysis(graph, context); + progress |= eaResult; - @Override - public Boolean call() { - 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; + Map hints = PEAInliningHints.getValue() ? PartialEscapePhase.getHints(graph) : null; - InliningPhase inlining = new InliningPhase(hints, new CanonicalizerPhase(true)); - inlining.setMaxMethodsPerInlining(simple ? 1 : Integer.MAX_VALUE); - inlining.apply(graph, context); - progress |= inlining.getInliningCount() > 0; + InliningPhase inlining = new InliningPhase(hints, new CanonicalizerPhase(true)); + inlining.setMaxMethodsPerInlining(simple ? 1 : Integer.MAX_VALUE); + inlining.apply(graph, context); + progress |= inlining.getInliningCount() > 0; - new DeadCodeEliminationPhase().apply(graph); + new DeadCodeEliminationPhase().apply(graph); - if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { - canonicalizer.apply(graph, context); - new IterativeConditionalEliminationPhase(canonicalizer).apply(graph, context); - } - - return progress; + if (ConditionalElimination.getValue() && OptCanonicalizer.getValue()) { + canonicalizer.apply(graph, context); + new IterativeConditionalEliminationPhase(canonicalizer).apply(graph, context); } - }); + if (!progress) { + break; + } + } catch (Throwable e) { + throw Debug.handle(e); + } } } } diff -r 833f8e96d0a5 -r 8b14bab15757 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 Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Sat Nov 30 19:05:44 2013 +0100 @@ -114,7 +114,7 @@ if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) { ValueNode value = exitState.getReadCache(entry.getKey().object, entry.getKey().identity, this); if (!(value instanceof ProxyNode) || ((ProxyNode) value).proxyPoint() != exitNode) { - ProxyNode proxy = new ProxyNode(value, exitNode, PhiType.Value, null); + ProxyNode proxy = new ProxyNode(value, exitNode, PhiType.Value); effects.addFloatingNode(proxy, "readCacheProxy"); entry.setValue(proxy); } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Sat Nov 30 19:05:44 2013 +0100 @@ -247,7 +247,7 @@ ValueNode value = obj.getEntry(i); if (!(value instanceof VirtualObjectNode || value.isConstant())) { if (exitNode.loopBegin().isPhiAtMerge(value) || initialObj == null || !initialObj.isVirtual() || initialObj.getEntry(i) != value) { - ProxyNode proxy = new ProxyNode(value, exitNode, PhiType.Value, null); + ProxyNode proxy = new ProxyNode(value, exitNode, PhiType.Value); obj.setEntry(i, proxy); effects.addFloatingNode(proxy, "virtualProxy"); } @@ -257,7 +257,7 @@ if (initialObj == null || initialObj.isVirtual()) { ProxyNode proxy = proxies.get(obj.virtual); if (proxy == null) { - proxy = new ProxyNode(obj.getMaterializedValue(), exitNode, PhiType.Value, null); + proxy = new ProxyNode(obj.getMaterializedValue(), exitNode, PhiType.Value); effects.addFloatingNode(proxy, "proxy"); } else { effects.replaceFirstInput(proxy, proxy.value(), obj.getMaterializedValue()); diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Sat Nov 30 19:05:44 2013 +0100 @@ -171,7 +171,7 @@ protected void processLoopExit(LoopExitNode exitNode, ReadEliminationBlockState initialState, ReadEliminationBlockState exitState, GraphEffectList effects) { for (Map.Entry, ValueNode> entry : exitState.getReadCache().entrySet()) { if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) { - ProxyNode proxy = new ProxyNode(exitState.getCacheEntry(entry.getKey()), exitNode, PhiType.Value, null); + ProxyNode proxy = new ProxyNode(exitState.getCacheEntry(entry.getKey()), exitNode, PhiType.Value); effects.addFloatingNode(proxy, "readCacheProxy"); entry.setValue(proxy); } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.word/src/com/oracle/graal/word/ComparableWord.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/ComparableWord.java Sat Nov 30 19:05:44 2013 +0100 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012, 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.word; + +public interface ComparableWord extends WordBase { + + /** + * Compares this word with the specified value. + * + * @param val value to which this word is to be compared. + * @return {@code this == val} + */ + boolean equal(ComparableWord val); + + /** + * Compares this word with the specified value. + * + * @param val value to which this word is to be compared. + * @return {@code this != val} + */ + boolean notEqual(ComparableWord val); +} diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java Sat Nov 30 19:05:44 2013 +0100 @@ -26,7 +26,7 @@ import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.extended.*; -public interface Pointer extends Unsigned { +public interface Pointer extends Unsigned, PointerBase { /** * Unsafe conversion of this Pointer to a Java language object. No correctness checks or type diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.word/src/com/oracle/graal/word/PointerBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/PointerBase.java Sat Nov 30 19:05:44 2013 +0100 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2013, 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.word; + +/** + * Marker interface for all {@link WordBase word types} that have the semantic of a pointer (but not + * necessarily all the memory access methods defined in {@link Pointer}). + */ +public interface PointerBase extends ComparableWord { +} diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.word/src/com/oracle/graal/word/Signed.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Signed.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Signed.java Sat Nov 30 19:05:44 2013 +0100 @@ -22,7 +22,7 @@ */ package com.oracle.graal.word; -public interface Signed extends WordBase { +public interface Signed extends ComparableWord { /** * Returns a Signed whose value is {@code (this + val)}. diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.word/src/com/oracle/graal/word/Unsigned.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Unsigned.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Unsigned.java Sat Nov 30 19:05:44 2013 +0100 @@ -22,7 +22,7 @@ */ package com.oracle.graal.word; -public interface Unsigned extends WordBase { +public interface Unsigned extends ComparableWord { /** * Returns a Unsigned whose value is {@code (this + val)}. diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java Sat Nov 30 19:05:44 2013 +0100 @@ -427,6 +427,12 @@ @Override @Operation(opcode = Opcode.COMPARISON, condition = Condition.EQ) + public boolean equal(ComparableWord val) { + return equal((Word) val); + } + + @Override + @Operation(opcode = Opcode.COMPARISON, condition = Condition.EQ) public boolean equal(Signed val) { return equal((Word) val); } @@ -450,6 +456,12 @@ @Override @Operation(opcode = Opcode.COMPARISON, condition = Condition.NE) + public boolean notEqual(ComparableWord val) { + return notEqual((Word) val); + } + + @Override + @Operation(opcode = Opcode.COMPARISON, condition = Condition.NE) public boolean notEqual(Signed val) { return notEqual((Word) val); } diff -r 833f8e96d0a5 -r 8b14bab15757 graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Fri Nov 22 14:45:09 2013 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Sat Nov 30 19:05:44 2013 +0100 @@ -86,6 +86,21 @@ * prepared to see the word type during canonicalization. */ protected void inferStamps(StructuredGraph graph) { + /* + * We want to make the stamps more precise. For cyclic phi functions, this means we have to + * ignore the initial stamp because the imprecise stamp would always propagate around the + * cycle. We therefore set the stamp to an illegal stamp, which is automatically ignored + * when the phi function performs the "meet" operator on its input stamps. + */ + for (Node n : graph.getNodes()) { + if (n instanceof PhiNode || n instanceof ProxyNode) { + ValueNode node = (ValueNode) n; + if (node.kind() == Kind.Object) { + node.setStamp(StampFactory.illegal(node.kind())); + } + } + } + boolean stampChanged; do { stampChanged = false; @@ -104,6 +119,22 @@ } } } while (stampChanged); + + /* + * Check that all the illegal stamps we introduced above are correctly replaced with real + * stamps again. + */ + assert checkNoIllegalStamp(graph); + } + + private static boolean checkNoIllegalStamp(StructuredGraph graph) { + for (Node n : graph.getNodes()) { + if (n instanceof ValueNode) { + ValueNode node = (ValueNode) n; + assert !(node.stamp() instanceof IllegalStamp); + } + } + return true; } /** @@ -243,7 +274,7 @@ } else { location = makeLocation(graph, arguments.get(1), readKind, arguments.get(2)); } - replace(invoke, readOp(graph, arguments.get(0), invoke, location, BarrierType.NONE, false)); + replace(invoke, readOp(graph, arguments.get(0), invoke, location, readKind, BarrierType.NONE, false)); break; } case READ_HEAP: { @@ -251,7 +282,7 @@ Kind readKind = asKind(callTargetNode.returnType()); LocationNode location = makeLocation(graph, arguments.get(1), readKind, ANY_LOCATION); BarrierType barrierType = (BarrierType) arguments.get(2).asConstant().asObject(); - replace(invoke, readOp(graph, arguments.get(0), invoke, location, barrierType, arguments.get(3).asConstant().asInt() == 0 ? false : true)); + replace(invoke, readOp(graph, arguments.get(0), invoke, location, readKind, barrierType, arguments.get(3).asConstant().asInt() == 0 ? false : true)); break; } case WRITE: @@ -390,15 +421,16 @@ if (locationIdentity.isConstant()) { return makeLocation(graph, offset, readKind, (LocationIdentity) locationIdentity.asConstant().asObject()); } - return SnippetLocationNode.create(locationIdentity, ConstantNode.forObject(readKind, metaAccess, graph), ConstantNode.forLong(0, graph), offset, ConstantNode.forInt(1, graph), graph); + return SnippetLocationNode.create(locationIdentity, ConstantNode.forObject(readKind, metaAccess, graph), ConstantNode.forLong(0, graph), fromSigned(graph, offset), + ConstantNode.forInt(1, graph), graph); } protected LocationNode makeLocation(StructuredGraph graph, ValueNode offset, Kind readKind, LocationIdentity locationIdentity) { - return IndexedLocationNode.create(locationIdentity, readKind, 0, offset, graph, 1); + return IndexedLocationNode.create(locationIdentity, readKind, 0, fromSigned(graph, offset), graph, 1); } - protected ValueNode readOp(StructuredGraph graph, ValueNode base, Invoke invoke, LocationNode location, BarrierType barrierType, boolean compressible) { - ReadNode read = graph.add(new ReadNode(base, location, invoke.asNode().stamp(), barrierType, compressible)); + protected ValueNode readOp(StructuredGraph graph, ValueNode base, Invoke invoke, LocationNode location, Kind readKind, BarrierType barrierType, boolean compressible) { + ReadNode read = graph.add(new ReadNode(base, location, StampFactory.forKind(readKind), barrierType, compressible)); graph.addBeforeFixed(invoke.asNode(), read); /* * The read must not float outside its block otherwise it may float above an explicit zero diff -r 833f8e96d0a5 -r 8b14bab15757 make/bsd/makefiles/jsig.make --- a/make/bsd/makefiles/jsig.make Fri Nov 22 14:45:09 2013 +0100 +++ b/make/bsd/makefiles/jsig.make Sat Nov 30 19:05:44 2013 +0100 @@ -97,7 +97,7 @@ $(QUIETLY) test -f $(LIBJSIG_DEBUGINFO) && \ cp -f $(LIBJSIG_DEBUGINFO) $(DEST_JSIG_DEBUGINFO) endif - -$(QUIETLY) test -f $(LIBJSIG_DIZ) && \ + $(QUIETLY) test ! -f $(LIBJSIG_DIZ) || \ cp -f $(LIBJSIG_DIZ) $(DEST_JSIG_DIZ) $(QUIETLY) cp -f $(LIBJSIG) $(DEST_JSIG) && echo "Done" diff -r 833f8e96d0a5 -r 8b14bab15757 make/bsd/makefiles/saproc.make --- a/make/bsd/makefiles/saproc.make Fri Nov 22 14:45:09 2013 +0100 +++ b/make/bsd/makefiles/saproc.make Sat Nov 30 19:05:44 2013 +0100 @@ -163,7 +163,7 @@ $(QUIETLY) test -f $(LIBSAPROC_DEBUGINFO) && \ cp -f $(LIBSAPROC_DEBUGINFO) $(DEST_SAPROC_DEBUGINFO) endif - -$(QUIETLY) test -f $(LIBSAPROC_DIZ) && \ + $(QUIETLY) test ! -f $(LIBSAPROC_DIZ) || \ cp -f $(LIBSAPROC_DIZ) $(DEST_SAPROC_DIZ) $(QUIETLY) cp -f $(LIBSAPROC) $(DEST_SAPROC) && echo "Done" diff -r 833f8e96d0a5 -r 8b14bab15757 make/bsd/makefiles/vm.make --- a/make/bsd/makefiles/vm.make Fri Nov 22 14:45:09 2013 +0100 +++ b/make/bsd/makefiles/vm.make Sat Nov 30 19:05:44 2013 +0100 @@ -393,7 +393,7 @@ $(QUIETLY) test -f $(LIBJVM_DEBUGINFO) && \ cp -f $(LIBJVM_DEBUGINFO) $(DEST_JVM_DEBUGINFO) endif - -$(QUIETLY) test -f $(LIBJVM_DIZ) && \ + $(QUIETLY) test ! -f $(LIBJVM_DIZ) || \ cp -f $(LIBJVM_DIZ) $(DEST_JVM_DIZ) $(QUIETLY) cp -f $(LIBJVM) $(DEST_JVM) && echo "Done" diff -r 833f8e96d0a5 -r 8b14bab15757 make/linux/makefiles/jsig.make --- a/make/linux/makefiles/jsig.make Fri Nov 22 14:45:09 2013 +0100 +++ b/make/linux/makefiles/jsig.make Sat Nov 30 19:05:44 2013 +0100 @@ -74,9 +74,9 @@ install_jsig: $(LIBJSIG) @echo "Copying $(LIBJSIG) to $(DEST_JSIG)" - -$(QUIETLY) test -f $(LIBJSIG_DEBUGINFO) && \ + $(QUIETLY) test ! -f $(LIBJSIG_DEBUGINFO) || \ cp -f $(LIBJSIG_DEBUGINFO) $(DEST_JSIG_DEBUGINFO) - -$(QUIETLY) test -f $(LIBJSIG_DIZ) && \ + $(QUIETLY) test ! -f $(LIBJSIG_DIZ) || \ cp -f $(LIBJSIG_DIZ) $(DEST_JSIG_DIZ) $(QUIETLY) cp -f $(LIBJSIG) $(DEST_JSIG) && echo "Done" diff -r 833f8e96d0a5 -r 8b14bab15757 make/linux/makefiles/vm.make --- a/make/linux/makefiles/vm.make Fri Nov 22 14:45:09 2013 +0100 +++ b/make/linux/makefiles/vm.make Sat Nov 30 19:05:44 2013 +0100 @@ -382,9 +382,9 @@ install_jvm: $(LIBJVM) @echo "Copying $(LIBJVM) to $(DEST_JVM)" - -$(QUIETLY) test -f $(LIBJVM_DEBUGINFO) && \ + $(QUIETLY) test ! -f $(LIBJVM_DEBUGINFO) || \ cp -f $(LIBJVM_DEBUGINFO) $(DEST_JVM_DEBUGINFO) - -$(QUIETLY) test -f $(LIBJVM_DIZ) && \ + $(QUIETLY) test ! -f $(LIBJVM_DIZ) || \ cp -f $(LIBJVM_DIZ) $(DEST_JVM_DIZ) $(QUIETLY) cp -f $(LIBJVM) $(DEST_JVM) && echo "Done" diff -r 833f8e96d0a5 -r 8b14bab15757 make/solaris/makefiles/jsig.make --- a/make/solaris/makefiles/jsig.make Fri Nov 22 14:45:09 2013 +0100 +++ b/make/solaris/makefiles/jsig.make Sat Nov 30 19:05:44 2013 +0100 @@ -79,9 +79,9 @@ install_jsig: $(LIBJSIG) @echo "Copying $(LIBJSIG) to $(DEST_JSIG)" - -$(QUIETLY) test -f $(LIBJSIG_DEBUGINFO) && \ + $(QUIETLY) test ! -f $(LIBJSIG_DEBUGINFO) || \ cp -f $(LIBJSIG_DEBUGINFO) $(DEST_JSIG_DEBUGINFO) - -$(QUIETLY) test -f $(LIBJSIG_DIZ) && \ + $(QUIETLY) test ! -f $(LIBJSIG_DIZ) || \ cp -f $(LIBJSIG_DIZ) $(DEST_JSIG_DIZ) $(QUIETLY) cp -f $(LIBJSIG) $(DEST_JSIG) && echo "Done" diff -r 833f8e96d0a5 -r 8b14bab15757 make/solaris/makefiles/vm.make --- a/make/solaris/makefiles/vm.make Fri Nov 22 14:45:09 2013 +0100 +++ b/make/solaris/makefiles/vm.make Sat Nov 30 19:05:44 2013 +0100 @@ -343,9 +343,9 @@ install_jvm: $(LIBJVM) @echo "Copying $(LIBJVM) to $(DEST_JVM)" - -$(QUIETLY) test -f $(LIBJVM_DEBUGINFO) && \ + $(QUIETLY) test ! -f $(LIBJVM_DEBUGINFO) || \ cp -f $(LIBJVM_DEBUGINFO) $(DEST_JVM_DEBUGINFO) - -$(QUIETLY) test -f $(LIBJVM_DIZ) && \ + $(QUIETLY) test ! -f $(LIBJVM_DIZ) || \ cp -f $(LIBJVM_DIZ) $(DEST_JVM_DIZ) $(QUIETLY) cp -f $(LIBJVM) $(DEST_JVM) && echo "Done" diff -r 833f8e96d0a5 -r 8b14bab15757 mx/projects --- a/mx/projects Fri Nov 22 14:45:09 2013 +0100 +++ b/mx/projects Sat Nov 30 19:05:44 2013 +0100 @@ -67,6 +67,14 @@ project@com.oracle.graal.api.meta.test@javaCompliance=1.7 project@com.oracle.graal.api.meta.test@workingSets=API,Graal,Test +# graal.api.meta.jdk8.test +project@com.oracle.graal.api.meta.jdk8.test@subDir=graal +project@com.oracle.graal.api.meta.jdk8.test@sourceDirs=src +project@com.oracle.graal.api.meta.jdk8.test@dependencies=com.oracle.graal.api.meta.test +project@com.oracle.graal.api.meta.jdk8.test@checkstyle=com.oracle.graal.graph +project@com.oracle.graal.api.meta.jdk8.test@javaCompliance=1.8 +project@com.oracle.graal.api.meta.jdk8.test@workingSets=API,Graal,Test + # graal.api.code project@com.oracle.graal.api.code@subDir=graal project@com.oracle.graal.api.code@sourceDirs=src @@ -176,7 +184,7 @@ project@com.oracle.graal.hotspot.test@javaCompliance=1.7 project@com.oracle.graal.hotspot.test@workingSets=Graal,HotSpot,Test -# graal.hotspot.test +# graal.hotspot.jdk8.test project@com.oracle.graal.hotspot.jdk8.test@subDir=graal project@com.oracle.graal.hotspot.jdk8.test@sourceDirs=src project@com.oracle.graal.hotspot.jdk8.test@dependencies=com.oracle.graal.compiler.test diff -r 833f8e96d0a5 -r 8b14bab15757 src/cpu/sparc/vm/c2_globals_sparc.hpp --- a/src/cpu/sparc/vm/c2_globals_sparc.hpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/cpu/sparc/vm/c2_globals_sparc.hpp Sat Nov 30 19:05:44 2013 +0100 @@ -44,12 +44,7 @@ #else define_pd_global(bool, ProfileInterpreter, true); #endif // CC_INTERP -// Disable TieredCompilation while profile data problems are not resolved - same thing in c2_globals_x86.hpp -#ifdef GRAAL -define_pd_global(bool, TieredCompilation, false); -#else define_pd_global(bool, TieredCompilation, trueInTiered); -#endif define_pd_global(intx, CompileThreshold, 10000); define_pd_global(intx, BackEdgeThreshold, 140000); diff -r 833f8e96d0a5 -r 8b14bab15757 src/cpu/x86/vm/c2_globals_x86.hpp --- a/src/cpu/x86/vm/c2_globals_x86.hpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/cpu/x86/vm/c2_globals_x86.hpp Sat Nov 30 19:05:44 2013 +0100 @@ -45,12 +45,7 @@ #else define_pd_global(bool, ProfileInterpreter, true); #endif // CC_INTERP -// Disable TieredCompilation while profile data problems are not resolved - same thing in c2_globals_sparc.hpp -#ifdef GRAAL -define_pd_global(bool, TieredCompilation, false); -#else define_pd_global(bool, TieredCompilation, trueInTiered); -#endif define_pd_global(intx, CompileThreshold, 10000); define_pd_global(intx, BackEdgeThreshold, 100000); diff -r 833f8e96d0a5 -r 8b14bab15757 src/gpu/hsail/vm/gpu_hsail.cpp --- a/src/gpu/hsail/vm/gpu_hsail.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/gpu/hsail/vm/gpu_hsail.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -33,8 +33,8 @@ void * gpu::Hsail::_device_context; -gpu::Hsail::okra_ctx_create_func_t gpu::Hsail::_okra_ctx_create; -gpu::Hsail::okra_kernel_create_func_t gpu::Hsail::_okra_kernel_create; +gpu::Hsail::okra_create_context_func_t gpu::Hsail::_okra_create_context; +gpu::Hsail::okra_create_kernel_func_t gpu::Hsail::_okra_create_kernel; gpu::Hsail::okra_push_object_func_t gpu::Hsail::_okra_push_object; gpu::Hsail::okra_push_boolean_func_t gpu::Hsail::_okra_push_boolean; gpu::Hsail::okra_push_byte_func_t gpu::Hsail::_okra_push_byte; @@ -92,13 +92,13 @@ // The kernel entrypoint is always run for the time being const char* entryPointName = "&run"; - _device_context = _okra_ctx_create(); + _device_context = _okra_create_context(); // code is not null terminated, must be a better way to do this unsigned char* nullTerminatedCodeBuffer = (unsigned char*) malloc(code_len + 1); memcpy(nullTerminatedCodeBuffer, code, code_len); nullTerminatedCodeBuffer[code_len] = 0; - void* kernel = _okra_kernel_create(_device_context, nullTerminatedCodeBuffer, entryPointName); + void* kernel = _okra_create_kernel(_device_context, nullTerminatedCodeBuffer, entryPointName); free(nullTerminatedCodeBuffer); return kernel; } @@ -113,6 +113,16 @@ #define STD_BUFFER_SIZE 1024 +#define STRINGIFY(x) #x + +#define LOOKUP_OKRA_FUNCTION(name, alias) \ + _##alias = \ + CAST_TO_FN_PTR(alias##_func_t, os::dll_lookup(handle, STRINGIFY(name))); \ + if (_##alias == NULL) { \ + tty->print_cr("[HSAIL] ***** Error: Failed to lookup %s in %s, wrong version of OKRA?", STRINGIFY(name), okra_library_name); \ + return 0; \ + } \ + bool gpu::Hsail::probe_linkage() { if (okra_library_name != NULL) { char *buffer = (char*)malloc(STD_BUFFER_SIZE); @@ -123,34 +133,19 @@ free(buffer); if (handle != NULL) { - _okra_ctx_create = - CAST_TO_FN_PTR(okra_ctx_create_func_t, os::dll_lookup(handle, "okra_create_context")); - _okra_kernel_create = - CAST_TO_FN_PTR(okra_kernel_create_func_t, os::dll_lookup(handle, "okra_create_kernel")); - _okra_push_object = - CAST_TO_FN_PTR(okra_push_object_func_t, os::dll_lookup(handle, "okra_push_object")); - _okra_push_boolean = - CAST_TO_FN_PTR(okra_push_boolean_func_t, os::dll_lookup(handle, "okra_push_boolean")); - _okra_push_byte = - CAST_TO_FN_PTR(okra_push_byte_func_t, os::dll_lookup(handle, "okra_push_byte")); - _okra_push_double = - CAST_TO_FN_PTR(okra_push_double_func_t, os::dll_lookup(handle, "okra_push_double")); - _okra_push_float = - CAST_TO_FN_PTR(okra_push_float_func_t, os::dll_lookup(handle, "okra_push_float")); - _okra_push_int = - CAST_TO_FN_PTR(okra_push_int_func_t, os::dll_lookup(handle, "okra_push_int")); - _okra_push_long = - CAST_TO_FN_PTR(okra_push_long_func_t, os::dll_lookup(handle, "okra_push_long")); - _okra_execute_with_range = - CAST_TO_FN_PTR(okra_execute_with_range_func_t, os::dll_lookup(handle, "okra_execute_with_range")); - _okra_clearargs = - CAST_TO_FN_PTR(okra_clearargs_func_t, os::dll_lookup(handle, "okra_clearargs")); - _okra_register_heap = - CAST_TO_FN_PTR(okra_register_heap_func_t, os::dll_lookup(handle, "okra_register_heap")); + LOOKUP_OKRA_FUNCTION(okra_create_context, okra_create_context); + LOOKUP_OKRA_FUNCTION(okra_create_kernel, okra_create_kernel); + LOOKUP_OKRA_FUNCTION(okra_push_object, okra_push_object); + LOOKUP_OKRA_FUNCTION(okra_push_boolean, okra_push_boolean); + LOOKUP_OKRA_FUNCTION(okra_push_byte, okra_push_byte); + LOOKUP_OKRA_FUNCTION(okra_push_double, okra_push_double); + LOOKUP_OKRA_FUNCTION(okra_push_float, okra_push_float); + LOOKUP_OKRA_FUNCTION(okra_push_int, okra_push_int); + LOOKUP_OKRA_FUNCTION(okra_push_long, okra_push_long); + LOOKUP_OKRA_FUNCTION(okra_execute_with_range, okra_execute_with_range); + LOOKUP_OKRA_FUNCTION(okra_clearargs, okra_clearargs); + LOOKUP_OKRA_FUNCTION(okra_register_heap, okra_register_heap); - if (TraceGPUInteraction) { - tty->print_cr("[HSAIL] Success: library linkage _okra_clearargs=0x%08x", _okra_clearargs); - } return true; } else { // Unable to dlopen okra diff -r 833f8e96d0a5 -r 8b14bab15757 src/gpu/hsail/vm/gpu_hsail.hpp --- a/src/gpu/hsail/vm/gpu_hsail.hpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/gpu/hsail/vm/gpu_hsail.hpp Sat Nov 30 19:05:44 2013 +0100 @@ -44,8 +44,8 @@ #endif private: - typedef void* (*okra_ctx_create_func_t)(); - typedef void* (*okra_kernel_create_func_t)(void*, unsigned char *, const char *); + typedef void* (*okra_create_context_func_t)(); + typedef void* (*okra_create_kernel_func_t)(void*, unsigned char *, const char *); typedef bool (*okra_push_object_func_t)(void*, void*); typedef bool (*okra_push_boolean_func_t)(void*, jboolean); typedef bool (*okra_push_byte_func_t)(void*, jbyte); @@ -58,8 +58,8 @@ typedef bool (*okra_register_heap_func_t)(void*, size_t); public: - static okra_ctx_create_func_t _okra_ctx_create; - static okra_kernel_create_func_t _okra_kernel_create; + static okra_create_context_func_t _okra_create_context; + static okra_create_kernel_func_t _okra_create_kernel; static okra_push_object_func_t _okra_push_object; static okra_push_boolean_func_t _okra_push_boolean; static okra_push_byte_func_t _okra_push_byte; diff -r 833f8e96d0a5 -r 8b14bab15757 src/os_gpu/linux_ptx/vm/gpu_linux.cpp --- a/src/os_gpu/linux_ptx/vm/gpu_linux.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/os_gpu/linux_ptx/vm/gpu_linux.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -81,13 +81,19 @@ tty->print_cr("Found supported nVidia GPU device vendor : 0x%04x device 0x%04x", vendor, device); } break; - } else if (vendor == amd_vendor_id) { - gpu_device_exists = true; - set_target_il_type(gpu::HSAIL); - if (TraceGPUInteraction) { - tty->print_cr("Found supported AMD GPU device vendor : 0x%04x device 0x%04x", vendor, device); - } - break; + /* + * Remove AMD detection until we decide how to detect real HSA hardware. + * In the current form this check does not work correctly on AMD CPU system with + * Nvidia GPU. + * + * } else if (vendor == amd_vendor_id) { + * gpu_device_exists = true; + * set_target_il_type(gpu::HSAIL); + * if (TraceGPUInteraction) { + * tty->print_cr("Found supported AMD GPU device vendor : 0x%04x device 0x%04x", vendor, device); + * } + * break; + */ } } diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/asm/codeBuffer.cpp --- a/src/share/vm/asm/codeBuffer.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/asm/codeBuffer.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -1096,8 +1096,9 @@ CodeString* c = find(offset); while (c && c->offset() == offset) { stream->bol(); - stream->print(" ;; "); - stream->print_cr(c->string()); + stream->print_raw(" ;; "); + // Don't interpret as format strings since it could contain % + stream->print_raw_cr(c->string()); c = c->next_comment(); } } diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/c1/c1_GraphBuilder.cpp --- a/src/share/vm/c1/c1_GraphBuilder.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -4340,11 +4340,15 @@ #endif // PRODUCT void GraphBuilder::profile_call(ciMethod* callee, Value recv, ciKlass* known_holder, Values* obj_args, bool inlined) { - // A default method's holder is an interface - if (known_holder != NULL && known_holder->is_interface()) { - assert(known_holder->is_instance_klass() && ((ciInstanceKlass*)known_holder)->has_default_methods(), "should be default method"); - known_holder = NULL; + assert(known_holder == NULL || (known_holder->is_instance_klass() && + (!known_holder->is_interface() || + ((ciInstanceKlass*)known_holder)->has_default_methods())), "should be default method"); + if (known_holder != NULL) { + if (known_holder->exact_klass() == NULL) { + known_holder = compilation()->cha_exact_type(known_holder); + } } + append(new ProfileCall(method(), bci(), callee, recv, known_holder, obj_args, inlined)); } diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/c1/c1_Runtime1.cpp --- a/src/share/vm/c1/c1_Runtime1.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/c1/c1_Runtime1.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -169,7 +169,7 @@ RegisterMap reg_map(thread, false); frame runtime_frame = thread->last_frame(); frame caller_frame = runtime_frame.sender(®_map); - Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint); + Deoptimization::deoptimize_frame(thread, caller_frame.id()); assert(caller_is_deopted(), "Must be deoptimized"); } } @@ -431,7 +431,7 @@ if (osr_nm != NULL) { RegisterMap map(thread, false); frame fr = thread->last_frame().sender(&map); - Deoptimization::deoptimize_frame(thread, fr.id(), Deoptimization::Reason_constraint); + Deoptimization::deoptimize_frame(thread, fr.id()); } JRT_BLOCK_END return NULL; @@ -502,7 +502,7 @@ // We don't really want to deoptimize the nmethod itself since we // can actually continue in the exception handler ourselves but I // don't see an easy way to have the desired effect. - Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint); + Deoptimization::deoptimize_frame(thread, caller_frame.id()); assert(caller_is_deopted(), "Must be deoptimized"); return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls(); @@ -696,7 +696,7 @@ assert(CodeCache::find_nmethod(caller_frame.pc()) != NULL, "sanity"); // Deoptimize the caller frame. - Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint); + Deoptimization::deoptimize_frame(thread, caller_frame.id()); // Return to the now deoptimized frame. JRT_END @@ -932,7 +932,7 @@ nm->make_not_entrant(); } - Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint); + Deoptimization::deoptimize_frame(thread, caller_frame.id()); // Return to the now deoptimized frame. } @@ -1434,7 +1434,7 @@ } - Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_none); + Deoptimization::deoptimize_frame(thread, caller_frame.id()); JRT_END diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -361,8 +361,13 @@ // constructor used to create a method CodeInstaller::CodeInstaller(Handle& compiled_code, GraalEnv::CodeInstallResult& result, CodeBlob*& cb, Handle installed_code, Handle triggered_deoptimizations) { - GraalCompiler::initialize_buffer_blob(); - CodeBuffer buffer(JavaThread::current()->get_buffer_blob()); + BufferBlob* buffer_blob = GraalCompiler::initialize_buffer_blob(); + if (buffer_blob == NULL) { + result = GraalEnv::cache_full; + return; + } + + CodeBuffer buffer(buffer_blob); jobject compiled_code_obj = JNIHandles::make_local(compiled_code()); initialize_assumptions(JNIHandles::resolve(compiled_code_obj)); diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/graal/graalCompiler.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -56,7 +56,13 @@ _deopted_leaf_graph_count = 0; - initialize_buffer_blob(); + BufferBlob* buffer_blob = initialize_buffer_blob(); + if (buffer_blob == NULL) { + // If we are called from JNI_CreateJavaVM we cannot use set_state yet because it takes a lock. + // set_state(failed); + } else { + // set_state(initialized); + } JNIEnv *env = ((JavaThread *) Thread::current())->jni_environment(); jclass klass = env->FindClass("com/oracle/graal/hotspot/bridge/CompilerToVMImpl"); @@ -106,10 +112,12 @@ _initialized = true; CompilationPolicy::completed_vm_startup(); if (bootstrap) { + // Avoid -Xcomp and -Xbatch problems by turning on interpreter and background compilation for bootstrapping. + FlagSetting a(UseInterpreter, true); + FlagSetting b(BackgroundCompilation, true); VMToCompiler::bootstrap(); } - #ifndef PRODUCT if (CompileTheWorld) { // We turn off CompileTheWorld so that Graal can @@ -163,14 +171,16 @@ return array; } -void GraalCompiler::initialize_buffer_blob() { - +BufferBlob* GraalCompiler::initialize_buffer_blob() { JavaThread* THREAD = JavaThread::current(); - if (THREAD->get_buffer_blob() == NULL) { - BufferBlob* blob = BufferBlob::create("Graal thread-local CodeBuffer", GraalNMethodSizeLimit); - guarantee(blob != NULL, "must create code buffer"); - THREAD->set_buffer_blob(blob); + BufferBlob* buffer_blob = THREAD->get_buffer_blob(); + if (buffer_blob == NULL) { + buffer_blob = BufferBlob::create("Graal thread-local CodeBuffer", GraalNMethodSizeLimit); + if (buffer_blob != NULL) { + THREAD->set_buffer_blob(buffer_blob); + } } + return buffer_blob; } void GraalCompiler::compile_method(methodHandle method, int entry_bci, jboolean blocking) { diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/graal/graalCompiler.hpp --- a/src/share/vm/graal/graalCompiler.hpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/graal/graalCompiler.hpp Sat Nov 30 19:05:44 2013 +0100 @@ -105,7 +105,7 @@ return cp_index; } - static void initialize_buffer_blob(); + static BufferBlob* initialize_buffer_blob(); }; // Tracing macros diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/graal/graalCompilerToGPU.cpp --- a/src/share/vm/graal/graalCompilerToGPU.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/graal/graalCompilerToGPU.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -177,7 +177,9 @@ C2V_VMENTRY(jboolean, deviceInit, (JNIEnv *env, jobject)) if (gpu::is_available() == false || gpu::has_gpu_linkage() == false) { - tty->print_cr("deviceInit - not available / no linkage"); + if (TraceGPUInteraction) { + tty->print_cr("deviceInit - not available / no linkage"); + } return false; } if (gpu::is_initialized()) { @@ -190,7 +192,9 @@ C2V_VMENTRY(jint, availableProcessors, (JNIEnv *env, jobject)) if (gpu::is_available() == false || gpu::has_gpu_linkage() == false) { - tty->print_cr("deviceInit - not available / no linkage"); + if (TraceGPUInteraction) { + tty->print_cr("deviceInit - not available / no linkage"); + } return false; } return gpu::available_processors(); diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -1025,7 +1025,7 @@ method_data = MethodData::allocate(loader_data, method, CHECK); method->set_method_data(method_data); } else { - method_data->initialize(); + method_data->initialize(true); } C2V_END diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/graal/graalEnv.hpp --- a/src/share/vm/graal/graalEnv.hpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/graal/graalEnv.hpp Sat Nov 30 19:05:44 2013 +0100 @@ -58,7 +58,6 @@ public: - // Must be kept in sync with the enum in the HotSpot implementation of CompilerToVM enum CodeInstallResult { ok, dependencies_failed, diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/graal/vmStructs_graal.hpp --- a/src/share/vm/graal/vmStructs_graal.hpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/graal/vmStructs_graal.hpp Sat Nov 30 19:05:44 2013 +0100 @@ -26,14 +26,18 @@ #define SHARE_VM_GRAAL_VMSTRUCTS_GRAAL_HPP #include "compiler/abstractCompiler.hpp" +#include "graal/graalEnv.hpp" #define VM_STRUCTS_GRAAL(nonstatic_field, static_field) \ - \ static_field(java_lang_Class, _graal_mirror_offset, int) \ - \ #define VM_TYPES_GRAAL(declare_type, declare_toplevel_type) \ - \ +#define VM_INT_CONSTANTS_GRAAL(declare_constant) \ + declare_constant(Deoptimization::Reason_aliasing) \ + declare_constant(GraalEnv::ok) \ + declare_constant(GraalEnv::dependencies_failed) \ + declare_constant(GraalEnv::cache_full) \ + declare_constant(GraalEnv::code_too_large) \ #endif // SHARE_VM_GRAAL_VMSTRUCTS_GRAAL_HPP diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/oops/methodData.cpp --- a/src/share/vm/oops/methodData.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/oops/methodData.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -821,8 +821,7 @@ while ((c = stream.next()) >= 0) { int size_in_bytes = compute_data_size(&stream); data_size += size_in_bytes; - - if (is_empty_data(size_in_bytes, c)) empty_bc_count += 1; + if (size_in_bytes == 0 GRAAL_ONLY(&& Bytecodes::can_trap(c))) empty_bc_count += 1; } int object_size = in_bytes(data_offset()) + data_size; @@ -830,7 +829,6 @@ int extra_data_count = compute_extra_data_count(data_size, empty_bc_count); object_size += extra_data_count * DataLayout::compute_size_in_bytes(0); -#ifndef GRAALVM // Add a cell to record information about modified arguments. int arg_size = method->size_of_parameters(); object_size += DataLayout::compute_size_in_bytes(arg_size+1); @@ -841,7 +839,6 @@ if (args_cell > 0) { object_size += DataLayout::compute_size_in_bytes(args_cell); } -#endif return object_size; } @@ -1051,7 +1048,7 @@ initialize(); } -void MethodData::initialize() { +void MethodData::initialize(bool for_reprofile) { No_Safepoint_Verifier no_safepoint; // init function atomic wrt GC ResourceMark rm; @@ -1068,8 +1065,7 @@ while ((c = stream.next()) >= 0) { int size_in_bytes = initialize_data(&stream, data_size); data_size += size_in_bytes; - - if (is_empty_data(size_in_bytes, c)) empty_bc_count += 1; + if (size_in_bytes == 0 GRAAL_ONLY(&& Bytecodes::can_trap(c))) empty_bc_count += 1; } _data_size = data_size; int object_size = in_bytes(data_offset()) + data_size; @@ -1077,11 +1073,14 @@ // Add some extra DataLayout cells (at least one) to track stray traps. int extra_data_count = compute_extra_data_count(data_size, empty_bc_count); int extra_size = extra_data_count * DataLayout::compute_size_in_bytes(0); - object_size += extra_size; - Copy::zero_to_bytes((HeapWord*) extra_data_base(), extra_size); +#ifdef GRAAL + if (for_reprofile) { + // Clear out extra data + Copy::zero_to_bytes((HeapWord*) extra_data_base(), extra_size); + } +#endif -#ifndef GRAALVM // Add a cell to record information about modified arguments. // Set up _args_modified array after traps cells so that // the code for traps cells works. @@ -1107,9 +1106,6 @@ } else { _parameters_type_data_di = -1; } -#else - _parameters_type_data_di = -1; -#endif // Set an initial hint. Don't use set_hint_di() because // first_di() may be out of bounds if data_size is 0. @@ -1119,6 +1115,7 @@ post_initialize(&stream); + assert(object_size == compute_allocation_size_in_bytes(methodHandle(_method)), "MethodData: computed size != initialized size"); set_size(object_size); } @@ -1143,14 +1140,6 @@ sizeof(_trap_hist) / sizeof(HeapWord)); } -bool MethodData::is_empty_data(int size_in_bytes, Bytecodes::Code code) { -#ifdef GRAAL - return size_in_bytes == 0 && Bytecodes::can_trap(code); -#else - return size_in_bytes == 0; -#endif -} - // Get a measure of how much mileage the method has on it. int MethodData::mileage_of(Method* method) { int mileage = 0; diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/oops/methodData.hpp --- a/src/share/vm/oops/methodData.hpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/oops/methodData.hpp Sat Nov 30 19:05:44 2013 +0100 @@ -1896,7 +1896,7 @@ MethodData() {}; // For ciMethodData bool is_methodData() const volatile { return true; } - void initialize(); + void initialize(bool for_reprofile = false); // Whole-method sticky bits and flags enum { @@ -2103,7 +2103,6 @@ bool is_mature() const; // consult mileage and ProfileMaturityPercentage static int mileage_of(Method* m); - static bool is_empty_data(int size, Bytecodes::Code code); // Support for interprocedural escape analysis, from Thomas Kotzmann. enum EscapeFlag { diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/opto/runtime.cpp --- a/src/share/vm/opto/runtime.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/opto/runtime.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -1,5 +1,6 @@ /* * Copyright (c) 1998, 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 @@ -1185,7 +1186,7 @@ frame caller_frame = stub_frame.sender(®_map); // Deoptimize the caller frame. - Deoptimization::deoptimize_frame(thread, caller_frame.id(), Deoptimization::Reason_constraint); + Deoptimization::deoptimize_frame(thread, caller_frame.id()); } diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/prims/jni.cpp --- a/src/share/vm/prims/jni.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/prims/jni.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -5176,7 +5176,11 @@ #ifdef GRAAL // GraalCompiler needs to have been created in compileBroker.cpp GraalCompiler* graal_compiler = GraalCompiler::instance(); - graal_compiler->initialize(); + if (graal_compiler != NULL) { + graal_compiler->initialize(); + } else { + assert(!UseCompiler, "why isn't there are compiler?"); + } #endif // Tracks the time application was running before GC diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/prims/jvmtiEnv.cpp --- a/src/share/vm/prims/jvmtiEnv.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/prims/jvmtiEnv.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -1442,7 +1442,7 @@ // If any of the top 2 frames is a compiled one, need to deoptimize it for (int i = 0; i < 2; i++) { if (!is_interpreted[i]) { - Deoptimization::deoptimize_frame(java_thread, frame_sp[i], Deoptimization::Reason_constraint); + Deoptimization::deoptimize_frame(java_thread, frame_sp[i]); } } diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/prims/jvmtiEnvBase.cpp --- a/src/share/vm/prims/jvmtiEnvBase.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/prims/jvmtiEnvBase.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -1338,7 +1338,7 @@ if (!vf->fr().can_be_deoptimized()) { return JVMTI_ERROR_OPAQUE_FRAME; } - Deoptimization::deoptimize_frame(java_thread, jvf->fr().id(), Deoptimization::Reason_constraint); + Deoptimization::deoptimize_frame(java_thread, jvf->fr().id()); } // Get information about method return type diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/prims/jvmtiImpl.cpp --- a/src/share/vm/prims/jvmtiImpl.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/prims/jvmtiImpl.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -752,7 +752,7 @@ // Schedule deoptimization so that eventually the local // update will be written to an interpreter frame. - Deoptimization::deoptimize_frame(_jvf->thread(), _jvf->fr().id(), Deoptimization::Reason_constraint); + Deoptimization::deoptimize_frame(_jvf->thread(), _jvf->fr().id()); // Now store a new value for the local which will be applied // once deoptimization occurs. Note however that while this diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/runtime/deoptimization.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -1214,6 +1214,10 @@ fr.deoptimize(thread); } +void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map) { + deoptimize(thread, fr, map, Reason_constraint); +} + void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map, DeoptReason reason) { // Deoptimize only if the frame comes from compile code. // Do not deoptimize the frame which is already patched @@ -1253,6 +1257,9 @@ } } +void Deoptimization::deoptimize_frame(JavaThread* thread, intptr_t* id) { + deoptimize_frame(thread, id, Reason_constraint); +} // JVMTI PopFrame support JRT_LEAF(void, Deoptimization::popframe_preserve_args(JavaThread* thread, int bytes_to_save, void* start_address)) @@ -1948,7 +1955,8 @@ "div0_check", "age" GRAAL_ONLY("|jsr_mismatch"), "predicate", - "loop_limit_check" + "loop_limit_check", + GRAAL_ONLY("aliasing") }; const char* Deoptimization::_trap_action_name[Action_LIMIT] = { // Note: Keep this in sync. with enum DeoptAction. diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/runtime/deoptimization.hpp --- a/src/share/vm/runtime/deoptimization.hpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/runtime/deoptimization.hpp Sat Nov 30 19:05:44 2013 +0100 @@ -72,6 +72,9 @@ Reason_age, // nmethod too old; tier threshold reached Reason_predicate, // compiler generated predicate failed Reason_loop_limit_check, // compiler generated loop limits check failed +#ifdef GRAAL + Reason_aliasing, // optimistic assumption about aliasing failed +#endif Reason_LIMIT, #ifdef GRAAL @@ -121,6 +124,7 @@ static int deoptimize_dependents(); // Deoptimizes a frame lazily. nmethod gets patched deopt happens on return to the frame + static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map); static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map, DeoptReason reason); private: @@ -261,6 +265,7 @@ // if thread is not the current thread then execute // VM_DeoptimizeFrame otherwise deoptimize directly. static void deoptimize_frame(JavaThread* thread, intptr_t* id, DeoptReason reason); + static void deoptimize_frame(JavaThread* thread, intptr_t* id); // Statistics static void gather_statistics(DeoptReason reason, DeoptAction action, diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/runtime/java.cpp --- a/src/share/vm/runtime/java.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/runtime/java.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -462,7 +462,9 @@ static jint volatile _before_exit_status = BEFORE_EXIT_NOT_RUN; #ifdef GRAAL - GraalCompiler::instance()->exit(); + if (GraalCompiler::instance() != NULL) { + GraalCompiler::instance()->exit(); + } #endif // Note: don't use a Mutex to guard the entire before_exit(), as diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/runtime/safepoint.cpp --- a/src/share/vm/runtime/safepoint.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/runtime/safepoint.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -1081,7 +1081,7 @@ // as otherwise we may never deliver it. if (thread()->has_async_condition()) { ThreadInVMfromJavaNoAsyncException __tiv(thread()); - Deoptimization::deoptimize_frame(thread(), caller_fr.id(), Deoptimization::Reason_constraint); + Deoptimization::deoptimize_frame(thread(), caller_fr.id()); } // If an exception has been installed we must check for a pending deoptimization diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/runtime/thread.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -2265,7 +2265,7 @@ RegisterMap reg_map(this, UseBiasedLocking); frame compiled_frame = f.sender(®_map); if (!StressCompiledExceptionHandlers && compiled_frame.can_be_deoptimized()) { - Deoptimization::deoptimize(this, compiled_frame, ®_map, Deoptimization::Reason_constraint); + Deoptimization::deoptimize(this, compiled_frame, ®_map); } } } @@ -2698,7 +2698,7 @@ trace_frames(); trace_stack(); } - Deoptimization::deoptimize(this, *fst.current(), fst.register_map(), Deoptimization::Reason_constraint); + Deoptimization::deoptimize(this, *fst.current(), fst.register_map()); } } @@ -2734,7 +2734,7 @@ this->name(), nm != NULL ? nm->compile_id() : -1); } - Deoptimization::deoptimize(this, *fst.current(), fst.register_map(), Deoptimization::Reason_constraint); + Deoptimization::deoptimize(this, *fst.current(), fst.register_map()); } } } @@ -3378,10 +3378,6 @@ // Initialize the os module before using TLS os::init(); - // Probe for existance of supported GPU and initialize it if one - // exists. - gpu::init(); - // Initialize system properties. Arguments::init_system_properties(); @@ -3395,6 +3391,10 @@ jint parse_result = Arguments::parse(args); if (parse_result != JNI_OK) return parse_result; + // Probe for existance of supported GPU and initialize it if one + // exists. + gpu::init(); + os::init_before_ergo(); jint ergo_result = Arguments::apply_ergo(); diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/runtime/vframeArray.cpp --- a/src/share/vm/runtime/vframeArray.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/runtime/vframeArray.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -251,9 +251,6 @@ case Deoptimization::Unpack_uncommon_trap: case Deoptimization::Unpack_reexecute: // redo last byte code -#ifdef GRAALVM - assert(should_reexecute(), ""); -#endif pc = Interpreter::deopt_entry(vtos, 0); use_next_mdp = false; break; diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/runtime/vmStructs.cpp --- a/src/share/vm/runtime/vmStructs.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/runtime/vmStructs.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -2373,6 +2373,19 @@ /**************/ \ \ declare_constant(DataLayout::cell_size) \ + declare_constant(DataLayout::no_tag) \ + declare_constant(DataLayout::bit_data_tag) \ + declare_constant(DataLayout::counter_data_tag) \ + declare_constant(DataLayout::jump_data_tag) \ + declare_constant(DataLayout::receiver_type_data_tag) \ + declare_constant(DataLayout::virtual_call_data_tag) \ + declare_constant(DataLayout::ret_data_tag) \ + declare_constant(DataLayout::branch_data_tag) \ + declare_constant(DataLayout::multi_branch_data_tag) \ + declare_constant(DataLayout::arg_info_data_tag) \ + declare_constant(DataLayout::call_type_data_tag) \ + declare_constant(DataLayout::virtual_call_type_data_tag) \ + declare_constant(DataLayout::parameters_type_data_tag) \ \ /*************************************/ \ /* InstanceKlass enum */ \ @@ -3011,6 +3024,10 @@ GENERATE_C2_VM_INT_CONSTANT_ENTRY, GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY) +#ifdef GRAAL + VM_INT_CONSTANTS_GRAAL(GENERATE_VM_INT_CONSTANT_ENTRY) +#endif + #if INCLUDE_ALL_GCS VM_INT_CONSTANTS_CMS(GENERATE_VM_INT_CONSTANT_ENTRY) diff -r 833f8e96d0a5 -r 8b14bab15757 src/share/vm/runtime/vm_operations.cpp --- a/src/share/vm/runtime/vm_operations.cpp Fri Nov 22 14:45:09 2013 +0100 +++ b/src/share/vm/runtime/vm_operations.cpp Sat Nov 30 19:05:44 2013 +0100 @@ -150,7 +150,7 @@ if (fst.current()->can_be_deoptimized()) { if (fcount++ == fnum) { fcount = 0; - Deoptimization::deoptimize(thread, *fst.current(), fst.register_map(), Deoptimization::Reason_constraint); + Deoptimization::deoptimize(thread, *fst.current(), fst.register_map()); } } }