changeset 9107:368ed6c6a02b

Merge
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Sat, 13 Apr 2013 22:16:04 +0200
parents 0c8ec85fa013 3495149b9531
children b78686983a75 23c96de53386
files
diffstat 14 files changed, 499 insertions(+), 210 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Sat Apr 13 00:33:37 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Sat Apr 13 22:16:04 2013 +0200
@@ -47,6 +47,17 @@
     }
 
     /**
+     * Calls {@link JavaType#resolve(ResolvedJavaType)} on an array of types.
+     */
+    public static ResolvedJavaType[] resolveJavaTypes(JavaType[] types, ResolvedJavaType accessingClass) {
+        ResolvedJavaType[] result = new ResolvedJavaType[types.length];
+        for (int i = 0; i < result.length; i++) {
+            result[i] = types[i].resolve(accessingClass);
+        }
+        return result;
+    }
+
+    /**
      * Calls {@link MetaAccessProvider#lookupJavaType(Class)} on an array of classes.
      */
     public static ResolvedJavaType[] lookupJavaTypes(MetaAccessProvider metaAccess, Class[] classes) {
@@ -58,54 +69,6 @@
     }
 
     /**
-     * Gets the {@link Class} mirror for a given resolved type.
-     * 
-     * @param type the type for which the Java mirror is requested
-     * @param loader class loader from which the class must be loaded (null means use the class
-     *            loader of the {@link MetaUtil} class)
-     * @return the mirror for {@code type}
-     * @throws NoClassDefFoundError if the mirror is not available
-     */
-    public static Class getMirrorOrFail(ResolvedJavaType type, ClassLoader loader) throws NoClassDefFoundError {
-        ResolvedJavaType elementalType = getElementalType(type);
-        Class elementalClass;
-        if (elementalType.isPrimitive()) {
-            elementalClass = elementalType.getKind().toJavaClass();
-        } else {
-            try {
-                elementalClass = Class.forName(toJavaName(elementalType), true, loader);
-            } catch (ClassNotFoundException e) {
-                throw (NoClassDefFoundError) new NoClassDefFoundError().initCause(e);
-            }
-        }
-        if (type.isArray()) {
-            ResolvedJavaType t = type;
-            while (t.getComponentType() != null) {
-                elementalClass = Array.newInstance(elementalClass, 0).getClass();
-                t = t.getComponentType();
-            }
-        }
-        assert elementalClass != null : toJavaName(type);
-        return elementalClass;
-    }
-
-    /**
-     * Gets the {@link Class} mirror for a given resolved type.
-     * 
-     * @param type the type for which the Java mirror is requested
-     * @param loader class loader from which the class must be loaded (null means use the class
-     *            loader of the {@link MetaUtil} class)
-     * @return the mirror for {@code type} or null if it is not available
-     */
-    public static Class getMirror(ResolvedJavaType type, ClassLoader loader) {
-        try {
-            return getMirrorOrFail(type, loader);
-        } catch (NoClassDefFoundError e) {
-            return null;
-        }
-    }
-
-    /**
      * 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.
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java	Sat Apr 13 00:33:37 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java	Sat Apr 13 22:16:04 2013 +0200
@@ -180,4 +180,26 @@
      * Returns the localvariable table of this method.
      */
     LocalVariableTable getLocalVariableTable();
+
+    /**
+     * Invokes the underlying method represented by this object, on the specified object with the
+     * specified parameters. This method is similar to a reflective method invocation by
+     * {@link Method#invoke}.
+     * 
+     * @param receiver The receiver for the invocation, or {@code null} if it is a static method.
+     * @param arguments The arguments for the invocation.
+     * @return The value returned by the method invocation, or {@code null} if the return type is
+     *         {@code void}.
+     */
+    Constant invoke(Constant receiver, Constant[] arguments);
+
+    /**
+     * Uses the constructor represented by this object to create and initialize a new instance of
+     * the constructor's declaring class, with the specified initialization parameters. This method
+     * is similar to a reflective instantiation by {@link Constructor#newInstance}.
+     * 
+     * @param arguments The arguments for the constructor.
+     * @return The newly created and initialized object.
+     */
+    Constant newInstance(Constant[] arguments);
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Sat Apr 13 00:33:37 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Sat Apr 13 22:16:04 2013 +0200
@@ -274,4 +274,22 @@
      * Returns the enclosing type of this type, if it exists, or {@code null}.
      */
     ResolvedJavaType getEnclosingType();
