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

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

Issue 1385183002: Revert "Avoid eager enqueueing from resolution" (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 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.enqueue; 5 library dart2js.enqueue;
6 6
7 import 'dart:collection' show 7 import 'dart:collection' show
8 Queue; 8 Queue;
9 9
10 import 'common/names.dart' show 10 import 'common/names.dart' show
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 105
106 // TODO(johnniwinther): Split this into more precise subsets. 106 // TODO(johnniwinther): Split this into more precise subsets.
107 Iterable<Element> get staticUses => const <Element>[]; 107 Iterable<Element> get staticUses => const <Element>[];
108 108
109 // TODO(johnniwinther): Replace this by called constructors with type 109 // TODO(johnniwinther): Replace this by called constructors with type
110 // arguments. 110 // arguments.
111 Iterable<InterfaceType> get instantiatedTypes => const <InterfaceType>[]; 111 Iterable<InterfaceType> get instantiatedTypes => const <InterfaceType>[];
112 112
113 // TODO(johnniwinther): Collect checked types for checked mode separately to 113 // TODO(johnniwinther): Collect checked types for checked mode separately to
114 // support serialization. 114 // support serialization.
115 Iterable<DartType> get isChecks => const <DartType>[]; 115 Iterable<DartType> get checkedTypes => const <DartType>[];
116
117 Iterable<DartType> get checkedModeChecks => const <DartType>[];
118
119 Iterable<DartType> get asCasts => const <DartType>[];
120 116
121 Iterable<MethodElement> get closurizedFunctions => const <MethodElement>[]; 117 Iterable<MethodElement> get closurizedFunctions => const <MethodElement>[];
122
123 Iterable<LocalFunctionElement> get closures => const <LocalFunctionElement>[];
124 } 118 }
125 119
126 abstract class Enqueuer { 120 abstract class Enqueuer {
127 final String name; 121 final String name;
128 final Compiler compiler; // TODO(ahe): Remove this dependency. 122 final Compiler compiler; // TODO(ahe): Remove this dependency.
129 final EnqueuerStrategy strategy; 123 final EnqueuerStrategy strategy;
130 final ItemCompilationContextCreator itemCompilationContextCreator; 124 final ItemCompilationContextCreator itemCompilationContextCreator;
131 final Map<String, Set<Element>> instanceMembersByName 125 final Map<String, Set<Element>> instanceMembersByName
132 = new Map<String, Set<Element>>(); 126 = new Map<String, Set<Element>>();
133 final Map<String, Set<Element>> instanceFunctionsByName 127 final Map<String, Set<Element>> instanceFunctionsByName
(...skipping 26 matching lines...) Expand all
160 /// Returns [:true:] if this enqueuer is the resolution enqueuer. 154 /// Returns [:true:] if this enqueuer is the resolution enqueuer.
161 bool get isResolutionQueue => false; 155 bool get isResolutionQueue => false;
162 156
163 QueueFilter get filter => compiler.enqueuerFilter; 157 QueueFilter get filter => compiler.enqueuerFilter;
164 158
165 DiagnosticReporter get reporter => compiler.reporter; 159 DiagnosticReporter get reporter => compiler.reporter;
166 160
167 /// Returns [:true:] if [member] has been processed by this enqueuer. 161 /// Returns [:true:] if [member] has been processed by this enqueuer.
168 bool isProcessed(Element member); 162 bool isProcessed(Element member);
169 163
170 bool isClassProcessed(ClassElement cls) => _processedClasses.contains(cls);
171
172 Iterable<ClassElement> get processedClasses => _processedClasses;
173
174 /** 164 /**
175 * Documentation wanted -- johnniwinther 165 * Documentation wanted -- johnniwinther
176 * 166 *
177 * Invariant: [element] must be a declaration element. 167 * Invariant: [element] must be a declaration element.
178 */ 168 */
179 void addToWorkList(Element element) { 169 void addToWorkList(Element element) {
180 assert(invariant(element, element.isDeclaration)); 170 assert(invariant(element, element.isDeclaration));
181 if (internalAddToWorkList(element) && compiler.dumpInfo) { 171 if (internalAddToWorkList(element) && compiler.dumpInfo) {
182 // TODO(sigmund): add other missing dependencies (internals, selectors 172 // TODO(sigmund): add other missing dependencies (internals, selectors
183 // enqueued after allocations), also enable only for the codegen enqueuer. 173 // enqueued after allocations), also enable only for the codegen enqueuer.
184 compiler.dumpInfoTask.registerDependency( 174 compiler.dumpInfoTask.registerDependency(
185 compiler.currentElement, element); 175 compiler.currentElement, element);
186 } 176 }
187 } 177 }
188 178
189 /** 179 /**
190 * Adds [element] to the work list if it has not already been processed. 180 * Adds [element] to the work list if it has not already been processed.
191 * 181 *
192 * Returns [true] if the element was actually added to the queue. 182 * Returns [true] if the element was actually added to the queue.
193 */ 183 */
194 bool internalAddToWorkList(Element element); 184 bool internalAddToWorkList(Element element);
195 185
196 /// Apply the [worldImpact] of processing [element] to this enqueuer. 186 /// Apply the [worldImpact] of processing [element] to this enqueuer.
197 void applyImpact(Element element, WorldImpact worldImpact) { 187 void applyImpact(Element element, WorldImpact worldImpact) {
198 // TODO(johnniwinther): Optimize the application of the world impact. 188 // TODO(johnniwinther): Optimize the application of the world impact.
199 worldImpact.dynamicInvocations.forEach(registerDynamicInvocation); 189 worldImpact.dynamicInvocations.forEach(registerDynamicInvocation);
200 worldImpact.dynamicGetters.forEach(registerDynamicGetter); 190 worldImpact.dynamicGetters.forEach(registerDynamicGetter);
201 worldImpact.dynamicSetters.forEach(registerDynamicSetter); 191 worldImpact.dynamicSetters.forEach(registerDynamicSetter);
202 worldImpact.staticUses.forEach(registerStaticUse); 192 worldImpact.staticUses.forEach(registerStaticUse);
203 worldImpact.instantiatedTypes.forEach(registerInstantiatedType); 193 // TODO(johnniwinther): Register [worldImpact.instantiatedTypes] when it
204 worldImpact.isChecks.forEach(registerIsCheck); 194 // doesn't require a [Registry].
205 worldImpact.asCasts.forEach(registerIsCheck); 195 worldImpact.checkedTypes.forEach(registerIsCheck);
206 if (compiler.enableTypeAssertions) {
207 worldImpact.checkedModeChecks.forEach(registerIsCheck);
208 }
209 worldImpact.closurizedFunctions.forEach(registerGetOfStaticFunction); 196 worldImpact.closurizedFunctions.forEach(registerGetOfStaticFunction);
210 worldImpact.closures.forEach(registerClosure);
211 } 197 }
212 198
213 // TODO(johnniwinther): Remove the need for passing the [registry]. 199 // TODO(johnniwinther): Remove the need for passing the [registry].
214 void registerInstantiatedType(InterfaceType type, 200 void registerInstantiatedType(InterfaceType type,
215 {bool mirrorUsage: false}) { 201 {bool mirrorUsage: false}) {
216 task.measure(() { 202 task.measure(() {
217 ClassElement cls = type.element; 203 ClassElement cls = type.element;
218 cls.ensureResolved(resolution); 204 cls.ensureResolved(resolution);
219 universe.registerTypeInstantiation( 205 universe.registerTypeInstantiation(
220 type, 206 type,
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 327
342 void processInstantiatedClass(ClassElement cls) { 328 void processInstantiatedClass(ClassElement cls) {
343 task.measure(() { 329 task.measure(() {
344 if (_processedClasses.contains(cls)) return; 330 if (_processedClasses.contains(cls)) return;
345 // The class must be resolved to compute the set of all 331 // The class must be resolved to compute the set of all
346 // supertypes. 332 // supertypes.
347 cls.ensureResolved(resolution); 333 cls.ensureResolved(resolution);
348 334
349 void processClass(ClassElement superclass) { 335 void processClass(ClassElement superclass) {
350 if (_processedClasses.contains(superclass)) return; 336 if (_processedClasses.contains(superclass)) return;
351 // TODO(johnniwinther): Re-insert this invariant when unittests don't
352 // fail. There is already a similar invariant on the members.
353 /*if (!isResolutionQueue) {
354 assert(invariant(superclass,
355 superclass.isClosure ||
356 compiler.enqueuer.resolution.isClassProcessed(superclass),
357 message: "Class $superclass has not been "
358 "processed in resolution."));
359 }*/
360 337
361 _processedClasses.add(superclass); 338 _processedClasses.add(superclass);
362 recentClasses.add(superclass); 339 recentClasses.add(superclass);
363 superclass.ensureResolved(resolution); 340 superclass.ensureResolved(resolution);
364 superclass.implementation.forEachMember(processInstantiatedClassMember); 341 superclass.implementation.forEachMember(processInstantiatedClassMember);
365 if (isResolutionQueue && !superclass.isSynthesized) { 342 if (isResolutionQueue && !superclass.isSynthesized) {
366 compiler.resolver.checkClass(superclass); 343 compiler.resolver.checkClass(superclass);
367 } 344 }
368 // We only tell the backend once that [superclass] was instantiated, so 345 // We only tell the backend once that [superclass] was instantiated, so
369 // any additional dependencies must be treated as global 346 // any additional dependencies must be treated as global
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 } 760 }
784 761
785 /// [Enqueuer] which is specific to resolution. 762 /// [Enqueuer] which is specific to resolution.
786 class ResolutionEnqueuer extends Enqueuer { 763 class ResolutionEnqueuer extends Enqueuer {
787 /** 764 /**
788 * Map from declaration elements to the [TreeElements] object holding the 765 * Map from declaration elements to the [TreeElements] object holding the
789 * resolution mapping for the element implementation. 766 * resolution mapping for the element implementation.
790 * 767 *
791 * Invariant: Key elements are declaration elements. 768 * Invariant: Key elements are declaration elements.
792 */ 769 */
793 final Set<AstElement> processedElements; 770 final Set<AstElement> resolvedElements;
794 771
795 final Queue<ResolutionWorkItem> queue; 772 final Queue<ResolutionWorkItem> queue;
796 773
797 /** 774 /**
798 * A deferred task queue for the resolution phase which is processed 775 * A deferred task queue for the resolution phase which is processed
799 * when the resolution queue has been emptied. 776 * when the resolution queue has been emptied.
800 */ 777 */
801 final Queue<DeferredTask> deferredTaskQueue; 778 final Queue<DeferredTask> deferredTaskQueue;
802 779
803 ResolutionEnqueuer(Compiler compiler, 780 ResolutionEnqueuer(Compiler compiler,
804 ItemCompilationContext itemCompilationContextCreator(), 781 ItemCompilationContext itemCompilationContextCreator(),
805 EnqueuerStrategy strategy) 782 EnqueuerStrategy strategy)
806 : super('resolution enqueuer', 783 : super('resolution enqueuer',
807 compiler, 784 compiler,
808 itemCompilationContextCreator, 785 itemCompilationContextCreator,
809 strategy), 786 strategy),
810 processedElements = new Set<AstElement>(), 787 resolvedElements = new Set<AstElement>(),
811 queue = new Queue<ResolutionWorkItem>(), 788 queue = new Queue<ResolutionWorkItem>(),
812 deferredTaskQueue = new Queue<DeferredTask>(); 789 deferredTaskQueue = new Queue<DeferredTask>();
813 790
814 bool get isResolutionQueue => true; 791 bool get isResolutionQueue => true;
815 792
816 bool isProcessed(Element member) => processedElements.contains(member); 793 bool isProcessed(Element member) => resolvedElements.contains(member);
817 794
818 /// Returns `true` if [element] has been processed by the resolution enqueuer. 795 /// Returns `true` if [element] has been processed by the resolution enqueuer.
819 bool hasBeenProcessed(Element element) { 796 bool hasBeenResolved(Element element) {
820 return processedElements.contains(element.analyzableElement.declaration); 797 return resolvedElements.contains(element.analyzableElement.declaration);
821 } 798 }
822 799
823 /// Registers [element] as processed by the resolution enqueuer. 800 /// Registers [element] as resolved for the resolution enqueuer.
824 void registerProcessedElement(AstElement element) { 801 void registerResolvedElement(AstElement element) {
825 processedElements.add(element); 802 resolvedElements.add(element);
826 } 803 }
827 804
828 /** 805 /**
829 * Decides whether an element should be included to satisfy requirements 806 * Decides whether an element should be included to satisfy requirements
830 * of the mirror system. 807 * of the mirror system.
831 * 808 *
832 * During resolution, we have to resort to matching elements against the 809 * During resolution, we have to resort to matching elements against the
833 * [MirrorsUsed] pattern, as we do not have a complete picture of the world, 810 * [MirrorsUsed] pattern, as we do not have a complete picture of the world,
834 * yet. 811 * yet.
835 */ 812 */
836 bool shouldIncludeElementDueToMirrors(Element element, 813 bool shouldIncludeElementDueToMirrors(Element element,
837 {bool includedEnclosing}) { 814 {bool includedEnclosing}) {
838 return includedEnclosing || compiler.backend.requiredByMirrorSystem(element) ; 815 return includedEnclosing || compiler.backend.requiredByMirrorSystem(element) ;
839 } 816 }
840 817
841 bool internalAddToWorkList(Element element) { 818 bool internalAddToWorkList(Element element) {
842 if (element.isErroneous) return false; 819 if (element.isErroneous) return false;
843 820
844 assert(invariant(element, element is AnalyzableElement, 821 assert(invariant(element, element is AnalyzableElement,
845 message: 'Element $element is not analyzable.')); 822 message: 'Element $element is not analyzable.'));
846 if (hasBeenProcessed(element)) return false; 823 if (hasBeenResolved(element)) return false;
847 if (queueIsClosed) { 824 if (queueIsClosed) {
848 throw new SpannableAssertionFailure(element, 825 throw new SpannableAssertionFailure(element,
849 "Resolution work list is closed. Trying to add $element."); 826 "Resolution work list is closed. Trying to add $element.");
850 } 827 }
851 828
852 compiler.world.registerUsedElement(element); 829 compiler.world.registerUsedElement(element);
853 830
854 ResolutionWorkItem workItem; 831 ResolutionWorkItem workItem;
855 if (compiler.serialization.isDeserialized(element)) { 832 if (compiler.serialization.isDeserialized(element)) {
856 workItem = compiler.serialization.createResolutionWorkItem( 833 workItem = compiler.serialization.createResolutionWorkItem(
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 } 905 }
929 906
930 void emptyDeferredTaskQueue() { 907 void emptyDeferredTaskQueue() {
931 while (!deferredTaskQueue.isEmpty) { 908 while (!deferredTaskQueue.isEmpty) {
932 DeferredTask task = deferredTaskQueue.removeFirst(); 909 DeferredTask task = deferredTaskQueue.removeFirst();
933 reporter.withCurrentElement(task.element, task.action); 910 reporter.withCurrentElement(task.element, task.action);
934 } 911 }
935 } 912 }
936 913
937 void _logSpecificSummary(log(message)) { 914 void _logSpecificSummary(log(message)) {
938 log('Resolved ${processedElements.length} elements.'); 915 log('Resolved ${resolvedElements.length} elements.');
939 } 916 }
940 917
941 void forgetElement(Element element) { 918 void forgetElement(Element element) {
942 super.forgetElement(element); 919 super.forgetElement(element);
943 processedElements.remove(element); 920 resolvedElements.remove(element);
944 } 921 }
945 } 922 }
946 923
947 /// [Enqueuer] which is specific to code generation. 924 /// [Enqueuer] which is specific to code generation.
948 class CodegenEnqueuer extends Enqueuer { 925 class CodegenEnqueuer extends Enqueuer {
949 final Queue<CodegenWorkItem> queue; 926 final Queue<CodegenWorkItem> queue;
950 final Map<Element, js.Expression> generatedCode = 927 final Map<Element, js.Expression> generatedCode =
951 new Map<Element, js.Expression>(); 928 new Map<Element, js.Expression>();
952 929
953 final Set<Element> newlyEnqueuedElements; 930 final Set<Element> newlyEnqueuedElements;
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1092 @override 1069 @override
1093 void processStaticUse(Enqueuer enqueuer, Element element) { 1070 void processStaticUse(Enqueuer enqueuer, Element element) {
1094 enqueuer.registerStaticUseInternal(element); 1071 enqueuer.registerStaticUseInternal(element);
1095 } 1072 }
1096 1073
1097 @override 1074 @override
1098 void processSelector(Enqueuer enqueuer, UniverseSelector selector) { 1075 void processSelector(Enqueuer enqueuer, UniverseSelector selector) {
1099 enqueuer.handleUnseenSelectorInternal(selector); 1076 enqueuer.handleUnseenSelectorInternal(selector);
1100 } 1077 }
1101 } 1078 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/elements/modelx.dart ('k') | pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698