|
2 | 2 | // for details. All rights reserved. Use of this source code is governed by a
|
3 | 3 | // BSD-style license that can be found in the LICENSE file.
|
4 | 4 |
|
| 5 | +import 'package:collection/collection.dart'; |
5 | 6 | import 'package:kernel/ast.dart' as ir;
|
6 | 7 |
|
7 | 8 | import '../../compiler_api.dart' as api;
|
@@ -480,60 +481,66 @@ class InferrerEngine {
|
480 | 481 | _processCalledTargets(shouldMarkCalled: true);
|
481 | 482 |
|
482 | 483 | if (debug.PRINT_SUMMARY) {
|
483 |
| - types.allocatedLists.values.forEach((_info) { |
| 484 | + void printSorted(Iterable<String> toSort) { |
| 485 | + print(toSort.sorted((a, b) => a.compareTo(b)).join('\n')); |
| 486 | + } |
| 487 | + |
| 488 | + printSorted(types.allocatedLists.values.map((_info) { |
484 | 489 | ListTypeInformation info = _info;
|
485 |
| - print('${info.type} ' |
| 490 | + return '${info.type} ' |
486 | 491 | 'for ${abstractValueDomain.getAllocationNode(info.originalType)} '
|
487 | 492 | 'at ${abstractValueDomain.getAllocationElement(info.originalType)}'
|
488 |
| - 'after ${info.refineCount}'); |
489 |
| - }); |
490 |
| - types.allocatedSets.values.forEach((_info) { |
| 493 | + 'after ${info.refineCount}'; |
| 494 | + })); |
| 495 | + printSorted(types.allocatedSets.values.map((_info) { |
491 | 496 | SetTypeInformation info = _info;
|
492 |
| - print('${info.type} ' |
| 497 | + return ('${info.type} ' |
493 | 498 | 'for ${abstractValueDomain.getAllocationNode(info.originalType)} '
|
494 | 499 | 'at ${abstractValueDomain.getAllocationElement(info.originalType)} '
|
495 | 500 | 'after ${info.refineCount}');
|
496 |
| - }); |
497 |
| - types.allocatedMaps.values.forEach((_info) { |
| 501 | + })); |
| 502 | + printSorted(types.allocatedMaps.values.map((_info) { |
498 | 503 | MapTypeInformation info = _info;
|
499 |
| - print('${info.type} ' |
| 504 | + return '${info.type} ' |
500 | 505 | 'for ${abstractValueDomain.getAllocationNode(info.originalType)} '
|
501 | 506 | 'at ${abstractValueDomain.getAllocationElement(info.originalType)}'
|
502 |
| - 'after ${info.refineCount}'); |
503 |
| - }); |
504 |
| - types.allocatedClosures.forEach((TypeInformation info) { |
| 507 | + 'after ${info.refineCount}'; |
| 508 | + })); |
| 509 | + printSorted(types.allocatedClosures.map((TypeInformation info) { |
505 | 510 | if (info is ElementTypeInformation) {
|
506 |
| - print('${info.getInferredSignature(types)} for ' |
507 |
| - '${info.debugName}'); |
| 511 | + return '${info.getInferredSignature(types)} for ' |
| 512 | + '${info.debugName}'; |
508 | 513 | } else if (info is ClosureTypeInformation) {
|
509 |
| - print('${info.getInferredSignature(types)} for ' |
510 |
| - '${info.debugName}'); |
| 514 | + return '${info.getInferredSignature(types)} for ' |
| 515 | + '${info.debugName}'; |
511 | 516 | } else if (info is DynamicCallSiteTypeInformation) {
|
| 517 | + var str = ''; |
512 | 518 | if (info.hasClosureCallTargets) {
|
513 |
| - print('<Closure.call>'); |
| 519 | + str += '<Closure.call>'; |
514 | 520 | }
|
515 | 521 | info.forEachConcreteTarget(memberHierarchyBuilder, (member) {
|
516 | 522 | if (member is FunctionEntity) {
|
517 |
| - print('${types.getInferredSignatureOfMethod(member)} ' |
518 |
| - 'for ${member}'); |
| 523 | + str += '${types.getInferredSignatureOfMethod(member)} ' |
| 524 | + 'for ${member}'; |
519 | 525 | } else {
|
520 |
| - print('${types.getInferredTypeOfMember(member).type} ' |
521 |
| - 'for ${member}'); |
| 526 | + str += '${types.getInferredTypeOfMember(member).type} ' |
| 527 | + 'for ${member}'; |
522 | 528 | }
|
523 | 529 | return true;
|
524 | 530 | });
|
| 531 | + return str; |
525 | 532 | } else if (info is StaticCallSiteTypeInformation) {
|
526 | 533 | final cls = info.calledElement.enclosingClass!;
|
527 | 534 | final callMethod = _lookupCallMethod(cls)!;
|
528 |
| - print('${types.getInferredSignatureOfMethod(callMethod)} for ${cls}'); |
| 535 | + return '${types.getInferredSignatureOfMethod(callMethod)} for ${cls}'; |
529 | 536 | } else {
|
530 |
| - print('${info.type} for some unknown kind of closure'); |
| 537 | + return '${info.type} for some unknown kind of closure'; |
531 | 538 | }
|
532 |
| - }); |
533 |
| - _analyzedElements.forEach((MemberEntity elem) { |
| 539 | + })); |
| 540 | + printSorted(_analyzedElements.map((MemberEntity elem) { |
534 | 541 | TypeInformation type = types.getInferredTypeOfMember(elem);
|
535 |
| - print('${elem} :: ${type} from ${type.inputs} '); |
536 |
| - }); |
| 542 | + return '${elem} :: ${type} from ${type.inputs} '; |
| 543 | + })); |
537 | 544 | }
|
538 | 545 | dump?.afterAnalysis();
|
539 | 546 |
|
@@ -779,7 +786,9 @@ class InferrerEngine {
|
779 | 786 | // Check that refinement has not accidentally changed the type.
|
780 | 787 | assert(oldType == info.type);
|
781 | 788 | if (info.abandonInferencing) info.doNotEnqueue = true;
|
782 |
| - if ((info.type = newType) != oldType) { |
| 789 | + final invalidRefine = |
| 790 | + abstractValueDomain.isInvalidRefinement(oldType, newType); |
| 791 | + if (!invalidRefine && (info.type = newType) != oldType) { |
783 | 792 | _overallRefineCount++;
|
784 | 793 | info.incrementRefineCount();
|
785 | 794 | if (info.refineCount > _MAX_CHANGE_COUNT) {
|
|
0 commit comments