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 |