changeset 16513:d86f948268da

Merge with f0f4402a4f65bc5456feeb4d78e6b4843ec23d8c
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Mon, 14 Jul 2014 17:06:32 -0700
parents abe7128ca473 (current diff) f0f4402a4f65 (diff)
children 247a6c2fc382
files graal/com.oracle.graal.api.meta.jdk8.test/src/com/oracle/graal/api/meta/jdk8/test/TestResolvedJavaMethodJDK8.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java
diffstat 103 files changed, 1235 insertions(+), 961 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java	Mon Jul 14 17:06:32 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)") + "]";
         }
     }
 
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java	Mon Jul 14 17:06:32 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();
     }
 }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java	Mon Jul 14 17:06:32 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<VirtualObject> 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('{');
--- a/graal/com.oracle.graal.api.meta.jdk8.test/src/com/oracle/graal/api/meta/jdk8/test/TestResolvedJavaMethodJDK8.java	Mon Jul 14 16:51:41 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 &ge; 8.
- */
-public class TestResolvedJavaMethodJDK8 extends MethodUniverse {
-
-    public TestResolvedJavaMethodJDK8() {
-    }
-
-    @Test
-    public void isDefaultTest() {
-        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
-            ResolvedJavaMethod m = e.getValue();
-            assertEquals(e.getKey().isDefault(), m.isDefault());
-        }
-        for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
-            ResolvedJavaMethod m = e.getValue();
-            assertFalse(m.isDefault());
-        }
-    }
-}
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/ResolvedJavaTypeResolveMethodTest.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/ResolvedJavaTypeResolveMethodTest.java	Mon Jul 14 17:06:32 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;
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java	Mon Jul 14 17:06:32 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);
+        }
+    }
 }
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java	Mon Jul 14 17:06:32 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());
             }
         }
     }
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java	Mon Jul 14 17:06:32 2014 -0700
@@ -267,6 +267,18 @@
         assertTrue(2 <= method2StackSize && method2StackSize <= 4);
     }
 
+    @Test
+    public void isDefaultTest() {
+        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
+            ResolvedJavaMethod m = e.getValue();
+            assertEquals(e.getKey().isDefault(), m.isDefault());
+        }
+        for (Map.Entry<Constructor<?>, 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
 
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java	Mon Jul 14 17:06:32 2014 -0700
@@ -709,7 +709,9 @@
         "getSourceFileName",
         "getClassFilePath",
         "isLocal",
+        "isJavaLangObject",
         "isMember",
+        "getElementalType",
         "getEnclosingType"
     };
     // @formatter:on
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java	Mon Jul 14 17:06:32 2014 -0700
@@ -93,7 +93,7 @@
 
     @Override
     public String toString() {
-        return "BaseProfilingInfo<" + MetaUtil.profileToString(this, null, "; ") + ">";
+        return "BaseProfilingInfo<" + this.toString(null, "; ") + ">";
     }
 
     public void setMature() {
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaField.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaField.java	Mon Jul 14 17:06:32 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:
+     *
+     * <pre>
+     *     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                                      | "%"
+     * </pre>
+     *
+     * @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();
+    }
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaMethod.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaMethod.java	Mon Jul 14 17:06:32 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:
+     *
+     * <pre>
+     *     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                                      | "%"
+     * </pre>
+     *
+     * @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();
+    }
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaType.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaType.java	Mon Jul 14 17:06:32 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:
-     * 
+     *
      * <pre>
      *     "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:
