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

Side by Side Diff: pkg/compiler/lib/src/js_backend/enqueuer.dart

Issue 2716713003: Move main and isolate handling to enqueuer listeners. (Closed)
Patch Set: Created 3 years, 10 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
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.js.enqueue; 5 library dart2js.js.enqueue;
6 6
7 import 'dart:collection' show Queue; 7 import 'dart:collection' show Queue;
8 8
9 import '../common/codegen.dart' show CodegenWorkItem; 9 import '../common/codegen.dart' show CodegenWorkItem;
10 import '../common/tasks.dart' show CompilerTask; 10 import '../common/tasks.dart' show CompilerTask;
(...skipping 21 matching lines...) Expand all
32 final String name; 32 final String name;
33 final EnqueuerStrategy strategy; 33 final EnqueuerStrategy strategy;
34 34
35 Set<ClassEntity> _recentClasses = new Setlet<ClassEntity>(); 35 Set<ClassEntity> _recentClasses = new Setlet<ClassEntity>();
36 final CodegenWorldBuilderImpl _universe; 36 final CodegenWorldBuilderImpl _universe;
37 final WorkItemBuilder _workItemBuilder; 37 final WorkItemBuilder _workItemBuilder;
38 38
39 bool queueIsClosed = false; 39 bool queueIsClosed = false;
40 final CompilerTask task; 40 final CompilerTask task;
41 final native.NativeEnqueuer nativeEnqueuer; 41 final native.NativeEnqueuer nativeEnqueuer;
42 final EnqueuerListener _listener; 42 final EnqueuerListener listener;
43 final CompilerOptions _options; 43 final CompilerOptions _options;
44 44
45 WorldImpactVisitor _impactVisitor; 45 WorldImpactVisitor _impactVisitor;
46 46
47 final Queue<WorkItem> _queue = new Queue<WorkItem>(); 47 final Queue<WorkItem> _queue = new Queue<WorkItem>();
48 48
49 /// All declaration elements that have been processed by codegen. 49 /// All declaration elements that have been processed by codegen.
50 final Set<Entity> _processedEntities = new Set<Entity>(); 50 final Set<Entity> _processedEntities = new Set<Entity>();
51 51
52 static const ImpactUseCase IMPACT_USE = 52 static const ImpactUseCase IMPACT_USE =
53 const ImpactUseCase('CodegenEnqueuer'); 53 const ImpactUseCase('CodegenEnqueuer');
54 54
55 CodegenEnqueuer(this.task, JavaScriptBackend backend, CompilerOptions options, 55 CodegenEnqueuer(this.task, JavaScriptBackend backend, CompilerOptions options,
56 this.strategy) 56 this.strategy)
57 : _universe = 57 : _universe =
58 new CodegenWorldBuilderImpl(backend, const TypeMaskStrategy()), 58 new CodegenWorldBuilderImpl(backend, const TypeMaskStrategy()),
59 _workItemBuilder = new CodegenWorkItemBuilder(backend, options), 59 _workItemBuilder = new CodegenWorkItemBuilder(backend, options),
60 nativeEnqueuer = backend.nativeCodegenEnqueuer(), 60 nativeEnqueuer = backend.nativeCodegenEnqueuer(),
61 this._listener = backend.codegenEnqueuerListener, 61 this.listener = backend.codegenEnqueuerListener,
62 this._options = options, 62 this._options = options,
63 this.name = 'codegen enqueuer' { 63 this.name = 'codegen enqueuer' {
64 _impactVisitor = new EnqueuerImplImpactVisitor(this); 64 _impactVisitor = new EnqueuerImplImpactVisitor(this);
65 } 65 }
66 66
67 CodegenWorldBuilder get worldBuilder => _universe; 67 CodegenWorldBuilder get worldBuilder => _universe;
68 68
69 bool get queueIsEmpty => _queue.isEmpty; 69 bool get queueIsEmpty => _queue.isEmpty;
70 70
71 @override 71 @override
(...skipping 13 matching lines...) Expand all
85 if (_processedEntities.contains(entity)) return; 85 if (_processedEntities.contains(entity)) return;
86 86
87 WorkItem workItem = _workItemBuilder.createWorkItem(entity); 87 WorkItem workItem = _workItemBuilder.createWorkItem(entity);
88 if (workItem == null) return; 88 if (workItem == null) return;
89 89
90 if (queueIsClosed) { 90 if (queueIsClosed) {
91 throw new SpannableAssertionFailure( 91 throw new SpannableAssertionFailure(
92 entity, "Codegen work list is closed. Trying to add $entity"); 92 entity, "Codegen work list is closed. Trying to add $entity");
93 } 93 }
94 94
95 applyImpact(_listener.registerUsedElement(entity)); 95 applyImpact(listener.registerUsedElement(entity));
96 _queue.add(workItem); 96 _queue.add(workItem);
97 } 97 }
98 98
99 void applyImpact(WorldImpact worldImpact, {var impactSource}) { 99 void applyImpact(WorldImpact worldImpact, {var impactSource}) {
100 if (worldImpact.isEmpty) return; 100 if (worldImpact.isEmpty) return;
101 impactStrategy.visitImpact( 101 impactStrategy.visitImpact(
102 impactSource, worldImpact, _impactVisitor, impactUse); 102 impactSource, worldImpact, _impactVisitor, impactUse);
103 } 103 }
104 104
105 void _registerInstantiatedType(ResolutionInterfaceType type, 105 void _registerInstantiatedType(ResolutionInterfaceType type,
106 {bool mirrorUsage: false, bool nativeUsage: false}) { 106 {bool mirrorUsage: false, bool nativeUsage: false}) {
107 task.measure(() { 107 task.measure(() {
108 _universe.registerTypeInstantiation(type, _applyClassUse, 108 _universe.registerTypeInstantiation(type, _applyClassUse,
109 byMirrors: mirrorUsage); 109 byMirrors: mirrorUsage);
110 if (nativeUsage) { 110 if (nativeUsage) {
111 nativeEnqueuer.onInstantiatedType(type); 111 nativeEnqueuer.onInstantiatedType(type);
112 } 112 }
113 _listener.registerInstantiatedType(type); 113 listener.registerInstantiatedType(type);
114 }); 114 });
115 } 115 }
116 116
117 bool checkNoEnqueuedInvokedInstanceMethods() { 117 bool checkNoEnqueuedInvokedInstanceMethods() {
118 return strategy.checkEnqueuerConsistency(this); 118 return strategy.checkEnqueuerConsistency(this);
119 } 119 }
120 120
121 void checkClass(ClassEntity cls) { 121 void checkClass(ClassEntity cls) {
122 _universe.processClassMembers(cls, (MemberEntity member, useSet) { 122 _universe.processClassMembers(cls, (MemberEntity member, useSet) {
123 if (useSet.isNotEmpty) { 123 if (useSet.isNotEmpty) {
124 throw new SpannableAssertionFailure(member, 124 throw new SpannableAssertionFailure(member,
125 'Unenqueued use of $member: ${useSet.iterable(MemberUse.values)}'); 125 'Unenqueued use of $member: ${useSet.iterable(MemberUse.values)}');
126 } 126 }
127 }); 127 });
128 } 128 }
129 129
130 /// Callback for applying the use of a [cls]. 130 /// Callback for applying the use of a [cls].
131 void _applyClassUse(ClassEntity cls, EnumSet<ClassUse> useSet) { 131 void _applyClassUse(ClassEntity cls, EnumSet<ClassUse> useSet) {
132 if (useSet.contains(ClassUse.INSTANTIATED)) { 132 if (useSet.contains(ClassUse.INSTANTIATED)) {
133 _recentClasses.add(cls); 133 _recentClasses.add(cls);
134 _universe.processClassMembers(cls, _applyMemberUse); 134 _universe.processClassMembers(cls, _applyMemberUse);
135 // We only tell the backend once that [cls] was instantiated, so 135 // We only tell the backend once that [cls] was instantiated, so
136 // any additional dependencies must be treated as global 136 // any additional dependencies must be treated as global
137 // dependencies. 137 // dependencies.
138 applyImpact(_listener.registerInstantiatedClass(cls)); 138 applyImpact(listener.registerInstantiatedClass(cls));
139 } 139 }
140 if (useSet.contains(ClassUse.IMPLEMENTED)) { 140 if (useSet.contains(ClassUse.IMPLEMENTED)) {
141 applyImpact(_listener.registerImplementedClass(cls)); 141 applyImpact(listener.registerImplementedClass(cls));
142 } 142 }
143 } 143 }
144 144
145 /// Callback for applying the use of a [member]. 145 /// Callback for applying the use of a [member].
146 void _applyMemberUse(Entity member, EnumSet<MemberUse> useSet) { 146 void _applyMemberUse(Entity member, EnumSet<MemberUse> useSet) {
147 if (useSet.contains(MemberUse.NORMAL)) { 147 if (useSet.contains(MemberUse.NORMAL)) {
148 _addToWorkList(member); 148 _addToWorkList(member);
149 } 149 }
150 if (useSet.contains(MemberUse.CLOSURIZE_INSTANCE)) { 150 if (useSet.contains(MemberUse.CLOSURIZE_INSTANCE)) {
151 _registerClosurizedMember(member); 151 _registerClosurizedMember(member);
152 } 152 }
153 if (useSet.contains(MemberUse.CLOSURIZE_STATIC)) { 153 if (useSet.contains(MemberUse.CLOSURIZE_STATIC)) {
154 applyImpact(_listener.registerGetOfStaticFunction()); 154 applyImpact(listener.registerGetOfStaticFunction());
155 } 155 }
156 } 156 }
157 157
158 void processDynamicUse(DynamicUse dynamicUse) { 158 void processDynamicUse(DynamicUse dynamicUse) {
159 task.measure(() { 159 task.measure(() {
160 _universe.registerDynamicUse(dynamicUse, _applyMemberUse); 160 _universe.registerDynamicUse(dynamicUse, _applyMemberUse);
161 }); 161 });
162 } 162 }
163 163
164 void processStaticUse(StaticUse staticUse) { 164 void processStaticUse(StaticUse staticUse) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 // Even in checked mode, type annotations for return type and argument 206 // Even in checked mode, type annotations for return type and argument
207 // types do not imply type checks, so there should never be a check 207 // types do not imply type checks, so there should never be a check
208 // against the type variable of a typedef. 208 // against the type variable of a typedef.
209 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); 209 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef);
210 } 210 }
211 211
212 void _registerClosurizedMember(TypedElement element) { 212 void _registerClosurizedMember(TypedElement element) {
213 assert(element.isInstanceMember); 213 assert(element.isInstanceMember);
214 if (element.type.containsTypeVariables) { 214 if (element.type.containsTypeVariables) {
215 MemberElement member = element; 215 MemberElement member = element;
216 applyImpact(_listener.registerClosureWithFreeTypeVariables(member)); 216 applyImpact(listener.registerClosureWithFreeTypeVariables(member));
217 } 217 }
218 applyImpact(_listener.registerBoundClosure()); 218 applyImpact(listener.registerBoundClosure());
219 } 219 }
220 220
221 void forEach(void f(WorkItem work)) { 221 void forEach(void f(WorkItem work)) {
222 do { 222 do {
223 while (_queue.isNotEmpty) { 223 while (_queue.isNotEmpty) {
224 // TODO(johnniwinther): Find an optimal process order. 224 // TODO(johnniwinther): Find an optimal process order.
225 WorkItem work = _queue.removeLast(); 225 WorkItem work = _queue.removeLast();
226 if (!_processedEntities.contains(work.element)) { 226 if (!_processedEntities.contains(work.element)) {
227 strategy.processWorkItem(f, work); 227 strategy.processWorkItem(f, work);
228 // TODO(johnniwinther): Register the processed element here. This 228 // TODO(johnniwinther): Register the processed element here. This
229 // is currently a side-effect of calling `work.run`. 229 // is currently a side-effect of calling `work.run`.
230 _processedEntities.add(work.element); 230 _processedEntities.add(work.element);
231 } 231 }
232 } 232 }
233 List recents = _recentClasses.toList(growable: false); 233 List recents = _recentClasses.toList(growable: false);
234 _recentClasses.clear(); 234 _recentClasses.clear();
235 if (!_onQueueEmpty(recents)) _recentClasses.addAll(recents); 235 if (!_onQueueEmpty(recents)) _recentClasses.addAll(recents);
236 } while (_queue.isNotEmpty || _recentClasses.isNotEmpty); 236 } while (_queue.isNotEmpty || _recentClasses.isNotEmpty);
237 } 237 }
238 238
239 /// [_onQueueEmpty] is called whenever the queue is drained. [recentClasses] 239 /// [_onQueueEmpty] is called whenever the queue is drained. [recentClasses]
240 /// contains the set of all classes seen for the first time since 240 /// contains the set of all classes seen for the first time since
241 /// [_onQueueEmpty] was called last. A return value of [true] indicates that 241 /// [_onQueueEmpty] was called last. A return value of [true] indicates that
242 /// the [recentClasses] have been processed and may be cleared. If [false] is 242 /// the [recentClasses] have been processed and may be cleared. If [false] is
243 /// returned, [_onQueueEmpty] will be called once the queue is empty again (or 243 /// returned, [_onQueueEmpty] will be called once the queue is empty again (or
244 /// still empty) and [recentClasses] will be a superset of the current value. 244 /// still empty) and [recentClasses] will be a superset of the current value.
245 bool _onQueueEmpty(Iterable<ClassEntity> recentClasses) { 245 bool _onQueueEmpty(Iterable<ClassEntity> recentClasses) {
246 return _listener.onQueueEmpty(this, recentClasses); 246 return listener.onQueueEmpty(this, recentClasses);
247 } 247 }
248 248
249 void logSummary(log(message)) { 249 void logSummary(log(message)) {
250 log('Compiled ${_processedEntities.length} methods.'); 250 log('Compiled ${_processedEntities.length} methods.');
251 nativeEnqueuer.logSummary(log); 251 nativeEnqueuer.logSummary(log);
252 } 252 }
253 253
254 String toString() => 'Enqueuer($name)'; 254 String toString() => 'Enqueuer($name)';
255 255
256 ImpactUseCase get impactUse => IMPACT_USE; 256 ImpactUseCase get impactUse => IMPACT_USE;
(...skipping 24 matching lines...) Expand all
281 // code for checked setters. 281 // code for checked setters.
282 if (element.isField && element.isInstanceMember) { 282 if (element.isField && element.isInstanceMember) {
283 if (!_options.enableTypeAssertions || 283 if (!_options.enableTypeAssertions ||
284 element.enclosingElement.isClosure) { 284 element.enclosingElement.isClosure) {
285 return null; 285 return null;
286 } 286 }
287 } 287 }
288 return new CodegenWorkItem(_backend, element); 288 return new CodegenWorkItem(_backend, element);
289 } 289 }
290 } 290 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/codegen_listener.dart ('k') | pkg/compiler/lib/src/js_backend/resolution_listener.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698