comparison graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java @ 8592:a80bf36c6a1e

Refactor to shared template method signature comparison.
author Christian Humer <christian.humer@gmail.com>
date Mon, 01 Apr 2013 11:52:38 +0200
parents c210577168e7
children 8a1115c92271
comparison
equal deleted inserted replaced
8591:5c58da5b8233 8592:a80bf36c6a1e
184 nodes = new ArrayList<>(); 184 nodes = new ArrayList<>();
185 nodes.add(nodeData); 185 nodes.add(nodeData);
186 } 186 }
187 187
188 for (NodeData splittedNode : nodes) { 188 for (NodeData splittedNode : nodes) {
189 finalizeSpecializations(splittedNode); 189 finalizeSpecializations(elements, splittedNode);
190 verifyNode(splittedNode); 190 verifyNode(splittedNode);
191 } 191 }
192 192
193 if (needsSplit) { 193 if (needsSplit) {
194 nodeData.setDeclaredChildren(nodes); 194 nodeData.setDeclaredChildren(nodes);
252 } 252 }
253 return grouped; 253 return grouped;
254 } 254 }
255 255
256 private void parseMethods(final NodeData node, List<Element> elements) { 256 private void parseMethods(final NodeData node, List<Element> elements) {
257 node.setGuards(new GuardParser(context, node, node.getTypeSystem()).parse(elements));
258 node.setShortCircuits(new ShortCircuitParser(context, node).parse(elements)); 257 node.setShortCircuits(new ShortCircuitParser(context, node).parse(elements));
259 node.setSpecializationListeners(new SpecializationListenerParser(context, node).parse(elements)); 258 node.setSpecializationListeners(new SpecializationListenerParser(context, node).parse(elements));
260 List<SpecializationData> generics = new GenericParser(context, node).parse(elements); 259 List<SpecializationData> generics = new GenericParser(context, node).parse(elements);
261 List<SpecializationData> specializations = new SpecializationMethodParser(context, node).parse(elements); 260 List<SpecializationData> specializations = new SpecializationMethodParser(context, node).parse(elements);
262 261
265 allSpecializations.addAll(specializations); 264 allSpecializations.addAll(specializations);
266 265
267 node.setSpecializations(allSpecializations); 266 node.setSpecializations(allSpecializations);
268 } 267 }
269 268
270 private void finalizeSpecializations(final NodeData node) { 269 private void finalizeSpecializations(List<Element> elements, final NodeData node) {
271 List<SpecializationData> specializations = new ArrayList<>(node.getSpecializations()); 270 List<SpecializationData> specializations = new ArrayList<>(node.getSpecializations());
272 271
273 if (specializations.isEmpty()) { 272 if (specializations.isEmpty()) {
274 return; 273 return;
274 }
275
276 for (SpecializationData specialization : specializations) {
277 matchGuards(elements, specialization);
275 } 278 }
276 279
277 List<SpecializationData> generics = new ArrayList<>(); 280 List<SpecializationData> generics = new ArrayList<>();
278 for (SpecializationData spec : specializations) { 281 for (SpecializationData spec : specializations) {
279 if (spec.isGeneric()) { 282 if (spec.isGeneric()) {
334 337
335 Collections.sort(specializations, new Comparator<SpecializationData>() { 338 Collections.sort(specializations, new Comparator<SpecializationData>() {
336 339
337 @Override 340 @Override
338 public int compare(SpecializationData o1, SpecializationData o2) { 341 public int compare(SpecializationData o1, SpecializationData o2) {
339 return compareSpecialization(node.getTypeSystem(), o1, o2); 342 return compareSpecialization(o1, o2);
340 } 343 }
341 }); 344 });
342 345
343 node.setSpecializations(specializations); 346 node.setSpecializations(specializations);
344 347
354 } 357 }
355 List<String> ids = calculateSpecializationIds(needsId); 358 List<String> ids = calculateSpecializationIds(needsId);
356 for (int i = 0; i < ids.size(); i++) { 359 for (int i = 0; i < ids.size(); i++) {
357 needsId.get(i).setId(ids.get(i)); 360 needsId.get(i).setId(ids.get(i));
358 } 361 }
362 }
363
364 private void matchGuards(List<Element> elements, SpecializationData specialization) {
365 if (specialization.getGuardDefinitions().isEmpty()) {
366 specialization.setGuards(Collections.<GuardData> emptyList());
367 return;
368 }
369
370 List<GuardData> foundGuards = new ArrayList<>();
371 List<ExecutableElement> methods = ElementFilter.methodsIn(elements);
372 for (String guardDefinition : specialization.getGuardDefinitions()) {
373 GuardParser parser = new GuardParser(context, specialization, guardDefinition);
374 List<GuardData> guards = parser.parse(methods);
375 Collections.sort(guards, new Comparator<GuardData>() {
376
377 @Override
378 public int compare(GuardData o1, GuardData o2) {
379 int compare = o1.compareBySignature(o2);
380 if (compare == 0) {
381 compare = o1.getId().compareTo(o2.getId());
382 }
383 if (compare == 0) {
384 TypeElement enclosingType1 = Utils.findNearestEnclosingType(o1.getMethod());
385 TypeElement enclosingType2 = Utils.findNearestEnclosingType(o2.getMethod());
386 compare = enclosingType1.getQualifiedName().toString().compareTo(enclosingType2.getQualifiedName().toString());
387 }
388 return compare;
389 }
390 });
391 if (!guards.isEmpty()) {
392 foundGuards.add(guards.get(0));
393 } else {
394 // error no guard found
395 specialization.addError("No guard found with with name '%s'.", guardDefinition);
396 }
397 }
398
399 specialization.setGuards(foundGuards);
400
359 } 401 }
360 402
361 private static List<String> calculateSpecializationIds(List<SpecializationData> specializations) { 403 private static List<String> calculateSpecializationIds(List<SpecializationData> specializations) {
362 int lastSize = -1; 404 int lastSize = -1;
363 List<List<String>> signatureChunks = new ArrayList<>(); 405 List<List<String>> signatureChunks = new ArrayList<>();
925 collection.add(element); 967 collection.add(element);
926 return collection; 968 return collection;
927 } 969 }
928 970
929 private static void verifySpecializationOrder(NodeData node) { 971 private static void verifySpecializationOrder(NodeData node) {
930 TypeSystemData typeSystem = node.getTypeSystem();
931 List<SpecializationData> specializations = node.getSpecializations(); 972 List<SpecializationData> specializations = node.getSpecializations();
932
933 for (int i = 0; i < specializations.size(); i++) { 973 for (int i = 0; i < specializations.size(); i++) {
934 SpecializationData m1 = specializations.get(i); 974 SpecializationData m1 = specializations.get(i);
935 for (int j = i + 1; j < specializations.size(); j++) { 975 for (int j = i + 1; j < specializations.size(); j++) {
936 SpecializationData m2 = specializations.get(j); 976 SpecializationData m2 = specializations.get(j);
937 int inferredOrder = compareSpecializationWithoutOrder(typeSystem, m1, m2); 977 int inferredOrder = compareSpecialization(m1, m2);
938 978
939 if (m1.getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) { 979 if (m1.getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) {
940 int specOrder = m1.getOrder() - m2.getOrder(); 980 int specOrder = m1.getOrder() - m2.getOrder();
941 if (specOrder == 0) { 981 if (specOrder == 0) {
942 m1.addError("Order value %d used multiple times", m1.getOrder()); 982 m1.addError("Order value %d used multiple times", m1.getOrder());
972 } 1012 }
973 } 1013 }
974 } 1014 }
975 } 1015 }
976 1016
977 private static int compareSpecialization(TypeSystemData typeSystem, SpecializationData m1, SpecializationData m2) { 1017 private static int compareSpecialization(SpecializationData m1, SpecializationData m2) {
978 if (m1 == m2) { 1018 if (m1 == m2) {
979 return 0; 1019 return 0;
980 } 1020 }
981 int result = compareSpecializationWithoutOrder(typeSystem, m1, m2);
982 if (result == 0) {
983 if (m1.getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) {
984 return m1.getOrder() - m2.getOrder();
985 }
986 }
987 return result;
988 }
989
990 private static int compareSpecializationWithoutOrder(TypeSystemData typeSystem, SpecializationData m1, SpecializationData m2) {
991 if (m1 == m2) {
992 return 0;
993 }
994 1021
995 if (m1.getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) { 1022 if (m1.getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) {
996 return m1.getOrder() - m2.getOrder(); 1023 return m1.getOrder() - m2.getOrder();
997 } else if (m1.isUninitialized() && !m2.isUninitialized()) { 1024 } else if (m1.isUninitialized() ^ m2.isUninitialized()) {
998 return -1; 1025 return m1.isUninitialized() ? -1 : 1;
999 } else if (!m1.isUninitialized() && m2.isUninitialized()) { 1026 } else if (m1.isGeneric() ^ m2.isGeneric()) {
1000 return 1; 1027 return m1.isGeneric() ? 1 : -1;
1001 } else if (m1.isGeneric() && !m2.isGeneric()) {
1002 return 1;
1003 } else if (!m1.isGeneric() && m2.isGeneric()) {
1004 return -1;
1005 } 1028 }
1006 1029
1007 if (m1.getTemplate() != m2.getTemplate()) { 1030 if (m1.getTemplate() != m2.getTemplate()) {
1008 throw new UnsupportedOperationException("Cannot compare two specializations with different templates."); 1031 throw new UnsupportedOperationException("Cannot compare two specializations with different templates.");
1009 } 1032 }
1010 1033
1011 int result = compareActualParameter(typeSystem, m1.getReturnType(), m2.getReturnType()); 1034 return m1.compareBySignature(m2);
1012
1013 for (ActualParameter p1 : m1.getParameters()) {
1014 NodeFieldData field = m1.getNode().findField(p1.getSpecification().getName());
1015 if (field == null) {
1016 continue;
1017 }
1018 ActualParameter p2 = m2.findParameter(p1.getLocalName());
1019
1020 if (p1 != null && p2 != null && !Utils.typeEquals(p1.getActualType(), p2.getActualType())) {
1021 int typeResult = compareActualParameter(typeSystem, p1, p2);
1022 if (result == 0) {
1023 result = typeResult;
1024 } else if (Math.signum(result) != Math.signum(typeResult)) {
1025 // We cannot define an order.
1026 return 0;
1027 }
1028 }
1029 }
1030 return result;
1031 }
1032
1033 private static int compareActualParameter(TypeSystemData typeSystem, ActualParameter p1, ActualParameter p2) {
1034 int index1 = typeSystem.findType(p1.getActualType());
1035 int index2 = typeSystem.findType(p2.getActualType());
1036
1037 assert index1 != index2;
1038 assert !(index1 == -1 ^ index2 == -1);
1039
1040 return index1 - index2;
1041 } 1035 }
1042 1036
1043 @Override 1037 @Override
1044 public Class<? extends Annotation> getAnnotationType() { 1038 public Class<? extends Annotation> getAnnotationType() {
1045 return null; 1039 return null;