+     *
+     * <pre>
+     *      java.lang.Object
+     *      int
+     *      boolean[][]
+     * </pre>
+     *
+     * @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:
+     *
+     * <pre>
+     *     qualified == true:
+     *         java.lang.Object
+     *         int
+     *         boolean[][]
+     *     qualified == false:
+     *         Object
+     *         int
+     *         boolean[][]
+     * </pre>
+     *
+     * @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);
+    }
+
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Mon Jul 14 17:06:32 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) {
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Mon Jul 14 17:06:32 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);
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Mon Jul 14 17:06:32 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:
-     *
-     * <pre>
-     *     qualified == true:
-     *         java.lang.Object
-     *         int
-     *         boolean[][]
-     *     qualified == false:
-     *         Object
-     *         int
-     *         boolean[][]
-     * </pre>
-     *
-     * @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:
-     *
-     * <pre>
-     *      java.lang.Object
-     *      int
-     *      boolean[][]
-     * </pre>
-     *
-     * @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:
-     *
-     * <pre>
-     *     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                                      | "%"
-     * </pre>
-     *
-     * @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:
-     *
-     * <pre>
-     *     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                                      | "%"
-     * </pre>
-     *
-     * @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 extends Annotation> T[] getParameterAnnotations(Class<T> 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 extends Annotation> T getParameterAnnotation(Class<T> 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]
      * </pre>
      *
-     * 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:
      *
      * <pre>
@@ -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 <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">method
-     * descriptor</a> corresponding to this signature. For example:
-     *
-     * <pre>
-     * (ILjava/lang/String;D)V
-     * </pre>
-     *
-     * .
-     *
-     * @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 extends Annotation> T[] getParameterAnnotations(Class<T> annotationClass, ResolvedJavaMethod method) {
+        return method.getParameterAnnotations(annotationClass);
+    }
+
+    @Deprecated
+    public static <T extends Annotation> T getParameterAnnotation(Class<T> 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);
+    }
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java	Mon Jul 14 17:06:32 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());
+    }
+
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java	Mon Jul 14 17:06:32 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 extends Annotation> T getParameterAnnotation(Class<T> 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 extends Annotation> T[] getParameterAnnotations(Class<T> 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;
+    }
+
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Mon Jul 14 17:06:32 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.
      * <p>
      * 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.
      * <p>
      * For a non-array type T, the result is the unique concrete type in the current hierarchy of T.
      * <p>
@@ -202,6 +210,14 @@
 
     ResolvedJavaType getComponentType();
 
+    default ResolvedJavaType getElementalType() {
+        ResolvedJavaType t = this;
+        while (t.isArray()) {
+            t = t.getComponentType();
+        }
+        return t;
+    }
+
     ResolvedJavaType getArrayClass();
 
     /**
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Signature.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Signature.java	Mon Jul 14 17:06:32 2014 -0700
@@ -24,7 +24,7 @@
 
 /**
  * Represents a method signature provided by the runtime.
- * 
+ *
  * @see <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">Method
  *      Descriptors</a>
  */
@@ -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 <a
+     * href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">method
+     * descriptor</a> corresponding to this signature. For example:
+     *
+     * <pre>
+     * (ILjava/lang/String;D)V
+     * </pre>
+     *
+     * @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;
+    }
 }
--- a/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/MethodSubstitution.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/MethodSubstitution.java	Mon Jul 14 17:06:32 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.
      * <p>
      * 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.
      */
--- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java	Mon Jul 14 17:06:32 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)) {
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILNodeLIRBuilder.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILNodeLIRBuilder.java	Mon Jul 14 17:06:32 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
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXNodeLIRBuilder.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXNodeLIRBuilder.java	Mon Jul 14 17:06:32 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 {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Mon Jul 14 17:06:32 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);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/MethodFilter.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/MethodFilter.java	Mon Jul 14 17:06:32 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;
                 }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILNewObjectSnippets.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILNewObjectSnippets.java	Mon Jul 14 17:06:32 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);
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java	Mon Jul 14 17:06:32 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<LaunchArg, ValueNode> 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());
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java	Mon Jul 14 17:06:32 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);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationStatistics.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationStatistics.java	Mon Jul 14 17:06:32 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();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Mon Jul 14 17:06:32 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) + "]";
     }
 
     /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Mon Jul 14 17:06:32 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);
         }
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Mon Jul 14 17:06:32 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);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Mon Jul 14 17:06:32 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}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java	Mon Jul 14 17:06:32 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 + ")";
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Mon Jul 14 17:06:32 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;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethod.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethod.java	Mon Jul 14 17:06:32 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) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Mon Jul 14 17:06:32 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;
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Mon Jul 14 17:06:32 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;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Mon Jul 14 17:06:32 2014 -0700
@@ -199,7 +199,7 @@
 
     @Override
     public String toString() {
-        return "HotSpotProfilingInfo<" + MetaUtil.profileToString(this, null, "; ") + ">";
+        return "HotSpotProfilingInfo<" + this.toString(null, "; ") + ">";
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Mon Jul 14 17:06:32 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
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Mon Jul 14 17:06:32 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());
                 }
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Mon Jul 14 17:06:32 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);
     }
 
     /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Mon Jul 14 17:06:32 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;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Mon Jul 14 17:06:32 2014 -0700
