| 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 '../../compiler_new.dart'; |
| 7 import '../common.dart'; | 8 import '../common.dart'; |
| 8 import '../common/names.dart'; | 9 import '../common/names.dart'; |
| 9 import '../compiler.dart'; | 10 import '../compiler.dart'; |
| 10 import '../common_elements.dart'; | 11 import '../common_elements.dart'; |
| 11 import '../constants/values.dart'; | 12 import '../constants/values.dart'; |
| 12 import '../elements/elements.dart' | 13 import '../elements/elements.dart' |
| 13 show | 14 show |
| 14 ClassElement, | 15 ClassElement, |
| 15 ConstructorElement, | 16 ConstructorElement, |
| 16 Elements, | 17 Elements, |
| 17 MemberElement, | 18 MemberElement, |
| 18 ParameterElement; | 19 ParameterElement; |
| 19 import '../elements/entities.dart'; | 20 import '../elements/entities.dart'; |
| 20 import '../elements/names.dart'; | 21 import '../elements/names.dart'; |
| 21 import '../js_backend/annotations.dart'; | 22 import '../js_backend/annotations.dart'; |
| 22 import '../js_backend/js_backend.dart'; | 23 import '../js_backend/mirrors_data.dart'; |
| 24 import '../js_backend/no_such_method_registry.dart'; |
| 23 import '../native/behavior.dart' as native; | 25 import '../native/behavior.dart' as native; |
| 26 import '../options.dart'; |
| 24 import '../types/constants.dart'; | 27 import '../types/constants.dart'; |
| 25 import '../types/types.dart'; | 28 import '../types/types.dart'; |
| 26 import '../universe/call_structure.dart'; | 29 import '../universe/call_structure.dart'; |
| 27 import '../universe/selector.dart'; | 30 import '../universe/selector.dart'; |
| 28 import '../universe/side_effects.dart'; | 31 import '../universe/side_effects.dart'; |
| 29 import '../util/setlet.dart'; | 32 import '../util/setlet.dart'; |
| 30 import '../world.dart'; | 33 import '../world.dart'; |
| 31 import 'closure_tracer.dart'; | 34 import 'closure_tracer.dart'; |
| 32 import 'debug.dart' as debug; | 35 import 'debug.dart' as debug; |
| 33 import 'locals_handler.dart'; | 36 import 'locals_handler.dart'; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 50 new Selector.getter(const PublicName('first')), | 53 new Selector.getter(const PublicName('first')), |
| 51 new Selector.getter(const PublicName('last')), | 54 new Selector.getter(const PublicName('last')), |
| 52 new Selector.getter(const PublicName('single')), | 55 new Selector.getter(const PublicName('single')), |
| 53 new Selector.call(const PublicName('singleWhere'), CallStructure.ONE_ARG), | 56 new Selector.call(const PublicName('singleWhere'), CallStructure.ONE_ARG), |
| 54 new Selector.call(const PublicName('elementAt'), CallStructure.ONE_ARG), | 57 new Selector.call(const PublicName('elementAt'), CallStructure.ONE_ARG), |
| 55 new Selector.index(), | 58 new Selector.index(), |
| 56 new Selector.call(const PublicName('removeAt'), CallStructure.ONE_ARG), | 59 new Selector.call(const PublicName('removeAt'), CallStructure.ONE_ARG), |
| 57 new Selector.call(const PublicName('removeLast'), CallStructure.NO_ARGS) | 60 new Selector.call(const PublicName('removeLast'), CallStructure.NO_ARGS) |
| 58 ]); | 61 ]); |
| 59 | 62 |
| 60 Compiler get compiler; | 63 CompilerOptions get options; |
| 61 ClosedWorld get closedWorld; | 64 ClosedWorld get closedWorld; |
| 62 ClosedWorldRefiner get closedWorldRefiner; | 65 ClosedWorldRefiner get closedWorldRefiner; |
| 63 JavaScriptBackend get backend => compiler.backend; | 66 OptimizerHintsForTests get optimizerHints; |
| 64 OptimizerHintsForTests get optimizerHints => backend.optimizerHints; | 67 DiagnosticReporter get reporter; |
| 65 DiagnosticReporter get reporter => compiler.reporter; | |
| 66 CommonMasks get commonMasks => closedWorld.commonMasks; | 68 CommonMasks get commonMasks => closedWorld.commonMasks; |
| 67 CommonElements get commonElements => closedWorld.commonElements; | 69 CommonElements get commonElements => closedWorld.commonElements; |
| 68 | 70 |
| 71 // TODO(johnniwinther): This should be part of [ClosedWorld] or |
| 72 // [ClosureWorldRefiner]. |
| 73 NoSuchMethodRegistry get noSuchMethodRegistry; |
| 74 |
| 69 TypeSystem<T> get types; | 75 TypeSystem<T> get types; |
| 70 Map<T, TypeInformation> get concreteTypes; | 76 Map<T, TypeInformation> get concreteTypes; |
| 71 | 77 |
| 72 FunctionEntity get mainElement; | 78 FunctionEntity get mainElement; |
| 73 | 79 |
| 74 void runOverAllElements(); | 80 void runOverAllElements(); |
| 75 | 81 |
| 76 void analyze(MemberEntity member, T node, ArgumentsTypes arguments); | 82 void analyze(MemberEntity member, T node, ArgumentsTypes arguments); |
| 77 void analyzeListAndEnqueue(ListTypeInformation info); | 83 void analyzeListAndEnqueue(ListTypeInformation info); |
| 78 void analyzeMapAndEnqueue(MapTypeInformation info); | 84 void analyzeMapAndEnqueue(MapTypeInformation info); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 | 222 |
| 217 /// Returns the type for [nativeBehavior]. See documentation on | 223 /// Returns the type for [nativeBehavior]. See documentation on |
| 218 /// [native.NativeBehavior]. | 224 /// [native.NativeBehavior]. |
| 219 TypeInformation typeOfNativeBehavior(native.NativeBehavior nativeBehavior); | 225 TypeInformation typeOfNativeBehavior(native.NativeBehavior nativeBehavior); |
| 220 | 226 |
| 221 bool returnsListElementType(Selector selector, TypeMask mask); | 227 bool returnsListElementType(Selector selector, TypeMask mask); |
| 222 | 228 |
| 223 bool returnsMapValueType(Selector selector, TypeMask mask); | 229 bool returnsMapValueType(Selector selector, TypeMask mask); |
| 224 | 230 |
| 225 void clear(); | 231 void clear(); |
| 232 |
| 233 /// Returns true if global optimizations such as type inferencing can apply to |
| 234 /// the field [element]. |
| 235 /// |
| 236 /// One category of elements that do not apply is runtime helpers that the |
| 237 /// backend calls, but the optimizations don't see those calls. |
| 238 bool canFieldBeUsedForGlobalOptimizations(FieldEntity element); |
| 239 |
| 240 /// Returns true if global optimizations such as type inferencing can apply to |
| 241 /// the parameter [element]. |
| 242 /// |
| 243 /// One category of elements that do not apply is runtime helpers that the |
| 244 /// backend calls, but the optimizations don't see those calls. |
| 245 bool canFunctionParametersBeUsedForGlobalOptimizations( |
| 246 FunctionEntity function); |
| 226 } | 247 } |
| 227 | 248 |
| 228 abstract class InferrerEngineImpl<T> extends InferrerEngine<T> { | 249 abstract class InferrerEngineImpl<T> extends InferrerEngine<T> { |
| 229 final Map<Local, TypeInformation> defaultTypeOfParameter = | 250 final Map<Local, TypeInformation> defaultTypeOfParameter = |
| 230 new Map<Local, TypeInformation>(); | 251 new Map<Local, TypeInformation>(); |
| 231 final WorkQueue workQueue = new WorkQueue(); | 252 final WorkQueue workQueue = new WorkQueue(); |
| 232 final FunctionEntity mainElement; | 253 final FunctionEntity mainElement; |
| 233 final Set<MemberEntity> analyzedElements = new Set<MemberEntity>(); | 254 final Set<MemberEntity> analyzedElements = new Set<MemberEntity>(); |
| 234 | 255 |
| 235 /// The maximum number of times we allow a node in the graph to | 256 /// The maximum number of times we allow a node in the graph to |
| 236 /// change types. If a node reaches that limit, we give up | 257 /// change types. If a node reaches that limit, we give up |
| 237 /// inferencing on it and give it the dynamic type. | 258 /// inferencing on it and give it the dynamic type. |
| 238 final int MAX_CHANGE_COUNT = 6; | 259 final int MAX_CHANGE_COUNT = 6; |
| 239 | 260 |
| 240 int overallRefineCount = 0; | 261 int overallRefineCount = 0; |
| 241 int addedInGraph = 0; | 262 int addedInGraph = 0; |
| 242 | 263 |
| 243 final Compiler compiler; | 264 final CompilerOptions options; |
| 265 final Progress progress; |
| 266 final DiagnosticReporter reporter; |
| 267 final CompilerOutput _compilerOutput; |
| 268 final OptimizerHintsForTests optimizerHints; |
| 244 | 269 |
| 245 /// The [ClosedWorld] on which inference reasoning is based. | 270 /// The [ClosedWorld] on which inference reasoning is based. |
| 246 final ClosedWorld closedWorld; | 271 final ClosedWorld closedWorld; |
| 247 | 272 |
| 248 final ClosedWorldRefiner closedWorldRefiner; | 273 final ClosedWorldRefiner closedWorldRefiner; |
| 249 final TypeSystem<T> types; | 274 final TypeSystem<T> types; |
| 250 final Map<T, TypeInformation> concreteTypes = new Map<T, TypeInformation>(); | 275 final Map<T, TypeInformation> concreteTypes = new Map<T, TypeInformation>(); |
| 251 | 276 |
| 252 final Map<ir.Node, TypeInformation> concreteKernelTypes = | 277 final Map<ir.Node, TypeInformation> concreteKernelTypes = |
| 253 new Map<ir.Node, TypeInformation>(); | 278 new Map<ir.Node, TypeInformation>(); |
| 254 final Set<ConstructorEntity> generativeConstructorsExposingThis = | 279 final Set<ConstructorEntity> generativeConstructorsExposingThis = |
| 255 new Set<ConstructorEntity>(); | 280 new Set<ConstructorEntity>(); |
| 256 | 281 |
| 257 /// Data computed internally within elements, like the type-mask of a send a | 282 /// Data computed internally within elements, like the type-mask of a send a |
| 258 /// list allocation, or a for-in loop. | 283 /// list allocation, or a for-in loop. |
| 259 final Map<MemberEntity, GlobalTypeInferenceElementData> _memberData = | 284 final Map<MemberEntity, GlobalTypeInferenceElementData> _memberData = |
| 260 new Map<MemberEntity, GlobalTypeInferenceElementData>(); | 285 new Map<MemberEntity, GlobalTypeInferenceElementData>(); |
| 261 | 286 |
| 287 // TODO(johnniwinther): This should be accessible throught [closedWorld]. |
| 288 final MirrorsData mirrorsData; |
| 289 |
| 290 final NoSuchMethodRegistry noSuchMethodRegistry; |
| 291 |
| 262 InferrerEngineImpl( | 292 InferrerEngineImpl( |
| 263 this.compiler, | 293 this.options, |
| 264 ClosedWorld closedWorld, | 294 this.progress, |
| 295 this.reporter, |
| 296 this._compilerOutput, |
| 297 this.optimizerHints, |
| 298 this.closedWorld, |
| 265 this.closedWorldRefiner, | 299 this.closedWorldRefiner, |
| 300 this.mirrorsData, |
| 301 this.noSuchMethodRegistry, |
| 266 this.mainElement, | 302 this.mainElement, |
| 267 TypeSystemStrategy<T> typeSystemStrategy) | 303 TypeSystemStrategy<T> typeSystemStrategy) |
| 268 : this.types = new TypeSystem<T>(closedWorld, typeSystemStrategy), | 304 : this.types = new TypeSystem<T>(closedWorld, typeSystemStrategy); |
| 269 this.closedWorld = closedWorld; | |
| 270 | 305 |
| 271 void forEachElementMatching( | 306 void forEachElementMatching( |
| 272 Selector selector, TypeMask mask, bool f(MemberEntity element)) { | 307 Selector selector, TypeMask mask, bool f(MemberEntity element)) { |
| 273 Iterable<MemberEntity> elements = closedWorld.locateMembers(selector, mask); | 308 Iterable<MemberEntity> elements = closedWorld.locateMembers(selector, mask); |
| 274 for (MemberEntity e in elements) { | 309 for (MemberEntity e in elements) { |
| 275 if (!f(e)) return; | 310 if (!f(e)) return; |
| 276 } | 311 } |
| 277 } | 312 } |
| 278 | 313 |
| 279 GlobalTypeInferenceElementData<T> createElementData(); | 314 GlobalTypeInferenceElementData<T> createElementData(); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 } | 485 } |
| 451 | 486 |
| 452 info.markAsInferred(); | 487 info.markAsInferred(); |
| 453 workQueue.add(info.keyType); | 488 workQueue.add(info.keyType); |
| 454 workQueue.add(info.valueType); | 489 workQueue.add(info.valueType); |
| 455 workQueue.addAll(info.typeInfoMap.values); | 490 workQueue.addAll(info.typeInfoMap.values); |
| 456 workQueue.add(info); | 491 workQueue.add(info); |
| 457 } | 492 } |
| 458 | 493 |
| 459 void runOverAllElements() { | 494 void runOverAllElements() { |
| 460 if (compiler.disableTypeInference) return; | 495 progress.startPhase(); |
| 461 if (compiler.options.verbose) { | 496 |
| 462 compiler.progress.reset(); | |
| 463 } | |
| 464 analyzeAllElements(); | 497 analyzeAllElements(); |
| 465 | 498 |
| 466 TypeGraphDump dump = debug.PRINT_GRAPH ? new TypeGraphDump(this) : null; | 499 TypeGraphDump dump = |
| 500 debug.PRINT_GRAPH ? new TypeGraphDump(_compilerOutput, this) : null; |
| 467 | 501 |
| 468 dump?.beforeAnalysis(); | 502 dump?.beforeAnalysis(); |
| 469 buildWorkQueue(); | 503 buildWorkQueue(); |
| 470 refine(); | 504 refine(); |
| 471 | 505 |
| 472 // Try to infer element types of lists and compute their escape information. | 506 // Try to infer element types of lists and compute their escape information. |
| 473 types.allocatedLists.values.forEach((TypeInformation info) { | 507 types.allocatedLists.values.forEach((TypeInformation info) { |
| 474 analyzeListAndEnqueue(info); | 508 analyzeListAndEnqueue(info); |
| 475 }); | 509 }); |
| 476 | 510 |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 | 657 |
| 624 reporter.log('Inferred $overallRefineCount types.'); | 658 reporter.log('Inferred $overallRefineCount types.'); |
| 625 | 659 |
| 626 processLoopInformation(); | 660 processLoopInformation(); |
| 627 } | 661 } |
| 628 | 662 |
| 629 /// Call [analyze] for all live members. | 663 /// Call [analyze] for all live members. |
| 630 void analyzeAllElements() { | 664 void analyzeAllElements() { |
| 631 sortMembers(closedWorld.processedMembers, computeMemberSize) | 665 sortMembers(closedWorld.processedMembers, computeMemberSize) |
| 632 .forEach((MemberEntity member) { | 666 .forEach((MemberEntity member) { |
| 633 if (compiler.shouldPrintProgress) { | 667 progress.showProgress( |
| 634 reporter.log('Added $addedInGraph elements in inferencing graph.'); | 668 'Added ', addedInGraph, ' elements in inferencing graph.'); |
| 635 compiler.progress.reset(); | |
| 636 } | |
| 637 // This also forces the creation of the [ElementTypeInformation] to ensure | 669 // This also forces the creation of the [ElementTypeInformation] to ensure |
| 638 // it is in the graph. | 670 // it is in the graph. |
| 639 T body = computeMemberBody(member); | 671 T body = computeMemberBody(member); |
| 640 types.withMember(member, () => analyze(member, body, null)); | 672 types.withMember(member, () => analyze(member, body, null)); |
| 641 }); | 673 }); |
| 642 reporter.log('Added $addedInGraph elements in inferencing graph.'); | 674 reporter.log('Added $addedInGraph elements in inferencing graph.'); |
| 643 } | 675 } |
| 644 | 676 |
| 645 /// Compute a 'size' of [member] used for sorting member for the type | 677 /// Compute a 'size' of [member] used for sorting member for the type |
| 646 /// inference work-queue. Smallest members are processed first. | 678 /// inference work-queue. Smallest members are processed first. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 // on the code bloat. | 772 // on the code bloat. |
| 741 info.targets.forEach((MemberEntity element) { | 773 info.targets.forEach((MemberEntity element) { |
| 742 closedWorldRefiner.addFunctionCalledInLoop(element); | 774 closedWorldRefiner.addFunctionCalledInLoop(element); |
| 743 }); | 775 }); |
| 744 } | 776 } |
| 745 }); | 777 }); |
| 746 } | 778 } |
| 747 | 779 |
| 748 void refine() { | 780 void refine() { |
| 749 while (!workQueue.isEmpty) { | 781 while (!workQueue.isEmpty) { |
| 750 if (compiler.shouldPrintProgress) { | 782 progress.showProgress('Inferred ', overallRefineCount, ' types.'); |
| 751 reporter.log('Inferred $overallRefineCount types.'); | |
| 752 compiler.progress.reset(); | |
| 753 } | |
| 754 TypeInformation info = workQueue.remove(); | 783 TypeInformation info = workQueue.remove(); |
| 755 TypeMask oldType = info.type; | 784 TypeMask oldType = info.type; |
| 756 TypeMask newType = info.refine(this); | 785 TypeMask newType = info.refine(this); |
| 757 // Check that refinement has not accidentally changed the type. | 786 // Check that refinement has not accidentally changed the type. |
| 758 assert(oldType == info.type); | 787 assert(oldType == info.type); |
| 759 if (info.abandonInferencing) info.doNotEnqueue = true; | 788 if (info.abandonInferencing) info.doNotEnqueue = true; |
| 760 if ((info.type = newType) != oldType) { | 789 if ((info.type = newType) != oldType) { |
| 761 overallRefineCount++; | 790 overallRefineCount++; |
| 762 info.refineCount++; | 791 info.refineCount++; |
| 763 if (info.refineCount > MAX_CHANGE_COUNT) { | 792 if (info.refineCount > MAX_CHANGE_COUNT) { |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1064 types.allocatedClosures.clear(); | 1093 types.allocatedClosures.clear(); |
| 1065 | 1094 |
| 1066 analyzedElements.clear(); | 1095 analyzedElements.clear(); |
| 1067 generativeConstructorsExposingThis.clear(); | 1096 generativeConstructorsExposingThis.clear(); |
| 1068 | 1097 |
| 1069 types.allocatedMaps.values.forEach(cleanup); | 1098 types.allocatedMaps.values.forEach(cleanup); |
| 1070 types.allocatedLists.values.forEach(cleanup); | 1099 types.allocatedLists.values.forEach(cleanup); |
| 1071 } | 1100 } |
| 1072 | 1101 |
| 1073 Iterable<MemberEntity> getCallersOf(MemberEntity element) { | 1102 Iterable<MemberEntity> getCallersOf(MemberEntity element) { |
| 1074 if (compiler.disableTypeInference) { | |
| 1075 throw new UnsupportedError( | |
| 1076 "Cannot query the type inferrer when type inference is disabled."); | |
| 1077 } | |
| 1078 MemberTypeInformation info = types.getInferredTypeOfMember(element); | 1103 MemberTypeInformation info = types.getInferredTypeOfMember(element); |
| 1079 return info.callers; | 1104 return info.callers; |
| 1080 } | 1105 } |
| 1081 | 1106 |
| 1082 TypeInformation typeOfMemberWithSelector( | 1107 TypeInformation typeOfMemberWithSelector( |
| 1083 covariant MemberElement element, Selector selector) { | 1108 covariant MemberElement element, Selector selector) { |
| 1084 if (element.name == Identifiers.noSuchMethod_ && | 1109 if (element.name == Identifiers.noSuchMethod_ && |
| 1085 selector.name != element.name) { | 1110 selector.name != element.name) { |
| 1086 // An invocation can resolve to a [noSuchMethod], in which case | 1111 // An invocation can resolve to a [noSuchMethod], in which case |
| 1087 // we get the return type of [noSuchMethod]. | 1112 // we get the return type of [noSuchMethod]. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1101 return returnTypeOfMember(element); | 1126 return returnTypeOfMember(element); |
| 1102 } | 1127 } |
| 1103 } else if (element.isGetter || element.isField) { | 1128 } else if (element.isGetter || element.isField) { |
| 1104 assert(selector.isCall || selector.isSetter); | 1129 assert(selector.isCall || selector.isSetter); |
| 1105 return types.dynamicType; | 1130 return types.dynamicType; |
| 1106 } else { | 1131 } else { |
| 1107 return returnTypeOfMember(element); | 1132 return returnTypeOfMember(element); |
| 1108 } | 1133 } |
| 1109 } | 1134 } |
| 1110 | 1135 |
| 1136 /// Returns true if global optimizations such as type inferencing can apply to |
| 1137 /// the field [element]. |
| 1138 /// |
| 1139 /// One category of elements that do not apply is runtime helpers that the |
| 1140 /// backend calls, but the optimizations don't see those calls. |
| 1141 bool canFieldBeUsedForGlobalOptimizations(FieldEntity element) { |
| 1142 if (closedWorld.backendUsage.isFieldUsedByBackend(element)) { |
| 1143 return false; |
| 1144 } |
| 1145 if ((element.isTopLevel || element.isStatic) && !element.isAssignable) { |
| 1146 return true; |
| 1147 } |
| 1148 return !mirrorsData.isMemberAccessibleByReflection(element); |
| 1149 } |
| 1150 |
| 1151 /// Returns true if global optimizations such as type inferencing can apply to |
| 1152 /// the parameter [element]. |
| 1153 /// |
| 1154 /// One category of elements that do not apply is runtime helpers that the |
| 1155 /// backend calls, but the optimizations don't see those calls. |
| 1156 bool canFunctionParametersBeUsedForGlobalOptimizations( |
| 1157 FunctionEntity function) { |
| 1158 return !closedWorld.backendUsage.isFunctionUsedByBackend(function) && |
| 1159 !mirrorsData.isMemberAccessibleByReflection(function); |
| 1160 } |
| 1161 |
| 1111 // Sorts the resolved elements by size. We do this for this inferrer | 1162 // Sorts the resolved elements by size. We do this for this inferrer |
| 1112 // to get the same results for [ListTracer] compared to the | 1163 // to get the same results for [ListTracer] compared to the |
| 1113 // [SimpleTypesInferrer]. | 1164 // [SimpleTypesInferrer]. |
| 1114 static Iterable<MemberEntity> sortMembers( | 1165 static Iterable<MemberEntity> sortMembers( |
| 1115 Iterable<MemberEntity> members, int computeSize(MemberEntity member)) { | 1166 Iterable<MemberEntity> members, int computeSize(MemberEntity member)) { |
| 1116 Map<int, Set<MemberEntity>> methodSizes = | 1167 Map<int, Set<MemberEntity>> methodSizes = |
| 1117 groupMembers(members, computeSize); | 1168 groupMembers(members, computeSize); |
| 1118 int max = methodSizes.keys.fold(0, (a, b) => a > b ? a : b); | 1169 int max = methodSizes.keys.fold(0, (a, b) => a > b ? a : b); |
| 1119 List<MemberEntity> result = <MemberEntity>[]; | 1170 List<MemberEntity> result = <MemberEntity>[]; |
| 1120 for (int i = 0; i <= max; i++) { | 1171 for (int i = 0; i <= max; i++) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1132 // Put the other operators in buckets by size, later to be added in | 1183 // Put the other operators in buckets by size, later to be added in |
| 1133 // size order. | 1184 // size order. |
| 1134 int size = computeSize(element); | 1185 int size = computeSize(element); |
| 1135 Set<MemberEntity> set = | 1186 Set<MemberEntity> set = |
| 1136 methodSizes.putIfAbsent(size, () => new Setlet<MemberEntity>()); | 1187 methodSizes.putIfAbsent(size, () => new Setlet<MemberEntity>()); |
| 1137 set.add(element); | 1188 set.add(element); |
| 1138 }); | 1189 }); |
| 1139 return methodSizes; | 1190 return methodSizes; |
| 1140 } | 1191 } |
| 1141 } | 1192 } |
| OLD | NEW |