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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/enqueue.dart

Issue 340783011: Take inheritance into account when computing the elements accessible by mirrors. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 6 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 | Annotate | Revision Log
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 part of dart2js; 5 part of dart2js;
6 6
7 typedef ItemCompilationContext ItemCompilationContextCreator(); 7 typedef ItemCompilationContext ItemCompilationContextCreator();
8 8
9 class EnqueueTask extends CompilerTask { 9 class EnqueueTask extends CompilerTask {
10 final ResolutionEnqueuer resolution; 10 final ResolutionEnqueuer resolution;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 66
67 abstract class Enqueuer { 67 abstract class Enqueuer {
68 final String name; 68 final String name;
69 final Compiler compiler; // TODO(ahe): Remove this dependency. 69 final Compiler compiler; // TODO(ahe): Remove this dependency.
70 final ItemCompilationContextCreator itemCompilationContextCreator; 70 final ItemCompilationContextCreator itemCompilationContextCreator;
71 final Map<String, Link<Element>> instanceMembersByName 71 final Map<String, Link<Element>> instanceMembersByName
72 = new Map<String, Link<Element>>(); 72 = new Map<String, Link<Element>>();
73 final Map<String, Link<Element>> instanceFunctionsByName 73 final Map<String, Link<Element>> instanceFunctionsByName
74 = new Map<String, Link<Element>>(); 74 = new Map<String, Link<Element>>();
75 final Set<ClassElement> seenClasses = new Set<ClassElement>(); 75 final Set<ClassElement> seenClasses = new Set<ClassElement>();
76 Set<ClassElement> recentClasses = new Setlet<ClassElement>();
76 final Universe universe = new Universe(); 77 final Universe universe = new Universe();
77 78
79 static final TRACE_MIRROR_ENQUEUING = false;
floitsch 2014/06/27 08:59:15 should we start making these things const X.fromEn
herhut 2014/06/27 12:34:35 I did not know it was that easy to read an environ
80
78 bool queueIsClosed = false; 81 bool queueIsClosed = false;
79 EnqueueTask task; 82 EnqueueTask task;
80 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask 83 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask
81 84
82 bool hasEnqueuedEverything = false; 85 bool hasEnqueuedReflectiveElements = false;
83 bool hasEnqueuedReflectiveStaticFields = false; 86 bool hasEnqueuedReflectiveStaticFields = false;
84 87
85 Enqueuer(this.name, this.compiler, this.itemCompilationContextCreator); 88 Enqueuer(this.name, this.compiler, this.itemCompilationContextCreator);
86 89
87 Queue<WorkItem> get queue; 90 Queue<WorkItem> get queue;
88 bool get queueIsEmpty => queue.isEmpty; 91 bool get queueIsEmpty => queue.isEmpty;
89 92
90 /// Returns [:true:] if this enqueuer is the resolution enqueuer. 93 /// Returns [:true:] if this enqueuer is the resolution enqueuer.
91 bool get isResolutionQueue => false; 94 bool get isResolutionQueue => false;
92 95
93 /// Returns [:true:] if [member] has been processed by this enqueuer. 96 /// Returns [:true:] if [member] has been processed by this enqueuer.
94 bool isProcessed(Element member); 97 bool isProcessed(Element member);
95 98
96 /** 99 /**
97 * Documentation wanted -- johnniwinther 100 * Documentation wanted -- johnniwinther
98 * 101 *
99 * Invariant: [element] must be a declaration element. 102 * Invariant: [element] must be a declaration element.
100 */ 103 */
101 void addToWorkList(Element element) { 104 void addToWorkList(Element element) {
102 assert(invariant(element, element.isDeclaration)); 105 assert(invariant(element, element.isDeclaration));
103 internalAddToWorkList(element); 106 internalAddToWorkList(element);
104 } 107 }
105 108
106 /** 109 /**
107 * Adds [element] to the work list if it has not already been processed. 110 * Adds [element] to the work list if it has not already been processed.
108 */ 111 */
109 void internalAddToWorkList(Element element); 112 void internalAddToWorkList(Element element);
110 113
111 void registerInstantiatedType(InterfaceType type, Registry registry) { 114 void registerInstantiatedType(InterfaceType type, Registry registry,
115 {mirrorUsage: false}) {
karlklose 2014/06/27 07:45:57 Only use registerInstantiatedType for types that a
herhut 2014/06/27 12:34:35 This only replicated what the original implementat
112 task.measure(() { 116 task.measure(() {
113 ClassElement cls = type.element; 117 ClassElement cls = type.element;
114 registry.registerDependency(cls); 118 registry.registerDependency(cls);
115 cls.ensureResolved(compiler); 119 cls.ensureResolved(compiler);
116 universe.instantiatedTypes.add(type); 120 universe.instantiatedTypes.add(type);
117 if (!cls.isAbstract 121 if (!cls.isAbstract
118 // We can't use the closed-world assumption with native abstract 122 // We can't use the closed-world assumption with native abstract
119 // classes; a native abstract class may have non-abstract subclasses 123 // classes; a native abstract class may have non-abstract subclasses
120 // not declared to the program. Instances of these classes are 124 // not declared to the program. Instances of these classes are
121 // indistinguishable from the abstract class. 125 // indistinguishable from the abstract class.
122 || cls.isNative) { 126 || cls.isNative
127 // Likewise, if this registration comes from the mirror system,
128 // all bets are off.
129 || mirrorUsage) {
123 universe.instantiatedClasses.add(cls); 130 universe.instantiatedClasses.add(cls);
124 } 131 }
125 onRegisterInstantiatedClass(cls); 132 onRegisterInstantiatedClass(cls);
126 }); 133 });
127 } 134 }
128 135
129 void registerInstantiatedClass(ClassElement cls, Registry registry) { 136 void registerInstantiatedClass(ClassElement cls, Registry registry,
137 {mirrorUsage: false}) {
130 cls.ensureResolved(compiler); 138 cls.ensureResolved(compiler);
131 registerInstantiatedType(cls.rawType, registry); 139 registerInstantiatedType(cls.rawType, registry, mirrorUsage: mirrorUsage);
132 } 140 }
133 141
134 bool checkNoEnqueuedInvokedInstanceMethods() { 142 bool checkNoEnqueuedInvokedInstanceMethods() {
135 task.measure(() { 143 task.measure(() {
136 // Run through the classes and see if we need to compile methods. 144 // Run through the classes and see if we need to compile methods.
137 for (ClassElement classElement in universe.instantiatedClasses) { 145 for (ClassElement classElement in universe.instantiatedClasses) {
138 for (ClassElement currentClass = classElement; 146 for (ClassElement currentClass = classElement;
139 currentClass != null; 147 currentClass != null;
140 currentClass = currentClass.superclass) { 148 currentClass = currentClass.superclass) {
141 processInstantiatedClass(currentClass); 149 processInstantiatedClass(currentClass);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 task.measure(() { 261 task.measure(() {
254 if (seenClasses.contains(cls)) return; 262 if (seenClasses.contains(cls)) return;
255 // The class must be resolved to compute the set of all 263 // The class must be resolved to compute the set of all
256 // supertypes. 264 // supertypes.
257 cls.ensureResolved(compiler); 265 cls.ensureResolved(compiler);
258 266
259 void processClass(ClassElement cls) { 267 void processClass(ClassElement cls) {
260 if (seenClasses.contains(cls)) return; 268 if (seenClasses.contains(cls)) return;
261 269
262 seenClasses.add(cls); 270 seenClasses.add(cls);
271 recentClasses.add(cls);
263 cls.ensureResolved(compiler); 272 cls.ensureResolved(compiler);
264 cls.implementation.forEachMember(processInstantiatedClassMember); 273 cls.implementation.forEachMember(processInstantiatedClassMember);
265 if (isResolutionQueue) { 274 if (isResolutionQueue) {
266 compiler.resolver.checkClass(cls); 275 compiler.resolver.checkClass(cls);
267 } 276 }
268 // We only tell the backend once that [cls] was instantiated, so 277 // We only tell the backend once that [cls] was instantiated, so
269 // any additional dependencies must be treated as global 278 // any additional dependencies must be treated as global
270 // dependencies. 279 // dependencies.
271 compiler.backend.registerInstantiatedClass( 280 compiler.backend.registerInstantiatedClass(
272 cls, this, compiler.globalDependencies); 281 cls, this, compiler.globalDependencies);
(...skipping 28 matching lines...) Expand all
301 registerNewSelector(selector, universe.invokedGetters); 310 registerNewSelector(selector, universe.invokedGetters);
302 }); 311 });
303 } 312 }
304 313
305 void registerInvokedSetter(Selector selector) { 314 void registerInvokedSetter(Selector selector) {
306 task.measure(() { 315 task.measure(() {
307 registerNewSelector(selector, universe.invokedSetters); 316 registerNewSelector(selector, universe.invokedSetters);
308 }); 317 });
309 } 318 }
310 319
311 void pretendElementWasUsed(Element element, Registry registry) { 320 /**
312 if (!compiler.backend.isNeededForReflection(element)) return; 321 * Decides whether an element should be included to satisfy requirements
313 if (Elements.isUnresolved(element)) { 322 * of the mirror system.
314 // Ignore. 323 *
315 } else if (element.isSynthesized 324 * The actual implementation depends on the current compiler phase.
316 && element.library.isPlatformLibrary) { 325 */
317 // TODO(ahe): Work-around for http://dartbug.com/11205. 326 bool includeElementDueToMirrors(bool includeEnclosing, Element element);
Johnni Winther 2014/06/27 07:43:01 Rename to [shouldIncludeElementDueToMirror] to ind
Johnni Winther 2014/06/27 07:43:01 Make [includeEnclosing] a named parameter.
herhut 2014/06/27 12:34:36 Done.
herhut 2014/06/27 12:34:36 Done.
318 } else if (element.isConstructor) { 327
319 ClassElement cls = element.declaration.enclosingClass; 328 void logEnqueueReflectiveAction(action, [msg = ""]) {
320 registerInstantiatedType(cls.rawType, registry); 329 if (TRACE_MIRROR_ENQUEUING) {
321 registerStaticUse(element.declaration); 330 print("MIRROR_ENQUEUE (${isResolutionQueue ? "R" : "B"}): $action $msg");
karlklose 2014/06/27 07:45:57 'R' -> 'resolution'? What is 'B'?
herhut 2014/06/27 12:34:36 Backend. Probably C for codegen is better. I have
322 } else if (element.isClass) { 331 }
323 ClassElement cls = element.declaration; 332 }
324 registerInstantiatedClass(cls, registry); 333
325 // Make sure that even abstract classes are considered instantiated. 334 void enqueueReflectiveConstructor(ConstructorElement ctor, bool add) {
Johnni Winther 2014/06/27 07:43:00 Add comment. I guess it is a helper method for [en
Johnni Winther 2014/06/27 07:43:01 Make [add] named.
karlklose 2014/06/27 07:45:57 Could you add a comment about the semantics of 'ad
floitsch 2014/06/27 08:59:15 nit: s/add/forceAdd/ I'm guessing that's the mean
herhut 2014/06/27 12:34:36 Done.
herhut 2014/06/27 12:34:36 Done.
herhut 2014/06/27 12:34:36 Done.
herhut 2014/06/27 12:34:37 Done.
326 universe.instantiatedClasses.add(cls); 335 if (includeElementDueToMirrors(add, ctor)) {
327 } else if (element.impliesType) { 336 logEnqueueReflectiveAction(ctor);
328 // Don't enqueue typedefs, and type variables. 337 ClassElement cls = ctor.declaration.enclosingClass;
329 } else if (Elements.isStaticOrTopLevel(element)) { 338 registerInstantiatedType(cls.rawType, compiler.mirrorDependencies);
Johnni Winther 2014/06/27 07:43:01 Shouldn't this call have `mirrorUsage: true` ?
karlklose 2014/06/27 07:45:57 I am not sure we should register this type here.
herhut 2014/06/27 12:34:35 It will not have an effect currently but it is mor
herhut 2014/06/27 12:34:36 This implements what was done before. I will redo
330 registerStaticUse(element.declaration); 339 registerStaticUse(ctor.declaration);
331 } else if (element.isInstanceMember) { 340 }
332 Selector selector = new Selector.fromElement(element, compiler); 341 }
333 registerSelectorUse(selector); 342
334 if (element.isField) { 343 void enqueueReflectiveMember(Element element, bool add) {
Johnni Winther 2014/06/27 07:43:00 Make [add] named.
Johnni Winther 2014/06/27 07:43:01 Add comment.
herhut 2014/06/27 12:34:35 Done.
herhut 2014/06/27 12:34:36 Done.
335 Selector selector = 344 add = includeElementDueToMirrors(add, element);
karlklose 2014/06/27 07:45:57 Inline call to includeElementsDueToMirrors? (Also
herhut 2014/06/27 12:34:36 Below I have to pass the result on to the processi
336 new Selector.setter(element.name, element.library); 345 if (add && !element.impliesType) {
floitsch 2014/06/27 08:59:15 Keep comment exlpaining what "impliesType" means.
herhut 2014/06/27 12:34:36 Done.
337 registerInvokedSetter(selector); 346 logEnqueueReflectiveAction(element);
347 if (Elements.isStaticOrTopLevel(element)) {
348 registerStaticUse(element.declaration);
349 } else if (element.isInstanceMember) {
350 // We need to enqueue all members matching this one in subclasses, as
351 // well.
352 // TODO(herhut): Use TypedSelector.subtype for enqueueing
353 Selector selector = new Selector.fromElement(element, compiler);
354 registerSelectorUse(selector);
355 if (element.isField) {
356 Selector selector =
357 new Selector.setter(element.name, element.library);
358 registerInvokedSetter(selector);
359 }
338 } 360 }
339 } 361 }
340 } 362 }
341 363
342 void enqueueEverything() { 364 void enqueueReflectiveElementsInClass(ClassElement cls,
Johnni Winther 2014/06/27 07:43:00 Add comment.
herhut 2014/06/27 12:34:36 Done.
343 if (hasEnqueuedEverything) return; 365 Iterable<ClassElement> recents,
344 compiler.log('Enqueuing everything'); 366 bool add) {
Johnni Winther 2014/06/27 07:43:00 Make [add] named.
herhut 2014/06/27 12:34:37 Done.
345 task.ensureAllElementsByName(); 367 if (cls.library.isInternalLibrary) return;
346 for (Link link in task.allElementsByName.values) { 368 if (cls.isInjected) return;
Johnni Winther 2014/06/27 07:43:00 Merge conditions.
herhut 2014/06/27 12:34:36 Done.
347 for (Element element in link) { 369 add = includeElementDueToMirrors(add, cls);
348 pretendElementWasUsed(element, compiler.mirrorDependencies); 370 if (add) {
371 logEnqueueReflectiveAction(cls, "register");
372 ClassElement decl = cls.declaration;
373 registerInstantiatedClass(decl, compiler.mirrorDependencies,
374 mirrorUsage: true);
375 }
376 // If the class is never instantiated, we know nothing of it can possibly
377 // be reflected upon.
378 // TODO(herhut): Add a warning if a mirrors annotation cannot hit.
379 if (recents.contains(cls.declaration)) {
380 logEnqueueReflectiveAction(cls, "members");
381 cls.constructors.forEach((Element element) {
382 enqueueReflectiveConstructor(element, add);
383 });
384 cls.forEachClassMember((Member member) {
385 enqueueReflectiveMember(member.element, add);
386 });
387 }
388 }
389
390 void enqueueReflectiveSpecialClasses() {
Johnni Winther 2014/06/27 07:43:00 Add comment.
herhut 2014/06/27 12:34:36 Done.
391 // [Closure] is treated specially as it is the superclass of all closures.
392 // Although it is in an internal library, we mark it as reflectable. Note
393 // that none of its methods are reflectable, unless reflectable by
394 // inheritance.
395 ClassElement closureClass = compiler.closureClass;
396 if (compiler.backend.referencedFromMirrorSystem(closureClass)) {
397 logEnqueueReflectiveAction(closureClass);
398 registerInstantiatedClass(closureClass, compiler.mirrorDependencies,
399 mirrorUsage: true);
400 }
401 }
402
403 void enqueueReflectiveElementsInLibrary(LibraryElement lib,
Johnni Winther 2014/06/27 07:43:00 Add comment.
herhut 2014/06/27 12:34:36 Done.
404 Iterable<ClassElement> recents,
405 bool add) {
406 add = includeElementDueToMirrors(add, lib);
407 lib.forEachLocalMember((Element member) {
408 if (member.isClass) {
409 enqueueReflectiveElementsInClass(member, recents, add);
410 } else {
411 enqueueReflectiveMember(member, add);
349 } 412 }
413 });
414 }
415
416 /// Enqueue all elements that are matched by the mirrors used
417 /// annotation or, in lack thereof, all elements.
418 void enqueueReflectiveElements(Iterable<ClassElement> recents) {
419 if (!hasEnqueuedReflectiveElements) {
420 logEnqueueReflectiveAction("!START enqueueAll");
421 // First round of enqueuing, visit everything that is visible to
422 // also pick up static top levels, etc.
423 // Also, during the first round, consider all classes that have been seen
424 // as recently seen, as a couple of rounds of resolution might have run
floitsch 2014/06/27 08:59:15 maybe? ... as treeshaking might only be disabled
herhut 2014/06/27 12:34:35 Rephrased: Also, during the first round, consider
425 // before treeshaking is disabled and we thus enqueue everything.
426 recents = seenClasses.toSet();
427 compiler.log('Enqueuing everything');
428 for (LibraryElement lib in compiler.libraries.values) {
429 enqueueReflectiveElementsInLibrary(lib, recents, false);
430 }
431 enqueueReflectiveSpecialClasses();
432 hasEnqueuedReflectiveElements = true;
433 hasEnqueuedReflectiveStaticFields = true;
434 logEnqueueReflectiveAction("!DONE enqueueAll");
435 } else if (recents.isNotEmpty) {
436 // Keep looking at new classes until fixpoint is reached.
437 logEnqueueReflectiveAction("!START enqueueRecents");
438 recents.forEach((ClassElement cls) {
439 enqueueReflectiveElementsInClass(cls, recents,
440 includeElementDueToMirrors(false, cls.library));
441 });
442 logEnqueueReflectiveAction("!DONE enqueueRecents");
350 } 443 }
351 hasEnqueuedEverything = true;
352 hasEnqueuedReflectiveStaticFields = true;
353 } 444 }
354 445
355 /// Enqueue the static fields that have been marked as used by reflective 446 /// Enqueue the static fields that have been marked as used by reflective
356 /// usage through `MirrorsUsed`. 447 /// usage through `MirrorsUsed`.
357 void enqueueReflectiveStaticFields(Iterable<Element> elements) { 448 void enqueueReflectiveStaticFields(Iterable<Element> elements) {
358 if (hasEnqueuedReflectiveStaticFields) return; 449 if (hasEnqueuedReflectiveStaticFields) return;
359 hasEnqueuedReflectiveStaticFields = true; 450 hasEnqueuedReflectiveStaticFields = true;
360 for (Element element in elements) { 451 for (Element element in elements) {
361 pretendElementWasUsed(element, compiler.mirrorDependencies); 452 enqueueReflectiveMember(element, true);
362 } 453 }
363 } 454 }
364 455
365 processLink(Map<String, Link<Element>> map, 456 processLink(Map<String, Link<Element>> map,
366 String memberName, 457 String memberName,
367 bool f(Element e)) { 458 bool f(Element e)) {
368 Link<Element> members = map[memberName]; 459 Link<Element> members = map[memberName];
369 if (members != null) { 460 if (members != null) {
370 // [f] might add elements to [: map[memberName] :] during the loop below 461 // [f] might add elements to [: map[memberName] :] during the loop below
371 // so we create a new list for [: map[memberName] :] and prepend the 462 // so we create a new list for [: map[memberName] :] and prepend the
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 } 612 }
522 613
523 614
524 void registerIfGeneric(Element element, Registry registry) { 615 void registerIfGeneric(Element element, Registry registry) {
525 if (element.computeType(compiler).containsTypeVariables) { 616 if (element.computeType(compiler).containsTypeVariables) {
526 compiler.backend.registerGenericClosure(element, this, registry); 617 compiler.backend.registerGenericClosure(element, this, registry);
527 universe.genericClosures.add(element); 618 universe.genericClosures.add(element);
528 } 619 }
529 } 620 }
530 621
531 void registerClosure(Element element, Registry registry) { 622 void registerClosure(Element element, Registry registry) {
Johnni Winther 2014/06/27 07:43:00 Change [Element] to [FunctionElement].
herhut 2014/06/27 12:34:36 Done.
623 universe.allClosures.add(element);
532 registerIfGeneric(element, registry); 624 registerIfGeneric(element, registry);
533 } 625 }
534 626
535 void forEach(f(WorkItem work)) { 627 void forEach(f(WorkItem work)) {
536 do { 628 do {
537 while (!queue.isEmpty) { 629 while (queue.isNotEmpty) {
538 // TODO(johnniwinther): Find an optimal process order. 630 // TODO(johnniwinther): Find an optimal process order.
539 f(queue.removeLast()); 631 f(queue.removeLast());
540 } 632 }
541 onQueueEmpty(); 633 List recents = recentClasses.toList(growable: false);
542 } while (!queue.isEmpty); 634 recentClasses.clear();
635 if (!onQueueEmpty(recents)) recentClasses.addAll(recents);
636 } while (queue.isNotEmpty || recentClasses.isNotEmpty);
543 } 637 }
544 638
545 void onQueueEmpty() { 639 /// [onQueueEmpty] is called whenever the queue is drained. [recentClasses]
546 compiler.backend.onQueueEmpty(this); 640 /// contains the set of all classes seen for the first time since
641 /// [onQueueEmpty] was called last. A return value of [true] indicates that
642 /// the [recentClasses] have been processed and may be cleared. If [false] is
643 /// returned, [onQueueEmpty] will be called once the queue is empty again (or
644 /// still empty) and [recentClasses] will be a superset of the current value.
645 bool onQueueEmpty(Iterable<ClassElement> recentClasses) {
646 return compiler.backend.onQueueEmpty(this, recentClasses);
547 } 647 }
548 648
549 void logSummary(log(message)) { 649 void logSummary(log(message)) {
550 _logSpecificSummary(log); 650 _logSpecificSummary(log);
551 nativeEnqueuer.logSummary(log); 651 nativeEnqueuer.logSummary(log);
552 } 652 }
553 653
554 /// Log summary specific to the concrete enqueuer. 654 /// Log summary specific to the concrete enqueuer.
555 void _logSpecificSummary(log(message)); 655 void _logSpecificSummary(log(message));
556 656
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 resolvedElements.add(element); 696 resolvedElements.add(element);
597 } 697 }
598 698
599 /// Returns [:true:] if [element] has actually been used. 699 /// Returns [:true:] if [element] has actually been used.
600 bool isLive(Element element) { 700 bool isLive(Element element) {
601 if (seenClasses.contains(element)) return true; 701 if (seenClasses.contains(element)) return true;
602 if (hasBeenResolved(element)) return true; 702 if (hasBeenResolved(element)) return true;
603 return false; 703 return false;
604 } 704 }
605 705
706 /**
707 * Decides whether an element should be included to satisfy requirements
708 * of the mirror system.
709 *
710 * During resoltion, we have to resort to matching elements against the
Johnni Winther 2014/06/27 07:43:01 'resoltion' -> 'resolution'.
karlklose 2014/06/27 07:45:57 'resoltion' -> 'resolution'.
herhut 2014/06/27 12:34:36 Done.
herhut 2014/06/27 12:34:37 Done.
711 * [MirrorsUsed] pattern, as we do not have a complete picture of the world,
712 * yet.
713 */
714 bool includeElementDueToMirrors(bool includeEnclosing, Element element) {
karlklose 2014/06/27 07:45:57 Does it make sense to move functionality like this
herhut 2014/06/27 12:34:36 Yes, this is also on the list of further refactori
715 return includeEnclosing || compiler.backend.requiredByMirrorSystem(element);
716 }
717
606 void internalAddToWorkList(Element element) { 718 void internalAddToWorkList(Element element) {
607 assert(invariant(element, element is AnalyzableElement, 719 assert(invariant(element, element is AnalyzableElement,
608 message: 'Element $element is not analyzable.')); 720 message: 'Element $element is not analyzable.'));
609 if (hasBeenResolved(element)) return; 721 if (hasBeenResolved(element)) return;
610 if (queueIsClosed) { 722 if (queueIsClosed) {
611 throw new SpannableAssertionFailure(element, 723 throw new SpannableAssertionFailure(element,
612 "Resolution work list is closed. Trying to add $element."); 724 "Resolution work list is closed. Trying to add $element.");
613 } 725 }
614 726
615 compiler.world.registerUsedElement(element); 727 compiler.world.registerUsedElement(element);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 */ 794 */
683 void addDeferredAction(Element element, DeferredAction action) { 795 void addDeferredAction(Element element, DeferredAction action) {
684 if (queueIsClosed) { 796 if (queueIsClosed) {
685 throw new SpannableAssertionFailure(element, 797 throw new SpannableAssertionFailure(element,
686 "Resolution work list is closed. " 798 "Resolution work list is closed. "
687 "Trying to add deferred action for $element"); 799 "Trying to add deferred action for $element");
688 } 800 }
689 deferredTaskQueue.add(new DeferredTask(element, action)); 801 deferredTaskQueue.add(new DeferredTask(element, action));
690 } 802 }
691 803
692 void onQueueEmpty() { 804 bool onQueueEmpty(Iterable<ClassElement> recentClasses) {
693 emptyDeferredTaskQueue(); 805 emptyDeferredTaskQueue();
694 super.onQueueEmpty(); 806 return super.onQueueEmpty(recentClasses);
695 } 807 }
696 808
697 void emptyDeferredTaskQueue() { 809 void emptyDeferredTaskQueue() {
698 while (!deferredTaskQueue.isEmpty) { 810 while (!deferredTaskQueue.isEmpty) {
699 DeferredTask task = deferredTaskQueue.removeFirst(); 811 DeferredTask task = deferredTaskQueue.removeFirst();
700 compiler.withCurrentElement(task.element, task.action); 812 compiler.withCurrentElement(task.element, task.action);
701 } 813 }
702 } 814 }
703 815
704 void registerJsCall(Send node, ResolverVisitor resolver) { 816 void registerJsCall(Send node, ResolverVisitor resolver) {
(...skipping 15 matching lines...) Expand all
720 832
721 CodegenEnqueuer(Compiler compiler, 833 CodegenEnqueuer(Compiler compiler,
722 ItemCompilationContext itemCompilationContextCreator()) 834 ItemCompilationContext itemCompilationContextCreator())
723 : queue = new Queue<CodegenWorkItem>(), 835 : queue = new Queue<CodegenWorkItem>(),
724 newlyEnqueuedElements = compiler.cacheStrategy.newSet(), 836 newlyEnqueuedElements = compiler.cacheStrategy.newSet(),
725 super('codegen enqueuer', compiler, itemCompilationContextCreator); 837 super('codegen enqueuer', compiler, itemCompilationContextCreator);
726 838
727 bool isProcessed(Element member) => 839 bool isProcessed(Element member) =>
728 member.isAbstract || generatedCode.containsKey(member); 840 member.isAbstract || generatedCode.containsKey(member);
729 841
842 /**
843 * Decides whether an element should be included to satisfy requirements
844 * of the mirror system.
845 *
846 * For code generation, we rely on the precomputed set of elements that takes
847 * subtyping constraints into account.
848 */
849 bool includeElementDueToMirrors(bool includeEnclosing, Element element) {
850 return compiler.backend.isAccessibleByReflection(element);
851 }
852
730 void internalAddToWorkList(Element element) { 853 void internalAddToWorkList(Element element) {
731 if (compiler.hasIncrementalSupport) { 854 if (compiler.hasIncrementalSupport) {
732 newlyEnqueuedElements.add(element); 855 newlyEnqueuedElements.add(element);
733 } 856 }
734 // Don't generate code for foreign elements. 857 // Don't generate code for foreign elements.
735 if (element.isForeign(compiler)) return; 858 if (element.isForeign(compiler)) return;
736 859
737 // Codegen inlines field initializers. It only needs to generate 860 // Codegen inlines field initializers. It only needs to generate
738 // code for checked setters. 861 // code for checked setters.
739 if (element.isField && element.isInstanceMember) { 862 if (element.isField && element.isInstanceMember) {
740 if (!compiler.enableTypeAssertions 863 if (!compiler.enableTypeAssertions
741 || element.enclosingElement.isClosure) { 864 || element.enclosingElement.isClosure) {
742 return; 865 return;
743 } 866 }
744 } 867 }
745 868
746 if (queueIsClosed) { 869 if (queueIsClosed) {
747 throw new SpannableAssertionFailure(element, 870 throw new SpannableAssertionFailure(element,
748 "Codegen work list is closed. Trying to add $element"); 871 "Codegen work list is closed. Trying to add $element");
749 } 872 }
750 CodegenWorkItem workItem = new CodegenWorkItem( 873 CodegenWorkItem workItem = new CodegenWorkItem(
751 element, itemCompilationContextCreator()); 874 element, itemCompilationContextCreator());
752 queue.add(workItem); 875 queue.add(workItem);
753 } 876 }
754 877
755 void _logSpecificSummary(log(message)) { 878 void _logSpecificSummary(log(message)) {
756 log('Compiled ${generatedCode.length} methods.'); 879 log('Compiled ${generatedCode.length} methods.');
757 } 880 }
758 } 881 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698