@@ -40,8 +40,8 @@
     private final List<String> 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;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedField.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedField.java	Mon Jul 14 17:06:32 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>");
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedJavaType.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedJavaType.java	Mon Jul 14 17:06:32 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);
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TailcallNode.java	Mon Jul 14 17:06:32 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<ValueNode> parameters = new ArrayList<>();
         for (int i = 0, slot = 0; i < cc.getArgumentCount(); i++, slot += HIRFrameStateBuilder.stackSlots(frameState.localAt(slot).getKind())) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java	Mon Jul 14 17:06:32 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);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Mon Jul 14 17:06:32 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<ReturnNode> 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));
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Mon Jul 14 17:06:32 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);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Mon Jul 14 17:06:32 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)>");
             }
         };
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Mon Jul 14 17:06:32 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") + ">";
     }
 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Mon Jul 14 17:06:32 2014 -0700
@@ -1058,7 +1058,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;
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeDisassembler.java	Mon Jul 14 17:06:32 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;
                     }
                 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Mon Jul 14 17:06:32 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)) {
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java	Mon Jul 14 17:06:32 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);
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java	Mon Jul 14 17:06:32 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);
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopEx.java	Mon Jul 14 17:06:32 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();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DirectCallTargetNode.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DirectCallTargetNode.java	Mon Jul 14 17:06:32 2014 -0700
@@ -36,6 +36,6 @@
 
     @Override
     public String targetName() {
-        return MetaUtil.format("Direct#%h.%n", target());
+        return target().format("Direct#%h.%n");
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardPhiNode.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardPhiNode.java	Mon Jul 14 17:06:32 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 {
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IndirectCallTargetNode.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IndirectCallTargetNode.java	Mon Jul 14 17:06:32 2014 -0700
@@ -43,6 +43,6 @@
 
     @Override
     public String targetName() {
-        return MetaUtil.format("Indirect#%h.%n", target());
+        return target().format("Indirect#%h.%n");
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java	Mon Jul 14 17:06:32 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 {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java	Mon Jul 14 17:06:32 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<ValueNode> 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<ValueNode> 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());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValuePhiNode.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValuePhiNode.java	Mon Jul 14 17:06:32 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<ValueNode> values;
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java	Mon Jul 14 17:06:32 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.0f == 0.0f
+                    if (Double.compare(y.asDouble(), -0.0) == 0) {
+                        return forX;
+                    }
+                    break;
+                default:
+                    throw GraalGraphInternalError.shouldNotReachHere();
+            }
+        }
         return this;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java	Mon Jul 14 17:06:32 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;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java	Mon Jul 14 17:06:32 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;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java	Mon Jul 14 17:06:32 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.0f == 0.0f
+                    if (Double.compare(y.asDouble(), 0.0) == 0) {
+                        return forX;
+                    }
+                    break;
+                default:
+                    throw GraalGraphInternalError.shouldNotReachHere();
+            }
+        }
         return this;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Mon Jul 14 17:06:32 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) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/MacroSubstitution.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/MacroSubstitution.java	Mon Jul 14 17:06:32 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.
      * <p>
      * 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.
      */
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Mon Jul 14 17:06:32 2014 -0700
@@ -174,7 +174,7 @@
         }
 
         ValueNode singleValue = phiNode.singleValue();
-        if (singleValue != null) {
+        if (singleValue != PhiNode.NO_VALUE) {
             Collection<PhiNode> phiUsages = phiNode.usages().filter(PhiNode.class).snapshot();
             Collection<ProxyNode> proxyUsages = phiNode.usages().filter(ProxyNode.class).snapshot();
             phiNode.graph().replaceFloating(phiNode, singleValue);
@@ -343,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;
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java	Mon Jul 14 17:06:32 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));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java	Mon Jul 14 17:06:32 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);
         }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReductionPhase.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/FlowSensitiveReductionPhase.java	Mon Jul 14 17:06:32 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");
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Mon Jul 14 17:06:32 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();
     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AssumptionInlineInfo.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AssumptionInlineInfo.java	Mon Jul 14 17:06:32 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");
     }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/ExactInlineInfo.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/ExactInlineInfo.java	Mon Jul 14 17:06:32 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
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Mon Jul 14 17:06:32 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());
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/TypeGuardInlineInfo.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/TypeGuardInlineInfo.java	Mon Jul 14 17:06:32 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() {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderExplorable.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderExplorable.java	Mon Jul 14 17:06:32 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()) : "<null method>") + remainingInvokes;
+        return (graph != null ? method().format("%H.%n(%p)") : "<null method>") + remainingInvokes;
     }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/MethodInvocation.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/MethodInvocation.java	Mon Jul 14 17:06:32 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();
         }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyDebugUsage.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyDebugUsage.java	Mon Jul 14 17:06:32 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)")));
                                     }
                                 }
                             }
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java	Mon Jul 14 17:06:32 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;
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java	Mon Jul 14 17:06:32 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");
     }
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java	Mon Jul 14 17:06:32 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
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java	Mon Jul 14 17:06:32 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;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Mon Jul 14 17:06:32 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) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationVerificationPhase.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationVerificationPhase.java	Mon Jul 14 17:06:32 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");
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Mon Jul 14 17:06:32 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();
     }
 
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Mon Jul 14 17:06:32 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;
             }
