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

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

Issue 2318593003: Split Universe into ResolutionUniverse and CodegenUniverse (Closed)
Patch Set: Updated cf. comments. Created 4 years, 2 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/backend_api.dart' show Backend; 9 import '../common/backend_api.dart' show Backend;
10 import '../common/codegen.dart' show CodegenWorkItem; 10 import '../common/codegen.dart' show CodegenWorkItem;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 final String name; 47 final String name;
48 @deprecated 48 @deprecated
49 final Compiler _compiler; // TODO(ahe): Remove this dependency. 49 final Compiler _compiler; // TODO(ahe): Remove this dependency.
50 final EnqueuerStrategy strategy; 50 final EnqueuerStrategy strategy;
51 final Map<String, Set<Element>> instanceMembersByName = 51 final Map<String, Set<Element>> instanceMembersByName =
52 new Map<String, Set<Element>>(); 52 new Map<String, Set<Element>>();
53 final Map<String, Set<Element>> instanceFunctionsByName = 53 final Map<String, Set<Element>> instanceFunctionsByName =
54 new Map<String, Set<Element>>(); 54 new Map<String, Set<Element>>();
55 final Set<ClassElement> _processedClasses = new Set<ClassElement>(); 55 final Set<ClassElement> _processedClasses = new Set<ClassElement>();
56 Set<ClassElement> recentClasses = new Setlet<ClassElement>(); 56 Set<ClassElement> recentClasses = new Setlet<ClassElement>();
57 final Universe universe = new Universe(const TypeMaskStrategy()); 57 final CodegenUniverseImpl _universe =
58 new CodegenUniverseImpl(const TypeMaskStrategy());
58 59
59 static final TRACE_MIRROR_ENQUEUING = 60 static final TRACE_MIRROR_ENQUEUING =
60 const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING"); 61 const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING");
61 62
62 bool queueIsClosed = false; 63 bool queueIsClosed = false;
63 EnqueueTask task; 64 EnqueueTask task;
64 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask 65 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask
65 66
66 bool hasEnqueuedReflectiveElements = false; 67 bool hasEnqueuedReflectiveElements = false;
67 bool hasEnqueuedReflectiveStaticFields = false; 68 bool hasEnqueuedReflectiveStaticFields = false;
68 69
69 WorldImpactVisitor impactVisitor; 70 WorldImpactVisitor impactVisitor;
70 71
71 CodegenEnqueuer(Compiler compiler, this.strategy) 72 CodegenEnqueuer(Compiler compiler, this.strategy)
72 : queue = new Queue<CodegenWorkItem>(), 73 : queue = new Queue<CodegenWorkItem>(),
73 newlyEnqueuedElements = compiler.cacheStrategy.newSet(), 74 newlyEnqueuedElements = compiler.cacheStrategy.newSet(),
74 newlySeenSelectors = compiler.cacheStrategy.newSet(), 75 newlySeenSelectors = compiler.cacheStrategy.newSet(),
75 this.name = 'codegen enqueuer', 76 this.name = 'codegen enqueuer',
76 this._compiler = compiler { 77 this._compiler = compiler {
77 impactVisitor = new _EnqueuerImpactVisitor(this); 78 impactVisitor = new _EnqueuerImpactVisitor(this);
78 } 79 }
79 80
81 CodegenUniverse get universe => _universe;
82
80 Backend get backend => _compiler.backend; 83 Backend get backend => _compiler.backend;
81 84
82 CompilerOptions get options => _compiler.options; 85 CompilerOptions get options => _compiler.options;
83 86
84 Registry get globalDependencies => _compiler.globalDependencies; 87 Registry get globalDependencies => _compiler.globalDependencies;
85 88
86 Registry get mirrorDependencies => _compiler.mirrorDependencies; 89 Registry get mirrorDependencies => _compiler.mirrorDependencies;
87 90
88 ClassWorld get _world => _compiler.closedWorld; 91 ClassWorld get _world => _compiler.closedWorld;
89 92
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 /// Apply the [worldImpact] of processing [element] to this enqueuer. 137 /// Apply the [worldImpact] of processing [element] to this enqueuer.
135 void applyImpact(Element element, WorldImpact worldImpact) { 138 void applyImpact(Element element, WorldImpact worldImpact) {
136 _compiler.impactStrategy 139 _compiler.impactStrategy
137 .visitImpact(element, worldImpact, impactVisitor, impactUse); 140 .visitImpact(element, worldImpact, impactVisitor, impactUse);
138 } 141 }
139 142
140 void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}) { 143 void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}) {
141 task.measure(() { 144 task.measure(() {
142 ClassElement cls = type.element; 145 ClassElement cls = type.element;
143 bool isNative = backend.isNative(cls); 146 bool isNative = backend.isNative(cls);
144 universe.registerTypeInstantiation(type, 147 _universe.registerTypeInstantiation(type,
145 isNative: isNative, 148 isNative: isNative,
146 byMirrors: mirrorUsage, onImplemented: (ClassElement cls) { 149 byMirrors: mirrorUsage, onImplemented: (ClassElement cls) {
147 backend.registerImplementedClass(cls, this, globalDependencies); 150 backend.registerImplementedClass(cls, this, globalDependencies);
148 }); 151 });
149 // TODO(johnniwinther): Share this reasoning with [Universe]. 152 // TODO(johnniwinther): Share this reasoning with [Universe].
150 if (!cls.isAbstract || isNative || mirrorUsage) { 153 if (!cls.isAbstract || isNative || mirrorUsage) {
151 processInstantiatedClass(cls); 154 processInstantiatedClass(cls);
152 } 155 }
153 }); 156 });
154 } 157 }
(...skipping 14 matching lines...) Expand all
169 172
170 if (member.isField) { 173 if (member.isField) {
171 // The obvious thing to test here would be "member.isNative", 174 // The obvious thing to test here would be "member.isNative",
172 // however, that only works after metadata has been parsed/analyzed, 175 // however, that only works after metadata has been parsed/analyzed,
173 // and that may not have happened yet. 176 // and that may not have happened yet.
174 // So instead we use the enclosing class, which we know have had 177 // So instead we use the enclosing class, which we know have had
175 // its metadata parsed and analyzed. 178 // its metadata parsed and analyzed.
176 // Note: this assumes that there are no non-native fields on native 179 // Note: this assumes that there are no non-native fields on native
177 // classes, which may not be the case when a native class is subclassed. 180 // classes, which may not be the case when a native class is subclassed.
178 if (backend.isNative(cls)) { 181 if (backend.isNative(cls)) {
179 if (universe.hasInvokedGetter(member, _world) || 182 if (_universe.hasInvokedGetter(member, _world) ||
180 universe.hasInvocation(member, _world)) { 183 _universe.hasInvocation(member, _world)) {
181 addToWorkList(member); 184 addToWorkList(member);
182 return; 185 return;
183 } else if (universe.hasInvokedSetter(member, _world)) { 186 } else if (universe.hasInvokedSetter(member, _world)) {
184 addToWorkList(member); 187 addToWorkList(member);
185 return; 188 return;
186 } 189 }
187 // Native fields need to go into instanceMembersByName as they 190 // Native fields need to go into instanceMembersByName as they
188 // are virtual instantiation points and escape points. 191 // are virtual instantiation points and escape points.
189 } else { 192 } else {
190 // All field initializers must be resolved as they could 193 // All field initializers must be resolved as they could
191 // have an observable side-effect (and cannot be tree-shaken 194 // have an observable side-effect (and cannot be tree-shaken
192 // away). 195 // away).
193 addToWorkList(member); 196 addToWorkList(member);
194 return; 197 return;
195 } 198 }
196 } else if (member.isFunction) { 199 } else if (member.isFunction) {
197 FunctionElement function = member; 200 FunctionElement function = member;
198 if (function.name == Identifiers.noSuchMethod_) { 201 if (function.name == Identifiers.noSuchMethod_) {
199 registerNoSuchMethod(function); 202 registerNoSuchMethod(function);
200 } 203 }
201 if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) { 204 if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) {
202 registerCallMethodWithFreeTypeVariables(function); 205 registerCallMethodWithFreeTypeVariables(function);
203 } 206 }
204 // If there is a property access with the same name as a method we 207 // If there is a property access with the same name as a method we
205 // need to emit the method. 208 // need to emit the method.
206 if (universe.hasInvokedGetter(function, _world)) { 209 if (_universe.hasInvokedGetter(function, _world)) {
207 registerClosurizedMember(function); 210 registerClosurizedMember(function);
208 addToWorkList(function); 211 addToWorkList(function);
209 return; 212 return;
210 } 213 }
211 // Store the member in [instanceFunctionsByName] to catch 214 // Store the member in [instanceFunctionsByName] to catch
212 // getters on the function. 215 // getters on the function.
213 instanceFunctionsByName 216 instanceFunctionsByName
214 .putIfAbsent(memberName, () => new Set<Element>()) 217 .putIfAbsent(memberName, () => new Set<Element>())
215 .add(member); 218 .add(member);
216 if (universe.hasInvocation(function, _world)) { 219 if (_universe.hasInvocation(function, _world)) {
217 addToWorkList(function); 220 addToWorkList(function);
218 return; 221 return;
219 } 222 }
220 } else if (member.isGetter) { 223 } else if (member.isGetter) {
221 FunctionElement getter = member; 224 FunctionElement getter = member;
222 if (universe.hasInvokedGetter(getter, _world)) { 225 if (_universe.hasInvokedGetter(getter, _world)) {
223 addToWorkList(getter); 226 addToWorkList(getter);
224 return; 227 return;
225 } 228 }
226 // We don't know what selectors the returned closure accepts. If 229 // We don't know what selectors the returned closure accepts. If
227 // the set contains any selector we have to assume that it matches. 230 // the set contains any selector we have to assume that it matches.
228 if (universe.hasInvocation(getter, _world)) { 231 if (_universe.hasInvocation(getter, _world)) {
229 addToWorkList(getter); 232 addToWorkList(getter);
230 return; 233 return;
231 } 234 }
232 } else if (member.isSetter) { 235 } else if (member.isSetter) {
233 FunctionElement setter = member; 236 FunctionElement setter = member;
234 if (universe.hasInvokedSetter(setter, _world)) { 237 if (_universe.hasInvokedSetter(setter, _world)) {
235 addToWorkList(setter); 238 addToWorkList(setter);
236 return; 239 return;
237 } 240 }
238 } 241 }
239 242
240 // The element is not yet used. Add it to the list of instance 243 // The element is not yet used. Add it to the list of instance
241 // members to still be processed. 244 // members to still be processed.
242 instanceMembersByName 245 instanceMembersByName
243 .putIfAbsent(memberName, () => new Set<Element>()) 246 .putIfAbsent(memberName, () => new Set<Element>())
244 .add(member); 247 .add(member);
(...skipping 28 matching lines...) Expand all
273 ClassElement superclass = cls; 276 ClassElement superclass = cls;
274 while (superclass != null) { 277 while (superclass != null) {
275 processClass(superclass); 278 processClass(superclass);
276 superclass = superclass.superclass; 279 superclass = superclass.superclass;
277 } 280 }
278 }); 281 });
279 } 282 }
280 283
281 void registerDynamicUse(DynamicUse dynamicUse) { 284 void registerDynamicUse(DynamicUse dynamicUse) {
282 task.measure(() { 285 task.measure(() {
283 if (universe.registerDynamicUse(dynamicUse)) { 286 if (_universe.registerDynamicUse(dynamicUse)) {
284 handleUnseenSelector(dynamicUse); 287 handleUnseenSelector(dynamicUse);
285 } 288 }
286 }); 289 });
287 } 290 }
288 291
289 void logEnqueueReflectiveAction(action, [msg = ""]) { 292 void logEnqueueReflectiveAction(action, [msg = ""]) {
290 if (TRACE_MIRROR_ENQUEUING) { 293 if (TRACE_MIRROR_ENQUEUING) {
291 print("MIRROR_ENQUEUE (C): $action $msg"); 294 print("MIRROR_ENQUEUE (C): $action $msg");
292 } 295 }
293 } 296 }
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 * Invariant: [element] must be a declaration element. 505 * Invariant: [element] must be a declaration element.
503 */ 506 */
504 void registerStaticUse(StaticUse staticUse) { 507 void registerStaticUse(StaticUse staticUse) {
505 strategy.processStaticUse(this, staticUse); 508 strategy.processStaticUse(this, staticUse);
506 } 509 }
507 510
508 void registerStaticUseInternal(StaticUse staticUse) { 511 void registerStaticUseInternal(StaticUse staticUse) {
509 Element element = staticUse.element; 512 Element element = staticUse.element;
510 assert(invariant(element, element.isDeclaration, 513 assert(invariant(element, element.isDeclaration,
511 message: "Element ${element} is not the declaration.")); 514 message: "Element ${element} is not the declaration."));
512 universe.registerStaticUse(staticUse); 515 _universe.registerStaticUse(staticUse);
513 backend.registerStaticUse(element, this); 516 backend.registerStaticUse(element, this);
514 bool addElement = true; 517 bool addElement = true;
515 switch (staticUse.kind) { 518 switch (staticUse.kind) {
516 case StaticUseKind.STATIC_TEAR_OFF: 519 case StaticUseKind.STATIC_TEAR_OFF:
517 backend.registerGetOfStaticFunction(this); 520 backend.registerGetOfStaticFunction(this);
518 break; 521 break;
519 case StaticUseKind.FIELD_GET: 522 case StaticUseKind.FIELD_GET:
520 case StaticUseKind.FIELD_SET: 523 case StaticUseKind.FIELD_SET:
521 case StaticUseKind.CLOSURE: 524 case StaticUseKind.CLOSURE:
522 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and 525 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and
(...skipping 28 matching lines...) Expand all
551 if (options.enableTypeAssertions) { 554 if (options.enableTypeAssertions) {
552 _registerIsCheck(type); 555 _registerIsCheck(type);
553 } 556 }
554 break; 557 break;
555 case TypeUseKind.TYPE_LITERAL: 558 case TypeUseKind.TYPE_LITERAL:
556 break; 559 break;
557 } 560 }
558 } 561 }
559 562
560 void _registerIsCheck(DartType type) { 563 void _registerIsCheck(DartType type) {
561 type = universe.registerIsCheck(type, _compiler); 564 type = _universe.registerIsCheck(type, _compiler);
562 // Even in checked mode, type annotations for return type and argument 565 // Even in checked mode, type annotations for return type and argument
563 // types do not imply type checks, so there should never be a check 566 // types do not imply type checks, so there should never be a check
564 // against the type variable of a typedef. 567 // against the type variable of a typedef.
565 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); 568 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef);
566 } 569 }
567 570
568 void registerCallMethodWithFreeTypeVariables(Element element) { 571 void registerCallMethodWithFreeTypeVariables(Element element) {
569 backend.registerCallMethodWithFreeTypeVariables( 572 backend.registerCallMethodWithFreeTypeVariables(
570 element, this, globalDependencies); 573 element, this, globalDependencies);
571 universe.callMethodsWithFreeTypeVariables.add(element);
572 } 574 }
573 575
574 void registerClosurizedMember(TypedElement element) { 576 void registerClosurizedMember(TypedElement element) {
575 assert(element.isInstanceMember); 577 assert(element.isInstanceMember);
576 if (element.type.containsTypeVariables) { 578 if (element.type.containsTypeVariables) {
577 backend.registerClosureWithFreeTypeVariables( 579 backend.registerClosureWithFreeTypeVariables(
578 element, this, globalDependencies); 580 element, this, globalDependencies);
579 } 581 }
580 backend.registerBoundClosure(this); 582 backend.registerBoundClosure(this);
581 universe.closurizedMembers.add(element);
582 } 583 }
583 584
584 void forEach(void f(WorkItem work)) { 585 void forEach(void f(WorkItem work)) {
585 do { 586 do {
586 while (queue.isNotEmpty) { 587 while (queue.isNotEmpty) {
587 // TODO(johnniwinther): Find an optimal process order. 588 // TODO(johnniwinther): Find an optimal process order.
588 filter.processWorkItem(f, queue.removeLast()); 589 filter.processWorkItem(f, queue.removeLast());
589 } 590 }
590 List recents = recentClasses.toList(growable: false); 591 List recents = recentClasses.toList(growable: false);
591 recentClasses.clear(); 592 recentClasses.clear();
(...skipping 12 matching lines...) Expand all
604 } 605 }
605 606
606 void logSummary(log(message)) { 607 void logSummary(log(message)) {
607 _logSpecificSummary(log); 608 _logSpecificSummary(log);
608 nativeEnqueuer.logSummary(log); 609 nativeEnqueuer.logSummary(log);
609 } 610 }
610 611
611 String toString() => 'Enqueuer($name)'; 612 String toString() => 'Enqueuer($name)';
612 613
613 void _forgetElement(Element element) { 614 void _forgetElement(Element element) {
614 universe.forgetElement(element, _compiler); 615 _universe.forgetElement(element, _compiler);
615 _processedClasses.remove(element); 616 _processedClasses.remove(element);
616 instanceMembersByName[element.name]?.remove(element); 617 instanceMembersByName[element.name]?.remove(element);
617 instanceFunctionsByName[element.name]?.remove(element); 618 instanceFunctionsByName[element.name]?.remove(element);
618 } 619 }
619 620
620 final Queue<CodegenWorkItem> queue; 621 final Queue<CodegenWorkItem> queue;
621 final Map<Element, js.Expression> generatedCode = <Element, js.Expression>{}; 622 final Map<Element, js.Expression> generatedCode = <Element, js.Expression>{};
622 623
623 final Set<Element> newlyEnqueuedElements; 624 final Set<Element> newlyEnqueuedElements;
624 625
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 @override 700 @override
700 void visitStaticUse(StaticUse staticUse) { 701 void visitStaticUse(StaticUse staticUse) {
701 enqueuer.registerStaticUse(staticUse); 702 enqueuer.registerStaticUse(staticUse);
702 } 703 }
703 704
704 @override 705 @override
705 void visitTypeUse(TypeUse typeUse) { 706 void visitTypeUse(TypeUse typeUse) {
706 enqueuer.registerTypeUse(typeUse); 707 enqueuer.registerTypeUse(typeUse);
707 } 708 }
708 } 709 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart ('k') | pkg/compiler/lib/src/js_backend/runtime_types.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698