| 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 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 |
| 11 Identifiers; | 11 Identifiers; |
| 12 import 'common/resolution.dart' show |
| 13 Resolution; |
| 12 import 'common/work.dart' show | 14 import 'common/work.dart' show |
| 13 ItemCompilationContext, | 15 ItemCompilationContext, |
| 14 WorkItem; | 16 WorkItem; |
| 15 import 'common/tasks.dart' show | 17 import 'common/tasks.dart' show |
| 16 CompilerTask, | 18 CompilerTask, |
| 17 DeferredAction, | 19 DeferredAction, |
| 18 DeferredTask; | 20 DeferredTask; |
| 19 import 'common/codegen.dart' show | 21 import 'common/codegen.dart' show |
| 20 CodegenWorkItem; | 22 CodegenWorkItem; |
| 21 import 'common/resolution.dart' show | 23 import 'common/resolution.dart' show |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask | 136 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask |
| 135 | 137 |
| 136 bool hasEnqueuedReflectiveElements = false; | 138 bool hasEnqueuedReflectiveElements = false; |
| 137 bool hasEnqueuedReflectiveStaticFields = false; | 139 bool hasEnqueuedReflectiveStaticFields = false; |
| 138 | 140 |
| 139 Enqueuer(this.name, | 141 Enqueuer(this.name, |
| 140 this.compiler, | 142 this.compiler, |
| 141 this.itemCompilationContextCreator, | 143 this.itemCompilationContextCreator, |
| 142 this.strategy); | 144 this.strategy); |
| 143 | 145 |
| 146 // TODO(johnniwinther): Move this to [ResolutionEnqueuer]. |
| 147 Resolution get resolution => compiler.resolution; |
| 148 |
| 144 Queue<WorkItem> get queue; | 149 Queue<WorkItem> get queue; |
| 145 bool get queueIsEmpty => queue.isEmpty; | 150 bool get queueIsEmpty => queue.isEmpty; |
| 146 | 151 |
| 147 /// Returns [:true:] if this enqueuer is the resolution enqueuer. | 152 /// Returns [:true:] if this enqueuer is the resolution enqueuer. |
| 148 bool get isResolutionQueue => false; | 153 bool get isResolutionQueue => false; |
| 149 | 154 |
| 150 QueueFilter get filter => compiler.enqueuerFilter; | 155 QueueFilter get filter => compiler.enqueuerFilter; |
| 151 | 156 |
| 152 /// Returns [:true:] if [member] has been processed by this enqueuer. | 157 /// Returns [:true:] if [member] has been processed by this enqueuer. |
| 153 bool isProcessed(Element member); | 158 bool isProcessed(Element member); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 // doesn't require a [Registry]. | 190 // doesn't require a [Registry]. |
| 186 worldImpact.checkedTypes.forEach(registerIsCheck); | 191 worldImpact.checkedTypes.forEach(registerIsCheck); |
| 187 worldImpact.closurizedFunctions.forEach(registerGetOfStaticFunction); | 192 worldImpact.closurizedFunctions.forEach(registerGetOfStaticFunction); |
| 188 } | 193 } |
| 189 | 194 |
| 190 // TODO(johnniwinther): Remove the need for passing the [registry]. | 195 // TODO(johnniwinther): Remove the need for passing the [registry]. |
| 191 void registerInstantiatedType(InterfaceType type, | 196 void registerInstantiatedType(InterfaceType type, |
| 192 {bool mirrorUsage: false}) { | 197 {bool mirrorUsage: false}) { |
| 193 task.measure(() { | 198 task.measure(() { |
| 194 ClassElement cls = type.element; | 199 ClassElement cls = type.element; |
| 195 cls.ensureResolved(compiler); | 200 cls.ensureResolved(resolution); |
| 196 universe.registerTypeInstantiation( | 201 universe.registerTypeInstantiation( |
| 197 type, | 202 type, |
| 198 byMirrors: mirrorUsage, | 203 byMirrors: mirrorUsage, |
| 199 onImplemented: (ClassElement cls) { | 204 onImplemented: (ClassElement cls) { |
| 200 compiler.backend.registerImplementedClass( | 205 compiler.backend.registerImplementedClass( |
| 201 cls, this, compiler.globalDependencies); | 206 cls, this, compiler.globalDependencies); |
| 202 }); | 207 }); |
| 203 processInstantiatedClass(cls); | 208 processInstantiatedClass(cls); |
| 204 }); | 209 }); |
| 205 } | 210 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 // are virtual instantiation points and escape points. | 259 // are virtual instantiation points and escape points. |
| 255 } else { | 260 } else { |
| 256 // All field initializers must be resolved as they could | 261 // All field initializers must be resolved as they could |
| 257 // have an observable side-effect (and cannot be tree-shaken | 262 // have an observable side-effect (and cannot be tree-shaken |
| 258 // away). | 263 // away). |
| 259 addToWorkList(member); | 264 addToWorkList(member); |
| 260 return; | 265 return; |
| 261 } | 266 } |
| 262 } else if (member.isFunction) { | 267 } else if (member.isFunction) { |
| 263 FunctionElement function = member; | 268 FunctionElement function = member; |
| 264 function.computeType(compiler); | 269 function.computeType(resolution); |
| 265 if (function.name == Identifiers.noSuchMethod_) { | 270 if (function.name == Identifiers.noSuchMethod_) { |
| 266 registerNoSuchMethod(function); | 271 registerNoSuchMethod(function); |
| 267 } | 272 } |
| 268 if (function.name == Identifiers.call && | 273 if (function.name == Identifiers.call && |
| 269 !cls.typeVariables.isEmpty) { | 274 !cls.typeVariables.isEmpty) { |
| 270 registerCallMethodWithFreeTypeVariables(function); | 275 registerCallMethodWithFreeTypeVariables(function); |
| 271 } | 276 } |
| 272 // If there is a property access with the same name as a method we | 277 // If there is a property access with the same name as a method we |
| 273 // need to emit the method. | 278 // need to emit the method. |
| 274 if (universe.hasInvokedGetter(function, compiler.world)) { | 279 if (universe.hasInvokedGetter(function, compiler.world)) { |
| 275 registerClosurizedMember(function); | 280 registerClosurizedMember(function); |
| 276 addToWorkList(function); | 281 addToWorkList(function); |
| 277 return; | 282 return; |
| 278 } | 283 } |
| 279 // Store the member in [instanceFunctionsByName] to catch | 284 // Store the member in [instanceFunctionsByName] to catch |
| 280 // getters on the function. | 285 // getters on the function. |
| 281 instanceFunctionsByName.putIfAbsent(memberName, () => new Set<Element>()) | 286 instanceFunctionsByName.putIfAbsent(memberName, () => new Set<Element>()) |
| 282 .add(member); | 287 .add(member); |
| 283 if (universe.hasInvocation(function, compiler.world)) { | 288 if (universe.hasInvocation(function, compiler.world)) { |
| 284 addToWorkList(function); | 289 addToWorkList(function); |
| 285 return; | 290 return; |
| 286 } | 291 } |
| 287 } else if (member.isGetter) { | 292 } else if (member.isGetter) { |
| 288 FunctionElement getter = member; | 293 FunctionElement getter = member; |
| 289 getter.computeType(compiler); | 294 getter.computeType(resolution); |
| 290 if (universe.hasInvokedGetter(getter, compiler.world)) { | 295 if (universe.hasInvokedGetter(getter, compiler.world)) { |
| 291 addToWorkList(getter); | 296 addToWorkList(getter); |
| 292 return; | 297 return; |
| 293 } | 298 } |
| 294 // We don't know what selectors the returned closure accepts. If | 299 // We don't know what selectors the returned closure accepts. If |
| 295 // the set contains any selector we have to assume that it matches. | 300 // the set contains any selector we have to assume that it matches. |
| 296 if (universe.hasInvocation(getter, compiler.world)) { | 301 if (universe.hasInvocation(getter, compiler.world)) { |
| 297 addToWorkList(getter); | 302 addToWorkList(getter); |
| 298 return; | 303 return; |
| 299 } | 304 } |
| 300 } else if (member.isSetter) { | 305 } else if (member.isSetter) { |
| 301 FunctionElement setter = member; | 306 FunctionElement setter = member; |
| 302 setter.computeType(compiler); | 307 setter.computeType(resolution); |
| 303 if (universe.hasInvokedSetter(setter, compiler.world)) { | 308 if (universe.hasInvokedSetter(setter, compiler.world)) { |
| 304 addToWorkList(setter); | 309 addToWorkList(setter); |
| 305 return; | 310 return; |
| 306 } | 311 } |
| 307 } | 312 } |
| 308 | 313 |
| 309 // The element is not yet used. Add it to the list of instance | 314 // The element is not yet used. Add it to the list of instance |
| 310 // members to still be processed. | 315 // members to still be processed. |
| 311 instanceMembersByName.putIfAbsent(memberName, () => new Set<Element>()) | 316 instanceMembersByName.putIfAbsent(memberName, () => new Set<Element>()) |
| 312 .add(member); | 317 .add(member); |
| 313 } | 318 } |
| 314 | 319 |
| 315 void registerNoSuchMethod(Element noSuchMethod); | 320 void registerNoSuchMethod(Element noSuchMethod); |
| 316 | 321 |
| 317 void enableIsolateSupport() {} | 322 void enableIsolateSupport() {} |
| 318 | 323 |
| 319 void processInstantiatedClass(ClassElement cls) { | 324 void processInstantiatedClass(ClassElement cls) { |
| 320 task.measure(() { | 325 task.measure(() { |
| 321 if (_processedClasses.contains(cls)) return; | 326 if (_processedClasses.contains(cls)) return; |
| 322 // The class must be resolved to compute the set of all | 327 // The class must be resolved to compute the set of all |
| 323 // supertypes. | 328 // supertypes. |
| 324 cls.ensureResolved(compiler); | 329 cls.ensureResolved(resolution); |
| 325 | 330 |
| 326 void processClass(ClassElement superclass) { | 331 void processClass(ClassElement superclass) { |
| 327 if (_processedClasses.contains(superclass)) return; | 332 if (_processedClasses.contains(superclass)) return; |
| 328 | 333 |
| 329 _processedClasses.add(superclass); | 334 _processedClasses.add(superclass); |
| 330 recentClasses.add(superclass); | 335 recentClasses.add(superclass); |
| 331 superclass.ensureResolved(compiler); | 336 superclass.ensureResolved(resolution); |
| 332 superclass.implementation.forEachMember(processInstantiatedClassMember); | 337 superclass.implementation.forEachMember(processInstantiatedClassMember); |
| 333 if (isResolutionQueue && !superclass.isSynthesized) { | 338 if (isResolutionQueue && !superclass.isSynthesized) { |
| 334 compiler.resolver.checkClass(superclass); | 339 compiler.resolver.checkClass(superclass); |
| 335 } | 340 } |
| 336 // We only tell the backend once that [superclass] was instantiated, so | 341 // We only tell the backend once that [superclass] was instantiated, so |
| 337 // any additional dependencies must be treated as global | 342 // any additional dependencies must be treated as global |
| 338 // dependencies. | 343 // dependencies. |
| 339 compiler.backend.registerInstantiatedClass( | 344 compiler.backend.registerInstantiatedClass( |
| 340 superclass, this, compiler.globalDependencies); | 345 superclass, this, compiler.globalDependencies); |
| 341 } | 346 } |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 /// Enqeue the member [element] if it is required for reflection. | 414 /// Enqeue the member [element] if it is required for reflection. |
| 410 /// | 415 /// |
| 411 /// [enclosingWasIncluded] provides a hint whether the enclosing element was | 416 /// [enclosingWasIncluded] provides a hint whether the enclosing element was |
| 412 /// needed for reflection. | 417 /// needed for reflection. |
| 413 void enqueueReflectiveMember(Element element, bool enclosingWasIncluded) { | 418 void enqueueReflectiveMember(Element element, bool enclosingWasIncluded) { |
| 414 if (shouldIncludeElementDueToMirrors(element, | 419 if (shouldIncludeElementDueToMirrors(element, |
| 415 includedEnclosing: enclosingWasIncluded)) { | 420 includedEnclosing: enclosingWasIncluded)) { |
| 416 logEnqueueReflectiveAction(element); | 421 logEnqueueReflectiveAction(element); |
| 417 if (element.isTypedef) { | 422 if (element.isTypedef) { |
| 418 TypedefElement typedef = element; | 423 TypedefElement typedef = element; |
| 419 typedef.ensureResolved(compiler); | 424 typedef.ensureResolved(resolution); |
| 420 compiler.world.allTypedefs.add(element); | 425 compiler.world.allTypedefs.add(element); |
| 421 } else if (Elements.isStaticOrTopLevel(element)) { | 426 } else if (Elements.isStaticOrTopLevel(element)) { |
| 422 registerStaticUse(element.declaration); | 427 registerStaticUse(element.declaration); |
| 423 } else if (element.isInstanceMember) { | 428 } else if (element.isInstanceMember) { |
| 424 // We need to enqueue all members matching this one in subclasses, as | 429 // We need to enqueue all members matching this one in subclasses, as |
| 425 // well. | 430 // well. |
| 426 // TODO(herhut): Use TypedSelector.subtype for enqueueing | 431 // TODO(herhut): Use TypedSelector.subtype for enqueueing |
| 427 UniverseSelector selector = new UniverseSelector( | 432 UniverseSelector selector = new UniverseSelector( |
| 428 new Selector.fromElement(element), null); | 433 new Selector.fromElement(element), null); |
| 429 registerSelectorUse(selector); | 434 registerSelectorUse(selector); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 443 /// needed for reflection. | 448 /// needed for reflection. |
| 444 void enqueueReflectiveElementsInClass(ClassElement cls, | 449 void enqueueReflectiveElementsInClass(ClassElement cls, |
| 445 Iterable<ClassElement> recents, | 450 Iterable<ClassElement> recents, |
| 446 bool enclosingWasIncluded) { | 451 bool enclosingWasIncluded) { |
| 447 if (cls.library.isInternalLibrary || cls.isInjected) return; | 452 if (cls.library.isInternalLibrary || cls.isInjected) return; |
| 448 bool includeClass = shouldIncludeElementDueToMirrors(cls, | 453 bool includeClass = shouldIncludeElementDueToMirrors(cls, |
| 449 includedEnclosing: enclosingWasIncluded); | 454 includedEnclosing: enclosingWasIncluded); |
| 450 if (includeClass) { | 455 if (includeClass) { |
| 451 logEnqueueReflectiveAction(cls, "register"); | 456 logEnqueueReflectiveAction(cls, "register"); |
| 452 ClassElement decl = cls.declaration; | 457 ClassElement decl = cls.declaration; |
| 453 decl.ensureResolved(compiler); | 458 decl.ensureResolved(resolution); |
| 454 compiler.backend.registerInstantiatedType( | 459 compiler.backend.registerInstantiatedType( |
| 455 decl.rawType, | 460 decl.rawType, |
| 456 this, | 461 this, |
| 457 compiler.mirrorDependencies, | 462 compiler.mirrorDependencies, |
| 458 mirrorUsage: true); | 463 mirrorUsage: true); |
| 459 } | 464 } |
| 460 // If the class is never instantiated, we know nothing of it can possibly | 465 // If the class is never instantiated, we know nothing of it can possibly |
| 461 // be reflected upon. | 466 // be reflected upon. |
| 462 // TODO(herhut): Add a warning if a mirrors annotation cannot hit. | 467 // TODO(herhut): Add a warning if a mirrors annotation cannot hit. |
| 463 if (recents.contains(cls.declaration)) { | 468 if (recents.contains(cls.declaration)) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 477 /// [Closure] is treated specially as it is the superclass of all closures. | 482 /// [Closure] is treated specially as it is the superclass of all closures. |
| 478 /// Although it is in an internal library, we mark it as reflectable. Note | 483 /// Although it is in an internal library, we mark it as reflectable. Note |
| 479 /// that none of its methods are reflectable, unless reflectable by | 484 /// that none of its methods are reflectable, unless reflectable by |
| 480 /// inheritance. | 485 /// inheritance. |
| 481 void enqueueReflectiveSpecialClasses() { | 486 void enqueueReflectiveSpecialClasses() { |
| 482 Iterable<ClassElement> classes = | 487 Iterable<ClassElement> classes = |
| 483 compiler.backend.classesRequiredForReflection; | 488 compiler.backend.classesRequiredForReflection; |
| 484 for (ClassElement cls in classes) { | 489 for (ClassElement cls in classes) { |
| 485 if (compiler.backend.referencedFromMirrorSystem(cls)) { | 490 if (compiler.backend.referencedFromMirrorSystem(cls)) { |
| 486 logEnqueueReflectiveAction(cls); | 491 logEnqueueReflectiveAction(cls); |
| 487 cls.ensureResolved(compiler); | 492 cls.ensureResolved(resolution); |
| 488 compiler.backend.registerInstantiatedType( | 493 compiler.backend.registerInstantiatedType( |
| 489 cls.rawType, | 494 cls.rawType, |
| 490 this, | 495 this, |
| 491 compiler.mirrorDependencies, | 496 compiler.mirrorDependencies, |
| 492 mirrorUsage: true); | 497 mirrorUsage: true); |
| 493 } | 498 } |
| 494 } | 499 } |
| 495 } | 500 } |
| 496 | 501 |
| 497 /// Enqeue all local members of the library [lib] if they are required for | 502 /// Enqeue all local members of the library [lib] if they are required for |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 } | 698 } |
| 694 | 699 |
| 695 void registerCallMethodWithFreeTypeVariables(Element element) { | 700 void registerCallMethodWithFreeTypeVariables(Element element) { |
| 696 compiler.backend.registerCallMethodWithFreeTypeVariables( | 701 compiler.backend.registerCallMethodWithFreeTypeVariables( |
| 697 element, this, compiler.globalDependencies); | 702 element, this, compiler.globalDependencies); |
| 698 universe.callMethodsWithFreeTypeVariables.add(element); | 703 universe.callMethodsWithFreeTypeVariables.add(element); |
| 699 } | 704 } |
| 700 | 705 |
| 701 void registerClosurizedMember(TypedElement element) { | 706 void registerClosurizedMember(TypedElement element) { |
| 702 assert(element.isInstanceMember); | 707 assert(element.isInstanceMember); |
| 703 if (element.computeType(compiler).containsTypeVariables) { | 708 if (element.computeType(resolution).containsTypeVariables) { |
| 704 compiler.backend.registerClosureWithFreeTypeVariables( | 709 compiler.backend.registerClosureWithFreeTypeVariables( |
| 705 element, this, compiler.globalDependencies); | 710 element, this, compiler.globalDependencies); |
| 706 } | 711 } |
| 707 compiler.backend.registerBoundClosure(this); | 712 compiler.backend.registerBoundClosure(this); |
| 708 universe.closurizedMembers.add(element); | 713 universe.closurizedMembers.add(element); |
| 709 } | 714 } |
| 710 | 715 |
| 711 void registerClosure(LocalFunctionElement element) { | 716 void registerClosure(LocalFunctionElement element) { |
| 712 universe.allClosures.add(element); | 717 universe.allClosures.add(element); |
| 713 } | 718 } |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1072 @override | 1077 @override |
| 1073 void processStaticUse(Enqueuer enqueuer, Element element) { | 1078 void processStaticUse(Enqueuer enqueuer, Element element) { |
| 1074 enqueuer.registerStaticUseInternal(element); | 1079 enqueuer.registerStaticUseInternal(element); |
| 1075 } | 1080 } |
| 1076 | 1081 |
| 1077 @override | 1082 @override |
| 1078 void processSelector(Enqueuer enqueuer, UniverseSelector selector) { | 1083 void processSelector(Enqueuer enqueuer, UniverseSelector selector) { |
| 1079 enqueuer.handleUnseenSelectorInternal(selector); | 1084 enqueuer.handleUnseenSelectorInternal(selector); |
| 1080 } | 1085 } |
| 1081 } | 1086 } |
| OLD | NEW |