| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 library dart2js.enqueue; | 5 library dart2js.enqueue; |
| 6 | 6 |
| 7 import 'dart:collection' show Queue; | 7 import 'dart:collection' show Queue; |
| 8 | 8 |
| 9 import 'cache_strategy.dart'; | 9 import 'cache_strategy.dart'; |
| 10 import 'common/backend_api.dart' show Backend; | 10 import 'common/backend_api.dart' show Backend; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 bool isProcessed(Element member); | 115 bool isProcessed(Element member); |
| 116 | 116 |
| 117 Iterable<Entity> get processedEntities; | 117 Iterable<Entity> get processedEntities; |
| 118 | 118 |
| 119 Iterable<ClassElement> get processedClasses; | 119 Iterable<ClassElement> get processedClasses; |
| 120 } | 120 } |
| 121 | 121 |
| 122 abstract class EnqueuerImpl extends Enqueuer { | 122 abstract class EnqueuerImpl extends Enqueuer { |
| 123 CompilerTask get task; | 123 CompilerTask get task; |
| 124 EnqueuerStrategy get strategy; | 124 EnqueuerStrategy get strategy; |
| 125 void processInstantiatedClassMembers(ClassElement cls); | |
| 126 void processInstantiatedClassMember(ClassElement cls, Element member); | 125 void processInstantiatedClassMember(ClassElement cls, Element member); |
| 127 void processStaticUse(StaticUse staticUse); | 126 void processStaticUse(StaticUse staticUse); |
| 128 void processTypeUse(TypeUse typeUse); | 127 void processTypeUse(TypeUse typeUse); |
| 129 void processDynamicUse(DynamicUse dynamicUse); | 128 void processDynamicUse(DynamicUse dynamicUse); |
| 130 } | 129 } |
| 131 | 130 |
| 132 /// [Enqueuer] which is specific to resolution. | 131 /// [Enqueuer] which is specific to resolution. |
| 133 class ResolutionEnqueuer extends EnqueuerImpl { | 132 class ResolutionEnqueuer extends EnqueuerImpl { |
| 134 static const ImpactUseCase IMPACT_USE = | 133 static const ImpactUseCase IMPACT_USE = |
| 135 const ImpactUseCase('ResolutionEnqueuer'); | 134 const ImpactUseCase('ResolutionEnqueuer'); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 if (!cls.isAbstract || isNative || mirrorUsage) { | 226 if (!cls.isAbstract || isNative || mirrorUsage) { |
| 228 _processInstantiatedClass(cls); | 227 _processInstantiatedClass(cls); |
| 229 } | 228 } |
| 230 }); | 229 }); |
| 231 } | 230 } |
| 232 | 231 |
| 233 bool checkNoEnqueuedInvokedInstanceMethods() { | 232 bool checkNoEnqueuedInvokedInstanceMethods() { |
| 234 return strategy.checkEnqueuerConsistency(this); | 233 return strategy.checkEnqueuerConsistency(this); |
| 235 } | 234 } |
| 236 | 235 |
| 237 void processInstantiatedClassMembers(ClassElement cls) { | |
| 238 strategy.processInstantiatedClass(this, cls); | |
| 239 } | |
| 240 | |
| 241 void processInstantiatedClassMember(ClassElement cls, Element member) { | 236 void processInstantiatedClassMember(ClassElement cls, Element member) { |
| 242 assert(invariant(member, member.isDeclaration)); | 237 assert(invariant(member, member.isDeclaration)); |
| 243 if (isProcessed(member)) return; | 238 if (isProcessed(member)) return; |
| 244 if (!member.isInstanceMember) return; | 239 if (!member.isInstanceMember) return; |
| 245 String memberName = member.name; | 240 String memberName = member.name; |
| 246 | 241 |
| 247 if (member.isField) { | 242 if (member.isField) { |
| 248 // The obvious thing to test here would be "member.isNative", | 243 // The obvious thing to test here would be "member.isNative", |
| 249 // however, that only works after metadata has been parsed/analyzed, | 244 // however, that only works after metadata has been parsed/analyzed, |
| 250 // and that may not have happened yet. | 245 // and that may not have happened yet. |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 void removeFromSet(Map<String, Set<Element>> map, Element element) { | 665 void removeFromSet(Map<String, Set<Element>> map, Element element) { |
| 671 Set<Element> set = map[element.name]; | 666 Set<Element> set = map[element.name]; |
| 672 if (set == null) return; | 667 if (set == null) return; |
| 673 set.remove(element); | 668 set.remove(element); |
| 674 } | 669 } |
| 675 | 670 |
| 676 /// Strategy used by the enqueuer to populate the world. | 671 /// Strategy used by the enqueuer to populate the world. |
| 677 class EnqueuerStrategy { | 672 class EnqueuerStrategy { |
| 678 const EnqueuerStrategy(); | 673 const EnqueuerStrategy(); |
| 679 | 674 |
| 680 /// Process a class instantiated in live code. | |
| 681 void processInstantiatedClass(EnqueuerImpl enqueuer, ClassElement cls) {} | |
| 682 | |
| 683 /// Process a static use of and element in live code. | 675 /// Process a static use of and element in live code. |
| 684 void processStaticUse(EnqueuerImpl enqueuer, StaticUse staticUse) {} | 676 void processStaticUse(EnqueuerImpl enqueuer, StaticUse staticUse) {} |
| 685 | 677 |
| 686 /// Process a type use in live code. | 678 /// Process a type use in live code. |
| 687 void processTypeUse(EnqueuerImpl enqueuer, TypeUse typeUse) {} | 679 void processTypeUse(EnqueuerImpl enqueuer, TypeUse typeUse) {} |
| 688 | 680 |
| 689 /// Process a dynamic use for a call site in live code. | 681 /// Process a dynamic use for a call site in live code. |
| 690 void processDynamicUse(EnqueuerImpl enqueuer, DynamicUse dynamicUse) {} | 682 void processDynamicUse(EnqueuerImpl enqueuer, DynamicUse dynamicUse) {} |
| 691 | 683 |
| 692 /// Check enqueuer consistency after the queue has been closed. | 684 /// Check enqueuer consistency after the queue has been closed. |
| 693 bool checkEnqueuerConsistency(EnqueuerImpl enqueuer) { | 685 bool checkEnqueuerConsistency(EnqueuerImpl enqueuer) => true; |
| 694 enqueuer.task.measure(() { | |
| 695 // Run through the classes and see if we need to enqueue more methods. | |
| 696 for (ClassElement classElement | |
| 697 in enqueuer.universe.directlyInstantiatedClasses) { | |
| 698 for (ClassElement currentClass = classElement; | |
| 699 currentClass != null; | |
| 700 currentClass = currentClass.superclass) { | |
| 701 enqueuer.processInstantiatedClassMembers(currentClass); | |
| 702 } | |
| 703 } | |
| 704 }); | |
| 705 return true; | |
| 706 } | |
| 707 | 686 |
| 708 /// Process [work] using [f]. | 687 /// Process [work] using [f]. |
| 709 void processWorkItem(void f(WorkItem work), WorkItem work) { | 688 void processWorkItem(void f(WorkItem work), WorkItem work) { |
| 710 f(work); | 689 f(work); |
| 711 } | 690 } |
| 712 } | 691 } |
| 713 | 692 |
| 714 /// Strategy that only enqueues directly used elements. | 693 /// Strategy that only enqueues directly used elements. |
| 715 class DirectEnqueuerStrategy extends EnqueuerStrategy { | 694 class DirectEnqueuerStrategy extends EnqueuerStrategy { |
| 716 const DirectEnqueuerStrategy(); | 695 const DirectEnqueuerStrategy(); |
| 717 void processStaticUse(EnqueuerImpl enqueuer, StaticUse staticUse) { | 696 void processStaticUse(EnqueuerImpl enqueuer, StaticUse staticUse) { |
| 718 if (staticUse.kind == StaticUseKind.DIRECT_USE) { | 697 if (staticUse.kind == StaticUseKind.DIRECT_USE) { |
| 719 enqueuer.processStaticUse(staticUse); | 698 enqueuer.processStaticUse(staticUse); |
| 720 } | 699 } |
| 721 } | 700 } |
| 722 } | 701 } |
| 723 | 702 |
| 724 /// Strategy used for tree-shaking. | 703 /// Strategy used for tree-shaking. |
| 725 class TreeShakingEnqueuerStrategy extends EnqueuerStrategy { | 704 class TreeShakingEnqueuerStrategy extends EnqueuerStrategy { |
| 726 const TreeShakingEnqueuerStrategy(); | 705 const TreeShakingEnqueuerStrategy(); |
| 727 | 706 |
| 728 @override | 707 @override |
| 729 void processInstantiatedClass(EnqueuerImpl enqueuer, ClassElement cls) { | |
| 730 cls.implementation.forEachMember(enqueuer.processInstantiatedClassMember); | |
| 731 } | |
| 732 | |
| 733 @override | |
| 734 void processStaticUse(EnqueuerImpl enqueuer, StaticUse staticUse) { | 708 void processStaticUse(EnqueuerImpl enqueuer, StaticUse staticUse) { |
| 735 enqueuer.processStaticUse(staticUse); | 709 enqueuer.processStaticUse(staticUse); |
| 736 } | 710 } |
| 737 | 711 |
| 738 @override | 712 @override |
| 739 void processTypeUse(EnqueuerImpl enqueuer, TypeUse typeUse) { | 713 void processTypeUse(EnqueuerImpl enqueuer, TypeUse typeUse) { |
| 740 enqueuer.processTypeUse(typeUse); | 714 enqueuer.processTypeUse(typeUse); |
| 741 } | 715 } |
| 742 | 716 |
| 743 @override | 717 @override |
| 744 void processDynamicUse(EnqueuerImpl enqueuer, DynamicUse dynamicUse) { | 718 void processDynamicUse(EnqueuerImpl enqueuer, DynamicUse dynamicUse) { |
| 745 enqueuer.processDynamicUse(dynamicUse); | 719 enqueuer.processDynamicUse(dynamicUse); |
| 746 } | 720 } |
| 721 |
| 722 /// Check enqueuer consistency after the queue has been closed. |
| 723 bool checkEnqueuerConsistency(EnqueuerImpl enqueuer) { |
| 724 enqueuer.task.measure(() { |
| 725 // Run through the classes and see if we need to enqueue more methods. |
| 726 for (ClassElement classElement |
| 727 in enqueuer.universe.directlyInstantiatedClasses) { |
| 728 for (ClassElement currentClass = classElement; |
| 729 currentClass != null; |
| 730 currentClass = currentClass.superclass) { |
| 731 currentClass.implementation |
| 732 .forEachMember(enqueuer.processInstantiatedClassMember); |
| 733 } |
| 734 } |
| 735 }); |
| 736 return true; |
| 737 } |
| 747 } | 738 } |
| 748 | 739 |
| 749 class EnqueuerImplImpactVisitor implements WorldImpactVisitor { | 740 class EnqueuerImplImpactVisitor implements WorldImpactVisitor { |
| 750 final EnqueuerImpl enqueuer; | 741 final EnqueuerImpl enqueuer; |
| 751 | 742 |
| 752 EnqueuerImplImpactVisitor(this.enqueuer); | 743 EnqueuerImplImpactVisitor(this.enqueuer); |
| 753 | 744 |
| 754 @override | 745 @override |
| 755 void visitDynamicUse(DynamicUse dynamicUse) { | 746 void visitDynamicUse(DynamicUse dynamicUse) { |
| 756 enqueuer.strategy.processDynamicUse(enqueuer, dynamicUse); | 747 enqueuer.strategy.processDynamicUse(enqueuer, dynamicUse); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 768 } | 759 } |
| 769 | 760 |
| 770 typedef void _DeferredActionFunction(); | 761 typedef void _DeferredActionFunction(); |
| 771 | 762 |
| 772 class _DeferredAction { | 763 class _DeferredAction { |
| 773 final Element element; | 764 final Element element; |
| 774 final _DeferredActionFunction action; | 765 final _DeferredActionFunction action; |
| 775 | 766 |
| 776 _DeferredAction(this.element, this.action); | 767 _DeferredAction(this.element, this.action); |
| 777 } | 768 } |
| OLD | NEW |