| 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 Queue; | 7 import 'dart:collection' show Queue; |
| 8 | 8 |
| 9 import 'common/resolution.dart' show Resolution; | 9 import 'common/resolution.dart' show Resolution; |
| 10 import 'common/tasks.dart' show CompilerTask; | 10 import 'common/tasks.dart' show CompilerTask; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 EnqueueTask(Compiler compiler) | 42 EnqueueTask(Compiler compiler) |
| 43 : this.compiler = compiler, | 43 : this.compiler = compiler, |
| 44 super(compiler.measurer) { | 44 super(compiler.measurer) { |
| 45 _resolution = new ResolutionEnqueuer( | 45 _resolution = new ResolutionEnqueuer( |
| 46 this, | 46 this, |
| 47 compiler.options, | 47 compiler.options, |
| 48 compiler.reporter, | 48 compiler.reporter, |
| 49 compiler.options.analyzeOnly && compiler.options.analyzeMain | 49 compiler.options.analyzeOnly && compiler.options.analyzeMain |
| 50 ? const DirectEnqueuerStrategy() | 50 ? const DirectEnqueuerStrategy() |
| 51 : const TreeShakingEnqueuerStrategy(), | 51 : const TreeShakingEnqueuerStrategy(), |
| 52 compiler.backend, | 52 compiler.backend.resolutionEnqueuerListener, |
| 53 compiler.backend.nativeResolutionEnqueuer(), | 53 compiler.backend.nativeResolutionEnqueuer(), |
| 54 new ResolutionWorldBuilderImpl( | 54 new ResolutionWorldBuilderImpl( |
| 55 compiler.backend, compiler.resolution, const OpenWorldStrategy()), | 55 compiler.backend, compiler.resolution, const OpenWorldStrategy()), |
| 56 new ResolutionWorkItemBuilder(compiler.resolution)); | 56 new ResolutionWorkItemBuilder(compiler.resolution)); |
| 57 _codegen = compiler.backend.createCodegenEnqueuer(this, compiler); | 57 _codegen = compiler.backend.createCodegenEnqueuer(this, compiler); |
| 58 } | 58 } |
| 59 | 59 |
| 60 ResolutionEnqueuer get resolution => _resolution; | 60 ResolutionEnqueuer get resolution => _resolution; |
| 61 Enqueuer get codegen => _codegen; | 61 Enqueuer get codegen => _codegen; |
| 62 } | 62 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 | 102 |
| 103 Iterable<ClassEntity> get processedClasses; | 103 Iterable<ClassEntity> get processedClasses; |
| 104 } | 104 } |
| 105 | 105 |
| 106 abstract class EnqueuerListener { | 106 abstract class EnqueuerListener { |
| 107 /// Called to instruct to the backend that [type] has been instantiated. | 107 /// Called to instruct to the backend that [type] has been instantiated. |
| 108 void registerInstantiatedType(InterfaceType type, {bool isGlobal}); | 108 void registerInstantiatedType(InterfaceType type, {bool isGlobal}); |
| 109 | 109 |
| 110 /// Called to notify to the backend that a class is being instantiated. Any | 110 /// Called to notify to the backend that a class is being instantiated. Any |
| 111 /// backend specific [WorldImpact] of this is returned. | 111 /// backend specific [WorldImpact] of this is returned. |
| 112 WorldImpact registerInstantiatedClass(ClassEntity cls, {bool forResolution}); | 112 WorldImpact registerInstantiatedClass(ClassEntity cls); |
| 113 | 113 |
| 114 /// Called to notify to the backend that a class is implemented by an | 114 /// Called to notify to the backend that a class is implemented by an |
| 115 /// instantiated class. Any backend specific [WorldImpact] of this is | 115 /// instantiated class. Any backend specific [WorldImpact] of this is |
| 116 /// returned. | 116 /// returned. |
| 117 WorldImpact registerImplementedClass(ClassEntity cls, {bool forResolution}); | 117 WorldImpact registerImplementedClass(ClassEntity cls); |
| 118 | 118 |
| 119 /// Called to register that a static function has been closurized. Any backend | 119 /// Called to register that a static function has been closurized. Any backend |
| 120 /// specific [WorldImpact] of this is returned. | 120 /// specific [WorldImpact] of this is returned. |
| 121 WorldImpact registerGetOfStaticFunction(); | 121 WorldImpact registerGetOfStaticFunction(); |
| 122 | 122 |
| 123 /// Called to instruct the backend to register that a closure exists for a | 123 /// Called to instruct the backend to register that a closure exists for a |
| 124 /// function on an instantiated generic class. Any backend specific | 124 /// function on an instantiated generic class. Any backend specific |
| 125 /// [WorldImpact] of this is returned. | 125 /// [WorldImpact] of this is returned. |
| 126 WorldImpact registerClosureWithFreeTypeVariables(MemberEntity member, | 126 WorldImpact registerClosureWithFreeTypeVariables(MemberEntity member); |
| 127 {bool forResolution}); | |
| 128 | 127 |
| 129 /// Called to register that a member has been closurized. Any backend specific | 128 /// Called to register that a member has been closurized. Any backend specific |
| 130 /// [WorldImpact] of this is returned. | 129 /// [WorldImpact] of this is returned. |
| 131 WorldImpact registerBoundClosure(); | 130 WorldImpact registerBoundClosure(); |
| 132 | 131 |
| 133 /// Called to register that [element] is statically known to be used. Any | 132 /// Called to register that [element] is statically known to be used. Any |
| 134 /// backend specific [WorldImpact] of this is returned. | 133 /// backend specific [WorldImpact] of this is returned. |
| 135 WorldImpact registerUsedElement(MemberEntity member, {bool forResolution}); | 134 WorldImpact registerUsedElement(MemberEntity member); |
| 136 | 135 |
| 137 /// Called when [enqueuer]'s queue is empty, but before it is closed. | 136 /// Called when [enqueuer]'s queue is empty, but before it is closed. |
| 138 /// | 137 /// |
| 139 /// This is used, for example, by the JS backend to enqueue additional | 138 /// This is used, for example, by the JS backend to enqueue additional |
| 140 /// elements needed for reflection. [recentClasses] is a collection of | 139 /// elements needed for reflection. [recentClasses] is a collection of |
| 141 /// all classes seen for the first time by the [enqueuer] since the last call | 140 /// all classes seen for the first time by the [enqueuer] since the last call |
| 142 /// to [onQueueEmpty]. | 141 /// to [onQueueEmpty]. |
| 143 /// | 142 /// |
| 144 /// A return value of `true` indicates that [recentClasses] has been | 143 /// A return value of `true` indicates that [recentClasses] has been |
| 145 /// processed and its elements do not need to be seen in the next round. When | 144 /// processed and its elements do not need to be seen in the next round. When |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 } | 263 } |
| 265 | 264 |
| 266 /// Callback for applying the use of a [cls]. | 265 /// Callback for applying the use of a [cls]. |
| 267 void _applyClassUse(ClassEntity cls, EnumSet<ClassUse> useSet) { | 266 void _applyClassUse(ClassEntity cls, EnumSet<ClassUse> useSet) { |
| 268 if (useSet.contains(ClassUse.INSTANTIATED)) { | 267 if (useSet.contains(ClassUse.INSTANTIATED)) { |
| 269 _recentClasses.add(cls); | 268 _recentClasses.add(cls); |
| 270 _universe.processClassMembers(cls, _applyMemberUse); | 269 _universe.processClassMembers(cls, _applyMemberUse); |
| 271 // We only tell the backend once that [cls] was instantiated, so | 270 // We only tell the backend once that [cls] was instantiated, so |
| 272 // any additional dependencies must be treated as global | 271 // any additional dependencies must be treated as global |
| 273 // dependencies. | 272 // dependencies. |
| 274 applyImpact( | 273 applyImpact(_listener.registerInstantiatedClass(cls)); |
| 275 _listener.registerInstantiatedClass(cls, forResolution: true)); | |
| 276 } | 274 } |
| 277 if (useSet.contains(ClassUse.IMPLEMENTED)) { | 275 if (useSet.contains(ClassUse.IMPLEMENTED)) { |
| 278 applyImpact(_listener.registerImplementedClass(cls, forResolution: true)); | 276 applyImpact(_listener.registerImplementedClass(cls)); |
| 279 } | 277 } |
| 280 } | 278 } |
| 281 | 279 |
| 282 void processDynamicUse(DynamicUse dynamicUse) { | 280 void processDynamicUse(DynamicUse dynamicUse) { |
| 283 task.measure(() { | 281 task.measure(() { |
| 284 _universe.registerDynamicUse(dynamicUse, _applyMemberUse); | 282 _universe.registerDynamicUse(dynamicUse, _applyMemberUse); |
| 285 }); | 283 }); |
| 286 } | 284 } |
| 287 | 285 |
| 288 void processStaticUse(StaticUse staticUse) { | 286 void processStaticUse(StaticUse staticUse) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 type = _universe.registerIsCheck(type); | 340 type = _universe.registerIsCheck(type); |
| 343 // Even in checked mode, type annotations for return type and argument | 341 // Even in checked mode, type annotations for return type and argument |
| 344 // types do not imply type checks, so there should never be a check | 342 // types do not imply type checks, so there should never be a check |
| 345 // against the type variable of a typedef. | 343 // against the type variable of a typedef. |
| 346 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); | 344 assert(!type.isTypeVariable || !type.element.enclosingElement.isTypedef); |
| 347 } | 345 } |
| 348 | 346 |
| 349 void _registerClosurizedMember(MemberElement element) { | 347 void _registerClosurizedMember(MemberElement element) { |
| 350 assert(element.isInstanceMember); | 348 assert(element.isInstanceMember); |
| 351 if (element.type.containsTypeVariables) { | 349 if (element.type.containsTypeVariables) { |
| 352 applyImpact(_listener.registerClosureWithFreeTypeVariables(element, | 350 applyImpact(_listener.registerClosureWithFreeTypeVariables(element)); |
| 353 forResolution: true)); | |
| 354 _universe.closuresWithFreeTypeVariables.add(element); | 351 _universe.closuresWithFreeTypeVariables.add(element); |
| 355 } | 352 } |
| 356 applyImpact(_listener.registerBoundClosure()); | 353 applyImpact(_listener.registerBoundClosure()); |
| 357 _universe.closurizedMembers.add(element); | 354 _universe.closurizedMembers.add(element); |
| 358 } | 355 } |
| 359 | 356 |
| 360 void forEach(void f(WorkItem work)) { | 357 void forEach(void f(WorkItem work)) { |
| 361 do { | 358 do { |
| 362 while (_queue.isNotEmpty) { | 359 while (_queue.isNotEmpty) { |
| 363 // TODO(johnniwinther): Find an optimal process order. | 360 // TODO(johnniwinther): Find an optimal process order. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 void _addToWorkList(MemberEntity entity) { | 404 void _addToWorkList(MemberEntity entity) { |
| 408 if (hasBeenProcessed(entity)) return; | 405 if (hasBeenProcessed(entity)) return; |
| 409 WorkItem workItem = _workItemBuilder.createWorkItem(entity); | 406 WorkItem workItem = _workItemBuilder.createWorkItem(entity); |
| 410 if (workItem == null) return; | 407 if (workItem == null) return; |
| 411 | 408 |
| 412 if (queueIsClosed) { | 409 if (queueIsClosed) { |
| 413 throw new SpannableAssertionFailure( | 410 throw new SpannableAssertionFailure( |
| 414 entity, "Resolution work list is closed. Trying to add $entity."); | 411 entity, "Resolution work list is closed. Trying to add $entity."); |
| 415 } | 412 } |
| 416 | 413 |
| 417 applyImpact(_listener.registerUsedElement(entity, forResolution: true)); | 414 applyImpact(_listener.registerUsedElement(entity)); |
| 418 _universe.registerUsedElement(entity); | 415 _universe.registerUsedElement(entity); |
| 419 _queue.add(workItem); | 416 _queue.add(workItem); |
| 420 } | 417 } |
| 421 | 418 |
| 422 /// Adds an action to the deferred task queue. | 419 /// Adds an action to the deferred task queue. |
| 423 /// The action is performed the next time the resolution queue has been | 420 /// The action is performed the next time the resolution queue has been |
| 424 /// emptied. | 421 /// emptied. |
| 425 /// | 422 /// |
| 426 /// The queue is processed in FIFO order. | 423 /// The queue is processed in FIFO order. |
| 427 void addDeferredAction(Entity entity, void action()) { | 424 void addDeferredAction(Entity entity, void action()) { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 @override | 566 @override |
| 570 WorkItem createWorkItem(MemberElement element) { | 567 WorkItem createWorkItem(MemberElement element) { |
| 571 assert(invariant(element, element.isDeclaration)); | 568 assert(invariant(element, element.isDeclaration)); |
| 572 if (element.isMalformed) return null; | 569 if (element.isMalformed) return null; |
| 573 | 570 |
| 574 assert(invariant(element, element is AnalyzableElement, | 571 assert(invariant(element, element is AnalyzableElement, |
| 575 message: 'Element $element is not analyzable.')); | 572 message: 'Element $element is not analyzable.')); |
| 576 return _resolution.createWorkItem(element); | 573 return _resolution.createWorkItem(element); |
| 577 } | 574 } |
| 578 } | 575 } |
| OLD | NEW |