changeset 16909:62cfffca9be2

Truffle-DSL: some more performance optimizations.
author Christian Humer <christian.humer@gmail.com>
date Sat, 23 Aug 2014 19:31:18 +0200
parents d3f282a9e287
children c9437b07c26a
files graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeCodeGenerator.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/ElementUtils.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeElementScanner.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeExecutableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTree.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTreeBuilder.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeVariableElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/GeneratedPackageElement.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/transform/AbstractCodeWriter.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/transform/FixWarningsVisitor.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/TemplateMethod.java
diffstat 12 files changed, 189 insertions(+), 163 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeCodeGenerator.java	Sat Aug 23 19:31:13 2014 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeCodeGenerator.java	Sat Aug 23 19:31:18 2014 +0200
@@ -322,12 +322,12 @@
     /**
      * <pre>
      * variant1 $condition != null
-     *
+     * 
      * $type $name = defaultValue($type);
      * if ($condition) {
      *     $name = $value;
      * }
-     *
+     * 
      * variant2 $condition != null
      * $type $name = $value;
      * </pre>
@@ -1745,14 +1745,14 @@
                 builder.startReturn().tree(createTemplateMethodCall(builder, null, source, current, null)).end();
             }
 
-            return encloseThrowsWithFallThrough(current, builder.getRoot());
+            return encloseThrowsWithFallThrough(parent, current, builder.getRoot());
         }
 
-        private CodeTree encloseThrowsWithFallThrough(SpecializationData current, CodeTree tree) {
+        private CodeTree encloseThrowsWithFallThrough(CodeTreeBuilder parent, SpecializationData current, CodeTree tree) {
             if (current.getExceptions().isEmpty()) {
                 return tree;
             }
-            CodeTreeBuilder builder = new CodeTreeBuilder(null);
+            CodeTreeBuilder builder = new CodeTreeBuilder(parent);
 
             builder.startTryBlock();
             builder.tree(tree);
@@ -1880,36 +1880,36 @@
 
         private CodeTree createExecuteChild(CodeTreeBuilder parent, NodeExecutionData execution, ExecutableTypeData sourceExecutable, Parameter targetParameter, Parameter unexpectedParameter) {
             SpecializationData specialization = getModel();
-            TreeSet<TypeData> possiblePolymorphicTypes = lookupPolymorphicTargetTypes(targetParameter);
-            if (specialization.isPolymorphic() && targetParameter.getTypeSystemType().isGeneric() && unexpectedParameter == null && possiblePolymorphicTypes.size() > 1) {
-
-                CodeTreeBuilder builder = parent.create();
-
-                boolean elseIf = false;
-                for (TypeData possiblePolymoprhicType : possiblePolymorphicTypes) {
-                    if (possiblePolymoprhicType.isGeneric()) {
-                        continue;
+            if (specialization.isPolymorphic() && targetParameter.getTypeSystemType().isGeneric() && unexpectedParameter == null) {
+                List<TypeData> possiblePolymorphicTypes = lookupPolymorphicTargetTypes(targetParameter);
+                if (possiblePolymorphicTypes.size() > 1) {
+                    CodeTreeBuilder builder = parent.create();
+
+                    boolean elseIf = false;
+                    for (TypeData possiblePolymoprhicType : possiblePolymorphicTypes) {
+                        if (possiblePolymoprhicType.isGeneric()) {
+                            continue;
+                        }
+                        elseIf = builder.startIf(elseIf);
+
+                        Parameter sourceParameter = sourceExecutable.findParameter(targetParameter.getLocalName());
+                        TypeData sourceType = sourceParameter != null ? sourceParameter.getTypeSystemType() : null;
+                        builder.string(polymorphicTypeName(targetParameter.getSpecification().getExecution())).string(" == ").typeLiteral(possiblePolymoprhicType.getPrimitiveType());
+                        builder.end().startBlock();
+                        builder.startStatement();
+                        builder.tree(createExecuteChildExpression(parent, execution, sourceType, new Parameter(targetParameter, possiblePolymoprhicType), unexpectedParameter, null));
+                        builder.end();
+                        builder.end();
                     }
-                    elseIf = builder.startIf(elseIf);
-
-                    Parameter sourceParameter = sourceExecutable.findParameter(targetParameter.getLocalName());
-                    TypeData sourceType = sourceParameter != null ? sourceParameter.getTypeSystemType() : null;
-                    builder.string(polymorphicTypeName(targetParameter.getSpecification().getExecution())).string(" == ").typeLiteral(possiblePolymoprhicType.getPrimitiveType());
-                    builder.end().startBlock();
-                    builder.startStatement();
-                    builder.tree(createExecuteChildExpression(parent, execution, sourceType, new Parameter(targetParameter, possiblePolymoprhicType), unexpectedParameter, null));
-                    builder.end();
+
+                    builder.startElseBlock();
+                    builder.startStatement().tree(createExecuteChildImplicit(parent, execution, sourceExecutable, targetParameter, unexpectedParameter)).end();
                     builder.end();
+
+                    return builder.getRoot();
                 }
-
-                builder.startElseBlock();
-                builder.startStatement().tree(createExecuteChildImplicit(parent, execution, sourceExecutable, targetParameter, unexpectedParameter)).end();
-                builder.end();
-
-                return builder.getRoot();
-            } else {
-                return createExecuteChildImplicit(parent, execution, sourceExecutable, targetParameter, unexpectedParameter);
             }
+            return createExecuteChildImplicit(parent, execution, sourceExecutable, targetParameter, unexpectedParameter);
         }
 
         protected final List<Parameter> getImplicitTypeParameters(SpecializationData model) {
@@ -1924,9 +1924,9 @@
             return parameter;
         }
 
-        protected final TreeSet<TypeData> lookupPolymorphicTargetTypes(Parameter param) {
+        protected final List<TypeData> lookupPolymorphicTargetTypes(Parameter param) {
             SpecializationData specialization = getModel();
-            TreeSet<TypeData> possiblePolymorphicTypes = new TreeSet<>();
+            Set<TypeData> possiblePolymorphicTypes = new HashSet<>();
             for (SpecializationData otherSpecialization : specialization.getNode().getSpecializations()) {
                 if (!otherSpecialization.isSpecialized()) {
                     continue;
@@ -1936,7 +1936,9 @@
                     possiblePolymorphicTypes.add(otherParameter.getTypeSystemType());
                 }
             }
-            return possiblePolymorphicTypes;
+            List<TypeData> types = new ArrayList<>(possiblePolymorphicTypes);
+            Collections.sort(types);
+            return types;
         }
 
         private CodeTree createExecuteChildImplicit(CodeTreeBuilder parent, NodeExecutionData execution, ExecutableTypeData sourceExecutable, Parameter param, Parameter unexpectedParameter) {
@@ -2115,9 +2117,12 @@
                 return true;
             }
 
-            for (CodeTree codeTree : tree.getEnclosedElements()) {
-                if (containsNewLine(codeTree)) {
-                    return true;
+            List<CodeTree> enclosing = tree.getEnclosedElements();
+            if (enclosing != null) {
+                for (CodeTree codeTree : enclosing) {
+                    if (containsNewLine(codeTree)) {
+                        return true;
+                    }
                 }
             }
             return false;
@@ -2128,7 +2133,7 @@
 
             if (getModel().isPolymorphic() && targetParameter.getTypeSystemType().isGeneric() && unexpectedParameter == null) {
                 // check for other polymorphic types
-                TreeSet<TypeData> polymorphicTargetTypes = lookupPolymorphicTargetTypes(targetParameter);
+                List<TypeData> polymorphicTargetTypes = lookupPolymorphicTargetTypes(targetParameter);
                 if (polymorphicTargetTypes.size() > 1) {
                     for (TypeData polymorphicTargetType : polymorphicTargetTypes) {
                         if (hasUnexpectedType(execution, sourceParameter, polymorphicTargetType)) {
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/ElementUtils.java	Sat Aug 23 19:31:13 2014 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/ElementUtils.java	Sat Aug 23 19:31:18 2014 +0200
@@ -398,7 +398,7 @@
             case LONG:
                 return "long";
             case DECLARED:
-                return getDeclaredName((DeclaredType) mirror);
+                return getDeclaredName((DeclaredType) mirror, true);
             case ARRAY:
                 return getSimpleName(((ArrayType) mirror).getComponentType()) + "[]";
             case VOID:
@@ -424,10 +424,10 @@
         return b.toString();
     }
 
-    private static String getDeclaredName(DeclaredType element) {
+    public static String getDeclaredName(DeclaredType element, boolean includeTypeVariables) {
         String simpleName = fixECJBinaryNameIssue(element.asElement().getSimpleName().toString());
 
-        if (element.getTypeArguments().size() == 0) {
+        if (!includeTypeVariables || element.getTypeArguments().size() == 0) {
             return simpleName;
         }
 
@@ -655,6 +655,17 @@
         return findPackageElement(element).getQualifiedName().toString();
     }
 
+    public static String getEnclosedQualifiedName(DeclaredType mirror) {
+        Element e = ((TypeElement) mirror.asElement()).getEnclosingElement();
+        if (e.getKind() == ElementKind.PACKAGE) {
+            return ((PackageElement) e).getQualifiedName().toString();
+        } else if (e.getKind().isInterface() || e.getKind().isClass()) {
+            return getQualifiedName((TypeElement) e);
+        } else {
+            return null;
+        }
+    }
+
     public static String getPackageName(TypeMirror mirror) {
         switch (mirror.getKind()) {
             case BOOLEAN:
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeElement.java	Sat Aug 23 19:31:13 2014 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeElement.java	Sat Aug 23 19:31:18 2014 +0200
@@ -41,10 +41,6 @@
     private Element generatorElement;
     private AnnotationMirror generatorAnnotationMirror;
 
-    public CodeElement() {
-        this.modifiers = new LinkedHashSet<>();
-    }
-
     public CodeElement(Set<Modifier> modifiers) {
         this.modifiers = new LinkedHashSet<>(modifiers);
     }
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeElementScanner.java	Sat Aug 23 19:31:13 2014 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeElementScanner.java	Sat Aug 23 19:31:18 2014 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.truffle.dsl.processor.java.model;
 
+import java.util.*;
+
 import javax.lang.model.element.*;
 import javax.lang.model.util.*;
 
@@ -35,12 +37,23 @@
     public R visitExecutable(CodeExecutableElement e, P p) {
         R ret = super.visitExecutable(e, p);
         if (e.getBodyTree() != null) {
-            visitTree(e.getBodyTree(), p);
+            visitTree(e.getBodyTree(), p, e);
         }
         return ret;
     }
 
     @Override
+    public R visitVariable(VariableElement e, P p) {
+        if (e instanceof CodeVariableElement) {
+            CodeTree init = ((CodeVariableElement) e).getInit();
+            if (init != null) {
+                visitTree(init, p, e);
+            }
+        }
+        return super.visitVariable(e, p);
+    }
+
+    @Override
     public R visitPackage(PackageElement e, P p) {
         return super.visitPackage(e, p);
     }
@@ -63,9 +76,12 @@
         return clazz.cast(element);
     }
 
-    public void visitTree(CodeTree e, P p) {
-        for (CodeTree tree : e.getEnclosedElements()) {
-            tree.acceptCodeElementScanner(this, p);
+    public void visitTree(CodeTree e, P p, Element parent) {
+        List<CodeTree> elements = e.getEnclosedElements();
+        if (elements != null) {
+            for (CodeTree tree : e.getEnclosedElements()) {
+                visitTree(tree, p, parent);
+            }
         }
     }
 
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeExecutableElement.java	Sat Aug 23 19:31:13 2014 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeExecutableElement.java	Sat Aug 23 19:31:18 2014 +0200
@@ -117,8 +117,8 @@
 
     public CodeTreeBuilder createBuilder() {
         CodeTreeBuilder builder = new CodeTreeBuilder(null);
+        builder.setEnclosingElement(this);
         this.bodyTree = builder.getTree();
-        this.bodyTree.setEnclosingElement(this);
         this.body = null;
         return builder;
     }
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTree.java	Sat Aug 23 19:31:13 2014 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTree.java	Sat Aug 23 19:31:18 2014 +0200
@@ -22,27 +22,53 @@
  */
 package com.oracle.truffle.dsl.processor.java.model;
 
