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

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

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