+
+    /**
+     * Returns an array reflecting all the constructors declared by this type. This method is
+     * similar to {@link Class#getDeclaredConstructors()} in terms of returned constructors.
+     */
+    ResolvedJavaMethod[] getDeclaredConstructors();
+
+    /**
+     * Returns an array reflecting all the methods declared by this type. This method is similar to
+     * {@link Class#getDeclaredMethods()} in terms of returned methods.
+     */
+    ResolvedJavaMethod[] getDeclaredMethods();
+
+    /**
+     * Creates a new array with this type as the component type and the specified length. This
+     * method is similar to {@link Array#newInstance(Class, int)}.
+     */
+    Constant newArray(int length);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug.test/src/com/oracle/graal/debug/test/DebugHistogramTest.java	Sat Apr 13 22:16:04 2013 +0200
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug.test;
+
+import java.io.*;
+
+import org.junit.*;
+
+import com.oracle.graal.debug.*;
+
+public class DebugHistogramTest {
+
+    @Test
+    public void testEmptyHistogram() {
+        DebugHistogram histogram = Debug.createHistogram("TestHistogram");
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        histogram.print(new PrintStream(outputStream));
+        Assert.assertEquals("TestHistogram is empty.\n", outputStream.toString());
+    }
+
+    @Test
+    public void testSingleEntryHistogram() {
+        DebugHistogram histogram = Debug.createHistogram("TestHistogram");
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        histogram.add(new Integer(1));
+        histogram.add(new Integer(1));
+        histogram.print(new PrintStream(outputStream));
+        String[] lines = outputStream.toString().split("\n");
+        Assert.assertEquals(4, lines.length);
+        Assert.assertEquals("TestHistogram has 1 unique elements and 2 total elements:", lines[0]);
+        Assert.assertEquals(
+                        "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
+                        lines[1]);
+        Assert.assertEquals(
+                        "| 1                                                  | 2          | ==================================================================================================== |",
+                        lines[2]);
+        Assert.assertEquals(
+                        "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
+                        lines[3]);
+    }
+
+    @Test
+    public void testMultipleEntryHistogram() {
+        DebugHistogram histogram = Debug.createHistogram("TestHistogram");
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        histogram.add(new Integer(1));
+        histogram.add(new Integer(2));
+        histogram.add(new Integer(2));
+        histogram.print(new PrintStream(outputStream));
+        String[] lines = outputStream.toString().split("\n");
+        Assert.assertEquals(5, lines.length);
+        Assert.assertEquals("TestHistogram has 2 unique elements and 3 total elements:", lines[0]);
+        Assert.assertEquals(
+                        "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
+                        lines[1]);
+        Assert.assertEquals(
+                        "| 2                                                  | 2          | ==================================================================================================== |",
+                        lines[2]);
+        Assert.assertEquals(
+                        "| 1                                                  | 1          | ==================================================                                                   |",
+                        lines[3]);
+        Assert.assertEquals(
+                        "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------",
+                        lines[4]);
+    }
+
+    @Test
+    public void testTooLongValueString() {
+        DebugHistogram histogram = Debug.createHistogram("TestHistogram");
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        histogram.add("MyCustomValue");
+        histogram.print(new PrintStream(outputStream), Integer.MAX_VALUE, 10, 10);
+        String[] lines = outputStream.toString().split("\n");
+        Assert.assertEquals(4, lines.length);
+        Assert.assertEquals("TestHistogram has 1 unique elements and 1 total elements:", lines[0]);
+        Assert.assertEquals("----------------------------------------", lines[1]);
+        Assert.assertEquals("| MyCusto... | 1          | ========== |", lines[2]);
+        Assert.assertEquals("----------------------------------------", lines[3]);
+    }
+}
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Sat Apr 13 00:33:37 2013 +0200
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Sat Apr 13 22:16:04 2013 +0200
@@ -189,6 +189,10 @@
         }
     }
 
