diff graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/SpecializedNodeFactory.java @ 18753:f6b8787dc113

Truffle-DSL: replace complex factory system with a much simpler version
author Christian Humer <christian.humer@gmail.com>
date Mon, 29 Dec 2014 23:38:21 +0100
parents 1acaa69ff61b
children 59bf50cc5a32
line wrap: on
line diff
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/SpecializedNodeFactory.java	Mon Dec 29 23:38:16 2014 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/SpecializedNodeFactory.java	Mon Dec 29 23:38:21 2014 +0100
@@ -32,6 +32,7 @@
 import javax.lang.model.util.*;
 
 import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.dsl.processor.*;
 import com.oracle.truffle.dsl.processor.java.*;
 import com.oracle.truffle.dsl.processor.java.model.*;
 import com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror;
@@ -42,18 +43,18 @@
 
     protected final CodeTypeElement nodeGen;
 
-    public SpecializedNodeFactory(CodeTypeElement nodeGen) {
+    public SpecializedNodeFactory(ProcessorContext context, NodeData node, SpecializationData specialization, CodeTypeElement nodeGen) {
+        super(context, node, specialization);
         this.nodeGen = nodeGen;
     }
 
     @Override
-    public CodeTypeElement create(SpecializationData specialization) {
-        NodeData node = specialization.getNode();
+    public CodeTypeElement create() {
         TypeMirror baseType = node.getNodeType();
         if (nodeGen != null) {
             baseType = nodeGen.asType();
         }
-        CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodeSpecializationClassName(specialization), baseType, false);
+        CodeTypeElement clazz = GeneratorUtils.createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodeSpecializationClassName(specialization), baseType, false);
 
         if (specialization.isSpecialized() || specialization.isUninitialized()) {
             clazz.add(createGetMetadata0(false));
@@ -72,12 +73,38 @@
         } else {
             throw new AssertionError();
         }
-        clazz.getAnnotationMirrors().add(createNodeInfo(node, cost));
+        clazz.getAnnotationMirrors().add(createNodeInfo(cost));
 
         if (specialization.isUninitialized() && node.getGenericSpecialization().isReachable()) {
             clazz.add(createUninitializedGetCostOverride());
         }
 
+        createConstructors(clazz);
+
+        createExecuteMethods(clazz);
+        createCachedExecuteMethods(clazz);
+
+        if (specialization.isUninitialized()) {
+            if (specialization.getNode().isFallbackReachable()) {
+                CodeVariableElement var = new CodeVariableElement(modifiers(Modifier.PRIVATE), context.getType(boolean.class), CONTAINS_FALLBACK);
+                var.addAnnotationMirror(new CodeAnnotationMirror(context.getTruffleTypes().getCompilationFinal()));
+                clazz.add(var);
+            }
+            clazz.add(createExecuteUninitialized());
+        }
+
+        if (!specialization.isUninitialized() && specialization.getNode().needsRewrites(context)) {
+            clazz.add(createCopyConstructorFactoryMethod(clazz, nodeGen.asType()));
+        } else {
+            for (ExecutableElement constructor : ElementFilter.constructorsIn(clazz.getEnclosedElements())) {
+                if (constructor.getParameters().size() == 1 && ((CodeVariableElement) constructor.getParameters().get(0)).getType().equals(nodeGen.asType())) {
+                    // skip copy constructor - not used
+                    continue;
+                }
+                clazz.add(createConstructorFactoryMethod(clazz, constructor));
+            }
+        }
+
         return clazz;
     }
 
@@ -97,9 +124,6 @@
 
         CodeTreeBuilder builder = includes.createInitBuilder();
 
-        SpecializationData specialization = getModel();
-        NodeData node = specialization.getNode();
-
         Set<SpecializationData> contains = specialization.getContains();
         if (specialization.isUninitialized()) {
             contains = new HashSet<>();
@@ -115,10 +139,10 @@
         }
 
         builder.startNew(context.getTruffleTypes().getDslMetadata());
-        builder.startGroup().string(nodeSpecializationClassName(getModel()), ".class").end();
+        builder.startGroup().string(nodeSpecializationClassName(getSpecialization()), ".class").end();
         builder.tree(createSpecializationListLiteral(builder, contains));
