diff graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLAddNode.java @ 13836:64c77f0577bb

More documentation and improvements of Simple Language
author Christian Wimmer <christian.wimmer@oracle.com>
date Thu, 30 Jan 2014 17:53:27 -0800
parents b16ec83edc73
children ff3136ecb5a7
line wrap: on
line diff
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLAddNode.java	Thu Jan 30 17:52:24 2014 -0800
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLAddNode.java	Thu Jan 30 17:53:27 2014 -0800
@@ -29,29 +29,81 @@
 import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.sl.nodes.*;
 
+/**
+ * SL node that performs the "+" operation, which performs addition on arbitrary precision numbers,
+ * as well as String concatenation if one of the operands is a String.
+ * <p>
+ * Type specialization on the input values is essential for the performance. This is achieved via
+ * node rewriting: specialized subclasses handle just a single type, so that the generic node that
+ * can handle all types is used only in cases where different types were encountered. The subclasses
+ * are automatically generated by the Truffle DSL. In addition, a {@link SLAddNodeFactory factory
+ * class} is generated that provides, e.g., {@link SLAddNodeFactory#create node creation}.
+ */
 @NodeInfo(shortName = "+")
 public abstract class SLAddNode extends SLBinaryNode {
 
+    /**
+     * Specialization for primitive {@code long} values. This is the fast path of the
+     * arbitrary-precision arithmetic. We need to check for overflows of the addition, and switch to
+     * the {@link #add(BigInteger, BigInteger) slow path}. Therefore, we use an
+     * {@link ExactMath#addExact(long, long) addition method that throws an exception on overflow}.
+     * The {@code rewriteOn} attribute on the {@link Specialization} annotation automatically
+     * triggers the node rewriting on the exception.
+     * <p>
+     * In compiled code, {@link ExactMath#addExact(long, long) addExact} is compiled to efficient
+     * machine code that uses the processor's overflow flag. Therefore, this method is compiled to
+     * only two machine code instructions on the fast path.
+     * <p>
+     * This specialization is automatically selected by the Truffle DSL if both the left and right
+     * operand are {@code long} values.
+     */
     @Specialization(rewriteOn = ArithmeticException.class)
     protected long add(long left, long right) {
         return ExactMath.addExact(left, right);
     }
 
+    /**
+     * This is the slow path of the arbitrary-precision arithmetic. The {@link BigInteger} type of
+     * Java is doing everything we need.
+     * <p>
+     * This specialization is automatically selected by the Truffle DSL if both the left and right
+     * operand are {@link BigInteger} values. Because the type system defines an
+     * {@link ImplicitCast implicit conversion} from {@code long} to {@link BigInteger} in
+     * {@link SLTypes#castBigInteger(long)}, this specialization is also taken if the left or the
+     * right operand is a {@code long} value.
+     */
     @Specialization
     protected BigInteger add(BigInteger left, BigInteger right) {
         return left.add(right);
     }
 
+    /**
+     * Specialization for String concatenation. This specialization is not strictly necessary, since
+     * {@link #add(Object, Object)} covers this case too. But it leads to slightly better code,
+     * since we do not require the {@link Object#toString()} calls in this specialization.
+     */
     @Specialization
     protected String add(String left, String right) {
         return left + right;
     }
 
+    /**
+     * Specialization for String concatenation. The SL specification says that String concatenation
+     * works if either the left or the right operand is a String. The non-string operand is
+     * converted then automatically converted to a String.
+     * <p>
+     * To implement these semantics, we tell the Truffle DSL to use a custom guard. The guard
+     * function is defined in {@link #isString this class}, but could also be in any superclass.
+     */
     @Specialization(guards = "isString")
     protected String add(Object left, Object right) {
         return left.toString() + right.toString();
     }
 
+    /**
+     * Guard for String concatenation: returns true if either the left or the right operand is a
+     * {@link String}.
+     */
     protected boolean isString(Object a, Object b) {
         return a instanceof String || b instanceof String;
     }