| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../common/names.dart'; | 8 import '../common/names.dart'; |
| 9 import '../compiler.dart'; | 9 import '../compiler.dart'; |
| 10 import '../common_elements.dart'; | 10 import '../common_elements.dart'; |
| 11 import '../constants/values.dart'; | 11 import '../constants/values.dart'; |
| 12 import '../elements/elements.dart' | 12 import '../elements/elements.dart' |
| 13 show | 13 show |
| 14 ClassElement, | 14 ClassElement, |
| 15 ConstructorElement, | 15 ConstructorElement, |
| 16 Elements, | 16 Elements, |
| 17 MemberElement, | 17 MemberElement, |
| 18 ParameterElement; | 18 ParameterElement; |
| 19 import '../elements/entities.dart'; | 19 import '../elements/entities.dart'; |
| 20 import '../elements/names.dart'; | 20 import '../elements/names.dart'; |
| 21 import '../js_backend/annotations.dart'; | 21 import '../js_backend/annotations.dart'; |
| 22 import '../js_backend/js_backend.dart'; | 22 import '../js_backend/js_backend.dart'; |
| 23 import '../native/behavior.dart' as native; | 23 import '../native/behavior.dart' as native; |
| 24 import '../types/constants.dart'; | 24 import '../types/constants.dart'; |
| 25 import '../types/types.dart'; | 25 import '../types/types.dart'; |
| 26 import '../universe/call_structure.dart'; | 26 import '../universe/call_structure.dart'; |
| 27 import '../universe/selector.dart'; | 27 import '../universe/selector.dart'; |
| 28 import '../universe/side_effects.dart'; | 28 import '../universe/side_effects.dart'; |
| 29 import '../util/setlet.dart'; |
| 29 import '../world.dart'; | 30 import '../world.dart'; |
| 30 import 'closure_tracer.dart'; | 31 import 'closure_tracer.dart'; |
| 31 import 'debug.dart' as debug; | 32 import 'debug.dart' as debug; |
| 32 import 'locals_handler.dart'; | 33 import 'locals_handler.dart'; |
| 33 import 'list_tracer.dart'; | 34 import 'list_tracer.dart'; |
| 34 import 'map_tracer.dart'; | 35 import 'map_tracer.dart'; |
| 35 import 'builder.dart'; | 36 import 'builder.dart'; |
| 36 import 'type_graph_dump.dart'; | 37 import 'type_graph_dump.dart'; |
| 37 import 'type_graph_inferrer.dart'; | 38 import 'type_graph_inferrer.dart'; |
| 38 import 'type_graph_nodes.dart'; | 39 import 'type_graph_nodes.dart'; |
| (...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 624 }); | 625 }); |
| 625 } | 626 } |
| 626 dump?.afterAnalysis(); | 627 dump?.afterAnalysis(); |
| 627 | 628 |
| 628 reporter.log('Inferred $overallRefineCount types.'); | 629 reporter.log('Inferred $overallRefineCount types.'); |
| 629 | 630 |
| 630 processLoopInformation(); | 631 processLoopInformation(); |
| 631 } | 632 } |
| 632 | 633 |
| 633 /// Call [analyze] for all live members. | 634 /// Call [analyze] for all live members. |
| 634 void analyzeAllElements(); | 635 void analyzeAllElements() { |
| 636 sortMembers(compiler, computeMemberSize).forEach((MemberEntity member) { |
| 637 if (compiler.shouldPrintProgress) { |
| 638 reporter.log('Added $addedInGraph elements in inferencing graph.'); |
| 639 compiler.progress.reset(); |
| 640 } |
| 641 // This also forces the creation of the [ElementTypeInformation] to ensure |
| 642 // it is in the graph. |
| 643 T body = computeMemberBody(member); |
| 644 types.withMember(member, () => analyze(member, body, null)); |
| 645 }); |
| 646 reporter.log('Added $addedInGraph elements in inferencing graph.'); |
| 647 } |
| 648 |
| 649 /// Compute a 'size' of [member] used for sorting member for the type |
| 650 /// inference work-queue. Smallest members are processed first. |
| 651 int computeMemberSize(MemberEntity member); |
| 652 |
| 653 /// Returns the body node for [member]. |
| 654 T computeMemberBody(MemberEntity member); |
| 635 | 655 |
| 636 /// Calls [f] for each parameter of [method]. | 656 /// Calls [f] for each parameter of [method]. |
| 637 void forEachParameter(FunctionEntity method, void f(Local parameter)); | 657 void forEachParameter(FunctionEntity method, void f(Local parameter)); |
| 638 | 658 |
| 639 /// Returns the `call` method on [cls] or the `noSuchMethod` if [cls] doesn't | 659 /// Returns the `call` method on [cls] or the `noSuchMethod` if [cls] doesn't |
| 640 /// implement `call`. | 660 /// implement `call`. |
| 641 FunctionEntity lookupCallMethod(ClassEntity cls); | 661 FunctionEntity lookupCallMethod(ClassEntity cls); |
| 642 | 662 |
| 643 void analyze(MemberEntity element, T body, ArgumentsTypes arguments) { | 663 void analyze(MemberEntity element, T body, ArgumentsTypes arguments) { |
| 644 assert(!(element is MemberElement && !element.isDeclaration)); | 664 assert(!(element is MemberElement && !element.isDeclaration)); |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1087 assert(element.isGetter); | 1107 assert(element.isGetter); |
| 1088 return returnTypeOfMember(element); | 1108 return returnTypeOfMember(element); |
| 1089 } | 1109 } |
| 1090 } else if (element.isGetter || element.isField) { | 1110 } else if (element.isGetter || element.isField) { |
| 1091 assert(selector.isCall || selector.isSetter); | 1111 assert(selector.isCall || selector.isSetter); |
| 1092 return types.dynamicType; | 1112 return types.dynamicType; |
| 1093 } else { | 1113 } else { |
| 1094 return returnTypeOfMember(element); | 1114 return returnTypeOfMember(element); |
| 1095 } | 1115 } |
| 1096 } | 1116 } |
| 1117 |
| 1118 // Sorts the resolved elements by size. We do this for this inferrer |
| 1119 // to get the same results for [ListTracer] compared to the |
| 1120 // [SimpleTypesInferrer]. |
| 1121 static Iterable<MemberEntity> sortMembers( |
| 1122 Compiler compiler, int computeSize(MemberEntity member)) { |
| 1123 Map<int, Set<MemberEntity>> methodSizes = |
| 1124 groupMembers(compiler, computeSize); |
| 1125 int max = methodSizes.keys.fold(0, (a, b) => a > b ? a : b); |
| 1126 List<MemberEntity> result = <MemberEntity>[]; |
| 1127 for (int i = 0; i <= max; i++) { |
| 1128 Set<MemberEntity> set = methodSizes[i]; |
| 1129 if (set != null) result.addAll(set); |
| 1130 } |
| 1131 return result; |
| 1132 } |
| 1133 |
| 1134 static Map<int, Set<MemberEntity>> groupMembers( |
| 1135 Compiler compiler, int computeSize(MemberEntity member)) { |
| 1136 Map<int, Set<MemberEntity>> methodSizes = <int, Set<MemberEntity>>{}; |
| 1137 compiler.enqueuer.resolution.processedEntities |
| 1138 .forEach((MemberEntity element) { |
| 1139 if (element.isAbstract) return; |
| 1140 // Put the other operators in buckets by size, later to be added in |
| 1141 // size order. |
| 1142 int size = computeSize(element); |
| 1143 Set<MemberEntity> set = |
| 1144 methodSizes.putIfAbsent(size, () => new Setlet<MemberEntity>()); |
| 1145 set.add(element); |
| 1146 }); |
| 1147 return methodSizes; |
| 1148 } |
| 1097 } | 1149 } |
| OLD | NEW |