Chromium Code Reviews| 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.js.enqueue; | 5 library dart2js.js.enqueue; |
| 6 | 6 |
| 7 import 'dart:collection' show Queue; | 7 import 'dart:collection' show Queue; |
| 8 | 8 |
| 9 import '../cache_strategy.dart' show CacheStrategy; | 9 import '../cache_strategy.dart' show CacheStrategy; |
| 10 import '../common/backend_api.dart' show Backend; | 10 import '../common/backend_api.dart' show Backend; |
| 11 import '../common/codegen.dart' show CodegenWorkItem; | 11 import '../common/codegen.dart' show CodegenWorkItem; |
| 12 import '../common/tasks.dart' show CompilerTask; | 12 import '../common/tasks.dart' show CompilerTask; |
| 13 import '../common/work.dart' show WorkItem; | 13 import '../common/work.dart' show WorkItem; |
| 14 import '../common.dart'; | 14 import '../common.dart'; |
| 15 import '../compiler.dart' show Compiler; | 15 import '../compiler.dart' show Compiler; |
| 16 import '../dart_types.dart' show DartType, InterfaceType; | 16 import '../dart_types.dart' show DartType, InterfaceType; |
| 17 import '../elements/elements.dart' show Element, Entity, TypedElement; | 17 import '../elements/elements.dart' show Entity, MemberElement, TypedElement; |
| 18 import '../elements/entities.dart'; | 18 import '../elements/entities.dart'; |
| 19 import '../enqueue.dart'; | 19 import '../enqueue.dart'; |
| 20 import '../native/native.dart' as native; | 20 import '../native/native.dart' as native; |
| 21 import '../options.dart'; | 21 import '../options.dart'; |
| 22 import '../types/types.dart' show TypeMaskStrategy; | 22 import '../types/types.dart' show TypeMaskStrategy; |
| 23 import '../universe/world_builder.dart'; | 23 import '../universe/world_builder.dart'; |
| 24 import '../universe/use.dart' | 24 import '../universe/use.dart' |
| 25 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind; | 25 show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind; |
| 26 import '../universe/world_impact.dart' | 26 import '../universe/world_impact.dart' |
| 27 show ImpactUseCase, WorldImpact, WorldImpactVisitor; | 27 show ImpactUseCase, WorldImpact, WorldImpactVisitor; |
| 28 import '../util/enumset.dart'; | 28 import '../util/enumset.dart'; |
| 29 import '../util/util.dart' show Setlet; | 29 import '../util/util.dart' show Setlet; |
| 30 | 30 |
| 31 /// [Enqueuer] which is specific to code generation. | 31 /// [Enqueuer] which is specific to code generation. |
| 32 class CodegenEnqueuer extends EnqueuerImpl { | 32 class CodegenEnqueuer extends EnqueuerImpl { |
| 33 final String name; | 33 final String name; |
| 34 final EnqueuerStrategy strategy; | 34 final EnqueuerStrategy strategy; |
| 35 | 35 |
| 36 Set<ClassEntity> _recentClasses = new Setlet<ClassEntity>(); | 36 Set<ClassEntity> _recentClasses = new Setlet<ClassEntity>(); |
| 37 final CodegenWorldBuilderImpl _universe; | 37 final CodegenWorldBuilderImpl _universe; |
| 38 final WorkItemBuilder _workItemBuilder; | |
| 38 | 39 |
| 39 bool queueIsClosed = false; | 40 bool queueIsClosed = false; |
| 40 final CompilerTask task; | 41 final CompilerTask task; |
| 41 final native.NativeEnqueuer nativeEnqueuer; | 42 final native.NativeEnqueuer nativeEnqueuer; |
| 42 final Backend _backend; | 43 final Backend _backend; |
| 43 final CompilerOptions _options; | 44 final CompilerOptions _options; |
| 44 | 45 |
| 45 WorldImpactVisitor _impactVisitor; | 46 WorldImpactVisitor _impactVisitor; |
| 46 | 47 |
| 47 final Queue<WorkItem> _queue = new Queue<WorkItem>(); | 48 final Queue<WorkItem> _queue = new Queue<WorkItem>(); |
| 48 | 49 |
| 49 /// All declaration elements that have been processed by codegen. | 50 /// All declaration elements that have been processed by codegen. |
| 50 final Set<Entity> _processedEntities = new Set<Entity>(); | 51 final Set<Entity> _processedEntities = new Set<Entity>(); |
| 51 | 52 |
| 52 final Set<Entity> newlyEnqueuedElements; | 53 final Set<Entity> newlyEnqueuedElements; |
| 53 | 54 |
| 54 final Set<DynamicUse> newlySeenSelectors; | 55 final Set<DynamicUse> newlySeenSelectors; |
| 55 | 56 |
| 56 static const ImpactUseCase IMPACT_USE = | 57 static const ImpactUseCase IMPACT_USE = |
| 57 const ImpactUseCase('CodegenEnqueuer'); | 58 const ImpactUseCase('CodegenEnqueuer'); |
| 58 | 59 |
| 59 CodegenEnqueuer(this.task, CacheStrategy cacheStrategy, Backend backend, | 60 CodegenEnqueuer(this.task, CacheStrategy cacheStrategy, Backend backend, |
| 60 this._options, this.strategy) | 61 CompilerOptions options, this.strategy) |
| 61 : _universe = | 62 : _universe = |
| 62 new CodegenWorldBuilderImpl(backend, const TypeMaskStrategy()), | 63 new CodegenWorldBuilderImpl(backend, const TypeMaskStrategy()), |
| 64 _workItemBuilder = new CodegenWorkItemBuilder(backend, options), | |
|
Siggi Cherem (dart-lang)
2016/12/20 21:21:47
You might be thinking of this already, but can we
Johnni Winther
2016/12/21 10:19:37
This move is needed to, eventually, create kernel
Siggi Cherem (dart-lang)
2016/12/21 15:08:53
I'm not sure I fully understand, we can chat more
| |
| 63 newlyEnqueuedElements = cacheStrategy.newSet(), | 65 newlyEnqueuedElements = cacheStrategy.newSet(), |
| 64 newlySeenSelectors = cacheStrategy.newSet(), | 66 newlySeenSelectors = cacheStrategy.newSet(), |
| 65 nativeEnqueuer = backend.nativeCodegenEnqueuer(), | 67 nativeEnqueuer = backend.nativeCodegenEnqueuer(), |
| 66 this._backend = backend, | 68 this._backend = backend, |
| 69 this._options = options, | |
| 67 this.name = 'codegen enqueuer' { | 70 this.name = 'codegen enqueuer' { |
| 68 _impactVisitor = new EnqueuerImplImpactVisitor(this); | 71 _impactVisitor = new EnqueuerImplImpactVisitor(this); |
| 69 } | 72 } |
| 70 | 73 |
| 71 CodegenWorldBuilder get universe => _universe; | 74 CodegenWorldBuilder get universe => _universe; |
| 72 | 75 |
| 73 bool get queueIsEmpty => _queue.isEmpty; | 76 bool get queueIsEmpty => _queue.isEmpty; |
| 74 | 77 |
| 75 /// Returns [:true:] if this enqueuer is the resolution enqueuer. | 78 /// Returns [:true:] if this enqueuer is the resolution enqueuer. |
| 76 bool get isResolutionQueue => false; | 79 bool get isResolutionQueue => false; |
| 77 | 80 |
| 78 /** | 81 /// Create a [WorkItem] for [entity] and add it to the work list if it has not |
| 79 * Documentation wanted -- johnniwinther | 82 /// already been processed. |
| 80 * | 83 void _addToWorkList(MemberEntity entity) { |
| 81 * Invariant: [element] must be a declaration element. | 84 if (_processedEntities.contains(entity)) return; |
| 82 */ | |
| 83 void _addToWorkList(Element element) { | |
| 84 assert(invariant(element, element.isDeclaration)); | |
| 85 // Don't generate code for foreign elements. | |
| 86 if (_backend.isForeign(element)) return; | |
| 87 if (element.isAbstract) return; | |
| 88 | 85 |
| 89 // Codegen inlines field initializers. It only needs to generate | 86 WorkItem workItem = _workItemBuilder.createWorkItem(entity); |
| 90 // code for checked setters. | 87 if (workItem == null) return; |
| 91 if (element.isField && element.isInstanceMember) { | |
| 92 if (!_options.enableTypeAssertions || | |
| 93 element.enclosingElement.isClosure) { | |
| 94 return; | |
| 95 } | |
| 96 } | |
| 97 | 88 |
| 98 if (_options.hasIncrementalSupport && | 89 if (_options.hasIncrementalSupport) { |
| 99 !_processedEntities.contains(element)) { | 90 newlyEnqueuedElements.add(entity); |
| 100 newlyEnqueuedElements.add(element); | |
| 101 } | 91 } |
| 102 | 92 |
| 103 if (queueIsClosed) { | 93 if (queueIsClosed) { |
| 104 throw new SpannableAssertionFailure( | 94 throw new SpannableAssertionFailure( |
| 105 element, "Codegen work list is closed. Trying to add $element"); | 95 entity, "Codegen work list is closed. Trying to add $entity"); |
| 106 } | 96 } |
| 107 _queue.add(new CodegenWorkItem(_backend, element)); | 97 |
| 108 applyImpact(_backend.registerUsedElement(element, forResolution: false)); | 98 applyImpact(_backend.registerUsedElement(entity, forResolution: false)); |
| 99 _queue.add(workItem); | |
| 109 } | 100 } |
| 110 | 101 |
| 111 void applyImpact(WorldImpact worldImpact, {var impactSource}) { | 102 void applyImpact(WorldImpact worldImpact, {var impactSource}) { |
| 112 if (worldImpact.isEmpty) return; | 103 if (worldImpact.isEmpty) return; |
| 113 impactStrategy.visitImpact( | 104 impactStrategy.visitImpact( |
| 114 impactSource, worldImpact, _impactVisitor, impactUse); | 105 impactSource, worldImpact, _impactVisitor, impactUse); |
| 115 } | 106 } |
| 116 | 107 |
| 117 void _registerInstantiatedType(InterfaceType type, | 108 void _registerInstantiatedType(InterfaceType type, |
| 118 {bool mirrorUsage: false, bool nativeUsage: false}) { | 109 {bool mirrorUsage: false, bool nativeUsage: false}) { |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 276 _universe.forgetElement(entity, compiler); | 267 _universe.forgetElement(entity, compiler); |
| 277 _processedEntities.remove(entity); | 268 _processedEntities.remove(entity); |
| 278 } | 269 } |
| 279 | 270 |
| 280 @override | 271 @override |
| 281 Iterable<Entity> get processedEntities => _processedEntities; | 272 Iterable<Entity> get processedEntities => _processedEntities; |
| 282 | 273 |
| 283 @override | 274 @override |
| 284 Iterable<ClassEntity> get processedClasses => _universe.processedClasses; | 275 Iterable<ClassEntity> get processedClasses => _universe.processedClasses; |
| 285 } | 276 } |
| 277 | |
| 278 /// Builder that creates the work item necessary for the code generation of a | |
| 279 /// [MemberElement]. | |
| 280 class CodegenWorkItemBuilder extends WorkItemBuilder { | |
| 281 Backend _backend; | |
| 282 CompilerOptions _options; | |
| 283 | |
| 284 CodegenWorkItemBuilder(this._backend, this._options); | |
| 285 | |
| 286 @override | |
| 287 WorkItem createWorkItem(MemberElement element) { | |
| 288 assert(invariant(element, element.isDeclaration)); | |
| 289 // Don't generate code for foreign elements. | |
| 290 if (_backend.isForeign(element)) return null; | |
| 291 if (element.isAbstract) return null; | |
| 292 | |
| 293 // Codegen inlines field initializers. It only needs to generate | |
| 294 // code for checked setters. | |
| 295 if (element.isField && element.isInstanceMember) { | |
| 296 if (!_options.enableTypeAssertions || | |
| 297 element.enclosingElement.isClosure) { | |
| 298 return null; | |
| 299 } | |
| 300 } | |
| 301 return new CodegenWorkItem(_backend, element); | |
| 302 } | |
| 303 } | |
| OLD | NEW |