@@ -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;
     }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Mon Jul 14 17:06:32 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;
     }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Mon Jul 14 17:06:32 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('$');
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Mon Jul 14 17:06:32 2014 -0700
@@ -91,6 +91,8 @@
     public static final OptionValue<Boolean> TruffleCompilationDecisionTimePrintFail = new OptionValue<>(false);
     @Option(help = "")
     public static final OptionValue<Boolean> TruffleReturnTypeSpeculation = new OptionValue<>(true);
+    @Option(help = "")
+    public static final OptionValue<Boolean> TruffleArgumentTypeSpeculation = new StableOptionValue<>(true);
 
     // tracing
     @Option(help = "")
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java	Mon Jul 14 17:06:32 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)>");
     }
 }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java	Mon Jul 14 17:06:32 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;
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java	Mon Jul 14 17:06:32 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;
         }
     }
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Mon Jul 14 17:06:32 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<? extends Node> from = getClass();
-        Class<? extends Node> 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<? extends Node> 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<Node> getChildren() {
-        final Node node = this;
         return new Iterable<Node>() {
-
             public Iterator<Node> iterator() {
-                return new NodeUtil.NodeIterator(node);
+                return NodeUtil.makeIterator(Node.this);
             }
         };
     }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java	Mon Jul 14 17:06:32 2014 -0700
@@ -157,8 +157,14 @@
      * every subclass of {@link Node} that is used.
      */
     public static final class NodeClass {
-
-        private static final Map<Class<?>, NodeClass> nodeClasses = new IdentityHashMap<>();
+        private static final ClassValue<NodeClass> nodeClasses = new ClassValue<NodeClass>() {
+            @SuppressWarnings("unchecked")
+            @Override
+            protected NodeClass computeValue(Class<?> clazz) {
+                assert Node.class.isAssignableFrom(clazz);
+                return new NodeClass((Class<? extends Node>) 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<? extends Node> clazz;
 
         public static NodeClass get(Class<? extends Node> 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<? extends Node> 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<Node> {
-
-        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<Node> 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<Node> {
+            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<Node> makeIterator(Node node) {
+        return NodeClass.get(node.getClass()).makeIterator(node);
     }
 
     private static long[] toLongArray(List<Long> list) {
@@ -542,15 +543,12 @@
         return null;
     }
 
-    public static <T extends Node> List<T> findAllNodeInstances(final Node root, final Class<T> clazz) {
+    public static <T> List<T> findAllNodeInstances(final Node root, final Class<T> clazz) {
         final List<T> 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 <T extends Node> List<T> findNodeInstancesShallow(final Node root, final Class<T> clazz) {
-        final List<T> 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 <T extends Node> List<T> findNodeInstancesInFunction(final Node root, final Class<T> clazz) {
+    /**
+     * Like {@link #findAllNodeInstances(Node, Class)} but do not visit children of found nodes.
+     */
+    public static <T> List<T> findNodeInstancesShallow(final Node root, final Class<T> clazz) {
         final List<T> 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 <I> List<I> findNodeInstancesInFunctionInterface(final Node root, final Class<I> clazz) {
-        final List<I> 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;
@@ -894,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<? extends Node> from = oldNode.getClass();
+        Class<? extends Node> 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<? extends Node> from, String filter) {
+        Class<?> currentFrom = from;
+        while (currentFrom != null) {
+            if (currentFrom.getName().contains(filter)) {
+                return false;
+            }
+            currentFrom = currentFrom.getSuperclass();
+        }
+        return true;
+    }
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/JSONHelper.java	Mon Jul 14 16:51:41 2014 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/JSONHelper.java	Mon Jul 14 17:06:32 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<String, Object> 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<Object> 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;
         }
--- a/mx/mx_graal.py	Mon Jul 14 16:51:41 2014 -0700
+++ b/mx/mx_graal.py	Mon Jul 14 17:06:32 2014 -0700
@@ -2055,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
--- a/mx/projects	Mon Jul 14 16:51:41 2014 -0700
+++ b/mx/projects	Mon Jul 14 17:06:32 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
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Mon Jul 14 16:51:41 2014 -0700
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Mon Jul 14 17:06:32 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);