changeset 13945:285d38e44ae5

Merge
author Christian Wimmer <christian.wimmer@oracle.com>
date Wed, 12 Feb 2014 23:57:22 -0800
parents 911e540a2116 (diff) ca0e1af320f6 (current diff)
children 28b59501c7b2
files
diffstat 23 files changed, 310 insertions(+), 182 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Wed Feb 12 23:57:22 2014 -0800
@@ -288,6 +288,14 @@
             }
         }
 
+        public int getAlignment() {
+            if (externalData instanceof ConstantData) {
+                return ((ConstantData) externalData).getAlignment();
+            } else {
+                return 0;
+            }
+        }
+
         public String getDataString() {
             if (inlineData != null) {
                 return inlineData.toString();
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java	Wed Feb 12 23:57:22 2014 -0800
@@ -86,6 +86,29 @@
         return frameRefMap != null && frameRefMap.size() > 0;
     }
 
+    public interface Iterator {
+        void register(int idx, boolean narrow);
+
+        void stackSlot(int idx, boolean narrow1, boolean narrow2);
+    }
+
+    public void iterate(Iterator iterator) {
+        if (hasRegisterRefMap()) {
+            for (int i = 0; i < registerRefMap.size() / 2; i++) {
+                if (registerRefMap.get(2 * i)) {
+                    iterator.register(i, registerRefMap.get(2 * i + 1));
+                }
+            }
+        }
+        if (hasFrameRefMap()) {
+            for (int i = 0; i < frameRefMap.size() / 3; i++) {
+                if (frameRefMap.get(3 * i)) {
+                    iterator.stackSlot(i, frameRefMap.get(3 * i + 1), frameRefMap.get(3 * i + 2));
+                }
+            }
+        }
+    }
+
     private static class NumberedRefMapFormatter implements RefMapFormatter {
 
         public String formatStackSlot(int frameRefMapIndex) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Feb 12 23:57:22 2014 -0800
@@ -280,7 +280,9 @@
         try (Scope s = Debug.scope("ControlFlowOptimizations")) {
             EdgeMoveOptimizer.optimize(lir);
             ControlFlowOptimizer.optimize(lir);
-            RedundantMoveElimination.optimize(lir, frameMap, lirGen.getGraph().method());
+            if (lirGen.canEliminateRedundantMoves()) {
+                RedundantMoveElimination.optimize(lir, frameMap, lirGen.getGraph().method());
+            }
             NullCheckOptimizer.optimize(lir, target.implicitNullCheckLimit);
 
             Debug.dump(lir, "After control flow optimization");
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Feb 12 23:57:22 2014 -0800
@@ -219,6 +219,14 @@
         return null;
     }
 
+    /**
+     * Returns true if the redundant move elimination optimization should be done after register
+     * allocation.
+     */
+    public boolean canEliminateRedundantMoves() {
+        return true;
+    }
+
     @SuppressWarnings("hiding")
     protected DebugInfoBuilder createDebugInfoBuilder(NodeMap<Value> nodeOperands) {
         return new DebugInfoBuilder(nodeOperands);
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Wed Feb 12 23:57:22 2014 -0800
@@ -950,12 +950,16 @@
                 dims[i] = frameState.ipop();
             }
             if (type instanceof ResolvedJavaType) {
-                frameState.apush(append(new NewMultiArrayNode((ResolvedJavaType) type, dims)));
+                frameState.apush(append(createNewMultiArray((ResolvedJavaType) type, dims)));
             } else {
                 handleUnresolvedNewMultiArray(type, dims);
             }
         }
 
+        protected NewMultiArrayNode createNewMultiArray(ResolvedJavaType type, ValueNode[] dimensions) {
+            return new NewMultiArrayNode(type, dimensions);
+        }
+
         private void genGetField(JavaField field) {
             emitExplicitExceptions(frameState.peek(0), null);
 
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Wed Feb 12 23:57:22 2014 -0800
@@ -122,6 +122,10 @@
         return frameSize;
     }
 
+    public int outgoingSize() {
+        return outgoingSize;
+    }
+
     /**
      * Determines if any space is used in the frame apart from the
      * {@link Architecture#getReturnAddressSize() return address slot}.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java	Wed Feb 12 23:57:22 2014 -0800
@@ -36,7 +36,7 @@
  * loop.
  */
 @NodeInfo(nameTemplate = "{p#type/s}Proxy")
-public class ProxyNode extends FloatingNode implements IterableNodeType, ValueNumberable, Canonicalizable, Virtualizable, ValueProxy, GuardingNode {
+public class ProxyNode extends FloatingNode implements IterableNodeType, ValueNumberable, Canonicalizable, Virtualizable, ValueAndStampProxy, GuardingNode {
 
     @Input(notDataflow = true) private AbstractBeginNode proxyPoint;
     @Input private ValueNode value;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Wed Feb 12 23:57:22 2014 -0800
@@ -31,7 +31,7 @@
 /**
  * The {@code NewMultiArrayNode} represents an allocation of a multi-dimensional object array.
  */
-public final class NewMultiArrayNode extends DeoptimizingFixedWithNextNode implements Lowerable, ArrayLengthProvider {
+public class NewMultiArrayNode extends DeoptimizingFixedWithNextNode implements Lowerable, ArrayLengthProvider {
 
     @Input private final NodeInputList<ValueNode> dimensions;
     private final ResolvedJavaType type;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ValueAndStampProxy.java	Wed Feb 12 23:57:22 2014 -0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes.spi;
+
+/**
+ * This interface marks nodes whose result is the same as one of their inputs, and whose stamp is
+ * the same as one of their inputs.
+ * 
+ * For some algorithms it is necessary or advantageous to see through these proxies.
+ */
+public interface ValueAndStampProxy extends ValueProxy {
+}
--- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionProcessor.java	Wed Feb 12 23:57:22 2014 -0800
@@ -157,6 +157,7 @@
 
             boolean needPrivateFieldAccessor = false;
             int i = 0;
+            Collections.sort(info.options);
             for (OptionInfo option : info.options) {
                 String optionValue;
                 if (option.field.getModifiers().contains(Modifier.PRIVATE)) {
@@ -223,7 +224,7 @@
         }
     }
 
-    static class OptionInfo {
+    static class OptionInfo implements Comparable<OptionInfo> {
 
         final String name;
         final String help;
@@ -240,6 +241,11 @@
         }
 
         @Override
+        public int compareTo(OptionInfo other) {
+            return name.compareTo(other.name);
+        }
+
+        @Override
         public String toString() {
             return declaringClass + "." + field;
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/InferStamps.java	Wed Feb 12 23:57:22 2014 -0800
@@ -0,0 +1,96 @@
+/*
+ * 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.phases.graph;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+public class InferStamps {
+
+    /**
+     * Infer the stamps for all Object nodes in the graph, to make the stamps as precise as
+     * possible. For example, this propagates the word-type through phi functions. To handle phi
+     * functions at loop headers, the stamp inference is called until a fix point is reached.
+     * <p>
+     * This method can be used when it is needed that stamps are inferred before the first run of
+     * the canonicalizer. For example, word type rewriting must run before the first run of the
+     * canonicalizer because many nodes are not prepared to see the word type during
+     * canonicalization.
+     */
+    public static void inferStamps(StructuredGraph graph) {
+        /*
+         * We want to make the stamps more precise. For cyclic phi functions, this means we have to
+         * ignore the initial stamp because the imprecise stamp would always propagate around the
+         * cycle. We therefore set the stamp to an illegal stamp, which is automatically ignored
+         * when the phi function performs the "meet" operator on its input stamps.
+         */
+        for (Node n : graph.getNodes()) {
+            if (n instanceof PhiNode || n instanceof ValueAndStampProxy) {
+                ValueNode node = (ValueNode) n;
+                if (node.kind() == Kind.Object) {
+                    assert !(node.stamp() instanceof IllegalStamp) : "We assume all Phi and Proxy stamps are legal before the analysis";
+                    node.setStamp(StampFactory.illegal(node.kind()));
+                }
+            }
+        }
+
+        boolean stampChanged;
+        do {
+            stampChanged = false;
+            /*
+             * We could use GraphOrder.forwardGraph() to process the nodes in a defined order and
+             * propagate long def-use chains in fewer iterations. However, measurements showed that
+             * we have few iterations anyway, and the overhead of computing the order is much higher
+             * than the benefit.
+             */
+            for (Node n : graph.getNodes()) {
+                if (n instanceof ValueNode) {
+                    ValueNode node = (ValueNode) n;
+                    if (node.kind() == Kind.Object) {
+                        stampChanged |= node.inferStamp();
+                    }
+                }
+            }
+        } while (stampChanged);
+
+        /*
+         * Check that all the illegal stamps we introduced above are correctly replaced with real
+         * stamps again.
+         */
+        assert checkNoIllegalStamp(graph);
+    }
+
+    private static boolean checkNoIllegalStamp(StructuredGraph graph) {
+        for (Node n : graph.getNodes()) {
+            if (n instanceof PhiNode || n instanceof ValueAndStampProxy) {
+                ValueNode node = (ValueNode) n;
+                assert !(node.stamp() instanceof IllegalStamp) : "Stamp is illegal after analysis. This is not necessarily an error, but a condition that we want to investigate (and then maybe relax or remove the assertion).";
+            }
+        }
+        return true;
+    }
+
+}
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java	Wed Feb 12 23:57:22 2014 -0800
@@ -36,6 +36,7 @@
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.graph.*;
 import com.oracle.graal.word.*;
 import com.oracle.graal.word.Word.Opcode;
 import com.oracle.graal.word.Word.Operation;
@@ -63,7 +64,7 @@
 
     @Override
     protected void run(StructuredGraph graph) {
-        inferStamps(graph);
+        InferStamps.inferStamps(graph);
 
         for (Node n : graph.getNodes()) {
             if (n instanceof ValueNode) {
@@ -77,68 +78,6 @@
     }
 
     /**
-     * Infer the stamps for all Object nodes in the graph, to make the stamps as precise as
-     * possible. For example, this propagates the word-type through phi functions. To handle phi
-     * functions at loop headers, the stamp inference is called until a fix point is reached.
-     * <p>
-     * Note that we cannot rely on the normal canonicalizer to propagate stamps: The word type
-     * rewriting must run before the first run of the canonicalizer because many nodes are not
-     * prepared to see the word type during canonicalization.
-     */
-    protected void inferStamps(StructuredGraph graph) {
-        /*
-         * We want to make the stamps more precise. For cyclic phi functions, this means we have to
-         * ignore the initial stamp because the imprecise stamp would always propagate around the
-         * cycle. We therefore set the stamp to an illegal stamp, which is automatically ignored
-         * when the phi function performs the "meet" operator on its input stamps.
-         */
-        for (Node n : graph.getNodes()) {
-            if (n instanceof PhiNode || n instanceof ProxyNode) {
-                ValueNode node = (ValueNode) n;
-                if (node.kind() == Kind.Object) {
-                    assert !(node.stamp() instanceof IllegalStamp) : "We assume all Phi and Proxy stamps are legal before the analysis";
-                    node.setStamp(StampFactory.illegal(node.kind()));
-                }
-            }
-        }
-
-        boolean stampChanged;
-        do {
-            stampChanged = false;
-            /*
-             * We could use GraphOrder.forwardGraph() to process the nodes in a defined order and
-             * propagate long def-use chains in fewer iterations. However, measurements showed that
-             * we have few iterations anyway, and the overhead of computing the order is much higher
-             * than the benefit.
-             */
-            for (Node n : graph.getNodes()) {
-                if (n instanceof ValueNode) {
-                    ValueNode node = (ValueNode) n;
-                    if (node.kind() == Kind.Object) {
-                        stampChanged |= node.inferStamp();
-                    }
-                }
-            }
-        } while (stampChanged);
-
-        /*
-         * Check that all the illegal stamps we introduced above are correctly replaced with real
-         * stamps again.
-         */
-        assert checkNoIllegalStamp(graph);
-    }
-
-    private static boolean checkNoIllegalStamp(StructuredGraph graph) {
-        for (Node n : graph.getNodes()) {
-            if (n instanceof PhiNode || n instanceof ProxyNode) {
-                ValueNode node = (ValueNode) n;
-                assert !(node.stamp() instanceof IllegalStamp) : "Stamp is illegal after analysis. This is not necessarily an error, but a condition that we want to investigate (and then maybe relax or remove the assertion).";
-            }
-        }
-        return true;
-    }
-
-    /**
      * Change the stamp for word nodes from the object stamp ({@link WordBase} or anything extending
      * or implementing that interface) to the primitive word stamp.
      */
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeVerificationPhase.java	Wed Feb 12 23:57:22 2014 -0800
@@ -32,6 +32,7 @@
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.graph.*;
 import com.oracle.graal.word.*;
 import com.oracle.graal.word.Word.Operation;
 
@@ -58,7 +59,7 @@
          * modifies the stamp of nodes, we copy the graph before running the verification.
          */
         StructuredGraph graph = inputGraph.copy();
-        wordAccess.inferStamps(graph);
+        InferStamps.inferStamps(graph);
 
         for (ValueNode node : graph.getNodes().filter(ValueNode.class)) {
             if (!node.recordsUsages()) {
@@ -81,7 +82,6 @@
                 } else if (usage instanceof StoreIndexedNode) {
                     verify(!isWord(node) || ((StoreIndexedNode) usage).array() != node, node, usage, "cannot store to word value");
                     verify(!isWord(node) || ((StoreIndexedNode) usage).index() != node, node, usage, "cannot use word value as index");
-                    verify(!isWord(node) || ((StoreIndexedNode) usage).value() != node, node, usage, "cannot store word value to array");
                 } else if (usage instanceof MethodCallTargetNode) {
                     MethodCallTargetNode callTarget = (MethodCallTargetNode) usage;
                     verifyInvoke(node, callTarget);
--- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreMethodNodeManager.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreMethodNodeManager.java	Wed Feb 12 23:57:22 2014 -0800
@@ -31,7 +31,13 @@
      * given the Object class object, which should already be initialized with all the core classes.
      */
     public static void addMethods(RubyClass rubyObjectClass) {
-        for (MethodDetails methodDetails : getMethods()) {
+        addMethods(rubyObjectClass, getMethods());
+    }
+
+    public static void addMethods(RubyClass rubyObjectClass, List<MethodDetails> methods) {
+        // Same as above, but allows passing of a specific list of core methods.
+        // This allows extending Truffle-Ruby with non-standard Core Method.
+        for (MethodDetails methodDetails : methods) {
             addMethod(rubyObjectClass, methodDetails);
         }
     }
@@ -82,7 +88,7 @@
     /**
      * Collect up the core methods created by a factory.
      */
-    private static void getMethods(List<MethodDetails> methods, List<? extends NodeFactory<? extends CoreMethodNode>> nodeFactories) {
+    public static void getMethods(List<MethodDetails> methods, List<? extends NodeFactory<? extends CoreMethodNode>> nodeFactories) {
         for (NodeFactory<? extends RubyNode> nodeFactory : nodeFactories) {
             final GeneratedBy generatedBy = nodeFactory.getClass().getAnnotation(GeneratedBy.class);
             final Class<?> nodeClass = generatedBy.value();
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLMain.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLMain.java	Wed Feb 12 23:57:22 2014 -0800
@@ -80,7 +80,7 @@
  * <li>Basic control flow statements: {@link SLBlockNode blocks}, {@link SLIfNode if},
  * {@link SLWhileNode while} with {@link SLBreakNode break} and {@link SLContinueNode continue},
  * {@link SLReturnNode return}.
- * <li>Function calls: {@link SLCallNode calls} are efficiently implemented with
+ * <li>Function calls: {@link SLInvokeNode invocations} are efficiently implemented with
  * {@link SLAbstractDispatchNode polymorphic inline caches}.
  * </ul>
  * 
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLDefineFunctionBuiltin.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLDefineFunctionBuiltin.java	Wed Feb 12 23:57:22 2014 -0800
@@ -38,14 +38,14 @@
 
     @Specialization
     public String defineFunction(String code) {
-        return doDefineFunction(getContext(), code);
+        doDefineFunction(getContext(), code);
+        return code;
     }
 
     @SlowPath
-    private static String doDefineFunction(SLContext context, String code) {
+    private static void doDefineFunction(SLContext context, String code) {
         Source source = context.getSourceManager().get("[defineFunction]", code);
         /* The same parsing code as for parsing the initial source. */
         Parser.parseSL(context, source);
-        return code;
     }
 }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLAbstractDispatchNode.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLAbstractDispatchNode.java	Wed Feb 12 23:57:22 2014 -0800
@@ -35,14 +35,14 @@
  * a single {@link SLGenericDispatchNode}. All this rewriting happens on runtime, based on profiling
  * feedback of the actual execution.
  * <p>
- * Example of the chain of nodes ({@code C}: {@link SLCallNode}; {@code U}:
+ * Example of the chain of nodes ({@code I}: {@link SLInvokeNode}; {@code U}:
  * {@link SLUninitializedDispatchNode}; {@code D}: {@link SLDirectDispatchNode}; {@code G}:
  * {@link SLGenericDispatchNode}):
  * <ol>
- * <li>After parsing: {@code C->U}
- * <li>After execution of function {@code f1}: {@code C->D(f1)->U}
- * <li>After execution of function {@code f2}: {@code C->D(f1)->D(f2)->U}
- * <li>After execution of function {@code f3}: {@code C->G}
+ * <li>After parsing: {@code I->U}
+ * <li>After execution of function {@code f1}: {@code I->D(f1)->U}
+ * <li>After execution of function {@code f2}: {@code I->D(f1)->D(f2)->U}
+ * <li>After execution of function {@code f3}: {@code I->G}
  * </ol>
  * */
 public abstract class SLAbstractDispatchNode extends Node {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLCallNode.java	Wed Feb 12 20:12:33 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.sl.nodes.call;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.sl.nodes.*;
-import com.oracle.truffle.sl.runtime.*;
-
-/**
- * The node for a function call in SL. Since SL has first class functions, the {@link SLFunction
- * target function} can be computed by an {@link #functionNode arbitrary expression}. This node is
- * responsible for evaluating this expression, as well as evaluating the {@link #argumentNodes
- * arguments}. The actual call dispatch is then delegated to a chain of
- * {@link SLAbstractDispatchNode}s that form a polymorphic inline cache.
- */
-@NodeInfo(shortName = "call")
-public final class SLCallNode extends SLExpressionNode {
-
-    public static SLCallNode create(SLExpressionNode function, SLExpressionNode[] arguments) {
-        return new SLCallNode(function, arguments, new SLUninitializedDispatchNode());
-    }
-
-    @Child protected SLExpressionNode functionNode;
-    @Children protected final SLExpressionNode[] argumentNodes;
-    @Child protected SLAbstractDispatchNode dispatchNode;
-
-    private SLCallNode(SLExpressionNode functionNode, SLExpressionNode[] argumentNodes, SLAbstractDispatchNode dispatchNode) {
-        this.functionNode = adoptChild(functionNode);
-        this.argumentNodes = adoptChildren(argumentNodes);
-        this.dispatchNode = adoptChild(dispatchNode);
-    }
-
-    @Override
-    @ExplodeLoop
-    public Object executeGeneric(VirtualFrame frame) {
-        SLFunction function = evaluateFunction(frame);
-
-        /*
-         * The number of arguments is constant for one call node. During compilation, the loop is
-         * unrolled and the execute methods of all arguments are inlined. This is triggered by the
-         * ExplodeLoop annotation on the method. The compiler assertion below illustrates that the
-         * array length is really constant.
-         */
-        CompilerAsserts.compilationConstant(argumentNodes.length);
-
-        Object[] argumentValues = new Object[argumentNodes.length];
-        for (int i = 0; i < argumentNodes.length; i++) {
-            argumentValues[i] = argumentNodes[i].executeGeneric(frame);
-        }
-        SLArguments arguments = new SLArguments(argumentValues);
-
-        return dispatchNode.executeDispatch(frame, function, arguments);
-    }
-
-    private SLFunction evaluateFunction(VirtualFrame frame) {
-        try {
-            /*
-             * The function node must evaluate to a SLFunction value, so we call
-             * function-specialized method.
-             */
-            return functionNode.executeFunction(frame);
-        } catch (UnexpectedResultException ex) {
-            /*
-             * The function node evaluated to a non-function result. This is a type error in the SL
-             * program. We report it with the same exception that Truffle DSL generated nodes use to
-             * report type errors.
-             */
-            throw new UnsupportedSpecializationException(this, new Node[]{functionNode}, ex.getResult());
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLInvokeNode.java	Wed Feb 12 23:57:22 2014 -0800
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.sl.nodes.call;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.runtime.*;
+
+/**
+ * The node for function invocation in SL. Since SL has first class functions, the
+ * {@link SLFunction target function} can be computed by an {@link #functionNode arbitrary
+ * expression}. This node is responsible for evaluating this expression, as well as evaluating the
+ * {@link #argumentNodes arguments}. The actual dispatch is then delegated to a chain of
+ * {@link SLAbstractDispatchNode}s that form a polymorphic inline cache.
+ */
+@NodeInfo(shortName = "invoke")
+public final class SLInvokeNode extends SLExpressionNode {
+
+    public static SLInvokeNode create(SLExpressionNode function, SLExpressionNode[] arguments) {
+        return new SLInvokeNode(function, arguments, new SLUninitializedDispatchNode());
+    }
+
+    @Child protected SLExpressionNode functionNode;
+    @Children protected final SLExpressionNode[] argumentNodes;
+    @Child protected SLAbstractDispatchNode dispatchNode;
+
+    private SLInvokeNode(SLExpressionNode functionNode, SLExpressionNode[] argumentNodes, SLAbstractDispatchNode dispatchNode) {
+        this.functionNode = adoptChild(functionNode);
+        this.argumentNodes = adoptChildren(argumentNodes);
+        this.dispatchNode = adoptChild(dispatchNode);
+    }
+
+    @Override
+    @ExplodeLoop
+    public Object executeGeneric(VirtualFrame frame) {
+        SLFunction function = evaluateFunction(frame);
+
+        /*
+         * The number of arguments is constant for one invoke node. During compilation, the loop is
+         * unrolled and the execute methods of all arguments are inlined. This is triggered by the
+         * ExplodeLoop annotation on the method. The compiler assertion below illustrates that the
+         * array length is really constant.
+         */
+        CompilerAsserts.compilationConstant(argumentNodes.length);
+
+        Object[] argumentValues = new Object[argumentNodes.length];
+        for (int i = 0; i < argumentNodes.length; i++) {
+            argumentValues[i] = argumentNodes[i].executeGeneric(frame);
+        }
+        SLArguments arguments = new SLArguments(argumentValues);
+
+        return dispatchNode.executeDispatch(frame, function, arguments);
+    }
+
+    private SLFunction evaluateFunction(VirtualFrame frame) {
+        try {
+            /*
+             * The function node must evaluate to a SLFunction value, so we call
+             * function-specialized method.
+             */
+            return functionNode.executeFunction(frame);
+        } catch (UnexpectedResultException ex) {
+            /*
+             * The function node evaluated to a non-function result. This is a type error in the SL
+             * program. We report it with the same exception that Truffle DSL generated nodes use to
+             * report type errors.
+             */
+            throw new UnsupportedSpecializationException(this, new Node[]{functionNode}, ex.getResult());
+        }
+    }
+}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLUninitializedDispatchNode.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLUninitializedDispatchNode.java	Wed Feb 12 23:57:22 2014 -0800
@@ -54,7 +54,7 @@
             cur = cur.getParent();
             depth++;
         }
-        SLCallNode callNode = (SLCallNode) cur.getParent();
+        SLInvokeNode invokeNode = (SLInvokeNode) cur.getParent();
 
         SLAbstractDispatchNode specialized;
         if (function.getCallTarget() == null) {
@@ -72,7 +72,7 @@
             /* Cache size exceeded, fall back to a single generic dispatch node. */
             SLAbstractDispatchNode generic = new SLGenericDispatchNode();
             /* Replace the whole chain, not just ourself, with the new generic node. */
-            specialized = callNode.dispatchNode.replace(generic);
+            specialized = invokeNode.dispatchNode.replace(generic);
         }
 
         /*
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java	Wed Feb 12 23:57:22 2014 -0800
@@ -42,17 +42,17 @@
      */
     protected abstract FrameSlot getSlot();
 
-    @Specialization(rewriteOn = {FrameSlotTypeException.class})
+    @Specialization(rewriteOn = FrameSlotTypeException.class)
     protected long readLong(VirtualFrame frame) throws FrameSlotTypeException {
         return frame.getLong(getSlot());
     }
 
-    @Specialization(rewriteOn = {FrameSlotTypeException.class})
+    @Specialization(rewriteOn = FrameSlotTypeException.class)
     protected boolean readBoolean(VirtualFrame frame) throws FrameSlotTypeException {
         return frame.getBoolean(getSlot());
     }
 
-    @Specialization(order = 1, rewriteOn = {FrameSlotTypeException.class})
+    @Specialization(order = 1, rewriteOn = FrameSlotTypeException.class)
     protected Object readObject(VirtualFrame frame) throws FrameSlotTypeException {
         return frame.getObject(getSlot());
     }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java	Wed Feb 12 23:57:22 2014 -0800
@@ -197,7 +197,7 @@
 
     public SLExpressionNode createCall(Token nameToken, List<SLExpressionNode> parameterNodes) {
         SLExpressionNode functionNode = createRead(nameToken);
-        return assignSource(nameToken, SLCallNode.create(functionNode, parameterNodes.toArray(new SLExpressionNode[parameterNodes.size()])));
+        return assignSource(nameToken, SLInvokeNode.create(functionNode, parameterNodes.toArray(new SLExpressionNode[parameterNodes.size()])));
     }
 
     public SLExpressionNode createAssignment(Token nameToken, SLExpressionNode valueNode) {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLArguments.java	Wed Feb 12 20:12:33 2014 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLArguments.java	Wed Feb 12 23:57:22 2014 -0800
@@ -36,7 +36,7 @@
     private final Object[] argumentValues;
 
     /**
-     * Used by the caller, i.e., the {@link SLCallNode node that performs a function call}.
+     * Used by the caller, i.e., the {@link SLInvokeNode node that performs a function call}.
      */
     public SLArguments(Object[] arguments) {
         this.argumentValues = arguments;