# HG changeset patch # User Christian Humer # Date 1363445518 -3600 # Node ID b1dff27a1da6ee7b87044ac8242e7097dfc91db8 # Parent 5663e3c7eabeb82f7056bfb7f81a8e8af93ed681 Fixed specialization id generation. diff -r 5663e3c7eabe -r b1dff27a1da6 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 Fri Mar 15 21:18:47 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java Sat Mar 16 15:51:58 2013 +0100 @@ -28,13 +28,12 @@ import javax.lang.model.element.*; import javax.lang.model.type.*; import javax.lang.model.util.*; -import javax.tools.Diagnostic.*; +import javax.tools.Diagnostic.Kind; import com.oracle.truffle.api.codegen.*; import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.api.nodes.Node.Children; import com.oracle.truffle.codegen.processor.*; -import com.oracle.truffle.codegen.processor.ast.*; import com.oracle.truffle.codegen.processor.node.NodeFieldData.ExecutionKind; import com.oracle.truffle.codegen.processor.node.NodeFieldData.FieldKind; import com.oracle.truffle.codegen.processor.template.*; @@ -42,7 +41,8 @@ public class NodeParser extends TemplateParser { - public static final List> ANNOTATIONS = Arrays.asList(Generic.class, TypeSystemReference.class, ShortCircuit.class, Specialization.class, SpecializationListener.class); + public static final List> ANNOTATIONS = Arrays.asList(Generic.class, TypeSystemReference.class, ShortCircuit.class, Specialization.class, SpecializationListener.class, + ExecuteChildren.class, NodeClass.class, NodeId.class); private Map parsedNodes; @@ -151,6 +151,17 @@ } NodeData nodeData = parseNodeData(type, nodeType); + + if (Utils.typeEquals(nodeType.asType(), type.asType())) { + // filter fields if they were not split. (field are accessible anyway) + for (ListIterator iterator = nodeData.getFields().listIterator(); iterator.hasNext();) { + NodeFieldData field = iterator.next(); + if (field.getKind() == FieldKind.FIELD) { + iterator.remove(); + } + } + } + if (nodeData.hasErrors()) { return nodeData; // error sync point } @@ -314,9 +325,10 @@ } if (genericSpecialization != null) { - CodeExecutableElement uninitializedMethod = new CodeExecutableElement(Utils.modifiers(Modifier.PUBLIC), context.getType(void.class), "doUninitialized"); - TemplateMethod uninializedMethod = new TemplateMethod("Uninitialized", node, genericSpecialization.getSpecification(), uninitializedMethod, genericSpecialization.getMarkerAnnotation(), - genericSpecialization.getReturnType(), genericSpecialization.getParameters()); + TemplateMethod uninializedMethod = new TemplateMethod("Uninitialized", node, genericSpecialization.getSpecification(), null, null, genericSpecialization.getReturnType(), + genericSpecialization.getParameters()); + // should not use messages from generic specialization + uninializedMethod.getMessages().clear(); specializations.add(new SpecializationData(uninializedMethod, false, true)); } @@ -330,97 +342,125 @@ node.setSpecializations(specializations); + List needsId = new ArrayList<>(); for (SpecializationData specialization : specializations) { - specialization.setId(findUniqueSpecializationId(specialization)); + if (specialization.isGeneric()) { + specialization.setId("Generic"); + } else if (specialization.isUninitialized()) { + specialization.setId("Uninitialized"); + } else { + needsId.add(specialization); + } + } + List ids = calculateSpecializationIds(needsId); + for (int i = 0; i < ids.size(); i++) { + needsId.get(i).setId(ids.get(i)); } } - private static String findUniqueSpecializationId(SpecializationData specialization) { + private static List calculateSpecializationIds(List specializations) { + int lastSize = -1; + List> signatureChunks = new ArrayList<>(); + for (SpecializationData other : specializations) { + if (other.isUninitialized() || other.isGeneric()) { + continue; + } + List paramIds = new LinkedList<>(); + paramIds.add(Utils.getTypeId(other.getReturnType().getActualType())); + for (ActualParameter param : other.getParameters()) { + if (other.getNode().findField(param.getSpecification().getName()) == null) { + continue; + } + paramIds.add(Utils.getTypeId(param.getActualType())); + } + assert lastSize == -1 || lastSize == paramIds.size(); + if (lastSize != -1 && lastSize != paramIds.size()) { + throw new AssertionError(); + } + signatureChunks.add(paramIds); + lastSize = paramIds.size(); + } - String name; - if (specialization.isGeneric()) { - name = "Generic"; - } else if (specialization.isUninitialized()) { - name = "Uninitialized"; - } else { - List specializations = new ArrayList<>(specialization.getNode().getSpecializations()); - for (ListIterator iterator = specializations.listIterator(); iterator.hasNext();) { - SpecializationData data = iterator.next(); - if (data.isGeneric() || data.isUninitialized()) { - iterator.remove(); + // reduce id vertically + for (int i = 0; i < lastSize; i++) { + String prev = null; + boolean allSame = true; + for (List signature : signatureChunks) { + String arg = signature.get(i); + if (prev == null) { + prev = arg; + continue; + } else if (!prev.equals(arg)) { + allSame = false; + break; } + prev = arg; } - Map> usedIds = new HashMap<>(); - for (SpecializationData other : specializations) { - for (ActualParameter param : other.getReturnTypeAndParameters()) { - if (other.getNode().findField(param.getSpecification().getName()) == null) { - continue; - } + if (allSame) { + for (List signature : signatureChunks) { + signature.remove(i); + } + lastSize--; + } + } - Set types = usedIds.get(param.getSpecification()); - if (types == null) { - types = new HashSet<>(); - usedIds.put(param.getSpecification(), types); - } - types.add(Utils.getTypeId(param.getActualType())); + // reduce id horizontally + for (List signature : signatureChunks) { + String prev = null; + boolean allSame = true; + for (String arg : signature) { + if (prev == null) { + prev = arg; + continue; + } else if (!prev.equals(arg)) { + allSame = false; + break; } + prev = arg; } - List ambiguousSpecs = new ArrayList<>(); - for (ActualParameter param : specialization.getReturnTypeAndParameters()) { - Set ids = usedIds.get(param.getSpecification()); - if (ids != null && ids.size() > 1) { - ambiguousSpecs.add(param.getSpecification()); - } + if (allSame) { + signature.clear(); + signature.add(prev); } + } + + // create signatures + List signatures = new ArrayList<>(); + for (List signatureChunk : signatureChunks) { + StringBuilder b = new StringBuilder(); + for (String s : signatureChunk) { + b.append(s); + } + signatures.add(b.toString()); + } - String specializationId = findSpecializationId(specialization, ambiguousSpecs); - int specializationIndex = 0; - int totalIndex = 0; + Map counts = new HashMap<>(); + for (String s1 : signatures) { + Integer count = counts.get(s1); + if (count == null) { + count = 0; + } + count++; + counts.put(s1, count); + } - for (SpecializationData other : specializations) { - String id = findSpecializationId(other, ambiguousSpecs); - if (id.equals(specializationId)) { - totalIndex++; - if (specialization == other) { - specializationIndex = totalIndex; + for (String s : counts.keySet()) { + int count = counts.get(s); + if (count > 1) { + int number = 0; + for (ListIterator iterator = signatures.listIterator(); iterator.hasNext();) { + String s2 = iterator.next(); + if (s.equals(s2)) { + iterator.set(s2 + number); + number++; } } } - - if (specializationIndex != totalIndex) { - name = specializationId + specializationIndex; - } else { - name = specializationId; - } - } - return name; - } - - private static String findSpecializationId(SpecializationData specialization, List specs) { - boolean allSame = true; - ActualParameter prevParam = specialization.getReturnType(); - for (ParameterSpec spec : specs) { - ActualParameter param = specialization.findParameter(spec); - if (!Utils.typeEquals(prevParam.getActualType(), param.getActualType())) { - allSame = false; - break; - } - prevParam = param; } - if (allSame) { - return Utils.getTypeId(prevParam.getActualType()); - } else { - StringBuilder nameBuilder = new StringBuilder(); - nameBuilder.append(Utils.getTypeId(prevParam.getActualType())); - for (ParameterSpec spec : specs) { - ActualParameter param = specialization.findParameter(spec); - nameBuilder.append(Utils.getTypeId(param.getActualType())); - } - return nameBuilder.toString(); - } + return signatures; } private void verifyNode(NodeData nodeData) { @@ -474,7 +514,8 @@ List executableTypes = filterExecutableTypes(new ExecutableTypeMethodParser(context, nodeData).parse(elements)); nodeData.setExecutableTypes(executableTypes); parsedNodes.put(Utils.getQualifiedName(templateType), nodeData); - nodeData.setFields(parseFields(nodeData, elements, typeHierarchy)); + + nodeData.setFields(parseFields(elements, typeHierarchy)); return nodeData; } @@ -597,7 +638,7 @@ return null; } - private List parseFields(NodeData nodeData, List elements, final List typeHierarchy) { + private List parseFields(List elements, final List typeHierarchy) { AnnotationMirror executionOrderMirror = findFirstAnnotation(typeHierarchy, ExecuteChildren.class); List executionDefinition = null; if (executionOrderMirror != null) { @@ -627,14 +668,16 @@ } } - NodeFieldData field = parseField(nodeData, var, shortCircuits); - fields.add(field); + NodeFieldData field = parseField(var, shortCircuits); + if (field != null) { + fields.add(field); + } } sortByExecutionOrder(fields, executionDefinition == null ? Collections. emptyList() : executionDefinition, typeHierarchy); return fields; } - private NodeFieldData parseField(NodeData parentNodeData, VariableElement var, Set foundShortCircuits) { + private NodeFieldData parseField(VariableElement var, Set foundShortCircuits) { AnnotationMirror childMirror = Utils.findAnnotationMirror(processingEnv, var, Child.class); AnnotationMirror childrenMirror = Utils.findAnnotationMirror(processingEnv, var, Children.class); @@ -675,12 +718,12 @@ } else if (fieldNodeData.findGenericExecutableTypes(context).isEmpty()) { fieldData.addError("No executable generic types found for node '%s'.", Utils.getQualifiedName(type)); } + } - // TODO correct handling of access elements - if (var.getModifiers().contains(Modifier.PRIVATE) && Utils.typeEquals(var.getEnclosingElement().asType(), parentNodeData.getTemplateType().asType())) { - execution = ExecutionKind.IGNORE; - } + if (fieldData.getAccessElement().getModifiers().contains(Modifier.PRIVATE)) { + return null; } + return fieldData; } @@ -704,8 +747,7 @@ break; } } - - if (getter != null) { + if (getter != null && !getter.getModifiers().contains(Modifier.PRIVATE)) { return getter; } else { return variableElement; @@ -943,7 +985,9 @@ return 0; } - if (m1.isUninitialized() && !m2.isUninitialized()) { + if (m1.getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) { + return m1.getOrder() - m2.getOrder(); + } else if (m1.isUninitialized() && !m2.isUninitialized()) { return -1; } else if (!m1.isUninitialized() && m2.isUninitialized()) { return 1; @@ -959,9 +1003,12 @@ int result = compareActualParameter(typeSystem, m1.getReturnType(), m2.getReturnType()); - for (ParameterSpec spec : m1.getSpecification().getParameters()) { - ActualParameter p1 = m1.findParameter(spec); - ActualParameter p2 = m2.findParameter(spec); + for (ActualParameter p1 : m1.getParameters()) { + NodeFieldData field = m1.getNode().findField(p1.getSpecification().getName()); + if (field == null) { + continue; + } + ActualParameter p2 = m2.findParameter(p1.getLocalName()); if (p1 != null && p2 != null && !Utils.typeEquals(p1.getActualType(), p2.getActualType())) { int typeResult = compareActualParameter(typeSystem, p1, p2);