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 '../constants/expressions.dart'; | 10 import '../constants/expressions.dart'; |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 }); | 329 }); |
330 reporter.log('Added $addedInGraph elements in inferencing graph.'); | 330 reporter.log('Added $addedInGraph elements in inferencing graph.'); |
331 | 331 |
332 TypeGraphDump dump = debug.PRINT_GRAPH ? new TypeGraphDump(this) : null; | 332 TypeGraphDump dump = debug.PRINT_GRAPH ? new TypeGraphDump(this) : null; |
333 | 333 |
334 dump?.beforeAnalysis(); | 334 dump?.beforeAnalysis(); |
335 buildWorkQueue(); | 335 buildWorkQueue(); |
336 refine(); | 336 refine(); |
337 | 337 |
338 // Try to infer element types of lists and compute their escape information. | 338 // Try to infer element types of lists and compute their escape information. |
339 types.allocatedLists.values.forEach((ListTypeInformation info) { | 339 types.allocatedLists.values.forEach((TypeInformation info) { |
340 analyzeListAndEnqueue(info); | 340 analyzeListAndEnqueue(info); |
341 }); | 341 }); |
342 | 342 |
343 // Try to infer the key and value types for maps and compute the values' | 343 // Try to infer the key and value types for maps and compute the values' |
344 // escape information. | 344 // escape information. |
345 types.allocatedMaps.values.forEach((MapTypeInformation info) { | 345 types.allocatedMaps.values.forEach((TypeInformation info) { |
346 analyzeMapAndEnqueue(info); | 346 analyzeMapAndEnqueue(info); |
347 }); | 347 }); |
348 | 348 |
349 Set<FunctionElement> bailedOutOn = new Set<FunctionElement>(); | 349 Set<FunctionElement> bailedOutOn = new Set<FunctionElement>(); |
350 | 350 |
351 // Trace closures to potentially infer argument types. | 351 // Trace closures to potentially infer argument types. |
352 types.allocatedClosures.forEach((info) { | 352 types.allocatedClosures.forEach((dynamic info) { |
353 void trace( | 353 void trace( |
354 Iterable<FunctionElement> elements, ClosureTracerVisitor tracer) { | 354 Iterable<FunctionElement> elements, ClosureTracerVisitor tracer) { |
355 tracer.run(); | 355 tracer.run(); |
356 if (!tracer.continueAnalyzing) { | 356 if (!tracer.continueAnalyzing) { |
357 elements.forEach((FunctionElement e) { | 357 elements.forEach((FunctionElement e) { |
358 closedWorldRefiner.registerMightBePassedToApply(e); | 358 closedWorldRefiner.registerMightBePassedToApply(e); |
359 if (debug.VERBOSE) print("traced closure $e as ${true} (bail)"); | 359 if (debug.VERBOSE) print("traced closure $e as ${true} (bail)"); |
360 e.functionSignature.forEachParameter((parameter) { | 360 e.functionSignature.forEachParameter((parameter) { |
361 types | 361 types |
362 .getInferredTypeOf(parameter) | 362 .getInferredTypeOf(parameter) |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 // If the node cannot be reset, we do not need to update its users either. | 427 // If the node cannot be reset, we do not need to update its users either. |
428 if (!info.reset(this)) continue; | 428 if (!info.reset(this)) continue; |
429 seenTypes.add(info); | 429 seenTypes.add(info); |
430 workQueue.addAll(info.users); | 430 workQueue.addAll(info.users); |
431 } | 431 } |
432 | 432 |
433 workQueue.addAll(seenTypes); | 433 workQueue.addAll(seenTypes); |
434 refine(); | 434 refine(); |
435 | 435 |
436 if (debug.PRINT_SUMMARY) { | 436 if (debug.PRINT_SUMMARY) { |
437 types.allocatedLists.values.forEach((ListTypeInformation info) { | 437 types.allocatedLists.values.forEach((_info) { |
| 438 ListTypeInformation info = _info; |
438 print('${info.type} ' | 439 print('${info.type} ' |
439 'for ${info.originalType.allocationNode} ' | 440 'for ${info.originalType.allocationNode} ' |
440 'at ${info.originalType.allocationElement} ' | 441 'at ${info.originalType.allocationElement} ' |
441 'after ${info.refineCount}'); | 442 'after ${info.refineCount}'); |
442 }); | 443 }); |
443 types.allocatedMaps.values.forEach((MapTypeInformation info) { | 444 types.allocatedMaps.values.forEach((_info) { |
| 445 MapTypeInformation info = _info; |
444 print('${info.type} ' | 446 print('${info.type} ' |
445 'for ${info.originalType.allocationNode} ' | 447 'for ${info.originalType.allocationNode} ' |
446 'at ${info.originalType.allocationElement} ' | 448 'at ${info.originalType.allocationElement} ' |
447 'after ${info.refineCount}'); | 449 'after ${info.refineCount}'); |
448 }); | 450 }); |
449 types.allocatedClosures.forEach((TypeInformation info) { | 451 types.allocatedClosures.forEach((TypeInformation info) { |
450 if (info is ElementTypeInformation) { | 452 if (info is ElementTypeInformation) { |
451 print('${types.getInferredSignatureOf(info.element)} for ' | 453 print('${types.getInferredSignatureOf(info.element)} for ' |
452 '${info.element}'); | 454 '${info.element}'); |
453 } else if (info is ClosureTypeInformation) { | 455 } else if (info is ClosureTypeInformation) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 // assignment. Instance fields are dealt with in the constructor. | 548 // assignment. Instance fields are dealt with in the constructor. |
547 if (Elements.isStaticOrTopLevelField(element)) { | 549 if (Elements.isStaticOrTopLevelField(element)) { |
548 recordTypeOfNonFinalField(node, element, type); | 550 recordTypeOfNonFinalField(node, element, type); |
549 } | 551 } |
550 } else { | 552 } else { |
551 recordTypeOfNonFinalField(node, element, type); | 553 recordTypeOfNonFinalField(node, element, type); |
552 } | 554 } |
553 if (Elements.isStaticOrTopLevelField(element) && | 555 if (Elements.isStaticOrTopLevelField(element) && |
554 resolvedAst.body != null && | 556 resolvedAst.body != null && |
555 !element.isConst) { | 557 !element.isConst) { |
556 var argument = resolvedAst.body; | 558 dynamic argument = resolvedAst.body; |
557 // TODO(13429): We could do better here by using the | 559 // TODO(13429): We could do better here by using the |
558 // constant handler to figure out if it's a lazy field or not. | 560 // constant handler to figure out if it's a lazy field or not. |
559 if (argument.asSend() != null || | 561 if (argument.asSend() != null || |
560 (argument.asNewExpression() != null && !argument.isConst)) { | 562 (argument.asNewExpression() != null && !argument.isConst)) { |
561 recordType(element, types.nullType); | 563 recordType(element, types.nullType); |
562 } | 564 } |
563 } | 565 } |
564 } else { | 566 } else { |
565 recordReturnType(element, type); | 567 recordReturnType(element, type); |
566 } | 568 } |
567 } | 569 } |
568 | 570 |
569 void processLoopInformation() { | 571 void processLoopInformation() { |
570 types.allocatedCalls.forEach((info) { | 572 types.allocatedCalls.forEach((dynamic info) { |
571 if (!info.inLoop) return; | 573 if (!info.inLoop) return; |
572 if (info is StaticCallSiteTypeInformation) { | 574 if (info is StaticCallSiteTypeInformation) { |
573 closedWorldRefiner | 575 closedWorldRefiner |
574 .addFunctionCalledInLoop(info.calledElement.declaration); | 576 .addFunctionCalledInLoop(info.calledElement.declaration); |
575 } else if (info.mask != null && !info.mask.containsAll(closedWorld)) { | 577 } else if (info.mask != null && !info.mask.containsAll(closedWorld)) { |
576 // For instance methods, we only register a selector called in a | 578 // For instance methods, we only register a selector called in a |
577 // loop if it is a typed selector, to avoid marking too many | 579 // loop if it is a typed selector, to avoid marking too many |
578 // methods as being called from within a loop. This cuts down | 580 // methods as being called from within a loop. This cuts down |
579 // on the code bloat. | 581 // on the code bloat. |
580 info.targets.forEach((MemberElement element) { | 582 info.targets.forEach((MemberElement element) { |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 TypeInformation receiverType, | 894 TypeInformation receiverType, |
893 Element caller, | 895 Element caller, |
894 ArgumentsTypes arguments, | 896 ArgumentsTypes arguments, |
895 SideEffects sideEffects, | 897 SideEffects sideEffects, |
896 bool inLoop) { | 898 bool inLoop) { |
897 if (selector.isClosureCall) { | 899 if (selector.isClosureCall) { |
898 return registerCalledClosure(node, selector, mask, receiverType, caller, | 900 return registerCalledClosure(node, selector, mask, receiverType, caller, |
899 arguments, sideEffects, inLoop); | 901 arguments, sideEffects, inLoop); |
900 } | 902 } |
901 | 903 |
902 closedWorld.locateMembers(selector, mask).forEach((MemberElement callee) { | 904 closedWorld.locateMembers(selector, mask).forEach((_callee) { |
| 905 MemberElement callee = _callee; |
903 updateSideEffects(sideEffects, selector, callee); | 906 updateSideEffects(sideEffects, selector, callee); |
904 }); | 907 }); |
905 | 908 |
906 CallSiteTypeInformation info = new DynamicCallSiteTypeInformation( | 909 CallSiteTypeInformation info = new DynamicCallSiteTypeInformation( |
907 types.currentMember, | 910 types.currentMember, |
908 node, | 911 node, |
909 caller, | 912 caller, |
910 selector, | 913 selector, |
911 mask, | 914 mask, |
912 receiverType, | 915 receiverType, |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
974 types.allocatedCalls.add(info); | 977 types.allocatedCalls.add(info); |
975 return info; | 978 return info; |
976 } | 979 } |
977 | 980 |
978 // Sorts the resolved elements by size. We do this for this inferrer | 981 // Sorts the resolved elements by size. We do this for this inferrer |
979 // to get the same results for [ListTracer] compared to the | 982 // to get the same results for [ListTracer] compared to the |
980 // [SimpleTypesInferrer]. | 983 // [SimpleTypesInferrer]. |
981 Iterable<ResolvedAst> sortResolvedAsts() { | 984 Iterable<ResolvedAst> sortResolvedAsts() { |
982 int max = 0; | 985 int max = 0; |
983 Map<int, Setlet<ResolvedAst>> methodSizes = <int, Setlet<ResolvedAst>>{}; | 986 Map<int, Setlet<ResolvedAst>> methodSizes = <int, Setlet<ResolvedAst>>{}; |
984 compiler.enqueuer.resolution.processedEntities | 987 compiler.enqueuer.resolution.processedEntities.forEach((_element) { |
985 .forEach((MemberElement element) { | 988 MemberElement element = _element; |
986 ResolvedAst resolvedAst = element.resolvedAst; | 989 ResolvedAst resolvedAst = element.resolvedAst; |
987 element = element.implementation; | 990 element = element.implementation; |
988 if (element.impliesType) return; | 991 if (element.impliesType) return; |
989 assert( | 992 assert( |
990 element.isField || | 993 element.isField || |
991 element.isFunction || | 994 element.isFunction || |
992 element.isConstructor || | 995 element.isConstructor || |
993 element.isGetter || | 996 element.isGetter || |
994 element.isSetter, | 997 element.isSetter, |
995 failedAt(element, 'Unexpected element kind: ${element.kind}')); | 998 failedAt(element, 'Unexpected element kind: ${element.kind}')); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1084 /** | 1087 /** |
1085 * Records that the captured variable [local] is read. | 1088 * Records that the captured variable [local] is read. |
1086 */ | 1089 */ |
1087 void recordCapturedLocalRead(Local local) {} | 1090 void recordCapturedLocalRead(Local local) {} |
1088 | 1091 |
1089 /** | 1092 /** |
1090 * Records that the variable [local] is being updated. | 1093 * Records that the variable [local] is being updated. |
1091 */ | 1094 */ |
1092 void recordLocalUpdate(Local local, TypeInformation type) {} | 1095 void recordLocalUpdate(Local local, TypeInformation type) {} |
1093 } | 1096 } |
OLD | NEW |