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

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

Issue 2531303002: Decouple WorkItem from Compiler (Closed)
Patch Set: Updated cf. comments. Created 4 years 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/deferred_load.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 '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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 47
48 String get name => 'Enqueue'; 48 String get name => 'Enqueue';
49 49
50 EnqueueTask(Compiler compiler) 50 EnqueueTask(Compiler compiler)
51 : this.compiler = compiler, 51 : this.compiler = compiler,
52 super(compiler.measurer) { 52 super(compiler.measurer) {
53 _resolution = new ResolutionEnqueuer( 53 _resolution = new ResolutionEnqueuer(
54 this, 54 this,
55 compiler.options, 55 compiler.options,
56 compiler.resolution, 56 compiler.resolution,
57 compiler.enqueuerFilter,
58 compiler.options.analyzeOnly && compiler.options.analyzeMain 57 compiler.options.analyzeOnly && compiler.options.analyzeMain
59 ? const EnqueuerStrategy() 58 ? const DirectEnqueuerStrategy()
60 : const TreeShakingEnqueuerStrategy(), 59 : const TreeShakingEnqueuerStrategy(),
61 compiler.globalDependencies, 60 compiler.globalDependencies,
62 compiler.backend, 61 compiler.backend,
63 compiler.coreClasses, 62 compiler.coreClasses,
64 compiler.cacheStrategy); 63 compiler.cacheStrategy);
65 _codegen = compiler.backend.createCodegenEnqueuer(this, compiler); 64 _codegen = compiler.backend.createCodegenEnqueuer(this, compiler);
66 } 65 }
67 66
68 ResolutionEnqueuer get resolution => _resolution; 67 ResolutionEnqueuer get resolution => _resolution;
69 Enqueuer get codegen => _codegen; 68 Enqueuer get codegen => _codegen;
70 69
71 void forgetElement(Element element) { 70 void forgetElement(Element element) {
72 resolution.forgetElement(element, compiler); 71 resolution.forgetElement(element, compiler);
73 codegen.forgetElement(element, compiler); 72 codegen.forgetElement(element, compiler);
74 } 73 }
75 } 74 }
76 75
77 abstract class Enqueuer { 76 abstract class Enqueuer {
78 CompilerTask get task;
79 WorldBuilder get universe; 77 WorldBuilder get universe;
80 native.NativeEnqueuer get nativeEnqueuer; 78 native.NativeEnqueuer get nativeEnqueuer;
81 void forgetElement(Element element, Compiler compiler); 79 void forgetElement(Element element, Compiler compiler);
82 void processInstantiatedClassMembers(ClassElement cls); 80
83 void processInstantiatedClassMember(ClassElement cls, Element member); 81 // TODO(johnniwinther): Initialize [_impactStrategy] to `null`.
84 void handleUnseenSelectorInternal(DynamicUse dynamicUse); 82 ImpactStrategy _impactStrategy = const ImpactStrategy();
85 void registerStaticUse(StaticUse staticUse); 83
86 void registerStaticUseInternal(StaticUse staticUse); 84 ImpactStrategy get impactStrategy => _impactStrategy;
87 void registerDynamicUse(DynamicUse dynamicUse); 85
86 void open(ImpactStrategy impactStrategy) {
87 _impactStrategy = impactStrategy;
88 }
89
90 void close() {
91 // TODO(johnniwinther): Set [_impactStrategy] to `null` and [queueIsClosed]
92 // to `false` here.
93 _impactStrategy = const ImpactStrategy();
94 }
88 95
89 /// Returns [:true:] if this enqueuer is the resolution enqueuer. 96 /// Returns [:true:] if this enqueuer is the resolution enqueuer.
90 bool get isResolutionQueue; 97 bool get isResolutionQueue;
91 98
92 bool queueIsClosed; 99 bool queueIsClosed;
93 100
94 bool get queueIsEmpty; 101 bool get queueIsEmpty;
95 102
96 ImpactUseCase get impactUse; 103 ImpactUseCase get impactUse;
97 104
98 /**
99 * Documentation wanted -- johnniwinther
100 *
101 * Invariant: [element] must be a declaration element.
102 */
103 void addToWorkList(Element element);
104
105 void enableIsolateSupport();
106
107 void registerInstantiatedType(InterfaceType type);
108 void forEach(void f(WorkItem work)); 105 void forEach(void f(WorkItem work));
109 106
110 /// Apply the [worldImpact] to this enqueuer. If the [impactSource] is provide d 107 /// Apply the [worldImpact] to this enqueuer. If the [impactSource] is
111 /// the impact strategy will remove it from the element impact cache, if it is 108 /// provided the impact strategy will remove it from the element impact cache,
112 /// no longer needed. 109 /// if it is no longer needed.
113 void applyImpact(ImpactStrategy impactStrategy, WorldImpact worldImpact, 110 void applyImpact(WorldImpact worldImpact, {Element impactSource});
114 {Element impactSource});
115 bool checkNoEnqueuedInvokedInstanceMethods(); 111 bool checkNoEnqueuedInvokedInstanceMethods();
116 void logSummary(log(message)); 112 void logSummary(log(message));
117 113
118 /// Returns [:true:] if [member] has been processed by this enqueuer. 114 /// Returns [:true:] if [member] has been processed by this enqueuer.
119 bool isProcessed(Element member); 115 bool isProcessed(Element member);
120 116
121 Iterable<Entity> get processedEntities; 117 Iterable<Entity> get processedEntities;
122 118
123 Iterable<ClassElement> get processedClasses; 119 Iterable<ClassElement> get processedClasses;
124 } 120 }
125 121
122 abstract class EnqueuerImpl extends Enqueuer {
123 CompilerTask get task;
124 void processInstantiatedClassMembers(ClassElement cls);
125 void processInstantiatedClassMember(ClassElement cls, Element member);
126 void registerStaticUse(StaticUse staticUse);
127 void registerStaticUseInternal(StaticUse staticUse);
128 void registerTypeUse(TypeUse typeUse);
129 void registerTypeUseInternal(TypeUse typeUse);
130 void registerDynamicUse(DynamicUse dynamicUse);
131 void handleUnseenSelectorInternal(DynamicUse dynamicUse);
132 }
133
126 /// [Enqueuer] which is specific to resolution. 134 /// [Enqueuer] which is specific to resolution.
127 class ResolutionEnqueuer extends Enqueuer { 135 class ResolutionEnqueuer extends EnqueuerImpl {
128 final CompilerTask task; 136 final CompilerTask task;
129 final String name; 137 final String name;
130 final Resolution resolution; 138 final Resolution resolution;
131 final QueueFilter filter;
132 final CompilerOptions options; 139 final CompilerOptions options;
133 final Backend backend; 140 final Backend backend;
134 final GlobalDependencyRegistry globalDependencies; 141 final GlobalDependencyRegistry globalDependencies;
135 final CommonElements commonElements; 142 final CommonElements commonElements;
136 final native.NativeEnqueuer nativeEnqueuer; 143 final native.NativeEnqueuer nativeEnqueuer;
137 144
138 final EnqueuerStrategy strategy; 145 final EnqueuerStrategy strategy;
139 final Map<String, Set<Element>> instanceMembersByName = 146 final Map<String, Set<Element>> instanceMembersByName =
140 new Map<String, Set<Element>>(); 147 new Map<String, Set<Element>>();
141 final Map<String, Set<Element>> instanceFunctionsByName = 148 final Map<String, Set<Element>> instanceFunctionsByName =
142 new Map<String, Set<Element>>(); 149 new Map<String, Set<Element>>();
143 final Set<ClassElement> _processedClasses = new Set<ClassElement>(); 150 final Set<ClassElement> _processedClasses = new Set<ClassElement>();
144 Set<ClassElement> recentClasses = new Setlet<ClassElement>(); 151 Set<ClassElement> recentClasses = new Setlet<ClassElement>();
145 final ResolutionWorldBuilderImpl _universe; 152 final ResolutionWorldBuilderImpl _universe;
146 153
147 bool queueIsClosed = false; 154 bool queueIsClosed = false;
148 155
149 WorldImpactVisitor impactVisitor; 156 WorldImpactVisitor impactVisitor;
150 157
151 ImpactStrategy impactStrategy;
152
153 ResolutionEnqueuer( 158 ResolutionEnqueuer(
154 this.task, 159 this.task,
155 this.options, 160 this.options,
156 this.resolution, 161 this.resolution,
157 this.filter,
158 this.strategy, 162 this.strategy,
159 this.globalDependencies, 163 this.globalDependencies,
160 Backend backend, 164 Backend backend,
161 CommonElements commonElements, 165 CommonElements commonElements,
162 CacheStrategy cacheStrategy, 166 CacheStrategy cacheStrategy,
163 [this.name = 'resolution enqueuer']) 167 [this.name = 'resolution enqueuer'])
164 : this.backend = backend, 168 : this.backend = backend,
165 this.commonElements = commonElements, 169 this.commonElements = commonElements,
166 this.nativeEnqueuer = backend.nativeResolutionEnqueuer(), 170 this.nativeEnqueuer = backend.nativeResolutionEnqueuer(),
167 processedElements = new Set<AstElement>(), 171 processedElements = new Set<AstElement>(),
168 queue = new Queue<ResolutionWorkItem>(), 172 queue = new Queue<ResolutionWorkItem>(),
169 deferredQueue = new Queue<_DeferredAction>(), 173 deferredQueue = new Queue<_DeferredAction>(),
170 _universe = new ResolutionWorldBuilderImpl( 174 _universe = new ResolutionWorldBuilderImpl(
171 backend, commonElements, cacheStrategy, const TypeMaskStrategy()) { 175 backend, commonElements, cacheStrategy, const TypeMaskStrategy()) {
172 impactVisitor = new _EnqueuerImpactVisitor(this); 176 impactVisitor = new EnqueuerImplImpactVisitor(this);
173 } 177 }
174 178
175 ResolutionWorldBuilder get universe => _universe; 179 ResolutionWorldBuilder get universe => _universe;
176 180
177 OpenWorld get openWorld => universe.openWorld; 181 OpenWorld get openWorld => universe.openWorld;
178 182
179 bool get queueIsEmpty => queue.isEmpty; 183 bool get queueIsEmpty => queue.isEmpty;
180 184
181 DiagnosticReporter get reporter => resolution.reporter; 185 DiagnosticReporter get reporter => resolution.reporter;
182 186
183 bool isClassProcessed(ClassElement cls) => _processedClasses.contains(cls); 187 bool isClassProcessed(ClassElement cls) => _processedClasses.contains(cls);
184 188
185 Iterable<ClassElement> get processedClasses => _processedClasses; 189 Iterable<ClassElement> get processedClasses => _processedClasses;
186 190
187 /** 191 /**
188 * Documentation wanted -- johnniwinther 192 * Documentation wanted -- johnniwinther
189 * 193 *
190 * Invariant: [element] must be a declaration element. 194 * Invariant: [element] must be a declaration element.
191 */ 195 */
192 void addToWorkList(Element element) { 196 void addToWorkList(Element element) {
193 assert(invariant(element, element.isDeclaration)); 197 assert(invariant(element, element.isDeclaration));
194 internalAddToWorkList(element); 198 internalAddToWorkList(element);
195 } 199 }
196 200
197 void applyImpact(ImpactStrategy impactStrategy, WorldImpact worldImpact, 201 void applyImpact(WorldImpact worldImpact, {Element impactSource}) {
198 {Element impactSource}) { 202 if (worldImpact.isEmpty) return;
199 impactStrategy.visitImpact( 203 impactStrategy.visitImpact(
200 impactSource, worldImpact, impactVisitor, impactUse); 204 impactSource, worldImpact, impactVisitor, impactUse);
201 } 205 }
202 206
203 void registerInstantiatedType(InterfaceType type) { 207 void registerInstantiatedType(InterfaceType type) {
204 _registerInstantiatedType(type, globalDependency: true); 208 _registerInstantiatedType(type, globalDependency: true);
205 } 209 }
206 210
207 void _registerInstantiatedType(InterfaceType type, 211 void _registerInstantiatedType(InterfaceType type,
208 {ConstructorElement constructor, 212 {ConstructorElement constructor,
209 bool mirrorUsage: false, 213 bool mirrorUsage: false,
210 bool nativeUsage: false, 214 bool nativeUsage: false,
211 bool globalDependency: false, 215 bool globalDependency: false,
212 bool isRedirection: false}) { 216 bool isRedirection: false}) {
213 task.measure(() { 217 task.measure(() {
214 ClassElement cls = type.element; 218 ClassElement cls = type.element;
215 cls.ensureResolved(resolution); 219 cls.ensureResolved(resolution);
216 bool isNative = backend.isNative(cls); 220 bool isNative = backend.isNative(cls);
217 _universe.registerTypeInstantiation(type, 221 _universe.registerTypeInstantiation(type,
218 constructor: constructor, 222 constructor: constructor,
219 isNative: isNative, 223 isNative: isNative,
220 byMirrors: mirrorUsage, 224 byMirrors: mirrorUsage,
221 isRedirection: isRedirection, onImplemented: (ClassElement cls) { 225 isRedirection: isRedirection, onImplemented: (ClassElement cls) {
222 backend.registerImplementedClass(cls, this); 226 applyImpact(backend.registerImplementedClass(cls, forResolution: true));
223 }); 227 });
224 if (globalDependency && !mirrorUsage) { 228 if (globalDependency && !mirrorUsage) {
225 globalDependencies.registerDependency(type.element); 229 globalDependencies.registerDependency(type.element);
226 } 230 }
227 if (nativeUsage) { 231 if (nativeUsage) {
228 nativeEnqueuer.onInstantiatedType(type); 232 nativeEnqueuer.onInstantiatedType(type);
229 } 233 }
230 backend.registerInstantiatedType(type); 234 backend.registerInstantiatedType(type);
231 // TODO(johnniwinther): Share this reasoning with [Universe]. 235 // TODO(johnniwinther): Share this reasoning with [Universe].
232 if (!cls.isAbstract || isNative || mirrorUsage) { 236 if (!cls.isAbstract || isNative || mirrorUsage) {
233 processInstantiatedClass(cls); 237 processInstantiatedClass(cls);
234 } 238 }
235 }); 239 });
236 } 240 }
237 241
238 bool checkNoEnqueuedInvokedInstanceMethods() { 242 bool checkNoEnqueuedInvokedInstanceMethods() {
239 return filter.checkNoEnqueuedInvokedInstanceMethods(this); 243 return strategy.checkEnqueuerConsistency(this);
240 } 244 }
241 245
242 void processInstantiatedClassMembers(ClassElement cls) { 246 void processInstantiatedClassMembers(ClassElement cls) {
243 strategy.processInstantiatedClass(this, cls); 247 strategy.processInstantiatedClass(this, cls);
244 } 248 }
245 249
246 void processInstantiatedClassMember(ClassElement cls, Element member) { 250 void processInstantiatedClassMember(ClassElement cls, Element member) {
247 assert(invariant(member, member.isDeclaration)); 251 assert(invariant(member, member.isDeclaration));
248 if (isProcessed(member)) return; 252 if (isProcessed(member)) return;
249 if (!member.isInstanceMember) return; 253 if (!member.isInstanceMember) return;
(...skipping 27 matching lines...) Expand all
277 addToWorkList(member); 281 addToWorkList(member);
278 return; 282 return;
279 } 283 }
280 } else if (member.isFunction) { 284 } else if (member.isFunction) {
281 FunctionElement function = member; 285 FunctionElement function = member;
282 function.computeType(resolution); 286 function.computeType(resolution);
283 if (function.name == Identifiers.noSuchMethod_) { 287 if (function.name == Identifiers.noSuchMethod_) {
284 registerNoSuchMethod(function); 288 registerNoSuchMethod(function);
285 } 289 }
286 if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) { 290 if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) {
287 registerCallMethodWithFreeTypeVariables(function); 291 _registerCallMethodWithFreeTypeVariables(function);
288 } 292 }
289 // If there is a property access with the same name as a method we 293 // If there is a property access with the same name as a method we
290 // need to emit the method. 294 // need to emit the method.
291 if (_universe.hasInvokedGetter(function, openWorld)) { 295 if (_universe.hasInvokedGetter(function, openWorld)) {
292 registerClosurizedMember(function); 296 registerClosurizedMember(function);
293 addToWorkList(function); 297 addToWorkList(function);
294 return; 298 return;
295 } 299 }
296 // Store the member in [instanceFunctionsByName] to catch 300 // Store the member in [instanceFunctionsByName] to catch
297 // getters on the function. 301 // getters on the function.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 if (_processedClasses.contains(superclass)) return; 346 if (_processedClasses.contains(superclass)) return;
343 347
344 _processedClasses.add(superclass); 348 _processedClasses.add(superclass);
345 recentClasses.add(superclass); 349 recentClasses.add(superclass);
346 superclass.ensureResolved(resolution); 350 superclass.ensureResolved(resolution);
347 superclass.implementation.forEachMember(processInstantiatedClassMember); 351 superclass.implementation.forEachMember(processInstantiatedClassMember);
348 resolution.ensureClassMembers(superclass); 352 resolution.ensureClassMembers(superclass);
349 // We only tell the backend once that [superclass] was instantiated, so 353 // We only tell the backend once that [superclass] was instantiated, so
350 // any additional dependencies must be treated as global 354 // any additional dependencies must be treated as global
351 // dependencies. 355 // dependencies.
352 backend.registerInstantiatedClass(superclass, this); 356 applyImpact(
357 backend.registerInstantiatedClass(superclass, forResolution: true));
353 } 358 }
354 359
355 ClassElement superclass = cls; 360 ClassElement superclass = cls;
356 while (superclass != null) { 361 while (superclass != null) {
357 processClass(superclass); 362 processClass(superclass);
358 superclass = superclass.superclass; 363 superclass = superclass.superclass;
359 } 364 }
360 }); 365 });
361 } 366 }
362 367
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 */ 431 */
427 void registerStaticUse(StaticUse staticUse) { 432 void registerStaticUse(StaticUse staticUse) {
428 strategy.processStaticUse(this, staticUse); 433 strategy.processStaticUse(this, staticUse);
429 } 434 }
430 435
431 void registerStaticUseInternal(StaticUse staticUse) { 436 void registerStaticUseInternal(StaticUse staticUse) {
432 Element element = staticUse.element; 437 Element element = staticUse.element;
433 assert(invariant(element, element.isDeclaration, 438 assert(invariant(element, element.isDeclaration,
434 message: "Element ${element} is not the declaration.")); 439 message: "Element ${element} is not the declaration."));
435 _universe.registerStaticUse(staticUse); 440 _universe.registerStaticUse(staticUse);
436 backend.registerStaticUse(this, element); 441 applyImpact(backend.registerStaticUse(element, forResolution: true));
437 bool addElement = true; 442 bool addElement = true;
438 switch (staticUse.kind) { 443 switch (staticUse.kind) {
439 case StaticUseKind.STATIC_TEAR_OFF: 444 case StaticUseKind.STATIC_TEAR_OFF:
440 backend.registerGetOfStaticFunction(this); 445 applyImpact(backend.registerGetOfStaticFunction());
441 break; 446 break;
442 case StaticUseKind.FIELD_GET: 447 case StaticUseKind.FIELD_GET:
443 case StaticUseKind.FIELD_SET: 448 case StaticUseKind.FIELD_SET:
444 case StaticUseKind.CLOSURE: 449 case StaticUseKind.CLOSURE:
445 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and 450 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and
446 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue. 451 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue.
447 // Also [CLOSURE] contains [LocalFunctionElement] which we cannot 452 // Also [CLOSURE] contains [LocalFunctionElement] which we cannot
448 // enqueue. 453 // enqueue.
449 LocalFunctionElement closure = staticUse.element; 454 LocalFunctionElement closure = staticUse.element;
450 if (closure.type.containsTypeVariables) { 455 if (closure.type.containsTypeVariables) {
451 universe.closuresWithFreeTypeVariables.add(closure); 456 universe.closuresWithFreeTypeVariables.add(closure);
452 } 457 }
453 addElement = false; 458 addElement = false;
454 break; 459 break;
455 case StaticUseKind.SUPER_FIELD_SET: 460 case StaticUseKind.SUPER_FIELD_SET:
456 case StaticUseKind.SUPER_TEAR_OFF: 461 case StaticUseKind.SUPER_TEAR_OFF:
457 case StaticUseKind.GENERAL: 462 case StaticUseKind.GENERAL:
463 case StaticUseKind.DIRECT_USE:
458 break; 464 break;
459 case StaticUseKind.CONSTRUCTOR_INVOKE: 465 case StaticUseKind.CONSTRUCTOR_INVOKE:
460 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: 466 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
461 _registerInstantiatedType(staticUse.type, 467 _registerInstantiatedType(staticUse.type,
462 constructor: staticUse.element, globalDependency: false); 468 constructor: staticUse.element, globalDependency: false);
463 break; 469 break;
464 case StaticUseKind.REDIRECTION: 470 case StaticUseKind.REDIRECTION:
465 _registerInstantiatedType(staticUse.type, 471 _registerInstantiatedType(staticUse.type,
466 constructor: staticUse.element, 472 constructor: staticUse.element,
467 globalDependency: false, 473 globalDependency: false,
468 isRedirection: true); 474 isRedirection: true);
469 break; 475 break;
470 case StaticUseKind.DIRECT_INVOKE: 476 case StaticUseKind.DIRECT_INVOKE:
471 invariant( 477 invariant(
472 element, 'Direct static use is not supported for resolution.'); 478 element, 'Direct static use is not supported for resolution.');
473 break; 479 break;
474 } 480 }
475 if (addElement) { 481 if (addElement) {
476 addToWorkList(element); 482 addToWorkList(element);
477 } 483 }
478 } 484 }
479 485
480 void _registerTypeUse(TypeUse typeUse) { 486 void registerTypeUse(TypeUse typeUse) {
487 strategy.processTypeUse(this, typeUse);
488 }
489
490 void registerTypeUseInternal(TypeUse typeUse) {
481 DartType type = typeUse.type; 491 DartType type = typeUse.type;
482 switch (typeUse.kind) { 492 switch (typeUse.kind) {
483 case TypeUseKind.INSTANTIATION: 493 case TypeUseKind.INSTANTIATION:
484 _registerInstantiatedType(type, globalDependency: false); 494 _registerInstantiatedType(type, globalDependency: false);
485 break; 495 break;
486 case TypeUseKind.MIRROR_INSTANTIATION: 496 case TypeUseKind.MIRROR_INSTANTIATION:
487 _registerInstantiatedType(type, 497 _registerInstantiatedType(type,
488 mirrorUsage: true, globalDependency: false); 498 mirrorUsage: true, globalDependency: false);
489 break; 499 break;
490 case TypeUseKind.NATIVE_INSTANTIATION: 500 case TypeUseKind.NATIVE_INSTANTIATION:
(...skipping 16 matching lines...) Expand all
507 } 517 }
508 518
509 void _registerIsCheck(DartType type) { 519 void _registerIsCheck(DartType type) {
510 type = _universe.registerIsCheck(type, resolution); 520 type = _universe.registerIsCheck(type, resolution);
511 // Even in checked mode, type annotations for return type and argument 521 // Even in checked mode, type annotations for return type and argument
512 // types do not imply type checks, so there should never be a check 522 // types do not imply type checks, so there should never be a check
513 // against the type variable of a typedef. 523 // against the type variable of a typedef.
514 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); 524 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef);
515 } 525 }
516 526
517 void registerCallMethodWithFreeTypeVariables(Element element) { 527 void _registerCallMethodWithFreeTypeVariables(Element element) {
518 backend.registerCallMethodWithFreeTypeVariables(element, this); 528 applyImpact(backend.registerCallMethodWithFreeTypeVariables(element,
529 forResolution: true));
519 _universe.callMethodsWithFreeTypeVariables.add(element); 530 _universe.callMethodsWithFreeTypeVariables.add(element);
520 } 531 }
521 532
522 void registerClosurizedMember(TypedElement element) { 533 void registerClosurizedMember(TypedElement element) {
523 assert(element.isInstanceMember); 534 assert(element.isInstanceMember);
524 if (element.computeType(resolution).containsTypeVariables) { 535 if (element.computeType(resolution).containsTypeVariables) {
525 backend.registerClosureWithFreeTypeVariables(element, this); 536 applyImpact(backend.registerClosureWithFreeTypeVariables(element,
537 forResolution: true));
526 _universe.closuresWithFreeTypeVariables.add(element); 538 _universe.closuresWithFreeTypeVariables.add(element);
527 } 539 }
528 backend.registerBoundClosure(this); 540 applyImpact(backend.registerBoundClosure());
529 _universe.closurizedMembers.add(element); 541 _universe.closurizedMembers.add(element);
530 } 542 }
531 543
532 void forEach(void f(WorkItem work)) { 544 void forEach(void f(WorkItem work)) {
533 do { 545 do {
534 while (queue.isNotEmpty) { 546 while (queue.isNotEmpty) {
535 // TODO(johnniwinther): Find an optimal process order. 547 // TODO(johnniwinther): Find an optimal process order.
536 filter.processWorkItem(f, queue.removeLast()); 548 WorkItem work = queue.removeLast();
549 if (!isProcessed(work.element)) {
550 strategy.processWorkItem(f, work);
551 registerProcessedElement(work.element);
552 }
537 } 553 }
538 List recents = recentClasses.toList(growable: false); 554 List recents = recentClasses.toList(growable: false);
539 recentClasses.clear(); 555 recentClasses.clear();
540 if (!onQueueEmpty(recents)) recentClasses.addAll(recents); 556 if (!onQueueEmpty(recents)) recentClasses.addAll(recents);
541 } while (queue.isNotEmpty || recentClasses.isNotEmpty); 557 } while (queue.isNotEmpty || recentClasses.isNotEmpty);
542 } 558 }
543 559
544 void logSummary(log(message)) { 560 void logSummary(log(message)) {
545 log('Resolved ${processedElements.length} elements.'); 561 log('Resolved ${processedElements.length} elements.');
546 nativeEnqueuer.logSummary(log); 562 nativeEnqueuer.logSummary(log);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 } 634 }
619 } 635 }
620 636
621 if (element.isGetter && element.name == Identifiers.runtimeType_) { 637 if (element.isGetter && element.name == Identifiers.runtimeType_) {
622 // Enable runtime type support if we discover a getter called runtimeType. 638 // Enable runtime type support if we discover a getter called runtimeType.
623 // We have to enable runtime type before hitting the codegen, so 639 // We have to enable runtime type before hitting the codegen, so
624 // that constructors know whether they need to generate code for 640 // that constructors know whether they need to generate code for
625 // runtime type. 641 // runtime type.
626 _universe.hasRuntimeTypeSupport = true; 642 _universe.hasRuntimeTypeSupport = true;
627 // TODO(ahe): Record precise dependency here. 643 // TODO(ahe): Record precise dependency here.
628 backend.registerRuntimeType(this); 644 applyImpact(backend.registerRuntimeType());
629 } else if (commonElements.isFunctionApplyMethod(element)) { 645 } else if (commonElements.isFunctionApplyMethod(element)) {
630 _universe.hasFunctionApplySupport = true; 646 _universe.hasFunctionApplySupport = true;
631 } 647 }
632 648
633 return true; 649 return true;
634 } 650 }
635 651
636 void registerNoSuchMethod(Element element) { 652 void registerNoSuchMethod(Element element) {
637 backend.registerNoSuchMethod(element); 653 backend.registerNoSuchMethod(element);
638 } 654 }
639 655
640 void enableIsolateSupport() { 656 void enableIsolateSupport() {
641 _universe.hasIsolateSupport = true; 657 _universe.hasIsolateSupport = true;
642 backend.enableIsolateSupport(this); 658 applyImpact(backend.enableIsolateSupport(forResolution: true));
643 } 659 }
644 660
645 /** 661 /**
646 * Adds an action to the deferred task queue. 662 * Adds an action to the deferred task queue.
647 * 663 *
648 * The action is performed the next time the resolution queue has been 664 * The action is performed the next time the resolution queue has been
649 * emptied. 665 * emptied.
650 * 666 *
651 * The queue is processed in FIFO order. 667 * The queue is processed in FIFO order.
652 */ 668 */
(...skipping 30 matching lines...) Expand all
683 699
684 void forgetElement(Element element, Compiler compiler) { 700 void forgetElement(Element element, Compiler compiler) {
685 _universe.forgetElement(element, compiler); 701 _universe.forgetElement(element, compiler);
686 _processedClasses.remove(element); 702 _processedClasses.remove(element);
687 instanceMembersByName[element.name]?.remove(element); 703 instanceMembersByName[element.name]?.remove(element);
688 instanceFunctionsByName[element.name]?.remove(element); 704 instanceFunctionsByName[element.name]?.remove(element);
689 processedElements.remove(element); 705 processedElements.remove(element);
690 } 706 }
691 } 707 }
692 708
693 /// Parameterizes filtering of which work items are enqueued. 709 void removeFromSet(Map<String, Set<Element>> map, Element element) {
694 class QueueFilter { 710 Set<Element> set = map[element.name];
695 bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) { 711 if (set == null) return;
712 set.remove(element);
713 }
714
715 /// Strategy used by the enqueuer to populate the world.
716 class EnqueuerStrategy {
717 const EnqueuerStrategy();
718
719 /// Process a class instantiated in live code.
720 void processInstantiatedClass(EnqueuerImpl enqueuer, ClassElement cls) {}
721
722 /// Process a static use of and element in live code.
723 void processStaticUse(EnqueuerImpl enqueuer, StaticUse staticUse) {}
724
725 /// Process a type use in live code.
726 void processTypeUse(EnqueuerImpl enqueuer, TypeUse typeUse) {}
727
728 /// Process a dynamic use for a call site in live code.
729 void processDynamicUse(EnqueuerImpl enqueuer, DynamicUse dynamicUse) {}
730
731 /// Check enqueuer consistency after the queue has been closed.
732 bool checkEnqueuerConsistency(EnqueuerImpl enqueuer) {
696 enqueuer.task.measure(() { 733 enqueuer.task.measure(() {
697 // Run through the classes and see if we need to compile methods. 734 // Run through the classes and see if we need to enqueue more methods.
698 for (ClassElement classElement 735 for (ClassElement classElement
699 in enqueuer.universe.directlyInstantiatedClasses) { 736 in enqueuer.universe.directlyInstantiatedClasses) {
700 for (ClassElement currentClass = classElement; 737 for (ClassElement currentClass = classElement;
701 currentClass != null; 738 currentClass != null;
702 currentClass = currentClass.superclass) { 739 currentClass = currentClass.superclass) {
703 enqueuer.processInstantiatedClassMembers(currentClass); 740 enqueuer.processInstantiatedClassMembers(currentClass);
704 } 741 }
705 } 742 }
706 }); 743 });
707 return true; 744 return true;
708 } 745 }
709 746
747 /// Process [work] using [f].
710 void processWorkItem(void f(WorkItem work), WorkItem work) { 748 void processWorkItem(void f(WorkItem work), WorkItem work) {
711 f(work); 749 f(work);
712 } 750 }
713 } 751 }
714 752
715 void removeFromSet(Map<String, Set<Element>> map, Element element) { 753 /// Strategy that only enqueues directly used elements.
716 Set<Element> set = map[element.name]; 754 class DirectEnqueuerStrategy extends EnqueuerStrategy {
717 if (set == null) return; 755 const DirectEnqueuerStrategy();
718 set.remove(element); 756 void processStaticUse(EnqueuerImpl enqueuer, StaticUse staticUse) {
757 if (staticUse.kind == StaticUseKind.DIRECT_USE) {
758 enqueuer.registerStaticUseInternal(staticUse);
759 }
760 }
719 } 761 }
720 762
721 /// Strategy used by the enqueuer to populate the world. 763 /// Strategy used for tree-shaking.
722 // TODO(johnniwinther): Merge this interface with [QueueFilter]. 764 class TreeShakingEnqueuerStrategy extends EnqueuerStrategy {
723 class EnqueuerStrategy {
724 const EnqueuerStrategy();
725
726 /// Process a class instantiated in live code.
727 void processInstantiatedClass(Enqueuer enqueuer, ClassElement cls) {}
728
729 /// Process a static use of and element in live code.
730 void processStaticUse(Enqueuer enqueuer, StaticUse staticUse) {}
731
732 /// Process a dynamic use for a call site in live code.
733 void processDynamicUse(Enqueuer enqueuer, DynamicUse dynamicUse) {}
734 }
735
736 class TreeShakingEnqueuerStrategy implements EnqueuerStrategy {
737 const TreeShakingEnqueuerStrategy(); 765 const TreeShakingEnqueuerStrategy();
738 766
739 @override 767 @override
740 void processInstantiatedClass(Enqueuer enqueuer, ClassElement cls) { 768 void processInstantiatedClass(EnqueuerImpl enqueuer, ClassElement cls) {
741 cls.implementation.forEachMember(enqueuer.processInstantiatedClassMember); 769 cls.implementation.forEachMember(enqueuer.processInstantiatedClassMember);
742 } 770 }
743 771
744 @override 772 @override
745 void processStaticUse(Enqueuer enqueuer, StaticUse staticUse) { 773 void processStaticUse(EnqueuerImpl enqueuer, StaticUse staticUse) {
746 enqueuer.registerStaticUseInternal(staticUse); 774 enqueuer.registerStaticUseInternal(staticUse);
747 } 775 }
748 776
749 @override 777 @override
750 void processDynamicUse(Enqueuer enqueuer, DynamicUse dynamicUse) { 778 void processTypeUse(EnqueuerImpl enqueuer, TypeUse typeUse) {
779 enqueuer.registerTypeUseInternal(typeUse);
780 }
781
782 @override
783 void processDynamicUse(EnqueuerImpl enqueuer, DynamicUse dynamicUse) {
751 enqueuer.handleUnseenSelectorInternal(dynamicUse); 784 enqueuer.handleUnseenSelectorInternal(dynamicUse);
752 } 785 }
753 } 786 }
754 787
755 class _EnqueuerImpactVisitor implements WorldImpactVisitor { 788 class EnqueuerImplImpactVisitor implements WorldImpactVisitor {
756 final ResolutionEnqueuer enqueuer; 789 final EnqueuerImpl enqueuer;
757 790
758 _EnqueuerImpactVisitor(this.enqueuer); 791 EnqueuerImplImpactVisitor(this.enqueuer);
759 792
760 @override 793 @override
761 void visitDynamicUse(DynamicUse dynamicUse) { 794 void visitDynamicUse(DynamicUse dynamicUse) {
762 enqueuer.registerDynamicUse(dynamicUse); 795 enqueuer.registerDynamicUse(dynamicUse);
763 } 796 }
764 797
765 @override 798 @override
766 void visitStaticUse(StaticUse staticUse) { 799 void visitStaticUse(StaticUse staticUse) {
767 enqueuer.registerStaticUse(staticUse); 800 enqueuer.registerStaticUse(staticUse);
768 } 801 }
769 802
770 @override 803 @override
771 void visitTypeUse(TypeUse typeUse) { 804 void visitTypeUse(TypeUse typeUse) {
772 enqueuer._registerTypeUse(typeUse); 805 enqueuer.registerTypeUse(typeUse);
773 } 806 }
774 } 807 }
775 808
776 typedef void _DeferredActionFunction(); 809 typedef void _DeferredActionFunction();
777 810
778 class _DeferredAction { 811 class _DeferredAction {
779 final Element element; 812 final Element element;
780 final _DeferredActionFunction action; 813 final _DeferredActionFunction action;
781 814
782 _DeferredAction(this.element, this.action); 815 _DeferredAction(this.element, this.action);
783 } 816 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/deferred_load.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