-import javax.lang.model.element.*;
+import java.util.*;
+
 import javax.lang.model.type.*;
 
-public class CodeTree extends CodeElement<CodeTree> {
+public class CodeTree {
 
     private final CodeTreeKind kind;
 
+    private CodeTree parent;
+
     private TypeMirror type;
     private final String string;
 
-    CodeTree(CodeTreeKind kind, TypeMirror type, String string) {
+    private List<CodeTree> children;
+
+    CodeTree(CodeTree parent, CodeTreeKind kind, TypeMirror type, String string) {
+        this.parent = parent;
         this.kind = kind;
         this.type = type;
         this.string = string;
     }
 
+    public void setParent(CodeTree parent) {
+        this.parent = parent;
+    }
+
+    public CodeTree getParent() {
+        return parent;
+    }
+
     public TypeMirror getType() {
         return type;
     }
 
-    public CodeTreeKind getCodeKind() {
+    public void add(CodeTree element) {
+        if (children == null) {
+            children = new ArrayList<>();
+        }
+        element.setParent(this);
+        children.add(element);
+    }
+
+    public final List<CodeTree> getEnclosedElements() {
+        return children;
+    }
+
+    public final CodeTreeKind getCodeKind() {
         return kind;
     }
 
@@ -50,36 +76,8 @@
         return string;
     }
 
-    public <P> void acceptCodeElementScanner(CodeElementScanner<?, P> s, P p) {
-        s.visitTree(this, p);
-    }
-
     public void setType(TypeMirror type) {
         this.type = type;
     }
 
-    @Override
-    public TypeMirror asType() {
-        return type;
-    }
-
-    @Override
-    public ElementKind getKind() {
-        return ElementKind.OTHER;
-    }
-
-    @Override
-    public Name getSimpleName() {
-        return CodeNames.of(getString());
-    }
-
-    @Override
-    public <R, P> R accept(ElementVisitor<R, P> v, P p) {
-        if (v instanceof CodeElementScanner<?, ?>) {
-            acceptCodeElementScanner((CodeElementScanner<?, P>) v, p);
-            return null;
-        } else {
-            throw new UnsupportedOperationException();
-        }
-    }
 }
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTreeBuilder.java	Sat Aug 23 19:31:13 2014 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTreeBuilder.java	Sat Aug 23 19:31:18 2014 +0200
@@ -33,17 +33,22 @@
 
 public class CodeTreeBuilder {
 
-    private final CodeTreeBuilder parent;
-
     private BuilderCodeTree currentElement;
     private final BuilderCodeTree root;
 
     private int treeCount;
+    private Element enclosingElement;
 
     public CodeTreeBuilder(CodeTreeBuilder parent) {
-        this.root = new BuilderCodeTree(GROUP, null, null);
+        this.root = new BuilderCodeTree(null, GROUP, null, null);
         this.currentElement = root;
-        this.parent = parent;
+        if (parent != null) {
+            this.enclosingElement = parent.enclosingElement;
+        }
+    }
+
+    public void setEnclosingElement(Element enclosingElement) {
+        this.enclosingElement = enclosingElement;
     }
 
     @Override
@@ -80,24 +85,24 @@
     }
 
     private CodeTreeBuilder push(CodeTreeKind kind) {
-        return push(new BuilderCodeTree(kind, null, null));
+        return push(new BuilderCodeTree(currentElement, kind, null, null), kind == NEW_LINE);
     }
 
     private CodeTreeBuilder push(String string) {
-        return push(new BuilderCodeTree(CodeTreeKind.STRING, null, string));
+        return push(new BuilderCodeTree(currentElement, CodeTreeKind.STRING, null, string), false);
     }
 
     private CodeTreeBuilder push(TypeMirror type) {
-        return push(new BuilderCodeTree(CodeTreeKind.TYPE, type, null));
+        return push(new BuilderCodeTree(currentElement, CodeTreeKind.TYPE, type, null), false);
     }
 
     private CodeTreeBuilder push(CodeTreeKind kind, TypeMirror type, String string) {
-        return push(new BuilderCodeTree(kind, type, string));
+        return push(new BuilderCodeTree(currentElement, kind, type, string), kind == NEW_LINE);
     }
 
-    private CodeTreeBuilder push(BuilderCodeTree tree) {
+    private CodeTreeBuilder push(BuilderCodeTree tree, boolean removeLast) {
         if (currentElement != null) {
-            if (!removeLastIfEnqueued(tree)) {
+            if (removeLast && !removeLastIfEnqueued(tree)) {
                 return this;
             }
             currentElement.add(tree);
@@ -118,7 +123,7 @@
             return !clearLastRec(tree.removeLast, currentElement.getEnclosedElements());
         }
         List<CodeTree> childTree = tree.getEnclosedElements();
-        if (!childTree.isEmpty()) {
+        if (childTree != null && !childTree.isEmpty()) {
             CodeTree last = childTree.get(0);
             if (last instanceof BuilderCodeTree) {
                 if (!removeLastIfEnqueued((BuilderCodeTree) last)) {
@@ -134,9 +139,9 @@
             treeCount--;
         } else {
             // delay clearing the last
-            BuilderCodeTree tree = new BuilderCodeTree(REMOVE_LAST, null, null);
+            BuilderCodeTree tree = new BuilderCodeTree(currentElement, REMOVE_LAST, null, null);
             tree.removeLast = kind;
-            push(tree);
+            push(tree, false);
         }
     }
 
@@ -299,11 +304,11 @@
 
     public CodeTreeBuilder tree(CodeTree treeToAdd) {
         if (treeToAdd instanceof BuilderCodeTree) {
-            return push((BuilderCodeTree) treeToAdd).end();
+            return push((BuilderCodeTree) treeToAdd, true).end();
         } else {
-            BuilderCodeTree tree = new BuilderCodeTree(GROUP, null, null);
-            tree.add(treeToAdd);
-            return push(tree).end();
+            BuilderCodeTree tree = new BuilderCodeTree(currentElement, GROUP, null, null);
+            currentElement.add(treeToAdd);
+            return push(tree, true).end();
         }
     }
 
@@ -364,6 +369,9 @@
     }
 
     private boolean clearLastRec(CodeTreeKind kind, List<CodeTree> children) {
+        if (children == null) {
+            return false;
+        }
         for (int i = children.size() - 1; i >= 0; i--) {
             CodeTree child = children.get(i);
             if (child.getCodeKind() == kind) {
@@ -474,7 +482,7 @@
     }
 
     private void toParent() {
-        Element parentElement = currentElement.getEnclosingElement();
+        CodeTree parentElement = currentElement.getParent();
         if (currentElement != root) {
             this.currentElement = (BuilderCodeTree) parentElement;
         } else {
@@ -640,15 +648,10 @@
     }
 
     public ExecutableElement findMethod() {
-        Element element = currentElement;
-        while (element != null && (element.getKind() != ElementKind.METHOD && (element.getKind() != ElementKind.CONSTRUCTOR))) {
-            element = element.getEnclosingElement();
+        if (enclosingElement != null && (enclosingElement.getKind() == ElementKind.METHOD || enclosingElement.getKind() == ElementKind.CONSTRUCTOR)) {
+            return (ExecutableElement) enclosingElement;
         }
-        ExecutableElement found = element != null ? (ExecutableElement) element : null;
-        if (found == null && parent != null) {
-            found = parent.findMethod();
-        }
-        return found;
+        return null;
     }
 
     public CodeTreeBuilder returnNull() {
@@ -751,8 +754,8 @@
         private EndCallback atEndListener;
         private CodeTreeKind removeLast;
 
-        public BuilderCodeTree(CodeTreeKind kind, TypeMirror type, String string) {
-            super(kind, type, string);
+        public BuilderCodeTree(CodeTree parent, CodeTreeKind kind, TypeMirror type, String string) {
+            super(parent, kind, type, string);
         }
 
         public void registerAtEnd(EndCallback atEnd) {
@@ -770,7 +773,7 @@
         @Override
         public String toString() {
             final StringBuilder b = new StringBuilder();
-            acceptCodeElementScanner(new Printer(b), null);
+            new Printer(b).visitTree(this, null, null);
             return b.toString();
         }
 
@@ -819,23 +822,25 @@
         }
 
         @Override
-        public void visitTree(CodeTree e, Void p) {
+        public void visitTree(CodeTree e, Void p, Element enclosingElement) {
             switch (e.getCodeKind()) {
                 case COMMA_GROUP:
                     List<CodeTree> children = e.getEnclosedElements();
-                    for (int i = 0; i < children.size(); i++) {
-                        children.get(i).acceptCodeElementScanner(this, p);
-                        if (i < e.getEnclosedElements().size() - 1) {
-                            b.append(", ");
+                    if (children != null) {
+                        for (int i = 0; i < children.size(); i++) {
+                            visitTree(children.get(i), p, enclosingElement);
+                            if (i < e.getEnclosedElements().size() - 1) {
+                                b.append(", ");
+                            }
                         }
                     }
                     break;
                 case GROUP:
-                    super.visitTree(e, p);
+                    super.visitTree(e, p, enclosingElement);
                     break;
                 case INDENT:
                     indent();
-                    super.visitTree(e, p);
+                    super.visitTree(e, p, enclosingElement);
                     dedent();
                     break;
                 case NEW_LINE:
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeVariableElement.java	Sat Aug 23 19:31:13 2014 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeVariableElement.java	Sat Aug 23 19:31:18 2014 +0200
@@ -52,14 +52,14 @@
     public CodeVariableElement(Set<Modifier> modifiers, TypeMirror type, String name, String init) {
         this(modifiers, type, name);
         if (init != null) {
-            this.init = new CodeTree(CodeTreeKind.STRING, null, init);
+            this.init = new CodeTree(null, CodeTreeKind.STRING, null, init);
         }
     }
 
     public CodeTreeBuilder createInitBuilder() {
         CodeTreeBuilder builder = new CodeTreeBuilder(null);
+        builder.setEnclosingElement(this);
         init = builder.getTree();
-        init.setEnclosingElement(this);
         return builder;
     }
 
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/GeneratedPackageElement.java	Sat Aug 23 19:31:13 2014 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/GeneratedPackageElement.java	Sat Aug 23 19:31:18 2014 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.truffle.dsl.processor.java.model;
 
+import java.util.*;
+
 import javax.lang.model.element.*;
 import javax.lang.model.type.*;
 
@@ -31,6 +33,7 @@
     private final Name simpleName;
 
     public GeneratedPackageElement(String qualifiedName) {
+        super(Collections.<Modifier> emptySet());
         this.qualifiedName = CodeNames.of(qualifiedName);
         int lastIndex = qualifiedName.lastIndexOf('.');
         if (lastIndex == -1) {
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/transform/AbstractCodeWriter.java	Sat Aug 23 19:31:13 2014 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/transform/AbstractCodeWriter.java	Sat Aug 23 19:31:18 2014 +0200
@@ -262,7 +262,7 @@
             write(f.getSimpleName());
             if (init != null) {
                 write("(");
-                init.acceptCodeElementScanner(this, p);
+                visitTree(init, p, f);
                 write(")");
             }
         } else {
@@ -292,7 +292,7 @@
             write(f.getSimpleName());
             if (init != null) {
                 write(" = ");
-                init.acceptCodeElementScanner(this, p);
+                visitTree(init, p, f);
             }
         }
         return null;
@@ -459,11 +459,14 @@
 
     @Override
     public void visitImport(CodeImport e, Void p) {
+        write("import ");
         if (e.isStaticImport()) {
-            write("import static ").write(e.getImportString()).write(";");
-        } else {
-            write("import ").write(e.getImportString()).write(";");
+            write("static ");
         }
+        write(e.getPackageName());
+        write(".");
+        write(e.getSymbolName());
+        write(";");
     }
 
     @Override
@@ -507,7 +510,7 @@
         } else if (e.getBodyTree() != null) {
             writeLn(" {");
             indent(1);
-            e.getBodyTree().acceptCodeElementScanner(this, p);
+            visitTree(e.getBodyTree(), p, e);
             dedent(1);
             writeLn("}");
         } else if (e.getBody() != null) {
@@ -522,29 +525,27 @@
     }
 
     @Override
-    public void visitTree(CodeTree e, Void p) {
+    public void visitTree(CodeTree e, Void p, Element enclosingElement) {
         CodeTreeKind kind = e.getCodeKind();
 
         switch (kind) {
             case COMMA_GROUP:
                 List<CodeTree> children = e.getEnclosedElements();
-                for (int i = 0; i < children.size(); i++) {
-                    children.get(i).acceptCodeElementScanner(this, p);
-                    if (i < e.getEnclosedElements().size() - 1) {
-                        write(", ");
+                if (children != null) {
+                    for (int i = 0; i < children.size(); i++) {
+                        visitTree(children.get(i), p, enclosingElement);
+                        if (i < e.getEnclosedElements().size() - 1) {
+                            write(", ");
+                        }
                     }
                 }
                 break;
             case GROUP:
-                for (CodeTree tree : e.getEnclosedElements()) {
-                    tree.acceptCodeElementScanner(this, p);
-                }
+                super.visitTree(e, p, enclosingElement);
                 break;
             case INDENT:
                 indent(1);
-                for (CodeTree tree : e.getEnclosedElements()) {
-                    tree.acceptCodeElementScanner(this, p);
-                }
+                super.visitTree(e, p, enclosingElement);
                 dedent(1);
                 break;
             case NEW_LINE:
@@ -559,20 +560,20 @@
                 break;
             case STATIC_FIELD_REFERENCE:
                 if (e.getString() != null) {
-                    write(imports.createStaticFieldReference(e, e.getType(), e.getString()));
+                    write(imports.createStaticFieldReference(enclosingElement, e.getType(), e.getString()));
                 } else {
                     write("null");
                 }
                 break;
             case STATIC_METHOD_REFERENCE:
                 if (e.getString() != null) {
-                    write(imports.createStaticMethodReference(e, e.getType(), e.getString()));
+                    write(imports.createStaticMethodReference(enclosingElement, e.getType(), e.getString()));
                 } else {
                     write("null");
                 }
                 break;
             case TYPE:
-                write(useImport(e, e.getType()));
+                write(useImport(enclosingElement, e.getType()));
                 break;
             default:
                 assert false;
@@ -676,8 +677,9 @@
 
                 // TODO(CH): fails in normal usage - output ok though
                 // assert lineLength + (end - i) + 2 < MAX_LINE_LENGTH;
-
-                write("\"" + string.substring(i, end) + "\"");
+                write("\"");
+                write(string.substring(i, end));
+                write("\"");
                 size = nextSize;
             }
 
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/transform/FixWarningsVisitor.java	Sat Aug 23 19:31:13 2014 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/transform/FixWarningsVisitor.java	Sat Aug 23 19:31:18 2014 +0200
@@ -103,11 +103,11 @@
     }
 
     @Override
-    public void visitTree(CodeTree e, Void p) {
+    public void visitTree(CodeTree e, Void p, Element enclosingElement) {
         if (e.getString() != null) {
             computeSymbols(e.getString());
         }
-        super.visitTree(e, p);
+        super.visitTree(e, p, enclosingElement);
     }
 
     private void computeSymbols(String s) {
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/TemplateMethod.java	Sat Aug 23 19:31:13 2014 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/TemplateMethod.java	Sat Aug 23 19:31:18 2014 +0200
@@ -44,7 +44,8 @@
     private final ExecutableElement method;
     private final AnnotationMirror markerAnnotation;
     private Parameter returnType;
-    private List<Parameter> parameters;
+    private final List<Parameter> parameters;
+    private final Map<String, Parameter> parameterCache = new HashMap<>();
 
     public TemplateMethod(String id, int naturalOrder, Template template, MethodSpec specification, ExecutableElement method, AnnotationMirror markerAnnotation, Parameter returnType,
                     List<Parameter> parameters) {
@@ -59,7 +60,9 @@
             Parameter newParam = new Parameter(param);
             this.parameters.add(newParam);
             newParam.setMethod(this);
+            parameterCache.put(param.getLocalName(), param);
         }
+        parameterCache.put(returnType.getLocalName(), returnType);
         this.id = id;
     }
 
@@ -77,10 +80,6 @@
         getMessages().addAll(method.getMessages());
     }
 
-    public void setParameters(List<Parameter> parameters) {
-        this.parameters = parameters;
-    }
-
     @Override
     public Element getMessageElement() {
         return method;
@@ -120,14 +119,10 @@
         if (returnType.getLocalName().equals(localName)) {
             returnType = newParameter;
             returnType.setMethod(this);
-        }
-
-        for (ListIterator<Parameter> iterator = parameters.listIterator(); iterator.hasNext();) {
-            Parameter parameter = iterator.next();
-            if (parameter.getLocalName().equals(localName)) {
-                iterator.set(newParameter);
-                newParameter.setMethod(this);
-            }
+        } else {
+            Parameter local = findParameter(localName);
+            int index = parameters.indexOf(local);
+            parameters.set(index, newParameter);
         }
     }
 
@@ -175,12 +170,7 @@
     }
 
     public Parameter findParameter(String valueName) {
-        for (Parameter param : getReturnTypeAndParameters()) {
-            if (param.getLocalName().equals(valueName)) {
-                return param;
-            }
-        }
-        return null;
+        return parameterCache.get(valueName);
     }
 
     public List<Parameter> getReturnTypeAndParameters() {