+    public static DebugHistogram createHistogram(String name) {
+        return new DebugHistogramImpl(name);
+    }
+
     public static DebugConfig fixedConfig(final boolean isLogEnabled, final boolean isDumpEnabled, final boolean isMeterEnabled, final boolean isTimerEnabled,
                     final Collection<DebugDumpHandler> dumpHandlers, final PrintStream output) {
         return new DebugConfig() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugHistogram.java	Sat Apr 13 22:16:04 2013 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug;
+
+import java.io.*;
+
+public interface DebugHistogram {
+
+    String getName();
+
+    void add(Object value);
+
+    void print(PrintStream os);
+
+    void print(PrintStream os, int limit, int nameSize, int barSize);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramImpl.java	Sat Apr 13 22:16:04 2013 +0200
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.debug.internal;
+
+import java.io.*;
+import java.util.*;
+
+import com.oracle.graal.debug.*;
+
+public class DebugHistogramImpl implements DebugHistogram {
+
+    public static final int NumberSize = 10;
+    public static final int DefaultNameSize = 50;
+    public static final int DefaultBarSize = 100;
+    private final String name;
+    private HashMap<Object, Integer> map = new HashMap<>();
+
+    public DebugHistogramImpl(String name) {
+        this.name = name;
+    }
+
+    public void add(Object value) {
+        if (!map.containsKey(value)) {
+            map.put(value, 1);
+        } else {
+            map.put(value, map.get(value) + 1);
+        }
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void print(PrintStream os) {
+        print(os, Integer.MAX_VALUE, DefaultNameSize, DefaultBarSize);
+    }
+
+    public void print(PrintStream os, int limit, int nameSize, int barSize) {
+
+        List<Object> list = new ArrayList<>(map.keySet());
+        if (list.size() == 0) {
+            // No elements in the histogram.
+            os.printf("%s is empty.\n", name);
+            return;
+        }
+
+        // Sort from highest to smallest.
+        Collections.sort(list, new Comparator<Object>() {
+
+            @Override
+            public int compare(Object o1, Object o2) {
+                return map.get(o2) - map.get(o1);
+            }
+        });
+
+        // Sum up the total number of elements.
+        int total = 0;
+        for (Object o : list) {
+            total += map.get(o);
+        }
+
+        // Print header.
+        os.printf("%s has %d unique elements and %d total elements:\n", name, list.size(), total);
+
+        int max = map.get(list.get(0));
+        final int lineSize = nameSize + NumberSize + barSize + 10;
+        printLine(os, '-', lineSize);
+        String formatString = "| %-" + nameSize + "s | %-" + NumberSize + "d | %-" + barSize + "s |\n";
+        for (int i = 0; i < list.size() && i < limit; ++i) {
+            Object o = list.get(i);
+            int value = map.get(o);
+            char[] bar = new char[(int) (((double) value / (double) max) * barSize)];
+            Arrays.fill(bar, '=');
+            String objectString = o.toString();
+            if (objectString.length() > nameSize) {
+                objectString = objectString.substring(0, nameSize - 3) + "...";
+            }
+            os.printf(formatString, objectString, value, new String(bar));
+        }
+        printLine(os, '-', lineSize);
+    }
+
+    private static void printLine(PrintStream printStream, char c, int lineSize) {
+        char[] charArr = new char[lineSize];
+        Arrays.fill(charArr, c);
+        printStream.printf("%s\n", new String(charArr));
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Sat Apr 13 00:33:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Sat Apr 13 22:16:04 2013 +0200
@@ -367,4 +367,46 @@
         HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig();
         return unsafe.getByte(metaspaceMethod + config.methodIntrinsicIdOffset) & 0xff;
     }
+
+    @Override
+    public Constant invoke(Constant receiver, Constant[] arguments) {
+        assert !isConstructor();
+        Method javaMethod = toJava();
+        javaMethod.setAccessible(true);
+
+        Object[] objArguments = new Object[arguments.length];
+        for (int i = 0; i < arguments.length; i++) {
+            objArguments[i] = arguments[i].asBoxedValue();
+        }
+        Object objReceiver = receiver != null ? receiver.asObject() : null;
+
+        try {
+            Object objResult = javaMethod.invoke(objReceiver, objArguments);
+            return javaMethod.getReturnType() == void.class ? null : Constant.forBoxed(getSignature().getReturnKind(), objResult);
+
+        } catch (IllegalAccessException | InvocationTargetException ex) {
+            throw new IllegalArgumentException(ex);
+        }
+    }
+
+    @Override
+    public Constant newInstance(Constant[] arguments) {
+        assert isConstructor();
+        Constructor javaConstructor = toJavaConstructor();
+        javaConstructor.setAccessible(true);
+
+        Object[] objArguments = new Object[arguments.length];
+        for (int i = 0; i < arguments.length; i++) {
+            objArguments[i] = arguments[i].asBoxedValue();
+        }
+
+        try {
+            Object objResult = javaConstructor.newInstance(objArguments);
+            assert objResult != null;
+            return Constant.forObject(objResult);
+
+        } catch (IllegalAccessException | InvocationTargetException | InstantiationException ex) {
+            throw new IllegalArgumentException(ex);
+        }
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Sat Apr 13 00:33:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Sat Apr 13 22:16:04 2013 +0200
@@ -519,4 +519,31 @@
         final Class<?> encl = mirror().getEnclosingClass();
         return encl == null ? null : fromClass(encl);
     }
+
+    @Override
+    public ResolvedJavaMethod[] getDeclaredConstructors() {
+        Constructor[] constructors = javaMirror.getDeclaredConstructors();
+        ResolvedJavaMethod[] result = new ResolvedJavaMethod[constructors.length];
+        for (int i = 0; i < constructors.length; i++) {
+            result[i] = HotSpotGraalRuntime.getInstance().getRuntime().lookupJavaConstructor(constructors[i]);
+            assert result[i].isConstructor();
+        }
+        return result;
+    }
+
+    @Override
+    public ResolvedJavaMethod[] getDeclaredMethods() {
+        Method[] methods = javaMirror.getDeclaredMethods();
+        ResolvedJavaMethod[] result = new ResolvedJavaMethod[methods.length];
+        for (int i = 0; i < methods.length; i++) {
+            result[i] = HotSpotGraalRuntime.getInstance().getRuntime().lookupJavaMethod(methods[i]);
+            assert !result[i].isConstructor();
+        }
+        return result;
+    }
+
+    @Override
+    public Constant newArray(int length) {
+        return Constant.forObject(Array.newInstance(javaMirror, length));
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Sat Apr 13 00:33:37 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Sat Apr 13 22:16:04 2013 +0200
@@ -210,4 +210,19 @@
     public ResolvedJavaType getEnclosingType() {
         return null;
     }
+
+    @Override
+    public ResolvedJavaMethod[] getDeclaredConstructors() {
+        return new ResolvedJavaMethod[0];
+    }
+
+    @Override
+    public ResolvedJavaMethod[] getDeclaredMethods() {
+        return new ResolvedJavaMethod[0];
+    }
+
+    @Override
+    public Constant newArray(int length) {
+        return Constant.forObject(Array.newInstance(javaMirror, length));
+    }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Sat Apr 13 00:33:37 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Sat Apr 13 22:16:04 2013 +0200
@@ -50,7 +50,7 @@
 
     public interface CustomCanonicalizer {
 
-        ValueNode canonicalize(Node node);
+        ValueNode canonicalize(ValueNode node);
     }
 
     @Override
@@ -187,11 +187,9 @@
 
         public boolean tryCanonicalize(final Node node, final StructuredGraph graph) {
             boolean result = baseTryCanonicalize(node, graph);
-            if (!result && customCanonicalizer != null) {
-                ValueNode canonical = customCanonicalizer.canonicalize(node);
-                if (canonical == node && customCanonicalizer != null) {
-                    canonical = customCanonicalizer.canonicalize(node);
-                }
+            if (!result && customCanonicalizer != null && node instanceof ValueNode) {
+                ValueNode valueNode = (ValueNode) node;
+                ValueNode canonical = customCanonicalizer.canonicalize(valueNode);
                 result = performReplacement(node, graph, canonical);
             }
             return result;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Sat Apr 13 00:33:37 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Sat Apr 13 22:16:04 2013 +0200
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.replacements;
 
-import static com.oracle.graal.api.meta.MetaUtil.*;
-
 import java.lang.reflect.*;
 import java.util.*;
 
@@ -67,41 +65,26 @@
         }
     }
 
-    public static Class<?>[] signatureToTypes(Signature signature, JavaType receiverType, ResolvedJavaType accessingClass) {
-        int count = signature.getParameterCount(receiverType != null);
-        Class<?>[] result = new Class<?>[count];
-        int j = 0;
-        if (receiverType != null) {
-            result[0] = getMirrorOrFail(receiverType.resolve(accessingClass), Thread.currentThread().getContextClassLoader());
-            j = 1;
-        }
-        for (int i = 0; i + j < result.length; ++i) {
-            result[i + j] = getMirrorOrFail(signature.getParameterType(i, accessingClass).resolve(accessingClass), Thread.currentThread().getContextClassLoader());
-        }
-        return result;
-    }
-
     private boolean tryIntrinsify(Invoke invoke, List<Node> cleanUpReturnList) {
         ResolvedJavaMethod target = invoke.methodCallTarget().targetMethod();
         NodeIntrinsic intrinsic = target.getAnnotation(Node.NodeIntrinsic.class);
         ResolvedJavaType declaringClass = target.getDeclaringClass();
-        JavaType receiverType = invoke.methodCallTarget().isStatic() ? null : declaringClass;
         if (intrinsic != null) {
             assert target.getAnnotation(Fold.class) == null;
+            assert Modifier.isStatic(target.getModifiers()) : "node intrinsic must be static: " + target;
 
-            // TODO mjj non-static intrinsic?
-            Class<?>[] parameterTypes = signatureToTypes(target.getSignature(), null, declaringClass);
+            ResolvedJavaType[] parameterTypes = MetaUtil.resolveJavaTypes(MetaUtil.signatureToTypes(target), declaringClass);
             ResolvedJavaType returnType = target.getSignature().getReturnType(declaringClass).resolve(declaringClass);
 
             // Prepare the arguments for the reflective constructor call on the node class.
-            Object[] nodeConstructorArguments = prepareArguments(invoke, parameterTypes, target, false);
+            Constant[] nodeConstructorArguments = prepareArguments(invoke, parameterTypes, target, false);
             if (nodeConstructorArguments == null) {
                 return false;
             }
 
             // Create the new node instance.
-            Class<?> c = getNodeClass(target, intrinsic);
-            Node newInstance = createNodeInstance(runtime, c, parameterTypes, returnType, intrinsic.setStampFromReturnType(), nodeConstructorArguments);
+            ResolvedJavaType c = getNodeClass(target, intrinsic);
+            Node newInstance = createNodeInstance(c, parameterTypes, returnType, intrinsic.setStampFromReturnType(), nodeConstructorArguments);
 
             // Replace the invoke with the new node.
             invoke.asNode().graph().add(newInstance);
@@ -110,23 +93,22 @@
             // Clean up checkcast instructions inserted by javac if the return type is generic.
             cleanUpReturnList.add(newInstance);
         } else if (target.getAnnotation(Fold.class) != null) {
-            Class<?>[] parameterTypes = signatureToTypes(target.getSignature(), receiverType, declaringClass);
+            ResolvedJavaType[] parameterTypes = MetaUtil.resolveJavaTypes(MetaUtil.signatureToTypes(target), declaringClass);
 
             // Prepare the arguments for the reflective method call
-            Object[] arguments = prepareArguments(invoke, parameterTypes, target, true);
+            Constant[] arguments = prepareArguments(invoke, parameterTypes, target, true);
             if (arguments == null) {
                 return false;
             }
-            Object receiver = null;
+            Constant receiver = null;
             if (!invoke.methodCallTarget().isStatic()) {
                 receiver = arguments[0];
-                arguments = Arrays.asList(arguments).subList(1, arguments.length).toArray();
-                parameterTypes = Arrays.asList(parameterTypes).subList(1, parameterTypes.length).toArray(new Class<?>[parameterTypes.length - 1]);
+                arguments = Arrays.copyOfRange(arguments, 1, arguments.length);
+                parameterTypes = Arrays.copyOfRange(parameterTypes, 1, parameterTypes.length);
             }
 
             // Call the method
-            Constant constant = callMethod(target.getSignature().getReturnKind(), getMirrorOrFail(declaringClass, Thread.currentThread().getContextClassLoader()), target.getName(), parameterTypes,
-                            receiver, arguments);
+            Constant constant = target.invoke(receiver, arguments);
 
             if (constant != null) {
                 // Replace the invoke with the result of the call
@@ -151,9 +133,9 @@
      * @return the arguments for the reflective invocation or null if an argument of {@code invoke}
      *         that is expected to be constant isn't
      */
-    private Object[] prepareArguments(Invoke invoke, Class<?>[] parameterTypes, ResolvedJavaMethod target, boolean folding) {
+    private Constant[] prepareArguments(Invoke invoke, ResolvedJavaType[] parameterTypes, ResolvedJavaMethod target, boolean folding) {
         NodeInputList<ValueNode> arguments = invoke.callTarget().arguments();
-        Object[] reflectionCallArguments = new Object[arguments.size()];
+        Constant[] reflectionCallArguments = new Constant[arguments.size()];
         for (int i = 0; i < reflectionCallArguments.length; ++i) {
             int parameterIndex = i;
             if (!invoke.methodCallTarget().isStatic()) {
@@ -168,130 +150,63 @@
                 Constant constant = constantNode.asConstant();
                 Object o = constant.asBoxedValue();
                 if (o instanceof Class<?>) {
-                    reflectionCallArguments[i] = runtime.lookupJavaType((Class<?>) o);
-                    parameterTypes[i] = ResolvedJavaType.class;
+                    reflectionCallArguments[i] = Constant.forObject(runtime.lookupJavaType((Class<?>) o));
+                    parameterTypes[i] = runtime.lookupJavaType(ResolvedJavaType.class);
                 } else {
-                    if (parameterTypes[i] == boolean.class) {
-                        reflectionCallArguments[i] = Boolean.valueOf(constant.asInt() != 0);
-                    } else if (parameterTypes[i] == byte.class) {
-                        reflectionCallArguments[i] = Byte.valueOf((byte) constant.asInt());
-                    } else if (parameterTypes[i] == short.class) {
-                        reflectionCallArguments[i] = Short.valueOf((short) constant.asInt());
-                    } else if (parameterTypes[i] == char.class) {
-                        reflectionCallArguments[i] = Character.valueOf((char) constant.asInt());
+                    if (parameterTypes[i].getKind() == Kind.Boolean) {
+                        reflectionCallArguments[i] = Constant.forObject(Boolean.valueOf(constant.asInt() != 0));
+                    } else if (parameterTypes[i].getKind() == Kind.Byte) {
+                        reflectionCallArguments[i] = Constant.forObject(Byte.valueOf((byte) constant.asInt()));
+                    } else if (parameterTypes[i].getKind() == Kind.Short) {
+                        reflectionCallArguments[i] = Constant.forObject(Short.valueOf((short) constant.asInt()));
+                    } else if (parameterTypes[i].getKind() == Kind.Char) {
+                        reflectionCallArguments[i] = Constant.forObject(Character.valueOf((char) constant.asInt()));
                     } else {
-                        reflectionCallArguments[i] = o;
+                        reflectionCallArguments[i] = constant;
                     }
                 }
             } else {
-                reflectionCallArguments[i] = argument;
-                parameterTypes[i] = ValueNode.class;
+                reflectionCallArguments[i] = Constant.forObject(argument);
+                parameterTypes[i] = runtime.lookupJavaType(ValueNode.class);
             }
         }
         return reflectionCallArguments;
     }
 
-    private static Class<?> getNodeClass(ResolvedJavaMethod target, NodeIntrinsic intrinsic) {
-        Class<?> result = intrinsic.value();
-        if (result == NodeIntrinsic.class) {
-            return getMirrorOrFail(target.getDeclaringClass(), Thread.currentThread().getContextClassLoader());
+    private ResolvedJavaType getNodeClass(ResolvedJavaMethod target, NodeIntrinsic intrinsic) {
+        ResolvedJavaType result;
+        if (intrinsic.value() == NodeIntrinsic.class) {
+            result = target.getDeclaringClass();
+        } else {
+            result = runtime.lookupJavaType(intrinsic.value());
         }
-        assert Node.class.isAssignableFrom(result);
+        assert runtime.lookupJavaType(ValueNode.class).isAssignableFrom(result);
         return result;
     }
 
-    private static Class asBoxedType(Class type) {
-        if (!type.isPrimitive()) {
-            return type;
-        }
+    private Node createNodeInstance(ResolvedJavaType nodeClass, ResolvedJavaType[] parameterTypes, ResolvedJavaType returnType, boolean setStampFromReturnType, Constant[] nodeConstructorArguments) {
+        ResolvedJavaMethod constructor = null;
+        Constant[] arguments = null;
 
-        if (Boolean.TYPE == type) {
-            return Boolean.class;
-        }
-        if (Character.TYPE == type) {
-            return Character.class;
-        }
-        if (Byte.TYPE == type) {
-            return Byte.class;
-        }
-        if (Short.TYPE == type) {
-            return Short.class;
-        }
-        if (Integer.TYPE == type) {
-            return Integer.class;
-        }
-        if (Long.TYPE == type) {
-            return Long.class;
-        }
-        if (Float.TYPE == type) {
-            return Float.class;
-        }
-        assert Double.TYPE == type;
-        return Double.class;
-    }
+        for (ResolvedJavaMethod c : nodeClass.getDeclaredConstructors()) {
+            Constant[] match = match(c, parameterTypes, nodeConstructorArguments);
 
-    static final int VARARGS = 0x00000080;
-
-    private static Node createNodeInstance(MetaAccessProvider runtime, Class<?> nodeClass, Class<?>[] parameterTypes, ResolvedJavaType returnType, boolean setStampFromReturnType,
-                    Object[] nodeConstructorArguments) {
-        Object[] arguments = null;
-        Constructor<?> constructor = null;
-        boolean needsMetaAccessProviderArgument = false;
-        nextConstructor: for (Constructor c : nodeClass.getDeclaredConstructors()) {
-            needsMetaAccessProviderArgument = false;
-            Class[] signature = c.getParameterTypes();
-            if (signature.length != 0 && signature[0] == MetaAccessProvider.class) {
-                // Chop off the MetaAccessProvider first parameter
-                signature = Arrays.copyOfRange(signature, 1, signature.length);
-                needsMetaAccessProviderArgument = true;
-            }
-            if ((c.getModifiers() & VARARGS) != 0) {
-                int fixedArgs = signature.length - 1;
-                if (parameterTypes.length < fixedArgs) {
-                    continue nextConstructor;
+            if (match != null) {
+                if (constructor == null) {
+                    constructor = c;
+                    arguments = match;
+                } else {
+                    throw new GraalInternalError("Found multiple constructors in " + nodeClass + " compatible with signature " + Arrays.toString(parameterTypes) + ": " + constructor + ", " + c);
                 }
-
-                for (int i = 0; i < fixedArgs; i++) {
-                    if (!parameterTypes[i].equals(signature[i])) {
-                        continue nextConstructor;
-                    }
-                }
-
-                Class componentType = signature[fixedArgs].getComponentType();
-                assert componentType != null : "expected last parameter of varargs constructor " + c + " to be an array type";
-                Class boxedType = asBoxedType(componentType);
-                for (int i = fixedArgs; i < nodeConstructorArguments.length; i++) {
-                    if (!boxedType.isInstance(nodeConstructorArguments[i])) {
-                        continue nextConstructor;
-                    }
-                }
-                arguments = Arrays.copyOf(nodeConstructorArguments, fixedArgs + 1);
-                int varargsLength = nodeConstructorArguments.length - fixedArgs;
-                Object varargs = Array.newInstance(componentType, varargsLength);
-                for (int i = fixedArgs; i < nodeConstructorArguments.length; i++) {
-                    Array.set(varargs, i - fixedArgs, nodeConstructorArguments[i]);
-                }
-                arguments[fixedArgs] = varargs;
-                constructor = c;
-                break;
-            } else if (Arrays.equals(parameterTypes, signature)) {
-                arguments = nodeConstructorArguments;
-                constructor = c;
-                break;
             }
         }
         if (constructor == null) {
             throw new GraalInternalError("Could not find constructor in " + nodeClass + " compatible with signature " + Arrays.toString(parameterTypes));
         }
-        if (needsMetaAccessProviderArgument) {
-            Object[] copy = new Object[arguments.length + 1];
-            System.arraycopy(arguments, 0, copy, 1, arguments.length);
-            copy[0] = runtime;
-            arguments = copy;
-        }
-        constructor.setAccessible(true);
+
         try {
-            ValueNode intrinsicNode = (ValueNode) constructor.newInstance(arguments);
+            ValueNode intrinsicNode = (ValueNode) constructor.newInstance(arguments).asObject();
+
             if (setStampFromReturnType) {
                 if (returnType.getKind() == Kind.Object) {
                     intrinsicNode.setStamp(StampFactory.declared(returnType));
@@ -305,26 +220,58 @@
         }
     }
 
-    /**
-     * Calls a Java method via reflection.
-     */
-    private static Constant callMethod(Kind returnKind, Class<?> holder, String name, Class<?>[] parameterTypes, Object receiver, Object[] arguments) {
-        Method method;
-        try {
-            method = holder.getDeclaredMethod(name, parameterTypes);
-            method.setAccessible(true);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
+    private Constant[] match(ResolvedJavaMethod c, ResolvedJavaType[] parameterTypes, Constant[] nodeConstructorArguments) {
+        Constant[] arguments = null;
+        boolean needsMetaAccessProviderArgument = false;
+
+        ResolvedJavaType[] signature = MetaUtil.resolveJavaTypes(MetaUtil.signatureToTypes(c.getSignature(), null), c.getDeclaringClass());
+        if (signature.length != 0 && signature[0].equals(runtime.lookupJavaType(MetaAccessProvider.class))) {
+            // Chop off the MetaAccessProvider first parameter
+            signature = Arrays.copyOfRange(signature, 1, signature.length);
+            needsMetaAccessProviderArgument = true;
         }
-        try {
-            Object result = method.invoke(receiver, arguments);
-            if (result == null) {
+
+        if (Arrays.equals(parameterTypes, signature)) {
+            // Exact match
+            arguments = nodeConstructorArguments;
+
+        } else if (signature.length > 0 && signature[signature.length - 1].isArray()) {
+            // Last constructor parameter is an array, so check if we have a vararg match
+            int fixedArgs = signature.length - 1;
+            if (parameterTypes.length < fixedArgs) {
                 return null;
             }
-            return Constant.forBoxed(returnKind, result);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
+            for (int i = 0; i < fixedArgs; i++) {
+                if (!parameterTypes[i].equals(signature[i])) {
+                    return null;
+                }
+            }
+
+            ResolvedJavaType componentType = signature[fixedArgs].getComponentType();
+            assert componentType != null;
+            for (int i = fixedArgs; i < nodeConstructorArguments.length; i++) {
+                if (!parameterTypes[i].equals(componentType)) {
+                    return null;
+                }
+            }
+            arguments = Arrays.copyOf(nodeConstructorArguments, fixedArgs + 1);
+            arguments[fixedArgs] = componentType.newArray(nodeConstructorArguments.length - fixedArgs);
+
+            Object varargs = arguments[fixedArgs].asObject();
+            for (int i = fixedArgs; i < nodeConstructorArguments.length; i++) {
+                Array.set(varargs, i - fixedArgs, nodeConstructorArguments[i].asBoxedValue());
+            }
+        } else {
+            return null;
         }
+
+        if (needsMetaAccessProviderArgument) {
+            Constant[] copy = new Constant[arguments.length + 1];
+            System.arraycopy(arguments, 0, copy, 1, arguments.length);
+            copy[0] = Constant.forObject(runtime);
+            arguments = copy;
+        }
+        return arguments;
     }
 
     private static String sourceLocation(Node n) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Sat Apr 13 00:33:37 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Sat Apr 13 22:16:04 2013 +0200
@@ -60,8 +60,8 @@
     public static class SnippetInfo {
 
         protected final ResolvedJavaMethod method;
-        protected final ConstantParameter[] constantParameters;
-        protected final VarargsParameter[] varargsParameters;
+        protected final boolean[] constantParameters;
+        protected final boolean[] varargsParameters;
 
         /**
          * The parameter names, taken from the local variables table. Only used for assertion
@@ -74,11 +74,11 @@
 
             assert Modifier.isStatic(method.getModifiers()) : "snippet method must be static: " + MetaUtil.format("%H.%n", method);
             int count = method.getSignature().getParameterCount(false);
-            constantParameters = new ConstantParameter[count];
-            varargsParameters = new VarargsParameter[count];
+            constantParameters = new boolean[count];
+            varargsParameters = new boolean[count];
             for (int i = 0; i < count; i++) {
-                constantParameters[i] = MetaUtil.getParameterAnnotation(ConstantParameter.class, i, method);
-                varargsParameters[i] = MetaUtil.getParameterAnnotation(VarargsParameter.class, i, method);
+                constantParameters[i] = MetaUtil.getParameterAnnotation(ConstantParameter.class, i, method) != null;
+                varargsParameters[i] = MetaUtil.getParameterAnnotation(VarargsParameter.class, i, method) != null;
 
                 assert !isConstantParameter(i) || !isVarargsParameter(i) : "Parameter cannot be annotated with both @" + ConstantParameter.class.getSimpleName() + " and @" +
                                 VarargsParameter.class.getSimpleName();
@@ -109,11 +109,11 @@
         }
 
         public boolean isConstantParameter(int paramIdx) {
-            return constantParameters[paramIdx] != null;
+            return constantParameters[paramIdx];
         }
 
         public boolean isVarargsParameter(int paramIdx) {
-            return varargsParameters[paramIdx] != null;
+            return varargsParameters[paramIdx];
         }
     }
 
--- a/mx/projects	Sat Apr 13 00:33:37 2013 +0200
+++ b/mx/projects	Sat Apr 13 22:16:04 2013 +0200
@@ -155,6 +155,13 @@
 project@com.oracle.graal.debug@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.debug@javaCompliance=1.7
 
+# graal.debug.test
+project@com.oracle.graal.debug.test@subDir=graal
+project@com.oracle.graal.debug.test@sourceDirs=src
+project@com.oracle.graal.debug.test@dependencies=JUNIT,com.oracle.graal.debug
+project@com.oracle.graal.debug.test@checkstyle=com.oracle.graal.graph
+project@com.oracle.graal.debug.test@javaCompliance=1.7
+
 # graal.lir
 project@com.oracle.graal.lir@subDir=graal
 project@com.oracle.graal.lir@sourceDirs=src