Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(481)

Side by Side Diff: pkg/compiler/lib/src/enqueue.dart

Issue 2289353003: Make Enqueuer a pure interface. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/compiler/lib/src/compiler.dart ('k') | pkg/compiler/lib/src/js_backend/backend.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 'common/codegen.dart' show CodegenWorkItem;
10 import 'common/names.dart' show Identifiers; 9 import 'common/names.dart' show Identifiers;
11 import 'common/resolution.dart' show Resolution; 10 import 'common/resolution.dart' show Resolution;
12 import 'common/resolution.dart' show ResolutionWorkItem; 11 import 'common/resolution.dart' show ResolutionWorkItem;
13 import 'common/tasks.dart' show CompilerTask; 12 import 'common/tasks.dart' show CompilerTask;
14 import 'common/work.dart' show ItemCompilationContext, WorkItem; 13 import 'common/work.dart' show ItemCompilationContext, WorkItem;
15 import 'common.dart'; 14 import 'common.dart';
16 import 'compiler.dart' show Compiler; 15 import 'compiler.dart' show Compiler;
17 import 'dart_types.dart' show DartType, InterfaceType; 16 import 'dart_types.dart' show DartType, InterfaceType;
18 import 'elements/elements.dart' 17 import 'elements/elements.dart'
19 show 18 show
20 AnalyzableElement, 19 AnalyzableElement,
21 AstElement, 20 AstElement,
22 ClassElement, 21 ClassElement,
23 ConstructorElement, 22 ConstructorElement,
24 Element, 23 Element,
25 Elements, 24 Elements,
25 Entity,
26 FunctionElement, 26 FunctionElement,
27 LibraryElement, 27 LibraryElement,
28 Member, 28 Member,
29 MemberElement,
30 Name, 29 Name,
31 TypedElement, 30 TypedElement,
32 TypedefElement; 31 TypedefElement;
33 import 'js/js.dart' as js;
34 import 'native/native.dart' as native; 32 import 'native/native.dart' as native;
35 import 'types/types.dart' show TypeMaskStrategy; 33 import 'types/types.dart' show TypeMaskStrategy;
36 import 'universe/selector.dart' show Selector; 34 import 'universe/selector.dart' show Selector;
37 import 'universe/universe.dart'; 35 import 'universe/universe.dart';
38 import 'universe/use.dart' 36 import 'universe/use.dart'
39 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind; 37 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind;
40 import 'universe/world_impact.dart' 38 import 'universe/world_impact.dart'
41 show ImpactUseCase, WorldImpact, WorldImpactVisitor; 39 show ImpactUseCase, WorldImpact, WorldImpactVisitor;
42 import 'util/util.dart' show Setlet; 40 import 'util/util.dart' show Setlet;
43 41
44 typedef ItemCompilationContext ItemCompilationContextCreator(); 42 typedef ItemCompilationContext ItemCompilationContextCreator();
45 43
46 class EnqueueTask extends CompilerTask { 44 class EnqueueTask extends CompilerTask {
47 final ResolutionEnqueuer resolution; 45 final ResolutionEnqueuer resolution;
48 final CodegenEnqueuer codegen; 46 final Enqueuer codegen;
49 final Compiler compiler; 47 final Compiler compiler;
50 48
51 String get name => 'Enqueue'; 49 String get name => 'Enqueue';
52 50
53 EnqueueTask(Compiler compiler) 51 EnqueueTask(Compiler compiler)
54 : compiler = compiler, 52 : compiler = compiler,
55 resolution = new ResolutionEnqueuer( 53 resolution = new ResolutionEnqueuer(
56 compiler, 54 compiler,
57 compiler.backend.createItemCompilationContext, 55 compiler.backend.createItemCompilationContext,
58 compiler.options.analyzeOnly && compiler.options.analyzeMain 56 compiler.options.analyzeOnly && compiler.options.analyzeMain
59 ? const EnqueuerStrategy() 57 ? const EnqueuerStrategy()
60 : const TreeShakingEnqueuerStrategy()), 58 : const TreeShakingEnqueuerStrategy()),
61 codegen = compiler.backend.createCodegenEnqueuer(compiler), 59 codegen = compiler.backend.createCodegenEnqueuer(compiler),
62 super(compiler.measurer) { 60 super(compiler.measurer) {
63 codegen.task = this; 61 codegen.task = this;
64 resolution.task = this; 62 resolution.task = this;
65 63
66 codegen.nativeEnqueuer = compiler.backend.nativeCodegenEnqueuer(codegen); 64 codegen.nativeEnqueuer = compiler.backend.nativeCodegenEnqueuer(codegen);
67 resolution.nativeEnqueuer = 65 resolution.nativeEnqueuer =
68 compiler.backend.nativeResolutionEnqueuer(resolution); 66 compiler.backend.nativeResolutionEnqueuer(resolution);
69 } 67 }
70 68
71 void forgetElement(Element element) { 69 void forgetElement(Element element) {
72 resolution.forgetElement(element); 70 resolution.forgetElement(element);
73 codegen.forgetElement(element); 71 codegen.forgetElement(element);
74 } 72 }
75 } 73 }
76 74
77 abstract class Enqueuer { 75 abstract class Enqueuer {
76 EnqueueTask task;
77 Universe get universe;
78 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask
79 void forgetElement(Element element);
80 void processInstantiatedClassMembers(ClassElement cls);
81 void processInstantiatedClassMember(ClassElement cls, Element member);
82 void handleUnseenSelectorInternal(DynamicUse dynamicUse);
83 void registerStaticUse(StaticUse staticUse);
84 void registerStaticUseInternal(StaticUse staticUse);
85 void registerDynamicUse(DynamicUse dynamicUse);
86 void registerTypeUse(TypeUse typeUse);
87
88 /// Returns [:true:] if this enqueuer is the resolution enqueuer.
89 bool get isResolutionQueue;
90
91 bool queueIsClosed;
92
93 bool get queueIsEmpty;
94
95 ImpactUseCase get impactUse;
96
97 /**
98 * Documentation wanted -- johnniwinther
99 *
100 * Invariant: [element] must be a declaration element.
101 */
102 void addToWorkList(Element element);
103
104 void enableIsolateSupport();
105
106 /// Enqueue the static fields that have been marked as used by reflective
107 /// usage through `MirrorsUsed`.
108 void enqueueReflectiveStaticFields(Iterable<Element> elements);
109
110 /// Enqueue all elements that are matched by the mirrors used
111 /// annotation or, in lack thereof, all elements.
112 void enqueueReflectiveElements(Iterable<ClassElement> recents);
113
114 void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false});
115 void forEach(void f(WorkItem work));
116 void applyImpact(Element element, WorldImpact worldImpact);
117 bool checkNoEnqueuedInvokedInstanceMethods();
118 void logSummary(log(message));
119
120 /// Returns [:true:] if [member] has been processed by this enqueuer.
121 bool isProcessed(Element member);
122
123 Iterable<Entity> get processedEntities;
124 }
125
126 /// [Enqueuer] which is specific to resolution.
127 class ResolutionEnqueuer extends Enqueuer {
78 final String name; 128 final String name;
79 final Compiler compiler; // TODO(ahe): Remove this dependency. 129 final Compiler compiler; // TODO(ahe): Remove this dependency.
80 final EnqueuerStrategy strategy; 130 final EnqueuerStrategy strategy;
81 final ItemCompilationContextCreator itemCompilationContextCreator; 131 final ItemCompilationContextCreator itemCompilationContextCreator;
82 final Map<String, Set<Element>> instanceMembersByName = 132 final Map<String, Set<Element>> instanceMembersByName =
83 new Map<String, Set<Element>>(); 133 new Map<String, Set<Element>>();
84 final Map<String, Set<Element>> instanceFunctionsByName = 134 final Map<String, Set<Element>> instanceFunctionsByName =
85 new Map<String, Set<Element>>(); 135 new Map<String, Set<Element>>();
86 final Set<ClassElement> _processedClasses = new Set<ClassElement>(); 136 final Set<ClassElement> _processedClasses = new Set<ClassElement>();
87 Set<ClassElement> recentClasses = new Setlet<ClassElement>(); 137 Set<ClassElement> recentClasses = new Setlet<ClassElement>();
88 final Universe universe = new Universe(const TypeMaskStrategy()); 138 final Universe universe = new Universe(const TypeMaskStrategy());
89 139
90 static final TRACE_MIRROR_ENQUEUING = 140 static final TRACE_MIRROR_ENQUEUING =
91 const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING"); 141 const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING");
92 142
93 bool queueIsClosed = false; 143 bool queueIsClosed = false;
94 EnqueueTask task;
95 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask
96 144
97 bool hasEnqueuedReflectiveElements = false; 145 bool hasEnqueuedReflectiveElements = false;
98 bool hasEnqueuedReflectiveStaticFields = false; 146 bool hasEnqueuedReflectiveStaticFields = false;
99 147
100 WorldImpactVisitor impactVisitor; 148 WorldImpactVisitor impactVisitor;
101 149
102 Enqueuer(this.name, this.compiler, this.itemCompilationContextCreator, 150 ResolutionEnqueuer(
103 this.strategy) { 151 Compiler compiler, this.itemCompilationContextCreator, this.strategy)
152 : this.name = 'resolution enqueuer',
153 this.compiler = compiler,
154 processedElements = new Set<AstElement>(),
155 queue = new Queue<ResolutionWorkItem>(),
156 deferredQueue = new Queue<_DeferredAction>() {
104 impactVisitor = new _EnqueuerImpactVisitor(this); 157 impactVisitor = new _EnqueuerImpactVisitor(this);
105 } 158 }
106 159
107 // TODO(johnniwinther): Move this to [ResolutionEnqueuer]. 160 // TODO(johnniwinther): Move this to [ResolutionEnqueuer].
108 Resolution get resolution => compiler.resolution; 161 Resolution get resolution => compiler.resolution;
109 162
110 Queue<WorkItem> get queue;
111 bool get queueIsEmpty => queue.isEmpty; 163 bool get queueIsEmpty => queue.isEmpty;
112 164
113 /// Returns [:true:] if this enqueuer is the resolution enqueuer.
114 bool get isResolutionQueue => false;
115
116 QueueFilter get filter => compiler.enqueuerFilter; 165 QueueFilter get filter => compiler.enqueuerFilter;
117 166
118 DiagnosticReporter get reporter => compiler.reporter; 167 DiagnosticReporter get reporter => compiler.reporter;
119 168
120 /// Returns [:true:] if [member] has been processed by this enqueuer.
121 bool isProcessed(Element member);
122
123 bool isClassProcessed(ClassElement cls) => _processedClasses.contains(cls); 169 bool isClassProcessed(ClassElement cls) => _processedClasses.contains(cls);
124 170
125 Iterable<ClassElement> get processedClasses => _processedClasses; 171 Iterable<ClassElement> get processedClasses => _processedClasses;
126 172
127 ImpactUseCase get impactUse;
128
129 /** 173 /**
130 * Documentation wanted -- johnniwinther 174 * Documentation wanted -- johnniwinther
131 * 175 *
132 * Invariant: [element] must be a declaration element. 176 * Invariant: [element] must be a declaration element.
133 */ 177 */
134 void addToWorkList(Element element) { 178 void addToWorkList(Element element) {
135 assert(invariant(element, element.isDeclaration)); 179 assert(invariant(element, element.isDeclaration));
136 if (internalAddToWorkList(element) && compiler.options.dumpInfo) { 180 if (internalAddToWorkList(element) && compiler.options.dumpInfo) {
137 // TODO(sigmund): add other missing dependencies (internals, selectors 181 // TODO(sigmund): add other missing dependencies (internals, selectors
138 // enqueued after allocations), also enable only for the codegen enqueuer. 182 // enqueued after allocations), also enable only for the codegen enqueuer.
139 compiler.dumpInfoTask 183 compiler.dumpInfoTask
140 .registerDependency(compiler.currentElement, element); 184 .registerDependency(compiler.currentElement, element);
141 } 185 }
142 } 186 }
143 187
144 /**
145 * Adds [element] to the work list if it has not already been processed.
146 *
147 * Returns [true] if the element was actually added to the queue.
148 */
149 bool internalAddToWorkList(Element element);
150
151 /// Apply the [worldImpact] of processing [element] to this enqueuer. 188 /// Apply the [worldImpact] of processing [element] to this enqueuer.
152 void applyImpact(Element element, WorldImpact worldImpact) { 189 void applyImpact(Element element, WorldImpact worldImpact) {
153 compiler.impactStrategy 190 compiler.impactStrategy
154 .visitImpact(element, worldImpact, impactVisitor, impactUse); 191 .visitImpact(element, worldImpact, impactVisitor, impactUse);
155 } 192 }
156 193
157 void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}) { 194 void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}) {
158 task.measure(() { 195 task.measure(() {
159 ClassElement cls = type.element; 196 ClassElement cls = type.element;
160 cls.ensureResolved(resolution); 197 cls.ensureResolved(resolution);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 } 298 }
262 } 299 }
263 300
264 // The element is not yet used. Add it to the list of instance 301 // The element is not yet used. Add it to the list of instance
265 // members to still be processed. 302 // members to still be processed.
266 instanceMembersByName 303 instanceMembersByName
267 .putIfAbsent(memberName, () => new Set<Element>()) 304 .putIfAbsent(memberName, () => new Set<Element>())
268 .add(member); 305 .add(member);
269 } 306 }
270 307
271 void registerNoSuchMethod(Element noSuchMethod);
272
273 void enableIsolateSupport() {}
274
275 void processInstantiatedClass(ClassElement cls) { 308 void processInstantiatedClass(ClassElement cls) {
276 task.measure(() { 309 task.measure(() {
277 if (_processedClasses.contains(cls)) return; 310 if (_processedClasses.contains(cls)) return;
278 // The class must be resolved to compute the set of all 311 // The class must be resolved to compute the set of all
279 // supertypes. 312 // supertypes.
280 cls.ensureResolved(resolution); 313 cls.ensureResolved(resolution);
281 314
282 void processClass(ClassElement superclass) { 315 void processClass(ClassElement superclass) {
283 if (_processedClasses.contains(superclass)) return; 316 if (_processedClasses.contains(superclass)) return;
284 // TODO(johnniwinther): Re-insert this invariant when unittests don't 317 // TODO(johnniwinther): Re-insert this invariant when unittests don't
(...skipping 30 matching lines...) Expand all
315 } 348 }
316 349
317 void registerDynamicUse(DynamicUse dynamicUse) { 350 void registerDynamicUse(DynamicUse dynamicUse) {
318 task.measure(() { 351 task.measure(() {
319 if (universe.registerDynamicUse(dynamicUse)) { 352 if (universe.registerDynamicUse(dynamicUse)) {
320 handleUnseenSelector(dynamicUse); 353 handleUnseenSelector(dynamicUse);
321 } 354 }
322 }); 355 });
323 } 356 }
324 357
325 /**
326 * Decides whether an element should be included to satisfy requirements
327 * of the mirror system. [includedEnclosing] provides a hint whether the
328 * enclosing element was included.
329 *
330 * The actual implementation depends on the current compiler phase.
331 */
332 bool shouldIncludeElementDueToMirrors(Element element,
333 {bool includedEnclosing});
334
335 void logEnqueueReflectiveAction(action, [msg = ""]) { 358 void logEnqueueReflectiveAction(action, [msg = ""]) {
336 if (TRACE_MIRROR_ENQUEUING) { 359 if (TRACE_MIRROR_ENQUEUING) {
337 print("MIRROR_ENQUEUE (${isResolutionQueue ? "R" : "C"}): $action $msg"); 360 print("MIRROR_ENQUEUE (${isResolutionQueue ? "R" : "C"}): $action $msg");
338 } 361 }
339 } 362 }
340 363
341 /// Enqeue the constructor [ctor] if it is required for reflection. 364 /// Enqeue the constructor [ctor] if it is required for reflection.
342 /// 365 ///
343 /// [enclosingWasIncluded] provides a hint whether the enclosing element was 366 /// [enclosingWasIncluded] provides a hint whether the enclosing element was
344 /// needed for reflection. 367 /// needed for reflection.
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 while (queue.isNotEmpty) { 663 while (queue.isNotEmpty) {
641 // TODO(johnniwinther): Find an optimal process order. 664 // TODO(johnniwinther): Find an optimal process order.
642 filter.processWorkItem(f, queue.removeLast()); 665 filter.processWorkItem(f, queue.removeLast());
643 } 666 }
644 List recents = recentClasses.toList(growable: false); 667 List recents = recentClasses.toList(growable: false);
645 recentClasses.clear(); 668 recentClasses.clear();
646 if (!onQueueEmpty(recents)) recentClasses.addAll(recents); 669 if (!onQueueEmpty(recents)) recentClasses.addAll(recents);
647 } while (queue.isNotEmpty || recentClasses.isNotEmpty); 670 } while (queue.isNotEmpty || recentClasses.isNotEmpty);
648 } 671 }
649 672
650 /// [onQueueEmpty] is called whenever the queue is drained. [recentClasses]
651 /// contains the set of all classes seen for the first time since
652 /// [onQueueEmpty] was called last. A return value of [true] indicates that
653 /// the [recentClasses] have been processed and may be cleared. If [false] is
654 /// returned, [onQueueEmpty] will be called once the queue is empty again (or
655 /// still empty) and [recentClasses] will be a superset of the current value.
656 bool onQueueEmpty(Iterable<ClassElement> recentClasses) {
657 return compiler.backend.onQueueEmpty(this, recentClasses);
658 }
659
660 void logSummary(log(message)) { 673 void logSummary(log(message)) {
661 _logSpecificSummary(log); 674 log('Resolved ${processedElements.length} elements.');
662 nativeEnqueuer.logSummary(log); 675 nativeEnqueuer.logSummary(log);
663 } 676 }
664 677
665 /// Log summary specific to the concrete enqueuer.
666 void _logSpecificSummary(log(message));
667
668 String toString() => 'Enqueuer($name)'; 678 String toString() => 'Enqueuer($name)';
669 679
670 void forgetElement(Element element) {
671 universe.forgetElement(element, compiler);
672 _processedClasses.remove(element);
673 instanceMembersByName[element.name]?.remove(element);
674 instanceFunctionsByName[element.name]?.remove(element);
675 }
676 }
677
678 /// [Enqueuer] which is specific to resolution.
679 class ResolutionEnqueuer extends Enqueuer {
680 /// All declaration elements that have been processed by the resolver. 680 /// All declaration elements that have been processed by the resolver.
681 final Set<AstElement> processedElements; 681 final Set<AstElement> processedElements;
682 682
683 Iterable<Entity> get processedEntities => processedElements;
684
683 final Queue<ResolutionWorkItem> queue; 685 final Queue<ResolutionWorkItem> queue;
684 686
685 /// Queue of deferred resolution actions to execute when the resolution queue 687 /// Queue of deferred resolution actions to execute when the resolution queue
686 /// has been emptied. 688 /// has been emptied.
687 final Queue<_DeferredAction> deferredQueue; 689 final Queue<_DeferredAction> deferredQueue;
688 690
689 static const ImpactUseCase IMPACT_USE = 691 static const ImpactUseCase IMPACT_USE =
690 const ImpactUseCase('ResolutionEnqueuer'); 692 const ImpactUseCase('ResolutionEnqueuer');
691 693
692 ImpactUseCase get impactUse => IMPACT_USE; 694 ImpactUseCase get impactUse => IMPACT_USE;
693 695
694 ResolutionEnqueuer(
695 Compiler compiler,
696 ItemCompilationContext itemCompilationContextCreator(),
697 EnqueuerStrategy strategy)
698 : super('resolution enqueuer', compiler, itemCompilationContextCreator,
699 strategy),
700 processedElements = new Set<AstElement>(),
701 queue = new Queue<ResolutionWorkItem>(),
702 deferredQueue = new Queue<_DeferredAction>();
703
704 bool get isResolutionQueue => true; 696 bool get isResolutionQueue => true;
705 697
706 bool isProcessed(Element member) => processedElements.contains(member); 698 bool isProcessed(Element member) => processedElements.contains(member);
707 699
708 /// Returns `true` if [element] has been processed by the resolution enqueuer. 700 /// Returns `true` if [element] has been processed by the resolution enqueuer.
709 bool hasBeenProcessed(Element element) { 701 bool hasBeenProcessed(Element element) {
710 return processedElements.contains(element.analyzableElement.declaration); 702 return processedElements.contains(element.analyzableElement.declaration);
711 } 703 }
712 704
713 /// Registers [element] as processed by the resolution enqueuer. 705 /// Registers [element] as processed by the resolution enqueuer.
714 void registerProcessedElement(AstElement element) { 706 void registerProcessedElement(AstElement element) {
715 processedElements.add(element); 707 processedElements.add(element);
716 compiler.backend.onElementResolved(element); 708 compiler.backend.onElementResolved(element);
717 } 709 }
718 710
719 /** 711 /**
720 * Decides whether an element should be included to satisfy requirements 712 * Decides whether an element should be included to satisfy requirements
721 * of the mirror system. 713 * of the mirror system.
722 * 714 *
723 * During resolution, we have to resort to matching elements against the 715 * During resolution, we have to resort to matching elements against the
724 * [MirrorsUsed] pattern, as we do not have a complete picture of the world, 716 * [MirrorsUsed] pattern, as we do not have a complete picture of the world,
725 * yet. 717 * yet.
726 */ 718 */
727 bool shouldIncludeElementDueToMirrors(Element element, 719 bool shouldIncludeElementDueToMirrors(Element element,
728 {bool includedEnclosing}) { 720 {bool includedEnclosing}) {
729 return includedEnclosing || 721 return includedEnclosing ||
730 compiler.backend.requiredByMirrorSystem(element); 722 compiler.backend.requiredByMirrorSystem(element);
731 } 723 }
732 724
725 /**
726 * Adds [element] to the work list if it has not already been processed.
727 *
728 * Returns [true] if the element was actually added to the queue.
729 */
733 bool internalAddToWorkList(Element element) { 730 bool internalAddToWorkList(Element element) {
734 if (element.isMalformed) return false; 731 if (element.isMalformed) return false;
735 732
736 assert(invariant(element, element is AnalyzableElement, 733 assert(invariant(element, element is AnalyzableElement,
737 message: 'Element $element is not analyzable.')); 734 message: 'Element $element is not analyzable.'));
738 if (hasBeenProcessed(element)) return false; 735 if (hasBeenProcessed(element)) return false;
739 if (queueIsClosed) { 736 if (queueIsClosed) {
740 throw new SpannableAssertionFailure( 737 throw new SpannableAssertionFailure(
741 element, "Resolution work list is closed. Trying to add $element."); 738 element, "Resolution work list is closed. Trying to add $element.");
742 } 739 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 void addDeferredAction(Element element, void action()) { 797 void addDeferredAction(Element element, void action()) {
801 if (queueIsClosed) { 798 if (queueIsClosed) {
802 throw new SpannableAssertionFailure( 799 throw new SpannableAssertionFailure(
803 element, 800 element,
804 "Resolution work list is closed. " 801 "Resolution work list is closed. "
805 "Trying to add deferred action for $element"); 802 "Trying to add deferred action for $element");
806 } 803 }
807 deferredQueue.add(new _DeferredAction(element, action)); 804 deferredQueue.add(new _DeferredAction(element, action));
808 } 805 }
809 806
807 /// [onQueueEmpty] is called whenever the queue is drained. [recentClasses]
808 /// contains the set of all classes seen for the first time since
809 /// [onQueueEmpty] was called last. A return value of [true] indicates that
810 /// the [recentClasses] have been processed and may be cleared. If [false] is
811 /// returned, [onQueueEmpty] will be called once the queue is empty again (or
812 /// still empty) and [recentClasses] will be a superset of the current value.
810 bool onQueueEmpty(Iterable<ClassElement> recentClasses) { 813 bool onQueueEmpty(Iterable<ClassElement> recentClasses) {
811 _emptyDeferredQueue(); 814 _emptyDeferredQueue();
812 return super.onQueueEmpty(recentClasses); 815
816 return compiler.backend.onQueueEmpty(this, recentClasses);
813 } 817 }
814 818
815 void emptyDeferredQueueForTesting() => _emptyDeferredQueue(); 819 void emptyDeferredQueueForTesting() => _emptyDeferredQueue();
816 820
817 void _emptyDeferredQueue() { 821 void _emptyDeferredQueue() {
818 while (!deferredQueue.isEmpty) { 822 while (!deferredQueue.isEmpty) {
819 _DeferredAction task = deferredQueue.removeFirst(); 823 _DeferredAction task = deferredQueue.removeFirst();
820 reporter.withCurrentElement(task.element, task.action); 824 reporter.withCurrentElement(task.element, task.action);
821 } 825 }
822 } 826 }
823 827
824 void _logSpecificSummary(log(message)) {
825 log('Resolved ${processedElements.length} elements.');
826 }
827
828 void forgetElement(Element element) { 828 void forgetElement(Element element) {
829 super.forgetElement(element); 829 universe.forgetElement(element, compiler);
830 _processedClasses.remove(element);
831 instanceMembersByName[element.name]?.remove(element);
832 instanceFunctionsByName[element.name]?.remove(element);
830 processedElements.remove(element); 833 processedElements.remove(element);
831 } 834 }
832 } 835 }
833 836
834 /// [Enqueuer] which is specific to code generation.
835 abstract class CodegenEnqueuer implements Enqueuer {
836 Map<Element, js.Expression> get generatedCode;
837
838 Set<Element> get newlyEnqueuedElements;
839 }
840
841 /// Parameterizes filtering of which work items are enqueued. 837 /// Parameterizes filtering of which work items are enqueued.
842 class QueueFilter { 838 class QueueFilter {
843 bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) { 839 bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) {
844 enqueuer.task.measure(() { 840 enqueuer.task.measure(() {
845 // Run through the classes and see if we need to compile methods. 841 // Run through the classes and see if we need to compile methods.
846 for (ClassElement classElement 842 for (ClassElement classElement
847 in enqueuer.universe.directlyInstantiatedClasses) { 843 in enqueuer.universe.directlyInstantiatedClasses) {
848 for (ClassElement currentClass = classElement; 844 for (ClassElement currentClass = classElement;
849 currentClass != null; 845 currentClass != null;
850 currentClass = currentClass.superclass) { 846 currentClass = currentClass.superclass) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 } 918 }
923 919
924 typedef void _DeferredActionFunction(); 920 typedef void _DeferredActionFunction();
925 921
926 class _DeferredAction { 922 class _DeferredAction {
927 final Element element; 923 final Element element;
928 final _DeferredActionFunction action; 924 final _DeferredActionFunction action;
929 925
930 _DeferredAction(this.element, this.action); 926 _DeferredAction(this.element, this.action);
931 } 927 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/compiler.dart ('k') | pkg/compiler/lib/src/js_backend/backend.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698