# HG changeset patch # User Stefan Anzinger # Date 1405477288 25200 # Node ID 446750355e5f6e71c9be34a62f81be359506811b # Parent 072b9501f5f9dccf85af79af899db0480251e8a0# Parent d6ac7470603e0e0d3dfb5cd9e6b2f39c0ad6625d Merge diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,8 +22,6 @@ */ package com.oracle.graal.api.code; -import static com.oracle.graal.api.meta.MetaUtil.*; - import java.io.*; import java.lang.invoke.*; import java.util.*; @@ -71,7 +69,7 @@ @Override public String toString() { - return "NoFinalizableSubclass[receiverType=" + toJavaName(receiverType) + "]"; + return "NoFinalizableSubclass[receiverType=" + receiverType.toJavaName() + "]"; } } @@ -97,7 +95,7 @@ this.context = context; this.subtype = subtype; assert !subtype.isAbstract() : subtype.toString() + " : " + context.toString(); - assert !subtype.isArray() || getElementalType(subtype).isFinal() : subtype.toString() + " : " + context.toString(); + assert !subtype.isArray() || subtype.getElementalType().isFinal() : subtype.toString() + " : " + context.toString(); } @Override @@ -120,7 +118,7 @@ @Override public String toString() { - return "ConcreteSubtype[context=" + toJavaName(context) + ", subtype=" + toJavaName(subtype) + "]"; + return "ConcreteSubtype[context=" + context.toJavaName() + ", subtype=" + subtype.toJavaName() + "]"; } } @@ -174,7 +172,7 @@ @Override public String toString() { - return "ConcreteMethod[method=" + format("%H.%n(%p)", method) + ", context=" + toJavaName(context) + ", impl=" + format("%H.%n(%p)", impl) + "]"; + return "ConcreteMethod[method=" + method.format("%H.%n(%p)") + ", context=" + context.toJavaName() + ", impl=" + impl.format("%H.%n(%p)") + "]"; } } @@ -207,7 +205,7 @@ @Override public String toString() { - return "MethodContents[method=" + format("%H.%n(%p)", method) + "]"; + return "MethodContents[method=" + method.format("%H.%n(%p)") + "]"; } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,7 +22,6 @@ */ package com.oracle.graal.api.code; -import static com.oracle.graal.api.meta.MetaUtil.*; import java.util.*; import com.oracle.graal.api.meta.*; @@ -153,6 +152,6 @@ * @return true if {@code type} can have subtypes */ public static boolean canHaveSubtype(ResolvedJavaType type) { - return !getElementalType(type).isFinal(); + return !type.getElementalType().isFinal(); } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,8 +22,6 @@ */ package com.oracle.graal.api.code; -import static com.oracle.graal.api.meta.MetaUtil.*; - import java.util.*; import com.oracle.graal.api.meta.*; @@ -70,7 +68,7 @@ private static StringBuilder appendValue(StringBuilder buf, Value value, Set visited) { if (value instanceof VirtualObject) { VirtualObject vo = (VirtualObject) value; - buf.append("vobject:").append(toJavaName(vo.type, false)).append(':').append(vo.id); + buf.append("vobject:").append(vo.type.toJavaName(false)).append(':').append(vo.id); if (!visited.contains(vo)) { visited.add(vo); buf.append('{'); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.api.meta.jdk8.test/src/com/oracle/graal/api/meta/jdk8/test/TestResolvedJavaMethodJDK8.java --- a/graal/com.oracle.graal.api.meta.jdk8.test/src/com/oracle/graal/api/meta/jdk8/test/TestResolvedJavaMethodJDK8.java Tue Jul 15 19:15:46 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.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, ResolvedJavaMethod> e : constructors.entrySet()) { - ResolvedJavaMethod m = e.getValue(); - assertFalse(m.isDefault()); - } - } -} diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/ResolvedJavaTypeResolveMethodTest.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/ResolvedJavaTypeResolveMethodTest.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/ResolvedJavaTypeResolveMethodTest.java Tue Jul 15 19:21:28 2014 -0700 @@ -156,7 +156,7 @@ } - private static ResolvedJavaMethod getMethod(ResolvedJavaType type, String methodName) { + static ResolvedJavaMethod getMethod(ResolvedJavaType type, String methodName) { for (ResolvedJavaMethod method : type.getDeclaredMethods()) { if (method.getName().equals(methodName)) { return method; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,6 +24,11 @@ import static org.junit.Assert.*; +import java.io.*; +import java.net.*; +import java.util.*; +import java.util.stream.*; + import org.junit.*; import com.oracle.graal.api.meta.*; @@ -45,4 +50,91 @@ assertEquals(expected, actual); } } + + static class A { + A or(A other) { + return other; + } + } + + @Test + public void testResolve() throws ClassNotFoundException { + String classPath = System.getProperty("java.class.path"); + String[] parts = classPath.split(File.pathSeparator); + URL[] urls = Arrays.asList(parts).stream().map(e -> asURL(e)).collect(Collectors.toList()).toArray(new URL[parts.length]); + URLClassLoader clOne = newClassLoader(urls); + URLClassLoader clTwo = newClassLoader(urls); + + String className = getClass().getName() + "$A"; + Class aClassOne = Class.forName(className, true, clOne); + Class aClassTwo = Class.forName(getClass().getName() + "$A", true, clTwo); + + assertNotEquals(aClassOne, aClassTwo); + assertNotEquals(aClassOne.getClassLoader(), aClassTwo.getClassLoader()); + + ResolvedJavaType aTypeOne = metaAccess.lookupJavaType(aClassOne); + ResolvedJavaType aTypeTwo = metaAccess.lookupJavaType(aClassTwo); + + assertNotEquals(aTypeOne, aTypeTwo); + + checkResolveWithoutAccessingClass(aTypeOne); + checkResolveWithoutAccessingClass(aTypeTwo); + + assertEquals(aTypeOne.resolve(aTypeOne), aTypeOne); + assertNotEquals(aTypeOne.resolve(aTypeTwo), aTypeOne); + assertEquals(aTypeOne.resolve(aTypeTwo), aTypeTwo); + + assertEquals(aTypeTwo.resolve(aTypeTwo), aTypeTwo); + assertNotEquals(aTypeTwo.resolve(aTypeOne), aTypeTwo); + assertEquals(aTypeTwo.resolve(aTypeOne), aTypeOne); + + ResolvedJavaMethod m = ResolvedJavaTypeResolveMethodTest.getMethod(aTypeOne, "or"); + JavaType resolvedTypeOne = m.getSignature().getParameterType(0, aTypeOne); + JavaType resolvedTypeTwo = m.getSignature().getReturnType(aTypeOne); + JavaType unresolvedTypeOne = m.getSignature().getParameterType(0, null); + JavaType unresolvedTypeTwo = m.getSignature().getReturnType(null); + + assertTrue(resolvedTypeOne instanceof ResolvedJavaType); + assertTrue(resolvedTypeTwo instanceof ResolvedJavaType); + assertFalse(unresolvedTypeOne instanceof ResolvedJavaType); + assertFalse(unresolvedTypeTwo instanceof ResolvedJavaType); + + assertEquals(resolvedTypeOne.resolve(aTypeOne), aTypeOne); + assertEquals(resolvedTypeOne.resolve(aTypeTwo), aTypeTwo); + assertEquals(resolvedTypeTwo.resolve(aTypeOne), aTypeOne); + assertEquals(resolvedTypeTwo.resolve(aTypeTwo), aTypeTwo); + + checkResolveWithoutAccessingClass(unresolvedTypeOne); + checkResolveWithoutAccessingClass(unresolvedTypeTwo); + + assertEquals(unresolvedTypeOne.resolve(aTypeOne), aTypeOne); + assertEquals(unresolvedTypeOne.resolve(aTypeTwo), aTypeTwo); + } + + private static void checkResolveWithoutAccessingClass(JavaType type) { + try { + type.resolve(null); + fail(); + } catch (NullPointerException e) { + } + } + + private static URLClassLoader newClassLoader(URL[] urls) { + URLClassLoader cl = new URLClassLoader(urls) { + @Override + protected java.lang.Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + boolean callSuper = name.startsWith("java/") || name.startsWith("java."); + return callSuper ? super.loadClass(name, resolve) : super.findClass(name); + } + }; + return cl; + } + + private static URL asURL(String e) { + try { + return new File(e).toURI().toURL(); + } catch (MalformedURLException e1) { + throw new RuntimeException(e1); + } + } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java Tue Jul 15 19:21:28 2014 -0700 @@ -44,7 +44,7 @@ assertEquals(c.getModifiers(), type.getModifiers()); if (!type.isArray()) { assertEquals(type.getName(), toInternalName(c.getName())); - assertEquals(toJavaName(type), c.getName()); + assertEquals(type.toJavaName(), c.getName()); } } } diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java Tue Jul 15 19:21:28 2014 -0700 @@ -267,6 +267,18 @@ assertTrue(2 <= method2StackSize && method2StackSize <= 4); } + @Test + public void isDefaultTest() { + for (Map.Entry e : methods.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + assertEquals(e.getKey().isDefault(), m.isDefault()); + } + for (Map.Entry, ResolvedJavaMethod> e : constructors.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + assertFalse(m.isDefault()); + } + } + private Method findTestMethod(Method apiMethod) { String testName = apiMethod.getName() + "Test"; for (Method m : getClass().getDeclaredMethods()) { @@ -291,7 +303,8 @@ "getLineNumberTable", "getLocalVariableTable", "isInVirtualMethodTable", - "isDefault" // tested in TestResolvedJavaMethodJDK8 + "toParameterTypes", + "getParameterAnnotation" }; // @formatter:on diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Tue Jul 15 19:21:28 2014 -0700 @@ -709,7 +709,9 @@ "getSourceFileName", "getClassFilePath", "isLocal", + "isJavaLangObject", "isMember", + "getElementalType", "getEnclosingType" }; // @formatter:on diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java Tue Jul 15 19:21:28 2014 -0700 @@ -93,7 +93,7 @@ @Override public String toString() { - return "BaseProfilingInfo<" + MetaUtil.profileToString(this, null, "; ") + ">"; + return "BaseProfilingInfo<" + this.toString(null, "; ") + ">"; } public void setMature() { diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaField.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaField.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaField.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,6 +22,8 @@ */ package com.oracle.graal.api.meta; +import java.util.*; + /** * Represents a reference to a Java field, either resolved or unresolved fields. Fields, like * methods and types, are resolved through {@link ConstantPool constant pools}. @@ -49,4 +51,77 @@ * field. */ JavaType getDeclaringClass(); + + /** + * Gets a string for this field formatted according to a given format specification. A format + * specification is composed of characters that are to be copied verbatim to the result and + * specifiers that denote an attribute of this field that is to be copied to the result. A + * specifier is a single character preceded by a '%' character. The accepted specifiers and the + * field attributes they denote are described below: + * + *
+     *     Specifier | Description                                          | Example(s)
+     *     ----------+------------------------------------------------------------------------------------------
+     *     'T'       | Qualified type                                       | "int" "java.lang.String"
+     *     't'       | Unqualified type                                     | "int" "String"
+     *     'H'       | Qualified holder                                     | "java.util.Map.Entry"
+     *     'h'       | Unqualified holder                                   | "Entry"
+     *     'n'       | Field name                                           | "age"
+     *     'f'       | Indicator if field is unresolved, static or instance | "unresolved" "static" "instance"
+     *     '%'       | A '%' character                                      | "%"
+     * 
+ * + * @param format a format specification + * @return the result of formatting this field according to {@code format} + * @throws IllegalFormatException if an illegal specifier is encountered in {@code format} + */ + default String format(String format) throws IllegalFormatException { + final StringBuilder sb = new StringBuilder(); + int index = 0; + JavaType type = getType(); + while (index < format.length()) { + final char ch = format.charAt(index++); + if (ch == '%') { + if (index >= format.length()) { + throw new UnknownFormatConversionException("An unquoted '%' character cannot terminate a field format specification"); + } + final char specifier = format.charAt(index++); + boolean qualified = false; + switch (specifier) { + case 'T': + qualified = true; + // fall through + case 't': { + sb.append(type.toJavaName(qualified)); + break; + } + case 'H': + qualified = true; + // fall through + case 'h': { + sb.append(getDeclaringClass().toJavaName(qualified)); + break; + } + case 'n': { + sb.append(getName()); + break; + } + case 'f': { + sb.append(!(this instanceof ResolvedJavaField) ? "unresolved" : ((ResolvedJavaField) this).isStatic() ? "static" : "instance"); + break; + } + case '%': { + sb.append('%'); + break; + } + default: { + throw new UnknownFormatConversionException(String.valueOf(specifier)); + } + } + } else { + sb.append(ch); + } + } + return sb.toString(); + } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaMethod.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaMethod.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaMethod.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,6 +22,8 @@ */ package com.oracle.graal.api.meta; +import java.util.*; + /** * Represents a reference to a Java method, either resolved or unresolved. Methods, like fields and * types, are resolved through {@link ConstantPool constant pools}. @@ -43,4 +45,97 @@ * Returns the signature of this method. */ Signature getSignature(); + + /** + * Gets a string for this method formatted according to a given format specification. A format + * specification is composed of characters that are to be copied verbatim to the result and + * specifiers that denote an attribute of this method that is to be copied to the result. A + * specifier is a single character preceded by a '%' character. The accepted specifiers and the + * method attributes they denote are described below: + * + *
+     *     Specifier | Description                                          | Example(s)
+     *     ----------+------------------------------------------------------------------------------------------
+     *     'R'       | Qualified return type                                | "int" "java.lang.String"
+     *     'r'       | Unqualified return type                              | "int" "String"
+     *     'H'       | Qualified holder                                     | "java.util.Map.Entry"
+     *     'h'       | Unqualified holder                                   | "Entry"
+     *     'n'       | Method name                                          | "add"
+     *     'P'       | Qualified parameter types, separated by ', '         | "int, java.lang.String"
+     *     'p'       | Unqualified parameter types, separated by ', '       | "int, String"
+     *     'f'       | Indicator if method is unresolved, static or virtual | "unresolved" "static" "virtual"
+     *     '%'       | A '%' character                                      | "%"
+     * 
+ * + * @param format a format specification + * @return the result of formatting this method according to {@code format} + * @throws IllegalFormatException if an illegal specifier is encountered in {@code format} + */ + default String format(String format) throws IllegalFormatException { + final StringBuilder sb = new StringBuilder(); + int index = 0; + Signature sig = null; + while (index < format.length()) { + final char ch = format.charAt(index++); + if (ch == '%') { + if (index >= format.length()) { + throw new UnknownFormatConversionException("An unquoted '%' character cannot terminate a method format specification"); + } + final char specifier = format.charAt(index++); + boolean qualified = false; + switch (specifier) { + case 'R': + qualified = true; + // fall through + case 'r': { + if (sig == null) { + sig = getSignature(); + } + sb.append(sig.getReturnType(null).toJavaName(qualified)); + break; + } + case 'H': + qualified = true; + // fall through + case 'h': { + sb.append(getDeclaringClass().toJavaName(qualified)); + break; + } + case 'n': { + sb.append(getName()); + break; + } + case 'P': + qualified = true; + // fall through + case 'p': { + if (sig == null) { + sig = getSignature(); + } + for (int i = 0; i < sig.getParameterCount(false); i++) { + if (i != 0) { + sb.append(", "); + } + sb.append(sig.getParameterType(i, null).toJavaName(qualified)); + } + break; + } + case 'f': { + sb.append(!(this instanceof ResolvedJavaMethod) ? "unresolved" : ((ResolvedJavaMethod) this).isStatic() ? "static" : "virtual"); + break; + } + case '%': { + sb.append('%'); + break; + } + default: { + throw new UnknownFormatConversionException(String.valueOf(specifier)); + } + } + } else { + sb.append(ch); + } + } + return sb.toString(); + } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaType.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaType.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaType.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,6 +22,8 @@ */ package com.oracle.graal.api.meta; +import static com.oracle.graal.api.meta.MetaUtil.*; + /** * Represents a resolved or unresolved type. Types include primitives, objects, {@code void}, and * arrays thereof. @@ -31,7 +33,7 @@ /** * Returns the name of this type in internal form. The following are examples of strings * returned by this method: - * + * *
      *     "Ljava/lang/Object;"
      *     "I"
@@ -47,6 +49,19 @@
     JavaType getComponentType();
 
     /**
+     * Gets the elemental type for this given type. The elemental type is the corresponding zero
+     * dimensional type of an array type. For example, the elemental type of {@code int[][][]} is
+     * {@code int}. A non-array type is its own elemental type.
+     */
+    default JavaType getElementalType() {
+        JavaType t = this;
+        while (t.getComponentType() != null) {
+            t = t.getComponentType();
+        }
+        return t;
+    }
+
+    /**
      * Gets the array class type representing an array with elements of this type.
      */
     JavaType getArrayClass();
@@ -57,11 +72,63 @@
     Kind getKind();
 
     /**
-     * Resolved this type and returns a {@link ResolvedJavaType}. If this type is already a
-     * {@link ResolvedJavaType}, it returns this type.
-     * 
-     * @param accessingClass the class that requests resolving this type
+     * Resolves this type to a {@link ResolvedJavaType}.
+     *
+     * @param accessingClass the context of resolution (must not be null)
      * @return the resolved Java type
+     * @throws LinkageError if the resolution failed
+     * @throws NullPointerException if {@code accessingClass} is {@code null}
      */
     ResolvedJavaType resolve(ResolvedJavaType accessingClass);
+
+    /**
+     * Gets the Java programming language name for this type. The following are examples of strings
+     * returned by this method:
+     *
+     * 
+     *      java.lang.Object
+     *      int
+     *      boolean[][]
+     * 
+ * + * @return the Java name corresponding to this type + */ + default String toJavaName() { + return internalNameToJava(getName(), true, false); + } + + /** + * Gets the Java programming language name for this type. The following are examples of strings + * returned by this method: + * + *
+     *     qualified == true:
+     *         java.lang.Object
+     *         int
+     *         boolean[][]
+     *     qualified == false:
+     *         Object
+     *         int
+     *         boolean[][]
+     * 
+ * + * @param qualified specifies if the package prefix of this type should be included in the + * returned name + * @return the Java name corresponding to this type + */ + default String toJavaName(boolean qualified) { + Kind kind = getKind(); + if (kind == Kind.Object) { + return internalNameToJava(getName(), qualified, false); + } + return getKind().getJavaName(); + } + + /** + * Returns this type's name in the same format as {@link Class#getName()}. + */ + default String toClassName() { + return internalNameToJava(getName(), true, true); + } + } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Tue Jul 15 19:21:28 2014 -0700 @@ -305,7 +305,7 @@ return "String:\"" + s + '"'; } } else if (value instanceof JavaType) { - return "JavaType:" + MetaUtil.toJavaName((JavaType) value); + return "JavaType:" + ((JavaType) value).toJavaName(); } else if (value instanceof Enum) { return MetaUtil.getSimpleName(value.getClass(), true) + ":" + ((Enum) value).name(); } else if (value instanceof FormatWithToString) { diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java Tue Jul 15 19:21:28 2014 -0700 @@ -31,13 +31,27 @@ /** * Returns the resolved Java type representing a given Java class. - * + * * @param clazz the Java class object * @return the resolved Java type object */ ResolvedJavaType lookupJavaType(Class clazz); /** + * Returns the resolved Java types representing some given Java classes. + * + * @param classes the Java class objects + * @return the resolved Java type objects + */ + default ResolvedJavaType[] lookupJavaTypes(Class[] classes) { + ResolvedJavaType[] result = new ResolvedJavaType[classes.length]; + for (int i = 0; i < result.length; i++) { + result[i] = lookupJavaType(classes[i]); + } + return result; + } + + /** * Provides the {@link ResolvedJavaMethod} for a {@link Method} obtained via reflection. */ ResolvedJavaMethod lookupJavaMethod(Method reflectionMethod); @@ -54,14 +68,14 @@ /** * Returns the resolved Java type of the given {@link Constant} object. - * + * * @return {@code null} if {@code constant.isNull() || !constant.kind.isObject()} */ ResolvedJavaType lookupJavaType(Constant constant); /** * Returns the number of bytes occupied by this constant value or constant object. - * + * * @param constant the constant whose bytes should be measured * @return the number of bytes occupied by this constant */ @@ -77,11 +91,11 @@ /** * Encodes a deoptimization action and a deoptimization reason in an integer value. - * + * * @param debugId an integer that can be used to track the origin of a deoptimization at * runtime. There is no guarantee that the runtime will use this value. The runtime * may even keep fewer than 32 bits. - * + * * @return the encoded value as an integer */ Constant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason, int debugId); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,11 +24,8 @@ import java.io.*; import java.lang.annotation.*; -import java.lang.reflect.*; import java.util.*; -import com.oracle.graal.api.meta.ProfilingInfo.TriState; - /** * Miscellaneous collection of utility methods used by {@code com.oracle.graal.api.meta} and its * clients. @@ -134,15 +131,6 @@ } /** - * Returns true if the specified typed is exactly the type {@link java.lang.Object}. - */ - public static boolean isJavaLangObject(ResolvedJavaType type) { - boolean result = type.getSuperclass() == null && !type.isInterface() && type.getKind() == Kind.Object; - assert result == type.getName().equals("Ljava/lang/Object;") : type.getName(); - return result; - } - - /** * Calls {@link JavaType#resolve(ResolvedJavaType)} on an array of types. */ public static ResolvedJavaType[] resolveJavaTypes(JavaType[] types, ResolvedJavaType accessingClass) { @@ -154,30 +142,6 @@ } /** - * Calls {@link MetaAccessProvider#lookupJavaType(Class)} on an array of classes. - */ - public static ResolvedJavaType[] lookupJavaTypes(MetaAccessProvider metaAccess, Class[] classes) { - ResolvedJavaType[] result = new ResolvedJavaType[classes.length]; - for (int i = 0; i < result.length; i++) { - result[i] = metaAccess.lookupJavaType(classes[i]); - } - return result; - } - - /** - * Gets the elemental type for a given type. The elemental type of an array type is the - * corresponding zero dimensional (e.g., the elemental type of {@code int[][][]} is {@code int} - * ). A non-array type is its own elemental type. - */ - public static ResolvedJavaType getElementalType(ResolvedJavaType type) { - ResolvedJavaType t = type; - while (t.getComponentType() != null) { - t = t.getComponentType(); - } - return t; - } - - /** * Extends the functionality of {@link Class#getSimpleName()} to include a non-empty string for * anonymous and local classes. * @@ -213,59 +177,7 @@ return name.substring(index + 1); } - /** - * Converts a given type to its Java programming language name. The following are examples of - * strings returned by this method: - * - *
-     *     qualified == true:
-     *         java.lang.Object
-     *         int
-     *         boolean[][]
-     *     qualified == false:
-     *         Object
-     *         int
-     *         boolean[][]
-     * 
- * - * @param type the type to be converted to a Java name - * @param qualified specifies if the package prefix of the type should be included in the - * returned name - * @return the Java name corresponding to {@code type} - */ - public static String toJavaName(JavaType type, boolean qualified) { - Kind kind = type.getKind(); - if (kind == Kind.Object) { - return internalNameToJava(type.getName(), qualified, false); - } - return type.getKind().getJavaName(); - } - - /** - * Converts a given type to its Java programming language name. The following are examples of - * strings returned by this method: - * - *
-     *      java.lang.Object
-     *      int
-     *      boolean[][]
-     * 
- * - * @param type the type to be converted to a Java name - * @return the Java name corresponding to {@code type} - */ - public static String toJavaName(JavaType type) { - return (type == null) ? null : internalNameToJava(type.getName(), true, false); - } - - /** - * Returns the type name in the same format as {@link Class#getName()}. - */ - public static String toClassName(JavaType type) { - return internalNameToJava(type.getName(), true, true); - } - - private static String internalNameToJava(String name, boolean qualified, boolean classForNameCompatible) { + static String internalNameToJava(String name, boolean qualified, boolean classForNameCompatible) { switch (name.charAt(0)) { case 'L': { String result = name.substring(1, name.length() - 1).replace('/', '.'); @@ -301,221 +213,8 @@ } /** - * Gets a string for a given method formatted according to a given format specification. A - * format specification is composed of characters that are to be copied verbatim to the result - * and specifiers that denote an attribute of the method that is to be copied to the result. A - * specifier is a single character preceded by a '%' character. The accepted specifiers and the - * method attributes they denote are described below: - * - *
-     *     Specifier | Description                                          | Example(s)
-     *     ----------+------------------------------------------------------------------------------------------
-     *     'R'       | Qualified return type                                | "int" "java.lang.String"
-     *     'r'       | Unqualified return type                              | "int" "String"
-     *     'H'       | Qualified holder                                     | "java.util.Map.Entry"
-     *     'h'       | Unqualified holder                                   | "Entry"
-     *     'n'       | Method name                                          | "add"
-     *     'P'       | Qualified parameter types, separated by ', '         | "int, java.lang.String"
-     *     'p'       | Unqualified parameter types, separated by ', '       | "int, String"
-     *     'f'       | Indicator if method is unresolved, static or virtual | "unresolved" "static" "virtual"
-     *     '%'       | A '%' character                                      | "%"
-     * 
- * - * @param format a format specification - * @param method the method to be formatted - * @return the result of formatting this method according to {@code format} - * @throws IllegalFormatException if an illegal specifier is encountered in {@code format} - */ - public static String format(String format, JavaMethod method) throws IllegalFormatException { - final StringBuilder sb = new StringBuilder(); - int index = 0; - Signature sig = null; - while (index < format.length()) { - final char ch = format.charAt(index++); - if (ch == '%') { - if (index >= format.length()) { - throw new UnknownFormatConversionException("An unquoted '%' character cannot terminate a method format specification"); - } - final char specifier = format.charAt(index++); - boolean qualified = false; - switch (specifier) { - case 'R': - qualified = true; - // fall through - case 'r': { - if (sig == null) { - sig = method.getSignature(); - } - sb.append(toJavaName(sig.getReturnType(null), qualified)); - break; - } - case 'H': - qualified = true; - // fall through - case 'h': { - sb.append(toJavaName(method.getDeclaringClass(), qualified)); - break; - } - case 'n': { - sb.append(method.getName()); - break; - } - case 'P': - qualified = true; - // fall through - case 'p': { - if (sig == null) { - sig = method.getSignature(); - } - for (int i = 0; i < sig.getParameterCount(false); i++) { - if (i != 0) { - sb.append(", "); - } - sb.append(toJavaName(sig.getParameterType(i, null), qualified)); - } - break; - } - case 'f': { - sb.append(!(method instanceof ResolvedJavaMethod) ? "unresolved" : ((ResolvedJavaMethod) method).isStatic() ? "static" : "virtual"); - break; - } - case '%': { - sb.append('%'); - break; - } - default: { - throw new UnknownFormatConversionException(String.valueOf(specifier)); - } - } - } else { - sb.append(ch); - } - } - return sb.toString(); - } - - /** - * Gets a string for a given field formatted according to a given format specification. A format - * specification is composed of characters that are to be copied verbatim to the result and - * specifiers that denote an attribute of the field that is to be copied to the result. A - * specifier is a single character preceded by a '%' character. The accepted specifiers and the - * field attributes they denote are described below: - * - *
-     *     Specifier | Description                                          | Example(s)
-     *     ----------+------------------------------------------------------------------------------------------
-     *     'T'       | Qualified type                                       | "int" "java.lang.String"
-     *     't'       | Unqualified type                                     | "int" "String"
-     *     'H'       | Qualified holder                                     | "java.util.Map.Entry"
-     *     'h'       | Unqualified holder                                   | "Entry"
-     *     'n'       | Field name                                           | "age"
-     *     'f'       | Indicator if field is unresolved, static or instance | "unresolved" "static" "instance"
-     *     '%'       | A '%' character                                      | "%"
-     * 
- * - * @param format a format specification - * @param field the field to be formatted - * @return the result of formatting this field according to {@code format} - * @throws IllegalFormatException if an illegal specifier is encountered in {@code format} - */ - public static String format(String format, JavaField field) throws IllegalFormatException { - final StringBuilder sb = new StringBuilder(); - int index = 0; - JavaType type = field.getType(); - while (index < format.length()) { - final char ch = format.charAt(index++); - if (ch == '%') { - if (index >= format.length()) { - throw new UnknownFormatConversionException("An unquoted '%' character cannot terminate a field format specification"); - } - final char specifier = format.charAt(index++); - boolean qualified = false; - switch (specifier) { - case 'T': - qualified = true; - // fall through - case 't': { - sb.append(toJavaName(type, qualified)); - break; - } - case 'H': - qualified = true; - // fall through - case 'h': { - sb.append(toJavaName(field.getDeclaringClass(), qualified)); - break; - } - case 'n': { - sb.append(field.getName()); - break; - } - case 'f': { - sb.append(!(field instanceof ResolvedJavaField) ? "unresolved" : ((ResolvedJavaField) field).isStatic() ? "static" : "instance"); - break; - } - case '%': { - sb.append('%'); - break; - } - default: { - throw new UnknownFormatConversionException(String.valueOf(specifier)); - } - } - } else { - sb.append(ch); - } - } - return sb.toString(); - } - - /** - * Gets the annotations of a particular type for the formal parameters of a given method. - * - * @param annotationClass the Class object corresponding to the annotation type - * @param method the method for which a parameter annotations are being requested - * @return the annotation of type {@code annotationClass} (if any) for each formal parameter - * present - */ - @SuppressWarnings("unchecked") - public static T[] getParameterAnnotations(Class annotationClass, ResolvedJavaMethod method) { - Annotation[][] parameterAnnotations = method.getParameterAnnotations(); - T[] result = (T[]) Array.newInstance(annotationClass, parameterAnnotations.length); - for (int i = 0; i < parameterAnnotations.length; i++) { - for (Annotation a : parameterAnnotations[i]) { - if (a.annotationType() == annotationClass) { - result[i] = annotationClass.cast(a); - } - } - } - return result; - } - - /** - * Gets the annotation of a particular type for a formal parameter of a given method. - * - * @param annotationClass the Class object corresponding to the annotation type - * @param parameterIndex the index of a formal parameter of {@code method} - * @param method the method for which a parameter annotation is being requested - * @return the annotation of type {@code annotationClass} for the formal parameter present, else - * null - * @throws IndexOutOfBoundsException if {@code parameterIndex} does not denote a formal - * parameter - */ - public static T getParameterAnnotation(Class annotationClass, int parameterIndex, ResolvedJavaMethod method) { - if (parameterIndex >= 0) { - Annotation[][] parameterAnnotations = method.getParameterAnnotations(); - for (Annotation a : parameterAnnotations[parameterIndex]) { - if (a.annotationType() == annotationClass) { - return annotationClass.cast(a); - } - } - } - return null; - } - - /** * Convenient shortcut for calling - * {@link #appendLocation(StringBuilder, ResolvedJavaMethod, int)} without having to supply a a + * {@link #appendLocation(StringBuilder, ResolvedJavaMethod, int)} without having to supply a * {@link StringBuilder} instance and convert the result to a string. */ public static String toLocation(ResolvedJavaMethod method, int bci) { @@ -533,7 +232,7 @@ * java.lang.String.valueOf(String.java:2930) [bci: 12] *
* - * Otherwise, the string returned is the value of applying {@link #format(String, JavaMethod)} + * Otherwise, the string returned is the value of applying {@link JavaMethod#format(String)} * with the format string {@code "%H.%n(%p)"}, suffixed by the bci location. For example: * *
@@ -550,7 +249,7 @@
             if (ste.getFileName() != null && ste.getLineNumber() > 0) {
                 sb.append(ste);
             } else {
-                sb.append(format("%H.%n(%p)", method));
+                sb.append(method.format("%H.%n(%p)"));
             }
         } else {
             sb.append("Null method");
@@ -558,116 +257,7 @@
         return sb.append(" [bci: ").append(bci).append(']');
     }
 
-    public static JavaType[] signatureToTypes(ResolvedJavaMethod method) {
-        JavaType receiver = method.isStatic() ? null : method.getDeclaringClass();
-        return signatureToTypes(method.getSignature(), receiver);
-    }
-
-    public static JavaType[] signatureToTypes(Signature signature, JavaType receiverType) {
-        int args = signature.getParameterCount(false);
-        JavaType[] result;
-        int i = 0;
-        if (receiverType != null) {
-            result = new JavaType[args + 1];
-            result[0] = receiverType;
-            i = 1;
-        } else {
-            result = new JavaType[args];
-        }
-        for (int j = 0; j < args; j++) {
-            result[i + j] = signature.getParameterType(j, null);
-        }
-        return result;
-    }
-
-    /**
-     * Gets the method
-     * descriptor corresponding to this signature. For example:
-     *
-     * 
-     * (ILjava/lang/String;D)V
-     * 
- * - * . - * - * @param sig the {@link Signature} to be converted. - * @return the signature as a string - */ - public static String signatureToMethodDescriptor(Signature sig) { - StringBuilder sb = new StringBuilder("("); - for (int i = 0; i < sig.getParameterCount(false); ++i) { - sb.append(sig.getParameterType(i, null).getName()); - } - sb.append(')').append(sig.getReturnType(null).getName()); - return sb.toString(); - } - - /** - * Formats some profiling information associated as a string. - * - * @param info the profiling info to format - * @param method an optional method that augments the profile string returned - * @param sep the separator to use for each separate profile record - */ - public static String profileToString(ProfilingInfo info, ResolvedJavaMethod method, String sep) { - StringBuilder buf = new StringBuilder(100); - if (method != null) { - buf.append(String.format("canBeStaticallyBound: %b%s", method.canBeStaticallyBound(), sep)); - } - for (int i = 0; i < info.getCodeSize(); i++) { - if (info.getExecutionCount(i) != -1) { - buf.append(String.format("executionCount@%d: %d%s", i, info.getExecutionCount(i), sep)); - } - - if (info.getBranchTakenProbability(i) != -1) { - buf.append(String.format("branchProbability@%d: %.6f%s", i, info.getBranchTakenProbability(i), sep)); - } - - double[] switchProbabilities = info.getSwitchProbabilities(i); - if (switchProbabilities != null) { - buf.append(String.format("switchProbabilities@%d:", i)); - for (int j = 0; j < switchProbabilities.length; j++) { - buf.append(String.format(" %.6f", switchProbabilities[j])); - } - buf.append(sep); - } - - if (info.getExceptionSeen(i) != TriState.UNKNOWN) { - buf.append(String.format("exceptionSeen@%d: %s%s", i, info.getExceptionSeen(i).name(), sep)); - } - - if (info.getNullSeen(i) != TriState.UNKNOWN) { - buf.append(String.format("nullSeen@%d: %s%s", i, info.getNullSeen(i).name(), sep)); - } - - JavaTypeProfile typeProfile = info.getTypeProfile(i); - appendProfile(buf, typeProfile, i, "types", sep); - - JavaMethodProfile methodProfile = info.getMethodProfile(i); - appendProfile(buf, methodProfile, i, "methods", sep); - } - - boolean firstDeoptReason = true; - for (DeoptimizationReason reason : DeoptimizationReason.values()) { - int count = info.getDeoptimizationCount(reason); - if (count > 0) { - if (firstDeoptReason) { - buf.append("deoptimization history").append(sep); - firstDeoptReason = false; - } - buf.append(String.format(" %s: %d%s", reason.name(), count, sep)); - } - } - if (buf.length() == 0) { - return ""; - } - String s = buf.toString(); - assert s.endsWith(sep); - return s.substring(0, s.length() - sep.length()); - } - - private static void appendProfile(StringBuilder buf, AbstractJavaProfile profile, int bci, String type, String sep) { + static void appendProfile(StringBuilder buf, AbstractJavaProfile profile, int bci, String type, String sep) { if (profile != null) { AbstractProfiledItem[] pitems = profile.getItems(); if (pitems != null) { @@ -743,4 +333,78 @@ } return indentation + lines.replace(newLine, newLine + indentation); } + + // The methods below here will be soon removed. They exist to simplify updating + // clients of the old API to switch to using the default methods that replace + // these utility methods. In Eclipse will show calls to these methods as warnings. + + @Deprecated + public static boolean isJavaLangObject(ResolvedJavaType type) { + return type.isJavaLangObject(); + } + + @Deprecated + public static ResolvedJavaType[] lookupJavaTypes(MetaAccessProvider metaAccess, Class[] classes) { + return metaAccess.lookupJavaTypes(classes); + } + + @Deprecated + public static ResolvedJavaType getElementalType(ResolvedJavaType type) { + return type.getElementalType(); + } + + @Deprecated + public static String toJavaName(JavaType type, boolean qualified) { + return type.toJavaName(qualified); + } + + @Deprecated + public static String toJavaName(JavaType type) { + return type.toJavaName(); + } + + @Deprecated + public static String toClassName(JavaType type) { + return type.toClassName(); + } + + @Deprecated + public static String format(String format, JavaMethod method) throws IllegalFormatException { + return method.format(format); + } + + @Deprecated + public static String format(String format, JavaField field) throws IllegalFormatException { + return field.format(format); + } + + @Deprecated + public static T[] getParameterAnnotations(Class annotationClass, ResolvedJavaMethod method) { + return method.getParameterAnnotations(annotationClass); + } + + @Deprecated + public static T getParameterAnnotation(Class annotationClass, int parameterIndex, ResolvedJavaMethod method) { + return method.getParameterAnnotation(annotationClass, parameterIndex); + } + + @Deprecated + public static JavaType[] signatureToTypes(Signature signature, JavaType receiverType) { + return signature.toParameterTypes(receiverType); + } + + @Deprecated + public static JavaType[] signatureToTypes(ResolvedJavaMethod method) { + return method.toParameterTypes(); + } + + @Deprecated + public static String signatureToMethodDescriptor(Signature sig) { + return sig.toMethodDescriptor(); + } + + @Deprecated + public static String profileToString(ProfilingInfo info, ResolvedJavaMethod method, String sep) { + return info.toString(method, sep); + } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java Tue Jul 15 19:21:28 2014 -0700 @@ -50,7 +50,7 @@ /** * Returns an estimate of how often the branch at the given byte code was taken. - * + * * @return The estimated probability, with 0.0 meaning never and 1.0 meaning always, or -1 if * this information is not available. */ @@ -59,7 +59,7 @@ /** * Returns an estimate of how often the switch cases are taken at the given BCI. The default * case is stored as the last entry. - * + * * @return A double value that contains the estimated probabilities, with 0.0 meaning never and * 1.0 meaning always, or -1 if this information is not available. */ @@ -67,21 +67,21 @@ /** * Returns the TypeProfile for the given BCI. - * + * * @return Returns a JavaTypeProfile object, or null if not available. */ JavaTypeProfile getTypeProfile(int bci); /** * Returns the MethodProfile for the given BCI. - * + * * @return Returns a JavaMethodProfile object, or null if not available. */ JavaMethodProfile getMethodProfile(int bci); /** * Returns information if the given BCI did ever throw an exception. - * + * * @return {@link TriState#TRUE} if the instruction has thrown an exception at least once, * {@link TriState#FALSE} if it never threw an exception, and {@link TriState#UNKNOWN} * if this information was not recorded. @@ -91,7 +91,7 @@ /** * Returns information if null was ever seen for the given BCI. This information is collected * for the aastore, checkcast and instanceof bytecodes. - * + * * @return {@link TriState#TRUE} if null was seen for the instruction, {@link TriState#FALSE} if * null was NOT seen, and {@link TriState#UNKNOWN} if this information was not recorded. */ @@ -100,7 +100,7 @@ /** * Returns an estimate how often the current BCI was executed. Avoid comparing execution counts * to each other, as the returned value highly depends on the time of invocation. - * + * * @return the estimated execution count or -1 if not available. */ int getExecutionCount(int bci); @@ -109,7 +109,7 @@ * Returns how frequently a method was deoptimized for the given deoptimization reason. This * only indicates how often the method did fall back to the interpreter for the execution and * does not indicate how often it was recompiled. - * + * * @param reason the reason for which the number of deoptimizations should be queried * @return the number of times the compiled method deoptimized for the given reason. */ @@ -118,7 +118,7 @@ /** * Records the size of the compiler intermediate representation (IR) associated with this * method. - * + * * @param irType the IR type for which the size is being recorded * @param irSize the IR size to be recorded. The unit depends on the IR. * @return whether recording this information for {@code irType} is supported @@ -128,7 +128,7 @@ /** * Gets the size of the compiler intermediate representation (IR) associated with this method * last recorded by {@link #setCompilerIRSize(Class, int)}. - * + * * @param irType the IR type for which the size is being requested * @return the requested IR size or -1 if it is unavailable for {@code irType} */ @@ -136,7 +136,7 @@ /** * Returns true if the profiling information can be assumed as sufficiently accurate. - * + * * @return true if the profiling information was recorded often enough mature enough, false * otherwise. */ @@ -146,4 +146,67 @@ * Force data to be treated as mature if possible. */ void setMature(); + + /** + * Formats this profiling information to a string. + * + * @param method an optional method that augments the profile string returned + * @param sep the separator to use for each separate profile record + */ + default String toString(ResolvedJavaMethod method, String sep) { + StringBuilder buf = new StringBuilder(100); + if (method != null) { + buf.append(String.format("canBeStaticallyBound: %b%s", method.canBeStaticallyBound(), sep)); + } + for (int i = 0; i < getCodeSize(); i++) { + if (getExecutionCount(i) != -1) { + buf.append(String.format("executionCount@%d: %d%s", i, getExecutionCount(i), sep)); + } + + if (getBranchTakenProbability(i) != -1) { + buf.append(String.format("branchProbability@%d: %.6f%s", i, getBranchTakenProbability(i), sep)); + } + + double[] switchProbabilities = getSwitchProbabilities(i); + if (switchProbabilities != null) { + buf.append(String.format("switchProbabilities@%d:", i)); + for (int j = 0; j < switchProbabilities.length; j++) { + buf.append(String.format(" %.6f", switchProbabilities[j])); + } + buf.append(sep); + } + + if (getExceptionSeen(i) != TriState.UNKNOWN) { + buf.append(String.format("exceptionSeen@%d: %s%s", i, getExceptionSeen(i).name(), sep)); + } + + if (getNullSeen(i) != TriState.UNKNOWN) { + buf.append(String.format("nullSeen@%d: %s%s", i, getNullSeen(i).name(), sep)); + } + + JavaTypeProfile typeProfile = getTypeProfile(i); + MetaUtil.appendProfile(buf, typeProfile, i, "types", sep); + + JavaMethodProfile methodProfile = getMethodProfile(i); + MetaUtil.appendProfile(buf, methodProfile, i, "methods", sep); + } + + boolean firstDeoptReason = true; + for (DeoptimizationReason reason : DeoptimizationReason.values()) { + int count = getDeoptimizationCount(reason); + if (count > 0) { + if (firstDeoptReason) { + buf.append("deoptimization history").append(sep); + firstDeoptReason = false; + } + buf.append(String.format(" %s: %d%s", reason.name(), count, sep)); + } + } + if (buf.length() == 0) { + return ""; + } + String s = buf.toString(); + return s.substring(0, s.length() - sep.length()); + } + } diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Tue Jul 15 19:21:28 2014 -0700 @@ -224,4 +224,53 @@ * @return true is this method is present in the virtual table for subtypes of this type. */ boolean isInVirtualMethodTable(ResolvedJavaType resolved); + + /** + * Gets the annotation of a particular type for a formal parameter of this method. + * + * @param annotationClass the Class object corresponding to the annotation type + * @param parameterIndex the index of a formal parameter of {@code method} + * @return the annotation of type {@code annotationClass} for the formal parameter present, else + * null + * @throws IndexOutOfBoundsException if {@code parameterIndex} does not denote a formal + * parameter + */ + default T getParameterAnnotation(Class annotationClass, int parameterIndex) { + if (parameterIndex >= 0) { + Annotation[][] parameterAnnotations = getParameterAnnotations(); + for (Annotation a : parameterAnnotations[parameterIndex]) { + if (a.annotationType() == annotationClass) { + return annotationClass.cast(a); + } + } + } + return null; + } + + default JavaType[] toParameterTypes() { + JavaType receiver = isStatic() ? null : getDeclaringClass(); + return getSignature().toParameterTypes(receiver); + } + + /** + * Gets the annotations of a particular type for the formal parameters of this method. + * + * @param annotationClass the Class object corresponding to the annotation type + * @return the annotation of type {@code annotationClass} (if any) for each formal parameter + * present + */ + @SuppressWarnings("unchecked") + default T[] getParameterAnnotations(Class annotationClass) { + Annotation[][] parameterAnnotations = getParameterAnnotations(); + T[] result = (T[]) Array.newInstance(annotationClass, parameterAnnotations.length); + for (int i = 0; i < parameterAnnotations.length; i++) { + for (Annotation a : parameterAnnotations[i]) { + if (a.annotationType() == annotationClass) { + result[i] = annotationClass.cast(a); + } + } + } + return result; + } + } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Tue Jul 15 19:21:28 2014 -0700 @@ -141,6 +141,14 @@ boolean isAssignableFrom(ResolvedJavaType other); /** + * Returns true if this type is exactly the type {@link java.lang.Object}. + */ + default boolean isJavaLangObject() { + // Removed assertion due to https://bugs.eclipse.org/bugs/show_bug.cgi?id=434442 + return getSuperclass() == null && !isInterface() && getKind() == Kind.Object; + } + + /** * Checks whether the specified object is an instance of this type. * * @param obj the object to test @@ -183,8 +191,8 @@ * Attempts to get a unique concrete subclass of this type. *

* For an {@linkplain #isArray() array} type A, the unique concrete subclass is A if the - * {@linkplain MetaUtil#getElementalType(ResolvedJavaType) elemental} type of A is final (which - * includes primitive types). Otherwise {@code null} is returned for A. + * {@linkplain #getElementalType() elemental} type of A is final (which includes primitive + * types). Otherwise {@code null} is returned for A. *

* For a non-array type T, the result is the unique concrete type in the current hierarchy of T. *

@@ -202,6 +210,14 @@ ResolvedJavaType getComponentType(); + default ResolvedJavaType getElementalType() { + ResolvedJavaType t = this; + while (t.isArray()) { + t = t.getComponentType(); + } + return t; + } + ResolvedJavaType getArrayClass(); /** diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Signature.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Signature.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Signature.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,7 +24,7 @@ /** * Represents a method signature provided by the runtime. - * + * * @see Method * Descriptors */ @@ -32,43 +32,44 @@ /** * Returns the number of parameters in this signature, adding 1 for a receiver if requested. - * + * * @param receiver true if 1 is to be added to the result for a receiver * @return the number of parameters; + 1 iff {@code receiver == true} */ int getParameterCount(boolean receiver); /** - * Gets the parameter type at the specified position. This method returns a - * {@linkplain ResolvedJavaType resolved} type if possible but without triggering any class - * loading or resolution. - * + * Gets the parameter type at the specified position. + * * @param index the index into the parameters, with {@code 0} indicating the first parameter - * @param accessingClass the context of the type lookup. If accessing class is provided, its - * class loader is used to retrieve an existing resolved type. This value can be - * {@code null} if the caller does not care for a resolved type. + * @param accessingClass the context of the type lookup. If non-null, its class loader is used + * for resolving the type. If {@code null}, then the type returned is either + * unresolved or a resolved type whose resolution is context free (e.g., a primitive + * type or a type in a java.* package). * @return the {@code index}'th parameter type + * @throws LinkageError if {@code accessingClass != null} and resolution fails + * */ JavaType getParameterType(int index, ResolvedJavaType accessingClass); /** * Gets the parameter kind at the specified position. This is the same as calling * {@link #getParameterType}. {@link JavaType#getKind getKind}. - * + * * @param index the index into the parameters, with {@code 0} indicating the first parameter * @return the kind of the parameter at the specified position */ Kind getParameterKind(int index); /** - * Gets the return type of this signature. This method will return a - * {@linkplain ResolvedJavaType resolved} type if possible but without triggering any class - * loading or resolution. - * - * @param accessingClass the context of the type lookup. If accessing class is provided, its - * class loader is used to retrieve an existing resolved type. This value can be - * {@code null} if the caller does not care for a resolved type. + * Gets the return type of this signature. + * + * @param accessingClass the context of the type lookup. If non-null, its class loader is used + * for resolving the type. If {@code null}, then the type returned is either + * unresolved or a resolved type whose resolution is context free (e.g., a primitive + * type or a type in a java.* package). * @return the return type + * @throws LinkageError if {@code accessingClass != null} and resolution fails */ JavaType getReturnType(ResolvedJavaType accessingClass); @@ -80,10 +81,47 @@ /** * Gets the size, in Java slots, of the parameters to this signature. - * + * * @param withReceiver {@code true} if to add a slot for a receiver object; {@code false} not to * include the receiver * @return the size of the parameters in slots */ int getParameterSlots(boolean withReceiver); + + /** + * Gets the method + * descriptor corresponding to this signature. For example: + * + *

+     * (ILjava/lang/String;D)V
+     * 
+ * + * @return the signature as a string + */ + default String toMethodDescriptor() { + StringBuilder sb = new StringBuilder("("); + for (int i = 0; i < getParameterCount(false); ++i) { + sb.append(getParameterType(i, null).getName()); + } + sb.append(')').append(getReturnType(null).getName()); + return sb.toString(); + } + + default JavaType[] toParameterTypes(JavaType receiverType) { + int args = getParameterCount(false); + JavaType[] result; + int i = 0; + if (receiverType != null) { + result = new JavaType[args + 1]; + result[0] = receiverType; + i = 1; + } else { + result = new JavaType[args]; + } + for (int j = 0; j < args; j++) { + result[i + j] = getParameterType(j, null); + } + return result; + } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/MethodSubstitution.java --- a/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/MethodSubstitution.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/MethodSubstitution.java Tue Jul 15 19:21:28 2014 -0700 @@ -48,7 +48,7 @@ boolean isStatic() default true; /** - * Gets the {@linkplain MetaUtil#signatureToMethodDescriptor signature} of the original method. + * Gets the {@linkplain Signature#toMethodDescriptor signature} of the original method. *

* If the default value is specified for this element, then the signature of the original method * is the same as the substitute method. @@ -58,7 +58,7 @@ /** * Determines if this method should be substituted in all cases, even if inlining thinks it is * not important. - * + * * Note that this is still depending on whether inlining sees the correct call target, so it's * only a hard guarantee for static and special invocations. */ diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java --- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java Tue Jul 15 19:21:28 2014 -0700 @@ -86,8 +86,8 @@ @Override protected void build() { if (PrintProfilingInformation.getValue()) { - TTY.println("Profiling info for " + MetaUtil.format("%H.%n(%p)", method)); - TTY.println(MetaUtil.indent(MetaUtil.profileToString(profilingInfo, method, CodeUtil.NEW_LINE), " ")); + TTY.println("Profiling info for " + method.format("%H.%n(%p)")); + TTY.println(MetaUtil.indent(profilingInfo.toString(method, CodeUtil.NEW_LINE), " ")); } try (Indent indent = Debug.logAndIndent("build graph for %s", method)) { diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineControlFlowGraph.java --- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineControlFlowGraph.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineControlFlowGraph.java Tue Jul 15 19:21:28 2014 -0700 @@ -39,6 +39,10 @@ try (Scope ds = Debug.scope("BaselineCFG", blockMap)) { BaselineControlFlowGraph cfg = new BaselineControlFlowGraph(blockMap); cfg.computeLoopInformation(blockMap); + AbstractControlFlowGraph.computeDominators(cfg); + + assert CFGVerifier.verify(cfg); + return cfg; } catch (Throwable e) { throw Debug.handle(e); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlock.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlock.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlock.java Tue Jul 15 19:21:28 2014 -0700 @@ -58,28 +58,14 @@ T getDominator(); + void setDominator(T block); + + List getDominated(); + + void setDominated(List blocks); + + T getPostdominator(); + double probability(); - /** - * True if block {@code a} dominates block {@code b}. - */ - static boolean dominates(AbstractBlock a, AbstractBlock b) { - assert a != null; - return isDominatedBy(b, a); - } - - /** - * True if block {@code a} is dominated by block {@code b}. - */ - static boolean isDominatedBy(AbstractBlock a, AbstractBlock b) { - assert a != null; - if (a == b) { - return true; - } - if (a.getDominator() == null) { - return false; - } - return isDominatedBy(a.getDominator(), b); - } - } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlockBase.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlockBase.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractBlockBase.java Tue Jul 15 19:21:28 2014 -0700 @@ -32,6 +32,7 @@ protected List successors; private T dominator; + private List dominated; private boolean align; private int linearScanNumber; @@ -73,6 +74,17 @@ this.dominator = dominator; } + public List getDominated() { + if (dominated == null) { + return Collections.emptyList(); + } + return dominated; + } + + public void setDominated(List blocks) { + dominated = blocks; + } + @Override public String toString() { return "B" + id; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractControlFlowGraph.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractControlFlowGraph.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/AbstractControlFlowGraph.java Tue Jul 15 19:21:28 2014 -0700 @@ -29,9 +29,99 @@ static final int BLOCK_ID_INITIAL = -1; static final int BLOCK_ID_VISITED = -2; + /** + * Returns the list blocks contained in this control flow graph. + * + * It is {@linkplain CFGVerifier guaranteed} that the blocks are numbered and ordered according + * to a reverse post order traversal of the control flow graph. + * + * @see CFGVerifier + */ List getBlocks(); Collection> getLoops(); T getStartBlock(); + + /** + * Computes the dominators of control flow graph. + */ + static > void computeDominators(AbstractControlFlowGraph cfg) { + List reversePostOrder = cfg.getBlocks(); + assert reversePostOrder.get(0).getPredecessorCount() == 0 : "start block has no predecessor and therefore no dominator"; + for (int i = 1; i < reversePostOrder.size(); i++) { + T block = reversePostOrder.get(i); + assert block.getPredecessorCount() > 0; + T dominator = null; + for (T pred : block.getPredecessors()) { + if (!pred.isLoopEnd()) { + dominator = commonDominatorTyped(dominator, pred); + } + } + // set dominator + block.setDominator(dominator); + if (dominator.getDominated().equals(Collections.emptyList())) { + dominator.setDominated(new ArrayList<>()); + } + dominator.getDominated().add(block); + } + } + + /** + * True if block {@code a} is dominated by block {@code b}. + */ + static boolean isDominatedBy(AbstractBlock a, AbstractBlock b) { + assert a != null; + if (a == b) { + return true; + } + if (a.getDominator() == null) { + return false; + } + return isDominatedBy(a.getDominator(), b); + } + + /** + * True if block {@code a} dominates block {@code b}. + */ + static boolean dominates(AbstractBlock a, AbstractBlock b) { + assert a != null; + return isDominatedBy(b, a); + } + + /** + * Calculates the common dominator of two blocks. + * + * Note that this algorithm makes use of special properties regarding the numbering of blocks. + * + * @see #getBlocks() + * @see CFGVerifier + */ + public static AbstractBlock commonDominator(AbstractBlock a, AbstractBlock b) { + if (a == null) { + return b; + } + if (b == null) { + return a; + } + AbstractBlock iterA = a; + AbstractBlock iterB = b; + while (iterA != iterB) { + if (iterA.getId() > iterB.getId()) { + iterA = iterA.getDominator(); + } else { + assert iterB.getId() > iterA.getId(); + iterB = iterB.getDominator(); + } + } + return iterA; + } + + /** + * @see AbstractControlFlowGraph#commonDominator(AbstractBlock, AbstractBlock) + */ + @SuppressWarnings("unchecked") + public static > T commonDominatorTyped(T a, T b) { + return (T) commonDominator(a, b); + } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/CFGVerifier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/cfg/CFGVerifier.java Tue Jul 15 19:21:28 2014 -0700 @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.common.cfg; + +import java.util.*; + +public class CFGVerifier { + + public static , C extends AbstractControlFlowGraph> boolean verify(C cfg) { + for (T block : cfg.getBlocks()) { + assert block.getId() >= 0; + assert cfg.getBlocks().get(block.getId()) == block; + + for (T pred : block.getPredecessors()) { + assert pred.getSuccessors().contains(block); + assert pred.getId() < block.getId() || pred.isLoopEnd(); + } + + for (T sux : block.getSuccessors()) { + assert sux.getPredecessors().contains(block); + assert sux.getId() > block.getId() || sux.isLoopHeader(); + } + + if (block.getDominator() != null) { + assert block.getDominator().getId() < block.getId(); + assert block.getDominator().getDominated().contains(block); + } + for (T dominated : block.getDominated()) { + assert dominated.getId() > block.getId(); + assert dominated.getDominator() == block; + } + + T postDominatorBlock = block.getPostdominator(); + if (postDominatorBlock != null) { + assert block.getSuccessorCount() > 0 : "block has post-dominator block, but no successors"; + + BlockMap visitedBlocks = new BlockMap<>(cfg); + visitedBlocks.put(block, true); + + Deque stack = new ArrayDeque<>(); + for (T sux : block.getSuccessors()) { + visitedBlocks.put(sux, true); + stack.push(sux); + } + + while (stack.size() > 0) { + T tos = stack.pop(); + assert tos.getId() <= postDominatorBlock.getId(); + if (tos == postDominatorBlock) { + continue; // found a valid path + } + assert tos.getSuccessorCount() > 0 : "no path found"; + + for (T sux : tos.getSuccessors()) { + if (visitedBlocks.get(sux) == null) { + visitedBlocks.put(sux, true); + stack.push(sux); + } + } + } + } + + assert cfg.getLoops() == null || !block.isLoopHeader() || block.getLoop().getHeader() == block; + } + + if (cfg.getLoops() != null) { + for (Loop loop : cfg.getLoops()) { + assert loop.getHeader().isLoopHeader(); + + for (T block : loop.getBlocks()) { + assert block.getId() >= loop.getHeader().getId(); + + Loop blockLoop = block.getLoop(); + while (blockLoop != loop) { + assert blockLoop != null; + blockLoop = blockLoop.getParent(); + } + + if (!(block.isLoopHeader() && block.getLoop() == loop)) { + for (T pred : block.getPredecessors()) { + if (!loop.getBlocks().contains(pred)) { + assert false : "Loop " + loop + " does not contain " + pred; + return false; + } + } + } + } + + for (T block : loop.getExits()) { + assert block.getId() >= loop.getHeader().getId(); + + Loop blockLoop = block.getLoop(); + while (blockLoop != null) { + blockLoop = blockLoop.getParent(); + assert blockLoop != loop; + } + } + } + } + + return true; + } +} diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILNodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILNodeLIRBuilder.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILNodeLIRBuilder.java Tue Jul 15 19:21:28 2014 -0700 @@ -47,12 +47,12 @@ @Override protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { - throw GraalInternalError.unimplemented(MetaUtil.format("direct call to %H.%n(%p)", callTarget.target())); + throw GraalInternalError.unimplemented(callTarget.target().format("direct call to %H.%n(%p)")); } @Override protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { - throw GraalInternalError.unimplemented(MetaUtil.format("direct call to %H.%n(%p)", callTarget.target())); + throw GraalInternalError.unimplemented(callTarget.target().format("direct call to %H.%n(%p)")); } @Override diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXNodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXNodeLIRBuilder.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXNodeLIRBuilder.java Tue Jul 15 19:21:28 2014 -0700 @@ -83,7 +83,7 @@ if (!Modifier.isStatic(graph.method().getModifiers())) { parameterIndex--; } - Warp warpAnnotation = parameterIndex >= 0 ? MetaUtil.getParameterAnnotation(Warp.class, parameterIndex, graph.method()) : null; + Warp warpAnnotation = parameterIndex >= 0 ? graph.method().getParameterAnnotation(Warp.class, parameterIndex) : null; if (warpAnnotation != null) { setResult(param, getGen().emitWarpParam(paramValue.getKind().getStackKind(), warpAnnotation)); } else { diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSenReduTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSenReduTest.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSenReduTest.java Tue Jul 15 19:21:28 2014 -0700 @@ -384,7 +384,7 @@ public StructuredGraph visualize(StructuredGraph graph, String title) { DebugConfig debugConfig = DebugScope.getConfig(); - DebugConfig fixedConfig = Debug.fixedConfig(false, true, false, false, false, false, debugConfig.dumpHandlers(), debugConfig.verifyHandlers(), debugConfig.output()); + DebugConfig fixedConfig = Debug.fixedConfig(0, Debug.DEFAULT_LOG_LEVEL, false, false, false, false, debugConfig.dumpHandlers(), debugConfig.verifyHandlers(), debugConfig.output()); try (DebugConfigScope s = Debug.setConfig(fixedConfig)) { Debug.dump(graph, title); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Jul 15 19:21:28 2014 -0700 @@ -475,7 +475,7 @@ try (Scope s = Debug.scope("CodeInstall", getCodeCache(), javaMethod)) { installedCode = addMethod(javaMethod, compResult); if (installedCode == null) { - throw new GraalInternalError("Could not install code for " + MetaUtil.format("%H.%n(%p)", javaMethod)); + throw new GraalInternalError("Could not install code for " + javaMethod.format("%H.%n(%p)")); } } catch (Throwable e) { throw Debug.handle(e); @@ -501,7 +501,7 @@ } protected void checkArgs(ResolvedJavaMethod method, Object[] args) { - JavaType[] sig = MetaUtil.signatureToTypes(method); + JavaType[] sig = method.toParameterTypes(); Assert.assertEquals(sig.length, args.length); for (int i = 0; i < args.length; i++) { JavaType javaType = sig[i]; @@ -637,7 +637,7 @@ try (Scope s = Debug.scope("CodeInstall", getCodeCache(), method)) { installedCode = addMethod(method, compResult); if (installedCode == null) { - throw new GraalInternalError("Could not install code for " + MetaUtil.format("%H.%n(%p)", method)); + throw new GraalInternalError("Could not install code for " + method.format("%H.%n(%p)")); } } catch (Throwable e) { throw Debug.handle(e); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Tue Jul 15 19:21:28 2014 -0700 @@ -464,28 +464,7 @@ assertReadAndWriteInSameBlock(schedule, false); } - /* - * read of field a should be in first block, read of field b in loop begin block - */ - public static void testProxy1Snippet() { - while (container.a < container.b) { - container.b--; - } - container.b++; - } - - @Test - public void testProxy1() { - SchedulePhase schedule = getFinalSchedule("testProxy1Snippet", TestMode.WITHOUT_FRAMESTATES); - assertReadWithinStartBlock(schedule, true); // read of container.a should be in start block - /* - * read of container.b for increment operation should be in return block. TODO: not sure - * though, could be replaced by read of container.b of the loop header... - */ - assertReadWithinAllReturnBlocks(schedule, true); - } - - public static void testProxy2Snippet() { + public static void testProxySnippet() { while (container.a < container.b) { List list = new ArrayList<>(containerList); while (container.c < list.size()) { @@ -501,8 +480,8 @@ } @Test - public void testProxy2() { - SchedulePhase schedule = getFinalSchedule("testProxy2Snippet", TestMode.WITHOUT_FRAMESTATES); + public void testProxy() { + SchedulePhase schedule = getFinalSchedule("testProxySnippet", TestMode.WITHOUT_FRAMESTATES); assertReadWithinStartBlock(schedule, false); assertReadWithinAllReturnBlocks(schedule, false); } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java Tue Jul 15 19:21:28 2014 -0700 @@ -35,52 +35,52 @@ *

* These options enable the associated debug facility if their filter matches the * {@linkplain DebugScope#getQualifiedName() name} of the {@linkplain Debug#currentScope() current - * scope}. + * scope}. For the {@link GraalDebugConfig#Dump} and {@link GraalDebugConfig#Log} options, the log + * or dump level is set. The {@link GraalDebugConfig#Meter} and {@link GraalDebugConfig#Time} + * options don't have a level, for them {@code level = 0} means disabled and a {@code level > 0} + * means enabled. *

- * A filter is a list of comma-separated terms. Each term is interpreted as a glob pattern if it - * contains a "*" or "?" character. Otherwise, it is interpreted as a substring. If a term starts - * with "~", then it is an positive term. An input is matched by a filter if any of its positive - * terms match the input (or it has no positive terms) AND none of its negative terms match the - * input (or it has no negative terms). + * A filter is a list of comma-separated terms of the form {@code [:]}. + * {@code } is interpreted as a glob pattern if it contains a "*" or "?" character. + * Otherwise, it is interpreted as a substring. If {@code } is empty, it matches every + * scope. If {@code :} is omitted, it defaults to {@link Debug#DEFAULT_LOG_LEVEL}. The term + * {@code ~} is a shorthand for {@code :0} to disable a debug facility for a + * pattern. *

- * Examples of filters include: - *

+ * The resulting log level of a scope is determined by the last matching term. If no term + * matches, the log level is 0 (disabled). A filter with no terms matches every scope with a log + * level of {@link Debug#DEFAULT_LOG_LEVEL}. + * + *

Examples of filters

+ * *
    - *
  • - * - *
    - * ""
    - * 
    - * - * Matches any scope.
  • - *
  • - * - *
    - * "*"
    - * 
    - * - * Matches any scope.
  • - *
  • - * - *
    - * "CodeGen,CodeInstall"
    - * 
    - * - * Matches a scope whose name contains "CodeGen" or "CodeInstall".
  • - *
  • - * - *
    - * "Code*"
    - * 
    - * - * Matches a scope whose name starts with "Code".
  • - *
  • - * - *
    - * "Code,˜Dead"
    - * 
    - * - * Matches a scope whose name contains "Code" but does not contain "Dead".
  • + *
  • (empty string)
    + * Matches any scope with log level {@link Debug#DEFAULT_LOG_LEVEL}. + * + *
  • {@code :1}
    + * Matches any scope with log level 1. + * + *
  • {@code *}
    + * Matches any scope with log level {@link Debug#DEFAULT_LOG_LEVEL}. + * + *
  • {@code CodeGen,CodeInstall}
    + * Matches scopes containing "CodeGen" or "CodeInstall", both with log level + * {@link Debug#DEFAULT_LOG_LEVEL}. + * + *
  • {@code CodeGen:2,CodeInstall:1}
    + * Matches scopes containing "CodeGen" with log level 2, or "CodeInstall" with log level 1. + * + *
  • {@code :1,Dead:2}
    + * Matches scopes containing "Dead" with log level 2, and all other scopes with log level 1. + * + *
  • {@code :1,Dead:0}
    + * Matches all scopes with log level 1, except those containing "Dead". + * + *
  • {@code Code*}
    + * Matches scopes starting with "Code" with log level {@link Debug#DEFAULT_LOG_LEVEL}. + * + *
  • {@code Code,~Dead}
    + * Matches scopes containing "Code" but not "Dead", with log level {@link Debug#DEFAULT_LOG_LEVEL}. *
*/ class DebugFilter { @@ -92,69 +92,76 @@ return new DebugFilter(spec.split(",")); } - final Term[] positive; - final Term[] negative; + private final Term[] terms; + + private DebugFilter(String[] terms) { + if (terms.length == 0) { + this.terms = null; + } else { + this.terms = new Term[terms.length]; + for (int i = 0; i < terms.length; i++) { + String t = terms[i]; + int idx = t.indexOf(':'); - DebugFilter(String[] terms) { - List pos = new ArrayList<>(terms.length); - List neg = new ArrayList<>(terms.length); - for (int i = 0; i < terms.length; i++) { - String t = terms[i]; - if (t.startsWith("~")) { - neg.add(new Term(t.substring(1))); - } else { - pos.add(new Term(t)); + String pattern; + int level; + if (idx < 0) { + if (t.startsWith("~")) { + pattern = t.substring(1); + level = 0; + } else { + pattern = t; + level = Debug.DEFAULT_LOG_LEVEL; + } + } else { + pattern = t.substring(0, idx); + if (idx + 1 < t.length()) { + level = Integer.parseInt(t.substring(idx + 1)); + } else { + level = Debug.DEFAULT_LOG_LEVEL; + } + } + + this.terms[i] = new Term(pattern, level); } } - this.positive = pos.isEmpty() ? null : pos.toArray(new Term[pos.size()]); - this.negative = neg.isEmpty() ? null : neg.toArray(new Term[neg.size()]); } /** - * Determines if a given input is matched by this filter. + * Check whether a given input is matched by this filter, and determine the log level. */ - public boolean matches(String input) { - boolean match = true; - if (positive != null) { - match = false; - for (Term t : positive) { + public int matchLevel(String input) { + if (terms == null) { + return Debug.DEFAULT_LOG_LEVEL; + } else { + int level = 0; + for (Term t : terms) { if (t.matches(input)) { - match = true; - break; + level = t.level; } } + return level; } - if (match && negative != null) { - for (Term t : negative) { - if (t.matches(input)) { - match = false; - break; - } - } - } - return match; } @Override public String toString() { - StringBuilder buf = new StringBuilder("DebugFilter["); - String sep = ""; - if (positive != null) { - buf.append(sep).append("pos=").append(Arrays.toString(positive)); - sep = ", "; + StringBuilder buf = new StringBuilder("DebugFilter"); + if (terms != null) { + buf.append(Arrays.toString(terms)); + } else { + buf.append("[]"); } - if (negative != null) { - buf.append(sep).append("neg=").append(Arrays.toString(negative)); - sep = ", "; - } - return buf.append("]").toString(); + return buf.toString(); } - static class Term { + private static class Term { - final Pattern pattern; + private final Pattern pattern; + public final int level; - public Term(String filter) { + public Term(String filter, int level) { + this.level = level; if (filter.isEmpty()) { this.pattern = null; } else if (filter.contains("*") || filter.contains("?")) { @@ -173,7 +180,7 @@ @Override public String toString() { - return pattern == null ? ".*" : pattern.toString(); + return (pattern == null ? ".*" : pattern.toString()) + ":" + level; } } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Tue Jul 15 19:21:28 2014 -0700 @@ -121,8 +121,8 @@ this.output = output; } - public boolean isLogEnabled() { - return isEnabled(logFilter); + public int getLogLevel() { + return getLevel(logFilter); } public boolean isLogEnabledForMethod() { @@ -137,8 +137,8 @@ return isEnabled(trackMemUseFilter); } - public boolean isDumpEnabled() { - return isEnabled(dumpFilter); + public int getDumpLevel() { + return getLevel(dumpFilter); } public boolean isDumpEnabledForMethod() { @@ -162,15 +162,27 @@ } private boolean isEnabled(DebugFilter filter) { - return checkDebugFilter(Debug.currentScope(), filter) && checkMethodFilter(); + return getLevel(filter) > 0; + } + + private int getLevel(DebugFilter filter) { + int level = checkDebugFilter(Debug.currentScope(), filter); + if (level > 0 && !checkMethodFilter()) { + level = 0; + } + return level; } private boolean isEnabledForMethod(DebugFilter filter) { return filter != null && checkMethodFilter(); } - private static boolean checkDebugFilter(String currentScope, DebugFilter filter) { - return filter != null && filter.matches(currentScope); + private static int checkDebugFilter(String currentScope, DebugFilter filter) { + if (filter == null) { + return 0; + } else { + return filter.matchLevel(currentScope); + } } /** @@ -241,7 +253,7 @@ if (e instanceof BailoutException) { return null; } - Debug.setConfig(Debug.fixedConfig(true, true, false, false, false, false, dumpHandlers, verifyHandlers, output)); + Debug.setConfig(Debug.fixedConfig(Debug.DEFAULT_LOG_LEVEL, Debug.DEFAULT_LOG_LEVEL, false, false, false, false, dumpHandlers, verifyHandlers, output)); Debug.log(String.format("Exception occurred in scope: %s", Debug.currentScope())); for (Object o : Debug.context()) { if (o instanceof Graph) { diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/MethodFilter.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/MethodFilter.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/MethodFilter.java Tue Jul 15 19:21:28 2014 -0700 @@ -171,7 +171,7 @@ if (methodName != null && !methodName.matcher(o.getName()).matches()) { return false; } - if (clazz != null && !clazz.matcher(MetaUtil.toJavaName(o.getDeclaringClass())).matches()) { + if (clazz != null && !clazz.matcher(o.getDeclaringClass().toJavaName()).matches()) { return false; } if (signature != null) { @@ -181,7 +181,7 @@ } for (int i = 0; i < signature.length; i++) { JavaType type = sig.getParameterType(i, null); - String javaName = MetaUtil.toJavaName(type); + String javaName = type.toJavaName(); if (signature[i] != null && !signature[i].matcher(javaName).matches()) { return false; } diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Tue Jul 15 19:21:28 2014 -0700 @@ -25,7 +25,7 @@ import static com.oracle.graal.api.code.CodeUtil.*; import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.compiler.GraalDebugConfig.*; -import static com.oracle.graal.compiler.common.cfg.AbstractBlock.*; +import static com.oracle.graal.compiler.common.cfg.AbstractControlFlowGraph.*; import static com.oracle.graal.lir.LIRValueUtil.*; import java.util.*; @@ -1720,7 +1720,7 @@ } else { AbstractBlock spillBlock = blockForId(spillPos); if (interval.alwaysInMemory() && !interval.location().equals(interval.spillSlot())) { - if ((spillBlock.equals(block) && op.id() > spillPos) || AbstractBlock.dominates(spillBlock, block)) { + if ((spillBlock.equals(block) && op.id() > spillPos) || dominates(spillBlock, block)) { assert spillPos > 0 : "position not set correctly"; assert interval.spillSlot() != null : "no spill slot assigned"; assert !isRegister(interval.operand) : "interval is on stack : so stack slot is registered twice"; @@ -1956,7 +1956,7 @@ if (spillBlock == null) { spillBlock = splitBlock; } else { - spillBlock = nearestCommonDominator(spillBlock, splitBlock); + spillBlock = commonDominator(spillBlock, splitBlock); assert spillBlock != null; } } @@ -2086,35 +2086,6 @@ return defBlock; } - private AbstractBlock nearestCommonDominator(AbstractBlock a, AbstractBlock b) { - assert a != null; - assert b != null; - try (Indent indent = Debug.logAndIndent("nearest common dominator of %s and %s", a, b)) { - - if (a.equals(b)) { - return a; - } - - // collect a's dominators - BitSet aDom = new BitSet(sortedBlocks.size()); - - // a != b - for (AbstractBlock x = a; x != null; x = x.getDominator()) { - aDom.set(x.getId()); - } - - // walk b's dominator - for (AbstractBlock x = b; x != null; x = x.getDominator()) { - if (aDom.get(x.getId())) { - Debug.log("found %s", x); - return x; - } - } - } - Debug.log("no common dominator found"); - return null; - } - void printIntervals(String label) { if (Debug.isLogEnabled()) { try (Indent indent = Debug.logAndIndent("intervals %s", label)) { diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Tue Jul 15 19:21:28 2014 -0700 @@ -82,8 +82,14 @@ return config.isDumpEnabledForMethod(); } + public static final int DEFAULT_LOG_LEVEL = 2; + public static boolean isDumpEnabled() { - return ENABLED && DebugScope.getInstance().isDumpEnabled(); + return isDumpEnabled(DEFAULT_LOG_LEVEL); + } + + public static boolean isDumpEnabled(int dumpLevel) { + return ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel); } /** @@ -137,7 +143,11 @@ } public static boolean isLogEnabled() { - return ENABLED && DebugScope.getInstance().isLogEnabled(); + return isLogEnabled(DEFAULT_LOG_LEVEL); + } + + public static boolean isLogEnabled(int logLevel) { + return ENABLED && DebugScope.getInstance().isLogEnabled(logLevel); } @SuppressWarnings("unused") @@ -352,74 +362,106 @@ } } + public static void log(String msg) { + log(DEFAULT_LOG_LEVEL, msg); + } + /** * Prints a message to the current debug scope's logging stream if logging is enabled. * * @param msg the message to log */ - public static void log(String msg) { + public static void log(int logLevel, String msg) { if (ENABLED) { - DebugScope.getInstance().log(msg); + DebugScope.getInstance().log(logLevel, msg); } } + public static void log(String format, Object arg) { + log(DEFAULT_LOG_LEVEL, format, arg); + } + /** * Prints a message to the current debug scope's logging stream if logging is enabled. * * @param format a format string * @param arg the argument referenced by the format specifiers in {@code format} */ - public static void log(String format, Object arg) { + public static void log(int logLevel, String format, Object arg) { if (ENABLED) { - DebugScope.getInstance().log(format, arg); + DebugScope.getInstance().log(logLevel, format, arg); } } + public static void log(String format, Object arg1, Object arg2) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + /** - * @see #log(String, Object) + * @see #log(int, String, Object) */ - public static void log(String format, Object arg1, Object arg2) { + public static void log(int logLevel, String format, Object arg1, Object arg2) { if (ENABLED) { - DebugScope.getInstance().log(format, arg1, arg2); + DebugScope.getInstance().log(logLevel, format, arg1, arg2); } } + public static void log(String format, Object arg1, Object arg2, Object arg3) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); + } + /** - * @see #log(String, Object) + * @see #log(int, String, Object) */ - public static void log(String format, Object arg1, Object arg2, Object arg3) { + public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3) { if (ENABLED) { - DebugScope.getInstance().log(format, arg1, arg2, arg3); + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3); } } + public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4); + } + /** - * @see #log(String, Object) + * @see #log(int, String, Object) */ - public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4) { + public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4) { if (ENABLED) { - DebugScope.getInstance().log(format, arg1, arg2, arg3, arg4); + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4); } } + public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5); + } + /** - * @see #log(String, Object) + * @see #log(int, String, Object) */ - public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { + public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { if (ENABLED) { - DebugScope.getInstance().log(format, arg1, arg2, arg3, arg4, arg5); + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5); } } + public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5, arg6); + } + /** - * @see #log(String, Object) + * @see #log(int, String, Object) */ - public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) { + public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) { if (ENABLED) { - DebugScope.getInstance().log(format, arg1, arg2, arg3, arg4, arg5, arg6); + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5, arg6); } } + public static void logv(String format, Object... args) { + logv(DEFAULT_LOG_LEVEL, format, args); + } + /** * Prints a message to the current debug scope's logging stream. This method must only be called * if debugging is {@linkplain Debug#isEnabled() enabled} as it incurs allocation at the call @@ -429,11 +471,11 @@ * @param format a format string * @param args the arguments referenced by the format specifiers in {@code format} */ - public static void logv(String format, Object... args) { + public static void logv(int logLevel, String format, Object... args) { if (!ENABLED) { throw new InternalError("Use of Debug.logv() must be guarded by a test of Debug.isEnabled()"); } - DebugScope.getInstance().log(format, args); + DebugScope.getInstance().log(logLevel, format, args); } /** @@ -445,30 +487,58 @@ @Deprecated public static void log(String format, Object[] args) { assert false : "shouldn't use this"; - logv(format, args); + log(DEFAULT_LOG_LEVEL, format, args); + } + + /** + * This override exists to catch cases when {@link #log(int, String, Object)} is called with one + * argument bound to a varargs method parameter. It will bind to this method instead of the + * single arg variant and produce a deprecation warning instead of silently wrapping the + * Object[] inside of another Object[]. + */ + @Deprecated + public static void log(int logLevel, String format, Object[] args) { + assert false : "shouldn't use this"; + logv(logLevel, format, args); } public static void dump(Object object, String msg) { - if (ENABLED && DebugScope.getInstance().isDumpEnabled()) { - DebugScope.getInstance().dump(object, msg); + dump(DEFAULT_LOG_LEVEL, object, msg); + } + + public static void dump(int dumpLevel, Object object, String msg) { + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, msg); } } public static void dump(Object object, String format, Object arg) { - if (ENABLED && DebugScope.getInstance().isDumpEnabled()) { - DebugScope.getInstance().dump(object, format, arg); + dump(DEFAULT_LOG_LEVEL, object, format, arg); + } + + public static void dump(int dumpLevel, Object object, String format, Object arg) { + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, format, arg); } } public static void dump(Object object, String format, Object arg1, Object arg2) { - if (ENABLED && DebugScope.getInstance().isDumpEnabled()) { - DebugScope.getInstance().dump(object, format, arg1, arg2); + dump(DEFAULT_LOG_LEVEL, object, format, arg1, arg2); + } + + public static void dump(int dumpLevel, Object object, String format, Object arg1, Object arg2) { + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, format, arg1, arg2); } } public static void dump(Object object, String format, Object arg1, Object arg2, Object arg3) { - if (ENABLED && DebugScope.getInstance().isDumpEnabled()) { - DebugScope.getInstance().dump(object, format, arg1, arg2, arg3); + dump(DEFAULT_LOG_LEVEL, object, format, arg1, arg2, arg3); + } + + public static void dump(int dumpLevel, Object object, String format, Object arg1, Object arg2, Object arg3) { + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, format, arg1, arg2, arg3); } } @@ -481,8 +551,20 @@ @Deprecated public static void dump(Object object, String format, Object[] args) { assert false : "shouldn't use this"; - if (ENABLED && DebugScope.getInstance().isDumpEnabled()) { - DebugScope.getInstance().dump(object, format, args); + dump(DEFAULT_LOG_LEVEL, object, format, args); + } + + /** + * This override exists to catch cases when {@link #dump(int, Object, String, Object)} is called + * with one argument bound to a varargs method parameter. It will bind to this method instead of + * the single arg variant and produce a deprecation warning instead of silently wrapping the + * Object[] inside of another Object[]. + */ + @Deprecated + public static void dump(int dumpLevel, Object object, String format, Object[] args) { + assert false : "shouldn't use this"; + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, format, args); } } @@ -537,8 +619,8 @@ * * @return an object that reverts to the current indentation level when * {@linkplain Indent#close() closed} or null if debugging is disabled - * @see #logAndIndent(String) - * @see #logAndIndent(String, Object) + * @see #logAndIndent(int, String) + * @see #logAndIndent(int, String, Object) */ public static Indent indent() { if (ENABLED) { @@ -548,6 +630,10 @@ return null; } + public static Indent logAndIndent(String msg) { + return logAndIndent(DEFAULT_LOG_LEVEL, msg); + } + /** * A convenience function which combines {@link #log(String)} and {@link #indent()}. * @@ -555,13 +641,17 @@ * @return an object that reverts to the current indentation level when * {@linkplain Indent#close() closed} or null if debugging is disabled */ - public static Indent logAndIndent(String msg) { + public static Indent logAndIndent(int logLevel, String msg) { if (ENABLED) { - return logvAndIndent(msg); + return logvAndIndent(logLevel, msg); } return null; } + public static Indent logAndIndent(String format, Object arg) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg); + } + /** * A convenience function which combines {@link #log(String, Object)} and {@link #indent()}. * @@ -570,45 +660,54 @@ * @return an object that reverts to the current indentation level when * {@linkplain Indent#close() closed} or null if debugging is disabled */ - public static Indent logAndIndent(String format, Object arg) { + public static Indent logAndIndent(int logLevel, String format, Object arg) { + if (ENABLED) { + return logvAndIndent(logLevel, format, arg); + } + return null; + } + + public static Indent logAndIndent(String format, Object arg1, Object arg2) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2) { if (ENABLED) { - return logvAndIndent(format, arg); + return logvAndIndent(logLevel, format, arg1, arg2); + } + return null; + } + + public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2, Object arg3) { + if (ENABLED) { + return logvAndIndent(logLevel, format, arg1, arg2, arg3); } return null; } /** - * @see #logAndIndent(String, Object) - */ - public static Indent logAndIndent(String format, Object arg1, Object arg2) { - if (ENABLED) { - return logvAndIndent(format, arg1, arg2); - } - return null; - } - - /** - * @see #logAndIndent(String, Object) - */ - public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3) { - if (ENABLED) { - return logvAndIndent(format, arg1, arg2, arg3); - } - return null; - } - - /** - * A convenience function which combines {@link #logv(String, Object...)} and {@link #indent()}. + * A convenience function which combines {@link #logv(int, String, Object...)} and + * {@link #indent()}. * * @param format a format string * @param args the arguments referenced by the format specifiers in {@code format} * @return an object that reverts to the current indentation level when * {@linkplain Indent#close() closed} or null if debugging is disabled */ - public static Indent logvAndIndent(String format, Object... args) { + public static Indent logvAndIndent(int logLevel, String format, Object... args) { if (ENABLED) { DebugScope scope = DebugScope.getInstance(); - scope.log(format, args); + scope.log(logLevel, format, args); return scope.pushIndentLogger(); } throw new InternalError("Use of Debug.logvAndIndent() must be guarded by a test of Debug.isEnabled()"); @@ -623,7 +722,19 @@ @Deprecated public static void logAndIndent(String format, Object[] args) { assert false : "shouldn't use this"; - logvAndIndent(format, args); + logAndIndent(DEFAULT_LOG_LEVEL, format, args); + } + + /** + * This override exists to catch cases when {@link #logAndIndent(int, String, Object)} is called + * with one argument bound to a varargs method parameter. It will bind to this method instead of + * the single arg variant and produce a deprecation warning instead of silently wrapping the + * Object[] inside of another Object[]. + */ + @Deprecated + public static void logAndIndent(int logLevel, String format, Object[] args) { + assert false : "shouldn't use this"; + logvAndIndent(logLevel, format, args); } public static Iterable context() { @@ -845,20 +956,20 @@ } public static DebugConfig silentConfig() { - return fixedConfig(false, false, false, false, false, false, Collections. emptyList(), Collections. emptyList(), null); + return fixedConfig(0, 0, false, false, false, false, Collections. emptyList(), Collections. emptyList(), null); } - public static DebugConfig fixedConfig(final boolean isLogEnabled, final boolean isDumpEnabled, final boolean isMeterEnabled, final boolean isMemUseTrackingEnabled, final boolean isTimerEnabled, + public static DebugConfig fixedConfig(final int logLevel, final int dumpLevel, final boolean isMeterEnabled, final boolean isMemUseTrackingEnabled, final boolean isTimerEnabled, final boolean isVerifyEnabled, final Collection dumpHandlers, final Collection verifyHandlers, final PrintStream output) { return new DebugConfig() { @Override - public boolean isLogEnabled() { - return isLogEnabled; + public int getLogLevel() { + return logLevel; } public boolean isLogEnabledForMethod() { - return isLogEnabled; + return logLevel > 0; } @Override @@ -872,12 +983,12 @@ } @Override - public boolean isDumpEnabled() { - return isDumpEnabled; + public int getDumpLevel() { + return dumpLevel; } public boolean isDumpEnabledForMethod() { - return isDumpEnabled; + return dumpLevel > 0; } @Override diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java Tue Jul 15 19:21:28 2014 -0700 @@ -28,9 +28,16 @@ public interface DebugConfig { /** - * Determines if logging is on in the {@linkplain Debug#currentScope() current debug scope} . + * Determines the current log level in the {@linkplain Debug#currentScope() current debug scope} + * . */ - boolean isLogEnabled(); + int getLogLevel(); + + /** + * Determines the current dump level in the {@linkplain Debug#currentScope() current debug + * scope}. + */ + int getDumpLevel(); /** * Determines if logging can be enabled in the current method, regardless of the @@ -55,14 +62,6 @@ boolean isMemUseTrackingEnabled(); /** - * Determines if dumping is enabled in the {@linkplain Debug#currentScope() current debug scope} - * . - * - * @see Debug#dump(Object, String) - */ - boolean isDumpEnabled(); - - /** * Determines if dumping can be enabled in the current method, regardless of the * {@linkplain Debug#currentScope() current debug scope}. */ diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java Tue Jul 15 19:21:28 2014 -0700 @@ -83,6 +83,18 @@ private final Map featureState = new EnumMap<>(Feature.class); /** + * The debug levels of a {@link DelegatingDebugConfig} than can be + * {@linkplain DelegatingDebugConfig#override(Level, int) overridden} or + * {@linkplain DelegatingDebugConfig#delegate(Level) delegated}. + */ + public enum Level { + LOG, + DUMP + } + + private final Map levelState = new EnumMap<>(Level.class); + + /** * Creates a config that delegates to the {@link DebugScope#getConfig() current config}. */ public DelegatingDebugConfig() { @@ -106,18 +118,28 @@ return this; } + public DelegatingDebugConfig override(Level level, int newLevel) { + levelState.put(level, newLevel); + return this; + } + public DelegatingDebugConfig delegate(Feature feature) { featureState.put(feature, null); return this; } + public DelegatingDebugConfig delegate(Level level) { + levelState.put(level, null); + return this; + } + @Override - public boolean isLogEnabled() { - Boolean fs = featureState.get(Feature.LOG); - if (fs == null) { - return delegate.isLogEnabled(); + public int getLogLevel() { + Integer ls = levelState.get(Level.LOG); + if (ls == null) { + return delegate.getLogLevel(); } - return fs.booleanValue(); + return ls.intValue(); } public boolean isLogEnabledForMethod() { @@ -146,12 +168,12 @@ } @Override - public boolean isDumpEnabled() { - Boolean fs = featureState.get(Feature.DUMP); - if (fs == null) { - return delegate.isDumpEnabled(); + public int getDumpLevel() { + Integer ls = levelState.get(Level.DUMP); + if (ls == null) { + return delegate.getDumpLevel(); } - return fs.booleanValue(); + return ls.intValue(); } public boolean isDumpEnabledForMethod() { diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java Tue Jul 15 19:21:28 2014 -0700 @@ -52,8 +52,8 @@ } } - public void log(String msg, Object... args) { - if (isLogEnabled()) { + public void log(int logLevel, String msg, Object... args) { + if (isLogEnabled(logLevel)) { StringBuilder str = new StringBuilder(); printScopeName(str); str.append(indent); @@ -102,9 +102,10 @@ private boolean meterEnabled; private boolean timeEnabled; private boolean memUseTrackingEnabled; - private boolean dumpEnabled; private boolean verifyEnabled; - private boolean logEnabled; + + private int currentDumpLevel; + private int currentLogLevel; private PrintStream output; @@ -163,16 +164,18 @@ lastClosedTL.set(this); } - public boolean isDumpEnabled() { - return dumpEnabled; + public boolean isDumpEnabled(int dumpLevel) { + assert dumpLevel > 0; + return currentDumpLevel >= dumpLevel; } public boolean isVerifyEnabled() { return verifyEnabled; } - public boolean isLogEnabled() { - return logEnabled; + public boolean isLogEnabled(int logLevel) { + assert logLevel > 0; + return currentLogLevel >= logLevel; } public boolean isMeterEnabled() { @@ -187,12 +190,12 @@ return memUseTrackingEnabled; } - public void log(String msg, Object... args) { - lastUsedIndent.log(msg, args); + public void log(int logLevel, String msg, Object... args) { + lastUsedIndent.log(logLevel, msg, args); } - public void dump(Object object, String formatString, Object... args) { - if (isDumpEnabled()) { + public void dump(int dumpLevel, Object object, String formatString, Object... args) { + if (isDumpEnabled(dumpLevel)) { DebugConfig config = getConfig(); if (config != null) { String message = String.format(formatString, args); @@ -289,9 +292,10 @@ meterEnabled = false; memUseTrackingEnabled = false; timeEnabled = false; - dumpEnabled = false; verifyEnabled = false; + currentDumpLevel = 0; + // Be pragmatic: provide a default log stream to prevent a crash if the stream is not // set while logging output = TTY.cachedOut; @@ -299,10 +303,10 @@ meterEnabled = config.isMeterEnabled(); memUseTrackingEnabled = config.isMemUseTrackingEnabled(); timeEnabled = config.isTimeEnabled(); - dumpEnabled = config.isDumpEnabled(); verifyEnabled = config.isVerifyEnabled(); - logEnabled = config.isLogEnabled(); output = config.output(); + currentDumpLevel = config.getDumpLevel(); + currentLogLevel = config.getLogLevel(); } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILNewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILNewObjectSnippets.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILNewObjectSnippets.java Tue Jul 15 19:21:28 2014 -0700 @@ -290,7 +290,7 @@ args.add("hub", hub); args.add("prototypeMarkWord", type.prototypeMarkWord()); args.addConst("fillContents", newInstanceNode.fillContents()); - args.addConst("typeContext", MetaUtil.toJavaName(type, false)); + args.addConst("typeContext", type.toJavaName(false)); SnippetTemplate template = template(args); Debug.log("Lowering allocateInstance in %s: node=%s, template=%s, arguments=%s", graph, newInstanceNode, template, args); @@ -320,7 +320,7 @@ args.addConst("log2ElementSize", log2ElementSize); args.addConst("fillContents", newArrayNode.fillContents()); args.addConst("maybeUnroll", length.isConstant()); - args.addConst("typeContext", MetaUtil.toJavaName(arrayType, false)); + args.addConst("typeContext", arrayType.toJavaName(false)); SnippetTemplate template = template(args); Debug.log("Lowering allocateArray in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, args); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Tue Jul 15 19:21:28 2014 -0700 @@ -25,12 +25,12 @@ import static com.oracle.graal.api.meta.DeoptimizationAction.*; import static com.oracle.graal.api.meta.DeoptimizationReason.*; import static com.oracle.graal.api.meta.LocationIdentity.*; -import static com.oracle.graal.api.meta.MetaUtil.*; import static com.oracle.graal.asm.NumUtil.*; import static com.oracle.graal.hotspot.ptx.PTXHotSpotBackend.*; import static com.oracle.graal.hotspot.ptx.PTXWrapperBuilder.LaunchArg.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.nodes.ConstantNode.*; + import java.util.*; import com.oracle.graal.api.meta.*; @@ -324,7 +324,7 @@ */ private void updateDimArg(ResolvedJavaMethod method, Signature sig, int sigIndex, Map launchArgs, ParameterNode javaParameter) { if (sigIndex >= 0) { - ParallelOver parallelOver = getParameterAnnotation(ParallelOver.class, sigIndex, method); + ParallelOver parallelOver = method.getParameterAnnotation(ParallelOver.class, sigIndex); if (parallelOver != null && sig.getParameterType(sigIndex, method.getDeclaringClass()).equals(providers.getMetaAccess().lookupJavaType(int[].class))) { ArrayLengthNode dimension = append(new ArrayLengthNode(javaParameter)); LaunchArg argKey = LaunchArg.valueOf(LaunchArg.class, "Dim" + parallelOver.dimension()); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot.test; -import static com.oracle.graal.api.meta.MetaUtil.*; import static java.lang.reflect.Modifier.*; import java.lang.reflect.*; @@ -85,7 +84,7 @@ if (argsToBind != null) { Object receiver = isStatic(m.getModifiers()) ? null : this; Object[] args = argsWithReceiver(receiver, argsToBind); - JavaType[] parameterTypes = signatureToTypes(getMetaAccess().lookupJavaMethod(m)); + JavaType[] parameterTypes = getMetaAccess().lookupJavaMethod(m).toParameterTypes(); assert parameterTypes.length == args.length; for (int i = 0; i < argsToBind.length; i++) { ParameterNode param = graph.getParameter(i); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Tue Jul 15 19:21:28 2014 -0700 @@ -692,7 +692,7 @@ }; DebugConfig debugConfig = DebugScope.getConfig(); - DebugConfig fixedConfig = Debug.fixedConfig(false, false, false, false, false, false, debugConfig.dumpHandlers(), debugConfig.verifyHandlers(), debugConfig.output()); + DebugConfig fixedConfig = Debug.fixedConfig(0, 0, false, false, false, false, debugConfig.dumpHandlers(), debugConfig.verifyHandlers(), debugConfig.output()); try (DebugConfigScope s = Debug.setConfig(fixedConfig)) { ReentrantNodeIterator.apply(closure, graph.start(), false); new WriteBarrierVerificationPhase().apply(graph); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationStatistics.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationStatistics.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationStatistics.java Tue Jul 15 19:21:28 2014 -0700 @@ -86,7 +86,7 @@ if (method != null) { holder = method.getDeclaringClass().getName(); name = method.getName(); - signature = method.getSignature().getMethodDescriptor(); + signature = method.getSignature().toMethodDescriptor(); startTime = System.nanoTime(); bytecodeCount = method.getCodeSize(); threadAllocatedBytesStart = getThreadAllocatedBytes(); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Tue Jul 15 19:21:28 2014 -0700 @@ -259,11 +259,11 @@ } catch (BailoutException bailout) { BAILOUTS.increment(); if (ExitVMOnBailout.getValue()) { - TTY.cachedOut.println(MetaUtil.format("Bailout in %H.%n(%p)", method)); + TTY.cachedOut.println(method.format("Bailout in %H.%n(%p)")); bailout.printStackTrace(TTY.cachedOut); System.exit(-1); } else if (PrintBailout.getValue()) { - TTY.cachedOut.println(MetaUtil.format("Bailout in %H.%n(%p)", method)); + TTY.cachedOut.println(method.format("Bailout in %H.%n(%p)")); bailout.printStackTrace(TTY.cachedOut); } } catch (Throwable t) { @@ -287,7 +287,7 @@ // Log a compilation event. if (compilationEvent.shouldWrite()) { - compilationEvent.setMethod(MetaUtil.format("%H.%n(%p)", method)); + compilationEvent.setMethod(method.format("%H.%n(%p)")); compilationEvent.setCompileId(getId()); compilationEvent.setCompileLevel(config.compilationLevelFullOptimization); compilationEvent.setSucceeded(true); @@ -311,7 +311,7 @@ } private String getMethodDescription() { - return String.format("%-6d Graal %-70s %-45s %-50s %s", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature().getMethodDescriptor(), + return String.format("%-6d Graal %-70s %-45s %-50s %s", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature().toMethodDescriptor(), entryBCI == StructuredGraph.INVOCATION_ENTRY_BCI ? "" : "(OSR@" + entryBCI + ") "); } @@ -328,7 +328,7 @@ @Override public String toString() { - return "Compilation[id=" + id + ", " + MetaUtil.format("%H.%n(%p)", method) + (entryBCI == StructuredGraph.INVOCATION_ENTRY_BCI ? "" : "@" + entryBCI) + "]"; + return "Compilation[id=" + id + ", " + method.format("%H.%n(%p)") + (entryBCI == StructuredGraph.INVOCATION_ENTRY_BCI ? "" : "@" + entryBCI) + "]"; } /** diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Tue Jul 15 19:21:28 2014 -0700 @@ -356,7 +356,7 @@ method.reprofile(); // makes the method also not-entrant } catch (Throwable t) { // Catch everything and print a message - println("CompileTheWorld (%d) : Error compiling method: %s", classFileCounter, MetaUtil.format("%H.%n(%p):%r", method)); + println("CompileTheWorld (%d) : Error compiling method: %s", classFileCounter, method.format("%H.%n(%p):%r")); t.printStackTrace(TTY.cachedOut); } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Tue Jul 15 19:21:28 2014 -0700 @@ -370,32 +370,31 @@ } /** - * Converts a name to a Java type. + * Converts a name to a Java type. This method attempts to resolve {@code name} to a + * {@link ResolvedJavaType}. * * @param name a well formed Java type in {@linkplain JavaType#getName() internal} format - * @param accessingType the context of resolution (may be null) - * @param resolve force resolution to a {@link ResolvedJavaType}. If true, this method will - * either return a {@link ResolvedJavaType} or throw an exception + * @param accessingType the context of resolution which must be non-null + * @param resolve specifies whether resolution failure results in an unresolved type being + * return or a {@link LinkageError} being thrown * @return a Java type for {@code name} which is guaranteed to be of type * {@link ResolvedJavaType} if {@code resolve == true} * @throws LinkageError if {@code resolve == true} and the resolution failed + * @throws NullPointerException if {@code accessingClass} is {@code null} */ public JavaType lookupType(String name, HotSpotResolvedObjectType accessingType, boolean resolve) { + Objects.requireNonNull(accessingType, "cannot resolve type without an accessing class"); // If the name represents a primitive type we can short-circuit the lookup. if (name.length() == 1) { Kind kind = Kind.fromPrimitiveOrVoidTypeChar(name.charAt(0)); return HotSpotResolvedPrimitiveType.fromKind(kind); } - // Handle non-primitive types. - Class accessingClass = null; - if (accessingType != null) { - accessingClass = accessingType.mirror(); - } + // Resolve non-primitive types in the VM. + final long metaspaceKlass = compilerToVm.lookupType(name, accessingType.mirror(), resolve); - // Resolve the type in the VM. - final long metaspaceKlass = compilerToVm.lookupType(name, accessingClass, resolve); - if (metaspaceKlass == 0) { + if (metaspaceKlass == 0L) { + assert resolve == false; return HotSpotUnresolvedJavaType.create(name); } return HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass); diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Tue Jul 15 19:21:28 2014 -0700 @@ -109,7 +109,7 @@ * Converts a name to a metaspace klass. * * @param name a well formed Java type in {@linkplain JavaType#getName() internal} format - * @param accessingClass the context of resolution (may be null) + * @param accessingClass the context of resolution (must not be null) * @param resolve force resolution to a {@link ResolvedJavaType}. If true, this method will * either return a {@link ResolvedJavaType} or throw an exception * @return a metaspace klass for {@code name} diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Tue Jul 15 19:21:28 2014 -0700 @@ -115,7 +115,7 @@ String group = counter.getGroup(); if (counter.isWithContext()) { StructuredGraph graph = counter.graph(); - name = counter.getName() + " @ " + graph.graphId() + ":" + (graph.method() == null ? "" : MetaUtil.format("%h.%n", graph.method())); + name = counter.getName() + " @ " + graph.graphId() + ":" + (graph.method() == null ? "" : graph.method().format("%h.%n")); if (graph.name != null) { name += " (" + graph.name + ")"; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/LocalImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/LocalImpl.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/LocalImpl.java Tue Jul 15 19:21:28 2014 -0700 @@ -84,6 +84,6 @@ @Override public String toString() { - return "LocalImpl"; + return "LocalImpl"; } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Tue Jul 15 19:21:28 2014 -0700 @@ -183,7 +183,7 @@ receiverNullCheck = createNullCheck(receiver, invoke.asNode(), tool); invoke.setGuard(receiverNullCheck); } - JavaType[] signature = MetaUtil.signatureToTypes(callTarget.targetMethod().getSignature(), callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass()); + JavaType[] signature = callTarget.targetMethod().getSignature().toParameterTypes(callTarget.isStatic() ? null : callTarget.targetMethod().getDeclaringClass()); LoweredCallTargetNode loweredCallTarget = null; boolean isVirtualOrInterface = callTarget.invokeKind() == InvokeKind.Virtual || callTarget.invokeKind() == InvokeKind.Interface; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethod.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethod.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.api.meta.MetaUtil.*; import static com.oracle.graal.debug.Debug.*; import static java.util.FormattableFlags.*; @@ -56,7 +55,7 @@ char h = FULLY_QUALIFIED_METHOD_NAME ? 'H' : 'h'; String suffix = this instanceof ResolvedJavaMethod ? "" : ", unresolved"; String fmt = String.format("HotSpotMethod<%%%c.%%n(%%p)%s>", h, suffix); - return format(fmt, this); + return format(fmt); } public void formatTo(Formatter formatter, int flags, int width, int precision) { diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Tue Jul 15 19:21:28 2014 -0700 @@ -84,7 +84,7 @@ /** * Returns the size of the extra data records. This method does the same calculation as * MethodData::extra_data_size(). - * + * * @return size of extra data records */ private int extraDataSize() { @@ -543,7 +543,7 @@ 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)); + sb.append(format("%n %s (%d, %4.2f)", profile.items[i].toJavaName(), count, (double) count / profile.totalCount)); } return sb; } @@ -664,7 +664,7 @@ 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)); + sb.append(format("%n %s (%d, %4.2f)", profile.items[i].format("%H.%n(%p)"), count, (double) count / profile.totalCount)); } return sb; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java Tue Jul 15 19:21:28 2014 -0700 @@ -89,14 +89,14 @@ } private boolean checkArgs(Object... args) { - JavaType[] sig = MetaUtil.signatureToTypes(method); - assert args.length == sig.length : MetaUtil.format("%H.%n(%p): expected ", method) + sig.length + " args, got " + args.length; + JavaType[] sig = method.toParameterTypes(); + assert args.length == sig.length : method.format("%H.%n(%p): expected ") + sig.length + " args, got " + args.length; for (int i = 0; i < sig.length; i++) { Object arg = args[i]; if (arg == null) { - assert sig[i].getKind() == Kind.Object : MetaUtil.format("%H.%n(%p): expected arg ", method) + i + " to be Object, not " + sig[i]; + assert sig[i].getKind() == Kind.Object : method.format("%H.%n(%p): expected arg ") + i + " to be Object, not " + sig[i]; } else if (sig[i].getKind() != Kind.Object) { - assert sig[i].getKind().toBoxedJavaClass() == arg.getClass() : MetaUtil.format("%H.%n(%p): expected arg ", method) + i + " to be " + sig[i] + ", not " + arg.getClass(); + assert sig[i].getKind().toBoxedJavaClass() == arg.getClass() : method.format("%H.%n(%p): expected arg ") + i + " to be " + sig[i] + ", not " + arg.getClass(); } } return true; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java Tue Jul 15 19:21:28 2014 -0700 @@ -199,7 +199,7 @@ @Override public String toString() { - return "HotSpotProfilingInfo<" + MetaUtil.profileToString(this, null, "; ") + ">"; + return "HotSpotProfilingInfo<" + this.toString(null, "; ") + ">"; } @Override diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.api.meta.MetaUtil.*; import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType.*; @@ -325,7 +324,7 @@ @Override public String toString() { - return format("HotSpotField<%H.%n %t:", this) + offset + ">"; + return format("HotSpotField<%H.%n %t:") + offset + ">"; } @Override diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Tue Jul 15 19:21:28 2014 -0700 @@ -423,8 +423,8 @@ 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) + ":"); + if (TraceMethodDataFilter != null && this.format("%H.%n").contains(TraceMethodDataFilter)) { + TTY.println("Raw method data for " + this.format("%H.%n(%p)") + ":"); TTY.println(methodData.toString()); } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,9 +22,9 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.api.meta.MetaUtil.*; import static com.oracle.graal.compiler.common.UnsafeAccess.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +import static java.util.Objects.*; import java.lang.annotation.*; import java.lang.reflect.*; @@ -140,7 +140,7 @@ public ResolvedJavaType findUniqueConcreteSubtype() { HotSpotVMConfig config = runtime().getConfig(); if (isArray()) { - return getElementalType(this).isFinal() ? this : null; + return getElementalType().isFinal() ? this : null; } else if (isInterface()) { final long implementorMetaspaceKlass = runtime().getCompilerToVM().getKlassImplementor(getMetaspaceKlass()); @@ -349,6 +349,11 @@ } @Override + public boolean isJavaLangObject() { + return javaClass.equals(Object.class); + } + + @Override public Kind getKind() { return Kind.Object; } @@ -706,9 +711,38 @@ return mirror().getAnnotation(annotationClass); } + /** + * Determines if this type is resolved in the context of a given accessing class. This is a + * conservative check based on this type's class loader being identical to + * {@code accessingClass}'s loader. This type may still be the correct resolved type in the + * context of {@code accessingClass} if its loader is an ancestor of {@code accessingClass}'s + * loader. + */ + public boolean isResolvedWithRespectTo(ResolvedJavaType accessingClass) { + assert accessingClass != null; + ResolvedJavaType elementType = getElementalType(); + if (elementType.isPrimitive()) { + // Primitive type resolution is context free. + return true; + } + if (elementType.getName().startsWith("Ljava/")) { + // Classes in a java.* package can only be defined by the + // boot class loader. This is enforced by ClassLoader.preDefineClass() + assert mirror().getClassLoader() == null; + return true; + } + ClassLoader thisCl = mirror().getClassLoader(); + ClassLoader accessingClassCl = ((HotSpotResolvedObjectType) accessingClass).mirror().getClassLoader(); + return thisCl == accessingClassCl; + } + @Override public ResolvedJavaType resolve(ResolvedJavaType accessingClass) { - return this; + if (isResolvedWithRespectTo(requireNonNull(accessingClass))) { + return this; + } + HotSpotResolvedObjectType accessingType = (HotSpotResolvedObjectType) accessingClass; + return (ResolvedJavaType) runtime().lookupType(getName(), accessingType, true); } /** diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,6 +22,8 @@ */ package com.oracle.graal.hotspot.meta; +import static java.util.Objects.*; + import java.lang.annotation.*; import java.lang.reflect.*; import java.net.*; @@ -77,6 +79,10 @@ return HotSpotResolvedObjectType.fromClass(javaArrayMirror); } + public ResolvedJavaType getElementalType() { + return this; + } + @Override public ResolvedJavaType getComponentType() { return null; @@ -163,6 +169,11 @@ } @Override + public boolean isJavaLangObject() { + return false; + } + + @Override public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) { return null; } @@ -199,6 +210,7 @@ @Override public ResolvedJavaType resolve(ResolvedJavaType accessingClass) { + requireNonNull(accessingClass); return this; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java Tue Jul 15 19:21:28 2014 -0700 @@ -40,8 +40,8 @@ private final List parameters = new ArrayList<>(); private final String returnType; private final String originalString; - private JavaType[] parameterTypes; - private JavaType returnTypeCache; + private ResolvedJavaType[] parameterTypes; + private ResolvedJavaType returnTypeCache; public HotSpotSignature(String signature) { assert signature.length() > 0; @@ -64,7 +64,7 @@ } } - public HotSpotSignature(JavaType returnType, JavaType... parameterTypes) { + public HotSpotSignature(ResolvedJavaType returnType, ResolvedJavaType... parameterTypes) { this.parameterTypes = parameterTypes.clone(); this.returnTypeCache = returnType; this.returnType = returnType.getName(); @@ -128,37 +128,47 @@ } private static boolean checkValidCache(JavaType type, ResolvedJavaType accessingClass) { + assert accessingClass != null; if (!(type instanceof ResolvedJavaType)) { return false; } if (type instanceof HotSpotResolvedObjectType) { - HotSpotResolvedObjectType resolved = (HotSpotResolvedObjectType) type; - if (accessingClass == null) { - return resolved.mirror().getClassLoader() == null; - } else { - return resolved.mirror().getClassLoader() == ((HotSpotResolvedObjectType) accessingClass).mirror().getClassLoader(); - } + return ((HotSpotResolvedObjectType) type).isResolvedWithRespectTo(accessingClass); } + return true; + } - return true; + private static JavaType getUnresolvedOrPrimitiveType(String name) { + if (name.length() == 1) { + Kind kind = Kind.fromPrimitiveOrVoidTypeChar(name.charAt(0)); + return HotSpotResolvedPrimitiveType.fromKind(kind); + } + return new HotSpotUnresolvedJavaType(name); } @Override public JavaType getParameterType(int index, ResolvedJavaType accessingClass) { - if (parameterTypes == null) { - parameterTypes = new JavaType[parameters.size()]; + if (accessingClass == null) { + // Caller doesn't care about resolution context so return an unresolved + // or primitive type (primitive type resolution is context free) + return getUnresolvedOrPrimitiveType(parameters.get(index)); } - JavaType type = parameterTypes[index]; + if (parameterTypes == null) { + parameterTypes = new ResolvedJavaType[parameters.size()]; + } + + ResolvedJavaType type = parameterTypes[index]; if (!checkValidCache(type, accessingClass)) { - type = runtime().lookupType(parameters.get(index), (HotSpotResolvedObjectType) accessingClass, false); + type = (ResolvedJavaType) runtime().lookupType(parameters.get(index), (HotSpotResolvedObjectType) accessingClass, true); parameterTypes[index] = type; } return type; } - public String getMethodDescriptor() { - assert originalString.equals(MetaUtil.signatureToMethodDescriptor(this)); + @Override + public String toMethodDescriptor() { + assert originalString.equals(Signature.super.toMethodDescriptor()); return originalString; } @@ -169,8 +179,13 @@ @Override public JavaType getReturnType(ResolvedJavaType accessingClass) { + if (accessingClass == null) { + // Caller doesn't care about resolution context so return an unresolved + // or primitive type (primitive type resolution is context free) + return getUnresolvedOrPrimitiveType(returnType); + } if (!checkValidCache(returnTypeCache, accessingClass)) { - returnTypeCache = runtime().lookupType(returnType, (HotSpotResolvedObjectType) accessingClass, false); + returnTypeCache = (ResolvedJavaType) runtime().lookupType(returnType, (HotSpotResolvedObjectType) accessingClass, true); } return returnTypeCache; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedField.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedField.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedField.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,8 +22,6 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.api.meta.MetaUtil.*; - import com.oracle.graal.api.meta.*; /** @@ -79,6 +77,6 @@ */ @Override public String toString() { - return format("HotSpotField<%H.%n %t, unresolved>", this); + return format("HotSpotField<%H.%n %t, unresolved>"); } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedJavaType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedJavaType.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedJavaType.java Tue Jul 15 19:21:28 2014 -0700 @@ -35,13 +35,13 @@ public HotSpotUnresolvedJavaType(String name) { super(name); + assert name.charAt(0) == '[' || name.charAt(name.length() - 1) == ';' : name; } /** * Creates an unresolved type for a valid {@link JavaType#getName() type name}. */ public static HotSpotUnresolvedJavaType create(String name) { - assert name.charAt(name.length() - 1) == ';' : name; return new HotSpotUnresolvedJavaType(name); } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -67,12 +67,4 @@ @NodeIntrinsic public static native Word fetchUnrollInfo(long registerSaver); - - public MemoryCheckpoint asMemoryCheckpoint() { - return null; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -96,12 +96,4 @@ */ @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 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SaveAllRegistersNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SaveAllRegistersNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SaveAllRegistersNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,15 +24,18 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.lir.StandardOp.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; /** * Saves all allocatable registers. */ -public class SaveAllRegistersNode extends FixedWithNextNode implements LIRLowerable { +@NodeInfo(allowedUsageTypes = {InputType.Memory}) +public class SaveAllRegistersNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Single { private SaveRegistersOp saveRegistersOp; @@ -59,4 +62,8 @@ */ @NodeIntrinsic public static native long saveAllRegisters(); + + public LocationIdentity getLocationIdentity() { + return LocationIdentity.ANY_LOCATION; + } } diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,10 +22,13 @@ */ package com.oracle.graal.hotspot.nodes; +import java.util.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; @@ -54,7 +57,10 @@ @Override public LocationIdentity[] getLocationIdentities() { - return foreignCalls.getKilledLocations(descriptor); + LocationIdentity[] killedLocations = foreignCalls.getKilledLocations(descriptor); + killedLocations = Arrays.copyOf(killedLocations, killedLocations.length + 1); + killedLocations[killedLocations.length - 1] = HotSpotReplacementsUtil.PENDING_EXCEPTION_LOCATION; + return killedLocations; } protected Value[] operands(NodeLIRBuilderTool gen) { @@ -83,12 +89,4 @@ } return super.toString(verbosity); } - - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -63,7 +63,7 @@ ResolvedJavaMethod method = frameState.method(); boolean isStatic = method.isStatic(); - JavaType[] signature = MetaUtil.signatureToTypes(method.getSignature(), isStatic ? null : method.getDeclaringClass()); + JavaType[] signature = method.getSignature().toParameterTypes(isStatic ? null : method.getDeclaringClass()); CallingConvention cc = lirGen.getResult().getFrameMap().registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, signature, lirGen.target(), false); List parameters = new ArrayList<>(); for (int i = 0, slot = 0; i < cc.getArgumentCount(); i++, slot += HIRFrameStateBuilder.stackSlots(frameState.localAt(slot).getKind())) { diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/UncommonTrapCallNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/UncommonTrapCallNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/UncommonTrapCallNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -70,12 +70,4 @@ @NodeIntrinsic public static native Word uncommonTrap(long registerSaver, int trapRequest); - - public MemoryCheckpoint asMemoryCheckpoint() { - return null; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot.nodes; -import static com.oracle.graal.api.meta.MetaUtil.*; import static com.oracle.graal.hotspot.HotSpotBackend.*; import static com.oracle.graal.hotspot.nodes.CStringNode.*; @@ -62,7 +61,7 @@ whereString = sb.toString(); } else { ResolvedJavaMethod method = graph().method(); - whereString = "in compiled code for " + (method == null ? graph().toString() : format("%H.%n(%p)", method)); + whereString = "in compiled code for " + (method == null ? graph().toString() : method.format("%H.%n(%p)")); } Value whereArg = emitCString(gen, whereString); Value formatArg = emitCString(gen, format); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,6 +24,7 @@ import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.HeapAccess.BarrierType; @@ -90,74 +91,66 @@ private void addWriteNodeBarriers(WriteNode node, StructuredGraph graph) { BarrierType barrierType = node.getBarrierType(); - if (barrierType == BarrierType.PRECISE) { - if (useG1GC()) { - if (!node.isInitialization()) { - addG1PreWriteBarrier(node, node.object(), null, node.location(), true, node.getNullCheck(), graph); + switch (barrierType) { + case NONE: + // nothing to do + break; + case IMPRECISE: + case PRECISE: + boolean precise = barrierType == BarrierType.PRECISE; + if (useG1GC()) { + if (!node.isInitialization()) { + addG1PreWriteBarrier(node, node.object(), null, node.location(), true, node.getNullCheck(), graph); + } + addG1PostWriteBarrier(node, node.object(), node.value(), node.location(), precise, graph); + } else { + addSerialPostWriteBarrier(node, node.object(), node.value(), node.location(), precise, graph); } - addG1PostWriteBarrier(node, node.object(), node.value(), node.location(), true, graph); - } else { - addSerialPostWriteBarrier(node, node.object(), node.value(), node.location(), true, graph); - } - } else if (barrierType == BarrierType.IMPRECISE) { - if (useG1GC()) { - if (!node.isInitialization()) { - addG1PreWriteBarrier(node, node.object(), null, node.location(), true, node.getNullCheck(), graph); - } - addG1PostWriteBarrier(node, node.object(), node.value(), node.location(), false, graph); - } else { - addSerialPostWriteBarrier(node, node.object(), node.value(), node.location(), false, graph); - } - } else { - assert barrierType == BarrierType.NONE; + break; + default: + throw new GraalInternalError("unexpected barrier type: " + barrierType); } } - private void addAtomicReadWriteNodeBarriers(LoweredAtomicReadAndWriteNode loweredAtomicReadAndWriteNode, StructuredGraph graph) { - BarrierType barrierType = loweredAtomicReadAndWriteNode.getBarrierType(); - if (barrierType == BarrierType.PRECISE) { - if (useG1GC()) { - addG1PreWriteBarrier(loweredAtomicReadAndWriteNode, loweredAtomicReadAndWriteNode.object(), null, loweredAtomicReadAndWriteNode.location(), true, - loweredAtomicReadAndWriteNode.getNullCheck(), graph); - addG1PostWriteBarrier(loweredAtomicReadAndWriteNode, loweredAtomicReadAndWriteNode.object(), loweredAtomicReadAndWriteNode.getNewValue(), loweredAtomicReadAndWriteNode.location(), - true, graph); - } else { - addSerialPostWriteBarrier(loweredAtomicReadAndWriteNode, loweredAtomicReadAndWriteNode.object(), loweredAtomicReadAndWriteNode.getNewValue(), loweredAtomicReadAndWriteNode.location(), - true, graph); - } - } else if (barrierType == BarrierType.IMPRECISE) { - if (useG1GC()) { - addG1PreWriteBarrier(loweredAtomicReadAndWriteNode, loweredAtomicReadAndWriteNode.object(), null, loweredAtomicReadAndWriteNode.location(), true, - loweredAtomicReadAndWriteNode.getNullCheck(), graph); - addG1PostWriteBarrier(loweredAtomicReadAndWriteNode, loweredAtomicReadAndWriteNode.object(), loweredAtomicReadAndWriteNode.getNewValue(), loweredAtomicReadAndWriteNode.location(), - false, graph); - } else { - addSerialPostWriteBarrier(loweredAtomicReadAndWriteNode, loweredAtomicReadAndWriteNode.object(), loweredAtomicReadAndWriteNode.getNewValue(), loweredAtomicReadAndWriteNode.location(), - false, graph); - } - } else { - assert barrierType == BarrierType.NONE; + private void addAtomicReadWriteNodeBarriers(LoweredAtomicReadAndWriteNode node, StructuredGraph graph) { + BarrierType barrierType = node.getBarrierType(); + switch (barrierType) { + case NONE: + // nothing to do + break; + case IMPRECISE: + case PRECISE: + boolean precise = barrierType == BarrierType.PRECISE; + if (useG1GC()) { + addG1PreWriteBarrier(node, node.object(), null, node.location(), true, node.getNullCheck(), graph); + addG1PostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), precise, graph); + } else { + addSerialPostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), precise, graph); + } + break; + default: + throw new GraalInternalError("unexpected barrier type: " + barrierType); } } private void addCASBarriers(LoweredCompareAndSwapNode node, StructuredGraph graph) { BarrierType barrierType = node.getBarrierType(); - if (barrierType == BarrierType.PRECISE) { - if (useG1GC()) { - addG1PreWriteBarrier(node, node.object(), node.getExpectedValue(), node.location(), false, false, graph); - addG1PostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), true, graph); - } else { - addSerialPostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), true, graph); - } - } else if (barrierType == BarrierType.IMPRECISE) { - if (useG1GC()) { - addG1PreWriteBarrier(node, node.object(), node.getExpectedValue(), node.location(), false, false, graph); - addG1PostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), false, graph); - } else { - addSerialPostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), false, graph); - } - } else { - assert barrierType == BarrierType.NONE; + switch (barrierType) { + case NONE: + // nothing to do + break; + case IMPRECISE: + case PRECISE: + boolean precise = barrierType == BarrierType.PRECISE; + if (useG1GC()) { + addG1PreWriteBarrier(node, node.object(), node.getExpectedValue(), node.location(), false, false, graph); + addG1PostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), precise, graph); + } else { + addSerialPostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), precise, graph); + } + break; + default: + throw new GraalInternalError("unexpected barrier type: " + barrierType); } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AssertionSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AssertionSnippets.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AssertionSnippets.java Tue Jul 15 19:21:28 2014 -0700 @@ -67,9 +67,6 @@ @NodeIntrinsic(ForeignCallNode.class) private static native void vmMessageC(@ConstantNodeParameter ForeignCallDescriptor stubPrintfC, boolean vmError, Word format, long v1, long v2, long v3); - @NodeIntrinsic(StubForeignCallNode.class) - private static native void stubVmMessageC(@ConstantNodeParameter ForeignCallDescriptor stubPrintfC, boolean vmError, Word format, long v1, long v2, long v3); - public static class Templates extends AbstractTemplates { private final SnippetInfo assertion = snippet(AssertionSnippets.class, "assertion"); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Tue Jul 15 19:21:28 2014 -0700 @@ -481,7 +481,7 @@ if (method == null) { return false; } - return (MetaUtil.format("%H.%n", method).contains(TRACE_METHOD_FILTER)); + return (method.format("%H.%n").contains(TRACE_METHOD_FILTER)); } } @@ -506,7 +506,7 @@ List rets = graph.getNodes(ReturnNode.class).snapshot(); for (ReturnNode ret : rets) { returnType = checkCounter.getMethod().getSignature().getReturnType(checkCounter.getMethod().getDeclaringClass()); - String msg = "unbalanced monitors in " + MetaUtil.format("%H.%n(%p)", graph.method()) + ", count = %d"; + String msg = "unbalanced monitors in " + graph.method().format("%H.%n(%p)") + ", count = %d"; ConstantNode errMsg = ConstantNode.forConstant(HotSpotObjectConstant.forObject(msg), providers.getMetaAccess(), graph); callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, checkCounter.getMethod(), new ValueNode[]{errMsg}, returnType)); invoke = graph.add(new InvokeNode(callTarget, 0)); diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Tue Jul 15 19:21:28 2014 -0700 @@ -23,7 +23,6 @@ package com.oracle.graal.hotspot.replacements; import static com.oracle.graal.api.code.UnsignedMath.*; -import static com.oracle.graal.api.meta.MetaUtil.*; import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.Options.*; @@ -398,7 +397,7 @@ args.addConst("fillContents", newInstanceNode.fillContents()); args.addConst("threadRegister", registers.getThreadRegister()); args.addConst("constantSize", true); - args.addConst("typeContext", ProfileAllocations.getValue() ? toJavaName(type, false) : ""); + args.addConst("typeContext", ProfileAllocations.getValue() ? type.toJavaName(false) : ""); SnippetTemplate template = template(args); Debug.log("Lowering allocateInstance in %s: node=%s, template=%s, arguments=%s", graph, newInstanceNode, template, args); @@ -428,7 +427,7 @@ args.addConst("fillContents", newArrayNode.fillContents()); args.addConst("threadRegister", registers.getThreadRegister()); args.addConst("maybeUnroll", length.isConstant()); - args.addConst("typeContext", ProfileAllocations.getValue() ? toJavaName(arrayType, false) : ""); + args.addConst("typeContext", ProfileAllocations.getValue() ? arrayType.toJavaName(false) : ""); SnippetTemplate template = template(args); Debug.log("Lowering allocateArray in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, args); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java Tue Jul 15 19:21:28 2014 -0700 @@ -135,7 +135,7 @@ * Stack bang to make sure there's enough room for the interpreter frames. Bang stack for * total size of the interpreter frames plus shadow page size. Bang one page at a time * because large sizes can bang beyond yellow and red zones. - * + * * @deprecated This code should go away as soon as JDK-8032410 hits the Graal repository. */ final int totalFrameSizes = unrollBlock.readInt(deoptimizationUnrollBlockTotalFrameSizesOffset()); @@ -143,7 +143,7 @@ Word stackPointer = readRegister(stackPointerRegister); for (int i = 1; i < bangPages; i++) { - stackPointer.writeInt((-i * pageSize()) + stackBias(), 0); + stackPointer.writeInt((-i * pageSize()) + stackBias(), 0, UncommonTrapStub.STACK_BANG_LOCATION); } // Load number of interpreter frames. diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Tue Jul 15 19:21:28 2014 -0700 @@ -23,7 +23,6 @@ package com.oracle.graal.hotspot.stubs; import static com.oracle.graal.api.code.CallingConvention.Type.*; -import static com.oracle.graal.api.meta.MetaUtil.*; import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*; import com.oracle.graal.api.meta.*; @@ -115,7 +114,7 @@ ForeignCallDescriptor d = linkage.getDescriptor(); MetaAccessProvider metaAccess = providers.getMetaAccess(); Class[] arguments = d.getArgumentTypes(); - JavaType[] parameters = new JavaType[arguments.length]; + ResolvedJavaType[] parameters = new ResolvedJavaType[arguments.length]; for (int i = 0; i < arguments.length; i++) { parameters[i] = metaAccess.lookupJavaType(arguments[i]); } @@ -132,7 +131,7 @@ @Override public String toString() { - return format("ForeignCallStub<%n(%p)>", this); + return format("ForeignCallStub<%n(%p)>"); } }; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,8 +22,6 @@ */ package com.oracle.graal.hotspot.stubs; -import static com.oracle.graal.api.meta.MetaUtil.*; - import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; @@ -125,6 +123,6 @@ @Override public String toString() { - return "Stub<" + format("%h.%n", getInstalledCodeOwner()) + ">"; + return "Stub<" + getInstalledCodeOwner().format("%h.%n") + ">"; } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Tue Jul 15 19:21:28 2014 -0700 @@ -43,6 +43,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.schedule.*; +import com.oracle.graal.phases.tiers.*; //JaCoCo Exclude @@ -160,8 +161,10 @@ compResult = new CompilationResult(toString()); try (Scope s0 = Debug.scope("StubCompilation", graph, providers.getCodeCache())) { Assumptions assumptions = new Assumptions(OptAssumptions.getValue()); + Suites defaultSuites = providers.getSuites().getDefaultSuites(); + Suites suites = new Suites(new PhaseSuite<>(), defaultSuites.getMidTier(), defaultSuites.getLowTier()); SchedulePhase schedule = emitFrontEnd(providers, target, graph, assumptions, null, providers.getSuites().getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, - getProfilingInfo(graph), null, providers.getSuites().getDefaultSuites()); + getProfilingInfo(graph), null, suites); emitBackEnd(graph, Stub.this, incomingCc, getInstalledCodeOwner(), backend, target, compResult, CompilationResultBuilderFactory.Default, assumptions, schedule, getRegisterConfig()); } catch (Throwable e) { throw Debug.handle(e); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java Tue Jul 15 19:21:28 2014 -0700 @@ -77,6 +77,8 @@ */ public class UncommonTrapStub extends SnippetStub { + public static final LocationIdentity STACK_BANG_LOCATION = new NamedLocationIdentity("stack bang"); + private final TargetDescription target; public UncommonTrapStub(HotSpotProviders providers, TargetDescription target, HotSpotForeignCallLinkage linkage) { @@ -152,7 +154,7 @@ Word stackPointer = readRegister(stackPointerRegister); for (int i = 1; i < bangPages; i++) { - stackPointer.writeInt((-i * pageSize()) + stackBias(), 0); + stackPointer.writeInt((-i * pageSize()) + stackBias(), 0, STACK_BANG_LOCATION); } // Load number of interpreter frames. diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Tue Jul 15 19:21:28 2014 -0700 @@ -246,6 +246,10 @@ public double probability() { return 1D; } + + public BciBlock getPostdominator() { + return null; + } } public static class ExceptionDispatchBlock extends BciBlock { @@ -1058,7 +1062,7 @@ BciBlockMapping map = new BciBlockMapping(method); map.build(); if (Debug.isDumpEnabled()) { - Debug.dump(map, MetaUtil.format("After block building %f %R %H.%n(%P)", method)); + Debug.dump(map, method.format("After block building %f %R %H.%n(%P)")); } return map; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java Tue Jul 15 19:21:28 2014 -0700 @@ -47,7 +47,7 @@ /** * Disassembles the bytecode of a given method in a {@code javap}-like format. - * + * * @return {@code null} if {@code method} has no bytecode (e.g., it is native or abstract) */ public String disassemble(ResolvedJavaMethod method) { @@ -73,7 +73,7 @@ case ANEWARRAY : { int cpi = stream.readCPI(); JavaType type = cp.lookupType(cpi, opcode); - buf.append(String.format("#%-10d // %s", cpi, MetaUtil.toJavaName(type))); + buf.append(String.format("#%-10d // %s", cpi, type.toJavaName())); break; } case GETSTATIC : @@ -82,7 +82,7 @@ case PUTFIELD : { int cpi = stream.readCPI(); JavaField field = cp.lookupField(cpi, opcode); - String fieldDesc = field.getDeclaringClass().getName().equals(method.getDeclaringClass().getName()) ? MetaUtil.format("%n:%T", field) : MetaUtil.format("%H.%n:%T", field); + String fieldDesc = field.getDeclaringClass().getName().equals(method.getDeclaringClass().getName()) ? field.format("%n:%T") : field.format("%H.%n:%T"); buf.append(String.format("#%-10d // %s", cpi, fieldDesc)); break; } @@ -91,21 +91,21 @@ case INVOKESTATIC : { int cpi = stream.readCPI(); JavaMethod callee = cp.lookupMethod(cpi, opcode); - String calleeDesc = callee.getDeclaringClass().getName().equals(method.getDeclaringClass().getName()) ? MetaUtil.format("%n:(%P)%R", callee) : MetaUtil.format("%H.%n:(%P)%R", callee); + String calleeDesc = callee.getDeclaringClass().getName().equals(method.getDeclaringClass().getName()) ? callee.format("%n:(%P)%R") : callee.format("%H.%n:(%P)%R"); buf.append(String.format("#%-10d // %s", cpi, calleeDesc)); break; } case INVOKEINTERFACE: { int cpi = stream.readCPI(); JavaMethod callee = cp.lookupMethod(cpi, opcode); - String calleeDesc = callee.getDeclaringClass().getName().equals(method.getDeclaringClass().getName()) ? MetaUtil.format("%n:(%P)%R", callee) : MetaUtil.format("%H.%n:(%P)%R", callee); + String calleeDesc = callee.getDeclaringClass().getName().equals(method.getDeclaringClass().getName()) ? callee.format("%n:(%P)%R") : callee.format("%H.%n:(%P)%R"); buf.append(String.format("#%-10s // %s", cpi + ", " + stream.readUByte(bci + 3), calleeDesc)); break; } case INVOKEDYNAMIC: { int cpi = stream.readCPI4(); JavaMethod callee = cp.lookupMethod(cpi, opcode); - String calleeDesc = callee.getDeclaringClass().getName().equals(method.getDeclaringClass().getName()) ? MetaUtil.format("%n:(%P)%R", callee) : MetaUtil.format("%H.%n:(%P)%R", callee); + String calleeDesc = callee.getDeclaringClass().getName().equals(method.getDeclaringClass().getName()) ? callee.format("%n:(%P)%R") : callee.format("%H.%n:(%P)%R"); buf.append(String.format("#%-10d // %s", cpi, calleeDesc)); break; } @@ -206,7 +206,7 @@ case MULTIANEWARRAY : { int cpi = stream.readCPI(); JavaType type = cp.lookupType(cpi, opcode); - buf.append(String.format("#%-10s // %s", cpi + ", " + stream.readUByte(bci + 3), MetaUtil.toJavaName(type))); + buf.append(String.format("#%-10s // %s", cpi + ", " + stream.readUByte(bci + 3), type.toJavaName())); break; } } diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Jul 15 19:21:28 2014 -0700 @@ -171,7 +171,7 @@ @Override protected String getDetailedName() { - return getName() + " " + MetaUtil.format("%H.%n(%p):%r", parser.getMethod()); + return getName() + " " + parser.getMethod().format("%H.%n(%p):%r"); } public static class ExceptionInfo { @@ -213,8 +213,8 @@ @Override protected void build() { if (PrintProfilingInformation.getValue()) { - TTY.println("Profiling info for " + MetaUtil.format("%H.%n(%p)", method)); - TTY.println(MetaUtil.indent(MetaUtil.profileToString(profilingInfo, method, CodeUtil.NEW_LINE), " ")); + TTY.println("Profiling info for " + method.format("%H.%n(%p)")); + TTY.println(MetaUtil.indent(profilingInfo.toString(method, CodeUtil.NEW_LINE), " ")); } try (Indent indent = Debug.logAndIndent("build graph for %s", method)) { diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,7 +22,6 @@ */ package com.oracle.graal.jtt; -import static com.oracle.graal.api.meta.MetaUtil.*; import static java.lang.reflect.Modifier.*; import java.lang.reflect.*; @@ -63,7 +62,7 @@ if (argsToBind != null) { Object receiver = isStatic(m.getModifiers()) ? null : this; Object[] args = argsWithReceiver(receiver, argsToBind); - JavaType[] parameterTypes = signatureToTypes(getMetaAccess().lookupJavaMethod(m)); + JavaType[] parameterTypes = getMetaAccess().lookupJavaMethod(m).toParameterTypes(); assert parameterTypes.length == args.length; for (int i = 0; i < args.length; i++) { ParameterNode param = graph.getParameter(i); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java Tue Jul 15 19:21:28 2014 -0700 @@ -51,7 +51,7 @@ AbstractEndNode forwardEnd = loopBegin.forwardEnd(); for (PhiNode phi : loopBegin.phis()) { ValueNode backValue = phi.singleBackValue(); - if (backValue == null) { + if (backValue == PhiNode.NO_VALUE) { continue; } ValueNode stride = addSub(backValue, phi); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,7 +24,6 @@ import java.util.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.compiler.common.cfg.*; @@ -145,7 +144,7 @@ BinaryNode result = BinaryNode.reassociate(binary, invariant, binary.getX(), binary.getY()); if (result != binary) { if (Debug.isLogEnabled()) { - Debug.log("%s : Reassociated %s into %s", MetaUtil.format("%H::%n", graph.method()), binary, result); + Debug.log("%s : Reassociated %s into %s", graph.method().format("%H::%n"), binary, result); } if (!result.isAlive()) { assert !result.isDeleted(); diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Tue Jul 15 19:21:28 2014 -0700 @@ -332,7 +332,7 @@ * VirtualState nodes contained in the old exit's state may be shared by other * dominated VirtualStates. Those dominated virtual states need to see the * proxy->phi update that are applied below. - * + * * We now update the original fragment's nodes accordingly: */ originalExitState.applyToVirtual(node -> original.nodes.clearAndGrow(node)); @@ -357,8 +357,6 @@ phi = graph.addWithoutUnique(new ValuePhiNode(vpn.stamp(), merge)); } else if (vpn instanceof GuardProxyNode) { phi = graph.addWithoutUnique(new GuardPhiNode(merge)); - } else if (vpn instanceof MemoryProxyNode) { - phi = graph.addWithoutUnique(new MemoryPhiNode(merge, ((MemoryProxyNode) vpn).getLocationIdentity())); } else { throw GraalInternalError.shouldNotReachHere(); } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java --- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java Tue Jul 15 19:21:28 2014 -0700 @@ -299,4 +299,16 @@ assertFalse(new IntegerStamp(32, 0, 0xff00, 0, 0xff00).join(new IntegerStamp(32, 1, 0xff, 0x00, 0xff)).isLegal()); assertFalse(new IntegerStamp(32, 0x100, 0xff00, 0, 0xff00).join(new IntegerStamp(32, 0, 0xff, 0x00, 0xff)).isLegal()); } + + @Test + public void testShiftLeft() { + assertEquals(new IntegerStamp(32, 0, 0x1ff, 0, 0x1ff), StampTool.leftShift(new IntegerStamp(32, 0, 0xff, 0, 0xff), new IntegerStamp(32, 0, 1, 0, 1))); + assertEquals(new IntegerStamp(32, 0, 0x1fe0, 0, 0x1fe0), StampTool.leftShift(new IntegerStamp(32, 0, 0xff, 0, 0xff), new IntegerStamp(32, 5, 5, 5, 5))); + assertEquals(new IntegerStamp(32, 0x1e0, 0x1fe0, 0, 0x1fe0), StampTool.leftShift(new IntegerStamp(32, 0xf, 0xff, 0, 0xff), new IntegerStamp(32, 5, 5, 5, 5))); + + assertEquals(new IntegerStamp(64, 0, 0x1ff, 0, 0x1ff), StampTool.leftShift(new IntegerStamp(64, 0, 0xff, 0, 0xff), new IntegerStamp(32, 0, 1, 0, 1))); + assertEquals(new IntegerStamp(64, 0, 0x1fe0, 0, 0x1fe0), StampTool.leftShift(new IntegerStamp(64, 0, 0xff, 0, 0xff), new IntegerStamp(32, 5, 5, 5, 5))); + assertEquals(new IntegerStamp(64, 0x1e0, 0x1fe0, 0, 0x1fe0), StampTool.leftShift(new IntegerStamp(64, 0xf, 0xff, 0, 0xff), new IntegerStamp(32, 5, 5, 5, 5))); + + } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMemoryCheckpoint.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMemoryCheckpoint.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMemoryCheckpoint.java Tue Jul 15 19:21:28 2014 -0700 @@ -37,12 +37,4 @@ protected AbstractMemoryCheckpoint(Stamp stamp, FrameState stateAfter) { super(stamp, stateAfter); } - - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DirectCallTargetNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DirectCallTargetNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DirectCallTargetNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -36,6 +36,6 @@ @Override public String targetName() { - return MetaUtil.format("Direct#%h.%n", target()); + return target().format("Direct#%h.%n"); } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardPhiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardPhiNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardPhiNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -26,6 +26,9 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.extended.*; +/** + * Guard {@link PhiNode}s merge guard dependencies at control flow merges. + */ @NodeInfo(nameTemplate = "GuardPhi({i#values})", allowedUsageTypes = {InputType.Guard}) public class GuardPhiNode extends PhiNode implements GuardingNode { diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -224,9 +224,7 @@ if (nodeClass.inputsEqual(trueNext, falseNext) && nodeClass.valueEqual(trueNext, falseNext)) { falseNext.replaceAtUsages(trueNext); graph().removeFixed(falseNext); - FixedNode next = trueNext.next(); - trueNext.setNext(null); - trueNext.replaceAtPredecessor(next); + GraphUtil.unlinkFixedNode(trueNext); graph().addBeforeFixed(this, trueNext); for (Node usage : trueNext.usages().snapshot()) { if (usage.isAlive()) { @@ -246,7 +244,8 @@ } } } - } while (false); + break; + } while (true); } /** diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IndirectCallTargetNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IndirectCallTargetNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IndirectCallTargetNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -43,6 +43,6 @@ @Override public String targetName() { - return MetaUtil.format("Indirect#%h.%n", target()); + return target().format("Indirect#%h.%n"); } } diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -232,12 +232,4 @@ updateUsagesInterface(this.guard, guard); this.guard = guard; } - - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -48,12 +48,4 @@ public LocationIdentity getLocationIdentity() { return locationIdentity; } - - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -28,7 +28,7 @@ import com.oracle.graal.nodes.extended.*; /** - * The {@code PhiNode} represents the merging of dataflow in the memory graph. + * Memory {@code PhiNode}s merge memory dependencies at control flow merges. */ @NodeInfo(nameTemplate = "MemoryPhi({i#values}) {p#locationIdentity/s}", allowedUsageTypes = {InputType.Memory}) public class MemoryPhiNode extends PhiNode implements MemoryNode { @@ -45,14 +45,6 @@ return locationIdentity; } - public MemoryCheckpoint asMemoryCheckpoint() { - return null; - } - - public MemoryPhiNode asMemoryPhi() { - return this; - } - @Override public NodeInputList values() { return values; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryProxyNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryProxyNode.java Tue Jul 15 19:15:46 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.nodes; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; - -@NodeInfo(allowedUsageTypes = {InputType.Memory}) -public class MemoryProxyNode extends ProxyNode implements MemoryProxy, LIRLowerable { - - @Input(InputType.Memory) private MemoryNode value; - private final LocationIdentity identity; - - public MemoryProxyNode(MemoryNode value, BeginNode exit, LocationIdentity identity) { - super(StampFactory.forVoid(), exit); - this.value = value; - this.identity = identity; - } - - @Override - public ValueNode value() { - return value.asNode(); - } - - public LocationIdentity getLocationIdentity() { - return identity; - } - - @Override - public void generate(NodeLIRBuilderTool generator) { - } - - @Override - public boolean verify() { - assert value() instanceof MemoryNode : this + " " + value(); - return super.verify(); - } - - public MemoryNode getOriginalMemoryNode() { - return (MemoryNode) value(); - } - - public MemoryCheckpoint asMemoryCheckpoint() { - return getOriginalMemoryNode().asMemoryCheckpoint(); - } - - public MemoryPhiNode asMemoryPhi() { - return getOriginalMemoryNode().asMemoryPhi(); - } - - public Node getOriginalNode() { - return value.asNode(); - } -} diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,12 +22,20 @@ */ package com.oracle.graal.nodes; +import java.util.*; + import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.calc.*; -public abstract class PhiNode extends FloatingNode { +/** + * {@code PhiNode}s represent the merging of edges at a control flow merges ({@link MergeNode} or + * {@link LoopBeginNode}). For a {@link MergeNode}, the order of the values corresponds to the order + * of the ends. For {@link LoopBeginNode}s, the first value corresponds to the loop's predecessor, + * while the rest of the values correspond to the {@link LoopEndNode}s. + */ +public abstract class PhiNode extends FloatingNode implements Simplifiable { @Input(InputType.Association) private MergeNode merge; @@ -129,39 +137,42 @@ values().remove(index); } + public static final ValueNode NO_VALUE = new ValueNode(null) { + // empty dummy class + }; + public ValueNode singleValue() { - ValueNode differentValue = null; - for (ValueNode n : values()) { - assert n != null : "Must have input value!"; - if (n != this) { - if (differentValue == null) { - differentValue = n; - } else if (differentValue != n) { - return null; + Iterator iterator = values().iterator(); + ValueNode singleValue = iterator.next(); + while (iterator.hasNext()) { + ValueNode value = iterator.next(); + if (value != this) { + if (value != singleValue) { + return NO_VALUE; } } } - return differentValue; + return singleValue; } public ValueNode singleBackValue() { assert merge() instanceof LoopBeginNode; - ValueNode differentValue = null; - for (ValueNode n : values().subList(merge().forwardEndCount(), values().size())) { - if (differentValue == null) { - differentValue = n; - } else if (differentValue != n) { - return null; + Iterator iterator = values().iterator(); + iterator.next(); + ValueNode singleValue = iterator.next(); + while (iterator.hasNext()) { + if (iterator.next() != singleValue) { + return NO_VALUE; } } - return differentValue; + return singleValue; } @Override public void simplify(SimplifierTool tool) { ValueNode singleValue = singleValue(); - if (singleValue != null) { + if (singleValue != NO_VALUE) { for (Node node : usages().snapshot()) { if (node instanceof ProxyNode && ((ProxyNode) node).proxyPoint() instanceof LoopExitNode && ((LoopExitNode) ((ProxyNode) node).proxyPoint()).loopBegin() == merge) { tool.addToWorkList(node.usages()); diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,7 +22,6 @@ */ package com.oracle.graal.nodes; -import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.ValueNumberable; @@ -57,10 +56,6 @@ return super.verify(); } - public static MemoryProxyNode forMemory(MemoryNode value, BeginNode exit, LocationIdentity location, StructuredGraph graph) { - return graph.unique(new MemoryProxyNode(value, exit, location)); - } - public static ValueProxyNode forValue(ValueNode value, BeginNode exit, StructuredGraph graph) { return graph.unique(new ValueProxyNode(value, exit)); } diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -36,12 +36,4 @@ public LocationIdentity getLocationIdentity() { return LocationIdentity.ANY_LOCATION; } - - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Tue Jul 15 19:21:28 2014 -0700 @@ -259,9 +259,7 @@ ((BeginNode) node).prepareDelete(); } assert node.usages().isEmpty() : node + " " + node.usages(); - FixedNode next = node.next(); - node.setNext(null); - node.replaceAtPredecessor(next); + GraphUtil.unlinkFixedNode(node); node.safeDelete(); } @@ -288,9 +286,7 @@ public void replaceFixedWithFloating(FixedWithNextNode node, FloatingNode replacement) { assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement; - FixedNode next = node.next(); - node.setNext(null); - node.replaceAtPredecessor(next); + GraphUtil.unlinkFixedNode(node); node.replaceAtUsages(replacement); node.safeDelete(); } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValuePhiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValuePhiNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValuePhiNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,15 +24,13 @@ import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; -import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.type.*; /** - * The {@code PhiNode} represents the merging of dataflow in the graph. It refers to a merge and a - * variable. + * Value {@link PhiNode}s merge data flow values at control flow merges. */ @NodeInfo(nameTemplate = "ValuePhi({i#values})") -public class ValuePhiNode extends PhiNode implements Simplifiable { +public class ValuePhiNode extends PhiNode { @Input final NodeInputList values; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -56,6 +56,26 @@ return ConstantNode.forConstant(evalConst(forX.asConstant(), forY.asConstant()), null); } // Constant 0.0 can't be eliminated since it can affect the sign of the result. + // Constant -0.0 is an additive identity. + if (forY.isConstant()) { + Constant y = forY.asConstant(); + switch (y.getKind()) { + case Float: + // use Float.compare because -0.0f == 0.0f + if (Float.compare(y.asFloat(), -0.0f) == 0) { + return forX; + } + break; + case Double: + // use Double.compare because -0.0 == 0.0 + if (Double.compare(y.asDouble(), -0.0) == 0) { + return forX; + } + break; + default: + throw GraalGraphInternalError.shouldNotReachHere(); + } + } return this; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -52,6 +52,23 @@ if (forX.isConstant() && forY.isConstant()) { return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant())); } + if (forY.isConstant()) { + Constant y = forY.asConstant(); + switch (y.getKind()) { + case Float: + if (y.asFloat() == 1.0f) { + return forX; + } + break; + case Double: + if (y.asDouble() == 1.0) { + return forX; + } + break; + default: + throw GraalGraphInternalError.shouldNotReachHere(); + } + } return this; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -55,6 +55,23 @@ if (forX.isConstant()) { return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant())); } + if (forY.isConstant()) { + Constant y = forY.asConstant(); + switch (y.getKind()) { + case Float: + if (y.asFloat() == 1.0f) { + return forX; + } + break; + case Double: + if (y.asDouble() == 1.0) { + return forX; + } + break; + default: + throw GraalGraphInternalError.shouldNotReachHere(); + } + } return this; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -56,7 +56,27 @@ if (forX.isConstant() && forY.isConstant()) { return ConstantNode.forPrimitive(evalConst(forX.asConstant(), forY.asConstant())); } - // Constant 0.0 can't be eliminated since it can affect the sign of the result. + // Constant -0.0 can't be eliminated since it can affect the sign of the result. + // Constant 0.0 is a subtractive identity. + if (forY.isConstant()) { + Constant y = forY.asConstant(); + switch (y.getKind()) { + case Float: + // use Float.compare because -0.0f == 0.0f + if (Float.compare(y.asFloat(), 0.0f) == 0) { + return forX; + } + break; + case Double: + // use Double.compare because -0.0 == 0.0 + if (Double.compare(y.asDouble(), 0.0) == 0) { + return forX; + } + break; + default: + throw GraalGraphInternalError.shouldNotReachHere(); + } + } return this; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java Tue Jul 15 19:21:28 2014 -0700 @@ -37,7 +37,6 @@ protected double probability; protected Loop loop; - protected List dominated; protected Block postdominator; protected Block(BeginNode node) { @@ -98,13 +97,6 @@ return b; } - public List getDominated() { - if (dominated == null) { - return Collections.emptyList(); - } - return dominated; - } - public Block getPostdominator() { return postdominator; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/CFGVerifier.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/CFGVerifier.java Tue Jul 15 19:15:46 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,125 +0,0 @@ -/* - * 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.nodes.cfg; - -import java.util.*; - -import com.oracle.graal.compiler.common.cfg.*; - -public class CFGVerifier { - - public static boolean verify(ControlFlowGraph cfg) { - for (Block block : cfg.getBlocks()) { - assert block.getId() >= 0; - assert cfg.getBlocks().get(block.getId()) == block; - - for (Block pred : block.getPredecessors()) { - assert pred.getSuccessors().contains(block); - assert pred.getId() < block.getId() || pred.isLoopEnd(); - } - - for (Block sux : block.getSuccessors()) { - assert sux.getPredecessors().contains(block); - assert sux.getId() > block.getId() || sux.isLoopHeader(); - } - - if (block.getDominator() != null) { - assert block.getDominator().getId() < block.getId(); - assert block.getDominator().getDominated().contains(block); - } - for (Block dominated : block.getDominated()) { - assert dominated.getId() > block.getId(); - assert dominated.getDominator() == block; - } - - Block postDominatorBlock = block.getPostdominator(); - if (postDominatorBlock != null) { - assert block.getSuccessorCount() > 0 : "block has post-dominator block, but no successors"; - - BlockMap visitedBlocks = new BlockMap<>(cfg); - visitedBlocks.put(block, true); - - Deque stack = new ArrayDeque<>(); - for (Block sux : block.getSuccessors()) { - visitedBlocks.put(sux, true); - stack.push(sux); - } - - while (stack.size() > 0) { - Block tos = stack.pop(); - assert tos.getId() <= postDominatorBlock.getId(); - if (tos == postDominatorBlock) { - continue; // found a valid path - } - assert tos.getSuccessorCount() > 0 : "no path found"; - - for (Block sux : tos.getSuccessors()) { - if (visitedBlocks.get(sux) == null) { - visitedBlocks.put(sux, true); - stack.push(sux); - } - } - } - } - - assert cfg.getLoops() == null || !block.isLoopHeader() || block.getLoop().getHeader() == block : block.beginNode; - } - - if (cfg.getLoops() != null) { - for (Loop loop : cfg.getLoops()) { - assert loop.getHeader().isLoopHeader(); - - for (Block block : loop.getBlocks()) { - assert block.getId() >= loop.getHeader().getId(); - - Loop blockLoop = block.getLoop(); - while (blockLoop != loop) { - assert blockLoop != null; - blockLoop = blockLoop.getParent(); - } - - if (!(block.isLoopHeader() && block.getLoop() == loop)) { - for (Block pred : block.getPredecessors()) { - if (!loop.getBlocks().contains(pred)) { - assert false : "Loop " + loop + " does not contain " + pred; - return false; - } - } - } - } - - for (Block block : loop.getExits()) { - assert block.getId() >= loop.getHeader().getId(); - - Loop blockLoop = block.getLoop(); - while (blockLoop != null) { - blockLoop = blockLoop.getParent(); - assert blockLoop != loop; - } - } - } - } - - return true; - } -} diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java Tue Jul 15 19:21:28 2014 -0700 @@ -49,7 +49,7 @@ cfg.computeLoopInformation(); } if (computeDominators) { - cfg.computeDominators(); + AbstractControlFlowGraph.computeDominators(cfg); } if (computePostdominators) { cfg.computePostdominators(); @@ -309,49 +309,6 @@ } } - private void computeDominators() { - assert reversePostOrder.get(0).getPredecessorCount() == 0 : "start block has no predecessor and therefore no dominator"; - for (int i = 1; i < reversePostOrder.size(); i++) { - Block block = reversePostOrder.get(i); - assert block.getPredecessorCount() > 0; - Block dominator = null; - for (Block pred : block.getPredecessors()) { - if (!pred.isLoopEnd()) { - dominator = commonDominator(dominator, pred); - } - } - setDominator(block, dominator); - } - } - - private static void setDominator(Block block, Block dominator) { - block.setDominator(dominator); - if (dominator.dominated == null) { - dominator.dominated = new ArrayList<>(); - } - dominator.dominated.add(block); - } - - public static > T commonDominator(T a, T b) { - if (a == null) { - return b; - } - if (b == null) { - return a; - } - T iterA = a; - T iterB = b; - while (iterA != iterB) { - if (iterA.getId() > iterB.getId()) { - iterA = iterA.getDominator(); - } else { - assert iterB.getId() > iterA.getId(); - iterB = iterB.getDominator(); - } - } - return iterA; - } - private void computePostdominators() { outer: for (Block block : postOrder()) { if (block.isLoopEnd()) { diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -92,12 +92,4 @@ updateUsages(lastLocationAccess, newLla); lastLocationAccess = newLla; } - - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -30,6 +30,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; /** * Location node that is the sum of two other location nodes. Can represent locations in the form of @@ -112,6 +113,11 @@ return getY().generateAddress(builder, gen, xAddr); } + @Override + public IntegerStamp getDisplacementStamp() { + return StampTool.add(getX().getDisplacementStamp(), getY().getDisplacementStamp()); + } + @NodeIntrinsic public static native Location addLocation(Location x, Location y); } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -73,4 +73,9 @@ public Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base) { return gen.emitAddress(base, getDisplacement(), Value.ILLEGAL, 0); } + + @Override + public IntegerStamp getDisplacementStamp() { + return StampFactory.forInteger(64, displacement, displacement); + } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -82,7 +82,8 @@ @Override public boolean verify() { MemoryNode lla = getLastLocationAccess(); - assert lla == null || lla.asMemoryCheckpoint() != null || lla.asMemoryPhi() != null : "lastLocationAccess of " + this + " should be a MemoryCheckpoint, but is " + lla; + assert lla == null || lla instanceof MemoryCheckpoint || lla instanceof MemoryProxy || lla instanceof MemoryPhiNode : "lastLocationAccess of " + this + + " should be a MemoryCheckpoint, but is " + lla; return super.verify(); } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.extended; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; @@ -29,6 +30,7 @@ import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; /** * Location node that has a displacement and a scaled index. Can represent locations in the form of @@ -101,6 +103,14 @@ } @Override + public IntegerStamp getDisplacementStamp() { + assert indexScaling > 0 && CodeUtil.isPowerOf2(indexScaling); + int scale = CodeUtil.log2(indexScaling); + return (IntegerStamp) StampTool.add(StampFactory.forInteger(64, displacement, displacement), + StampTool.signExtend(StampTool.leftShift(index.stamp(), StampFactory.forInteger(64, scale, scale)), 64)); + } + + @Override public Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base) { return gen.emitAddress(base, displacement, builder.operand(getIndex()), getIndexScaling()); } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -64,4 +64,9 @@ } public abstract Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base); + + /** + * @return the range of the displacement as a 64-bit integer stamp + */ + public abstract IntegerStamp getDisplacementStamp(); } diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -62,14 +62,6 @@ generator.getLIRGeneratorTool().emitMembar(barriers); } - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } - @SuppressWarnings("unused") @NodeIntrinsic public static void memoryBarrier(@ConstantNodeParameter int barriers) { diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -31,8 +31,4 @@ public interface MemoryNode extends NodeInterface { ValueNode asNode(); - - MemoryCheckpoint asMemoryCheckpoint(); - - MemoryPhiNode asMemoryPhi(); } diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -120,14 +120,6 @@ 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 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -70,12 +70,4 @@ assertTrue(stateAfter() != null, "an exception handler needs a frame state"); return super.verify(); } - - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredAtomicReadAndWriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredAtomicReadAndWriteNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredAtomicReadAndWriteNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -69,14 +69,6 @@ gen.setResult(this, result); } - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } - public boolean canNullCheck() { return false; } diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -84,12 +84,4 @@ Value result = gen.getLIRGeneratorTool().emitCompareAndSwap(address, gen.operand(getExpectedValue()), gen.operand(getNewValue()), Constant.INT_1, Constant.INT_0); gen.setResult(this, result); } - - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -195,7 +195,7 @@ if (targetMethod() == null) { return "??Invalid!"; } - return MetaUtil.format("%h.%n", targetMethod()); + return targetMethod().format("%h.%n"); } public static MethodCallTargetNode find(StructuredGraph graph, ResolvedJavaMethod method) { diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -47,6 +47,10 @@ this.escapedReturnValue = escapedReturnValue; } + public ValueNode getEscapedReturnValue() { + return escapedReturnValue; + } + public void setEscapedReturnValue(ValueNode x) { updateUsages(escapedReturnValue, x); this.escapedReturnValue = x; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/MacroSubstitution.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/MacroSubstitution.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/MacroSubstitution.java Tue Jul 15 19:21:28 2014 -0700 @@ -57,8 +57,7 @@ boolean isStatic() default true; /** - * Gets the {@linkplain MetaUtil#signatureToMethodDescriptor signature} of the substituted - * method. + * Gets the {@linkplain Signature#toMethodDescriptor signature} of the substituted method. *

* If the default value is specified for this element, then the signature of the substituted * method is the same as the substitute method. @@ -82,7 +81,7 @@ /** * Determines if this method should be substituted in all cases, even if inlining thinks it is * not important. - * + * * Note that this is still depending on whether inlining sees the correct call target, so it's * only a hard guarantee for static and special invocations. */ diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java Tue Jul 15 19:21:28 2014 -0700 @@ -298,6 +298,18 @@ } int shiftBits = bits > 32 ? 6 : 5; long shiftMask = bits > 32 ? 0x3FL : 0x1FL; + if (shift.lowerBound() == shift.upperBound()) { + int shiftAmount = (int) (shift.lowerBound() & shiftMask); + if (shiftAmount == 0) { + return value; + } + // the mask of bits that will be lost or shifted into the sign bit + long removedBits = -1L << (bits - shiftAmount - 1); + if ((value.lowerBound() & removedBits) == 0 && (value.upperBound() & removedBits) == 0) { + // use a better stamp if neither lower nor upper bound can lose bits + return new IntegerStamp(bits, value.lowerBound() << shiftAmount, value.upperBound() << shiftAmount, value.downMask() << shiftAmount, value.upMask() << shiftAmount); + } + } if ((shift.lowerBound() >>> shiftBits) == (shift.upperBound() >>> shiftBits)) { long downMask = defaultMask; long upMask = 0; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Tue Jul 15 19:21:28 2014 -0700 @@ -157,10 +157,15 @@ killWithUnusedFloatingInputs(stateAfter); } } + unlinkFixedNode(fixed); + killWithUnusedFloatingInputs(fixed); + } + + public static void unlinkFixedNode(FixedWithNextNode fixed) { + assert fixed.next() != null && fixed.predecessor() != null && fixed.isAlive(); FixedNode next = fixed.next(); fixed.setNext(null); fixed.replaceAtPredecessor(next); - killWithUnusedFloatingInputs(fixed); } public static void checkRedundantPhi(PhiNode phiNode) { @@ -169,7 +174,7 @@ } ValueNode singleValue = phiNode.singleValue(); - if (singleValue != null) { + if (singleValue != PhiNode.NO_VALUE) { Collection phiUsages = phiNode.usages().filter(PhiNode.class).snapshot(); Collection proxyUsages = phiNode.usages().filter(ProxyNode.class).snapshot(); phiNode.graph().replaceFloating(phiNode, singleValue); @@ -338,6 +343,9 @@ v = ((ValueProxy) v).getOriginalNode(); } else if (v instanceof PhiNode) { v = ((PhiNode) v).singleValue(); + if (v == PhiNode.NO_VALUE) { + v = null; + } } else { break; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,7 +24,6 @@ import java.util.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; @@ -102,7 +101,7 @@ for (int objIndex = 0; objIndex < virtualObjects.size(); objIndex++) { VirtualObjectNode virtual = virtualObjects.get(objIndex); StringBuilder s = new StringBuilder(); - s.append(MetaUtil.toJavaName(virtual.type(), false)).append("["); + s.append(virtual.type().toJavaName(false)).append("["); for (int i = 0; i < virtual.entryCount(); i++) { ValueNode value = values.get(valuePos++); s.append(i == 0 ? "" : ",").append(value == null ? "_" : value.toString(Verbosity.Id)); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -63,7 +63,7 @@ @Override public String toString(Verbosity verbosity) { if (verbosity == Verbosity.Name) { - return super.toString(Verbosity.Name) + " " + MetaUtil.toJavaName(type, false); + return super.toString(Verbosity.Name) + " " + type.toJavaName(false); } else { return super.toString(verbosity); } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java Tue Jul 15 19:21:28 2014 -0700 @@ -54,6 +54,7 @@ @Override protected void run(final StructuredGraph graph) { + assert graph.hasValueProxies() : "ConvertDeoptimizeToGuardPhase always creates proxies"; if (graph.getNodes(DeoptimizeNode.class).isEmpty()) { return; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Tue Jul 15 19:21:28 2014 -0700 @@ -43,10 +43,9 @@ public class FloatingReadPhase extends Phase { - public enum ExecutionMode { - ANALYSIS_ONLY, - CREATE_FLOATING_READS - } + private boolean createFloatingReads; + private boolean createMemoryMapNodes; + private boolean updateExistingPhis; public static class MemoryMapImpl implements MemoryMap { @@ -90,14 +89,23 @@ } } - private final ExecutionMode execmode; - public FloatingReadPhase() { - this(ExecutionMode.CREATE_FLOATING_READS); + this(true, false, false); } - public FloatingReadPhase(ExecutionMode execmode) { - this.execmode = execmode; + /** + * @param createFloatingReads specifies whether {@link FloatableAccessNode}s like + * {@link ReadNode} should be converted into floating nodes (e.g., + * {@link FloatingReadNode}s) where possible + * @param createMemoryMapNodes a {@link MemoryMapNode} will be created for each return if this + * is true + * @param updateExistingPhis if true, then existing {@link MemoryPhiNode}s in the graph will be + * updated + */ + public FloatingReadPhase(boolean createFloatingReads, boolean createMemoryMapNodes, boolean updateExistingPhis) { + this.createFloatingReads = createFloatingReads; + this.createMemoryMapNodes = createMemoryMapNodes; + this.updateExistingPhis = updateExistingPhis; } /** @@ -127,7 +135,7 @@ ReentrantNodeIterator.apply(new CollectMemoryCheckpointsClosure(modifiedInLoops), graph.start(), new HashSet()); HashSetNodeEventListener listener = new HashSetNodeEventListener(EnumSet.of(NODE_ADDED, ZERO_USAGES)); try (NodeEventScope nes = graph.trackNodeEvents(listener)) { - ReentrantNodeIterator.apply(new FloatingReadClosure(modifiedInLoops, execmode), graph.start(), new MemoryMapImpl(graph.start())); + ReentrantNodeIterator.apply(new FloatingReadClosure(modifiedInLoops, createFloatingReads, createMemoryMapNodes, updateExistingPhis), graph.start(), new MemoryMapImpl(graph.start())); } for (Node n : removeExternallyUsedNodes(listener.getNodes())) { @@ -136,13 +144,13 @@ GraphUtil.killWithUnusedFloatingInputs(n); } } - if (execmode == ExecutionMode.CREATE_FLOATING_READS) { + if (createFloatingReads) { assert !graph.isAfterFloatingReadPhase(); graph.setAfterFloatingReadPhase(true); } } - public static MemoryMapImpl mergeMemoryMaps(MergeNode merge, List states) { + public static MemoryMapImpl mergeMemoryMaps(MergeNode merge, List states, boolean updateExistingPhis) { MemoryMapImpl newState = new MemoryMapImpl(); Set keys = new HashSet<>(); @@ -151,6 +159,17 @@ } assert !keys.contains(FINAL_LOCATION); + Map existingPhis = null; + if (updateExistingPhis) { + for (MemoryPhiNode phi : merge.phis().filter(MemoryPhiNode.class)) { + if (existingPhis == null) { + existingPhis = newIdentityMap(); + } + phi.values().clear(); + existingPhis.put(phi.getLocationIdentity(), phi); + } + } + for (LocationIdentity key : keys) { int mergedStatesCount = 0; boolean isPhi = false; @@ -158,14 +177,17 @@ for (MemoryMap state : states) { MemoryNode last = state.getLastLocationAccess(key); if (isPhi) { - merged.asMemoryPhi().addInput(ValueNodeUtil.asNode(last)); + ((MemoryPhiNode) merged).addInput(ValueNodeUtil.asNode(last)); } else { if (merged == last) { // nothing to do } else if (merged == null) { merged = last; } else { - MemoryPhiNode phi = merge.graph().addWithoutUnique(new MemoryPhiNode(merge, key)); + MemoryPhiNode phi = null; + if (existingPhis == null || (phi = existingPhis.remove(key)) == null) { + phi = merge.graph().addWithoutUnique(new MemoryPhiNode(merge, key)); + } for (int j = 0; j < mergedStatesCount; j++) { phi.addInput(ValueNodeUtil.asNode(merged)); } @@ -178,6 +200,11 @@ } newState.lastMemorySnapshot.put(key, merged); } + if (existingPhis != null) { + for (Map.Entry entry : existingPhis.entrySet()) { + entry.getValue().replaceAndDelete(newState.getLastLocationAccess(entry.getKey()).asNode()); + } + } return newState; } @@ -237,11 +264,15 @@ private static class FloatingReadClosure extends NodeIteratorClosure { private final Map> modifiedInLoops; - private final ExecutionMode execmode; + private boolean createFloatingReads; + private boolean createMemoryMapNodes; + private boolean updateExistingPhis; - public FloatingReadClosure(Map> modifiedInLoops, ExecutionMode execmode) { + public FloatingReadClosure(Map> modifiedInLoops, boolean createFloatingReads, boolean createMemoryMapNodes, boolean updateExistingPhis) { this.modifiedInLoops = modifiedInLoops; - this.execmode = execmode; + this.createFloatingReads = createFloatingReads; + this.createMemoryMapNodes = createMemoryMapNodes; + this.updateExistingPhis = updateExistingPhis; } @Override @@ -250,7 +281,7 @@ processAccess((MemoryAccess) node, state); } - if (node instanceof FloatableAccessNode && execmode == ExecutionMode.CREATE_FLOATING_READS) { + if (createFloatingReads & node instanceof FloatableAccessNode) { processFloatable((FloatableAccessNode) node, state); } else if (node instanceof MemoryCheckpoint.Single) { processCheckpoint((MemoryCheckpoint.Single) node, state); @@ -259,7 +290,7 @@ } assert MemoryCheckpoint.TypeAssertion.correctType(node) : node; - if (execmode == ExecutionMode.ANALYSIS_ONLY && node instanceof ReturnNode) { + if (createMemoryMapNodes && node instanceof ReturnNode) { ((ReturnNode) node).setMemoryMap(node.graph().unique(new MemoryMapNode(state.lastMemorySnapshot))); } return state; @@ -309,7 +340,7 @@ @Override protected MemoryMapImpl merge(MergeNode merge, List states) { - return mergeMemoryMaps(merge, states); + return mergeMemoryMaps(merge, states, updateExistingPhis); } @Override @@ -339,10 +370,25 @@ } Map phis = new HashMap<>(); + + if (updateExistingPhis) { + for (MemoryPhiNode phi : loop.phis().filter(MemoryPhiNode.class)) { + if (modifiedLocations.contains(phi.getLocationIdentity())) { + phi.values().clear(); + phi.addInput(ValueNodeUtil.asNode(initialState.getLastLocationAccess(phi.getLocationIdentity()))); + phis.put(phi.getLocationIdentity(), phi); + } else { + phi.replaceAndDelete(initialState.getLastLocationAccess(phi.getLocationIdentity()).asNode()); + } + } + } + for (LocationIdentity location : modifiedLocations) { - MemoryPhiNode phi = loop.graph().addWithoutUnique(new MemoryPhiNode(loop, location)); - phi.addInput(ValueNodeUtil.asNode(initialState.getLastLocationAccess(location))); - phis.put(location, phi); + if (!updateExistingPhis || !phis.containsKey(location)) { + MemoryPhiNode phi = loop.graph().addWithoutUnique(new MemoryPhiNode(loop, location)); + phi.addInput(ValueNodeUtil.asNode(initialState.getLastLocationAccess(location))); + phis.put(location, phi); + } } for (Map.Entry entry : phis.entrySet()) { initialState.lastMemorySnapshot.put(entry.getKey(), entry.getValue()); @@ -358,16 +404,6 @@ 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) { - MemoryNode lastAccessAtExit = state.lastMemorySnapshot.get(location); - if (lastAccessAtExit != null) { - state.lastMemorySnapshot.put(location, MemoryProxyNode.forMemory(lastAccessAtExit, exit, location, loop.graph())); - } - } - } return loopInfo.exitStates; } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReductionPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReductionPhase.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReductionPhase.java Tue Jul 15 19:21:28 2014 -0700 @@ -44,7 +44,7 @@ protected final void run(StructuredGraph graph, PhaseContext context) { try (Debug.Scope s = Debug.scope("FlowSensitiveReduction")) { if (graph.isOSR()) { - Debug.log("Skipping OSR method %s", graph.method() == null ? "" : MetaUtil.format("%H.%n", graph.method())); + Debug.log("Skipping OSR method %s", graph.method() == null ? "" : graph.method().format("%H.%n")); return; } Debug.dump(graph, "FlowSensitiveReduction initial"); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java Tue Jul 15 19:21:28 2014 -0700 @@ -146,9 +146,9 @@ private static String methodName(ResolvedJavaMethod method, Invoke invoke) { if (invoke != null && invoke.stateAfter() != null) { - return methodName(invoke.stateAfter(), invoke.bci()) + ": " + MetaUtil.format("%H.%n(%p):%r", method) + " (" + method.getCodeSize() + " bytes)"; + return methodName(invoke.stateAfter(), invoke.bci()) + ": " + method.format("%H.%n(%p):%r") + " (" + method.getCodeSize() + " bytes)"; } else { - return MetaUtil.format("%H.%n(%p):%r", method) + " (" + method.getCodeSize() + " bytes)"; + return method.format("%H.%n(%p):%r") + " (" + method.getCodeSize() + " bytes)"; } } @@ -168,7 +168,7 @@ sb.append(methodName(frameState.outerFrameState(), frameState.outerFrameState().bci)); sb.append("->"); } - sb.append(MetaUtil.format("%h.%n", frameState.method())); + sb.append(frameState.method().format("%h.%n")); sb.append("@").append(bci); return sb.toString(); } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AssumptionInlineInfo.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AssumptionInlineInfo.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AssumptionInlineInfo.java Tue Jul 15 19:21:28 2014 -0700 @@ -26,7 +26,6 @@ import com.oracle.graal.api.code.Assumptions; import com.oracle.graal.api.meta.MetaAccessProvider; -import com.oracle.graal.api.meta.MetaUtil; import com.oracle.graal.api.meta.ResolvedJavaMethod; import com.oracle.graal.nodes.Invoke; import com.oracle.graal.phases.common.inlining.InliningUtil; @@ -62,6 +61,6 @@ @Override public String toString() { - return "assumption " + MetaUtil.format("%H.%n(%p):%r", concrete); + return "assumption " + concrete.format("%H.%n(%p):%r"); } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/ExactInlineInfo.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/ExactInlineInfo.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/ExactInlineInfo.java Tue Jul 15 19:21:28 2014 -0700 @@ -26,7 +26,6 @@ import com.oracle.graal.api.code.Assumptions; import com.oracle.graal.api.meta.MetaAccessProvider; -import com.oracle.graal.api.meta.MetaUtil; import com.oracle.graal.api.meta.ResolvedJavaMethod; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.Invoke; @@ -88,7 +87,7 @@ @Override public String toString() { - return "exact " + MetaUtil.format("%H.%n(%p):%r", concrete); + return "exact " + concrete.format("%H.%n(%p):%r"); } @Override diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java Tue Jul 15 19:21:28 2014 -0700 @@ -545,7 +545,7 @@ builder.append(concretes.size()); builder.append(" methods [ "); for (int i = 0; i < concretes.size(); i++) { - builder.append(MetaUtil.format(" %H.%n(%p):%r", concretes.get(i))); + builder.append(concretes.get(i).format(" %H.%n(%p):%r")); } builder.append(" ], "); builder.append(ptypes.size()); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/TypeGuardInlineInfo.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/TypeGuardInlineInfo.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/TypeGuardInlineInfo.java Tue Jul 15 19:21:28 2014 -0700 @@ -118,7 +118,7 @@ @Override public String toString() { - return "type-checked with type " + type.getName() + " and method " + MetaUtil.format("%H.%n(%p):%r", concrete); + return "type-checked with type " + type.getName() + " and method " + concrete.format("%H.%n(%p):%r"); } public boolean shouldInline() { diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderExplorable.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderExplorable.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderExplorable.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,7 +22,6 @@ */ package com.oracle.graal.phases.common.inlining.walker; -import com.oracle.graal.api.meta.MetaUtil; import com.oracle.graal.api.meta.ResolvedJavaMethod; import com.oracle.graal.nodes.*; import com.oracle.graal.phases.graph.FixedNodeProbabilityCache; @@ -209,6 +208,6 @@ @Override public String toString() { - return (graph != null ? MetaUtil.format("%H.%n(%p)", method()) : "") + remainingInvokes; + return (graph != null ? method().format("%H.%n(%p)") : "") + remainingInvokes; } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/MethodInvocation.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/MethodInvocation.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/MethodInvocation.java Tue Jul 15 19:21:28 2014 -0700 @@ -23,7 +23,6 @@ package com.oracle.graal.phases.common.inlining.walker; import com.oracle.graal.api.code.Assumptions; -import com.oracle.graal.api.meta.MetaUtil; import com.oracle.graal.api.meta.ResolvedJavaMethod; import com.oracle.graal.nodes.CallTargetNode; import com.oracle.graal.nodes.java.MethodCallTargetNode; @@ -152,7 +151,7 @@ CallTargetNode callTarget = callee.invoke().callTarget(); if (callTarget instanceof MethodCallTargetNode) { ResolvedJavaMethod calleeMethod = ((MethodCallTargetNode) callTarget).targetMethod(); - return MetaUtil.format("Invoke#%H.%n(%p)", calleeMethod); + return calleeMethod.format("Invoke#%H.%n(%p)"); } else { return "Invoke#" + callTarget.targetName(); } diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Tue Jul 15 19:21:28 2014 -0700 @@ -38,6 +38,8 @@ */ public abstract class BasePhase { + public static final int PHASE_DUMP_LEVEL = 1; + private CharSequence name; /** @@ -97,8 +99,8 @@ this.run(graph, context); executionCount.increment(); inputNodesCount.add(graph.getNodeCount()); - if (dumpGraph && Debug.isDumpEnabled()) { - Debug.dump(graph, "After phase %s", getName()); + if (dumpGraph && Debug.isDumpEnabled(PHASE_DUMP_LEVEL)) { + Debug.dump(PHASE_DUMP_LEVEL, graph, "After phase %s", getName()); } if (Debug.isVerifyEnabled()) { Debug.verify(graph, "After phase %s", getName()); diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,8 +24,7 @@ import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.compiler.common.GraalOptions.*; -import static com.oracle.graal.nodes.cfg.ControlFlowGraph.*; -import static com.oracle.graal.compiler.common.cfg.AbstractBlock.*; +import static com.oracle.graal.compiler.common.cfg.AbstractControlFlowGraph.*; import java.util.*; @@ -654,7 +653,7 @@ @Override public void apply(Block newBlock) { - this.block = commonDominator(this.block, newBlock); + this.block = commonDominatorTyped(this.block, newBlock); } } @@ -1050,7 +1049,7 @@ LocationIdentity readLocation = frn.location().getLocationIdentity(); assert readLocation != FINAL_LOCATION; if (frn.getLastLocationAccess() == node) { - assert identity == ANY_LOCATION || readLocation == identity : "location doesn't match: " + readLocation + ", " + identity; + assert identity == ANY_LOCATION || readLocation == identity || node instanceof MemoryCheckpoint.Multi : "location doesn't match: " + readLocation + ", " + identity; state.clearBeforeLastLocation(frn); } else if (!state.isBeforeLastLocation(frn) && (readLocation == identity || (node != getCFG().graph.start() && ANY_LOCATION == identity))) { state.removeRead(frn); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java Tue Jul 15 19:21:28 2014 -0700 @@ -107,6 +107,12 @@ } } + public Suites(PhaseSuite highTier, PhaseSuite midTier, PhaseSuite lowTier) { + this.highTier = highTier; + this.midTier = midTier; + this.lowTier = lowTier; + } + private Suites(CompilerConfiguration config) { highTier = config.createHighTier(); midTier = config.createMidTier(); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyDebugUsage.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyDebugUsage.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyDebugUsage.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,8 +22,6 @@ */ package com.oracle.graal.phases.verify; -import static com.oracle.graal.api.meta.MetaUtil.*; - import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.nodes.*; @@ -58,7 +56,7 @@ if (holder.equals("Ljava/lang/StringBuilder;") || holder.equals("Ljava/lang/StringBuffer;")) { StackTraceElement e = graph.method().asStackTraceElement(invoke.bci()); throw new VerificationError(String.format("%s: parameter %d of call to %s appears to be a String concatenation expression.%n" - + " Use one of the multi-parameter Debug.log() methods or Debug.logv() instead.", e, argIdx, format("%H.%n(%p)", callee))); + + " Use one of the multi-parameter Debug.log() methods or Debug.logv() instead.", e, argIdx, callee.format("%H.%n(%p)"))); } } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Tue Jul 15 19:21:28 2014 -0700 @@ -287,7 +287,7 @@ } else if (object instanceof JavaType) { JavaType type = (JavaType) object; writeByte(POOL_CLASS); - writeString(MetaUtil.toJavaName(type)); + writeString(type.toJavaName()); writeByte(KLASS); } else if (object instanceof NodeClass) { NodeClass nodeClass = (NodeClass) object; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinter.java Tue Jul 15 19:21:28 2014 -0700 @@ -186,7 +186,7 @@ if (!inFixedSchedule(input)) { Block inputBlock = block; if (latestScheduling.get(input) != null) { - inputBlock = ControlFlowGraph.commonDominator(inputBlock, latestScheduling.get(input)); + inputBlock = AbstractControlFlowGraph.commonDominatorTyped(inputBlock, latestScheduling.get(input)); } if (inputBlock != latestScheduling.get(input)) { latestScheduling.set(input, inputBlock); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java Tue Jul 15 19:21:28 2014 -0700 @@ -106,8 +106,8 @@ */ public void printCompilation(JavaMethod method) { begin("compilation"); - out.print("name \" ").print(MetaUtil.format("%H::%n", method)).println('"'); - out.print("method \"").print(MetaUtil.format("%f %r %H.%n(%p)", method)).println('"'); + out.print("name \" ").print(method.format("%H::%n")).println('"'); + out.print("method \"").print(method.format("%f %r %H.%n(%p)")).println('"'); out.print("date ").println(System.currentTimeMillis()); end("compilation"); } diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java Tue Jul 15 19:21:28 2014 -0700 @@ -210,7 +210,7 @@ JavaMethod method = asJavaMethod(o); if (method != null) { if (lastMethodOrGraph == null || asJavaMethod(lastMethodOrGraph) == null || !asJavaMethod(lastMethodOrGraph).equals(method)) { - result.add(MetaUtil.format("%H::%n(%p)", method)); + result.add(method.format("%H::%n(%p)")); } else { // This prevents multiple adjacent method context objects for the same method // from resulting in multiple IGV tree levels. This works on the diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Tue Jul 15 19:21:28 2014 -0700 @@ -183,7 +183,7 @@ ResolvedJavaType arrayType = StampTool.typeOrNull(array); if (arrayType != null && StampTool.isExactType(array)) { ResolvedJavaType elementType = arrayType.getComponentType(); - if (!MetaUtil.isJavaLangObject(elementType)) { + if (!elementType.isJavaLangObject()) { checkCastNode = graph.add(new CheckCastNode(elementType, value, null, true)); graph.addBeforeFixed(storeIndexed, checkCastNode); value = checkCastNode; diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Tue Jul 15 19:21:28 2014 -0700 @@ -83,7 +83,7 @@ assert target.getAnnotation(Fold.class) == null; assert target.isStatic() : "node intrinsic must be static: " + target; - ResolvedJavaType[] parameterTypes = resolveJavaTypes(signatureToTypes(target), declaringClass); + ResolvedJavaType[] parameterTypes = resolveJavaTypes(target.toParameterTypes(), declaringClass); // Prepare the arguments for the reflective constructor call on the node class. Constant[] nodeConstructorArguments = prepareArguments(methodCallTargetNode, parameterTypes, target, false); @@ -102,7 +102,7 @@ // Clean up checkcast instructions inserted by javac if the return type is generic. cleanUpReturnList.add(newInstance); } else if (isFoldable(target)) { - ResolvedJavaType[] parameterTypes = resolveJavaTypes(signatureToTypes(target), declaringClass); + ResolvedJavaType[] parameterTypes = resolveJavaTypes(target.toParameterTypes(), declaringClass); // Prepare the arguments for the reflective method call Constant[] arguments = prepareArguments(methodCallTargetNode, parameterTypes, target, true); @@ -165,7 +165,7 @@ parameterIndex--; } ValueNode argument = arguments.get(i); - if (folding || getParameterAnnotation(ConstantNodeParameter.class, parameterIndex, target) != null) { + if (folding || target.getParameterAnnotation(ConstantNodeParameter.class, parameterIndex) != null) { if (!(argument instanceof ConstantNode)) { return null; } @@ -203,8 +203,8 @@ } else { result = providers.getMetaAccess().lookupJavaType(intrinsic.value()); } - assert providers.getMetaAccess().lookupJavaType(ValueNode.class).isAssignableFrom(result) : "Node intrinsic class " + toJavaName(result, false) + " derived from @" + - NodeIntrinsic.class.getSimpleName() + " annotation on " + format("%H.%n(%p)", target) + " is not a subclass of " + ValueNode.class; + assert providers.getMetaAccess().lookupJavaType(ValueNode.class).isAssignableFrom(result) : "Node intrinsic class " + result.toJavaName(false) + " derived from @" + + NodeIntrinsic.class.getSimpleName() + " annotation on " + target.format("%H.%n(%p)") + " is not a subclass of " + ValueNode.class; return result; } @@ -221,12 +221,12 @@ constructor = c; arguments = match; } else { - throw new GraalInternalError("Found multiple constructors in %s compatible with signature %s: %s, %s", toJavaName(nodeClass), sigString(parameterTypes), constructor, c); + throw new GraalInternalError("Found multiple constructors in %s compatible with signature %s: %s, %s", nodeClass.toJavaName(), sigString(parameterTypes), constructor, c); } } } if (constructor == null) { - throw new GraalInternalError("Could not find constructor in %s compatible with signature %s", toJavaName(nodeClass), sigString(parameterTypes)); + throw new GraalInternalError("Could not find constructor in %s compatible with signature %s", nodeClass.toJavaName(), sigString(parameterTypes)); } try { @@ -247,14 +247,14 @@ if (i != 0) { sb.append(", "); } - sb.append(toJavaName(types[i])); + sb.append(types[i].toJavaName()); } return sb.append(")").toString(); } private static boolean containsInjected(ResolvedJavaMethod c, int start, int end) { for (int i = start; i < end; i++) { - if (getParameterAnnotation(InjectedNodeParameter.class, i, c) != null) { + if (c.getParameterAnnotation(InjectedNodeParameter.class, i) != null) { return true; } } @@ -265,10 +265,10 @@ Constant[] arguments = null; Constant[] injected = null; - ResolvedJavaType[] signature = resolveJavaTypes(signatureToTypes(c.getSignature(), null), c.getDeclaringClass()); + ResolvedJavaType[] signature = resolveJavaTypes(c.getSignature().toParameterTypes(null), c.getDeclaringClass()); MetaAccessProvider metaAccess = providers.getMetaAccess(); for (int i = 0; i < signature.length; i++) { - if (getParameterAnnotation(InjectedNodeParameter.class, i, c) != null) { + if (c.getParameterAnnotation(InjectedNodeParameter.class, i) != null) { injected = injected == null ? new Constant[1] : Arrays.copyOf(injected, injected.length + 1); if (signature[i].equals(metaAccess.lookupJavaType(MetaAccessProvider.class))) { injected[injected.length - 1] = snippetReflection.forObject(metaAccess); @@ -279,7 +279,7 @@ } else if (signature[i].equals(metaAccess.lookupJavaType(SnippetReflectionProvider.class))) { injected[injected.length - 1] = snippetReflection.forObject(snippetReflection); } else { - throw new GraalInternalError("Cannot handle injected argument of type %s in %s", toJavaName(signature[i]), format("%H.%n(%p)", c)); + throw new GraalInternalError("Cannot handle injected argument of type %s in %s", signature[i].toJavaName(), c.format("%H.%n(%p)")); } } else { if (i > 0) { @@ -347,9 +347,7 @@ for (Node checkCastUsage : checkCastNode.usages().snapshot()) { checkCheckCastUsage(graph, newInstance, checkCastNode, checkCastUsage); } - FixedNode next = checkCastNode.next(); - checkCastNode.setNext(null); - checkCastNode.replaceAtPredecessor(next); + GraphUtil.unlinkFixedNode(checkCastNode); GraphUtil.killCFG(checkCastNode); } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationVerificationPhase.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationVerificationPhase.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationVerificationPhase.java Tue Jul 15 19:21:28 2014 -0700 @@ -58,7 +58,7 @@ } private static void error(MethodCallTargetNode n, String failedAction) throws GraalInternalError { - String context = MetaUtil.format("%H.%n", n.graph().method()); + String context = n.graph().method().format("%H.%n"); String target = n.invoke().callTarget().targetName(); throw new GraalInternalError(failedAction + " of call to '" + target + "' in '" + context + "' failed, most likely due to a parameter annotated with @" + ConstantNodeParameter.class.getSimpleName() + " not being resolvable to a constant during compilation"); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Tue Jul 15 19:21:28 2014 -0700 @@ -350,7 +350,7 @@ original = metaAccess.lookupJavaConstructor((Constructor) originalMember); } if (Debug.isLogEnabled()) { - Debug.log("substitution: %s --> %s", MetaUtil.format("%H.%n(%p) %r", original), MetaUtil.format("%H.%n(%p) %r", substitute)); + Debug.log("substitution: %s --> %s", original.format("%H.%n(%p) %r"), substitute.format("%H.%n(%p) %r")); } cr.methodSubstitutions.put(original, substitute); @@ -645,8 +645,8 @@ 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 " + + throw new GraalInternalError("Parsing call to JaCoCo instrumentation method " + callee.format("%H.%n(%p)") + " from " + methodToParse.format("%H.%n(%p)") + + " while preparing replacement " + method.format("%H.%n(%p)") + ". Placing \"//JaCoCo Exclude\" anywhere in " + methodToParse.getDeclaringClass().getSourceFileName() + " should fix this."); } targetGraph = parseGraph(callee, policy, inliningDepth + 1); @@ -715,7 +715,7 @@ dimensions++; } - Class baseClass = base.getKind() != Kind.Object ? base.getKind().toJavaClass() : resolveClass(toJavaName(base), false); + Class baseClass = base.getKind() != Kind.Object ? base.getKind().toJavaClass() : resolveClass(base.toJavaName(), false); return dimensions == 0 ? baseClass : Array.newInstance(baseClass, new int[dimensions]).getClass(); } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Jul 15 19:21:28 2014 -0700 @@ -23,7 +23,6 @@ package com.oracle.graal.replacements; import static com.oracle.graal.api.meta.LocationIdentity.*; -import static com.oracle.graal.api.meta.MetaUtil.*; import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.debug.Debug.*; import static com.oracle.graal.graph.util.CollectionsAccess.*; @@ -91,8 +90,8 @@ constantParameters = new boolean[count]; varargsParameters = new boolean[count]; for (int i = 0; i < count; i++) { - constantParameters[i] = MetaUtil.getParameterAnnotation(ConstantParameter.class, i, method) != null; - varargsParameters[i] = MetaUtil.getParameterAnnotation(VarargsParameter.class, i, method) != null; + constantParameters[i] = method.getParameterAnnotation(ConstantParameter.class, i) != null; + varargsParameters[i] = method.getParameterAnnotation(VarargsParameter.class, i) != null; assert !constantParameters[i] || !varargsParameters[i] : "Parameter cannot be annotated with both @" + ConstantParameter.class.getSimpleName() + " and @" + VarargsParameter.class.getSimpleName(); @@ -152,7 +151,7 @@ this.method = method; instantiationCounter = Debug.metric("SnippetInstantiationCount[%s]", method); instantiationTimer = Debug.timer("SnippetInstantiationTime[%s]", method); - assert method.isStatic() : "snippet method must be static: " + MetaUtil.format("%H.%n", method); + assert method.isStatic() : "snippet method must be static: " + method.format("%H.%n"); } private int templateCount; @@ -161,7 +160,7 @@ templateCount++; if (UseSnippetTemplateCache && templateCount > MaxTemplatesPerSnippet) { PrintStream err = System.err; - err.printf("WARNING: Exceeded %d templates for snippet %s%n" + " Adjust maximum with %s system property%n", MaxTemplatesPerSnippet, format("%h.%n(%p)", method), + err.printf("WARNING: Exceeded %d templates for snippet %s%n" + " Adjust maximum with %s system property%n", MaxTemplatesPerSnippet, method.format("%h.%n(%p)"), MAX_TEMPLATES_PER_SNIPPET_PROPERTY_NAME); } } @@ -260,7 +259,7 @@ @Override public String toString() { StringBuilder result = new StringBuilder(); - result.append("Parameters<").append(MetaUtil.format("%h.%n", info.method)).append(" ["); + result.append("Parameters<").append(info.method.format("%h.%n")).append(" ["); String sep = ""; for (int i = 0; i < info.getParameterCount(); i++) { result.append(sep); @@ -497,7 +496,7 @@ * Determines if any parameter of a given method is annotated with {@link ConstantParameter}. */ public static boolean hasConstantParameter(ResolvedJavaMethod method) { - for (ConstantParameter p : MetaUtil.getParameterAnnotations(ConstantParameter.class, method)) { + for (ConstantParameter p : method.getParameterAnnotations(ConstantParameter.class)) { if (p != null) { return true; } @@ -669,7 +668,7 @@ assert checkAllVarargPlaceholdersAreDeleted(parameterCount, placeholders); - new FloatingReadPhase(FloatingReadPhase.ExecutionMode.ANALYSIS_ONLY).apply(snippetCopy); + new FloatingReadPhase(false, true, false).apply(snippetCopy); MemoryAnchorNode memoryAnchor = snippetCopy.add(new MemoryAnchorNode()); snippetCopy.start().replaceAtUsages(InputType.Memory, memoryAnchor); @@ -694,7 +693,7 @@ List memMaps = returnNodes.stream().map(n -> n.getMemoryMap()).collect(Collectors.toList()); ValueNode returnValue = InliningUtil.mergeReturns(merge, returnNodes, null); this.returnNode = snippet.add(new ReturnNode(returnValue)); - MemoryMapImpl mmap = FloatingReadPhase.mergeMemoryMaps(merge, memMaps); + MemoryMapImpl mmap = FloatingReadPhase.mergeMemoryMaps(merge, memMaps, false); MemoryMapNode memoryMap = snippet.unique(new MemoryMapNode(mmap.getMap())); this.returnNode.setMemoryMap(memoryMap); for (MemoryMapNode mm : memMaps) { @@ -747,7 +746,7 @@ private static boolean checkVarargs(MetaAccessProvider metaAccess, final ResolvedJavaMethod method, Signature signature, int i, String name, Varargs varargs) { ResolvedJavaType type = (ResolvedJavaType) signature.getParameterType(i, method.getDeclaringClass()); assert type.isArray() : "varargs parameter must be an array type"; - assert type.getComponentType().isAssignableFrom(metaAccess.lookupJavaType(varargs.componentType)) : "componentType for " + name + " not matching " + MetaUtil.toJavaName(type) + " instance: " + + assert type.getComponentType().isAssignableFrom(metaAccess.lookupJavaType(varargs.componentType)) : "componentType for " + name + " not matching " + type.toJavaName() + " instance: " + varargs.componentType; return true; } diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -25,6 +25,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; @@ -127,6 +128,9 @@ */ protected StructuredGraph lowerReplacement(final StructuredGraph replacementGraph, LoweringTool tool) { final PhaseContext c = new PhaseContext(tool.getMetaAccess(), tool.getConstantReflection(), tool.getLowerer(), tool.getReplacements(), tool.assumptions()); + if (!graph().hasValueProxies()) { + new RemoveValueProxyPhase().apply(replacementGraph); + } GuardsStage guardsStage = graph().getGuardsStage(); if (guardsStage.ordinal() >= GuardsStage.FIXED_DEOPTS.ordinal()) { new GuardLoweringPhase().apply(replacementGraph, null); @@ -164,7 +168,9 @@ InliningUtil.inline(invoke, replacementGraph, false, null); Debug.dump(graph(), "After inlining replacement %s", replacementGraph); } else { - assert stateAfter() != null : "cannot lower to invoke without state: " + this; + if (stateAfter() == null) { + throw new GraalInternalError("cannot lower to invoke without state: %s", this); + } invoke.lower(tool); } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroStateSplitNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroStateSplitNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroStateSplitNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -62,14 +62,6 @@ return LocationIdentity.ANY_LOCATION; } - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } - protected void replaceSnippetInvokes(StructuredGraph snippetGraph) { for (MethodCallTargetNode call : snippetGraph.getNodes(MethodCallTargetNode.class)) { Invoke invoke = call.invoke(); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MemoryAnchorNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MemoryAnchorNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MemoryAnchorNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -44,12 +44,4 @@ public Node canonical(CanonicalizerTool tool) { return usages().isEmpty() ? null : this; } - - public MemoryCheckpoint asMemoryCheckpoint() { - return null; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Tue Jul 15 19:21:28 2014 -0700 @@ -113,22 +113,16 @@ @Override public Object call(Object... args) { + if (profiledArgumentTypesAssumption != null && profiledArgumentTypesAssumption.isValid()) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + profiledArgumentTypesAssumption.invalidate(); + profiledArgumentTypes = null; + } return callBoundary(args); } public Object callDirect(Object... args) { - if (profiledArgumentTypesAssumption == null) { - CompilerDirectives.transferToInterpreter(); - profiledArgumentTypesAssumption = Truffle.getRuntime().createAssumption("Profiled Argument Types"); - profiledArgumentTypes = new Class[args.length]; - } else if (profiledArgumentTypes != null) { - if (profiledArgumentTypes.length != args.length) { - CompilerDirectives.transferToInterpreter(); - profiledArgumentTypesAssumption.invalidate(); - profiledArgumentTypes = null; - } - } - + profileArguments(args); Object result = callBoundary(args); Class klass = profiledReturnType; if (klass != null && CompilerDirectives.inCompiledCode() && profiledReturnTypeAssumption.isValid()) { @@ -137,6 +131,66 @@ return result; } + @ExplodeLoop + private void profileArguments(Object[] args) { + if (profiledArgumentTypesAssumption == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + initializeProfiledArgumentTypes(args); + } else if (profiledArgumentTypes != null) { + if (profiledArgumentTypes.length != args.length) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + profiledArgumentTypesAssumption.invalidate(); + profiledArgumentTypes = null; + } else if (TruffleArgumentTypeSpeculation.getValue() && profiledArgumentTypesAssumption.isValid()) { + for (int i = 0; i < profiledArgumentTypes.length; i++) { + if (profiledArgumentTypes[i] != null && !profiledArgumentTypes[i].isInstance(args[i])) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + updateProfiledArgumentTypes(args); + break; + } + } + } + } + } + + private void initializeProfiledArgumentTypes(Object[] args) { + CompilerAsserts.neverPartOfCompilation(); + profiledArgumentTypesAssumption = Truffle.getRuntime().createAssumption("Profiled Argument Types"); + profiledArgumentTypes = new Class[args.length]; + if (TruffleArgumentTypeSpeculation.getValue()) { + for (int i = 0; i < args.length; i++) { + profiledArgumentTypes[i] = classOf(args[i]); + } + } + } + + private void updateProfiledArgumentTypes(Object[] args) { + CompilerAsserts.neverPartOfCompilation(); + profiledArgumentTypesAssumption.invalidate(); + for (int j = 0; j < profiledArgumentTypes.length; j++) { + profiledArgumentTypes[j] = joinTypes(profiledArgumentTypes[j], classOf(args[j])); + } + profiledArgumentTypesAssumption = Truffle.getRuntime().createAssumption("Profiled Argument Types"); + } + + private static Class classOf(Object arg) { + return arg != null ? arg.getClass() : null; + } + + private static Class joinTypes(Class class1, Class class2) { + if (class1 == class2) { + return class1; + } else if (class1 == null || class2 == null) { + return null; + } else if (class1.isAssignableFrom(class2)) { + return class1; + } else if (class2.isAssignableFrom(class1)) { + return class2; + } else { + return Object.class; + } + } + @TruffleCallBoundary private Object callBoundary(Object[] args) { if (CompilerDirectives.inInterpreter()) { @@ -313,10 +367,12 @@ } public final Object callRoot(Object[] originalArguments) { - Object[] args = originalArguments; if (this.profiledArgumentTypesAssumption != null && CompilerDirectives.inCompiledCode() && profiledArgumentTypesAssumption.isValid()) { args = CompilerDirectives.unsafeCast(castArrayFixedLength(args, profiledArgumentTypes.length), Object[].class, true, true); + if (TruffleArgumentTypeSpeculation.getValue()) { + args = castArguments(args); + } } VirtualFrame frame = createFrame(getRootNode().getFrameDescriptor(), args); @@ -325,13 +381,13 @@ // Profile call return type if (profiledReturnTypeAssumption == null) { if (TruffleReturnTypeSpeculation.getValue()) { - CompilerDirectives.transferToInterpreter(); + CompilerDirectives.transferToInterpreterAndInvalidate(); profiledReturnType = (result == null ? null : result.getClass()); profiledReturnTypeAssumption = Truffle.getRuntime().createAssumption("Profiled Return Type"); } } else if (profiledReturnType != null) { if (result == null || profiledReturnType != result.getClass()) { - CompilerDirectives.transferToInterpreter(); + CompilerDirectives.transferToInterpreterAndInvalidate(); profiledReturnType = null; profiledReturnTypeAssumption.invalidate(); } @@ -340,6 +396,15 @@ return result; } + @ExplodeLoop + private Object[] castArguments(Object[] originalArguments) { + Object[] castArguments = new Object[profiledArgumentTypes.length]; + for (int i = 0; i < profiledArgumentTypes.length; i++) { + castArguments[i] = profiledArgumentTypes[i] != null ? CompilerDirectives.unsafeCast(originalArguments[i], profiledArgumentTypes[i], true, true) : originalArguments[i]; + } + return castArguments; + } + private static Object castArrayFixedLength(Object[] args, @SuppressWarnings("unused") int length) { return args; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Jul 15 19:21:28 2014 -0700 @@ -124,7 +124,7 @@ if (TraceTruffleCompilationHistogram.getValue() && constantReceivers != null) { DebugHistogram histogram = Debug.createHistogram("Expanded Truffle Nodes"); for (Constant c : constantReceivers) { - String javaName = MetaUtil.toJavaName(providers.getMetaAccess().lookupJavaType(c), false); + String javaName = providers.getMetaAccess().lookupJavaType(c).toJavaName(false); // The DSL uses nested classes with redundant names - only show the inner class int index = javaName.indexOf('$'); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Tue Jul 15 19:21:28 2014 -0700 @@ -91,6 +91,8 @@ public static final OptionValue TruffleCompilationDecisionTimePrintFail = new OptionValue<>(false); @Option(help = "") public static final OptionValue TruffleReturnTypeSpeculation = new OptionValue<>(true); + @Option(help = "") + public static final OptionValue TruffleArgumentTypeSpeculation = new StableOptionValue<>(true); // tracing @Option(help = "") diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java Tue Jul 15 19:21:28 2014 -0700 @@ -22,8 +22,6 @@ */ package com.oracle.graal.truffle; -import static com.oracle.graal.api.meta.MetaUtil.*; - import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.truffle.api.*; @@ -127,6 +125,6 @@ @Override public String toString() { - return format("Truffle<%n(%p)>", this); + return format("Truffle<%n(%p)>"); } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectList.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectList.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectList.java Tue Jul 15 19:21:28 2014 -0700 @@ -25,6 +25,8 @@ import java.lang.reflect.*; import java.util.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -34,47 +36,27 @@ */ public class EffectList implements Iterable { - public abstract static class Effect { - - public boolean isVisible() { + public interface Effect { + default boolean isVisible() { return true; } - @Override - public String toString() { - StringBuilder str = new StringBuilder(); - for (Field field : getClass().getDeclaredFields()) { - String name = field.getName(); - if (name.contains("$")) { - name = name.substring(name.indexOf('$') + 1); - } - if (!Modifier.isStatic(field.getModifiers()) && !name.equals("0")) { - try { - field.setAccessible(true); - str.append(str.length() > 0 ? ", " : "").append(name).append("=").append(format(field.get(this))); - } catch (SecurityException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } - } - return name() + " [" + str + "]"; + void apply(StructuredGraph graph, ArrayList obsoleteNodes); + } + + public interface SimpleEffect extends Effect { + default void apply(StructuredGraph graph, ArrayList obsoleteNodes) { + apply(graph); } - private static String format(Object object) { - if (object != null && Object[].class.isAssignableFrom(object.getClass())) { - return Arrays.toString((Object[]) object); - } - return "" + object; - } - - public abstract String name(); - - public abstract void apply(StructuredGraph graph, ArrayList obsoleteNodes); + void apply(StructuredGraph graph); } private static final Effect[] EMPTY_ARRAY = new Effect[0]; + private static final String[] EMPTY_STRING_ARRAY = new String[0]; private Effect[] effects = EMPTY_ARRAY; + private String[] names = EMPTY_STRING_ARRAY; private int size; private void enlarge(int elements) { @@ -84,26 +66,31 @@ length = Math.max(length * 2, 4); } effects = Arrays.copyOf(effects, length); + if (Debug.isEnabled()) { + names = Arrays.copyOf(names, length); + } } } - public void add(Effect effect) { - assert effect != null; - enlarge(1); - effects[size++] = effect; + public void add(String name, SimpleEffect effect) { + add(name, (Effect) effect); } - public void addAll(Collection list) { - enlarge(list.size()); - for (Effect effect : list) { - assert effect != null; - effects[size++] = effect; + public void add(String name, Effect effect) { + assert effect != null; + enlarge(1); + if (Debug.isEnabled()) { + names[size] = name; } + effects[size++] = effect; } public void addAll(EffectList list) { enlarge(list.size); System.arraycopy(list.effects, 0, effects, size, list.size); + if (Debug.isEnabled()) { + System.arraycopy(list.names, 0, names, size, list.size); + } size += list.size; } @@ -112,6 +99,10 @@ enlarge(list.size); System.arraycopy(effects, position, effects, position + list.size, size - position); System.arraycopy(list.effects, 0, effects, position, list.size); + if (Debug.isEnabled()) { + System.arraycopy(names, position, names, position + list.size, size - position); + System.arraycopy(list.names, 0, names, position, list.size); + } size += list.size; } @@ -167,15 +158,65 @@ return size == 0; } + public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { + for (int i = 0; i < size(); i++) { + Effect effect = effects[i]; + try { + effect.apply(graph, obsoleteNodes); + } catch (Throwable t) { + StringBuilder str = new StringBuilder(); + toString(str, i); + throw new GraalInternalError(t).addContext("effect", str); + } + if (effect.isVisible() && Debug.isLogEnabled()) { + StringBuilder str = new StringBuilder(); + toString(str, i); + Debug.log(" %s", str); + } + } + } + + private void toString(StringBuilder str, int i) { + Effect effect = effects[i]; + str.append(getName(i)).append(" ["); + boolean first = true; + for (Field field : effect.getClass().getDeclaredFields()) { + try { + field.setAccessible(true); + str.append(first ? "" : ", ").append(format(field.get(effect))); + first = false; + } catch (SecurityException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + str.append(']'); + } + + private static String format(Object object) { + if (object != null && Object[].class.isAssignableFrom(object.getClass())) { + return Arrays.toString((Object[]) object); + } + return "" + object; + } + @Override public String toString() { StringBuilder str = new StringBuilder(); for (int i = 0; i < size(); i++) { Effect effect = get(i); if (effect.isVisible()) { - str.append(effect).append('\n'); + toString(str, i); + str.append('\n'); } } return str.toString(); } + + private String getName(int i) { + if (Debug.isEnabled()) { + return names[i]; + } else { + return ""; + } + } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Tue Jul 15 19:21:28 2014 -0700 @@ -38,12 +38,11 @@ import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure; import com.oracle.graal.phases.graph.ReentrantBlockIterator.LoopInfo; import com.oracle.graal.phases.schedule.*; -import com.oracle.graal.virtual.phases.ea.EffectList.Effect; public abstract class EffectsClosure> extends EffectsPhase.Closure { - private final ControlFlowGraph cfg; - private final SchedulePhase schedule; + protected final ControlFlowGraph cfg; + protected final SchedulePhase schedule; protected final NodeMap aliases; protected final BlockMap blockEffects; @@ -81,12 +80,7 @@ private void apply(GraphEffectList effects, Object context) { if (!effects.isEmpty()) { Debug.log(" ==== effects for %s", context); - for (Effect effect : effects) { - effect.apply(graph, obsoleteNodes); - if (effect.isVisible()) { - Debug.log(" %s", effect); - } - } + effects.apply(graph, obsoleteNodes); if (TraceEscapeAnalysis.getValue()) { Debug.dump(graph, EffectsClosure.this.getClass().getSimpleName() + " - after processing %s", context); } @@ -228,6 +222,11 @@ @SuppressWarnings("unused") protected void commitEnds(List states) { } + + @Override + public String toString() { + return "MergeProcessor@" + merge; + } } public void addScalarAlias(ValueNode node, ValueNode alias) { diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Tue Jul 15 19:21:28 2014 -0700 @@ -26,44 +26,23 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.debug.*; -import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.util.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.common.*; public class GraphEffectList extends EffectList { public void addCounterBefore(final String group, final String name, final int increment, final boolean addContext, final FixedNode position) { - add(new Effect() { - - @Override - public String name() { - return "addCounterBefore"; - } + add("add counter", graph -> DynamicCounterNode.addCounterBefore(group, name, increment, addContext, position)); + } - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - assert position.isAlive(); - DynamicCounterNode.addCounterBefore(group, name, increment, addContext, position); - } - }); + public void addCounterAfter(final String group, final String name, final int increment, final boolean addContext, final FixedWithNextNode position) { + add("add counter after", graph -> DynamicCounterNode.addCounterBefore(group, name, increment, addContext, position.next())); } public void addWeakCounterCounterBefore(final String group, final String name, final int increment, final boolean addContext, final ValueNode checkedValue, final FixedNode position) { - add(new Effect() { - - @Override - public String name() { - return "addWeakCounterBefore"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - assert position.isAlive(); - WeakCounterNode.addCounterBefore(group, name, increment, addContext, checkedValue, position); - } - }); + add("add weak counter", graph -> WeakCounterNode.addCounterBefore(group, name, increment, addContext, checkedValue, position)); } /** @@ -74,18 +53,9 @@ * @param position The fixed node before which the node should be added. */ public void addFixedNodeBefore(final FixedWithNextNode node, final FixedNode position) { - add(new Effect() { - - @Override - public String name() { - return "addFixedNodeBefore"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - assert !node.isAlive() && !node.isDeleted() && position.isAlive(); - graph.addBeforeFixed(position, graph.add(node)); - } + add("add fixed node", graph -> { + assert !node.isAlive() && !node.isDeleted() && position.isAlive(); + graph.addBeforeFixed(position, graph.add(node)); }); } @@ -94,20 +64,8 @@ * * @param node The floating node to be added. */ - public void addFloatingNode(final ValueNode node, final String cause) { - add(new Effect() { - - @Override - public String name() { - return "addFloatingNode " + cause; - } - - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - assert !node.isAlive() && !node.isDeleted() : node + " " + cause; - graph.addWithoutUnique(node); - } - }); + public void addFloatingNode(final ValueNode node, @SuppressWarnings("unused") final String cause) { + add("add floating node", graph -> graph.addWithoutUnique(node)); } /** @@ -117,18 +75,9 @@ * @param value The value that will be added to the phi node. */ public void addPhiInput(final PhiNode node, final ValueNode value) { - add(new Effect() { - - @Override - public String name() { - return "addPhiInput"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - assert node.isAlive() && value.isAlive() : node + " " + value; - node.addInput(value); - } + add("add phi input", graph -> { + assert node.isAlive() && value.isAlive() : node + " " + value; + node.addInput(value); }); } @@ -141,18 +90,9 @@ * @param value The new value for the phi input. */ public void initializePhiInput(final PhiNode node, final int index, final ValueNode value) { - add(new Effect() { - - @Override - public String name() { - return "setPhiInput"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - assert node.isAlive() && value.isAlive() && index >= 0; - node.initializeValueAt(index, value); - } + add("set phi input", (graph, obsoleteNodes) -> { + assert node.isAlive() && value.isAlive() && index >= 0; + node.initializeValueAt(index, value); }); } @@ -164,13 +104,7 @@ * @param state The virtual object state to add. */ public void addVirtualMapping(final FrameState node, final EscapeObjectState state) { - add(new Effect() { - - @Override - public String name() { - return "addVirtualMapping"; - } - + add("add virtual mapping", new Effect() { @Override public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { assert node.isAlive() && !state.isAlive() && !state.isDeleted(); @@ -196,22 +130,19 @@ * @param node The fixed node that should be deleted. */ public void deleteFixedNode(final FixedWithNextNode node) { - add(new Effect() { - - @Override - public String name() { - return "deleteFixedNode"; - } + add("delete fixed node", (graph, obsoleteNodes) -> { + GraphUtil.unlinkFixedNode(node); + assert obsoleteNodes.add(node); + }); + } - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - assert node.isAlive(); - FixedNode next = node.next(); - node.setNext(null); - node.replaceAtPredecessor(next); - assert obsoleteNodes.add(node); - } - }); + /** + * Removes the given fixed node from the control flow. + * + * @param node The fixed node that should be deleted. + */ + public void unlinkFixedNode(final FixedWithNextNode node) { + add("unlink fixed node", graph -> GraphUtil.unlinkFixedNode(node)); } /** @@ -225,27 +156,18 @@ * */ public void replaceAtUsages(final ValueNode node, final ValueNode replacement) { - add(new Effect() { - - @Override - public String name() { - return "replaceAtUsages"; + add("replace at usages", (graph, obsoleteNodes) -> { + assert node.isAlive() && replacement.isAlive(); + if (replacement instanceof FixedWithNextNode && ((FixedWithNextNode) replacement).next() == null) { + assert node instanceof FixedNode; + graph.addBeforeFixed((FixedNode) node, (FixedWithNextNode) replacement); } - - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - assert node.isAlive() && replacement.isAlive(); - if (replacement instanceof FixedWithNextNode && ((FixedWithNextNode) replacement).next() == null) { - assert node instanceof FixedNode; - graph.addBeforeFixed((FixedNode) node, (FixedWithNextNode) replacement); - } - node.replaceAtUsages(replacement); - if (node instanceof FixedWithNextNode) { - FixedNode next = ((FixedWithNextNode) node).next(); - ((FixedWithNextNode) node).setNext(null); - node.replaceAtPredecessor(next); - assert obsoleteNodes.add(node); - } + node.replaceAtUsages(replacement); + if (node instanceof FixedWithNextNode) { + FixedNode next = ((FixedWithNextNode) node).next(); + ((FixedWithNextNode) node).setNext(null); + node.replaceAtPredecessor(next); + assert obsoleteNodes.add(node); } }); } @@ -258,13 +180,7 @@ * @param newInput The value to replace with. */ public void replaceFirstInput(final Node node, final Node oldInput, final Node newInput) { - add(new Effect() { - - @Override - public String name() { - return "replaceFirstInput"; - } - + add("replace first input", new Effect() { @Override public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { assert node.isAlive() && oldInput.isAlive() && newInput.isAlive(); @@ -284,83 +200,6 @@ * @param action The action that should be performed when the effects are applied. */ public void customAction(final Runnable action) { - add(new Effect() { - - @Override - public String name() { - return "customAction"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - action.run(); - } - }); - } - - /** - * Add the materialization node to the graph's control flow at the given position, and then sets - * its values. - * - * @param position The fixed node before which the materialization node should be added. - * @param objects The allocated objects. - * @param locks The lock depths for each object. - * @param values The values (field, elements) of all objects. - * @param otherAllocations A list of allocations that need to be added before the rest (used for - * boxing allocations). - */ - public void addMaterializationBefore(final FixedNode position, final List objects, final List> locks, final List values, - final List otherAllocations) { - add(new Effect() { - - @Override - public String name() { - return "addMaterializationBefore"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - for (ValueNode otherAllocation : otherAllocations) { - graph.addWithoutUnique(otherAllocation); - if (otherAllocation instanceof FixedWithNextNode) { - graph.addBeforeFixed(position, (FixedWithNextNode) otherAllocation); - } else { - assert otherAllocation instanceof FloatingNode; - } - } - if (!objects.isEmpty()) { - CommitAllocationNode commit; - if (position.predecessor() instanceof CommitAllocationNode) { - commit = (CommitAllocationNode) position.predecessor(); - } else { - commit = graph.add(new CommitAllocationNode()); - graph.addBeforeFixed(position, commit); - } - for (AllocatedObjectNode obj : objects) { - graph.addWithoutUnique(obj); - commit.getVirtualObjects().add(obj.getVirtualObject()); - obj.setCommit(commit); - } - commit.getValues().addAll(values); - for (List monitorIds : locks) { - commit.addLocks(monitorIds); - } - - assert commit.usages().filter(AllocatedObjectNode.class).count() == commit.usages().count(); - List materializedValues = commit.usages().filter(AllocatedObjectNode.class).snapshot(); - for (int i = 0; i < commit.getValues().size(); i++) { - if (materializedValues.contains(commit.getValues().get(i))) { - commit.getValues().set(i, ((AllocatedObjectNode) commit.getValues().get(i)).getVirtualObject()); - } - } - - } - } - - @Override - public boolean isVisible() { - return true; - } - }); + add("customAction", graph -> action.run()); } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Tue Jul 15 19:21:28 2014 -0700 @@ -120,13 +120,15 @@ protected void processLoopExit(LoopExitNode exitNode, PEReadEliminationBlockState initialState, PEReadEliminationBlockState exitState, GraphEffectList effects) { super.processLoopExit(exitNode, initialState, exitState, effects); - for (Map.Entry entry : exitState.getReadCache().entrySet()) { - if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) { - ValueNode value = exitState.getReadCache(entry.getKey().object, entry.getKey().identity, this); - if (!(value instanceof ProxyNode) || ((ProxyNode) value).proxyPoint() != exitNode) { - ProxyNode proxy = new ValueProxyNode(value, exitNode); - effects.addFloatingNode(proxy, "readCacheProxy"); - entry.setValue(proxy); + if (exitNode.graph().hasValueProxies()) { + for (Map.Entry entry : exitState.getReadCache().entrySet()) { + if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) { + ValueNode value = exitState.getReadCache(entry.getKey().object, entry.getKey().identity, this); + if (!(value instanceof ProxyNode) || ((ProxyNode) value).proxyPoint() != exitNode) { + ProxyNode proxy = new ValueProxyNode(value, exitNode); + effects.addFloatingNode(proxy, "readCacheProxy"); + entry.setValue(proxy); + } } } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java Tue Jul 15 19:21:28 2014 -0700 @@ -27,6 +27,7 @@ import java.util.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.Virtualizable.EscapeState; import com.oracle.graal.nodes.virtual.*; @@ -75,7 +76,42 @@ List otherAllocations = new ArrayList<>(2); materializeWithCommit(fixed, virtual, objects, locks, values, otherAllocations, state); - materializeEffects.addMaterializationBefore(fixed, objects, locks, values, otherAllocations); + materializeEffects.add("materializeBefore", (graph, obsoleteNodes) -> { + for (ValueNode otherAllocation : otherAllocations) { + graph.addWithoutUnique(otherAllocation); + if (otherAllocation instanceof FixedWithNextNode) { + graph.addBeforeFixed(fixed, (FixedWithNextNode) otherAllocation); + } else { + assert otherAllocation instanceof FloatingNode; + } + } + if (!objects.isEmpty()) { + CommitAllocationNode commit; + if (fixed.predecessor() instanceof CommitAllocationNode) { + commit = (CommitAllocationNode) fixed.predecessor(); + } else { + commit = graph.add(new CommitAllocationNode()); + graph.addBeforeFixed(fixed, commit); + } + for (AllocatedObjectNode obj : objects) { + graph.addWithoutUnique(obj); + commit.getVirtualObjects().add(obj.getVirtualObject()); + obj.setCommit(commit); + } + commit.getValues().addAll(values); + for (List monitorIds : locks) { + commit.addLocks(monitorIds); + } + + assert commit.usages().filter(AllocatedObjectNode.class).count() == commit.usages().count(); + List materializedValues = commit.usages().filter(AllocatedObjectNode.class).snapshot(); + for (int i = 0; i < commit.getValues().size(); i++) { + if (materializedValues.contains(commit.getValues().get(i))) { + commit.getValues().set(i, ((AllocatedObjectNode) commit.getValues().get(i)).getVirtualObject()); + } + } + } + }); } private void materializeWithCommit(FixedNode fixed, VirtualObjectNode virtual, List objects, List> locks, List values, diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Tue Jul 15 19:21:28 2014 -0700 @@ -229,33 +229,35 @@ proxies.put(obj.virtual, proxy); } } - for (ObjectState obj : exitState.getStates()) { - ObjectState initialObj = initialState.getObjectStateOptional(obj.virtual); - if (obj.isVirtual()) { - for (int i = 0; i < obj.getEntries().length; i++) { - 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 ValueProxyNode(value, exitNode); - obj.setEntry(i, proxy); - effects.addFloatingNode(proxy, "virtualProxy"); + if (exitNode.graph().hasValueProxies()) { + for (ObjectState obj : exitState.getStates()) { + ObjectState initialObj = initialState.getObjectStateOptional(obj.virtual); + if (obj.isVirtual()) { + for (int i = 0; i < obj.getEntries().length; i++) { + 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 ValueProxyNode(value, exitNode); + obj.setEntry(i, proxy); + effects.addFloatingNode(proxy, "virtualProxy"); + } } } - } - } else { - if (initialObj == null || initialObj.isVirtual()) { - ProxyNode proxy = proxies.get(obj.virtual); - if (proxy == null) { - proxy = new ValueProxyNode(obj.getMaterializedValue(), exitNode); - effects.addFloatingNode(proxy, "proxy"); + } else { + if (initialObj == null || initialObj.isVirtual()) { + ProxyNode proxy = proxies.get(obj.virtual); + if (proxy == null) { + proxy = new ValueProxyNode(obj.getMaterializedValue(), exitNode); + effects.addFloatingNode(proxy, "proxy"); + } else { + effects.replaceFirstInput(proxy, proxy.value(), obj.getMaterializedValue()); + // nothing to do - will be handled in processNode + } + obj.updateMaterializedValue(proxy); } else { - effects.replaceFirstInput(proxy, proxy.value(), obj.getMaterializedValue()); - // nothing to do - will be handled in processNode - } - obj.updateMaterializedValue(proxy); - } else { - if (initialObj.getMaterializedValue() == obj.getMaterializedValue()) { - Debug.log("materialized value changes within loop: %s vs. %s at %s", initialObj.getMaterializedValue(), obj.getMaterializedValue(), exitNode); + if (initialObj.getMaterializedValue() == obj.getMaterializedValue()) { + Debug.log("materialized value changes within loop: %s vs. %s at %s", initialObj.getMaterializedValue(), obj.getMaterializedValue(), exitNode); + } } } } @@ -457,6 +459,9 @@ phis[valueIndex] = new ValuePhiNode(values[valueIndex].stamp().unrestricted(), merge); } } + if (phis[valueIndex] != null && !phis[valueIndex].stamp().isCompatible(values[valueIndex].stamp())) { + phis[valueIndex] = new ValuePhiNode(values[valueIndex].stamp().unrestricted(), merge); + } if (twoSlotKinds != null && twoSlotKinds[valueIndex] != null) { // skip an entry after a long/double value that occupies two int slots valueIndex++; diff -r 072b9501f5f9 -r 446750355e5f 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 Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Tue Jul 15 19:21:28 2014 -0700 @@ -171,11 +171,13 @@ @Override 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 ValueProxyNode(exitState.getCacheEntry(entry.getKey()), exitNode); - effects.addFloatingNode(proxy, "readCacheProxy"); - entry.setValue(proxy); + if (exitNode.graph().hasValueProxies()) { + for (Map.Entry, ValueNode> entry : exitState.getReadCache().entrySet()) { + if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) { + ProxyNode proxy = new ValueProxyNode(exitState.getCacheEntry(entry.getKey()), exitNode); + effects.addFloatingNode(proxy, "readCacheProxy"); + entry.setValue(proxy); + } } } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java Tue Jul 15 19:21:28 2014 -0700 @@ -120,10 +120,10 @@ if (filter != null) { if (filter.startsWith("~")) { ResolvedJavaMethod method = graph.method(); - return method == null || !MetaUtil.format("%H.%n", method).contains(filter.substring(1)); + return method == null || !method.format("%H.%n").contains(filter.substring(1)); } else { ResolvedJavaMethod method = graph.method(); - return method != null && MetaUtil.format("%H.%n", method).contains(filter); + return method != null && method.format("%H.%n").contains(filter); } } return true; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -113,6 +113,11 @@ throw new GraalInternalError("locationIdentity must be a constant so that this node can be canonicalized: " + locationIdentity); } + @Override + public IntegerStamp getDisplacementStamp() { + throw GraalInternalError.shouldNotReachHere(); + } + @NodeIntrinsic public static native Location constantLocation(LocationIdentity identity, Kind kind, long displacement); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java Tue Jul 15 19:21:28 2014 -0700 @@ -114,7 +114,7 @@ ValueNode receiver = arguments.get(argc); if (receiver == node && isWord(node)) { ResolvedJavaMethod resolvedMethod = wordAccess.wordImplType.resolveMethod(method, invoke.getContextType()); - verify(resolvedMethod != null, node, invoke.asNode(), "cannot resolve method on Word class: " + MetaUtil.format("%H.%n(%P) %r", method)); + verify(resolvedMethod != null, node, invoke.asNode(), "cannot resolve method on Word class: " + method.format("%H.%n(%P) %r")); Operation operation = resolvedMethod.getAnnotation(Word.Operation.class); verify(operation != null, node, invoke.asNode(), "cannot dispatch on word value to non @Operation annotated method " + resolvedMethod); } @@ -165,7 +165,7 @@ return buf.toString(); } else { String loc = GraphUtil.approxSourceLocation(n); - return loc == null ? MetaUtil.format("method %h.%n", ((StructuredGraph) n.graph()).method()) : loc; + return loc == null ? ((StructuredGraph) n.graph()).method().format("method %h.%n") : loc; } } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,7 +24,6 @@ */ package com.oracle.truffle.api.nodes; -import java.io.*; import java.lang.annotation.*; import java.util.*; import java.util.concurrent.*; @@ -280,9 +279,6 @@ this.parent.adoptUnadoptedHelper(newNode); } reportReplace(this, newNode, reason); - if (TruffleOptions.TraceASTJSON) { - JSONHelper.dumpReplaceChild(this, newNode, reason); - } onReplace(newNode, reason); } @@ -310,6 +306,12 @@ ((ReplaceObserver) target).nodeReplaced(oldNode, newNode, reason); } } + if (TruffleOptions.TraceRewrites) { + NodeUtil.traceRewrite(this, newNode, reason); + } + if (TruffleOptions.TraceASTJSON) { + JSONHelper.dumpReplaceChild(this, newNode, reason); + } } /** @@ -320,36 +322,7 @@ * @param reason the reason the replace supplied */ protected void onReplace(Node newNode, CharSequence reason) { - if (TruffleOptions.TraceRewrites) { - traceRewrite(newNode, reason); - } - } - - private void traceRewrite(Node newNode, CharSequence reason) { - if (TruffleOptions.TraceRewritesFilterFromCost != null) { - if (filterByKind(this, TruffleOptions.TraceRewritesFilterFromCost)) { - return; - } - } - - if (TruffleOptions.TraceRewritesFilterToCost != null) { - if (filterByKind(newNode, TruffleOptions.TraceRewritesFilterToCost)) { - return; - } - } - - String filter = TruffleOptions.TraceRewritesFilterClass; - Class from = getClass(); - Class to = newNode.getClass(); - if (filter != null && (filterByContainsClassName(from, filter) || filterByContainsClassName(to, filter))) { - return; - } - - final SourceSection reportedSourceSection = getEncapsulatingSourceSection(); - - PrintStream out = System.out; - out.printf("[truffle] rewrite %-50s |From %-40s |To %-40s |Reason %s%s%n", this.toString(), formatNodeInfo(this), formatNodeInfo(newNode), reason != null && reason.length() > 0 ? reason - : "unknown", reportedSourceSection != null ? " at " + reportedSourceSection.getShortDescription() : ""); + // empty default } /** @@ -362,43 +335,6 @@ // empty default } - private static String formatNodeInfo(Node node) { - String cost = "?"; - switch (node.getCost()) { - case NONE: - cost = "G"; - break; - case MONOMORPHIC: - cost = "M"; - break; - case POLYMORPHIC: - cost = "P"; - break; - case MEGAMORPHIC: - cost = "G"; - break; - default: - cost = "?"; - break; - } - return cost + " " + node.getClass().getSimpleName(); - } - - private static boolean filterByKind(Node node, NodeCost cost) { - return node.getCost() == cost; - } - - private static boolean filterByContainsClassName(Class from, String filter) { - Class currentFrom = from; - while (currentFrom != null) { - if (currentFrom.getName().contains(filter)) { - return false; - } - currentFrom = currentFrom.getSuperclass(); - } - return true; - } - /** * Invokes the {@link NodeVisitor#visit(Node)} method for this node and recursively also for all * child nodes. @@ -421,11 +357,9 @@ * @return the iterator */ public final Iterable getChildren() { - final Node node = this; return new Iterable() { - public Iterator iterator() { - return new NodeUtil.NodeIterator(node); + return NodeUtil.makeIterator(Node.this); } }; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Tue Jul 15 19:21:28 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -157,8 +157,14 @@ * every subclass of {@link Node} that is used. */ public static final class NodeClass { - - private static final Map, NodeClass> nodeClasses = new IdentityHashMap<>(); + private static final ClassValue nodeClasses = new ClassValue() { + @SuppressWarnings("unchecked") + @Override + protected NodeClass computeValue(Class clazz) { + assert Node.class.isAssignableFrom(clazz); + return new NodeClass((Class) clazz, unsafeFieldOffsetProvider); + } + }; // The comprehensive list of all fields. private final NodeField[] fields; @@ -166,14 +172,10 @@ private final long parentOffset; private final long[] childOffsets; private final long[] childrenOffsets; + private final Class clazz; public static NodeClass get(Class clazz) { - NodeClass nodeClass = nodeClasses.get(clazz); - if (nodeClass == null) { - nodeClass = new NodeClass(clazz, unsafeFieldOffsetProvider); - nodeClasses.put(clazz, nodeClass); - } - return nodeClass; + return nodeClasses.get(clazz); } public NodeClass(Class clazz, FieldOffsetProvider fieldOffsetProvider) { @@ -209,6 +211,7 @@ this.parentOffset = parentOffsetsList.get(0); this.childOffsets = toLongArray(childOffsetsList); this.childrenOffsets = toLongArray(childrenOffsetsList); + this.clazz = clazz; } public NodeField[] getFields() { @@ -241,73 +244,71 @@ } return false; } - } - static class NodeIterator implements Iterator { - - private final Node node; - private final NodeClass nodeClass; - private final int childrenCount; - private int index; - - protected NodeIterator(Node node) { - this.node = node; - this.index = 0; - this.nodeClass = NodeClass.get(node.getClass()); - this.childrenCount = childrenCount(); - } - - private int childrenCount() { - int nodeCount = nodeClass.childOffsets.length; - for (long fieldOffset : nodeClass.childrenOffsets) { - Node[] children = ((Node[]) unsafe.getObject(node, fieldOffset)); - if (children != null) { - nodeCount += children.length; - } - } - return nodeCount; + public Iterator makeIterator(Node node) { + assert clazz.isInstance(node); + return new NodeIterator(node); } - private Node nodeAt(int idx) { - int nodeCount = nodeClass.childOffsets.length; - if (idx < nodeCount) { - return (Node) unsafe.getObject(node, nodeClass.childOffsets[idx]); - } else { - for (long fieldOffset : nodeClass.childrenOffsets) { - Node[] nodeArray = (Node[]) unsafe.getObject(node, fieldOffset); - if (idx < nodeCount + nodeArray.length) { - return nodeArray[idx - nodeCount]; + private final class NodeIterator implements Iterator { + private final Node node; + private int fieldIndex; + private int arrayIndex; + + protected NodeIterator(Node node) { + this.node = node; + } + + private void forward() { + if (fieldIndex < childOffsets.length) { + fieldIndex++; + } else if (fieldIndex < childOffsets.length + childrenOffsets.length) { + if (arrayIndex + 1 < currentChildrenArrayLength()) { + arrayIndex++; + } else { + arrayIndex = 0; + do { + fieldIndex++; + } while (fieldIndex < childOffsets.length + childrenOffsets.length && currentChildrenArrayLength() == 0); } - nodeCount += nodeArray.length; } } - return null; - } + + public boolean hasNext() { + return fieldIndex < childOffsets.length || (fieldIndex < childOffsets.length + childrenOffsets.length && arrayIndex < currentChildrenArrayLength()); + } + + private Node[] currentChildrenArray() { + assert fieldIndex >= childOffsets.length && fieldIndex < childOffsets.length + childrenOffsets.length; + return (Node[]) unsafe.getObject(node, childrenOffsets[fieldIndex - childOffsets.length]); + } + + private int currentChildrenArrayLength() { + Node[] childrenArray = currentChildrenArray(); + return childrenArray != null ? childrenArray.length : 0; + } - private void forward() { - if (index < childrenCount) { - index++; + public Node next() { + Node next; + if (fieldIndex < childOffsets.length) { + next = (Node) unsafe.getObject(node, childOffsets[fieldIndex]); + } else if (fieldIndex < childOffsets.length + childrenOffsets.length) { + next = currentChildrenArray()[arrayIndex]; + } else { + throw new NoSuchElementException(); + } + forward(); + return next; + } + + public void remove() { + throw new UnsupportedOperationException(); } } - - @Override - public boolean hasNext() { - return index < childrenCount; - } + } - @Override - public Node next() { - try { - return nodeAt(index); - } finally { - forward(); - } - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } + static Iterator makeIterator(Node node) { + return NodeClass.get(node.getClass()).makeIterator(node); } private static long[] toLongArray(List list) { @@ -542,15 +543,12 @@ return null; } - public static List findAllNodeInstances(final Node root, final Class clazz) { + public static List findAllNodeInstances(final Node root, final Class clazz) { final List nodeList = new ArrayList<>(); root.accept(new NodeVisitor() { - - @SuppressWarnings("unchecked") - @Override public boolean visit(Node node) { if (clazz.isInstance(node)) { - nodeList.add((T) node); + nodeList.add(clazz.cast(node)); } return true; } @@ -558,53 +556,15 @@ return nodeList; } - // Don't visit found node instances. - public static List findNodeInstancesShallow(final Node root, final Class clazz) { - final List nodeList = new ArrayList<>(); - root.accept(new NodeVisitor() { - - @SuppressWarnings("unchecked") - @Override - public boolean visit(Node node) { - if (clazz.isInstance(node)) { - nodeList.add((T) node); - return false; - } - return true; - } - }); - return nodeList; - } - - /** Find node instances within current function only (not in nested functions). */ - public static List findNodeInstancesInFunction(final Node root, final Class clazz) { + /** + * Like {@link #findAllNodeInstances(Node, Class)} but do not visit children of found nodes. + */ + public static List findNodeInstancesShallow(final Node root, final Class clazz) { final List nodeList = new ArrayList<>(); root.accept(new NodeVisitor() { - - @SuppressWarnings("unchecked") - @Override public boolean visit(Node node) { if (clazz.isInstance(node)) { - nodeList.add((T) node); - } else if (node instanceof RootNode && node != root) { - return false; - } - return true; - } - }); - return nodeList; - } - - public static List findNodeInstancesInFunctionInterface(final Node root, final Class clazz) { - final List nodeList = new ArrayList<>(); - root.accept(new NodeVisitor() { - - @SuppressWarnings("unchecked") - @Override - public boolean visit(Node node) { - if (clazz.isInstance(node)) { - nodeList.add((I) node); - } else if (node instanceof RootNode && node != root) { + nodeList.add(clazz.cast(node)); return false; } return true; @@ -864,6 +824,9 @@ private static String displaySourceAttribution(Node node) { final SourceSection section = node.getSourceSection(); + if (section instanceof NullSourceSection) { + return "source: " + section.getShortDescription(); + } if (section != null) { final String srcText = section.getCode(); final StringBuilder sb = new StringBuilder(); @@ -891,4 +854,68 @@ private static String toStringWithClass(Object obj) { return obj == null ? "null" : obj + "(" + obj.getClass().getName() + ")"; } + + static void traceRewrite(Node oldNode, Node newNode, CharSequence reason) { + if (TruffleOptions.TraceRewritesFilterFromCost != null) { + if (filterByKind(oldNode, TruffleOptions.TraceRewritesFilterFromCost)) { + return; + } + } + + if (TruffleOptions.TraceRewritesFilterToCost != null) { + if (filterByKind(newNode, TruffleOptions.TraceRewritesFilterToCost)) { + return; + } + } + + String filter = TruffleOptions.TraceRewritesFilterClass; + Class from = oldNode.getClass(); + Class to = newNode.getClass(); + if (filter != null && (filterByContainsClassName(from, filter) || filterByContainsClassName(to, filter))) { + return; + } + + final SourceSection reportedSourceSection = oldNode.getEncapsulatingSourceSection(); + + PrintStream out = System.out; + out.printf("[truffle] rewrite %-50s |From %-40s |To %-40s |Reason %s%s%n", oldNode.toString(), formatNodeInfo(oldNode), formatNodeInfo(newNode), + reason != null && reason.length() > 0 ? reason : "unknown", reportedSourceSection != null ? " at " + reportedSourceSection.getShortDescription() : ""); + } + + private static String formatNodeInfo(Node node) { + String cost = "?"; + switch (node.getCost()) { + case NONE: + cost = "G"; + break; + case MONOMORPHIC: + cost = "M"; + break; + case POLYMORPHIC: + cost = "P"; + break; + case MEGAMORPHIC: + cost = "G"; + break; + default: + cost = "?"; + break; + } + return cost + " " + node.getClass().getSimpleName(); + } + + private static boolean filterByKind(Node node, NodeCost cost) { + return node.getCost() == cost; + } + + private static boolean filterByContainsClassName(Class from, String filter) { + Class currentFrom = from; + while (currentFrom != null) { + if (currentFrom.getName().contains(filter)) { + return false; + } + currentFrom = currentFrom.getSuperclass(); + } + return true; + } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/JSONHelper.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/JSONHelper.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/JSONHelper.java Tue Jul 15 19:21:28 2014 -0700 @@ -122,15 +122,15 @@ AstJsonDumpBuilder = new StringBuilder(); } - public static JsonObjectBuilder object() { - return new JsonObjectBuilder(); + public static JSONObjectBuilder object() { + return new JSONObjectBuilder(); } - public static JsonArrayBuilder array() { - return new JsonArrayBuilder(); + public static JSONArrayBuilder array() { + return new JSONArrayBuilder(); } - public static abstract class JsonStringBuilder { + public static abstract class JSONStringBuilder { @Override public final String toString() { StringBuilder sb = new StringBuilder(); @@ -141,8 +141,8 @@ protected abstract void appendTo(StringBuilder sb); protected static void appendValue(StringBuilder sb, Object value) { - if (value instanceof JsonStringBuilder) { - ((JsonStringBuilder) value).appendTo(sb); + if (value instanceof JSONStringBuilder) { + ((JSONStringBuilder) value).appendTo(sb); } else if (value instanceof Integer || value instanceof Boolean || value == null) { sb.append(value); } else { @@ -151,28 +151,28 @@ } } - public static final class JsonObjectBuilder extends JsonStringBuilder { + public static final class JSONObjectBuilder extends JSONStringBuilder { private final Map contents = new LinkedHashMap<>(); - private JsonObjectBuilder() { + private JSONObjectBuilder() { } - public JsonObjectBuilder add(String key, String value) { + public JSONObjectBuilder add(String key, String value) { contents.put(key, value); return this; } - public JsonObjectBuilder add(String key, Number value) { + public JSONObjectBuilder add(String key, Number value) { contents.put(key, value); return this; } - public JsonObjectBuilder add(String key, Boolean value) { + public JSONObjectBuilder add(String key, Boolean value) { contents.put(key, value); return this; } - public JsonObjectBuilder add(String key, JsonStringBuilder value) { + public JSONObjectBuilder add(String key, JSONStringBuilder value) { contents.put(key, value); return this; } @@ -194,28 +194,28 @@ } } - public static final class JsonArrayBuilder extends JsonStringBuilder { + public static final class JSONArrayBuilder extends JSONStringBuilder { private final List contents = new ArrayList<>(); - private JsonArrayBuilder() { + private JSONArrayBuilder() { } - public JsonArrayBuilder add(String value) { + public JSONArrayBuilder add(String value) { contents.add(value); return this; } - public JsonArrayBuilder add(Number value) { + public JSONArrayBuilder add(Number value) { contents.add(value); return this; } - public JsonArrayBuilder add(Boolean value) { + public JSONArrayBuilder add(Boolean value) { contents.add(value); return this; } - public JsonArrayBuilder add(JsonStringBuilder value) { + public JSONArrayBuilder add(JSONStringBuilder value) { contents.add(value); return this; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl.test/tests/String.output --- a/graal/com.oracle.truffle.sl.test/tests/String.output Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl.test/tests/String.output Tue Jul 15 19:21:28 2014 -0700 @@ -7,4 +7,4 @@ bars foos 2 < 4: true -Type error at String.sl line 9 col 36: operation "<" not defined for Number 2, String "4" +Type error at String.sl line 9 col 34: operation "<" not defined for Number 2, String "4" diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl.test/tests/error/TypeError01.output --- a/graal/com.oracle.truffle.sl.test/tests/error/TypeError01.output Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError01.output Tue Jul 15 19:21:28 2014 -0700 @@ -1,1 +1,1 @@ -Type error at TypeError01.sl line 2 col 5: operation "-" not defined for Number 3, String "4" +Type error at TypeError01.sl line 2 col 3: operation "-" not defined for Number 3, String "4" diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl.test/tests/error/TypeError03.output --- a/graal/com.oracle.truffle.sl.test/tests/error/TypeError03.output Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError03.output Tue Jul 15 19:21:28 2014 -0700 @@ -1,1 +1,1 @@ -Type error at TypeError03.sl line 2 col 7: operation "&&" not defined for String "4", ANY +Type error at TypeError03.sl line 2 col 3: operation "&&" not defined for String "4", ANY diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl.test/tests/error/TypeError04.output --- a/graal/com.oracle.truffle.sl.test/tests/error/TypeError04.output Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError04.output Tue Jul 15 19:21:28 2014 -0700 @@ -1,1 +1,1 @@ -Type error at TypeError04.sl line 2 col 11: operation "||" not defined for Boolean false, Number 4 +Type error at TypeError04.sl line 2 col 4: operation "||" not defined for Boolean false, Number 4 diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLMain.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLMain.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLMain.java Tue Jul 15 19:21:28 2014 -0700 @@ -143,6 +143,7 @@ public static void run(SLContext context, Source source, PrintStream logOutput, int repeats) { if (logOutput != null) { logOutput.println("== running on " + Truffle.getRuntime().getName()); + // logOutput.println("Source = " + source.getCode()); } final SourceCallback sourceCallback = context.getSourceCallback(); @@ -163,10 +164,12 @@ /* Change to true if you want to see the AST on the console. */ boolean printASTToLog = false; + /* Change to true if you want to see source attribution for the AST to the console */ + boolean printSourceAttributionToLog = false; /* Change to dump the AST to IGV over the network. */ boolean dumpASTToIGV = false; - printScript("before execution", context, logOutput, printASTToLog, dumpASTToIGV); + printScript("before execution", context, logOutput, printASTToLog, printSourceAttributionToLog, dumpASTToIGV); try { for (int i = 0; i < repeats; i++) { long start = System.nanoTime(); @@ -187,7 +190,7 @@ } } finally { - printScript("after execution", context, logOutput, printASTToLog, dumpASTToIGV); + printScript("after execution", context, logOutput, printASTToLog, printSourceAttributionToLog, dumpASTToIGV); } } @@ -197,7 +200,7 @@ *

* When printASTToLog is true: prints the ASTs to the console. */ - private static void printScript(String groupName, SLContext context, PrintStream logOutput, boolean printASTToLog, boolean dumpASTToIGV) { + private static void printScript(String groupName, SLContext context, PrintStream logOutput, boolean printASTToLog, boolean printSourceAttributionToLog, boolean dumpASTToIGV) { if (dumpASTToIGV) { GraphPrintVisitor graphPrinter = new GraphPrintVisitor(); graphPrinter.beginGroup(groupName); @@ -218,6 +221,15 @@ } } } + if (printSourceAttributionToLog && logOutput != null) { + for (SLFunction function : context.getFunctionRegistry().getFunctions()) { + RootCallTarget callTarget = function.getCallTarget(); + if (callTarget != null) { + logOutput.println("=== " + function); + NodeUtil.printSourceAttributionTree(logOutput, callTarget.getRootNode()); + } + } + } } /** @@ -233,7 +245,9 @@ result.append("Type error"); if (ex.getNode() != null && ex.getNode().getSourceSection() != null) { SourceSection ss = ex.getNode().getSourceSection(); - result.append(" at ").append(ss.getSource().getName()).append(" line ").append(ss.getStartLine()).append(" col ").append(ss.getStartColumn()); + if (ss != null && !(ss instanceof NullSourceSection)) { + result.append(" at ").append(ss.getSource().getName()).append(" line ").append(ss.getStartLine()).append(" col ").append(ss.getStartColumn()); + } } result.append(": operation"); if (ex.getNode() != null && ex.getNode().getClass().getAnnotation(NodeInfo.class) != null) { diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLBuiltinNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLBuiltinNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLBuiltinNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -23,6 +23,7 @@ package com.oracle.truffle.sl.builtins; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; import com.oracle.truffle.sl.runtime.*; @@ -42,6 +43,10 @@ @NodeField(name = "context", type = SLContext.class) public abstract class SLBuiltinNode extends SLExpressionNode { + public SLBuiltinNode(SourceSection src) { + super(src); + } + /** * Accessor for the {@link SLContext}. The implementation of this method is generated * automatically based on the {@link NodeField} annotation on the class. diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLDefineFunctionBuiltin.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLDefineFunctionBuiltin.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLDefineFunctionBuiltin.java Tue Jul 15 19:21:28 2014 -0700 @@ -36,6 +36,10 @@ @NodeInfo(shortName = "defineFunction") public abstract class SLDefineFunctionBuiltin extends SLBuiltinNode { + public SLDefineFunctionBuiltin() { + super(new NullSourceSection("SL builtin", "defineFunction")); + } + @Specialization public String defineFunction(String code) { doDefineFunction(getContext(), code); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHelloEqualsWorldBuiltin.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHelloEqualsWorldBuiltin.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLHelloEqualsWorldBuiltin.java Tue Jul 15 19:21:28 2014 -0700 @@ -27,6 +27,7 @@ import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; /** * This builtin sets the variable named "hello" in the caller frame to the string "world". @@ -34,6 +35,10 @@ @NodeInfo(shortName = "helloEqualsWorld") public abstract class SLHelloEqualsWorldBuiltin extends SLBuiltinNode { + public SLHelloEqualsWorldBuiltin() { + super(new NullSourceSection("SL builtin", "helloEqualsWorld")); + } + @Specialization public String change() { FrameInstance frameInstance = Truffle.getRuntime().getStackTrace().iterator().next(); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLNanoTimeBuiltin.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLNanoTimeBuiltin.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLNanoTimeBuiltin.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,6 +24,7 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; /** * Builtin function that returns the value of a high-resolution time, in nanoseconds. @@ -31,6 +32,10 @@ @NodeInfo(shortName = "nanoTime") public abstract class SLNanoTimeBuiltin extends SLBuiltinNode { + public SLNanoTimeBuiltin() { + super(new NullSourceSection("SL builtin", "nanoTime")); + } + @Specialization public long nanoTime() { return System.nanoTime(); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLPrintlnBuiltin.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLPrintlnBuiltin.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLPrintlnBuiltin.java Tue Jul 15 19:21:28 2014 -0700 @@ -27,6 +27,7 @@ import com.oracle.truffle.api.CompilerDirectives.SlowPath; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.runtime.*; /** @@ -41,6 +42,10 @@ @NodeInfo(shortName = "println") public abstract class SLPrintlnBuiltin extends SLBuiltinNode { + public SLPrintlnBuiltin() { + super(new NullSourceSection("SL builtin", "println")); + } + @Specialization public long println(long value) { doPrint(getContext().getOutput(), value); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLReadlnBuiltin.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLReadlnBuiltin.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLReadlnBuiltin.java Tue Jul 15 19:21:28 2014 -0700 @@ -27,6 +27,7 @@ import com.oracle.truffle.api.CompilerDirectives.SlowPath; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.*; import com.oracle.truffle.sl.runtime.*; @@ -36,6 +37,10 @@ @NodeInfo(shortName = "readln") public abstract class SLReadlnBuiltin extends SLBuiltinNode { + public SLReadlnBuiltin() { + super(new NullSourceSection("SL builtin", "readln")); + } + @Specialization public String readln() { String result = doRead(getContext().getInput()); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLStackTraceBuiltin.java Tue Jul 15 19:21:28 2014 -0700 @@ -28,6 +28,7 @@ import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; /** * Returns a string representation of the current stack. This includes the {@link CallTarget}s and @@ -37,6 +38,10 @@ @NodeInfo(shortName = "stacktrace") public abstract class SLStackTraceBuiltin extends SLBuiltinNode { + public SLStackTraceBuiltin() { + super(new NullSourceSection("SL builtin", "stacktrace")); + } + @Specialization public String trace() { return createStackTrace(); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLBinaryNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLBinaryNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLBinaryNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -23,6 +23,7 @@ package com.oracle.truffle.sl.nodes; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.source.*; /** * Utility base class for operations that take two arguments (per convention called "left" and @@ -31,4 +32,8 @@ */ @NodeChildren({@NodeChild("leftNode"), @NodeChild("rightNode")}) public abstract class SLBinaryNode extends SLExpressionNode { + + public SLBinaryNode(SourceSection src) { + super(src); + } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLExpressionNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLExpressionNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLExpressionNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -27,6 +27,7 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.runtime.*; /** @@ -38,6 +39,10 @@ @NodeInfo(description = "The abstract base node for all expressions") public abstract class SLExpressionNode extends SLStatementNode { + public SLExpressionNode(SourceSection src) { + super(src); + } + /** * The execute method when no specialization is possible. This is the most general case, * therefore it must be provided by all subclasses. diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLStatementNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,6 +24,7 @@ import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; /** * The base class of all Truffle nodes for SL. All nodes (even expressions) can be used as @@ -33,6 +34,10 @@ @NodeInfo(language = "Simple Language", description = "The abstract base node for all statements") public abstract class SLStatementNode extends Node { + public SLStatementNode(SourceSection src) { + super(src); + } + /** * Execute this node as as statement, where no return value is necessary. */ diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLInvokeNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLInvokeNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLInvokeNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -26,6 +26,7 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; import com.oracle.truffle.sl.runtime.*; @@ -39,15 +40,16 @@ @NodeInfo(shortName = "invoke") public final class SLInvokeNode extends SLExpressionNode { - public static SLInvokeNode create(SLExpressionNode function, SLExpressionNode[] arguments) { - return new SLInvokeNode(function, arguments, new SLUninitializedDispatchNode()); + public static SLInvokeNode create(SourceSection src, SLExpressionNode function, SLExpressionNode[] arguments) { + return new SLInvokeNode(src, function, arguments, new SLUninitializedDispatchNode()); } @Child protected SLExpressionNode functionNode; @Children protected final SLExpressionNode[] argumentNodes; @Child protected SLAbstractDispatchNode dispatchNode; - private SLInvokeNode(SLExpressionNode functionNode, SLExpressionNode[] argumentNodes, SLAbstractDispatchNode dispatchNode) { + private SLInvokeNode(SourceSection src, SLExpressionNode functionNode, SLExpressionNode[] argumentNodes, SLAbstractDispatchNode dispatchNode) { + super(src); this.functionNode = functionNode; this.argumentNodes = argumentNodes; this.dispatchNode = dispatchNode; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBlockNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBlockNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBlockNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -25,6 +25,7 @@ import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; /** @@ -40,7 +41,8 @@ */ @Children private final SLStatementNode[] bodyNodes; - public SLBlockNode(SLStatementNode[] bodyNodes) { + public SLBlockNode(SourceSection src, SLStatementNode[] bodyNodes) { + super(src); this.bodyNodes = bodyNodes; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBreakNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBreakNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBreakNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,6 +24,7 @@ import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; /** @@ -35,6 +36,10 @@ @NodeInfo(shortName = "break", description = "The node implementing a break statement") public final class SLBreakNode extends SLStatementNode { + public SLBreakNode(SourceSection src) { + super(src); + } + @Override public void executeVoid(VirtualFrame frame) { throw SLBreakException.SINGLETON; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLContinueNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLContinueNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLContinueNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,6 +24,7 @@ import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; /** @@ -35,6 +36,10 @@ @NodeInfo(shortName = "continue", description = "The node implementing a continue statement") public final class SLContinueNode extends SLStatementNode { + public SLContinueNode(SourceSection src) { + super(src); + } + @Override public void executeVoid(VirtualFrame frame) { throw SLContinueException.SINGLETON; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLFunctionBodyNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLFunctionBodyNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLFunctionBodyNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -29,7 +29,7 @@ import com.oracle.truffle.sl.runtime.*; /** - * The body of a user-defined SL function. This is the node references by a {@link SLRootNode} for + * The body of a user-defined SL function. This is the node referenced by a {@link SLRootNode} for * user-defined functions. It handles the return value of a function: the {@link SLReturnNode return * statement} throws an {@link SLReturnException exception} with the return value. This node catches * the exception. If the method ends without an explicit {@code return}, return the @@ -50,6 +50,7 @@ private final BranchProfile nullTaken = new BranchProfile(); public SLFunctionBodyNode(SLStatementNode bodyNode) { + super(null); this.bodyNode = bodyNode; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -25,6 +25,7 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.api.utilities.*; import com.oracle.truffle.sl.nodes.*; @@ -52,7 +53,8 @@ private final BranchProfile thenTaken = new BranchProfile(); private final BranchProfile elseTaken = new BranchProfile(); - public SLIfNode(SLExpressionNode conditionNode, SLStatementNode thenPartNode, SLStatementNode elsePartNode) { + public SLIfNode(SourceSection src, SLExpressionNode conditionNode, SLStatementNode thenPartNode, SLStatementNode elsePartNode) { + super(src); this.conditionNode = conditionNode; this.thenPartNode = thenPartNode; this.elsePartNode = elsePartNode; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLReturnNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLReturnNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLReturnNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,6 +24,7 @@ import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; import com.oracle.truffle.sl.runtime.*; @@ -39,7 +40,8 @@ @Child private SLExpressionNode valueNode; - public SLReturnNode(SLExpressionNode valueNode) { + public SLReturnNode(SourceSection src, SLExpressionNode valueNode) { + super(src); this.valueNode = valueNode; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -26,6 +26,7 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.api.utilities.*; import com.oracle.truffle.sl.nodes.*; @@ -50,7 +51,8 @@ private final BranchProfile continueTaken = new BranchProfile(); private final BranchProfile breakTaken = new BranchProfile(); - public SLWhileNode(SLExpressionNode conditionNode, SLStatementNode bodyNode) { + public SLWhileNode(SourceSection src, SLExpressionNode conditionNode, SLStatementNode bodyNode) { + super(src); this.conditionNode = conditionNode; this.bodyNode = bodyNode; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLAddNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLAddNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLAddNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -27,6 +27,7 @@ import com.oracle.truffle.api.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; /** @@ -42,6 +43,10 @@ @NodeInfo(shortName = "+") public abstract class SLAddNode extends SLBinaryNode { + public SLAddNode(SourceSection src) { + super(src); + } + /** * Specialization for primitive {@code long} values. This is the fast path of the * arbitrary-precision arithmetic. We need to check for overflows of the addition, and switch to diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLBigIntegerLiteralNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLBigIntegerLiteralNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLBigIntegerLiteralNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -26,6 +26,7 @@ import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; /** @@ -37,7 +38,8 @@ private final BigInteger value; - public SLBigIntegerLiteralNode(BigInteger value) { + public SLBigIntegerLiteralNode(SourceSection src, BigInteger value) { + super(src); this.value = value; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -26,6 +26,7 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; /** @@ -36,6 +37,10 @@ @NodeInfo(shortName = "/") public abstract class SLDivNode extends SLBinaryNode { + public SLDivNode(SourceSection src) { + super(src); + } + @Specialization protected long div(long left, long right) { /* No overflow is possible on a division. */ diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLEqualNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLEqualNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLEqualNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -26,6 +26,7 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; import com.oracle.truffle.sl.runtime.*; @@ -42,6 +43,10 @@ @NodeInfo(shortName = "==") public abstract class SLEqualNode extends SLBinaryNode { + public SLEqualNode(SourceSection src) { + super(src); + } + @Specialization protected boolean equal(long left, long right) { return left == right; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLFunctionLiteralNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLFunctionLiteralNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLFunctionLiteralNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -25,6 +25,7 @@ import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; import com.oracle.truffle.sl.runtime.*; @@ -39,7 +40,8 @@ private final SLFunction value; - public SLFunctionLiteralNode(SLFunction value) { + public SLFunctionLiteralNode(SourceSection src, SLFunction value) { + super(src); this.value = value; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessOrEqualNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessOrEqualNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessOrEqualNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -26,6 +26,7 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; /** @@ -34,6 +35,10 @@ @NodeInfo(shortName = "<=") public abstract class SLLessOrEqualNode extends SLBinaryNode { + public SLLessOrEqualNode(SourceSection src) { + super(src); + } + @Specialization protected boolean lessOrEqual(long left, long right) { return left <= right; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessThanNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessThanNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLessThanNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -26,6 +26,7 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; /** @@ -35,6 +36,10 @@ @NodeInfo(shortName = "<") public abstract class SLLessThanNode extends SLBinaryNode { + public SLLessThanNode(SourceSection src) { + super(src); + } + @Specialization protected boolean lessThan(long left, long right) { return left < right; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalAndNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalAndNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalAndNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,6 +24,7 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; /** @@ -39,6 +40,10 @@ @SuppressWarnings("unused") public abstract class SLLogicalAndNode extends SLBinaryNode { + public SLLogicalAndNode(SourceSection src) { + super(src); + } + /** * This method is called after the left child was evaluated, but before the right child is * evaluated. The right child is only evaluated when the return value is {code true}. diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalNotNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalNotNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalNotNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,6 +24,7 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; /** @@ -34,6 +35,10 @@ @NodeInfo(shortName = "!") public abstract class SLLogicalNotNode extends SLExpressionNode { + public SLLogicalNotNode(SourceSection src) { + super(src); + } + @Specialization protected boolean doBoolean(boolean value) { return !value; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalOrNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalOrNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLogicalOrNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,6 +24,7 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; /** @@ -33,6 +34,10 @@ @SuppressWarnings("unused") public abstract class SLLogicalOrNode extends SLBinaryNode { + public SLLogicalOrNode(SourceSection src) { + super(src); + } + @ShortCircuit("rightNode") protected boolean needsRightNode(boolean left) { return !left; diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLongLiteralNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLongLiteralNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLLongLiteralNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,6 +24,7 @@ import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; /** @@ -36,7 +37,8 @@ private final long value; - public SLLongLiteralNode(long value) { + public SLLongLiteralNode(SourceSection src, long value) { + super(src); this.value = value; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLMulNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLMulNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLMulNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -28,6 +28,7 @@ import com.oracle.truffle.api.CompilerDirectives.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; /** @@ -36,6 +37,10 @@ @NodeInfo(shortName = "*") public abstract class SLMulNode extends SLBinaryNode { + public SLMulNode(SourceSection src) { + super(src); + } + @Specialization(rewriteOn = ArithmeticException.class) protected long mul(long left, long right) { return ExactMath.multiplyExact(left, right); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLStringLiteralNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLStringLiteralNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLStringLiteralNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,6 +24,7 @@ import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; /** @@ -34,7 +35,8 @@ private final String value; - public SLStringLiteralNode(String value) { + public SLStringLiteralNode(SourceSection src, String value) { + super(src); this.value = value; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLSubNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLSubNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLSubNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -27,6 +27,7 @@ import com.oracle.truffle.api.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; /** @@ -35,6 +36,10 @@ @NodeInfo(shortName = "-") public abstract class SLSubNode extends SLBinaryNode { + public SLSubNode(SourceSection src) { + super(src); + } + @Specialization(rewriteOn = ArithmeticException.class) protected long sub(long left, long right) { return ExactMath.subtractExact(left, right); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/demo/SLAddWithoutSpecializationNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/demo/SLAddWithoutSpecializationNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/demo/SLAddWithoutSpecializationNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -42,6 +42,7 @@ @Child private SLExpressionNode rightNode; public SLAddWithoutSpecializationNode(SLExpressionNode leftNode, SLExpressionNode rightNode) { + super(null); this.leftNode = leftNode; this.rightNode = rightNode; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadArgumentNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadArgumentNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadArgumentNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -23,6 +23,7 @@ package com.oracle.truffle.sl.nodes.local; import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.api.utilities.*; import com.oracle.truffle.sl.nodes.*; import com.oracle.truffle.sl.parser.*; @@ -46,7 +47,8 @@ */ private final BranchProfile outOfBoundsTaken = new BranchProfile(); - public SLReadArgumentNode(int index) { + public SLReadArgumentNode(SourceSection src, int index) { + super(src); this.index = index; } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -24,6 +24,7 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; /** @@ -36,6 +37,10 @@ @NodeField(name = "slot", type = FrameSlot.class) public abstract class SLReadLocalVariableNode extends SLExpressionNode { + public SLReadLocalVariableNode(SourceSection src) { + super(src); + } + /** * Returns the descriptor of the accessed local variable. The implementation of this method is * created by the Truffle DSL based on the {@link NodeField} annotation on the class. diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLWriteLocalVariableNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLWriteLocalVariableNode.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLWriteLocalVariableNode.java Tue Jul 15 19:21:28 2014 -0700 @@ -25,6 +25,7 @@ import com.oracle.truffle.api.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.source.*; import com.oracle.truffle.sl.nodes.*; /** @@ -35,6 +36,10 @@ @NodeField(name = "slot", type = FrameSlot.class) public abstract class SLWriteLocalVariableNode extends SLExpressionNode { + public SLWriteLocalVariableNode(SourceSection src) { + super(src); + } + /** * Returns the descriptor of the accessed local variable. The implementation of this method is * created by the Truffle DSL based on the {@link NodeField} annotation on the class. diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Parser.java Tue Jul 15 19:21:28 2014 -0700 @@ -52,7 +52,7 @@ public final Scanner scanner; public final Errors errors; private final SLNodeFactory factory; - + public Parser(SLContext context, Source source) { this.scanner = new Scanner(source.getInputStream()); this.factory = new SLNodeFactory(context, source); @@ -133,39 +133,41 @@ void Function() { Expect(4); Expect(1); - factory.startFunction(t); + factory.startFunction(t); Expect(5); if (la.kind == 1) { Get(); - factory.addFormalParameter(t); + factory.addFormalParameter(t); while (la.kind == 6) { Get(); Expect(1); - factory.addFormalParameter(t); + factory.addFormalParameter(t); } } Expect(7); SLStatementNode body = Block(false); - factory.finishFunction(body); + factory.finishFunction(body); } SLStatementNode Block(boolean inLoop) { SLStatementNode result; factory.startBlock(); - List body = new ArrayList<>(); + List body = new ArrayList<>(); Expect(8); + int lBracePos = t.charPos; while (StartOf(1)) { SLStatementNode s = Statement(inLoop); - body.add(s); + body.add(s); } Expect(9); - result = factory.finishBlock(body); + int length = (t.charPos + t.val.length()) - lBracePos; + result = factory.finishBlock(body, lBracePos, length); return result; } SLStatementNode Statement(boolean inLoop) { SLStatementNode result; - result = null; + result = null; switch (la.kind) { case 13: { result = WhileStatement(); @@ -173,13 +175,13 @@ } case 10: { Get(); - if (inLoop) { result = factory.createBreak(t); } else { SemErr("break used outside of loop"); } + if (inLoop) { result = factory.createBreak(t); } else { SemErr("break used outside of loop"); } Expect(11); break; } case 12: { Get(); - if (inLoop) { result = factory.createContinue(t); } else { SemErr("continue used outside of loop"); } + if (inLoop) { result = factory.createContinue(t); } else { SemErr("continue used outside of loop"); } Expect(11); break; } @@ -205,11 +207,11 @@ SLStatementNode result; Expect(13); Expect(5); - Token whileToken = t; + Token whileToken = t; SLExpressionNode condition = Expression(); Expect(7); SLStatementNode body = Block(true); - result = factory.createWhile(whileToken, condition, body); + result = factory.createWhile(whileToken, condition, body); return result; } @@ -217,16 +219,16 @@ SLStatementNode result; Expect(14); Expect(5); - Token ifToken = t; + Token ifToken = t; SLExpressionNode condition = Expression(); Expect(7); SLStatementNode thenPart = Block(inLoop); - SLStatementNode elsePart = null; + SLStatementNode elsePart = null; if (la.kind == 15) { Get(); elsePart = Block(inLoop); } - result = factory.createIf(ifToken, condition, thenPart, elsePart); + result = factory.createIf(ifToken, condition, thenPart, elsePart); return result; } @@ -234,11 +236,11 @@ SLStatementNode result; Expect(16); Token returnToken = t; - SLExpressionNode value = null; + SLExpressionNode value = null; if (StartOf(2)) { value = Expression(); } - result = factory.createReturn(returnToken, value); + result = factory.createReturn(returnToken, value); Expect(11); return result; } @@ -248,9 +250,9 @@ result = LogicTerm(); while (la.kind == 17) { Get(); - Token op = t; + Token op = t; SLExpressionNode right = LogicTerm(); - result = factory.createBinary(op, result, right); + result = factory.createBinary(op, result, right); } return result; } @@ -260,9 +262,9 @@ result = LogicFactor(); while (la.kind == 18) { Get(); - Token op = t; + Token op = t; SLExpressionNode right = LogicFactor(); - result = factory.createBinary(op, result, right); + result = factory.createBinary(op, result, right); } return result; } @@ -297,9 +299,9 @@ break; } } - Token op = t; + Token op = t; SLExpressionNode right = Arithmetic(); - result = factory.createBinary(op, result, right); + result = factory.createBinary(op, result, right); } return result; } @@ -313,9 +315,9 @@ } else { Get(); } - Token op = t; + Token op = t; SLExpressionNode right = Term(); - result = factory.createBinary(op, result, right); + result = factory.createBinary(op, result, right); } return result; } @@ -329,47 +331,48 @@ } else { Get(); } - Token op = t; + Token op = t; SLExpressionNode right = Factor(); - result = factory.createBinary(op, result, right); + result = factory.createBinary(op, result, right); } return result; } SLExpressionNode Factor() { SLExpressionNode result; - result = null; + result = null; if (la.kind == 1) { Get(); - Token nameToken = t; + Token nameToken = t; if (la.kind == 5) { Get(); List parameters = new ArrayList<>(); - SLExpressionNode parameter; + SLExpressionNode parameter; if (StartOf(2)) { parameter = Expression(); - parameters.add(parameter); + parameters.add(parameter); while (la.kind == 6) { Get(); parameter = Expression(); - parameters.add(parameter); + parameters.add(parameter); } } - result = factory.createCall(nameToken, parameters); Expect(7); + Token finalToken = t; + result = factory.createCall(nameToken, parameters, finalToken); } else if (la.kind == 29) { Get(); SLExpressionNode value = Expression(); - result = factory.createAssignment(nameToken, value); + result = factory.createAssignment(nameToken, value); } else if (StartOf(4)) { - result = factory.createRead(nameToken); + result = factory.createRead(nameToken); } else SynErr(32); } else if (la.kind == 2) { Get(); - result = factory.createStringLiteral(t); + result = factory.createStringLiteral(t); } else if (la.kind == 3) { Get(); - result = factory.createNumericLiteral(t); + result = factory.createNumericLiteral(t); } else if (la.kind == 5) { Get(); result = Expression(); diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java Tue Jul 15 19:21:28 2014 -0700 @@ -95,14 +95,16 @@ * ensures that accesses to parameters are specialized the same way as local variables are * specialized. */ - SLReadArgumentNode readArg = assignSource(nameToken, new SLReadArgumentNode(parameterCount)); + final SourceSection src = source.createSection(nameToken.val, nameToken.charPos, nameToken.val.length()); + SLReadArgumentNode readArg = new SLReadArgumentNode(src, parameterCount); methodNodes.add(createAssignment(nameToken, readArg)); parameterCount++; } public void finishFunction(SLStatementNode bodyNode) { methodNodes.add(bodyNode); - SLStatementNode methodBlock = finishBlock(methodNodes); + // TODO (mlvdv) testing + SLStatementNode methodBlock = finishBlock(methodNodes, -1, -1); assert lexicalScope == null : "Wrong scoping of blocks in parser"; SLFunctionBodyNode functionBodyNode = new SLFunctionBodyNode(methodBlock); @@ -120,17 +122,34 @@ lexicalScope = new LexicalScope(lexicalScope); } - public SLStatementNode finishBlock(List bodyNodes) { + public SLStatementNode finishBlock(List bodyNodes, int lBracePos, int length) { lexicalScope = lexicalScope.outer; List flattenedNodes = new ArrayList<>(bodyNodes.size()); flattenBlocks(bodyNodes, flattenedNodes); + + if (lBracePos >= 0) { + final SourceSection src = source.createSection("block", lBracePos, length); + return new SLBlockNode(src, flattenedNodes.toArray(new SLStatementNode[flattenedNodes.size()])); + } + if (flattenedNodes.size() == 0) { + // TODO (mlvdv) for error reporting, should have the character position, even if the + // block is empty. + return new SLBlockNode(null, new SLStatementNode[0]); + } if (flattenedNodes.size() == 1) { - /* A block containing one other node is unnecessary, we can just that other node. */ + /* + * A block containing one other node, not surrounded by braces is unnecessary, we can + * just that other node. + */ return flattenedNodes.get(0); - } else { - return new SLBlockNode(flattenedNodes.toArray(new SLStatementNode[flattenedNodes.size()])); } + /* + * A "block" not surrounded by braces. + */ + final int start = flattenedNodes.get(0).getSourceSection().getCharIndex(); + final int end = flattenedNodes.get(flattenedNodes.size() - 1).getSourceSection().getCharEndIndex(); + return new SLBlockNode(source.createSection("block", start, end - start), flattenedNodes.toArray(new SLStatementNode[flattenedNodes.size()])); } private void flattenBlocks(Iterable bodyNodes, List flattenedNodes) { @@ -144,75 +163,90 @@ } public SLStatementNode createBreak(Token t) { - return assignSource(t, new SLBreakNode()); + return new SLBreakNode(source.createSection(t.val, t.charPos, t.val.length())); } public SLStatementNode createContinue(Token t) { - return assignSource(t, new SLContinueNode()); + return new SLContinueNode(source.createSection(t.val, t.charPos, t.val.length())); } public SLStatementNode createWhile(Token t, SLExpressionNode conditionNode, SLStatementNode bodyNode) { - return assignSource(t, new SLWhileNode(conditionNode, bodyNode)); + final int start = t.charPos; + final int end = bodyNode.getSourceSection().getCharEndIndex(); + return new SLWhileNode(source.createSection(t.val, start, end - start), conditionNode, bodyNode); } public SLStatementNode createIf(Token t, SLExpressionNode conditionNode, SLStatementNode thenPartNode, SLStatementNode elsePartNode) { - return assignSource(t, new SLIfNode(conditionNode, thenPartNode, elsePartNode)); + final int start = t.charPos; + final int end = elsePartNode == null ? thenPartNode.getSourceSection().getCharEndIndex() : elsePartNode.getSourceSection().getCharEndIndex(); + return new SLIfNode(source.createSection(t.val, start, end - start), conditionNode, thenPartNode, elsePartNode); } public SLStatementNode createReturn(Token t, SLExpressionNode valueNode) { - return assignSource(t, new SLReturnNode(valueNode)); + final int start = t.charPos; + final int length = valueNode == null ? t.val.length() : valueNode.getSourceSection().getCharEndIndex() - start; + return new SLReturnNode(source.createSection(t.val, start, length), valueNode); } public SLExpressionNode createBinary(Token opToken, SLExpressionNode leftNode, SLExpressionNode rightNode) { + int start = leftNode.getSourceSection().getCharIndex(); + int length = rightNode.getSourceSection().getCharEndIndex() - start; + final SourceSection src = source.createSection(opToken.val, start, length); switch (opToken.val) { case "+": - return assignSource(opToken, SLAddNodeFactory.create(leftNode, rightNode)); + return SLAddNodeFactory.create(src, leftNode, rightNode); case "*": - return assignSource(opToken, SLMulNodeFactory.create(leftNode, rightNode)); + return SLMulNodeFactory.create(src, leftNode, rightNode); case "/": - return assignSource(opToken, SLDivNodeFactory.create(leftNode, rightNode)); + return SLDivNodeFactory.create(src, leftNode, rightNode); case "-": - return assignSource(opToken, SLSubNodeFactory.create(leftNode, rightNode)); + return SLSubNodeFactory.create(src, leftNode, rightNode); case "<": - return assignSource(opToken, SLLessThanNodeFactory.create(leftNode, rightNode)); + return SLLessThanNodeFactory.create(src, leftNode, rightNode); case "<=": - return assignSource(opToken, SLLessOrEqualNodeFactory.create(leftNode, rightNode)); + return SLLessOrEqualNodeFactory.create(src, leftNode, rightNode); case ">": - return assignSource(opToken, SLLogicalNotNodeFactory.create(assignSource(opToken, SLLessOrEqualNodeFactory.create(leftNode, rightNode)))); + return SLLogicalNotNodeFactory.create(src, SLLessOrEqualNodeFactory.create(null, leftNode, rightNode)); case ">=": - return assignSource(opToken, SLLogicalNotNodeFactory.create(assignSource(opToken, SLLessThanNodeFactory.create(leftNode, rightNode)))); + return SLLogicalNotNodeFactory.create(src, SLLessThanNodeFactory.create(null, leftNode, rightNode)); case "==": - return assignSource(opToken, SLEqualNodeFactory.create(leftNode, rightNode)); + return SLEqualNodeFactory.create(src, leftNode, rightNode); case "!=": - return assignSource(opToken, SLLogicalNotNodeFactory.create(assignSource(opToken, SLEqualNodeFactory.create(leftNode, rightNode)))); + return SLLogicalNotNodeFactory.create(src, SLEqualNodeFactory.create(null, leftNode, rightNode)); case "&&": - return assignSource(opToken, SLLogicalAndNodeFactory.create(leftNode, rightNode)); + return SLLogicalAndNodeFactory.create(src, leftNode, rightNode); case "||": - return assignSource(opToken, SLLogicalOrNodeFactory.create(leftNode, rightNode)); + return SLLogicalOrNodeFactory.create(src, leftNode, rightNode); default: throw new RuntimeException("unexpected operation: " + opToken.val); } } - public SLExpressionNode createCall(Token nameToken, List parameterNodes) { + public SLExpressionNode createCall(Token nameToken, List parameterNodes, Token finalToken) { + final int startPos = nameToken.charPos; + final int endPos = finalToken.charPos + finalToken.val.length(); + final SourceSection src = source.createSection(nameToken.val, startPos, endPos - startPos); SLExpressionNode functionNode = createRead(nameToken); - return assignSource(nameToken, SLInvokeNode.create(functionNode, parameterNodes.toArray(new SLExpressionNode[parameterNodes.size()]))); + return SLInvokeNode.create(src, functionNode, parameterNodes.toArray(new SLExpressionNode[parameterNodes.size()])); } public SLExpressionNode createAssignment(Token nameToken, SLExpressionNode valueNode) { FrameSlot frameSlot = frameDescriptor.findOrAddFrameSlot(nameToken.val); lexicalScope.locals.put(nameToken.val, frameSlot); - return assignSource(nameToken, SLWriteLocalVariableNodeFactory.create(valueNode, frameSlot)); + final int start = nameToken.charPos; + final int length = valueNode.getSourceSection().getCharEndIndex() - start; + return SLWriteLocalVariableNodeFactory.create(source.createSection("=", start, length), valueNode, frameSlot); } public SLExpressionNode createRead(Token nameToken) { - FrameSlot frameSlot = lexicalScope.locals.get(nameToken.val); + final FrameSlot frameSlot = lexicalScope.locals.get(nameToken.val); + final SourceSection src = source.createSection(nameToken.val, nameToken.charPos, nameToken.val.length()); if (frameSlot != null) { /* Read of a local variable. */ - return assignSource(nameToken, SLReadLocalVariableNodeFactory.create(frameSlot)); + return SLReadLocalVariableNodeFactory.create(src, frameSlot); } else { /* Read of a global name. In our language, the only global names are functions. */ - return assignSource(nameToken, new SLFunctionLiteralNode(context.getFunctionRegistry().lookup(nameToken.val))); + return new SLFunctionLiteralNode(src, context.getFunctionRegistry().lookup(nameToken.val)); } } @@ -220,31 +254,21 @@ /* Remove the trailing and ending " */ String literal = literalToken.val; assert literal.length() >= 2 && literal.startsWith("\"") && literal.endsWith("\""); + final SourceSection src = source.createSection(literalToken.val, literalToken.charPos, literalToken.val.length()); literal = literal.substring(1, literal.length() - 1); - return assignSource(literalToken, new SLStringLiteralNode(literal)); + return new SLStringLiteralNode(src, literal); } public SLExpressionNode createNumericLiteral(Token literalToken) { + final SourceSection src = source.createSection(literalToken.val, literalToken.charPos, literalToken.val.length()); try { /* Try if the literal is small enough to fit into a long value. */ - return assignSource(literalToken, new SLLongLiteralNode(Long.parseLong(literalToken.val))); + return new SLLongLiteralNode(src, Long.parseLong(literalToken.val)); } catch (NumberFormatException ex) { /* Overflow of long value, so fall back to BigInteger. */ - return assignSource(literalToken, new SLBigIntegerLiteralNode(new BigInteger(literalToken.val))); + return new SLBigIntegerLiteralNode(src, new BigInteger(literalToken.val)); } } - private T assignSource(Token t, T node) { - assert functionName != null; - assert t != null; - - int startLine = t.line; - int startColumn = t.col; - int charLength = t.val.length(); - SourceSection sourceSection = source.createSection(functionName, startLine, startColumn, 0, charLength); - - node.assignSourceSection(sourceSection); - return node; - } } diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/Scanner.java Tue Jul 15 19:21:28 2014 -0700 @@ -25,8 +25,11 @@ package com.oracle.truffle.sl.parser; -import java.io.*; -import java.util.*; +import java.io.InputStream; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.Map; +import java.util.HashMap; // Checkstyle: stop // @formatter:off diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg Tue Jul 15 19:21:28 2014 -0700 @@ -84,11 +84,12 @@ Block = (. factory.startBlock(); List body = new ArrayList<>(); .) -"{" +"{" (. int lBracePos = t.charPos; .) { Statement (. body.add(s); .) } -"}" (. result = factory.finishBlock(body); .) +"}" (. int length = (t.charPos + t.val.length()) - lBracePos; .) + (. result = factory.finishBlock(body, lBracePos, length); .) . @@ -210,8 +211,9 @@ "," Expression (. parameters.add(parameter); .) } - ] (. result = factory.createCall(nameToken, parameters); .) - ")" + ] + ")" (. Token finalToken = t; .) + (. result = factory.createCall(nameToken, parameters, finalToken); .) | "=" Expression (. result = factory.createAssignment(nameToken, value); .) diff -r 072b9501f5f9 -r 446750355e5f graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java Tue Jul 15 19:15:46 2014 -0700 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java Tue Jul 15 19:21:28 2014 -0700 @@ -121,7 +121,7 @@ * from this array. */ for (int i = 0; i < argumentCount; i++) { - argumentNodes[i] = new SLReadArgumentNode(i); + argumentNodes[i] = new SLReadArgumentNode(null, i); } /* Instantiate the builtin node. This node performs the actual functionality. */ SLBuiltinNode builtinBodyNode = factory.createNode(argumentNodes, this); diff -r 072b9501f5f9 -r 446750355e5f mx/mx_graal.py --- a/mx/mx_graal.py Tue Jul 15 19:15:46 2014 -0700 +++ b/mx/mx_graal.py Tue Jul 15 19:21:28 2014 -0700 @@ -1281,6 +1281,12 @@ dacapo(['-Xbatch', 'pmd']) tasks.append(t.stop()) + # ensure -Xcomp still works + with VM('graal', 'product'): + t = Task('XCompMode:product') + vm(['-Xcomp', '-version']) + tasks.append(t.stop()) + if args.jacocout is not None: jacocoreport([args.jacocout]) @@ -2049,7 +2055,7 @@ tmp = tempfile.mkdtemp(prefix='findbugs-download-tmp', dir=_graal_home) try: findbugsDist = join(tmp, 'findbugs.zip') - mx.download(findbugsDist, ['http://sourceforge.net/projects/findbugs/files/findbugs/3.0.0/findbugs-3.0.0-dev-20131204-e3cbbd5.zip']) + mx.download(findbugsDist, ['http://lafo.ssw.uni-linz.ac.at/graal-external-deps/findbugs-3.0.0.zip', 'http://sourceforge.net/projects/findbugs/files/findbugs/3.0.0/findbugs-3.0.0.zip']) with zipfile.ZipFile(findbugsDist) as zf: candidates = [e for e in zf.namelist() if e.endswith('/lib/findbugs.jar')] assert len(candidates) == 1, candidates diff -r 072b9501f5f9 -r 446750355e5f mx/projects --- a/mx/projects Tue Jul 15 19:15:46 2014 -0700 +++ b/mx/projects Tue Jul 15 19:21:28 2014 -0700 @@ -23,9 +23,9 @@ library@CHECKSTYLE@path=lib/checkstyle-5.5-all.jar library@CHECKSTYLE@urls=jar:http://sourceforge.net/projects/checkstyle/files/checkstyle/5.5/checkstyle-5.5-bin.zip/download!/checkstyle-5.5/checkstyle-5.5-all.jar -library@FINDBUGS@path=lib/findbugs-3.0.0-rc1.jar -library@FINDBUGS@urls=jar:http://lafo.ssw.uni-linz.ac.at/graal-external-deps/findbugs-3.0.0-rc1.zip!/findbugs-3.0.0-rc1/lib/findbugs.jar,jar:http://sourceforge.net/projects/findbugs/files/findbugs/3.0.0/findbugs-3.0.0-rc1.zip/download!/findbugs-3.0.0-rc1/lib/findbugs.jar -library@FINDBUGS@sha1=3a0a592608b41b57a77721b933b7bb78fcf64015 +library@FINDBUGS@path=lib/findbugs-3.0.0.jar +library@FINDBUGS@urls=jar:http://lafo.ssw.uni-linz.ac.at/graal-external-deps/findbugs-3.0.0.zip!/findbugs-3.0.0/lib/findbugs.jar,jar:http://sourceforge.net/projects/findbugs/files/findbugs/3.0.0/findbugs-3.0.0.zip/download!/findbugs-3.0.0/lib/findbugs.jar +library@FINDBUGS@sha1=e9a938f0cb34e2ab5853f9ecb1989f6f590ee385 library@DACAPO@path=lib/dacapo-9.12-bach.jar library@DACAPO@urls=http://lafo.ssw.uni-linz.ac.at/graal-external-deps/dacapo-9.12-bach.jar,http://softlayer.dl.sourceforge.net/project/dacapobench/9.12-bach/dacapo-9.12-bach.jar @@ -135,14 +135,6 @@ project@com.oracle.graal.api.meta.test@javaCompliance=1.8 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 diff -r 072b9501f5f9 -r 446750355e5f mxtool/mx.py --- a/mxtool/mx.py Tue Jul 15 19:15:46 2014 -0700 +++ b/mxtool/mx.py Tue Jul 15 19:21:28 2014 -0700 @@ -2043,7 +2043,7 @@ rootJdtProperties = join(self.proj.suite.mxDir, 'eclipse-settings', 'org.eclipse.jdt.core.prefs') if not exists(jdtProperties) or os.path.getmtime(jdtProperties) < os.path.getmtime(rootJdtProperties): # Try to fix a missing properties file by running eclipseinit - eclipseinit([], buildProcessorJars=False) + _eclipseinit_project(self.proj) if not exists(jdtProperties): log('JDT properties file {0} not found'.format(jdtProperties)) else: @@ -3174,6 +3174,229 @@ return False return True +def _eclipseinit_project(p, files=None, libFiles=None): + assert java(p.javaCompliance) + + if not exists(p.dir): + os.makedirs(p.dir) + + out = XMLDoc() + out.open('classpath') + + for src in p.srcDirs: + srcDir = join(p.dir, src) + if not exists(srcDir): + os.mkdir(srcDir) + out.element('classpathentry', {'kind' : 'src', 'path' : src}) + + if len(p.annotation_processors()) > 0: + genDir = p.source_gen_dir() + if not exists(genDir): + os.mkdir(genDir) + out.element('classpathentry', {'kind' : 'src', 'path' : 'src_gen'}) + if files: + files.append(genDir) + + # Every Java program depends on a JRE + out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-' + str(p.javaCompliance)}) + + if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project + out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.pde.core.requiredPlugins'}) + + containerDeps = set() + libraryDeps = set() + projectDeps = set() + + for dep in p.all_deps([], True): + if dep == p: + continue + if dep.isLibrary(): + if hasattr(dep, 'eclipse.container'): + container = getattr(dep, 'eclipse.container') + containerDeps.add(container) + libraryDeps -= set(dep.all_deps([], True)) + else: + libraryDeps.add(dep) + elif dep.isProject(): + projectDeps.add(dep) + + for dep in containerDeps: + out.element('classpathentry', {'exported' : 'true', 'kind' : 'con', 'path' : dep}) + + for dep in libraryDeps: + path = dep.path + dep.get_path(resolve=True) + + # Relative paths for "lib" class path entries have various semantics depending on the Eclipse + # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's + # safest to simply use absolute paths. + path = _make_absolute(path, p.suite.dir) + + attributes = {'exported' : 'true', 'kind' : 'lib', 'path' : path} + + sourcePath = dep.get_source_path(resolve=True) + if sourcePath is not None: + attributes['sourcepath'] = sourcePath + out.element('classpathentry', attributes) + if libFiles: + libFiles.append(path) + + for dep in projectDeps: + out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + dep.name}) + + out.element('classpathentry', {'kind' : 'output', 'path' : getattr(p, 'eclipse.output', 'bin')}) + out.close('classpath') + classpathFile = join(p.dir, '.classpath') + update_file(classpathFile, out.xml(indent='\t', newl='\n')) + if files: + files.append(classpathFile) + + csConfig = join(project(p.checkstyleProj).dir, '.checkstyle_checks.xml') + if exists(csConfig): + out = XMLDoc() + + dotCheckstyle = join(p.dir, ".checkstyle") + checkstyleConfigPath = '/' + p.checkstyleProj + '/.checkstyle_checks.xml' + out.open('fileset-config', {'file-format-version' : '1.2.0', 'simple-config' : 'true'}) + out.open('local-check-config', {'name' : 'Checks', 'location' : checkstyleConfigPath, 'type' : 'project', 'description' : ''}) + out.element('additional-data', {'name' : 'protect-config-file', 'value' : 'false'}) + out.close('local-check-config') + out.open('fileset', {'name' : 'all', 'enabled' : 'true', 'check-config-name' : 'Checks', 'local' : 'true'}) + out.element('file-match-pattern', {'match-pattern' : '.', 'include-pattern' : 'true'}) + out.close('fileset') + out.open('filter', {'name' : 'all', 'enabled' : 'true', 'check-config-name' : 'Checks', 'local' : 'true'}) + out.element('filter-data', {'value' : 'java'}) + out.close('filter') + + exclude = join(p.dir, '.checkstyle.exclude') + if exists(exclude): + out.open('filter', {'name' : 'FilesFromPackage', 'enabled' : 'true'}) + with open(exclude) as f: + for line in f: + if not line.startswith('#'): + line = line.strip() + exclDir = join(p.dir, line) + assert isdir(exclDir), 'excluded source directory listed in ' + exclude + ' does not exist or is not a directory: ' + exclDir + out.element('filter-data', {'value' : line}) + out.close('filter') + + out.close('fileset-config') + update_file(dotCheckstyle, out.xml(indent=' ', newl='\n')) + if files: + files.append(dotCheckstyle) + else: + # clean up existing .checkstyle file + dotCheckstyle = join(p.dir, ".checkstyle") + if exists(dotCheckstyle): + os.unlink(dotCheckstyle) + + out = XMLDoc() + out.open('projectDescription') + out.element('name', data=p.name) + out.element('comment', data='') + out.element('projects', data='') + out.open('buildSpec') + out.open('buildCommand') + out.element('name', data='org.eclipse.jdt.core.javabuilder') + out.element('arguments', data='') + out.close('buildCommand') + if exists(csConfig): + out.open('buildCommand') + out.element('name', data='net.sf.eclipsecs.core.CheckstyleBuilder') + out.element('arguments', data='') + out.close('buildCommand') + if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project + for buildCommand in ['org.eclipse.pde.ManifestBuilder', 'org.eclipse.pde.SchemaBuilder']: + out.open('buildCommand') + out.element('name', data=buildCommand) + out.element('arguments', data='') + out.close('buildCommand') + + # The path should always be p.name/dir. independent of where the workspace actually is. + # So we use the parent folder of the project, whatever that is, to generate such a relative path. + logicalWorkspaceRoot = os.path.dirname(p.dir) + binFolder = os.path.relpath(p.output_dir(), logicalWorkspaceRoot) + + if _isAnnotationProcessorDependency(p): + refreshFile = os.path.relpath(join(p.dir, p.name + '.jar'), logicalWorkspaceRoot) + _genEclipseBuilder(out, p, 'Jar', 'archive ' + p.name, refresh=True, refreshFile=refreshFile, relevantResources=[binFolder], async=True, xmlIndent='', xmlStandalone='no') + + out.close('buildSpec') + out.open('natures') + out.element('nature', data='org.eclipse.jdt.core.javanature') + if exists(csConfig): + out.element('nature', data='net.sf.eclipsecs.core.CheckstyleNature') + if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project + out.element('nature', data='org.eclipse.pde.PluginNature') + out.close('natures') + out.close('projectDescription') + projectFile = join(p.dir, '.project') + update_file(projectFile, out.xml(indent='\t', newl='\n')) + if files: + files.append(projectFile) + + settingsDir = join(p.dir, ".settings") + if not exists(settingsDir): + os.mkdir(settingsDir) + + # collect the defaults from mxtool + defaultEclipseSettingsDir = join(dirname(__file__), 'eclipse-settings') + esdict = {} + if exists(defaultEclipseSettingsDir): + for name in os.listdir(defaultEclipseSettingsDir): + if isfile(join(defaultEclipseSettingsDir, name)): + esdict[name] = os.path.abspath(join(defaultEclipseSettingsDir, name)) + + # check for suite overrides + eclipseSettingsDir = join(p.suite.mxDir, 'eclipse-settings') + if exists(eclipseSettingsDir): + for name in os.listdir(eclipseSettingsDir): + if isfile(join(eclipseSettingsDir, name)): + esdict[name] = os.path.abspath(join(eclipseSettingsDir, name)) + + # check for project overrides + projectSettingsDir = join(p.dir, 'eclipse-settings') + if exists(projectSettingsDir): + for name in os.listdir(projectSettingsDir): + if isfile(join(projectSettingsDir, name)): + esdict[name] = os.path.abspath(join(projectSettingsDir, name)) + + # copy a possibly modified file to the project's .settings directory + for name, path in esdict.iteritems(): + # ignore this file altogether if this project has no annotation processors + if name == "org.eclipse.jdt.apt.core.prefs" and not len(p.annotation_processors()) > 0: + continue + + with open(path) as f: + content = f.read() + content = content.replace('${javaCompliance}', str(p.javaCompliance)) + if len(p.annotation_processors()) > 0: + content = content.replace('org.eclipse.jdt.core.compiler.processAnnotations=disabled', 'org.eclipse.jdt.core.compiler.processAnnotations=enabled') + update_file(join(settingsDir, name), content) + if files: + files.append(join(settingsDir, name)) + + if len(p.annotation_processors()) > 0: + out = XMLDoc() + out.open('factorypath') + out.element('factorypathentry', {'kind' : 'PLUGIN', 'id' : 'org.eclipse.jst.ws.annotations.core', 'enabled' : 'true', 'runInBatchMode' : 'false'}) + for ap in p.annotation_processors(): + for dep in dependency(ap).all_deps([], True): + if dep.isLibrary(): + # Relative paths for "lib" class path entries have various semantics depending on the Eclipse + # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's + # safest to simply use absolute paths. + path = _make_absolute(dep.get_path(resolve=True), p.suite.dir) + out.element('factorypathentry', {'kind' : 'EXTJAR', 'id' : path, 'enabled' : 'true', 'runInBatchMode' : 'false'}) + if files: + files.append(path) + elif dep.isProject(): + out.element('factorypathentry', {'kind' : 'WKSPJAR', 'id' : '/' + dep.name + '/' + dep.name + '.jar', 'enabled' : 'true', 'runInBatchMode' : 'false'}) + out.close('factorypath') + update_file(join(p.dir, '.factorypath'), out.xml(indent='\t', newl='\n')) + if files: + files.append(join(p.dir, '.factorypath')) + def _eclipseinit_suite(args, suite, buildProcessorJars=True, refreshOnly=False): configZip = TimeStampFile(join(suite.mxDir, 'eclipse-config.zip')) configLibsZip = join(suite.mxDir, 'eclipse-config-libs.zip') @@ -3184,6 +3407,8 @@ logv('[Eclipse configurations are up to date - skipping]') return + + files = [] libFiles = [] if buildProcessorJars: @@ -3198,220 +3423,7 @@ for p in suite.projects: if p.native: continue - - assert java(p.javaCompliance) - - if not exists(p.dir): - os.makedirs(p.dir) - - out = XMLDoc() - out.open('classpath') - - for src in p.srcDirs: - srcDir = join(p.dir, src) - if not exists(srcDir): - os.mkdir(srcDir) - out.element('classpathentry', {'kind' : 'src', 'path' : src}) - - if len(p.annotation_processors()) > 0: - genDir = p.source_gen_dir() - if not exists(genDir): - os.mkdir(genDir) - out.element('classpathentry', {'kind' : 'src', 'path' : 'src_gen'}) - files.append(genDir) - - # Every Java program depends on a JRE - out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-' + str(p.javaCompliance)}) - - if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project - out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.pde.core.requiredPlugins'}) - - containerDeps = set() - libraryDeps = set() - projectDeps = set() - - for dep in p.all_deps([], True): - if dep == p: - continue - if dep.isLibrary(): - if hasattr(dep, 'eclipse.container'): - container = getattr(dep, 'eclipse.container') - containerDeps.add(container) - libraryDeps -= set(dep.all_deps([], True)) - else: - libraryDeps.add(dep) - elif dep.isProject(): - projectDeps.add(dep) - - for dep in containerDeps: - out.element('classpathentry', {'exported' : 'true', 'kind' : 'con', 'path' : dep}) - - for dep in libraryDeps: - path = dep.path - dep.get_path(resolve=True) - - # Relative paths for "lib" class path entries have various semantics depending on the Eclipse - # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's - # safest to simply use absolute paths. - path = _make_absolute(path, p.suite.dir) - - attributes = {'exported' : 'true', 'kind' : 'lib', 'path' : path} - - sourcePath = dep.get_source_path(resolve=True) - if sourcePath is not None: - attributes['sourcepath'] = sourcePath - out.element('classpathentry', attributes) - libFiles.append(path) - - for dep in projectDeps: - out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + dep.name}) - - out.element('classpathentry', {'kind' : 'output', 'path' : getattr(p, 'eclipse.output', 'bin')}) - out.close('classpath') - classpathFile = join(p.dir, '.classpath') - update_file(classpathFile, out.xml(indent='\t', newl='\n')) - files.append(classpathFile) - - csConfig = join(project(p.checkstyleProj).dir, '.checkstyle_checks.xml') - if exists(csConfig): - out = XMLDoc() - - dotCheckstyle = join(p.dir, ".checkstyle") - checkstyleConfigPath = '/' + p.checkstyleProj + '/.checkstyle_checks.xml' - out.open('fileset-config', {'file-format-version' : '1.2.0', 'simple-config' : 'true'}) - out.open('local-check-config', {'name' : 'Checks', 'location' : checkstyleConfigPath, 'type' : 'project', 'description' : ''}) - out.element('additional-data', {'name' : 'protect-config-file', 'value' : 'false'}) - out.close('local-check-config') - out.open('fileset', {'name' : 'all', 'enabled' : 'true', 'check-config-name' : 'Checks', 'local' : 'true'}) - out.element('file-match-pattern', {'match-pattern' : '.', 'include-pattern' : 'true'}) - out.close('fileset') - out.open('filter', {'name' : 'all', 'enabled' : 'true', 'check-config-name' : 'Checks', 'local' : 'true'}) - out.element('filter-data', {'value' : 'java'}) - out.close('filter') - - exclude = join(p.dir, '.checkstyle.exclude') - if exists(exclude): - out.open('filter', {'name' : 'FilesFromPackage', 'enabled' : 'true'}) - with open(exclude) as f: - for line in f: - if not line.startswith('#'): - line = line.strip() - exclDir = join(p.dir, line) - assert isdir(exclDir), 'excluded source directory listed in ' + exclude + ' does not exist or is not a directory: ' + exclDir - out.element('filter-data', {'value' : line}) - out.close('filter') - - out.close('fileset-config') - update_file(dotCheckstyle, out.xml(indent=' ', newl='\n')) - files.append(dotCheckstyle) - else: - # clean up existing .checkstyle file - dotCheckstyle = join(p.dir, ".checkstyle") - if exists(dotCheckstyle): - os.unlink(dotCheckstyle) - - out = XMLDoc() - out.open('projectDescription') - out.element('name', data=p.name) - out.element('comment', data='') - out.element('projects', data='') - out.open('buildSpec') - out.open('buildCommand') - out.element('name', data='org.eclipse.jdt.core.javabuilder') - out.element('arguments', data='') - out.close('buildCommand') - if exists(csConfig): - out.open('buildCommand') - out.element('name', data='net.sf.eclipsecs.core.CheckstyleBuilder') - out.element('arguments', data='') - out.close('buildCommand') - if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project - for buildCommand in ['org.eclipse.pde.ManifestBuilder', 'org.eclipse.pde.SchemaBuilder']: - out.open('buildCommand') - out.element('name', data=buildCommand) - out.element('arguments', data='') - out.close('buildCommand') - - # The path should always be p.name/dir. independent of where the workspace actually is. - # So we use the parent folder of the project, whatever that is, to generate such a relative path. - logicalWorkspaceRoot = os.path.dirname(p.dir) - binFolder = os.path.relpath(p.output_dir(), logicalWorkspaceRoot) - - if _isAnnotationProcessorDependency(p): - refreshFile = os.path.relpath(join(p.dir, p.name + '.jar'), logicalWorkspaceRoot) - _genEclipseBuilder(out, p, 'Jar', 'archive ' + p.name, refresh=True, refreshFile=refreshFile, relevantResources=[binFolder], async=True, xmlIndent='', xmlStandalone='no') - - out.close('buildSpec') - out.open('natures') - out.element('nature', data='org.eclipse.jdt.core.javanature') - if exists(csConfig): - out.element('nature', data='net.sf.eclipsecs.core.CheckstyleNature') - if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project - out.element('nature', data='org.eclipse.pde.PluginNature') - out.close('natures') - out.close('projectDescription') - projectFile = join(p.dir, '.project') - update_file(projectFile, out.xml(indent='\t', newl='\n')) - files.append(projectFile) - - settingsDir = join(p.dir, ".settings") - if not exists(settingsDir): - os.mkdir(settingsDir) - - # collect the defaults from mxtool - defaultEclipseSettingsDir = join(dirname(__file__), 'eclipse-settings') - esdict = {} - if exists(defaultEclipseSettingsDir): - for name in os.listdir(defaultEclipseSettingsDir): - if isfile(join(defaultEclipseSettingsDir, name)): - esdict[name] = os.path.abspath(join(defaultEclipseSettingsDir, name)) - - # check for suite overrides - eclipseSettingsDir = join(p.suite.mxDir, 'eclipse-settings') - if exists(eclipseSettingsDir): - for name in os.listdir(eclipseSettingsDir): - if isfile(join(eclipseSettingsDir, name)): - esdict[name] = os.path.abspath(join(eclipseSettingsDir, name)) - - # check for project overrides - projectSettingsDir = join(p.dir, 'eclipse-settings') - if exists(projectSettingsDir): - for name in os.listdir(projectSettingsDir): - if isfile(join(projectSettingsDir, name)): - esdict[name] = os.path.abspath(join(projectSettingsDir, name)) - - # copy a possibly modified file to the project's .settings directory - for name, path in esdict.iteritems(): - # ignore this file altogether if this project has no annotation processors - if name == "org.eclipse.jdt.apt.core.prefs" and not len(p.annotation_processors()) > 0: - continue - - with open(path) as f: - content = f.read() - content = content.replace('${javaCompliance}', str(p.javaCompliance)) - if len(p.annotation_processors()) > 0: - content = content.replace('org.eclipse.jdt.core.compiler.processAnnotations=disabled', 'org.eclipse.jdt.core.compiler.processAnnotations=enabled') - update_file(join(settingsDir, name), content) - files.append(join(settingsDir, name)) - - if len(p.annotation_processors()) > 0: - out = XMLDoc() - out.open('factorypath') - out.element('factorypathentry', {'kind' : 'PLUGIN', 'id' : 'org.eclipse.jst.ws.annotations.core', 'enabled' : 'true', 'runInBatchMode' : 'false'}) - for ap in p.annotation_processors(): - for dep in dependency(ap).all_deps([], True): - if dep.isLibrary(): - # Relative paths for "lib" class path entries have various semantics depending on the Eclipse - # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's - # safest to simply use absolute paths. - path = _make_absolute(dep.get_path(resolve=True), p.suite.dir) - out.element('factorypathentry', {'kind' : 'EXTJAR', 'id' : path, 'enabled' : 'true', 'runInBatchMode' : 'false'}) - files.append(path) - elif dep.isProject(): - out.element('factorypathentry', {'kind' : 'WKSPJAR', 'id' : '/' + dep.name + '/' + dep.name + '.jar', 'enabled' : 'true', 'runInBatchMode' : 'false'}) - out.close('factorypath') - update_file(join(p.dir, '.factorypath'), out.xml(indent='\t', newl='\n')) - files.append(join(p.dir, '.factorypath')) + _eclipseinit_project(p) _, launchFile = make_eclipse_attach(suite, 'localhost', '8000', deps=sorted_deps(projectNames=None, includeLibs=True)) files.append(launchFile) @@ -3422,7 +3434,6 @@ # Create an Eclipse project for each distribution that will create/update the archive # for the distribution whenever any project of the distribution is updated. for dist in suite.dists: - name = dist.name if hasattr(dist, 'subDir'): projectDir = join(suite.dir, dist.subDir, dist.name + '.dist') else: diff -r 072b9501f5f9 -r 446750355e5f src/share/vm/compiler/compileBroker.cpp --- a/src/share/vm/compiler/compileBroker.cpp Tue Jul 15 19:15:46 2014 -0700 +++ b/src/share/vm/compiler/compileBroker.cpp Tue Jul 15 19:21:28 2014 -0700 @@ -51,6 +51,9 @@ #endif #ifdef GRAAL #include "graal/graalCompiler.hpp" +#ifdef COMPILERGRAAL +#include "runtime/vframe.hpp" +#endif #endif #ifdef COMPILER2 #include "opto/c2compiler.hpp" @@ -1187,10 +1190,22 @@ blocking = is_compile_blocking(method, osr_bci); #ifdef COMPILERGRAAL - // Don't allow blocking compiles for requests triggered by Graal. - if (blocking && thread->is_Compiler_thread()) { - blocking = false; + if (blocking) { + // Don't allow blocking compiles for requests triggered by Graal. + if (thread->is_Compiler_thread()) { + blocking = false; + } + + // Don't allow blocking compiles if inside a class initializer + vframeStream vfst((JavaThread*) thread); + for (; !vfst.at_end(); vfst.next()) { + if (vfst.method()->is_static_initializer()) { + blocking = false; + break; + } + } } + // Don't allow blocking compiles #endif // We will enter the compilation in the queue. diff -r 072b9501f5f9 -r 446750355e5f src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Tue Jul 15 19:15:46 2014 -0700 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Tue Jul 15 19:21:28 2014 -0700 @@ -234,11 +234,13 @@ Klass* resolved_klass = NULL; Handle class_loader; Handle protection_domain; - if (JNIHandles::resolve(accessing_class) != NULL) { - Klass* accessing_klass = java_lang_Class::as_Klass(JNIHandles::resolve(accessing_class)); - class_loader = accessing_klass->class_loader(); - protection_domain = accessing_klass->protection_domain(); + if (JNIHandles::resolve(accessing_class) == NULL) { + THROW_(vmSymbols::java_lang_NullPointerException(), 0L); } + Klass* accessing_klass = java_lang_Class::as_Klass(JNIHandles::resolve(accessing_class)); + class_loader = accessing_klass->class_loader(); + protection_domain = accessing_klass->protection_domain(); + if (resolve) { resolved_klass = SystemDictionary::resolve_or_fail(class_name, class_loader, protection_domain, true, THREAD); diff -r 072b9501f5f9 -r 446750355e5f src/share/vm/runtime/thread.cpp