-        builder.tree(createSpecializationListLiteral(builder, getModel().getExcludedBy()));
-        builder.tree(createSpecializationTypeLiteral(builder, SpecializationData.getSignatureTypes(getModel())));
+        builder.tree(createSpecializationListLiteral(builder, getSpecialization().getExcludedBy()));
+        builder.tree(createSpecializationTypeLiteral(builder, SpecializationData.getSignatureTypes(getSpecialization())));
         builder.string("0").string("0");
         builder.end();
         return includes;
@@ -149,10 +173,10 @@
             builder.staticReference(context.getTruffleTypes().getDslMetadata(), EMPTY_CLASS_ARRAY);
         } else {
             builder.startNewArray(classArray, null);
-            for (SpecializationData specialization : list) {
-                SpecializationData s = specialization;
+            for (SpecializationData current : list) {
+                SpecializationData s = current;
                 if (s.isGeneric() || s.isPolymorphic()) {
-                    s = getModel().getNode().getUninitializedSpecialization();
+                    s = getSpecialization().getNode().getUninitializedSpecialization();
                 }
                 builder.startGroup().string(nodeSpecializationClassName(s)).string(".class").end();
             }
@@ -162,54 +186,22 @@
         return builder.getRoot();
     }
 
-    protected CodeAnnotationMirror createNodeInfo(NodeData node, NodeCost cost) {
+    protected CodeAnnotationMirror createNodeInfo(NodeCost cost) {
         String shortName = node.getShortName();
-        CodeAnnotationMirror nodeInfoMirror = new CodeAnnotationMirror(getContext().getTruffleTypes().getNodeInfoAnnotation());
+        CodeAnnotationMirror nodeInfoMirror = new CodeAnnotationMirror(context.getTruffleTypes().getNodeInfoAnnotation());
         if (shortName != null) {
             nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("shortName"), new CodeAnnotationValue(shortName));
         }
 
-        DeclaredType nodeinfoCost = getContext().getTruffleTypes().getNodeCost();
+        DeclaredType nodeinfoCost = context.getTruffleTypes().getNodeCost();
         VariableElement varKind = ElementUtils.findVariableElement(nodeinfoCost, cost.name());
 
         nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("cost"), new CodeAnnotationValue(varKind));
         return nodeInfoMirror;
     }
 
-    @Override
-    protected void createChildren(SpecializationData specialization) {
-        CodeTypeElement clazz = getElement();
-        createConstructors(clazz);
-
-        createExecuteMethods(specialization);
-        createCachedExecuteMethods(specialization);
-
-        if (specialization.isUninitialized()) {
-            if (specialization.getNode().isFallbackReachable()) {
-                CodeVariableElement var = new CodeVariableElement(modifiers(Modifier.PRIVATE), context.getType(boolean.class), CONTAINS_FALLBACK);
-                var.addAnnotationMirror(new CodeAnnotationMirror(context.getTruffleTypes().getCompilationFinal()));
-                clazz.add(var);
-            }
-            clazz.add(createExecuteUninitialized());
-        }
-
-        if (!specialization.isUninitialized() && specialization.getNode().needsRewrites(context)) {
-            clazz.add(createCopyConstructorFactoryMethod(nodeGen.asType(), specialization));
-        } else {
-            for (ExecutableElement constructor : ElementFilter.constructorsIn(clazz.getEnclosedElements())) {
-                if (constructor.getParameters().size() == 1 && ((CodeVariableElement) constructor.getParameters().get(0)).getType().equals(nodeGen.asType())) {
-                    // skip copy constructor - not used
-                    continue;
-                }
-                clazz.add(createConstructorFactoryMethod(specialization, constructor));
-            }
-        }
-    }
-
     protected void createConstructors(CodeTypeElement clazz) {
         TypeElement superTypeElement = ElementUtils.fromTypeMirror(clazz.getSuperclass());
-        SpecializationData specialization = getModel();
-        NodeData node = specialization.getNode();
         for (ExecutableElement constructor : ElementFilter.constructorsIn(superTypeElement.getEnclosedElements())) {
             if (specialization.isUninitialized()) {
                 // ignore copy constructors for uninitialized if not polymorphic
@@ -223,7 +215,7 @@
                 }
             }
 
-            CodeExecutableElement superConstructor = createSuperConstructor(clazz, constructor);
+            CodeExecutableElement superConstructor = GeneratorUtils.createSuperConstructor(context, clazz, constructor);
             if (superConstructor == null) {
                 continue;
             }
@@ -232,9 +224,9 @@
             builder.tree(body);
 
             if (superConstructor != null) {
-                for (Parameter param : getImplicitTypeParameters(getModel())) {
-                    clazz.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), getContext().getType(Class.class), implicitTypeName(param)));
-                    superConstructor.getParameters().add(new CodeVariableElement(getContext().getType(Class.class), implicitTypeName(param)));
+                for (Parameter param : getImplicitTypeParameters(getSpecialization())) {
+                    clazz.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), context.getType(Class.class), implicitTypeName(param)));
+                    superConstructor.getParameters().add(new CodeVariableElement(context.getType(Class.class), implicitTypeName(param)));
 
                     builder.startStatement();
                     builder.string("this.").string(implicitTypeName(param)).string(" = ").string(implicitTypeName(param));
