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

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

Issue 2488353004: Remove Compiler access from ResolutionEnqueuer (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
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 'cache_strategy.dart';
10 import 'common/backend_api.dart' show Backend;
9 import 'common/names.dart' show Identifiers; 11 import 'common/names.dart' show Identifiers;
10 import 'common/resolution.dart' show Resolution; 12 import 'common/resolution.dart' show Resolution, ResolutionWorkItem;
11 import 'common/resolution.dart' show ResolutionWorkItem; 13 import 'common/registry.dart' show Registry;
12 import 'common/tasks.dart' show CompilerTask; 14 import 'common/tasks.dart' show CompilerTask;
13 import 'common/work.dart' show WorkItem; 15 import 'common/work.dart' show WorkItem;
14 import 'common.dart'; 16 import 'common.dart';
15 import 'compiler.dart' show Compiler; 17 import 'compiler.dart' show Compiler, GlobalDependencyRegistry;
18 import 'core_types.dart' show CommonElements;
19 import 'options.dart';
16 import 'dart_types.dart' show DartType, InterfaceType; 20 import 'dart_types.dart' show DartType, InterfaceType;
17 import 'elements/elements.dart' 21 import 'elements/elements.dart'
18 show 22 show
19 AnalyzableElement, 23 AnalyzableElement,
20 AstElement, 24 AstElement,
21 ClassElement, 25 ClassElement,
22 Element, 26 Element,
23 Entity, 27 Entity,
24 FunctionElement, 28 FunctionElement,
25 LibraryElement, 29 LibraryElement,
26 LocalFunctionElement, 30 LocalFunctionElement,
27 TypedElement; 31 TypedElement;
28 import 'native/native.dart' as native; 32 import 'native/native.dart' as native;
29 import 'types/types.dart' show TypeMaskStrategy; 33 import 'types/types.dart' show TypeMaskStrategy;
30 import 'universe/selector.dart' show Selector; 34 import 'universe/selector.dart' show Selector;
31 import 'universe/world_builder.dart'; 35 import 'universe/world_builder.dart';
32 import 'universe/use.dart' 36 import 'universe/use.dart'
33 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind; 37 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind;
34 import 'universe/world_impact.dart' 38 import 'universe/world_impact.dart'
35 show ImpactUseCase, WorldImpact, WorldImpactVisitor; 39 show ImpactStrategy, ImpactUseCase, WorldImpact, WorldImpactVisitor;
36 import 'util/util.dart' show Setlet; 40 import 'util/util.dart' show Setlet;
41 import 'world.dart' show OpenWorld;
37 42
38 class EnqueueTask extends CompilerTask { 43 class EnqueueTask extends CompilerTask {
39 final ResolutionEnqueuer resolution; 44 ResolutionEnqueuer _resolution;
40 final Enqueuer codegen; 45 Enqueuer _codegen;
41 final Compiler compiler; 46 final Compiler compiler;
42 47
43 String get name => 'Enqueue'; 48 String get name => 'Enqueue';
44 49
45 EnqueueTask(Compiler compiler) 50 EnqueueTask(Compiler compiler)
46 : compiler = compiler, 51 : this.compiler = compiler,
47 resolution = new ResolutionEnqueuer(
48 compiler,
49 compiler.options.analyzeOnly && compiler.options.analyzeMain
50 ? const EnqueuerStrategy()
51 : const TreeShakingEnqueuerStrategy()),
52 codegen = compiler.backend.createCodegenEnqueuer(compiler),
53 super(compiler.measurer) { 52 super(compiler.measurer) {
54 codegen.task = this; 53 _resolution = new ResolutionEnqueuer(
55 resolution.task = this; 54 this,
56 55 compiler.options,
57 codegen.nativeEnqueuer = compiler.backend.nativeCodegenEnqueuer(codegen); 56 compiler.resolution,
58 resolution.nativeEnqueuer = 57 compiler.enqueuerFilter,
59 compiler.backend.nativeResolutionEnqueuer(resolution); 58 compiler.options.analyzeOnly && compiler.options.analyzeMain
59 ? const EnqueuerStrategy()
60 : const TreeShakingEnqueuerStrategy(),
61 compiler.globalDependencies,
62 compiler.backend,
63 compiler.coreClasses,
64 compiler.cacheStrategy);
65 _codegen = compiler.backend.createCodegenEnqueuer(this, compiler);
60 } 66 }
61 67
68 ResolutionEnqueuer get resolution => _resolution;
69 Enqueuer get codegen => _codegen;
70
62 void forgetElement(Element element) { 71 void forgetElement(Element element) {
63 resolution.forgetElement(element); 72 resolution.forgetElement(element, compiler);
64 codegen.forgetElement(element); 73 codegen.forgetElement(element, compiler);
65 } 74 }
66 } 75 }
67 76
68 abstract class Enqueuer { 77 abstract class Enqueuer {
69 EnqueueTask task; 78 CompilerTask get task;
70 WorldBuilder get universe; 79 WorldBuilder get universe;
71 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask 80 native.NativeEnqueuer get nativeEnqueuer;
72 void forgetElement(Element element); 81 void forgetElement(Element element, Compiler compiler);
73 void processInstantiatedClassMembers(ClassElement cls); 82 void processInstantiatedClassMembers(ClassElement cls);
74 void processInstantiatedClassMember(ClassElement cls, Element member); 83 void processInstantiatedClassMember(ClassElement cls, Element member);
75 void handleUnseenSelectorInternal(DynamicUse dynamicUse); 84 void handleUnseenSelectorInternal(DynamicUse dynamicUse);
76 void registerStaticUse(StaticUse staticUse); 85 void registerStaticUse(StaticUse staticUse);
77 void registerStaticUseInternal(StaticUse staticUse); 86 void registerStaticUseInternal(StaticUse staticUse);
78 void registerDynamicUse(DynamicUse dynamicUse); 87 void registerDynamicUse(DynamicUse dynamicUse);
79 void registerTypeUse(TypeUse typeUse); 88 void registerTypeUse(TypeUse typeUse);
80 89
81 /// Returns [:true:] if this enqueuer is the resolution enqueuer. 90 /// Returns [:true:] if this enqueuer is the resolution enqueuer.
82 bool get isResolutionQueue; 91 bool get isResolutionQueue;
(...skipping 12 matching lines...) Expand all
95 void addToWorkList(Element element); 104 void addToWorkList(Element element);
96 105
97 void enableIsolateSupport(); 106 void enableIsolateSupport();
98 107
99 void registerInstantiatedType(InterfaceType type); 108 void registerInstantiatedType(InterfaceType type);
100 void forEach(void f(WorkItem work)); 109 void forEach(void f(WorkItem work));
101 110
102 /// Apply the [worldImpact] to this enqueuer. If the [impactSource] is provide d 111 /// Apply the [worldImpact] to this enqueuer. If the [impactSource] is provide d
103 /// the impact strategy will remove it from the element impact cache, if it is 112 /// the impact strategy will remove it from the element impact cache, if it is
104 /// no longer needed. 113 /// no longer needed.
105 void applyImpact(WorldImpact worldImpact, {Element impactSource}); 114 void applyImpact(ImpactStrategy impactStrategy, WorldImpact worldImpact,
115 {Element impactSource});
106 bool checkNoEnqueuedInvokedInstanceMethods(); 116 bool checkNoEnqueuedInvokedInstanceMethods();
107 void logSummary(log(message)); 117 void logSummary(log(message));
108 118
109 /// Returns [:true:] if [member] has been processed by this enqueuer. 119 /// Returns [:true:] if [member] has been processed by this enqueuer.
110 bool isProcessed(Element member); 120 bool isProcessed(Element member);
111 121
112 Iterable<Entity> get processedEntities; 122 Iterable<Entity> get processedEntities;
113 123
114 Iterable<ClassElement> get processedClasses; 124 Iterable<ClassElement> get processedClasses;
115 } 125 }
116 126
117 /// [Enqueuer] which is specific to resolution. 127 /// [Enqueuer] which is specific to resolution.
118 class ResolutionEnqueuer extends Enqueuer { 128 class ResolutionEnqueuer extends Enqueuer {
129 final CompilerTask task;
119 final String name; 130 final String name;
120 final Compiler compiler; // TODO(ahe): Remove this dependency. 131 final Resolution resolution;
132 final QueueFilter filter;
133 final CompilerOptions options;
134 final Backend backend;
135 final GlobalDependencyRegistry globalDependencies;
136 final CommonElements commonElements;
137 final native.NativeEnqueuer nativeEnqueuer;
138
121 final EnqueuerStrategy strategy; 139 final EnqueuerStrategy strategy;
122 final Map<String, Set<Element>> instanceMembersByName = 140 final Map<String, Set<Element>> instanceMembersByName =
123 new Map<String, Set<Element>>(); 141 new Map<String, Set<Element>>();
124 final Map<String, Set<Element>> instanceFunctionsByName = 142 final Map<String, Set<Element>> instanceFunctionsByName =
125 new Map<String, Set<Element>>(); 143 new Map<String, Set<Element>>();
126 final Set<ClassElement> _processedClasses = new Set<ClassElement>(); 144 final Set<ClassElement> _processedClasses = new Set<ClassElement>();
127 Set<ClassElement> recentClasses = new Setlet<ClassElement>(); 145 Set<ClassElement> recentClasses = new Setlet<ClassElement>();
128 final ResolutionWorldBuilderImpl _universe = 146 final ResolutionWorldBuilderImpl _universe;
129 new ResolutionWorldBuilderImpl(const TypeMaskStrategy());
130
131 147
132 bool queueIsClosed = false; 148 bool queueIsClosed = false;
133 149
134 WorldImpactVisitor impactVisitor; 150 WorldImpactVisitor impactVisitor;
135 151
136 ResolutionEnqueuer(Compiler compiler, this.strategy) 152 ImpactStrategy impactStrategy;
153
154 ResolutionEnqueuer(
155 this.task,
156 this.options,
157 this.resolution,
158 this.filter,
159 this.strategy,
160 this.globalDependencies,
161 Backend backend,
162 CommonElements commonElements,
163 CacheStrategy cacheStrategy)
137 : this.name = 'resolution enqueuer', 164 : this.name = 'resolution enqueuer',
138 this.compiler = compiler, 165 this.backend = backend,
166 this.commonElements = commonElements,
167 this.nativeEnqueuer = backend.nativeResolutionEnqueuer(),
139 processedElements = new Set<AstElement>(), 168 processedElements = new Set<AstElement>(),
140 queue = new Queue<ResolutionWorkItem>(), 169 queue = new Queue<ResolutionWorkItem>(),
141 deferredQueue = new Queue<_DeferredAction>() { 170 deferredQueue = new Queue<_DeferredAction>(),
171 _universe = new ResolutionWorldBuilderImpl(
172 backend, commonElements, cacheStrategy, const TypeMaskStrategy()) {
142 impactVisitor = new _EnqueuerImpactVisitor(this); 173 impactVisitor = new _EnqueuerImpactVisitor(this);
143 } 174 }
144 175
145 Resolution get resolution => compiler.resolution; 176 ResolutionWorldBuilder get universe => _universe;
146 177
147 ResolutionWorldBuilder get universe => _universe; 178 OpenWorld get openWorld => universe.openWorld;
148 179
149 bool get queueIsEmpty => queue.isEmpty; 180 bool get queueIsEmpty => queue.isEmpty;
150 181
151 QueueFilter get filter => compiler.enqueuerFilter; 182 DiagnosticReporter get reporter => resolution.reporter;
152
153 DiagnosticReporter get reporter => compiler.reporter;
154 183
155 bool isClassProcessed(ClassElement cls) => _processedClasses.contains(cls); 184 bool isClassProcessed(ClassElement cls) => _processedClasses.contains(cls);
156 185
157 Iterable<ClassElement> get processedClasses => _processedClasses; 186 Iterable<ClassElement> get processedClasses => _processedClasses;
158 187
159 /** 188 /**
160 * Documentation wanted -- johnniwinther 189 * Documentation wanted -- johnniwinther
161 * 190 *
162 * Invariant: [element] must be a declaration element. 191 * Invariant: [element] must be a declaration element.
163 */ 192 */
164 void addToWorkList(Element element) { 193 void addToWorkList(Element element) {
165 assert(invariant(element, element.isDeclaration)); 194 assert(invariant(element, element.isDeclaration));
166 if (internalAddToWorkList(element) && compiler.options.dumpInfo) { 195 internalAddToWorkList(element);
167 // TODO(sigmund): add other missing dependencies (internals, selectors 196 }
168 // enqueued after allocations), also enable only for the codegen enqueuer. 197
169 compiler.dumpInfoTask 198 void applyImpact(ImpactStrategy impactStrategy, WorldImpact worldImpact,
170 .registerDependency(compiler.currentElement, element); 199 {Element impactSource}) {
171 } 200 impactStrategy.visitImpact(
201 impactSource, worldImpact, impactVisitor, impactUse);
172 } 202 }
173 203
174 void registerInstantiatedType(InterfaceType type) { 204 void registerInstantiatedType(InterfaceType type) {
175 _registerInstantiatedType(type, globalDependency: true); 205 _registerInstantiatedType(type, globalDependency: true);
176 } 206 }
177 207
178 void applyImpact(WorldImpact worldImpact, {Element impactSource}) {
179 compiler.impactStrategy
180 .visitImpact(impactSource, worldImpact, impactVisitor, impactUse);
181 }
182
183 void _registerInstantiatedType(InterfaceType type, 208 void _registerInstantiatedType(InterfaceType type,
184 {bool mirrorUsage: false, 209 {bool mirrorUsage: false,
185 bool nativeUsage: false, 210 bool nativeUsage: false,
186 bool globalDependency: false}) { 211 bool globalDependency: false}) {
187 task.measure(() { 212 task.measure(() {
188 ClassElement cls = type.element; 213 ClassElement cls = type.element;
189 cls.ensureResolved(resolution); 214 cls.ensureResolved(resolution);
190 bool isNative = compiler.backend.isNative(cls); 215 bool isNative = backend.isNative(cls);
191 _universe.registerTypeInstantiation(type, 216 _universe.registerTypeInstantiation(type,
192 isNative: isNative, 217 isNative: isNative,
193 byMirrors: mirrorUsage, onImplemented: (ClassElement cls) { 218 byMirrors: mirrorUsage, onImplemented: (ClassElement cls) {
194 compiler.backend.registerImplementedClass(cls, this); 219 backend.registerImplementedClass(cls, this);
195 }); 220 });
196 if (globalDependency && !mirrorUsage) { 221 if (globalDependency && !mirrorUsage) {
197 compiler.globalDependencies.registerDependency(type.element); 222 globalDependencies.registerDependency(type.element);
198 } 223 }
199 if (nativeUsage) { 224 if (nativeUsage) {
200 nativeEnqueuer.onInstantiatedType(type); 225 nativeEnqueuer.onInstantiatedType(type);
201 } 226 }
202 compiler.backend.registerInstantiatedType(type); 227 backend.registerInstantiatedType(type);
203 // TODO(johnniwinther): Share this reasoning with [Universe]. 228 // TODO(johnniwinther): Share this reasoning with [Universe].
204 if (!cls.isAbstract || isNative || mirrorUsage) { 229 if (!cls.isAbstract || isNative || mirrorUsage) {
205 processInstantiatedClass(cls); 230 processInstantiatedClass(cls);
206 } 231 }
207 }); 232 });
208 } 233 }
209 234
210 bool checkNoEnqueuedInvokedInstanceMethods() { 235 bool checkNoEnqueuedInvokedInstanceMethods() {
211 return filter.checkNoEnqueuedInvokedInstanceMethods(this); 236 return filter.checkNoEnqueuedInvokedInstanceMethods(this);
212 } 237 }
213 238
214 void processInstantiatedClassMembers(ClassElement cls) { 239 void processInstantiatedClassMembers(ClassElement cls) {
215 strategy.processInstantiatedClass(this, cls); 240 strategy.processInstantiatedClass(this, cls);
216 } 241 }
217 242
218 void processInstantiatedClassMember(ClassElement cls, Element member) { 243 void processInstantiatedClassMember(ClassElement cls, Element member) {
219 assert(invariant(member, member.isDeclaration)); 244 assert(invariant(member, member.isDeclaration));
220 if (isProcessed(member)) return; 245 if (isProcessed(member)) return;
221 if (!member.isInstanceMember) return; 246 if (!member.isInstanceMember) return;
222 String memberName = member.name; 247 String memberName = member.name;
223 248
224 if (member.isField) { 249 if (member.isField) {
225 // The obvious thing to test here would be "member.isNative", 250 // The obvious thing to test here would be "member.isNative",
226 // however, that only works after metadata has been parsed/analyzed, 251 // however, that only works after metadata has been parsed/analyzed,
227 // and that may not have happened yet. 252 // and that may not have happened yet.
228 // So instead we use the enclosing class, which we know have had 253 // So instead we use the enclosing class, which we know have had
229 // its metadata parsed and analyzed. 254 // its metadata parsed and analyzed.
230 // Note: this assumes that there are no non-native fields on native 255 // Note: this assumes that there are no non-native fields on native
231 // classes, which may not be the case when a native class is subclassed. 256 // classes, which may not be the case when a native class is subclassed.
232 if (compiler.backend.isNative(cls)) { 257 if (backend.isNative(cls)) {
233 compiler.openWorld.registerUsedElement(member); 258 openWorld.registerUsedElement(member);
234 if (_universe.hasInvokedGetter(member, compiler.openWorld) || 259 if (_universe.hasInvokedGetter(member, openWorld) ||
235 _universe.hasInvocation(member, compiler.openWorld)) { 260 _universe.hasInvocation(member, openWorld)) {
236 addToWorkList(member); 261 addToWorkList(member);
237 return; 262 return;
238 } 263 }
239 if (_universe.hasInvokedSetter(member, compiler.openWorld)) { 264 if (_universe.hasInvokedSetter(member, openWorld)) {
240 addToWorkList(member); 265 addToWorkList(member);
241 return; 266 return;
242 } 267 }
243 // Native fields need to go into instanceMembersByName as they 268 // Native fields need to go into instanceMembersByName as they
244 // are virtual instantiation points and escape points. 269 // are virtual instantiation points and escape points.
245 } else { 270 } else {
246 // All field initializers must be resolved as they could 271 // All field initializers must be resolved as they could
247 // have an observable side-effect (and cannot be tree-shaken 272 // have an observable side-effect (and cannot be tree-shaken
248 // away). 273 // away).
249 addToWorkList(member); 274 addToWorkList(member);
250 return; 275 return;
251 } 276 }
252 } else if (member.isFunction) { 277 } else if (member.isFunction) {
253 FunctionElement function = member; 278 FunctionElement function = member;
254 function.computeType(resolution); 279 function.computeType(resolution);
255 if (function.name == Identifiers.noSuchMethod_) { 280 if (function.name == Identifiers.noSuchMethod_) {
256 registerNoSuchMethod(function); 281 registerNoSuchMethod(function);
257 } 282 }
258 if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) { 283 if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) {
259 registerCallMethodWithFreeTypeVariables(function); 284 registerCallMethodWithFreeTypeVariables(function);
260 } 285 }
261 // If there is a property access with the same name as a method we 286 // If there is a property access with the same name as a method we
262 // need to emit the method. 287 // need to emit the method.
263 if (_universe.hasInvokedGetter(function, compiler.openWorld)) { 288 if (_universe.hasInvokedGetter(function, openWorld)) {
264 registerClosurizedMember(function); 289 registerClosurizedMember(function);
265 addToWorkList(function); 290 addToWorkList(function);
266 return; 291 return;
267 } 292 }
268 // Store the member in [instanceFunctionsByName] to catch 293 // Store the member in [instanceFunctionsByName] to catch
269 // getters on the function. 294 // getters on the function.
270 instanceFunctionsByName 295 instanceFunctionsByName
271 .putIfAbsent(memberName, () => new Set<Element>()) 296 .putIfAbsent(memberName, () => new Set<Element>())
272 .add(member); 297 .add(member);
273 if (_universe.hasInvocation(function, compiler.openWorld)) { 298 if (_universe.hasInvocation(function, openWorld)) {
274 addToWorkList(function); 299 addToWorkList(function);
275 return; 300 return;
276 } 301 }
277 } else if (member.isGetter) { 302 } else if (member.isGetter) {
278 FunctionElement getter = member; 303 FunctionElement getter = member;
279 getter.computeType(resolution); 304 getter.computeType(resolution);
280 if (_universe.hasInvokedGetter(getter, compiler.openWorld)) { 305 if (_universe.hasInvokedGetter(getter, openWorld)) {
281 addToWorkList(getter); 306 addToWorkList(getter);
282 return; 307 return;
283 } 308 }
284 // We don't know what selectors the returned closure accepts. If 309 // We don't know what selectors the returned closure accepts. If
285 // the set contains any selector we have to assume that it matches. 310 // the set contains any selector we have to assume that it matches.
286 if (_universe.hasInvocation(getter, compiler.openWorld)) { 311 if (_universe.hasInvocation(getter, openWorld)) {
287 addToWorkList(getter); 312 addToWorkList(getter);
288 return; 313 return;
289 } 314 }
290 } else if (member.isSetter) { 315 } else if (member.isSetter) {
291 FunctionElement setter = member; 316 FunctionElement setter = member;
292 setter.computeType(resolution); 317 setter.computeType(resolution);
293 if (_universe.hasInvokedSetter(setter, compiler.openWorld)) { 318 if (_universe.hasInvokedSetter(setter, openWorld)) {
294 addToWorkList(setter); 319 addToWorkList(setter);
295 return; 320 return;
296 } 321 }
297 } 322 }
298 323
299 // The element is not yet used. Add it to the list of instance 324 // The element is not yet used. Add it to the list of instance
300 // members to still be processed. 325 // members to still be processed.
301 instanceMembersByName 326 instanceMembersByName
302 .putIfAbsent(memberName, () => new Set<Element>()) 327 .putIfAbsent(memberName, () => new Set<Element>())
303 .add(member); 328 .add(member);
304 } 329 }
305 330
306 void processInstantiatedClass(ClassElement cls) { 331 void processInstantiatedClass(ClassElement cls) {
307 task.measure(() { 332 task.measure(() {
308 if (_processedClasses.contains(cls)) return; 333 if (_processedClasses.contains(cls)) return;
309 // The class must be resolved to compute the set of all 334 // The class must be resolved to compute the set of all
310 // supertypes. 335 // supertypes.
311 cls.ensureResolved(resolution); 336 cls.ensureResolved(resolution);
312 337
313 void processClass(ClassElement superclass) { 338 void processClass(ClassElement superclass) {
314 if (_processedClasses.contains(superclass)) return; 339 if (_processedClasses.contains(superclass)) return;
315 340
316 _processedClasses.add(superclass); 341 _processedClasses.add(superclass);
317 recentClasses.add(superclass); 342 recentClasses.add(superclass);
318 superclass.ensureResolved(resolution); 343 superclass.ensureResolved(resolution);
319 superclass.implementation.forEachMember(processInstantiatedClassMember); 344 superclass.implementation.forEachMember(processInstantiatedClassMember);
320 if (!compiler.serialization.isDeserialized(superclass)) { 345 resolution.ensureClassMembers(superclass);
321 compiler.resolver.checkClass(superclass);
322 }
323 // We only tell the backend once that [superclass] was instantiated, so 346 // We only tell the backend once that [superclass] was instantiated, so
324 // any additional dependencies must be treated as global 347 // any additional dependencies must be treated as global
325 // dependencies. 348 // dependencies.
326 compiler.backend.registerInstantiatedClass(superclass, this); 349 backend.registerInstantiatedClass(superclass, this);
327 } 350 }
328 351
329 ClassElement superclass = cls; 352 ClassElement superclass = cls;
330 while (superclass != null) { 353 while (superclass != null) {
331 processClass(superclass); 354 processClass(superclass);
332 superclass = superclass.superclass; 355 superclass = superclass.superclass;
333 } 356 }
334 }); 357 });
335 } 358 }
336 359
(...skipping 29 matching lines...) Expand all
366 } 389 }
367 390
368 void handleUnseenSelector(DynamicUse universeSelector) { 391 void handleUnseenSelector(DynamicUse universeSelector) {
369 strategy.processDynamicUse(this, universeSelector); 392 strategy.processDynamicUse(this, universeSelector);
370 } 393 }
371 394
372 void handleUnseenSelectorInternal(DynamicUse dynamicUse) { 395 void handleUnseenSelectorInternal(DynamicUse dynamicUse) {
373 Selector selector = dynamicUse.selector; 396 Selector selector = dynamicUse.selector;
374 String methodName = selector.name; 397 String methodName = selector.name;
375 processInstanceMembers(methodName, (Element member) { 398 processInstanceMembers(methodName, (Element member) {
376 if (dynamicUse.appliesUnnamed(member, compiler.openWorld)) { 399 if (dynamicUse.appliesUnnamed(member, openWorld)) {
377 if (member.isFunction && selector.isGetter) { 400 if (member.isFunction && selector.isGetter) {
378 registerClosurizedMember(member); 401 registerClosurizedMember(member);
379 } 402 }
380 addToWorkList(member); 403 addToWorkList(member);
381 return true; 404 return true;
382 } 405 }
383 return false; 406 return false;
384 }); 407 });
385 if (selector.isGetter) { 408 if (selector.isGetter) {
386 processInstanceFunctions(methodName, (Element member) { 409 processInstanceFunctions(methodName, (Element member) {
387 if (dynamicUse.appliesUnnamed(member, compiler.openWorld)) { 410 if (dynamicUse.appliesUnnamed(member, openWorld)) {
388 registerClosurizedMember(member); 411 registerClosurizedMember(member);
389 return true; 412 return true;
390 } 413 }
391 return false; 414 return false;
392 }); 415 });
393 } 416 }
394 } 417 }
395 418
396 /** 419 /**
397 * Documentation wanted -- johnniwinther 420 * Documentation wanted -- johnniwinther
398 * 421 *
399 * Invariant: [element] must be a declaration element. 422 * Invariant: [element] must be a declaration element.
400 */ 423 */
401 void registerStaticUse(StaticUse staticUse) { 424 void registerStaticUse(StaticUse staticUse) {
402 strategy.processStaticUse(this, staticUse); 425 strategy.processStaticUse(this, staticUse);
403 } 426 }
404 427
405 void registerStaticUseInternal(StaticUse staticUse) { 428 void registerStaticUseInternal(StaticUse staticUse) {
406 Element element = staticUse.element; 429 Element element = staticUse.element;
407 assert(invariant(element, element.isDeclaration, 430 assert(invariant(element, element.isDeclaration,
408 message: "Element ${element} is not the declaration.")); 431 message: "Element ${element} is not the declaration."));
409 _universe.registerStaticUse(staticUse); 432 _universe.registerStaticUse(staticUse);
410 compiler.backend.registerStaticUse(this, element); 433 backend.registerStaticUse(this, element);
411 bool addElement = true; 434 bool addElement = true;
412 switch (staticUse.kind) { 435 switch (staticUse.kind) {
413 case StaticUseKind.STATIC_TEAR_OFF: 436 case StaticUseKind.STATIC_TEAR_OFF:
414 compiler.backend.registerGetOfStaticFunction(this); 437 backend.registerGetOfStaticFunction(this);
415 break; 438 break;
416 case StaticUseKind.FIELD_GET: 439 case StaticUseKind.FIELD_GET:
417 case StaticUseKind.FIELD_SET: 440 case StaticUseKind.FIELD_SET:
418 case StaticUseKind.CLOSURE: 441 case StaticUseKind.CLOSURE:
419 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and 442 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and
420 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue. 443 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue.
421 // Also [CLOSURE] contains [LocalFunctionElement] which we cannot 444 // Also [CLOSURE] contains [LocalFunctionElement] which we cannot
422 // enqueue. 445 // enqueue.
423 LocalFunctionElement closure = staticUse.element; 446 LocalFunctionElement closure = staticUse.element;
424 if (closure.type.containsTypeVariables) { 447 if (closure.type.containsTypeVariables) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 case TypeUseKind.NATIVE_INSTANTIATION: 480 case TypeUseKind.NATIVE_INSTANTIATION:
458 _registerInstantiatedType(type, 481 _registerInstantiatedType(type,
459 nativeUsage: true, globalDependency: true); 482 nativeUsage: true, globalDependency: true);
460 break; 483 break;
461 case TypeUseKind.IS_CHECK: 484 case TypeUseKind.IS_CHECK:
462 case TypeUseKind.AS_CAST: 485 case TypeUseKind.AS_CAST:
463 case TypeUseKind.CATCH_TYPE: 486 case TypeUseKind.CATCH_TYPE:
464 _registerIsCheck(type); 487 _registerIsCheck(type);
465 break; 488 break;
466 case TypeUseKind.CHECKED_MODE_CHECK: 489 case TypeUseKind.CHECKED_MODE_CHECK:
467 if (compiler.options.enableTypeAssertions) { 490 if (options.enableTypeAssertions) {
468 _registerIsCheck(type); 491 _registerIsCheck(type);
469 } 492 }
470 break; 493 break;
471 case TypeUseKind.TYPE_LITERAL: 494 case TypeUseKind.TYPE_LITERAL:
472 break; 495 break;
473 } 496 }
474 } 497 }
475 498
476 void _registerIsCheck(DartType type) { 499 void _registerIsCheck(DartType type) {
477 type = _universe.registerIsCheck(type, compiler); 500 type = _universe.registerIsCheck(type, resolution);
478 // Even in checked mode, type annotations for return type and argument 501 // Even in checked mode, type annotations for return type and argument
479 // types do not imply type checks, so there should never be a check 502 // types do not imply type checks, so there should never be a check
480 // against the type variable of a typedef. 503 // against the type variable of a typedef.
481 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); 504 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef);
482 } 505 }
483 506
484 void registerCallMethodWithFreeTypeVariables(Element element) { 507 void registerCallMethodWithFreeTypeVariables(Element element) {
485 compiler.backend.registerCallMethodWithFreeTypeVariables(element, this); 508 backend.registerCallMethodWithFreeTypeVariables(element, this);
486 _universe.callMethodsWithFreeTypeVariables.add(element); 509 _universe.callMethodsWithFreeTypeVariables.add(element);
487 } 510 }
488 511
489 void registerClosurizedMember(TypedElement element) { 512 void registerClosurizedMember(TypedElement element) {
490 assert(element.isInstanceMember); 513 assert(element.isInstanceMember);
491 if (element.computeType(resolution).containsTypeVariables) { 514 if (element.computeType(resolution).containsTypeVariables) {
492 compiler.backend.registerClosureWithFreeTypeVariables(element, this); 515 backend.registerClosureWithFreeTypeVariables(element, this);
493 _universe.closuresWithFreeTypeVariables.add(element); 516 _universe.closuresWithFreeTypeVariables.add(element);
494 } 517 }
495 compiler.backend.registerBoundClosure(this); 518 backend.registerBoundClosure(this);
496 _universe.closurizedMembers.add(element); 519 _universe.closurizedMembers.add(element);
497 } 520 }
498 521
499 void forEach(void f(WorkItem work)) { 522 void forEach(void f(WorkItem work)) {
500 do { 523 do {
501 while (queue.isNotEmpty) { 524 while (queue.isNotEmpty) {
502 // TODO(johnniwinther): Find an optimal process order. 525 // TODO(johnniwinther): Find an optimal process order.
503 filter.processWorkItem(f, queue.removeLast()); 526 filter.processWorkItem(f, queue.removeLast());
504 } 527 }
505 List recents = recentClasses.toList(growable: false); 528 List recents = recentClasses.toList(growable: false);
(...skipping 30 matching lines...) Expand all
536 bool isProcessed(Element member) => processedElements.contains(member); 559 bool isProcessed(Element member) => processedElements.contains(member);
537 560
538 /// Returns `true` if [element] has been processed by the resolution enqueuer. 561 /// Returns `true` if [element] has been processed by the resolution enqueuer.
539 bool hasBeenProcessed(Element element) { 562 bool hasBeenProcessed(Element element) {
540 return processedElements.contains(element.analyzableElement.declaration); 563 return processedElements.contains(element.analyzableElement.declaration);
541 } 564 }
542 565
543 /// Registers [element] as processed by the resolution enqueuer. 566 /// Registers [element] as processed by the resolution enqueuer.
544 void registerProcessedElement(AstElement element) { 567 void registerProcessedElement(AstElement element) {
545 processedElements.add(element); 568 processedElements.add(element);
546 compiler.backend.onElementResolved(element); 569 backend.onElementResolved(element);
547 } 570 }
548 571
549 /** 572 /**
550 * Adds [element] to the work list if it has not already been processed. 573 * Adds [element] to the work list if it has not already been processed.
551 * 574 *
552 * Returns [true] if the element was actually added to the queue. 575 * Returns [true] if the element was actually added to the queue.
553 */ 576 */
554 bool internalAddToWorkList(Element element) { 577 bool internalAddToWorkList(Element element) {
555 if (element.isMalformed) return false; 578 if (element.isMalformed) return false;
556 579
557 assert(invariant(element, element is AnalyzableElement, 580 assert(invariant(element, element is AnalyzableElement,
558 message: 'Element $element is not analyzable.')); 581 message: 'Element $element is not analyzable.'));
559 if (hasBeenProcessed(element)) return false; 582 if (hasBeenProcessed(element)) return false;
560 if (queueIsClosed) { 583 if (queueIsClosed) {
561 throw new SpannableAssertionFailure( 584 throw new SpannableAssertionFailure(
562 element, "Resolution work list is closed. Trying to add $element."); 585 element, "Resolution work list is closed. Trying to add $element.");
563 } 586 }
564 587
565 compiler.openWorld.registerUsedElement(element); 588 openWorld.registerUsedElement(element);
566 589
567 ResolutionWorkItem workItem = compiler.resolution.createWorkItem(element); 590 ResolutionWorkItem workItem = resolution.createWorkItem(element);
568 queue.add(workItem); 591 queue.add(workItem);
569 592
570 // Enable isolate support if we start using something from the isolate 593 // Enable isolate support if we start using something from the isolate
571 // library, or timers for the async library. We exclude constant fields, 594 // library, or timers for the async library. We exclude constant fields,
572 // which are ending here because their initializing expression is compiled. 595 // which are ending here because their initializing expression is compiled.
573 LibraryElement library = element.library; 596 LibraryElement library = element.library;
574 if (!compiler.hasIsolateSupport && (!element.isField || !element.isConst)) { 597 if (!universe.hasIsolateSupport && (!element.isField || !element.isConst)) {
575 String uri = library.canonicalUri.toString(); 598 String uri = library.canonicalUri.toString();
576 if (uri == 'dart:isolate') { 599 if (uri == 'dart:isolate') {
577 enableIsolateSupport(); 600 enableIsolateSupport();
578 } else if (uri == 'dart:async') { 601 } else if (uri == 'dart:async') {
579 if (element.name == '_createTimer' || 602 if (element.name == '_createTimer' ||
580 element.name == '_createPeriodicTimer') { 603 element.name == '_createPeriodicTimer') {
581 // The [:Timer:] class uses the event queue of the isolate 604 // The [:Timer:] class uses the event queue of the isolate
582 // library, so we make sure that event queue is generated. 605 // library, so we make sure that event queue is generated.
583 enableIsolateSupport(); 606 enableIsolateSupport();
584 } 607 }
585 } 608 }
586 } 609 }
587 610
588 if (element.isGetter && element.name == Identifiers.runtimeType_) { 611 if (element.isGetter && element.name == Identifiers.runtimeType_) {
589 // Enable runtime type support if we discover a getter called runtimeType. 612 // Enable runtime type support if we discover a getter called runtimeType.
590 // We have to enable runtime type before hitting the codegen, so 613 // We have to enable runtime type before hitting the codegen, so
591 // that constructors know whether they need to generate code for 614 // that constructors know whether they need to generate code for
592 // runtime type. 615 // runtime type.
593 compiler.enabledRuntimeType = true; 616 _universe.hasRuntimeTypeSupport = true;
594 // TODO(ahe): Record precise dependency here. 617 // TODO(ahe): Record precise dependency here.
595 compiler.backend.registerRuntimeType(this); 618 backend.registerRuntimeType(this);
596 } else if (compiler.commonElements.isFunctionApplyMethod(element)) { 619 } else if (commonElements.isFunctionApplyMethod(element)) {
597 compiler.enabledFunctionApply = true; 620 _universe.hasFunctionApplySupport = true;
598 } 621 }
599 622
600 return true; 623 return true;
601 } 624 }
602 625
603 void registerNoSuchMethod(Element element) { 626 void registerNoSuchMethod(Element element) {
604 compiler.backend.registerNoSuchMethod(element); 627 backend.registerNoSuchMethod(element);
605 } 628 }
606 629
607 void enableIsolateSupport() { 630 void enableIsolateSupport() {
608 compiler.hasIsolateSupport = true; 631 _universe.hasIsolateSupport = true;
609 compiler.backend.enableIsolateSupport(this); 632 backend.enableIsolateSupport(this);
610 } 633 }
611 634
612 /** 635 /**
613 * Adds an action to the deferred task queue. 636 * Adds an action to the deferred task queue.
614 * 637 *
615 * The action is performed the next time the resolution queue has been 638 * The action is performed the next time the resolution queue has been
616 * emptied. 639 * emptied.
617 * 640 *
618 * The queue is processed in FIFO order. 641 * The queue is processed in FIFO order.
619 */ 642 */
620 void addDeferredAction(Element element, void action()) { 643 void addDeferredAction(Element element, void action()) {
621 if (queueIsClosed) { 644 if (queueIsClosed) {
622 throw new SpannableAssertionFailure( 645 throw new SpannableAssertionFailure(
623 element, 646 element,
624 "Resolution work list is closed. " 647 "Resolution work list is closed. "
625 "Trying to add deferred action for $element"); 648 "Trying to add deferred action for $element");
626 } 649 }
627 deferredQueue.add(new _DeferredAction(element, action)); 650 deferredQueue.add(new _DeferredAction(element, action));
628 } 651 }
629 652
630 /// [onQueueEmpty] is called whenever the queue is drained. [recentClasses] 653 /// [onQueueEmpty] is called whenever the queue is drained. [recentClasses]
631 /// contains the set of all classes seen for the first time since 654 /// contains the set of all classes seen for the first time since
632 /// [onQueueEmpty] was called last. A return value of [true] indicates that 655 /// [onQueueEmpty] was called last. A return value of [true] indicates that
633 /// the [recentClasses] have been processed and may be cleared. If [false] is 656 /// the [recentClasses] have been processed and may be cleared. If [false] is
634 /// returned, [onQueueEmpty] will be called once the queue is empty again (or 657 /// returned, [onQueueEmpty] will be called once the queue is empty again (or
635 /// still empty) and [recentClasses] will be a superset of the current value. 658 /// still empty) and [recentClasses] will be a superset of the current value.
636 bool onQueueEmpty(Iterable<ClassElement> recentClasses) { 659 bool onQueueEmpty(Iterable<ClassElement> recentClasses) {
637 _emptyDeferredQueue(); 660 _emptyDeferredQueue();
638 661
639 return compiler.backend.onQueueEmpty(this, recentClasses); 662 return backend.onQueueEmpty(this, recentClasses);
640 } 663 }
641 664
642 void emptyDeferredQueueForTesting() => _emptyDeferredQueue(); 665 void emptyDeferredQueueForTesting() => _emptyDeferredQueue();
643 666
644 void _emptyDeferredQueue() { 667 void _emptyDeferredQueue() {
645 while (!deferredQueue.isEmpty) { 668 while (!deferredQueue.isEmpty) {
646 _DeferredAction task = deferredQueue.removeFirst(); 669 _DeferredAction task = deferredQueue.removeFirst();
647 reporter.withCurrentElement(task.element, task.action); 670 reporter.withCurrentElement(task.element, task.action);
648 } 671 }
649 } 672 }
650 673
651 void forgetElement(Element element) { 674 void forgetElement(Element element, Compiler compiler) {
652 _universe.forgetElement(element, compiler); 675 _universe.forgetElement(element, compiler);
653 _processedClasses.remove(element); 676 _processedClasses.remove(element);
654 instanceMembersByName[element.name]?.remove(element); 677 instanceMembersByName[element.name]?.remove(element);
655 instanceFunctionsByName[element.name]?.remove(element); 678 instanceFunctionsByName[element.name]?.remove(element);
656 processedElements.remove(element); 679 processedElements.remove(element);
657 } 680 }
658 } 681 }
659 682
660 /// Parameterizes filtering of which work items are enqueued. 683 /// Parameterizes filtering of which work items are enqueued.
661 class QueueFilter { 684 class QueueFilter {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 } 764 }
742 765
743 typedef void _DeferredActionFunction(); 766 typedef void _DeferredActionFunction();
744 767
745 class _DeferredAction { 768 class _DeferredAction {
746 final Element element; 769 final Element element;
747 final _DeferredActionFunction action; 770 final _DeferredActionFunction action;
748 771
749 _DeferredAction(this.element, this.action); 772 _DeferredAction(this.element, this.action);
750 } 773 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/dump_info.dart ('k') | pkg/compiler/lib/src/inferrer/type_graph_nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698