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

Side by Side Diff: pkg/compiler/lib/src/js_backend/enqueuer.dart

Issue 2590913002: Add WorkItemBuilder to abstract WorkItem creation from the enqueuers. (Closed)
Patch Set: Created 4 years 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.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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698