@@ -246,9 +238,7 @@
         }
     }
 
-    protected void createExecuteMethods(SpecializationData specialization) {
-        NodeData node = specialization.getNode();
-        CodeTypeElement clazz = getElement();
+    protected void createExecuteMethods(CodeTypeElement clazz) {
 
         List<ExecutableTypeData> primaryExecutes = null;
         int lastEvaluatedCount = -1;
@@ -259,13 +249,13 @@
             }
             if (execType.getEvaluatedCount() != lastEvaluatedCount) {
                 lastEvaluatedCount = execType.getEvaluatedCount();
-                primaryExecutes = findFunctionalExecutableType(specialization, lastEvaluatedCount);
+                primaryExecutes = findFunctionalExecutableType(lastEvaluatedCount);
             }
 
             CodeExecutableElement executeMethod = createExecutableTypeOverride(execType, true);
             clazz.add(executeMethod);
             CodeTreeBuilder builder = executeMethod.getBuilder();
-            CodeTree result = createExecuteBody(builder, specialization, execType, primaryExecutes);
+            CodeTree result = createExecuteBody(builder, execType, primaryExecutes);
             if (result != null) {
                 builder.tree(result);
             } else {
@@ -274,17 +264,14 @@
         }
     }
 
-    protected void createCachedExecuteMethods(SpecializationData specialization) {
-        NodeData node = specialization.getNode();
+    protected void createCachedExecuteMethods(CodeTypeElement clazz) {
         if (!node.isPolymorphic(context)) {
             return;
         }
 
-        CodeTypeElement clazz = getElement();
-
         final SpecializationData polymorphic = node.getPolymorphicSpecialization();
         ExecutableElement executeCached = nodeGen.getMethod(EXECUTE_CHAINED);
-        CodeExecutableElement executeMethod = CodeExecutableElement.clone(getContext().getEnvironment(), executeCached);
+        CodeExecutableElement executeMethod = CodeExecutableElement.clone(context.getEnvironment(), executeCached);
         executeMethod.getModifiers().remove(Modifier.ABSTRACT);
         CodeTreeBuilder builder = executeMethod.createBuilder();
 
@@ -325,14 +312,14 @@
         return builder.getRoot();
     }
 
-    private CodeTree createExecuteBody(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData execType, List<ExecutableTypeData> primaryExecutes) {
+    private CodeTree createExecuteBody(CodeTreeBuilder parent, ExecutableTypeData execType, List<ExecutableTypeData> primaryExecutes) {
         CodeTreeBuilder builder = new CodeTreeBuilder(parent);
 
         if (primaryExecutes.contains(execType) || primaryExecutes.isEmpty()) {
-            builder.tree(createFunctionalExecute(builder, specialization, execType));
+            builder.tree(createFunctionalExecute(builder, execType));
         } else if (needsCastingExecuteMethod(execType)) {
             assert !primaryExecutes.isEmpty();
-            builder.tree(createCastingExecute(builder, specialization, execType, primaryExecutes.get(0)));
+            builder.tree(createCastingExecute(builder, execType, primaryExecutes.get(0)));
         } else {
             return null;
         }
@@ -341,7 +328,7 @@
     }
 
     private CodeExecutableElement createExecutableTypeOverride(ExecutableTypeData execType, boolean evaluated) {
-        CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), execType.getMethod());
+        CodeExecutableElement method = CodeExecutableElement.clone(context.getEnvironment(), execType.getMethod());
 
         method.getAnnotationMirrors().clear();
         for (VariableElement variable : method.getParameters()) {
@@ -366,7 +353,7 @@
                     name = valueName(actualParameter);
                 }
 
-                int varArgCount = getModel().getSignatureSize() - signatureIndex;
+                int varArgCount = getSpecialization().getSignatureSize() - signatureIndex;
                 if (evaluated && actualParameter.isTypeVarArgs()) {
                     Parameter baseVarArgs = actualParameter;
                     name = valueName(baseVarArgs) + "Args";
@@ -411,7 +398,7 @@
         return false;
     }
 
-    private List<ExecutableTypeData> findFunctionalExecutableType(SpecializationData specialization, int evaluatedCount) {
+    private List<ExecutableTypeData> findFunctionalExecutableType(int evaluatedCount) {
         TypeData primaryType = specialization.getReturnType().getTypeSystemType();
         List<ExecutableTypeData> otherTypes = specialization.getNode().getExecutableTypes(evaluatedCount);
 
@@ -425,7 +412,7 @@
         // no direct matches found use generic where the type is Object
         if (filteredTypes.isEmpty()) {
             for (ExecutableTypeData compareType : otherTypes) {
-                if (compareType.getType().isGeneric() && !compareType.hasUnexpectedValue(getContext())) {
+                if (compareType.getType().isGeneric() && !compareType.hasUnexpectedValue(context)) {
                     filteredTypes.add(compareType);
                 }
             }
@@ -442,7 +429,7 @@
         return filteredTypes;
     }
 
-    private CodeTree createFunctionalExecute(CodeTreeBuilder parent, final SpecializationData specialization, final ExecutableTypeData executable) {
+    private CodeTree createFunctionalExecute(CodeTreeBuilder parent, final ExecutableTypeData executable) {
         CodeTreeBuilder builder = new CodeTreeBuilder(parent);
 
         if (specialization.isUninitialized()) {
@@ -456,23 +443,21 @@
         if (specialization.findNextSpecialization() != null) {
             CodeTreeBuilder returnBuilder = new CodeTreeBuilder(builder);
             returnBuilder.tree(createDeoptimize(builder));
-            returnBuilder.tree(createCallRewriteMonomorphic(builder, executable.hasUnexpectedValue(context), executable.getType(), specialization, null, "One of guards " + specialization.getGuards() +
-                            " failed"));
+            returnBuilder.tree(createCallRewriteMonomorphic(builder, executable.hasUnexpectedValue(context), executable.getType(), null, "One of guards " + specialization.getGuards() + " failed"));
             returnSpecialized = returnBuilder.getRoot();
         }
 
         builder.tree(createExecuteTree(builder, specialization, SpecializationGroup.create(specialization), new CodeBlock<SpecializationData>() {
 
             public CodeTree create(CodeTreeBuilder b, SpecializationData current) {
-                return createExecute(b, executable, specialization);
+                return createExecute(b, executable);
             }
         }, returnSpecialized, false, false, false, false));
 
         return builder.getRoot();
     }
 
-    private CodeTree createExecute(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData specialization) {
-        NodeData node = specialization.getNode();
+    private CodeTree createExecute(CodeTreeBuilder parent, ExecutableTypeData executable) {
         CodeTreeBuilder builder = new CodeTreeBuilder(parent);
         if (!specialization.getExceptions().isEmpty() || !specialization.getAssumptions().isEmpty()) {
             builder.startTryBlock();
@@ -494,7 +479,7 @@
             addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, false, null);
             returnBuilder.end();
         } else if (specialization.getMethod() == null && !node.needsRewrites(context)) {
-            emitEncounteredSynthetic(builder, getModel().getNode(), specialization);
+            emitEncounteredSynthetic(builder, getSpecialization().getNode(), specialization);
         } else {
             returnBuilder.tree(createTemplateMethodCall(returnBuilder, null, specialization, specialization, null));
         }
@@ -522,31 +507,30 @@
             for (SpecializationThrowsData exception : specialization.getExceptions()) {
                 builder.end().startCatchBlock(exception.getJavaClass(), "ex");
                 builder.tree(createDeoptimize(builder));
-                builder.tree(createCallRewriteMonomorphic(parent, executable.hasUnexpectedValue(context), executable.getType(), specialization, null,
-                                "Thrown " + ElementUtils.getSimpleName(exception.getJavaClass())));
+                builder.tree(createCallRewriteMonomorphic(parent, executable.hasUnexpectedValue(context), executable.getType(), null, "Thrown " + ElementUtils.getSimpleName(exception.getJavaClass())));
             }
             builder.end();
         }
         if (!specialization.getAssumptions().isEmpty()) {
-            builder.end().startCatchBlock(getContext().getTruffleTypes().getInvalidAssumption(), "ex");
-            builder.tree(createCallRewriteMonomorphic(parent, executable.hasUnexpectedValue(context), executable.getType(), specialization, null, "Assumption failed"));
+            builder.end().startCatchBlock(context.getTruffleTypes().getInvalidAssumption(), "ex");
+            builder.tree(createCallRewriteMonomorphic(parent, executable.hasUnexpectedValue(context), executable.getType(), null, "Assumption failed"));
             builder.end();
         }
 
         return builder.getRoot();
     }
 
-    private CodeExecutableElement createCopyConstructorFactoryMethod(TypeMirror baseType, SpecializationData specialization) {
+    private CodeExecutableElement createCopyConstructorFactoryMethod(CodeTypeElement clazz, TypeMirror baseType) {
         List<Parameter> implicitTypeParams = getImplicitTypeParameters(specialization);
         String baseName = "current";
         CodeExecutableElement method = new CodeExecutableElement(modifiers(STATIC), specialization.getNode().getNodeType(), NodeFactoryFactory.FACTORY_METHOD_NAME);
         method.addParameter(new CodeVariableElement(specialization.getNode().getNodeType(), baseName));
         for (Parameter implicitTypeParam : implicitTypeParams) {
-            method.addParameter(new CodeVariableElement(getContext().getType(Class.class), implicitTypeName(implicitTypeParam)));
+            method.addParameter(new CodeVariableElement(context.getType(Class.class), implicitTypeName(implicitTypeParam)));
         }
         CodeTreeBuilder builder = method.createBuilder();
         builder.startReturn();
-        builder.startNew(getElement().asType());
+        builder.startNew(clazz.asType());
         builder.startGroup().cast(baseType, CodeTreeBuilder.singleString(baseName)).end();
         for (Parameter param : implicitTypeParams) {
             builder.string(implicitTypeName(param));
@@ -555,13 +539,13 @@
         return method;
     }
 
-    private CodeExecutableElement createConstructorFactoryMethod(SpecializationData specialization, ExecutableElement constructor) {
+    private CodeExecutableElement createConstructorFactoryMethod(CodeTypeElement clazz, ExecutableElement constructor) {
         List<? extends VariableElement> parameters = constructor.getParameters();
         CodeExecutableElement method = new CodeExecutableElement(modifiers(STATIC), specialization.getNode().getNodeType(), NodeFactoryFactory.FACTORY_METHOD_NAME,
                         parameters.toArray(new CodeVariableElement[parameters.size()]));
         CodeTreeBuilder builder = method.createBuilder();
         builder.startReturn();
-        builder.startNew(getElement().asType());
+        builder.startNew(clazz.asType());
         for (VariableElement param : parameters) {
             builder.string(((CodeVariableElement) param).getName());
         }