# HG changeset patch # User Christian Humer # Date 1362406451 -3600 # Node ID ac4e8c16ffdf95368583014b984fd87b6eb6b467 # Parent 91982900aceeede37782d8249f94e35107680830 Added new codegen api classes NodeId, NodeClass to codegen along with some refactorings. diff -r 91982900acee -r ac4e8c16ffdf graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeClass.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeClass.java Mon Mar 04 15:14:11 2013 +0100 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012, 2012, 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.api.codegen; + +import java.lang.annotation.*; + +import com.oracle.truffle.api.nodes.*; + +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.TYPE}) +public @interface NodeClass { + + Class value(); + +} diff -r 91982900acee -r ac4e8c16ffdf graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeId.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeId.java Mon Mar 04 15:14:11 2013 +0100 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2012, 2012, 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.api.codegen; + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.METHOD, ElementType.TYPE}) +public @interface NodeId { + + String value(); + +} diff -r 91982900acee -r ac4e8c16ffdf graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Mon Mar 04 15:13:25 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Mon Mar 04 15:14:11 2013 +0100 @@ -71,7 +71,7 @@ private static String specializationId(SpecializationData specialization) { String name = ""; NodeData node = specialization.getNode(); - if (node.getSpecializations().length > 1) { + if (node.getSpecializations().size() > 1) { name = specialization.getMethodName(); if (name.startsWith("do")) { name = name.substring(2); @@ -480,7 +480,7 @@ if (node.needsFactory()) { createFactoryMethods(node, clazz, createVisibility); - if (node.getSpecializations().length > 1) { + if (node.getSpecializations().size() > 1) { clazz.add(createCreateSpecializedMethod(node, createVisibility)); } @@ -781,10 +781,10 @@ CodeTreeBuilder body = method.createBuilder(); body.startReturn(); - if (node.getSpecializations().length == 0) { + if (node.getSpecializations().isEmpty()) { body.null_(); } else { - body.startNew(nodeClassName(node.getSpecializations()[0])); + body.startNew(nodeClassName(node.getSpecializations().get(0))); for (VariableElement var : method.getParameters()) { body.string(var.getSimpleName().toString()); } @@ -836,10 +836,10 @@ addValueParameters(method, node.getGenericSpecialization(), false); CodeTreeBuilder body = method.createBuilder(); - body.startStatement().string("boolean allowed = (minimumState == ").string(nodeClassName(node.getSpecializations()[0])).string(".class)").end(); + body.startStatement().string("boolean allowed = (minimumState == ").string(nodeClassName(node.getSpecializations().get(0))).string(".class)").end(); - for (int i = 1; i < node.getSpecializations().length; i++) { - SpecializationData specialization = node.getSpecializations()[i]; + for (int i = 1; i < node.getSpecializations().size(); i++) { + SpecializationData specialization = node.getSpecializations().get(i); body.startStatement().string("allowed = allowed || (minimumState == ").string(nodeClassName(specialization)).string(".class)").end(); CodeTreeBuilder guarded = new CodeTreeBuilder(body); @@ -859,11 +859,11 @@ if (node.getGenericSpecialization().isUseSpecializationsForGeneric()) { List methods = new ArrayList<>(); - SpecializationData[] specializations = node.getSpecializations(); + List specializations = node.getSpecializations(); SpecializationData prev = null; - for (int i = 0; i < specializations.length; i++) { - SpecializationData current = specializations[i]; - SpecializationData next = i + 1 < specializations.length ? specializations[i + 1] : null; + for (int i = 0; i < specializations.size(); i++) { + SpecializationData current = specializations.get(i); + SpecializationData next = i + 1 < specializations.size() ? specializations.get(i + 1) : null; if (prev == null || current.isUninitialized()) { prev = current; continue; @@ -1195,7 +1195,7 @@ builder.string(" = "); ExecutableTypeData genericExecutableType = field.getNodeData().findGenericExecutableType(getContext(), param.getActualTypeData(node.getTypeSystem())); if (genericExecutableType == null) { - throw new AssertionError("Must have generic executable type. Parser validation most likely failed. " + Arrays.toString(field.getNodeData().getExecutableTypes())); + throw new AssertionError("Must have generic executable type. Parser validation most likely failed. " + (field.getNodeData().getExecutableTypes())); } buildExecute(builder, param, field, genericExecutableType); builder.end(); diff -r 91982900acee -r ac4e8c16ffdf graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java Mon Mar 04 15:13:25 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java Mon Mar 04 15:14:11 2013 +0100 @@ -35,18 +35,18 @@ public class NodeData extends Template { - private NodeData parent; + private NodeData declaringNode; private List declaredChildren; private final TypeSystemData typeSystem; + private List fields; + private TypeMirror nodeType; - private NodeFieldData[] fields; - private SpecializationData[] specializations; - private TemplateMethod[] specializationListeners; - private GuardData[] guards; - private ExecutableTypeData[] executableTypes; - - private TypeMirror nodeType; + private List specializations; + private List specializationListeners; + private List guards; + private List executableTypes; + private List shortCircuits; public NodeData(TypeElement type, TypeSystemData typeSystem) { super(type, null); @@ -95,12 +95,12 @@ this.declaredChildren = declaredChildren; for (NodeData child : declaredChildren) { - child.parent = this; + child.declaringNode = this; } } public NodeData getParent() { - return parent; + return declaringNode; } public List getDeclaredChildren() { @@ -121,17 +121,14 @@ } } - methods.addAll(Arrays.asList(getSpecializationListeners())); - methods.addAll(Arrays.asList(getExecutableTypes())); - methods.addAll(Arrays.asList(getGuards())); + methods.addAll(getSpecializationListeners()); + methods.addAll(getExecutableTypes()); + methods.addAll(getGuards()); + methods.addAll(getShortCircuits()); return methods; } - public TemplateMethod[] getSpecializationListeners() { - return specializationListeners; - } - public List findGuards(String name) { List foundGuards = new ArrayList<>(); for (GuardData guardData : getGuards()) { @@ -142,10 +139,6 @@ return foundGuards; } - public ExecutableTypeData[] getExecutableTypes() { - return executableTypes; - } - public ExecutableTypeData findGenericExecutableType(ProcessorContext context, TypeData type) { List types = findGenericExecutableTypes(context); for (ExecutableTypeData availableType : types) { @@ -189,47 +182,20 @@ return result; } - public TypeMirror[] getExecutablePrimitiveTypeMirrors() { - TypeMirror[] typeMirrors = new TypeMirror[executableTypes.length]; - for (int i = 0; i < executableTypes.length; i++) { - typeMirrors[i] = executableTypes[i].getType().getPrimitiveType(); + public List getExecutablePrimitiveTypeMirrors() { + List typeMirrors = new ArrayList<>(); + for (ExecutableTypeData executableType : executableTypes) { + typeMirrors.add(executableType.getType().getPrimitiveType()); } return typeMirrors; } - void setExecutableTypes(ExecutableTypeData[] declaredExecuableTypes) { - this.executableTypes = declaredExecuableTypes; - } - - void setFields(NodeFieldData[] fields) { - this.fields = fields; - } - - void setSpecializations(SpecializationData[] specializations) { - this.specializations = specializations; - } - - void setSpecializationListeners(TemplateMethod[] specializationListeners) { - this.specializationListeners = specializationListeners; - } - - void setGuards(GuardData[] guards) { - this.guards = guards; - } - - public GuardData[] getGuards() { - return guards; - } - public NodeFieldData[] filterFields(FieldKind fieldKind, ExecutionKind usage) { List filteredFields = new ArrayList<>(); - NodeFieldData[] resolvedFields = getFields(); - if (fields != null) { - for (NodeFieldData field : resolvedFields) { - if (usage == null || field.getExecutionKind() == usage) { - if (fieldKind == null || field.getKind() == fieldKind) { - filteredFields.add(field); - } + for (NodeFieldData field : getFields()) { + if (usage == null || field.getExecutionKind() == usage) { + if (fieldKind == null || field.getKind() == fieldKind) { + filteredFields.add(field); } } } @@ -258,7 +224,7 @@ } } - needsRewrites &= specializations.length >= 2; + needsRewrites &= specializations.size() >= 2; return needsRewrites; } @@ -279,18 +245,6 @@ } } - public NodeFieldData[] getFields() { - return fields; - } - - public NodeFieldData[] getDeclaredFields() { - return fields; - } - - public SpecializationData[] getSpecializations() { - return specializations; - } - public String dump() { StringBuilder b = new StringBuilder(); b.append(String.format("[name = %s\n" + " typeSystem = %s\n" + " fields = %s\n" + " types = %s\n" + " specializations = %s\n" + " guards = %s\n" + "]", @@ -298,7 +252,7 @@ return b.toString(); } - private static String dumpList(Object[] array) { + private static String dumpList(List array) { if (array == null) { return "null"; } @@ -324,4 +278,55 @@ return null; } + public List getFields() { + return fields; + } + + void setFields(List fields) { + this.fields = fields; + } + + public List getSpecializations() { + return specializations; + } + + public List getSpecializationListeners() { + return specializationListeners; + } + + public List getGuards() { + return guards; + } + + public List getExecutableTypes() { + return executableTypes; + } + + public List getShortCircuits() { + return shortCircuits; + } + + void setSpecializations(List specializations) { + this.specializations = specializations; + for (SpecializationData specialization : specializations) { + specialization.setNode(this); + } + } + + void setSpecializationListeners(List specializationListeners) { + this.specializationListeners = specializationListeners; + } + + void setGuards(List guards) { + this.guards = guards; + } + + void setExecutableTypes(List executableTypes) { + this.executableTypes = executableTypes; + } + + void setShortCircuits(List shortCircuits) { + this.shortCircuits = shortCircuits; + } + } diff -r 91982900acee -r ac4e8c16ffdf graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java Mon Mar 04 15:13:25 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java Mon Mar 04 15:14:11 2013 +0100 @@ -112,10 +112,13 @@ private NodeData parseNode(TypeElement type) { if (Utils.findAnnotationMirror(processingEnv, type, GeneratedBy.class) != null) { - // generated nodes get called again. + // generated nodes should not get called again. return null; } - if (!Utils.isAssignable(type.asType(), context.getTruffleTypes().getNode())) { + + AnnotationMirror methodNodes = Utils.findAnnotationMirror(processingEnv, type, NodeClass.class); + + if (methodNodes == null && !Utils.isAssignable(type.asType(), context.getTruffleTypes().getNode())) { return null; // not a node } @@ -123,13 +126,149 @@ return null; // not visible } + final NodeData nodeData = parseNodeData(type); + if (nodeData == null) { + // TODO error message for instanceBaseClass? + return null; + } + + List elements = new ArrayList<>(context.getEnvironment().getElementUtils().getAllMembers(type)); + nodeData.setExtensionElements(getExtensionParser().parseAll(type, elements)); + if (nodeData.getExtensionElements() != null) { + elements.addAll(nodeData.getExtensionElements()); + } + + if (!parseMethods(nodeData, elements)) { + return null; + } + // TODO split + + if (!finalizeSpecializations(nodeData)) { + return null; + } + + if (!verifyNode(nodeData)) { + return null; + } + + return nodeData; + } + + private boolean parseMethods(final NodeData node, List elements) { + node.setGuards(new GuardParser(context, node, node.getTypeSystem()).parse(elements)); + node.setShortCircuits(new ShortCircuitParser(context, node).parse(elements)); + node.setSpecializationListeners(new SpecializationListenerParser(context, node).parse(elements)); + List generics = new GenericParser(context, node).parse(elements); + List specializations = new SpecializationMethodParser(context, node).parse(elements); + + if (generics == null || specializations == null || node.getGuards() == null || node.getShortCircuits() == null || node.getSpecializationListeners() == null) { + return false; + } + + List allSpecializations = new ArrayList<>(); + allSpecializations.addAll(generics); + allSpecializations.addAll(specializations); + + node.setSpecializations(allSpecializations); + + return true; + } + + private boolean finalizeSpecializations(final NodeData node) { + List specializations = new ArrayList<>(node.getSpecializations()); + + List generics = new ArrayList<>(); + for (SpecializationData spec : specializations) { + if (spec.isGeneric()) { + generics.add(spec); + } + } + + SpecializationData genericSpecialization = null; + if (generics.size() > 1) { + for (SpecializationData generic : generics) { + log.error(generic.getMethod(), "Only one method with @%s is allowed per operation.", Generic.class.getSimpleName()); + } + return false; + } else if (generics.size() == 1) { + genericSpecialization = generics.get(0); + } + + if (specializations.size() > 1 && genericSpecialization == null) { + log.error(node.getTemplateType(), "Need a @%s method.", Generic.class.getSimpleName()); + return false; + } + + if (genericSpecialization != null) { + CodeExecutableElement uninitializedMethod = new CodeExecutableElement(Utils.modifiers(Modifier.PUBLIC), context.getType(void.class), "doUninitialized"); + TemplateMethod uninializedMethod = new TemplateMethod(genericSpecialization.getId(), node, genericSpecialization.getSpecification(), uninitializedMethod, + genericSpecialization.getMarkerAnnotation(), genericSpecialization.getReturnType(), genericSpecialization.getParameters()); + specializations.add(new SpecializationData(uninializedMethod, false, true)); + } + + Collections.sort(specializations, new Comparator() { + + @Override + public int compare(SpecializationData o1, SpecializationData o2) { + return compareSpecialization(node.getTypeSystem(), o1, o2); + } + }); + + node.setSpecializations(specializations); + + return true; + } + + private boolean verifyNode(NodeData nodeData) { + // verify specialization parameter length + if (!verifySpecializationParameters(nodeData)) { + return false; + } + + // verify order is not ambiguous + if (!verifySpecializationOrder(nodeData)) { + return false; + } + + if (!verifyMissingAbstractMethods(nodeData)) { + return false; + } + + if (!assignShortCircuitsToSpecializations(nodeData)) { + return false; + } + + if (!verifyConstructors(nodeData)) { + return false; + } + +// if (!verifyNamingConvention(specializations, "do")) { +// return null; +// } +// +// if (!verifyNamesUnique(specializations)) { +// return null; +// } + + if (!verifyNamingConvention(nodeData.getShortCircuits(), "needs")) { + return false; + } + + if (!verifySpecializationThrows(nodeData)) { + return false; + } + + return true; + } + + private NodeData parseNodeData(TypeElement type) { List elements = new ArrayList<>(context.getEnvironment().getElementUtils().getAllMembers(type)); List typeHierarchy = findSuperClasses(new ArrayList(), type); Collections.reverse(typeHierarchy); AnnotationMirror typeSystemMirror = findFirstAnnotation(typeHierarchy, TypeSystemReference.class); if (typeSystemMirror == null) { - log.error(type, "No @%s annotation found in type hierarchy.", TypeSystemReference.class.getSimpleName()); + log.error(type, "No @%s annotation found in type hierarchy of %s.", TypeSystemReference.class.getSimpleName(), type.getQualifiedName().toString()); return null; } @@ -142,120 +281,24 @@ NodeData nodeData = new NodeData(type, typeSystem); - nodeData.setExtensionElements(getExtensionParser().parseAll(type, elements)); - if (nodeData.getExtensionElements() != null) { - elements.addAll(nodeData.getExtensionElements()); - } - List executableTypes = filterExecutableTypes(new ExecutableTypeMethodParser(context, nodeData).parse(elements)); - nodeData.setExecutableTypes(executableTypes.toArray(new ExecutableTypeData[executableTypes.size()])); + nodeData.setExecutableTypes(executableTypes); parsedNodes.put(Utils.getQualifiedName(type), nodeData); - NodeFieldData[] fields = parseFields(nodeData, elements, typeHierarchy); + List fields = parseFields(nodeData, elements, typeHierarchy); if (fields == null) { return null; } nodeData.setFields(fields); - - List genericSpecializations = new GenericParser(context, nodeData).parse(elements); - List guards = new GuardParser(context, nodeData, nodeData.getTypeSystem()).parse(elements); - nodeData.setGuards(guards.toArray(new GuardData[guards.size()])); - - SpecializationMethodParser specializationParser = new SpecializationMethodParser(context, nodeData); - List specializations = specializationParser.parse(elements); - List shortCircuits = new ShortCircuitParser(context, nodeData).parse(elements); - List listeners = new SpecializationListenerParser(context, nodeData).parse(elements); - - if (specializations == null || genericSpecializations == null || shortCircuits == null || listeners == null || guards == null) { - return null; - } - - SpecializationData genericSpecialization = null; - if (genericSpecializations.size() > 1) { - for (SpecializationData generic : genericSpecializations) { - log.error(generic.getMethod(), "Only one method with @%s is allowed per operation.", Generic.class.getSimpleName()); - } - return null; - } else if (genericSpecializations.size() == 1) { - genericSpecialization = genericSpecializations.get(0); - } - - if (specializations.size() > 1 && genericSpecialization == null) { - log.error(type, "Need a @%s method.", Generic.class.getSimpleName()); - return null; - } - - Collections.sort(specializations, new Comparator() { - - @Override - public int compare(SpecializationData o1, SpecializationData o2) { - return compareSpecialization(typeSystem, o1, o2); - } - }); - - List allSpecializations = new ArrayList<>(specializations); - if (genericSpecialization != null) { - allSpecializations.add(genericSpecialization); - CodeExecutableElement uninitializedMethod = new CodeExecutableElement(Utils.modifiers(Modifier.PUBLIC), context.getType(void.class), "doUninitialized"); - TemplateMethod uninializedMethod = new TemplateMethod(nodeData, genericSpecialization.getSpecification(), uninitializedMethod, genericSpecialization.getMarkerAnnotation(), - genericSpecialization.getReturnType(), genericSpecialization.getParameters()); - allSpecializations.add(0, new SpecializationData(uninializedMethod, false, true)); - } - - for (SpecializationData specialization : allSpecializations) { - specialization.setNode(nodeData); - } - - // verify specialization parameter length - if (!verifySpecializationParameters(specializations)) { - return null; - } - - // verify order is not ambiguous - if (!verifySpecializationOrder(typeSystem, specializations)) { - return null; - } - - nodeData.setSpecializations(allSpecializations.toArray(new SpecializationData[allSpecializations.size()])); - nodeData.setSpecializationListeners(listeners.toArray(new TemplateMethod[listeners.size()])); - - if (!verifyMissingAbstractMethods(nodeData, elements)) { - return null; - } - - if (!assignShortCircuitsToSpecializations(nodeData, allSpecializations, shortCircuits)) { - return null; - } - - if (!verifyConstructors(nodeData)) { - return null; - } - - if (!verifyNamingConvention(specializations, "do")) { - return null; - } - - if (!verifyNamesUnique(specializations)) { - return null; - } - - if (!verifyNamingConvention(shortCircuits, "needs")) { - return null; - } - - if (!verifySpecializationThrows(typeSystem, specializations)) { - return null; - } - return nodeData; } - private boolean verifySpecializationParameters(List specializations) { + private boolean verifySpecializationParameters(NodeData nodeData) { boolean valid = true; int args = -1; - for (SpecializationData specializationData : specializations) { + for (SpecializationData specializationData : nodeData.getSpecializations()) { int specializationArgs = 0; for (ActualParameter param : specializationData.getParameters()) { if (!param.getSpecification().isOptional()) { @@ -269,20 +312,22 @@ args = specializationArgs; } if (!valid) { - for (SpecializationData specialization : specializations) { + for (SpecializationData specialization : nodeData.getSpecializations()) { context.getLog().error(specialization.getMethod(), specialization.getMarkerAnnotation(), "All specializations must have the same number of arguments."); } } return valid; } - private boolean verifyMissingAbstractMethods(NodeData nodeData, List elements) { + private boolean verifyMissingAbstractMethods(NodeData nodeData) { if (nodeData.needsFactory()) { // missing abstract methods only needs to be implemented // if we need go generate factory for it. return true; } + List elements = new ArrayList<>(context.getEnvironment().getElementUtils().getAllMembers(nodeData.getTemplateType())); + Set unusedElements = new HashSet<>(elements); for (TemplateMethod method : nodeData.getAllTemplateMethods()) { unusedElements.remove(method.getMethod()); @@ -376,7 +421,7 @@ return null; } - private NodeFieldData[] parseFields(NodeData nodeData, List elements, final List typeHierarchy) { + private List parseFields(NodeData nodeData, List elements, final List typeHierarchy) { AnnotationMirror executionOrderMirror = findFirstAnnotation(typeHierarchy, ExecuteChildren.class); List executionDefinition = null; if (executionOrderMirror != null) { @@ -423,9 +468,8 @@ return null; } - NodeFieldData[] fieldArray = fields.toArray(new NodeFieldData[fields.size()]); - sortByExecutionOrder(fieldArray, executionDefinition == null ? Collections. emptyList() : executionDefinition, typeHierarchy); - return fieldArray; + sortByExecutionOrder(fields, executionDefinition == null ? Collections. emptyList() : executionDefinition, typeHierarchy); + return fields; } private NodeFieldData parseField(NodeData parentNodeData, VariableElement var, Set foundShortCircuits) { @@ -510,8 +554,8 @@ } } - private static void sortByExecutionOrder(NodeFieldData[] fields, final List executionOrder, final List typeHierarchy) { - Arrays.sort(fields, new Comparator() { + private static void sortByExecutionOrder(List fields, final List executionOrder, final List typeHierarchy) { + Collections.sort(fields, new Comparator() { @Override public int compare(NodeFieldData o1, NodeFieldData o2) { @@ -533,18 +577,17 @@ }); } - private boolean assignShortCircuitsToSpecializations(NodeData nodeData, List specializations, List shortCircuits) { - - Map> groupedShortCircuits = groupShortCircuits(shortCircuits); + private boolean assignShortCircuitsToSpecializations(NodeData node) { + Map> groupedShortCircuits = groupShortCircuits(node.getShortCircuits()); boolean valid = true; - for (NodeFieldData field : nodeData.filterFields(null, ExecutionKind.SHORT_CIRCUIT)) { + for (NodeFieldData field : node.filterFields(null, ExecutionKind.SHORT_CIRCUIT)) { String valueName = field.getName(); List availableCircuits = groupedShortCircuits.get(valueName); if (availableCircuits == null || availableCircuits.isEmpty()) { - log.error(nodeData.getTemplateType(), "@%s method for short cut value '%s' required.", ShortCircuit.class.getSimpleName(), valueName); + log.error(node.getTemplateType(), "@%s method for short cut value '%s' required.", ShortCircuit.class.getSimpleName(), valueName); valid = false; continue; } @@ -567,14 +610,14 @@ ShortCircuitData genericCircuit = null; for (ShortCircuitData circuit : availableCircuits) { - if (isGenericShortCutMethod(nodeData, circuit)) { + if (isGenericShortCutMethod(node, circuit)) { genericCircuit = circuit; break; } } if (genericCircuit == null) { - log.error(nodeData.getTemplateType(), "No generic @%s method available for short cut value '%s'.", ShortCircuit.class.getSimpleName(), valueName); + log.error(node.getTemplateType(), "No generic @%s method available for short cut value '%s'.", ShortCircuit.class.getSimpleName(), valueName); valid = false; continue; } @@ -590,8 +633,8 @@ return valid; } - NodeFieldData[] fields = nodeData.filterFields(null, ExecutionKind.SHORT_CIRCUIT); - for (SpecializationData specialization : specializations) { + NodeFieldData[] fields = node.filterFields(null, ExecutionKind.SHORT_CIRCUIT); + for (SpecializationData specialization : node.getSpecializations()) { ShortCircuitData[] assignedShortCuts = new ShortCircuitData[fields.length]; for (int i = 0; i < fields.length; i++) { @@ -696,7 +739,10 @@ return collection; } - private boolean verifySpecializationOrder(TypeSystemData typeSystem, List specializations) { + private boolean verifySpecializationOrder(NodeData node) { + TypeSystemData typeSystem = node.getTypeSystem(); + List specializations = node.getSpecializations(); + for (int i = 0; i < specializations.size(); i++) { SpecializationData m1 = specializations.get(i); for (int j = i + 1; j < specializations.size(); j++) { @@ -724,13 +770,15 @@ return true; } - private boolean verifySpecializationThrows(TypeSystemData typeSystem, List specializations) { + private boolean verifySpecializationThrows(NodeData node) { + TypeSystemData typeSystem = node.getTypeSystem(); + Map specializationMap = new HashMap<>(); - for (SpecializationData spec : specializations) { + for (SpecializationData spec : node.getSpecializations()) { specializationMap.put(spec.getMethodName(), spec); } boolean valid = true; - for (SpecializationData sourceSpecialization : specializations) { + for (SpecializationData sourceSpecialization : node.getSpecializations()) { if (sourceSpecialization.getExceptions() != null) { for (SpecializationThrowsData throwsData : sourceSpecialization.getExceptions()) { SpecializationData targetSpecialization = specializationMap.get(throwsData.getTransitionToName()); @@ -772,8 +820,22 @@ } private static int compareSpecializationWithoutOrder(TypeSystemData typeSystem, SpecializationData m1, SpecializationData m2) { - if (m1.getSpecification() != m2.getSpecification()) { - throw new UnsupportedOperationException("Cannot compare two specializations with different specifications."); + if (m1 == m2) { + return 0; + } + + if (m1.isUninitialized() && !m2.isUninitialized()) { + return -1; + } else if (!m1.isUninitialized() && m2.isUninitialized()) { + return 1; + } else if (m1.isGeneric() && !m2.isGeneric()) { + return 1; + } else if (!m1.isGeneric() && m2.isGeneric()) { + return -1; + } + + if (m1.getTemplate() != m2.getTemplate()) { + throw new UnsupportedOperationException("Cannot compare two specializations with different templates."); } int result = compareActualParameter(typeSystem, m1.getReturnType(), m2.getReturnType()); diff -r 91982900acee -r ac4e8c16ffdf graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java Mon Mar 04 15:13:25 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java Mon Mar 04 15:14:11 2013 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.truffle.codegen.processor.node; +import java.util.*; + import com.oracle.truffle.api.codegen.*; import com.oracle.truffle.codegen.processor.template.*; @@ -106,10 +108,10 @@ } public SpecializationData findNextSpecialization() { - SpecializationData[] specializations = node.getSpecializations(); - for (int i = 0; i < specializations.length - 1; i++) { - if (specializations[i] == this) { - return specializations[i + 1]; + List specializations = node.getSpecializations(); + for (int i = 0; i < specializations.size() - 1; i++) { + if (specializations.get(i) == this) { + return specializations.get(i + 1); } } return null; diff -r 91982900acee -r ac4e8c16ffdf graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerData.java Mon Mar 04 15:14:11 2013 +0100 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2012, 2012, 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.codegen.processor.node; + +import com.oracle.truffle.codegen.processor.template.*; + +public class SpecializationListenerData extends TemplateMethod { + + public SpecializationListenerData(TemplateMethod method) { + super(method); + } + +} diff -r 91982900acee -r ac4e8c16ffdf graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerParser.java Mon Mar 04 15:13:25 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerParser.java Mon Mar 04 15:14:11 2013 +0100 @@ -30,7 +30,7 @@ import com.oracle.truffle.codegen.processor.*; import com.oracle.truffle.codegen.processor.template.*; -public class SpecializationListenerParser extends MethodParser { +public class SpecializationListenerParser extends MethodParser { private final MethodSpec specification; @@ -50,8 +50,8 @@ } @Override - public TemplateMethod create(TemplateMethod method) { - return method; + public SpecializationListenerData create(TemplateMethod method) { + return new SpecializationListenerData(method); } @Override diff -r 91982900acee -r ac4e8c16ffdf graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java Mon Mar 04 15:13:25 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java Mon Mar 04 15:14:11 2013 +0100 @@ -26,6 +26,7 @@ public class TemplateMethod { + private final String id; private final Template template; private final MethodSpec specification; private final ExecutableElement method; @@ -33,13 +34,14 @@ private final ActualParameter returnType; private final ActualParameter[] parameters; - public TemplateMethod(Template template, MethodSpec specification, ExecutableElement method, AnnotationMirror markerAnnotation, ActualParameter returnType, ActualParameter[] parameters) { + public TemplateMethod(String id, Template template, MethodSpec specification, ExecutableElement method, AnnotationMirror markerAnnotation, ActualParameter returnType, ActualParameter[] parameters) { this.template = template; this.specification = specification; this.method = method; this.markerAnnotation = markerAnnotation; this.returnType = returnType; this.parameters = parameters; + this.id = id; if (parameters != null) { for (ActualParameter param : parameters) { @@ -49,7 +51,11 @@ } public TemplateMethod(TemplateMethod method) { - this(method.template, method.specification, method.method, method.markerAnnotation, method.returnType, method.parameters); + this(method.id, method.template, method.specification, method.method, method.markerAnnotation, method.returnType, method.parameters); + } + + public String getId() { + return id; } public Template getTemplate() { diff -r 91982900acee -r ac4e8c16ffdf graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java Mon Mar 04 15:13:25 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java Mon Mar 04 15:14:11 2013 +0100 @@ -31,6 +31,7 @@ import javax.lang.model.type.*; import javax.lang.model.util.*; +import com.oracle.truffle.api.codegen.*; import com.oracle.truffle.codegen.processor.*; import com.oracle.truffle.codegen.processor.template.ParameterSpec.Cardinality; @@ -149,8 +150,15 @@ } return null; } + + String id = method.getSimpleName().toString(); + AnnotationMirror idAnnotation = Utils.findAnnotationMirror(context.getEnvironment(), method, NodeId.class); + if (idAnnotation != null) { + id = Utils.getAnnotationValueString(idAnnotation, "value"); + } + ActualParameter[] paramMirrors = parameters.toArray(new ActualParameter[parameters.size()]); - return create(new TemplateMethod(template, methodSpecification, method, annotation, returnTypeMirror, paramMirrors)); + return create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, paramMirrors)); } private List parseParameters(ExecutableElement method, List parameterSpecs) {