changeset 7698:5172356ea7c3

Merge.
author Christian Haeubl <haeubl@ssw.jku.at>
date Mon, 04 Feb 2013 17:48:20 +0100
parents e7a85c94502e (current diff) d16336557215 (diff)
children 7af44fbe5095
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ComputeProbabilityPhase.java
diffstat 24 files changed, 290 insertions(+), 184 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Mon Feb 04 17:48:20 2013 +0100
@@ -84,4 +84,13 @@
      * @throws IllegalArgumentException if {@code array} is not an array
      */
     int lookupArrayLength(Constant array);
+
+    /**
+     * Reads a value of this kind using a base address and a displacement.
+     *
+     * @param base the base address from which the value is read
+     * @param displacement the displacement within the object in bytes
+     * @return the read value encapsulated in a {@link Constant} object, or {@code null} if the value cannot be read.
+     */
+    Constant readUnsafeConstant(Kind kind, Object base, long displacement);
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java	Mon Feb 04 17:48:20 2013 +0100
@@ -70,7 +70,7 @@
         ResolvedJavaType elementalType = getElementalType(type);
         Class elementalClass;
         if (elementalType.isPrimitive()) {
-            elementalClass = type.getKind().toJavaClass();
+            elementalClass = elementalType.getKind().toJavaClass();
         } else {
             try {
                 elementalClass = Class.forName(toJavaName(elementalType), true, loader);
@@ -177,7 +177,7 @@
     public static String toJavaName(JavaType type, boolean qualified) {
         Kind kind = type.getKind();
         if (kind == Kind.Object) {
-            return internalNameToJava(type.getName(), qualified);
+            return internalNameToJava(type.getName(), qualified, false);
         }
         return type.getKind().getJavaName();
     }
@@ -196,10 +196,10 @@
      * @return the Java name corresponding to {@code type}
      */
     public static String toJavaName(JavaType type) {
-        return (type == null) ? null : internalNameToJava(type.getName(), true);
+        return (type == null) ? null : internalNameToJava(type.getName(), true, false);
     }
 
-    private static String internalNameToJava(String name, boolean qualified) {
+    private static String internalNameToJava(String name, boolean qualified, boolean classForNameCompatible) {
         switch (name.charAt(0)) {
             case 'L': {
                 String result = name.substring(1, name.length() - 1).replace('/', '.');
@@ -210,10 +210,9 @@
                     }
                 }
                 return result;
-
             }
             case '[':
-                return internalNameToJava(name.substring(1), qualified) + "[]";
+                return classForNameCompatible ? name.replace('/', '.') : internalNameToJava(name.substring(1), qualified, classForNameCompatible) + "[]";
             default:
                 if (name.length() != 1) {
                     throw new IllegalArgumentException("Illegal internal name: " + name);
@@ -223,6 +222,19 @@
     }
 
     /**
+     * Turns an class name in internal format into a resolved Java type.
+     */
+    public static ResolvedJavaType classForName(String internal, MetaAccessProvider metaAccess, ClassLoader cl) {
+        Kind k = Kind.fromTypeString(internal);
+        try {
+            String n = internalNameToJava(internal, true, true);
+            return metaAccess.lookupJavaType(k.isPrimitive() ? k.toJavaClass() : Class.forName(n, true, cl));
+        } catch (ClassNotFoundException cnfe) {
+            throw new IllegalArgumentException("could not instantiate class described by " + internal, cnfe);
+        }
+    }
+
+    /**
      * 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
@@ -503,6 +515,29 @@
     }
 
     /**
+     * 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
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Mon Feb 04 17:48:20 2013 +0100
@@ -26,7 +26,7 @@
 import java.lang.reflect.*;
 
 /**
- * Represents a resolved Java types. Types include primitives, objects, {@code void}, and arrays
+ * Represents a resolved Java type. Types include primitives, objects, {@code void}, and arrays
  * thereof. Types, like fields and methods, are resolved through {@link ConstantPool constant pools}
  * .
  */
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Signature.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Signature.java	Mon Feb 04 17:48:20 2013 +0100
@@ -86,19 +86,4 @@
      * @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
-     */
-    String getMethodDescriptor();
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Mon Feb 04 17:48:20 2013 +0100
@@ -29,7 +29,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.snippets.*;
 
@@ -109,12 +108,12 @@
         if (receiver == null) {
             assert Modifier.isStatic(flags);
             if (holder.isInitialized()) {
-                return ReadNode.readUnsafeConstant(getKind(), holder.mirror(), offset);
+                return HotSpotGraalRuntime.getInstance().getRuntime().readUnsafeConstant(getKind(), holder.mirror(), offset);
             }
             return null;
         } else {
             assert !Modifier.isStatic(flags);
-            return ReadNode.readUnsafeConstant(getKind(), receiver.asObject(), offset);
+            return HotSpotGraalRuntime.getInstance().getRuntime().readUnsafeConstant(getKind(), receiver.asObject(), offset);
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Mon Feb 04 17:48:20 2013 +0100
@@ -52,7 +52,7 @@
     private final HotSpotResolvedObjectType holder;
     private/* final */int codeSize;
     private/* final */int exceptionHandlerCount;
-    private Signature signature;
+    private HotSpotSignature signature;
     private Boolean hasBalancedMonitors;
     private Map<Object, Object> compilerStorage;
     private HotSpotMethodData methodData;
@@ -162,7 +162,7 @@
     }
 
     @Override
-    public Signature getSignature() {
+    public HotSpotSignature getSignature() {
         if (signature == null) {
             signature = new HotSpotSignature(HotSpotGraalRuntime.getInstance().getCompilerToVM().getSignature(metaspaceMethod));
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Mon Feb 04 17:48:20 2013 +0100
@@ -28,6 +28,7 @@
 import static com.oracle.graal.api.code.Register.RegisterFlag.*;
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.api.meta.Value.*;
+import static com.oracle.graal.graph.UnsafeAccess.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.hotspot.snippets.SystemSubstitutions.*;
 import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*;
@@ -916,4 +917,30 @@
         gcRoots.put(object, object);
         return object;
     }
+
+    @Override
+    public Constant readUnsafeConstant(Kind kind, Object base, long displacement) {
+        switch (kind) {
+            case Boolean:
+                return Constant.forBoolean(base == null ? unsafe.getByte(displacement) != 0 : unsafe.getBoolean(base, displacement));
+            case Byte:
+                return Constant.forByte(base == null ? unsafe.getByte(displacement) : unsafe.getByte(base, displacement));
+            case Char:
+                return Constant.forChar(base == null ? unsafe.getChar(displacement) : unsafe.getChar(base, displacement));
+            case Short:
+                return Constant.forShort(base == null ? unsafe.getShort(displacement) : unsafe.getShort(base, displacement));
+            case Int:
+                return Constant.forInt(base == null ? unsafe.getInt(displacement) : unsafe.getInt(base, displacement));
+            case Long:
+                return Constant.forLong(base == null ? unsafe.getLong(displacement) : unsafe.getLong(base, displacement));
+            case Float:
+                return Constant.forFloat(base == null ? unsafe.getFloat(displacement) : unsafe.getFloat(base, displacement));
+            case Double:
+                return Constant.forDouble(base == null ? unsafe.getDouble(displacement) : unsafe.getDouble(base, displacement));
+            case Object:
+                return Constant.forObject(unsafe.getObject(base, displacement));
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Mon Feb 04 17:48:20 2013 +0100
@@ -124,8 +124,8 @@
         return type;
     }
 
-    @Override
     public String getMethodDescriptor() {
+        assert originalString.equals(MetaUtil.signatureToMethodDescriptor(this));
         return originalString;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java	Mon Feb 04 17:48:20 2013 +0100
@@ -58,6 +58,12 @@
         this.location = location;
     }
 
+    public AccessNode(ValueNode object, ValueNode location, Stamp stamp, ValueNode... dependencies) {
+        super(stamp, dependencies);
+        this.object = object;
+        this.location = location;
+    }
+
     @Override
     public Node node() {
         return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Mon Feb 04 17:48:20 2013 +0100
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import static com.oracle.graal.graph.FieldIntrospection.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -42,11 +41,12 @@
         super(object, object.graph().add(new LocationNode(locationIdentity, kind, displacement)), StampFactory.forKind(kind));
     }
 
-    private ReadNode(ValueNode object, ValueNode location) {
-        // Used by node intrinsics. Since the initial value for location is a parameter, i.e., a
-        // LocalNode, the
-        // constructor cannot use the declared type LocationNode
-        this(object, location, StampFactory.forNodeIntrinsic());
+    private ReadNode(ValueNode object, ValueNode location, ValueNode dependency) {
+        /*
+         * Used by node intrinsics. Since the initial value for location is a parameter, i.e., a
+         * LocalNode, the constructor cannot use the declared type LocationNode.
+         */
+        super(object, location, StampFactory.forNodeIntrinsic(), dependency);
     }
 
     @Override
@@ -59,60 +59,27 @@
         return canonicalizeRead(this, tool);
     }
 
-    /**
-     * Utility function for reading a value of this kind using a base address and a displacement.
-     * 
-     * @param base the base address from which the value is read
-     * @param displacement the displacement within the object in bytes
-     * @return the read value encapsulated in a {@link Constant} object
-     */
-    public static Constant readUnsafeConstant(Kind kind, Object base, long displacement) {
-        switch (kind) {
-            case Boolean:
-                return Constant.forBoolean(base == null ? unsafe.getByte(displacement) != 0 : unsafe.getBoolean(base, displacement));
-            case Byte:
-                return Constant.forByte(base == null ? unsafe.getByte(displacement) : unsafe.getByte(base, displacement));
-            case Char:
-                return Constant.forChar(base == null ? unsafe.getChar(displacement) : unsafe.getChar(base, displacement));
-            case Short:
-                return Constant.forShort(base == null ? unsafe.getShort(displacement) : unsafe.getShort(base, displacement));
-            case Int:
-                return Constant.forInt(base == null ? unsafe.getInt(displacement) : unsafe.getInt(base, displacement));
-            case Long:
-                return Constant.forLong(base == null ? unsafe.getLong(displacement) : unsafe.getLong(base, displacement));
-            case Float:
-                return Constant.forFloat(base == null ? unsafe.getFloat(displacement) : unsafe.getFloat(base, displacement));
-            case Double:
-                return Constant.forDouble(base == null ? unsafe.getDouble(displacement) : unsafe.getDouble(base, displacement));
-            case Object:
-                return Constant.forObject(unsafe.getObject(base, displacement));
-            default:
-                throw GraalInternalError.shouldNotReachHere();
-        }
-    }
-
     public static ValueNode canonicalizeRead(Access read, CanonicalizerTool tool) {
         MetaAccessProvider runtime = tool.runtime();
-        if (runtime != null && read.object() != null && read.object().isConstant()/*
-                                                                                   * &&
-                                                                                   * read.object()
-                                                                                   * .kind() ==
-                                                                                   * Kind.Object
-                                                                                   */) {
+        if (runtime != null && read.object() != null && read.object().isConstant()) {
             if (read.location().locationIdentity() == LocationNode.FINAL_LOCATION && read.location().getClass() == LocationNode.class) {
                 long displacement = read.location().displacement();
                 Kind kind = read.location().getValueKind();
                 if (read.object().kind() == Kind.Object) {
                     Object base = read.object().asConstant().asObject();
                     if (base != null) {
-                        Constant constant = readUnsafeConstant(kind, base, displacement);
-                        return ConstantNode.forConstant(constant, runtime, read.node().graph());
+                        Constant constant = tool.runtime().readUnsafeConstant(kind, base, displacement);
+                        if (constant != null) {
+                            return ConstantNode.forConstant(constant, runtime, read.node().graph());
+                        }
                     }
                 } else if (read.object().kind() == Kind.Long || read.object().kind().getStackKind() == Kind.Int) {
                     long base = read.object().asConstant().asLong();
                     if (base != 0L) {
-                        Constant constant = readUnsafeConstant(kind, null, base + displacement);
-                        return ConstantNode.forConstant(constant, runtime, read.node().graph());
+                        Constant constant = tool.runtime().readUnsafeConstant(kind, null, base + displacement);
+                        if (constant != null) {
+                            return ConstantNode.forConstant(constant, runtime, read.node().graph());
+                        }
                     }
                 }
             }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ComputeProbabilityPhase.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ComputeProbabilityPhase.java	Mon Feb 04 17:48:20 2013 +0100
@@ -384,7 +384,7 @@
                         current = getMaxProbabilitySux((ControlSplitNode) current, pathBeginNodes);
                         minPathProbability = getMinPathProbability((FixedNode) current, minPathProbability);
                     } else {
-                        assert current.successors().count() <= 1;
+                        assert current.successors.count() <= 1;
                         current = current.successors().first();
                     }
                 } while (current != null);
@@ -394,7 +394,7 @@
         }
 
         private static double getMinPathProbability(FixedNode current, double minPathProbability) {
-            if (current.probability() < minPathProbability) {
+            if (current != null && current.probability() < minPathProbability) {
                 return current.probability();
             }
             return minPathProbability;
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/ClassSubstitution.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/ClassSubstitution.java	Mon Feb 04 17:48:20 2013 +0100
@@ -77,7 +77,8 @@
         boolean isStatic() default true;
 
         /**
-         * Gets the {@linkplain Signature#getMethodDescriptor() signature} of the original method.
+         * Gets the {@linkplain MetaUtil#signatureToMethodDescriptor 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.
@@ -110,7 +111,7 @@
         boolean isStatic() default true;
 
         /**
-         * Gets the {@linkplain Signature#getMethodDescriptor() signature} of the substituted
+         * Gets the {@linkplain MetaUtil#signatureToMethodDescriptor signature} of the substituted
          * method.
          * <p>
          * If the default value is specified for this element, then the signature of the substituted
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Mon Feb 04 17:48:20 2013 +0100
@@ -284,7 +284,19 @@
     }
 
     public boolean isWord(ValueNode node) {
+        /*
+         * If we already know that we have a word type, we do not need to infer the stamp. This
+         * avoids exceptions in inferStamp when the inputs have already been rewritten to word,
+         * i.e., when the expected input is no longer an object.
+         */
+        if (isWord0(node)) {
+            return true;
+        }
         node.inferStamp();
+        return isWord0(node);
+    }
+
+    private boolean isWord0(ValueNode node) {
         if (node.stamp() == StampFactory.forWord()) {
             return true;
         }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java	Mon Feb 04 17:48:20 2013 +0100
@@ -41,12 +41,12 @@
  * </p>
  * 
  * <p>
- * There are five primitive types for slots available: {@link java.lang.Boolean}, @{link
- * java.lang.Integer}, {@link java.lang.Long}, {@link java.lang.Float}, and {@link java.lang.Double}
- * . It is encouraged to use those types whenever possible. Dynamically typed languages can
- * speculate on the type of a value fitting into a primitive (see
+ * There are five primitive types for slots available: {@link java.lang.Boolean},
+ * {@link java.lang.Integer}, {@link java.lang.Long}, {@link java.lang.Float}, and
+ * {@link java.lang.Double} . It is encouraged to use those types whenever possible. Dynamically
+ * typed languages can speculate on the type of a value fitting into a primitive (see
  * {@link FrameSlotTypeSpecializationTest}). When a frame slot is of one of those particular
- * primitive types, its value may only be accessed with the repectively typed getter method (
+ * primitive types, its value may only be accessed with the respectively typed getter method (
  * {@link Frame#getBoolean}, {@link Frame#getInt}, {@link Frame#getLong}, {@link Frame#getFloat}, or
  * {@link Frame#getDouble}) or setter method ({@link Frame#setBoolean}, {@link Frame#setInt},
  * {@link Frame#setLong}, {@link Frame#setFloat}, or {@link Frame#setDouble}) in the {@link Frame}
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Log.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Log.java	Mon Feb 04 17:48:20 2013 +0100
@@ -33,6 +33,8 @@
  */
 public class Log {
 
+    public static final boolean DEBUG = false;
+
     private final ProcessingEnvironment processingEnv;
 
     public Log(ProcessingEnvironment env) {
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeAnnotationValue.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeAnnotationValue.java	Mon Feb 04 17:48:20 2013 +0100
@@ -31,22 +31,16 @@
 
     private final Object value;
 
-    // @formatter:off
     public CodeAnnotationValue(Object value) {
         Objects.requireNonNull(value);
-        if ((value instanceof AnnotationMirror) || (value instanceof List< ? >)
-                        || (value instanceof Boolean) || (value instanceof Byte)
-                        || (value instanceof Character) || (value instanceof Double)
-                        || (value instanceof VariableElement) || (value instanceof Float)
-                        || (value instanceof Integer) || (value instanceof Long)
-                        || (value instanceof Short) || (value instanceof String)
-                        || (value instanceof TypeMirror)) {
+        if ((value instanceof AnnotationMirror) || (value instanceof List<?>) || (value instanceof Boolean) || (value instanceof Byte) || (value instanceof Character) || (value instanceof Double) ||
+                        (value instanceof VariableElement) || (value instanceof Float) || (value instanceof Integer) || (value instanceof Long) || (value instanceof Short) ||
+                        (value instanceof String) || (value instanceof TypeMirror)) {
             this.value = value;
         } else {
             throw new IllegalArgumentException("Invalid annotation value type " + value.getClass().getName());
         }
     }
-    // @formatter:on
 
     @Override
     public Object getValue() {
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/AbstractCodeWriter.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/AbstractCodeWriter.java	Mon Feb 04 17:48:20 2013 +0100
@@ -434,16 +434,6 @@
         }
     }
 
-    // @Override
-    // public void visitParameter(CodeVariableElement e) {
-    // for (CodeAnnotationMirror annotation : e.getAnnotationMirrors()) {
-    // annotation.accept(this);
-    // }
-    // write(typeSimpleName(e.getType()));
-    // write(" ");
-    // write(e.getSimpleName());
-    // }
-
     @Override
     public Void visitExecutable(CodeExecutableElement e, Void p) {
         for (AnnotationMirror annotation : e.getAnnotationMirrors()) {
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Mon Feb 04 17:48:20 2013 +0100
@@ -653,13 +653,13 @@
             if (specialization.getExceptions().length > 0) {
                 for (SpecializationThrowsData exception : specialization.getExceptions()) {
                     builder.end().startCatchBlock(exception.getJavaClass(), "ex");
-                    buildThrowSpecialize(builder, exception.getTransitionTo(), null);
+                    buildThrowSpecialize(builder, specialization, exception.getTransitionTo(), null);
                 }
                 builder.end();
             }
             if (specialization.hasDynamicGuards()) {
                 builder.end().startElseBlock();
-                buildThrowSpecialize(builder, specialization.findNextSpecialization(), null);
+                buildThrowSpecialize(builder, specialization, specialization.findNextSpecialization(), null);
                 builder.end();
             }
         }
@@ -737,7 +737,7 @@
                         execute = true;
                     }
                 }
-                buildThrowSpecialize(builder, specialization.findNextSpecialization(), param.getSpecification());
+                buildThrowSpecialize(builder, specialization, specialization.findNextSpecialization(), param.getSpecification());
                 builder.end(); // catch block
             }
 
@@ -785,7 +785,7 @@
             }
         }
 
-        private void buildThrowSpecialize(CodeTreeBuilder builder, SpecializationData nextSpecialization, ParameterSpec exceptionSpec) {
+        private void buildThrowSpecialize(CodeTreeBuilder builder, SpecializationData currentSpecialization, SpecializationData nextSpecialization, ParameterSpec exceptionSpec) {
             boolean canThrowUnexpected = Utils.canThrowType(builder.findMethod().getThrownTypes(), getContext().getTruffleTypes().getUnexpectedValueException());
 
             CodeTreeBuilder specializeCall = CodeTreeBuilder.createBuilder();
@@ -795,10 +795,12 @@
             specializeCall.end().end();
 
             if (canThrowUnexpected) {
-                builder.startThrow();
-                builder.startNew(getContext().getTruffleTypes().getUnexpectedValueException());
+                builder.startReturn();
+                TypeData expectedType = currentSpecialization.getReturnType().getActualTypeData(currentSpecialization.getNode().getTypeSystem());
+                startCallTypeSystemMethod(context, builder, currentSpecialization.getNode(), TypeSystemCodeGenerator.expectTypeMethodName(expectedType));
                 builder.tree(specializeCall.getRoot());
                 builder.end().end();
+                builder.end(); // return
             } else {
                 builder.startReturn();
                 builder.tree(specializeCall.getRoot());
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java	Mon Feb 04 17:48:20 2013 +0100
@@ -133,7 +133,8 @@
         } else {
             ExecutableTypeData execType = null;
             for (ExecutableTypeData type : types) {
-                if (!type.getReturnType().getActualTypeData(getTypeSystem()).isVoid()) {
+                TypeData returnType = type.getReturnType().getActualTypeData(getTypeSystem());
+                if (!returnType.isVoid()) {
                     if (execType != null) {
                         // multiple generic types not allowed
                         return null;
@@ -280,25 +281,12 @@
         return specializations;
     }
 
-    // @formatter:off
     public String dump() {
         StringBuilder b = new StringBuilder();
-        b.append(String.format("[name = %s\n" +
-                        "  typeSystem = %s\n" +
-                        "  fields = %s\n" +
-                        "  types = %s\n" +
-                        "  specializations = %s\n" +
-                        "  guards = %s\n" +
-                        "]", Utils.getQualifiedName(getTemplateType()),
-                            getTypeSystem(),
-                            dumpList(fields),
-                            dumpList(getExecutableTypes()),
-                            dumpList(getSpecializations()),
-                            dumpList(guards)
-                        ));
+        b.append(String.format("[name = %s\n" + "  typeSystem = %s\n" + "  fields = %s\n" + "  types = %s\n" + "  specializations = %s\n" + "  guards = %s\n" + "]",
+                        Utils.getQualifiedName(getTemplateType()), getTypeSystem(), dumpList(fields), dumpList(getExecutableTypes()), dumpList(getSpecializations()), dumpList(guards)));
         return b.toString();
     }
-    // @formatter:on
 
     private static String dumpList(Object[] array) {
         if (array == null) {
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java	Mon Feb 04 17:48:20 2013 +0100
@@ -44,8 +44,6 @@
     public static final List<Class<? extends Annotation>> ANNOTATIONS = Arrays.asList(Generic.class, GuardCheck.class, TypeSystemReference.class, ShortCircuit.class, Specialization.class,
                     SpecializationGuard.class, SpecializationListener.class, SpecializationThrows.class);
 
-    private static final boolean DEBUG = false;
-
     private Map<String, NodeData> parsedNodes;
     private TypeElement originalType;
 
@@ -62,7 +60,7 @@
 
             return parseInnerClassHierarchy((TypeElement) element);
         } finally {
-            if (DEBUG) {
+            if (Log.DEBUG) {
                 NodeData parsed = parsedNodes.get(Utils.getQualifiedName(originalType));
                 if (parsed != null) {
                     String dump = parsed.dump();
@@ -149,7 +147,7 @@
         nodeData.setExecutableTypes(executableTypes.toArray(new ExecutableTypeData[executableTypes.size()]));
 
         parsedNodes.put(Utils.getQualifiedName(type), nodeData); // node fields will resolve node
-                                                                 // types, to avoid endless loops
+// types, to avoid endless loops
 
         NodeFieldData[] fields = parseFields(nodeData, elements, typeHierarchy);
         if (fields == null) {
@@ -319,6 +317,19 @@
                 filteredExecutableTypes.add(t1);
             }
         }
+
+        Collections.sort(filteredExecutableTypes, new Comparator<ExecutableTypeData>() {
+
+            @Override
+            public int compare(ExecutableTypeData o1, ExecutableTypeData o2) {
+                int index1 = o1.getTypeSystem().findType(o1.getType());
+                int index2 = o2.getTypeSystem().findType(o2.getType());
+                if (index1 == -1 || index2 == -1) {
+                    return 0;
+                }
+                return index1 - index2;
+            }
+        });
         return filteredExecutableTypes;
     }
 
@@ -425,7 +436,8 @@
                 context.getLog().error(errorElement, "Node type '%s' is invalid.", Utils.getQualifiedName(nodeType));
                 return null;
             } else if (fieldNodeData.findGenericExecutableType(context) == null) {
-                context.getLog().error(errorElement, "No executable generic type found for node '%s'.", Utils.getQualifiedName(nodeType));
+                // TODO better error handling for (no or multiple?)
+                context.getLog().error(errorElement, "No or multiple executable generic types found for node '%s'.", Utils.getQualifiedName(nodeType));
                 return null;
             }
         }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java	Mon Feb 04 17:48:20 2013 +0100
@@ -144,7 +144,8 @@
                 ParameterSpec spec = param.getSpecification();
                 expectedParameterSpecs.add(new ParameterSpec(spec.getName(), param.getActualType(), false));
             }
-            String expectedSignature = TemplateMethodParser.createExpectedSignature(specializationGuard.getGuardMethod(), returnTypeSpec, expectedParameterSpecs);
+            List<TypeDef> typeDefs = createTypeDefinitions(returnTypeSpec, expectedParameterSpecs);
+            String expectedSignature = TemplateMethodParser.createExpectedSignature(specializationGuard.getGuardMethod(), returnTypeSpec, expectedParameterSpecs, typeDefs);
             AnnotationValue value = Utils.getAnnotationValue(mirror, "methodName");
             getContext().getLog().error(specialization.getMethod(), mirror, value, "No guard with signature '%s' found in type system.", expectedSignature);
             return null;
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java	Mon Feb 04 17:48:20 2013 +0100
@@ -120,6 +120,8 @@
             return null;
         }
 
+        List<TypeDef> typeDefs = createTypeDefinitions(methodSpecification.getReturnType(), methodSpecification.getParameters());
+
         ParameterSpec returnTypeSpec = methodSpecification.getReturnType();
         List<ParameterSpec> parameterSpecs = new ArrayList<>();
         parameterSpecs.addAll(methodSpecification.getParameters());
@@ -127,11 +129,11 @@
         ActualParameter returnTypeMirror = resolveTypeMirror(returnTypeSpec, method.getReturnType(), template);
         if (returnTypeMirror == null) {
             if (isEmitErrors()) {
-                String expectedReturnType = createTypeSignature(returnTypeSpec, true);
+                String expectedReturnType = createTypeSignature(returnTypeSpec, typeDefs, true);
                 String actualReturnType = Utils.getSimpleName(method.getReturnType());
 
                 String message = String.format("The provided return type \"%s\" does not match expected return type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType,
-                                createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs));
+                                createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
 
                 context.getLog().error(method, annotation, message);
             }
@@ -160,10 +162,10 @@
                 } else if (!specification.isOptional()) {
                     if (isEmitErrors()) {
                         // non option type specification found -> argument missing
-                        String expectedType = createTypeSignature(specification, false);
+                        String expectedType = createTypeSignature(specification, typeDefs, false);
 
                         String message = String.format("Missing argument \"%s\".\nExpected signature: \n %s", expectedType,
-                                        createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs));
+                                        createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
 
                         context.getLog().error(method, message);
                     }
@@ -184,11 +186,11 @@
                 }
 
                 if (isEmitErrors()) {
-                    String expectedReturnType = createTypeSignature(specification, false);
+                    String expectedReturnType = createTypeSignature(specification, typeDefs, false);
                     String actualReturnType = Utils.getSimpleName(parameter.asType()) + " " + parameter.getSimpleName();
 
                     String message = String.format("The provided argument type \"%s\" does not match expected type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType,
-                                    createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs));
+                                    createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
 
                     context.getLog().error(parameter, message);
                 }
@@ -208,7 +210,7 @@
             if (isEmitErrors()) {
                 String actualReturnType = Utils.getSimpleName(parameter.asType()) + " " + parameter.getSimpleName();
                 String message = String.format("No argument expected but found \"%s\".\nExpected signature: \n %s", actualReturnType,
-                                createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs));
+                                createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
 
                 context.getLog().error(parameter, message);
             }
@@ -231,11 +233,67 @@
         return new ActualParameter(specification, resolvedType);
     }
 
-    public static String createExpectedSignature(String methodName, ParameterSpec returnType, List<? extends ParameterSpec> parameters) {
+    protected static List<TypeDef> createTypeDefinitions(ParameterSpec returnType, List<? extends ParameterSpec> parameters) {
+        List<TypeDef> typeDefs = new ArrayList<>();
+
+        TypeMirror[] types = returnType.getAllowedTypes();
+        List<ParameterSpec> allParams = new ArrayList<>();
+        allParams.add(returnType);
+        allParams.addAll(parameters);
+
+        int defIndex = 0;
+        for (ParameterSpec spec : allParams) {
+            TypeMirror[] allowedTypes = spec.getAllowedTypes();
+            if (types != null && allowedTypes.length > 1) {
+                TypeDef foundDef = null;
+                for (TypeDef def : typeDefs) {
+                    if (Arrays.equals(spec.getAllowedTypes(), def.getTypes())) {
+                        foundDef = def;
+                        break;
+                    }
+                }
+                if (foundDef == null) {
+                    foundDef = new TypeDef(types, "Types" + defIndex);
+                    typeDefs.add(foundDef);
+                    defIndex++;
+                }
+
+                foundDef.getParameters().add(spec);
+            }
+        }
+
+        return typeDefs;
+    }
+
+    protected static class TypeDef {
+
+        private final TypeMirror[] types;
+        private final String name;
+        private final List<ParameterSpec> parameters = new ArrayList<>();
+
+        public TypeDef(TypeMirror[] types, String name) {
+            this.types = types;
+            this.name = name;
+        }
+
+        public List<ParameterSpec> getParameters() {
+            return parameters;
+        }
+
+        public TypeMirror[] getTypes() {
+            return types;
+        }
+
+        public String getName() {
+            return name;
+        }
+    }
+
+    public static String createExpectedSignature(String methodName, ParameterSpec returnType, List<? extends ParameterSpec> parameters, List<TypeDef> typeDefs) {
         StringBuilder b = new StringBuilder();
 
         b.append("    ");
-        b.append(createTypeSignature(returnType, true));
+        b.append(createTypeSignature(returnType, typeDefs, true));
 
         b.append(" ");
         b.append(methodName);
@@ -250,7 +308,7 @@
                 b.append("{");
             }
 
-            b.append(createTypeSignature(specification, false));
+            b.append(createTypeSignature(specification, typeDefs, false));
 
             if (specification.isOptional()) {
                 b.append("]");
@@ -268,34 +326,40 @@
 
         b.append(")");
 
-        TypeMirror[] types = null;
+        if (!typeDefs.isEmpty()) {
+            b.append("\n\n");
 
-        // TODO allowed types may differ so different <Any> must be generated.
-        if (returnType.getAllowedTypes().length > 1) {
-            types = returnType.getAllowedTypes();
-        }
-        for (ParameterSpec param : parameters) {
-            if (param.getAllowedTypes().length > 1) {
-                types = param.getAllowedTypes();
+            String lineSep = "";
+            for (TypeDef def : typeDefs) {
+                b.append(lineSep);
+                b.append("    <").append(def.getName()).append(">");
+                b.append(" = {");
+                String separator = "";
+                for (TypeMirror type : def.getTypes()) {
+                    b.append(separator).append(Utils.getSimpleName(type));
+                    separator = ", ";
+                }
+                b.append("}");
+                lineSep = "\n";
+
             }
         }
-        if (types != null) {
-            b.append("\n\n    ");
-            b.append("<Any> = {");
-            String separator = "";
-            for (TypeMirror type : types) {
-                b.append(separator).append(Utils.getSimpleName(type));
-                separator = ", ";
-            }
-            b.append("}");
-        }
         return b.toString();
     }
 
-    private static String createTypeSignature(ParameterSpec spec, boolean typeOnly) {
+    private static String createTypeSignature(ParameterSpec spec, List<TypeDef> typeDefs, boolean typeOnly) {
         StringBuilder builder = new StringBuilder();
         if (spec.getAllowedTypes().length > 1) {
-            builder.append("<Any>");
+            TypeDef foundTypeDef = null;
+            for (TypeDef typeDef : typeDefs) {
+                if (typeDef.getParameters().contains(spec)) {
+                    foundTypeDef = typeDef;
+                    break;
+                }
+            }
+            if (foundTypeDef != null) {
+                builder.append("<" + foundTypeDef.getName() + ">");
+            }
         } else if (spec.getAllowedTypes().length == 1) {
             builder.append(Utils.getSimpleName(spec.getAllowedTypes()[0]));
         } else {
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java	Mon Feb 04 17:42:53 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java	Mon Feb 04 17:48:20 2013 +0100
@@ -114,6 +114,10 @@
         return types[index];
     }
 
+    public int findType(TypeData typeData) {
+        return findType(typeData.getPrimitiveType());
+    }
+
     public int findType(TypeMirror type) {
         for (int i = 0; i < types.length; i++) {
             if (Utils.typeEquals(types[i].getPrimitiveType(), type)) {
--- a/mxtool/mx.py	Mon Feb 04 17:42:53 2013 +0100
+++ b/mxtool/mx.py	Mon Feb 04 17:48:20 2013 +0100
@@ -2096,21 +2096,23 @@
                 out.close('buildCommand')
 
         if (_needsEclipseJarBuild(p)):
-            out.open('buildCommand')
-            out.element('name', data='org.eclipse.ui.externaltools.ExternalToolBuilder')
-            out.element('triggers', data='auto,full,incremental,')
-            out.open('arguments')
-            out.open('dictionary')
-            out.element('key', data = 'LaunchConfigHandle')
-            out.element('value', data = _genEclipseJarBuild(p))
-            out.close('dictionary')
-            out.open('dictionary')
-            out.element('key', data = 'incclean')
-            out.element('value', data = 'true')
-            out.close('dictionary')
-            out.close('arguments')
-            out.close('buildCommand')       
-                
+            targetValues = _genEclipseJarBuild(p);
+            for value in targetValues:
+                out.open('buildCommand')
+                out.element('name', data='org.eclipse.ui.externaltools.ExternalToolBuilder')
+                out.element('triggers', data='auto,full,incremental,')
+                out.open('arguments')
+                out.open('dictionary')
+                out.element('key', data = 'LaunchConfigHandle')
+                out.element('value', data = value)
+                out.close('dictionary')
+                out.open('dictionary')
+                out.element('key', data = 'incclean')
+                out.element('value', data = 'true')
+                out.close('dictionary')
+                out.close('arguments')
+                out.close('buildCommand')       
+                    
         out.close('buildSpec')
         out.open('natures')
         out.element('nature', data='org.eclipse.jdt.core.javanature')
@@ -2184,12 +2186,20 @@
     return False
 
 def _genEclipseJarBuild(p):
+    builders = []
+    builders.append(_genEclipseLaunch(p, 'Jar.launch', ''.join(['jar ', p.name]), refresh = False, async = False))
+    builders.append(_genEclipseLaunch(p, 'Refresh.launch', '', refresh = True, async = True))
+    return builders
+
+def _genEclipseLaunch(p, name, mxCommand, refresh=True, async=False):
     launchOut = XMLDoc();
     launchOut.open('launchConfiguration', {'type' : 'org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType'})
-    launchOut.element('stringAttribute',  {'key' : 'org.eclipse.debug.core.ATTR_REFRESH_SCOPE',            'value': '${project}'})
+    if refresh:
+        launchOut.element('stringAttribute',  {'key' : 'org.eclipse.debug.core.ATTR_REFRESH_SCOPE',            'value': '${project}'})
     launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.core.capture_output',                'value': 'false'})
     launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.ui.ATTR_CONSOLE_OUTPUT_ON',          'value': 'false'})
-    launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND',       'value': 'true'})
+    if async:
+        launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND',       'value': 'true'})
     
     baseDir = dirname(dirname(os.path.abspath(__file__)))
     
@@ -2198,7 +2208,7 @@
         cmd = 'mx.cmd'
     launchOut.element('stringAttribute',  {'key' : 'org.eclipse.ui.externaltools.ATTR_LOCATION',           'value': join(baseDir, cmd) })
     launchOut.element('stringAttribute',  {'key' : 'org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS',    'value': 'auto,full,incremental'})
-    launchOut.element('stringAttribute',  {'key' : 'org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS',     'value': ''.join(['jar', ' ', p.name])})
+    launchOut.element('stringAttribute',  {'key' : 'org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS',     'value': mxCommand})
     launchOut.element('booleanAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED','value': 'true'})
     launchOut.element('stringAttribute',  {'key' : 'org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY',  'value': baseDir})
     
@@ -2209,11 +2219,9 @@
     
     if not exists(externalToolDir):
         os.makedirs(externalToolDir)
-    update_file(join(externalToolDir, 'Jar.launch'), launchOut.xml(indent='\t', newl='\n'))
+    update_file(join(externalToolDir, name), launchOut.xml(indent='\t', newl='\n'))
     
-    return "<project>/.externalToolBuilders/Jar.launch"
-
-
+    return ''.join(["<project>/.externalToolBuilders/", name])
 
 
 def netbeansinit(args, suite=None):