OLD | NEW |
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 22 matching lines...) Expand all Loading... |
33 } | 33 } |
34 | 34 |
35 abstract class Enqueuer { | 35 abstract class Enqueuer { |
36 final String name; | 36 final String name; |
37 final Compiler compiler; // TODO(ahe): Remove this dependency. | 37 final Compiler compiler; // TODO(ahe): Remove this dependency. |
38 final ItemCompilationContextCreator itemCompilationContextCreator; | 38 final ItemCompilationContextCreator itemCompilationContextCreator; |
39 final Map<String, Set<Element>> instanceMembersByName | 39 final Map<String, Set<Element>> instanceMembersByName |
40 = new Map<String, Set<Element>>(); | 40 = new Map<String, Set<Element>>(); |
41 final Map<String, Set<Element>> instanceFunctionsByName | 41 final Map<String, Set<Element>> instanceFunctionsByName |
42 = new Map<String, Set<Element>>(); | 42 = new Map<String, Set<Element>>(); |
43 final Set<ClassElement> _seenClasses = new Set<ClassElement>(); | 43 final Set<ClassElement> _processedClasses = new Set<ClassElement>(); |
44 Set<ClassElement> recentClasses = new Setlet<ClassElement>(); | 44 Set<ClassElement> recentClasses = new Setlet<ClassElement>(); |
45 final Universe universe = new Universe(); | 45 final Universe universe = new Universe(); |
46 | 46 |
47 static final TRACE_MIRROR_ENQUEUING = | 47 static final TRACE_MIRROR_ENQUEUING = |
48 const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING"); | 48 const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING"); |
49 | 49 |
50 bool queueIsClosed = false; | 50 bool queueIsClosed = false; |
51 EnqueueTask task; | 51 EnqueueTask task; |
52 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask | 52 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask |
53 | 53 |
(...skipping 30 matching lines...) Expand all Loading... |
84 */ | 84 */ |
85 bool internalAddToWorkList(Element element); | 85 bool internalAddToWorkList(Element element); |
86 | 86 |
87 void registerInstantiatedType(InterfaceType type, Registry registry, | 87 void registerInstantiatedType(InterfaceType type, Registry registry, |
88 {bool mirrorUsage: false}) { | 88 {bool mirrorUsage: false}) { |
89 task.measure(() { | 89 task.measure(() { |
90 ClassElement cls = type.element; | 90 ClassElement cls = type.element; |
91 registry.registerDependency(cls); | 91 registry.registerDependency(cls); |
92 cls.ensureResolved(compiler); | 92 cls.ensureResolved(compiler); |
93 universe.registerTypeInstantiation(type, byMirrors: mirrorUsage); | 93 universe.registerTypeInstantiation(type, byMirrors: mirrorUsage); |
94 onRegisterInstantiatedClass(cls); | 94 processInstantiatedClass(cls); |
95 }); | 95 }); |
96 } | 96 } |
97 | 97 |
98 void registerInstantiatedClass(ClassElement cls, Registry registry, | 98 void registerInstantiatedClass(ClassElement cls, Registry registry, |
99 {bool mirrorUsage: false}) { | 99 {bool mirrorUsage: false}) { |
100 cls.ensureResolved(compiler); | 100 cls.ensureResolved(compiler); |
101 registerInstantiatedType(cls.rawType, registry, mirrorUsage: mirrorUsage); | 101 registerInstantiatedType(cls.rawType, registry, mirrorUsage: mirrorUsage); |
102 } | 102 } |
103 | 103 |
104 bool checkNoEnqueuedInvokedInstanceMethods() { | 104 bool checkNoEnqueuedInvokedInstanceMethods() { |
105 return filter.checkNoEnqueuedInvokedInstanceMethods(this); | 105 return filter.checkNoEnqueuedInvokedInstanceMethods(this); |
106 } | 106 } |
107 | 107 |
108 void processInstantiatedClass(ClassElement cls) { | 108 void processInstantiatedClassMembers(ClassElement cls) { |
109 cls.implementation.forEachMember(processInstantiatedClassMember); | 109 cls.implementation.forEachMember(processInstantiatedClassMember); |
110 } | 110 } |
111 | 111 |
112 void processInstantiatedClassMember(ClassElement cls, Element member) { | 112 void processInstantiatedClassMember(ClassElement cls, Element member) { |
113 assert(invariant(member, member.isDeclaration)); | 113 assert(invariant(member, member.isDeclaration)); |
114 if (isProcessed(member)) return; | 114 if (isProcessed(member)) return; |
115 if (!member.isInstanceMember) return; | 115 if (!member.isInstanceMember) return; |
116 | 116 |
117 String memberName = member.name; | 117 String memberName = member.name; |
118 | 118 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 | 207 |
208 // The element is not yet used. Add it to the list of instance | 208 // The element is not yet used. Add it to the list of instance |
209 // members to still be processed. | 209 // members to still be processed. |
210 instanceMembersByName.putIfAbsent(memberName, () => new Set<Element>()) | 210 instanceMembersByName.putIfAbsent(memberName, () => new Set<Element>()) |
211 .add(member); | 211 .add(member); |
212 } | 212 } |
213 | 213 |
214 void enableNoSuchMethod(Element element) {} | 214 void enableNoSuchMethod(Element element) {} |
215 void enableIsolateSupport() {} | 215 void enableIsolateSupport() {} |
216 | 216 |
217 void onRegisterInstantiatedClass(ClassElement cls) { | 217 void processInstantiatedClass(ClassElement cls) { |
218 task.measure(() { | 218 task.measure(() { |
219 if (_seenClasses.contains(cls)) return; | 219 if (_processedClasses.contains(cls)) return; |
220 // The class must be resolved to compute the set of all | 220 // The class must be resolved to compute the set of all |
221 // supertypes. | 221 // supertypes. |
222 cls.ensureResolved(compiler); | 222 cls.ensureResolved(compiler); |
223 | 223 |
224 void processClass(ClassElement cls) { | 224 void processClass(ClassElement cls) { |
225 if (_seenClasses.contains(cls)) return; | 225 if (_processedClasses.contains(cls)) return; |
226 | 226 |
227 _seenClasses.add(cls); | 227 _processedClasses.add(cls); |
228 recentClasses.add(cls); | 228 recentClasses.add(cls); |
229 cls.ensureResolved(compiler); | 229 cls.ensureResolved(compiler); |
230 cls.implementation.forEachMember(processInstantiatedClassMember); | 230 cls.implementation.forEachMember(processInstantiatedClassMember); |
231 if (isResolutionQueue) { | 231 if (isResolutionQueue) { |
232 compiler.resolver.checkClass(cls); | 232 compiler.resolver.checkClass(cls); |
233 } | 233 } |
234 // We only tell the backend once that [cls] was instantiated, so | 234 // We only tell the backend once that [cls] was instantiated, so |
235 // any additional dependencies must be treated as global | 235 // any additional dependencies must be treated as global |
236 // dependencies. | 236 // dependencies. |
237 compiler.backend.registerInstantiatedClass( | 237 compiler.backend.registerInstantiatedClass( |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 /// annotation or, in lack thereof, all elements. | 403 /// annotation or, in lack thereof, all elements. |
404 void enqueueReflectiveElements(Iterable<ClassElement> recents) { | 404 void enqueueReflectiveElements(Iterable<ClassElement> recents) { |
405 if (!hasEnqueuedReflectiveElements) { | 405 if (!hasEnqueuedReflectiveElements) { |
406 logEnqueueReflectiveAction("!START enqueueAll"); | 406 logEnqueueReflectiveAction("!START enqueueAll"); |
407 // First round of enqueuing, visit everything that is visible to | 407 // First round of enqueuing, visit everything that is visible to |
408 // also pick up static top levels, etc. | 408 // also pick up static top levels, etc. |
409 // Also, during the first round, consider all classes that have been seen | 409 // Also, during the first round, consider all classes that have been seen |
410 // as recently seen, as we do not know how many rounds of resolution might | 410 // as recently seen, as we do not know how many rounds of resolution might |
411 // have run before tree shaking is disabled and thus everything is | 411 // have run before tree shaking is disabled and thus everything is |
412 // enqueued. | 412 // enqueued. |
413 recents = _seenClasses.toSet(); | 413 recents = _processedClasses.toSet(); |
414 compiler.log('Enqueuing everything'); | 414 compiler.log('Enqueuing everything'); |
415 for (LibraryElement lib in compiler.libraryLoader.libraries) { | 415 for (LibraryElement lib in compiler.libraryLoader.libraries) { |
416 enqueueReflectiveElementsInLibrary(lib, recents); | 416 enqueueReflectiveElementsInLibrary(lib, recents); |
417 } | 417 } |
418 enqueueReflectiveSpecialClasses(); | 418 enqueueReflectiveSpecialClasses(); |
419 hasEnqueuedReflectiveElements = true; | 419 hasEnqueuedReflectiveElements = true; |
420 hasEnqueuedReflectiveStaticFields = true; | 420 hasEnqueuedReflectiveStaticFields = true; |
421 logEnqueueReflectiveAction("!DONE enqueueAll"); | 421 logEnqueueReflectiveAction("!DONE enqueueAll"); |
422 } else if (recents.isNotEmpty) { | 422 } else if (recents.isNotEmpty) { |
423 // Keep looking at new classes until fixpoint is reached. | 423 // Keep looking at new classes until fixpoint is reached. |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 nativeEnqueuer.logSummary(log); | 632 nativeEnqueuer.logSummary(log); |
633 } | 633 } |
634 | 634 |
635 /// Log summary specific to the concrete enqueuer. | 635 /// Log summary specific to the concrete enqueuer. |
636 void _logSpecificSummary(log(message)); | 636 void _logSpecificSummary(log(message)); |
637 | 637 |
638 String toString() => 'Enqueuer($name)'; | 638 String toString() => 'Enqueuer($name)'; |
639 | 639 |
640 void forgetElement(Element element) { | 640 void forgetElement(Element element) { |
641 universe.forgetElement(element, compiler); | 641 universe.forgetElement(element, compiler); |
642 _seenClasses.remove(element); | 642 _processedClasses.remove(element); |
643 } | 643 } |
644 } | 644 } |
645 | 645 |
646 /// [Enqueuer] which is specific to resolution. | 646 /// [Enqueuer] which is specific to resolution. |
647 class ResolutionEnqueuer extends Enqueuer { | 647 class ResolutionEnqueuer extends Enqueuer { |
648 /** | 648 /** |
649 * Map from declaration elements to the [TreeElements] object holding the | 649 * Map from declaration elements to the [TreeElements] object holding the |
650 * resolution mapping for the element implementation. | 650 * resolution mapping for the element implementation. |
651 * | 651 * |
652 * Invariant: Key elements are declaration elements. | 652 * Invariant: Key elements are declaration elements. |
(...skipping 22 matching lines...) Expand all Loading... |
675 /// Returns `true` if [element] has been processed by the resolution enqueuer. | 675 /// Returns `true` if [element] has been processed by the resolution enqueuer. |
676 bool hasBeenResolved(Element element) { | 676 bool hasBeenResolved(Element element) { |
677 return resolvedElements.contains(element.analyzableElement.declaration); | 677 return resolvedElements.contains(element.analyzableElement.declaration); |
678 } | 678 } |
679 | 679 |
680 /// Registers [element] as resolved for the resolution enqueuer. | 680 /// Registers [element] as resolved for the resolution enqueuer. |
681 void registerResolvedElement(AstElement element) { | 681 void registerResolvedElement(AstElement element) { |
682 resolvedElements.add(element); | 682 resolvedElements.add(element); |
683 } | 683 } |
684 | 684 |
685 /// Returns [:true:] if [element] has actually been used. | |
686 bool isLive(Element element) { | |
687 if (_seenClasses.contains(element)) return true; | |
688 if (hasBeenResolved(element)) return true; | |
689 return false; | |
690 } | |
691 | |
692 /** | 685 /** |
693 * Decides whether an element should be included to satisfy requirements | 686 * Decides whether an element should be included to satisfy requirements |
694 * of the mirror system. | 687 * of the mirror system. |
695 * | 688 * |
696 * During resolution, we have to resort to matching elements against the | 689 * During resolution, we have to resort to matching elements against the |
697 * [MirrorsUsed] pattern, as we do not have a complete picture of the world, | 690 * [MirrorsUsed] pattern, as we do not have a complete picture of the world, |
698 * yet. | 691 * yet. |
699 */ | 692 */ |
700 bool shouldIncludeElementDueToMirrors(Element element, | 693 bool shouldIncludeElementDueToMirrors(Element element, |
701 {bool includedEnclosing}) { | 694 {bool includedEnclosing}) { |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 } | 874 } |
882 } | 875 } |
883 } | 876 } |
884 } | 877 } |
885 | 878 |
886 /// Parameterizes filtering of which work items are enqueued. | 879 /// Parameterizes filtering of which work items are enqueued. |
887 class QueueFilter { | 880 class QueueFilter { |
888 bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) { | 881 bool checkNoEnqueuedInvokedInstanceMethods(Enqueuer enqueuer) { |
889 enqueuer.task.measure(() { | 882 enqueuer.task.measure(() { |
890 // Run through the classes and see if we need to compile methods. | 883 // Run through the classes and see if we need to compile methods. |
891 for (ClassElement classElement in enqueuer.universe.instantiatedClasses) { | 884 for (ClassElement classElement in |
| 885 enqueuer.universe.directlyInstantiatedClasses) { |
892 for (ClassElement currentClass = classElement; | 886 for (ClassElement currentClass = classElement; |
893 currentClass != null; | 887 currentClass != null; |
894 currentClass = currentClass.superclass) { | 888 currentClass = currentClass.superclass) { |
895 enqueuer.processInstantiatedClass(currentClass); | 889 enqueuer.processInstantiatedClassMembers(currentClass); |
896 } | 890 } |
897 } | 891 } |
898 }); | 892 }); |
899 return true; | 893 return true; |
900 } | 894 } |
901 | 895 |
902 void processWorkItem(void f(WorkItem work), WorkItem work) { | 896 void processWorkItem(void f(WorkItem work), WorkItem work) { |
903 f(work); | 897 f(work); |
904 } | 898 } |
905 } | 899 } |
906 | 900 |
907 void removeFromSet(Map<String, Set<Element>> map, Element element) { | 901 void removeFromSet(Map<String, Set<Element>> map, Element element) { |
908 Set<Element> set = map[element.name]; | 902 Set<Element> set = map[element.name]; |
909 if (set == null) return; | 903 if (set == null) return; |
910 set.remove(element); | 904 set.remove(element); |
911 } | 905 } |
OLD | NEW |