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

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

Issue 2494093002: Refactor enqueuers (Closed)
Patch Set: Updated cf. comments. Created 4 years, 1 month 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 'common/names.dart' show Identifiers; 9 import 'common/names.dart' show Identifiers;
10 import 'common/resolution.dart' show Resolution; 10 import 'common/resolution.dart' show Resolution;
11 import 'common/resolution.dart' show ResolutionWorkItem; 11 import 'common/resolution.dart' show ResolutionWorkItem;
12 import 'common/tasks.dart' show CompilerTask; 12 import 'common/tasks.dart' show CompilerTask;
13 import 'common/work.dart' show WorkItem; 13 import 'common/work.dart' show WorkItem;
14 import 'common.dart'; 14 import 'common.dart';
15 import 'compiler.dart' show Compiler; 15 import 'compiler.dart' show Compiler;
16 import 'dart_types.dart' show DartType, InterfaceType; 16 import 'dart_types.dart' show DartType, InterfaceType;
17 import 'elements/elements.dart' 17 import 'elements/elements.dart'
18 show 18 show
19 AnalyzableElement, 19 AnalyzableElement,
20 AstElement, 20 AstElement,
21 ClassElement, 21 ClassElement,
22 ConstructorElement,
23 Element, 22 Element,
24 Elements,
25 Entity, 23 Entity,
26 FunctionElement, 24 FunctionElement,
27 LibraryElement, 25 LibraryElement,
28 Member, 26 LocalFunctionElement,
29 Name, 27 TypedElement;
30 TypedElement,
31 TypedefElement;
32 import 'native/native.dart' as native; 28 import 'native/native.dart' as native;
33 import 'types/types.dart' show TypeMaskStrategy; 29 import 'types/types.dart' show TypeMaskStrategy;
34 import 'universe/selector.dart' show Selector; 30 import 'universe/selector.dart' show Selector;
35 import 'universe/world_builder.dart'; 31 import 'universe/world_builder.dart';
36 import 'universe/use.dart' 32 import 'universe/use.dart'
37 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind; 33 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind;
38 import 'universe/world_impact.dart' 34 import 'universe/world_impact.dart'
39 show ImpactUseCase, WorldImpact, WorldImpactVisitor; 35 show ImpactUseCase, WorldImpact, WorldImpactVisitor;
40 import 'util/util.dart' show Setlet; 36 import 'util/util.dart' show Setlet;
41 37
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 89
94 /** 90 /**
95 * Documentation wanted -- johnniwinther 91 * Documentation wanted -- johnniwinther
96 * 92 *
97 * Invariant: [element] must be a declaration element. 93 * Invariant: [element] must be a declaration element.
98 */ 94 */
99 void addToWorkList(Element element); 95 void addToWorkList(Element element);
100 96
101 void enableIsolateSupport(); 97 void enableIsolateSupport();
102 98
103 /// Enqueue the static fields that have been marked as used by reflective 99 void registerInstantiatedType(InterfaceType type);
104 /// usage through `MirrorsUsed`.
105 void enqueueReflectiveStaticFields(Iterable<Element> elements);
106
107 /// Enqueue all elements that are matched by the mirrors used
108 /// annotation or, in lack thereof, all elements.
109 void enqueueReflectiveElements(Iterable<ClassElement> recents);
110
111 void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false});
112 void forEach(void f(WorkItem work)); 100 void forEach(void f(WorkItem work));
113 101
114 /// Apply the [worldImpact] to this enqueuer. If the [impactSource] is provide d 102 /// Apply the [worldImpact] to this enqueuer. If the [impactSource] is provide d
115 /// the impact strategy will remove it from the element impact cache, if it is 103 /// the impact strategy will remove it from the element impact cache, if it is
116 /// no longer needed. 104 /// no longer needed.
117 void applyImpact(WorldImpact worldImpact, {Element impactSource}); 105 void applyImpact(WorldImpact worldImpact, {Element impactSource});
118 bool checkNoEnqueuedInvokedInstanceMethods(); 106 bool checkNoEnqueuedInvokedInstanceMethods();
119 void logSummary(log(message)); 107 void logSummary(log(message));
120 108
121 /// Returns [:true:] if [member] has been processed by this enqueuer. 109 /// Returns [:true:] if [member] has been processed by this enqueuer.
122 bool isProcessed(Element member); 110 bool isProcessed(Element member);
123 111
124 Iterable<Entity> get processedEntities; 112 Iterable<Entity> get processedEntities;
113
114 Iterable<ClassElement> get processedClasses;
125 } 115 }
126 116
127 /// [Enqueuer] which is specific to resolution. 117 /// [Enqueuer] which is specific to resolution.
128 class ResolutionEnqueuer extends Enqueuer { 118 class ResolutionEnqueuer extends Enqueuer {
129 final String name; 119 final String name;
130 final Compiler compiler; // TODO(ahe): Remove this dependency. 120 final Compiler compiler; // TODO(ahe): Remove this dependency.
131 final EnqueuerStrategy strategy; 121 final EnqueuerStrategy strategy;
132 final Map<String, Set<Element>> instanceMembersByName = 122 final Map<String, Set<Element>> instanceMembersByName =
133 new Map<String, Set<Element>>(); 123 new Map<String, Set<Element>>();
134 final Map<String, Set<Element>> instanceFunctionsByName = 124 final Map<String, Set<Element>> instanceFunctionsByName =
135 new Map<String, Set<Element>>(); 125 new Map<String, Set<Element>>();
136 final Set<ClassElement> _processedClasses = new Set<ClassElement>(); 126 final Set<ClassElement> _processedClasses = new Set<ClassElement>();
137 Set<ClassElement> recentClasses = new Setlet<ClassElement>(); 127 Set<ClassElement> recentClasses = new Setlet<ClassElement>();
138 final ResolutionWorldBuilderImpl _universe = 128 final ResolutionWorldBuilderImpl _universe =
139 new ResolutionWorldBuilderImpl(const TypeMaskStrategy()); 129 new ResolutionWorldBuilderImpl(const TypeMaskStrategy());
140 130
141 static final TRACE_MIRROR_ENQUEUING =
142 const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING");
143
144 bool queueIsClosed = false; 131 bool queueIsClosed = false;
145 132
146 bool hasEnqueuedReflectiveElements = false;
147 bool hasEnqueuedReflectiveStaticFields = false;
148
149 WorldImpactVisitor impactVisitor; 133 WorldImpactVisitor impactVisitor;
150 134
151 ResolutionEnqueuer(Compiler compiler, this.strategy) 135 ResolutionEnqueuer(Compiler compiler, this.strategy)
152 : this.name = 'resolution enqueuer', 136 : this.name = 'resolution enqueuer',
153 this.compiler = compiler, 137 this.compiler = compiler,
154 processedElements = new Set<AstElement>(), 138 processedElements = new Set<AstElement>(),
155 queue = new Queue<ResolutionWorkItem>(), 139 queue = new Queue<ResolutionWorkItem>(),
156 deferredQueue = new Queue<_DeferredAction>() { 140 deferredQueue = new Queue<_DeferredAction>() {
157 impactVisitor = new _EnqueuerImpactVisitor(this); 141 impactVisitor = new _EnqueuerImpactVisitor(this);
158 } 142 }
(...skipping 20 matching lines...) Expand all
179 void addToWorkList(Element element) { 163 void addToWorkList(Element element) {
180 assert(invariant(element, element.isDeclaration)); 164 assert(invariant(element, element.isDeclaration));
181 if (internalAddToWorkList(element) && compiler.options.dumpInfo) { 165 if (internalAddToWorkList(element) && compiler.options.dumpInfo) {
182 // TODO(sigmund): add other missing dependencies (internals, selectors 166 // TODO(sigmund): add other missing dependencies (internals, selectors
183 // enqueued after allocations), also enable only for the codegen enqueuer. 167 // enqueued after allocations), also enable only for the codegen enqueuer.
184 compiler.dumpInfoTask 168 compiler.dumpInfoTask
185 .registerDependency(compiler.currentElement, element); 169 .registerDependency(compiler.currentElement, element);
186 } 170 }
187 } 171 }
188 172
173 void registerInstantiatedType(InterfaceType type) {
174 _registerInstantiatedType(type, globalDependency: true);
175 }
176
189 void applyImpact(WorldImpact worldImpact, {Element impactSource}) { 177 void applyImpact(WorldImpact worldImpact, {Element impactSource}) {
190 compiler.impactStrategy 178 compiler.impactStrategy
191 .visitImpact(impactSource, worldImpact, impactVisitor, impactUse); 179 .visitImpact(impactSource, worldImpact, impactVisitor, impactUse);
192 } 180 }
193 181
194 void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}) { 182 void _registerInstantiatedType(InterfaceType type,
183 {bool mirrorUsage: false,
184 bool nativeUsage: false,
185 bool globalDependency: false}) {
195 task.measure(() { 186 task.measure(() {
196 ClassElement cls = type.element; 187 ClassElement cls = type.element;
197 cls.ensureResolved(resolution); 188 cls.ensureResolved(resolution);
198 bool isNative = compiler.backend.isNative(cls); 189 bool isNative = compiler.backend.isNative(cls);
199 _universe.registerTypeInstantiation(type, 190 _universe.registerTypeInstantiation(type,
200 isNative: isNative, 191 isNative: isNative,
201 byMirrors: mirrorUsage, onImplemented: (ClassElement cls) { 192 byMirrors: mirrorUsage, onImplemented: (ClassElement cls) {
202 compiler.backend 193 compiler.backend.registerImplementedClass(cls, this);
203 .registerImplementedClass(cls, this, compiler.globalDependencies);
204 }); 194 });
195 if (globalDependency && !mirrorUsage) {
196 compiler.globalDependencies.registerDependency(type.element);
197 }
198 if (nativeUsage) {
199 nativeEnqueuer.onInstantiatedType(type);
200 }
201 compiler.backend.registerInstantiatedType(type);
205 // TODO(johnniwinther): Share this reasoning with [Universe]. 202 // TODO(johnniwinther): Share this reasoning with [Universe].
206 if (!cls.isAbstract || isNative || mirrorUsage) { 203 if (!cls.isAbstract || isNative || mirrorUsage) {
207 processInstantiatedClass(cls); 204 processInstantiatedClass(cls);
208 } 205 }
209 }); 206 });
210 } 207 }
211 208
212 bool checkNoEnqueuedInvokedInstanceMethods() { 209 bool checkNoEnqueuedInvokedInstanceMethods() {
213 return filter.checkNoEnqueuedInvokedInstanceMethods(this); 210 return filter.checkNoEnqueuedInvokedInstanceMethods(this);
214 } 211 }
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 _processedClasses.add(superclass); 315 _processedClasses.add(superclass);
319 recentClasses.add(superclass); 316 recentClasses.add(superclass);
320 superclass.ensureResolved(resolution); 317 superclass.ensureResolved(resolution);
321 superclass.implementation.forEachMember(processInstantiatedClassMember); 318 superclass.implementation.forEachMember(processInstantiatedClassMember);
322 if (!compiler.serialization.isDeserialized(superclass)) { 319 if (!compiler.serialization.isDeserialized(superclass)) {
323 compiler.resolver.checkClass(superclass); 320 compiler.resolver.checkClass(superclass);
324 } 321 }
325 // We only tell the backend once that [superclass] was instantiated, so 322 // We only tell the backend once that [superclass] was instantiated, so
326 // any additional dependencies must be treated as global 323 // any additional dependencies must be treated as global
327 // dependencies. 324 // dependencies.
328 compiler.backend.registerInstantiatedClass( 325 compiler.backend.registerInstantiatedClass(superclass, this);
329 superclass, this, compiler.globalDependencies);
330 } 326 }
331 327
332 ClassElement superclass = cls; 328 ClassElement superclass = cls;
333 while (superclass != null) { 329 while (superclass != null) {
334 processClass(superclass); 330 processClass(superclass);
335 superclass = superclass.superclass; 331 superclass = superclass.superclass;
336 } 332 }
337 }); 333 });
338 } 334 }
339 335
340 void registerDynamicUse(DynamicUse dynamicUse) { 336 void registerDynamicUse(DynamicUse dynamicUse) {
341 task.measure(() { 337 task.measure(() {
342 if (_universe.registerDynamicUse(dynamicUse)) { 338 if (_universe.registerDynamicUse(dynamicUse)) {
343 handleUnseenSelector(dynamicUse); 339 handleUnseenSelector(dynamicUse);
344 } 340 }
345 }); 341 });
346 } 342 }
347 343
348 void logEnqueueReflectiveAction(action, [msg = ""]) {
349 if (TRACE_MIRROR_ENQUEUING) {
350 print("MIRROR_ENQUEUE (R): $action $msg");
351 }
352 }
353
354 /// Enqeue the constructor [ctor] if it is required for reflection.
355 ///
356 /// [enclosingWasIncluded] provides a hint whether the enclosing element was
357 /// needed for reflection.
358 void enqueueReflectiveConstructor(
359 ConstructorElement ctor, bool enclosingWasIncluded) {
360 if (shouldIncludeElementDueToMirrors(ctor,
361 includedEnclosing: enclosingWasIncluded)) {
362 logEnqueueReflectiveAction(ctor);
363 ClassElement cls = ctor.declaration.enclosingClass;
364 compiler.backend.registerInstantiatedType(
365 cls.rawType, this, compiler.mirrorDependencies,
366 mirrorUsage: true);
367 registerStaticUse(new StaticUse.foreignUse(ctor.declaration));
368 }
369 }
370
371 /// Enqeue the member [element] if it is required for reflection.
372 ///
373 /// [enclosingWasIncluded] provides a hint whether the enclosing element was
374 /// needed for reflection.
375 void enqueueReflectiveMember(Element element, bool enclosingWasIncluded) {
376 if (shouldIncludeElementDueToMirrors(element,
377 includedEnclosing: enclosingWasIncluded)) {
378 logEnqueueReflectiveAction(element);
379 if (element.isTypedef) {
380 TypedefElement typedef = element;
381 typedef.ensureResolved(resolution);
382 } else if (Elements.isStaticOrTopLevel(element)) {
383 registerStaticUse(new StaticUse.foreignUse(element.declaration));
384 } else if (element.isInstanceMember) {
385 // We need to enqueue all members matching this one in subclasses, as
386 // well.
387 // TODO(herhut): Use TypedSelector.subtype for enqueueing
388 DynamicUse dynamicUse =
389 new DynamicUse(new Selector.fromElement(element), null);
390 registerDynamicUse(dynamicUse);
391 if (element.isField) {
392 DynamicUse dynamicUse = new DynamicUse(
393 new Selector.setter(
394 new Name(element.name, element.library, isSetter: true)),
395 null);
396 registerDynamicUse(dynamicUse);
397 }
398 }
399 }
400 }
401
402 /// Enqeue the member [element] if it is required for reflection.
403 ///
404 /// [enclosingWasIncluded] provides a hint whether the enclosing element was
405 /// needed for reflection.
406 void enqueueReflectiveElementsInClass(ClassElement cls,
407 Iterable<ClassElement> recents, bool enclosingWasIncluded) {
408 if (cls.library.isInternalLibrary || cls.isInjected) return;
409 bool includeClass = shouldIncludeElementDueToMirrors(cls,
410 includedEnclosing: enclosingWasIncluded);
411 if (includeClass) {
412 logEnqueueReflectiveAction(cls, "register");
413 ClassElement decl = cls.declaration;
414 decl.ensureResolved(resolution);
415 compiler.backend.registerInstantiatedType(
416 decl.rawType, this, compiler.mirrorDependencies,
417 mirrorUsage: true);
418 }
419 // If the class is never instantiated, we know nothing of it can possibly
420 // be reflected upon.
421 // TODO(herhut): Add a warning if a mirrors annotation cannot hit.
422 if (recents.contains(cls.declaration)) {
423 logEnqueueReflectiveAction(cls, "members");
424 cls.constructors.forEach((Element element) {
425 enqueueReflectiveConstructor(element, includeClass);
426 });
427 cls.forEachClassMember((Member member) {
428 enqueueReflectiveMember(member.element, includeClass);
429 });
430 }
431 }
432
433 /// Enqeue special classes that might not be visible by normal means or that
434 /// would not normally be enqueued:
435 ///
436 /// [Closure] is treated specially as it is the superclass of all closures.
437 /// Although it is in an internal library, we mark it as reflectable. Note
438 /// that none of its methods are reflectable, unless reflectable by
439 /// inheritance.
440 void enqueueReflectiveSpecialClasses() {
441 Iterable<ClassElement> classes =
442 compiler.backend.classesRequiredForReflection;
443 for (ClassElement cls in classes) {
444 if (compiler.backend.referencedFromMirrorSystem(cls)) {
445 logEnqueueReflectiveAction(cls);
446 cls.ensureResolved(resolution);
447 compiler.backend.registerInstantiatedType(
448 cls.rawType, this, compiler.mirrorDependencies,
449 mirrorUsage: true);
450 }
451 }
452 }
453
454 /// Enqeue all local members of the library [lib] if they are required for
455 /// reflection.
456 void enqueueReflectiveElementsInLibrary(
457 LibraryElement lib, Iterable<ClassElement> recents) {
458 bool includeLibrary =
459 shouldIncludeElementDueToMirrors(lib, includedEnclosing: false);
460 lib.forEachLocalMember((Element member) {
461 if (member.isInjected) return;
462 if (member.isClass) {
463 enqueueReflectiveElementsInClass(member, recents, includeLibrary);
464 } else {
465 enqueueReflectiveMember(member, includeLibrary);
466 }
467 });
468 }
469
470 /// Enqueue all elements that are matched by the mirrors used
471 /// annotation or, in lack thereof, all elements.
472 void enqueueReflectiveElements(Iterable<ClassElement> recents) {
473 if (!hasEnqueuedReflectiveElements) {
474 logEnqueueReflectiveAction("!START enqueueAll");
475 // First round of enqueuing, visit everything that is visible to
476 // also pick up static top levels, etc.
477 // Also, during the first round, consider all classes that have been seen
478 // as recently seen, as we do not know how many rounds of resolution might
479 // have run before tree shaking is disabled and thus everything is
480 // enqueued.
481 recents = _processedClasses.toSet();
482 reporter.log('Enqueuing everything');
483 for (LibraryElement lib in compiler.libraryLoader.libraries) {
484 enqueueReflectiveElementsInLibrary(lib, recents);
485 }
486 enqueueReflectiveSpecialClasses();
487 hasEnqueuedReflectiveElements = true;
488 hasEnqueuedReflectiveStaticFields = true;
489 logEnqueueReflectiveAction("!DONE enqueueAll");
490 } else if (recents.isNotEmpty) {
491 // Keep looking at new classes until fixpoint is reached.
492 logEnqueueReflectiveAction("!START enqueueRecents");
493 recents.forEach((ClassElement cls) {
494 enqueueReflectiveElementsInClass(
495 cls,
496 recents,
497 shouldIncludeElementDueToMirrors(cls.library,
498 includedEnclosing: false));
499 });
500 logEnqueueReflectiveAction("!DONE enqueueRecents");
501 }
502 }
503
504 /// Enqueue the static fields that have been marked as used by reflective
505 /// usage through `MirrorsUsed`.
506 void enqueueReflectiveStaticFields(Iterable<Element> elements) {
507 if (hasEnqueuedReflectiveStaticFields) return;
508 hasEnqueuedReflectiveStaticFields = true;
509 for (Element element in elements) {
510 enqueueReflectiveMember(element, true);
511 }
512 }
513
514 void processSet( 344 void processSet(
515 Map<String, Set<Element>> map, String memberName, bool f(Element e)) { 345 Map<String, Set<Element>> map, String memberName, bool f(Element e)) {
516 Set<Element> members = map[memberName]; 346 Set<Element> members = map[memberName];
517 if (members == null) return; 347 if (members == null) return;
518 // [f] might add elements to [: map[memberName] :] during the loop below 348 // [f] might add elements to [: map[memberName] :] during the loop below
519 // so we create a new list for [: map[memberName] :] and prepend the 349 // so we create a new list for [: map[memberName] :] and prepend the
520 // [remaining] members after the loop. 350 // [remaining] members after the loop.
521 map[memberName] = new Set<Element>(); 351 map[memberName] = new Set<Element>();
522 Set<Element> remaining = new Set<Element>(); 352 Set<Element> remaining = new Set<Element>();
523 for (Element member in members) { 353 for (Element member in members) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 */ 399 */
570 void registerStaticUse(StaticUse staticUse) { 400 void registerStaticUse(StaticUse staticUse) {
571 strategy.processStaticUse(this, staticUse); 401 strategy.processStaticUse(this, staticUse);
572 } 402 }
573 403
574 void registerStaticUseInternal(StaticUse staticUse) { 404 void registerStaticUseInternal(StaticUse staticUse) {
575 Element element = staticUse.element; 405 Element element = staticUse.element;
576 assert(invariant(element, element.isDeclaration, 406 assert(invariant(element, element.isDeclaration,
577 message: "Element ${element} is not the declaration.")); 407 message: "Element ${element} is not the declaration."));
578 _universe.registerStaticUse(staticUse); 408 _universe.registerStaticUse(staticUse);
579 compiler.backend.registerStaticUse(element, forResolution: true); 409 compiler.backend.registerStaticUse(this, element);
580 bool addElement = true; 410 bool addElement = true;
581 switch (staticUse.kind) { 411 switch (staticUse.kind) {
582 case StaticUseKind.STATIC_TEAR_OFF: 412 case StaticUseKind.STATIC_TEAR_OFF:
583 compiler.backend.registerGetOfStaticFunction(this); 413 compiler.backend.registerGetOfStaticFunction(this);
584 break; 414 break;
585 case StaticUseKind.FIELD_GET: 415 case StaticUseKind.FIELD_GET:
586 case StaticUseKind.FIELD_SET: 416 case StaticUseKind.FIELD_SET:
587 case StaticUseKind.CLOSURE: 417 case StaticUseKind.CLOSURE:
588 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and 418 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and
589 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue. 419 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue.
590 // Also [CLOSURE] contains [LocalFunctionElement] which we cannot 420 // Also [CLOSURE] contains [LocalFunctionElement] which we cannot
591 // enqueue. 421 // enqueue.
422 LocalFunctionElement closure = staticUse.element;
423 if (closure.type.containsTypeVariables) {
424 universe.closuresWithFreeTypeVariables.add(closure);
425 }
592 addElement = false; 426 addElement = false;
593 break; 427 break;
594 case StaticUseKind.SUPER_FIELD_SET: 428 case StaticUseKind.SUPER_FIELD_SET:
595 case StaticUseKind.SUPER_TEAR_OFF: 429 case StaticUseKind.SUPER_TEAR_OFF:
596 case StaticUseKind.GENERAL: 430 case StaticUseKind.GENERAL:
597 break; 431 break;
598 case StaticUseKind.CONSTRUCTOR_INVOKE: 432 case StaticUseKind.CONSTRUCTOR_INVOKE:
599 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: 433 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
600 registerTypeUse(new TypeUse.instantiation(staticUse.type)); 434 registerTypeUse(new TypeUse.instantiation(staticUse.type));
601 break; 435 break;
602 case StaticUseKind.DIRECT_INVOKE: 436 case StaticUseKind.DIRECT_INVOKE:
603 invariant( 437 invariant(
604 element, 'Direct static use is not supported for resolution.'); 438 element, 'Direct static use is not supported for resolution.');
605 break; 439 break;
606 } 440 }
607 if (addElement) { 441 if (addElement) {
608 addToWorkList(element); 442 addToWorkList(element);
609 } 443 }
610 } 444 }
611 445
612 void registerTypeUse(TypeUse typeUse) { 446 void registerTypeUse(TypeUse typeUse) {
613 DartType type = typeUse.type; 447 DartType type = typeUse.type;
614 switch (typeUse.kind) { 448 switch (typeUse.kind) {
615 case TypeUseKind.INSTANTIATION: 449 case TypeUseKind.INSTANTIATION:
616 registerInstantiatedType(type); 450 _registerInstantiatedType(type, globalDependency: false);
451 break;
452 case TypeUseKind.MIRROR_INSTANTIATION:
453 _registerInstantiatedType(type,
454 mirrorUsage: true, globalDependency: false);
455 break;
456 case TypeUseKind.NATIVE_INSTANTIATION:
457 _registerInstantiatedType(type,
458 nativeUsage: true, globalDependency: true);
617 break; 459 break;
618 case TypeUseKind.IS_CHECK: 460 case TypeUseKind.IS_CHECK:
619 case TypeUseKind.AS_CAST: 461 case TypeUseKind.AS_CAST:
620 case TypeUseKind.CATCH_TYPE: 462 case TypeUseKind.CATCH_TYPE:
621 _registerIsCheck(type); 463 _registerIsCheck(type);
622 break; 464 break;
623 case TypeUseKind.CHECKED_MODE_CHECK: 465 case TypeUseKind.CHECKED_MODE_CHECK:
624 if (compiler.options.enableTypeAssertions) { 466 if (compiler.options.enableTypeAssertions) {
625 _registerIsCheck(type); 467 _registerIsCheck(type);
626 } 468 }
627 break; 469 break;
628 case TypeUseKind.TYPE_LITERAL: 470 case TypeUseKind.TYPE_LITERAL:
629 break; 471 break;
630 } 472 }
631 } 473 }
632 474
633 void _registerIsCheck(DartType type) { 475 void _registerIsCheck(DartType type) {
634 type = _universe.registerIsCheck(type, compiler); 476 type = _universe.registerIsCheck(type, compiler);
635 // Even in checked mode, type annotations for return type and argument 477 // Even in checked mode, type annotations for return type and argument
636 // types do not imply type checks, so there should never be a check 478 // types do not imply type checks, so there should never be a check
637 // against the type variable of a typedef. 479 // against the type variable of a typedef.
638 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); 480 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef);
639 } 481 }
640 482
641 void registerCallMethodWithFreeTypeVariables(Element element) { 483 void registerCallMethodWithFreeTypeVariables(Element element) {
642 compiler.backend.registerCallMethodWithFreeTypeVariables( 484 compiler.backend.registerCallMethodWithFreeTypeVariables(element, this);
643 element, this, compiler.globalDependencies);
644 _universe.callMethodsWithFreeTypeVariables.add(element); 485 _universe.callMethodsWithFreeTypeVariables.add(element);
645 } 486 }
646 487
647 void registerClosurizedMember(TypedElement element) { 488 void registerClosurizedMember(TypedElement element) {
648 assert(element.isInstanceMember); 489 assert(element.isInstanceMember);
649 if (element.computeType(resolution).containsTypeVariables) { 490 if (element.computeType(resolution).containsTypeVariables) {
650 compiler.backend.registerClosureWithFreeTypeVariables( 491 compiler.backend.registerClosureWithFreeTypeVariables(element, this);
651 element, this, compiler.globalDependencies);
652 _universe.closuresWithFreeTypeVariables.add(element); 492 _universe.closuresWithFreeTypeVariables.add(element);
653 } 493 }
654 compiler.backend.registerBoundClosure(this); 494 compiler.backend.registerBoundClosure(this);
655 _universe.closurizedMembers.add(element); 495 _universe.closurizedMembers.add(element);
656 } 496 }
657 497
658 void forEach(void f(WorkItem work)) { 498 void forEach(void f(WorkItem work)) {
659 do { 499 do {
660 while (queue.isNotEmpty) { 500 while (queue.isNotEmpty) {
661 // TODO(johnniwinther): Find an optimal process order. 501 // TODO(johnniwinther): Find an optimal process order.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 return processedElements.contains(element.analyzableElement.declaration); 539 return processedElements.contains(element.analyzableElement.declaration);
700 } 540 }
701 541
702 /// Registers [element] as processed by the resolution enqueuer. 542 /// Registers [element] as processed by the resolution enqueuer.
703 void registerProcessedElement(AstElement element) { 543 void registerProcessedElement(AstElement element) {
704 processedElements.add(element); 544 processedElements.add(element);
705 compiler.backend.onElementResolved(element); 545 compiler.backend.onElementResolved(element);
706 } 546 }
707 547
708 /** 548 /**
709 * Decides whether an element should be included to satisfy requirements
710 * of the mirror system.
711 *
712 * During resolution, we have to resort to matching elements against the
713 * [MirrorsUsed] pattern, as we do not have a complete picture of the world,
714 * yet.
715 */
716 bool shouldIncludeElementDueToMirrors(Element element,
717 {bool includedEnclosing}) {
718 return includedEnclosing ||
719 compiler.backend.requiredByMirrorSystem(element);
720 }
721
722 /**
723 * Adds [element] to the work list if it has not already been processed. 549 * Adds [element] to the work list if it has not already been processed.
724 * 550 *
725 * Returns [true] if the element was actually added to the queue. 551 * Returns [true] if the element was actually added to the queue.
726 */ 552 */
727 bool internalAddToWorkList(Element element) { 553 bool internalAddToWorkList(Element element) {
728 if (element.isMalformed) return false; 554 if (element.isMalformed) return false;
729 555
730 assert(invariant(element, element is AnalyzableElement, 556 assert(invariant(element, element is AnalyzableElement,
731 message: 'Element $element is not analyzable.')); 557 message: 'Element $element is not analyzable.'));
732 if (hasBeenProcessed(element)) return false; 558 if (hasBeenProcessed(element)) return false;
(...skipping 25 matching lines...) Expand all
758 } 584 }
759 } 585 }
760 586
761 if (element.isGetter && element.name == Identifiers.runtimeType_) { 587 if (element.isGetter && element.name == Identifiers.runtimeType_) {
762 // Enable runtime type support if we discover a getter called runtimeType. 588 // Enable runtime type support if we discover a getter called runtimeType.
763 // We have to enable runtime type before hitting the codegen, so 589 // We have to enable runtime type before hitting the codegen, so
764 // that constructors know whether they need to generate code for 590 // that constructors know whether they need to generate code for
765 // runtime type. 591 // runtime type.
766 compiler.enabledRuntimeType = true; 592 compiler.enabledRuntimeType = true;
767 // TODO(ahe): Record precise dependency here. 593 // TODO(ahe): Record precise dependency here.
768 compiler.backend.registerRuntimeType(this, compiler.globalDependencies); 594 compiler.backend.registerRuntimeType(this);
769 } else if (compiler.commonElements.isFunctionApplyMethod(element)) { 595 } else if (compiler.commonElements.isFunctionApplyMethod(element)) {
770 compiler.enabledFunctionApply = true; 596 compiler.enabledFunctionApply = true;
771 } 597 }
772 598
773 return true; 599 return true;
774 } 600 }
775 601
776 void registerNoSuchMethod(Element element) { 602 void registerNoSuchMethod(Element element) {
777 compiler.backend.registerNoSuchMethod(element); 603 compiler.backend.registerNoSuchMethod(element);
778 } 604 }
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 } 740 }
915 741
916 typedef void _DeferredActionFunction(); 742 typedef void _DeferredActionFunction();
917 743
918 class _DeferredAction { 744 class _DeferredAction {
919 final Element element; 745 final Element element;
920 final _DeferredActionFunction action; 746 final _DeferredActionFunction action;
921 747
922 _DeferredAction(this.element, this.action); 748 _DeferredAction(this.element, this.action);
923 } 749 }
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