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

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

Issue 2527973002: Remove direct access to enqueuer through use of WorldImpact (Closed)
Patch Set: Cleanup 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
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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 resolution.forgetElement(element, compiler); 72 resolution.forgetElement(element, compiler);
73 codegen.forgetElement(element, compiler); 73 codegen.forgetElement(element, compiler);
74 } 74 }
75 } 75 }
76 76
77 abstract class Enqueuer { 77 abstract class Enqueuer {
78 CompilerTask get task; 78 CompilerTask get task;
79 WorldBuilder get universe; 79 WorldBuilder get universe;
80 native.NativeEnqueuer get nativeEnqueuer; 80 native.NativeEnqueuer get nativeEnqueuer;
81 void forgetElement(Element element, Compiler compiler); 81 void forgetElement(Element element, Compiler compiler);
82
83 // TODO(johnniwinther): Initialize [_impactStrategy] to `null`.
84 ImpactStrategy _impactStrategy = const ImpactStrategy();
85
86 ImpactStrategy get impactStrategy => _impactStrategy;
87
88 void open(ImpactStrategy impactStrategy) {
89 _impactStrategy = impactStrategy;
90 }
91
92 void close() {
93 // TODO(johnniwinther): Set [_impactStrategy] to `null` and [queueIsClosed]
94 // to `false` here.
Harry Terkelsen 2016/11/28 19:03:06 you mean set [queueIsClosed] to true?
Johnni Winther 2016/11/29 08:01:37 Yes :)
95 _impactStrategy = const ImpactStrategy();
96 }
97
82 void processInstantiatedClassMembers(ClassElement cls); 98 void processInstantiatedClassMembers(ClassElement cls);
83 void processInstantiatedClassMember(ClassElement cls, Element member); 99 void processInstantiatedClassMember(ClassElement cls, Element member);
84 void handleUnseenSelectorInternal(DynamicUse dynamicUse); 100 void handleUnseenSelectorInternal(DynamicUse dynamicUse);
85 void registerStaticUse(StaticUse staticUse); 101 void registerStaticUse(StaticUse staticUse);
86 void registerStaticUseInternal(StaticUse staticUse); 102 void registerStaticUseInternal(StaticUse staticUse);
87 void registerDynamicUse(DynamicUse dynamicUse); 103 void registerDynamicUse(DynamicUse dynamicUse);
88 104
89 /// Returns [:true:] if this enqueuer is the resolution enqueuer. 105 /// Returns [:true:] if this enqueuer is the resolution enqueuer.
90 bool get isResolutionQueue; 106 bool get isResolutionQueue;
91 107
(...skipping 11 matching lines...) Expand all
103 void addToWorkList(Element element); 119 void addToWorkList(Element element);
104 120
105 void enableIsolateSupport(); 121 void enableIsolateSupport();
106 122
107 void registerInstantiatedType(InterfaceType type); 123 void registerInstantiatedType(InterfaceType type);
108 void forEach(void f(WorkItem work)); 124 void forEach(void f(WorkItem work));
109 125
110 /// Apply the [worldImpact] to this enqueuer. If the [impactSource] is provide d 126 /// Apply the [worldImpact] to this enqueuer. If the [impactSource] is provide d
111 /// the impact strategy will remove it from the element impact cache, if it is 127 /// the impact strategy will remove it from the element impact cache, if it is
112 /// no longer needed. 128 /// no longer needed.
113 void applyImpact(ImpactStrategy impactStrategy, WorldImpact worldImpact, 129 void applyImpact(WorldImpact worldImpact, {Element impactSource});
114 {Element impactSource});
115 bool checkNoEnqueuedInvokedInstanceMethods(); 130 bool checkNoEnqueuedInvokedInstanceMethods();
116 void logSummary(log(message)); 131 void logSummary(log(message));
117 132
118 /// Returns [:true:] if [member] has been processed by this enqueuer. 133 /// Returns [:true:] if [member] has been processed by this enqueuer.
119 bool isProcessed(Element member); 134 bool isProcessed(Element member);
120 135
121 Iterable<Entity> get processedEntities; 136 Iterable<Entity> get processedEntities;
122 137
123 Iterable<ClassElement> get processedClasses; 138 Iterable<ClassElement> get processedClasses;
124 } 139 }
(...skipping 16 matching lines...) Expand all
141 final Map<String, Set<Element>> instanceFunctionsByName = 156 final Map<String, Set<Element>> instanceFunctionsByName =
142 new Map<String, Set<Element>>(); 157 new Map<String, Set<Element>>();
143 final Set<ClassElement> _processedClasses = new Set<ClassElement>(); 158 final Set<ClassElement> _processedClasses = new Set<ClassElement>();
144 Set<ClassElement> recentClasses = new Setlet<ClassElement>(); 159 Set<ClassElement> recentClasses = new Setlet<ClassElement>();
145 final ResolutionWorldBuilderImpl _universe; 160 final ResolutionWorldBuilderImpl _universe;
146 161
147 bool queueIsClosed = false; 162 bool queueIsClosed = false;
148 163
149 WorldImpactVisitor impactVisitor; 164 WorldImpactVisitor impactVisitor;
150 165
151 ImpactStrategy impactStrategy;
152
153 ResolutionEnqueuer( 166 ResolutionEnqueuer(
154 this.task, 167 this.task,
155 this.options, 168 this.options,
156 this.resolution, 169 this.resolution,
157 this.filter, 170 this.filter,
158 this.strategy, 171 this.strategy,
159 this.globalDependencies, 172 this.globalDependencies,
160 Backend backend, 173 Backend backend,
161 CommonElements commonElements, 174 CommonElements commonElements,
162 CacheStrategy cacheStrategy, 175 CacheStrategy cacheStrategy,
(...skipping 24 matching lines...) Expand all
187 /** 200 /**
188 * Documentation wanted -- johnniwinther 201 * Documentation wanted -- johnniwinther
189 * 202 *
190 * Invariant: [element] must be a declaration element. 203 * Invariant: [element] must be a declaration element.
191 */ 204 */
192 void addToWorkList(Element element) { 205 void addToWorkList(Element element) {
193 assert(invariant(element, element.isDeclaration)); 206 assert(invariant(element, element.isDeclaration));
194 internalAddToWorkList(element); 207 internalAddToWorkList(element);
195 } 208 }
196 209
197 void applyImpact(ImpactStrategy impactStrategy, WorldImpact worldImpact, 210 void applyImpact(WorldImpact worldImpact, {Element impactSource}) {
198 {Element impactSource}) { 211 if (worldImpact.isEmpty) return;
199 impactStrategy.visitImpact( 212 impactStrategy.visitImpact(
200 impactSource, worldImpact, impactVisitor, impactUse); 213 impactSource, worldImpact, impactVisitor, impactUse);
201 } 214 }
202 215
203 void registerInstantiatedType(InterfaceType type) { 216 void registerInstantiatedType(InterfaceType type) {
204 _registerInstantiatedType(type, globalDependency: true); 217 _registerInstantiatedType(type, globalDependency: true);
205 } 218 }
206 219
207 void _registerInstantiatedType(InterfaceType type, 220 void _registerInstantiatedType(InterfaceType type,
208 {ConstructorElement constructor, 221 {ConstructorElement constructor,
209 bool mirrorUsage: false, 222 bool mirrorUsage: false,
210 bool nativeUsage: false, 223 bool nativeUsage: false,
211 bool globalDependency: false, 224 bool globalDependency: false,
212 bool isRedirection: false}) { 225 bool isRedirection: false}) {
213 task.measure(() { 226 task.measure(() {
214 ClassElement cls = type.element; 227 ClassElement cls = type.element;
215 cls.ensureResolved(resolution); 228 cls.ensureResolved(resolution);
216 bool isNative = backend.isNative(cls); 229 bool isNative = backend.isNative(cls);
217 _universe.registerTypeInstantiation(type, 230 _universe.registerTypeInstantiation(type,
218 constructor: constructor, 231 constructor: constructor,
219 isNative: isNative, 232 isNative: isNative,
220 byMirrors: mirrorUsage, 233 byMirrors: mirrorUsage,
221 isRedirection: isRedirection, onImplemented: (ClassElement cls) { 234 isRedirection: isRedirection, onImplemented: (ClassElement cls) {
222 backend.registerImplementedClass(cls, this); 235 applyImpact(backend.registerImplementedClass(cls, forResolution: true));
223 }); 236 });
224 if (globalDependency && !mirrorUsage) { 237 if (globalDependency && !mirrorUsage) {
225 globalDependencies.registerDependency(type.element); 238 globalDependencies.registerDependency(type.element);
226 } 239 }
227 if (nativeUsage) { 240 if (nativeUsage) {
228 nativeEnqueuer.onInstantiatedType(type); 241 nativeEnqueuer.onInstantiatedType(type);
229 } 242 }
230 backend.registerInstantiatedType(type); 243 backend.registerInstantiatedType(type);
231 // TODO(johnniwinther): Share this reasoning with [Universe]. 244 // TODO(johnniwinther): Share this reasoning with [Universe].
232 if (!cls.isAbstract || isNative || mirrorUsage) { 245 if (!cls.isAbstract || isNative || mirrorUsage) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 addToWorkList(member); 290 addToWorkList(member);
278 return; 291 return;
279 } 292 }
280 } else if (member.isFunction) { 293 } else if (member.isFunction) {
281 FunctionElement function = member; 294 FunctionElement function = member;
282 function.computeType(resolution); 295 function.computeType(resolution);
283 if (function.name == Identifiers.noSuchMethod_) { 296 if (function.name == Identifiers.noSuchMethod_) {
284 registerNoSuchMethod(function); 297 registerNoSuchMethod(function);
285 } 298 }
286 if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) { 299 if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) {
287 registerCallMethodWithFreeTypeVariables(function); 300 _registerCallMethodWithFreeTypeVariables(function);
288 } 301 }
289 // If there is a property access with the same name as a method we 302 // If there is a property access with the same name as a method we
290 // need to emit the method. 303 // need to emit the method.
291 if (_universe.hasInvokedGetter(function, openWorld)) { 304 if (_universe.hasInvokedGetter(function, openWorld)) {
292 registerClosurizedMember(function); 305 registerClosurizedMember(function);
293 addToWorkList(function); 306 addToWorkList(function);
294 return; 307 return;
295 } 308 }
296 // Store the member in [instanceFunctionsByName] to catch 309 // Store the member in [instanceFunctionsByName] to catch
297 // getters on the function. 310 // getters on the function.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 if (_processedClasses.contains(superclass)) return; 355 if (_processedClasses.contains(superclass)) return;
343 356
344 _processedClasses.add(superclass); 357 _processedClasses.add(superclass);
345 recentClasses.add(superclass); 358 recentClasses.add(superclass);
346 superclass.ensureResolved(resolution); 359 superclass.ensureResolved(resolution);
347 superclass.implementation.forEachMember(processInstantiatedClassMember); 360 superclass.implementation.forEachMember(processInstantiatedClassMember);
348 resolution.ensureClassMembers(superclass); 361 resolution.ensureClassMembers(superclass);
349 // We only tell the backend once that [superclass] was instantiated, so 362 // We only tell the backend once that [superclass] was instantiated, so
350 // any additional dependencies must be treated as global 363 // any additional dependencies must be treated as global
351 // dependencies. 364 // dependencies.
352 backend.registerInstantiatedClass(superclass, this); 365 applyImpact(
366 backend.registerInstantiatedClass(superclass, forResolution: true));
353 } 367 }
354 368
355 ClassElement superclass = cls; 369 ClassElement superclass = cls;
356 while (superclass != null) { 370 while (superclass != null) {
357 processClass(superclass); 371 processClass(superclass);
358 superclass = superclass.superclass; 372 superclass = superclass.superclass;
359 } 373 }
360 }); 374 });
361 } 375 }
362 376
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 */ 440 */
427 void registerStaticUse(StaticUse staticUse) { 441 void registerStaticUse(StaticUse staticUse) {
428 strategy.processStaticUse(this, staticUse); 442 strategy.processStaticUse(this, staticUse);
429 } 443 }
430 444
431 void registerStaticUseInternal(StaticUse staticUse) { 445 void registerStaticUseInternal(StaticUse staticUse) {
432 Element element = staticUse.element; 446 Element element = staticUse.element;
433 assert(invariant(element, element.isDeclaration, 447 assert(invariant(element, element.isDeclaration,
434 message: "Element ${element} is not the declaration.")); 448 message: "Element ${element} is not the declaration."));
435 _universe.registerStaticUse(staticUse); 449 _universe.registerStaticUse(staticUse);
436 backend.registerStaticUse(this, element); 450 applyImpact(backend.registerStaticUse(element, forResolution: true));
437 bool addElement = true; 451 bool addElement = true;
438 switch (staticUse.kind) { 452 switch (staticUse.kind) {
439 case StaticUseKind.STATIC_TEAR_OFF: 453 case StaticUseKind.STATIC_TEAR_OFF:
440 backend.registerGetOfStaticFunction(this); 454 applyImpact(backend.registerGetOfStaticFunction());
441 break; 455 break;
442 case StaticUseKind.FIELD_GET: 456 case StaticUseKind.FIELD_GET:
443 case StaticUseKind.FIELD_SET: 457 case StaticUseKind.FIELD_SET:
444 case StaticUseKind.CLOSURE: 458 case StaticUseKind.CLOSURE:
445 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and 459 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and
446 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue. 460 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue.
447 // Also [CLOSURE] contains [LocalFunctionElement] which we cannot 461 // Also [CLOSURE] contains [LocalFunctionElement] which we cannot
448 // enqueue. 462 // enqueue.
449 LocalFunctionElement closure = staticUse.element; 463 LocalFunctionElement closure = staticUse.element;
450 if (closure.type.containsTypeVariables) { 464 if (closure.type.containsTypeVariables) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 } 521 }
508 522
509 void _registerIsCheck(DartType type) { 523 void _registerIsCheck(DartType type) {
510 type = _universe.registerIsCheck(type, resolution); 524 type = _universe.registerIsCheck(type, resolution);
511 // Even in checked mode, type annotations for return type and argument 525 // 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 526 // types do not imply type checks, so there should never be a check
513 // against the type variable of a typedef. 527 // against the type variable of a typedef.
514 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); 528 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef);
515 } 529 }
516 530
517 void registerCallMethodWithFreeTypeVariables(Element element) { 531 void _registerCallMethodWithFreeTypeVariables(Element element) {
518 backend.registerCallMethodWithFreeTypeVariables(element, this); 532 applyImpact(backend.registerCallMethodWithFreeTypeVariables(element,
533 forResolution: true));
519 _universe.callMethodsWithFreeTypeVariables.add(element); 534 _universe.callMethodsWithFreeTypeVariables.add(element);
520 } 535 }
521 536
522 void registerClosurizedMember(TypedElement element) { 537 void registerClosurizedMember(TypedElement element) {
523 assert(element.isInstanceMember); 538 assert(element.isInstanceMember);
524 if (element.computeType(resolution).containsTypeVariables) { 539 if (element.computeType(resolution).containsTypeVariables) {
525 backend.registerClosureWithFreeTypeVariables(element, this); 540 applyImpact(backend.registerClosureWithFreeTypeVariables(element,
541 forResolution: true));
526 _universe.closuresWithFreeTypeVariables.add(element); 542 _universe.closuresWithFreeTypeVariables.add(element);
527 } 543 }
528 backend.registerBoundClosure(this); 544 applyImpact(backend.registerBoundClosure());
529 _universe.closurizedMembers.add(element); 545 _universe.closurizedMembers.add(element);
530 } 546 }
531 547
532 void forEach(void f(WorkItem work)) { 548 void forEach(void f(WorkItem work)) {
533 do { 549 do {
534 while (queue.isNotEmpty) { 550 while (queue.isNotEmpty) {
535 // TODO(johnniwinther): Find an optimal process order. 551 // TODO(johnniwinther): Find an optimal process order.
536 filter.processWorkItem(f, queue.removeLast()); 552 filter.processWorkItem(f, queue.removeLast());
537 } 553 }
538 List recents = recentClasses.toList(growable: false); 554 List recents = recentClasses.toList(growable: false);
(...skipping 79 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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 } 790 }
775 791
776 typedef void _DeferredActionFunction(); 792 typedef void _DeferredActionFunction();
777 793
778 class _DeferredAction { 794 class _DeferredAction {
779 final Element element; 795 final Element element;
780 final _DeferredActionFunction action; 796 final _DeferredActionFunction action;
781 797
782 _DeferredAction(this.element, this.action); 798 _DeferredAction(this.element, this.action);
783 } 799 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698