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

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

Issue 2531303002: Decouple WorkItem from Compiler (Closed)
Patch Set: Updated cf. comments. 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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 /// Analysis to determine how to generate code for `LookupMap`s. 5 /// Analysis to determine how to generate code for `LookupMap`s.
6 library compiler.src.js_backend.lookup_map_analysis; 6 library compiler.src.js_backend.lookup_map_analysis;
7 7
8 import 'package:pub_semver/pub_semver.dart'; 8 import 'package:pub_semver/pub_semver.dart';
9 9
10 import '../common.dart'; 10 import '../common.dart';
11 import '../compiler.dart' show Compiler; 11 import '../compiler.dart' show Compiler;
12 import '../constants/values.dart' 12 import '../constants/values.dart'
13 show 13 show
14 ConstantValue, 14 ConstantValue,
15 ConstructedConstantValue, 15 ConstructedConstantValue,
16 ListConstantValue, 16 ListConstantValue,
17 NullConstantValue, 17 NullConstantValue,
18 StringConstantValue, 18 StringConstantValue,
19 TypeConstantValue; 19 TypeConstantValue;
20 import '../dart_types.dart' show DartType; 20 import '../dart_types.dart' show DartType;
21 import '../dart_types.dart' show InterfaceType; 21 import '../dart_types.dart' show InterfaceType;
22 import '../elements/elements.dart' 22 import '../elements/elements.dart'
23 show ClassElement, FieldElement, LibraryElement, VariableElement; 23 show ClassElement, FieldElement, LibraryElement, VariableElement;
24 import '../enqueue.dart'; 24 import '../universe/use.dart' show StaticUse;
25 import '../universe/world_impact.dart' 25 import '../universe/world_impact.dart'
26 show WorldImpact, StagedWorldImpactBuilder; 26 show WorldImpact, StagedWorldImpactBuilder;
27 import 'js_backend.dart' show JavaScriptBackend; 27 import 'js_backend.dart' show JavaScriptBackend;
28 28
29 /// An analysis and optimization to remove unused entries from a `LookupMap`. 29 /// An analysis and optimization to remove unused entries from a `LookupMap`.
30 /// 30 ///
31 /// `LookupMaps` are defined in `package:lookup_map/lookup_map.dart`. They are 31 /// `LookupMaps` are defined in `package:lookup_map/lookup_map.dart`. They are
32 /// simple maps that contain constant expressions as keys, and that only support 32 /// simple maps that contain constant expressions as keys, and that only support
33 /// the lookup operation. 33 /// the lookup operation.
34 /// 34 ///
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 /// runtime. Technically if we limit lookup-maps to check for identical keys, 113 /// runtime. Technically if we limit lookup-maps to check for identical keys,
114 /// we could allow const instances of these types. However, we internally use 114 /// we could allow const instances of these types. However, we internally use
115 /// a hash map within lookup-maps today, so we need this restriction. 115 /// a hash map within lookup-maps today, so we need this restriction.
116 final _typesWithEquals = <ClassElement, bool>{}; 116 final _typesWithEquals = <ClassElement, bool>{};
117 117
118 /// Pending work to do if we discover that a new key is in use. For each key 118 /// Pending work to do if we discover that a new key is in use. For each key
119 /// that we haven't seen, we record the list of lookup-maps that contain an 119 /// that we haven't seen, we record the list of lookup-maps that contain an
120 /// entry with that key. 120 /// entry with that key.
121 final _pending = <ConstantValue, List<_LookupMapInfo>>{}; 121 final _pending = <ConstantValue, List<_LookupMapInfo>>{};
122 122
123 final StagedWorldImpactBuilder impactBuilder = new StagedWorldImpactBuilder(); 123 final StagedWorldImpactBuilder impactBuilderForResolution =
124 new StagedWorldImpactBuilder();
125 final StagedWorldImpactBuilder impactBuilderForCodegen =
126 new StagedWorldImpactBuilder();
124 127
125 /// Whether the backend is currently processing the codegen queue. 128 /// Whether the backend is currently processing the codegen queue.
126 bool _inCodegen = false; 129 bool _inCodegen = false;
127 130
128 LookupMapAnalysis(this.backend, this.reporter); 131 LookupMapAnalysis(this.backend, this.reporter);
129 132
130 /// Compute the [WorldImpact] for the constants registered since last flush. 133 /// Compute the [WorldImpact] for the constants registered since last flush.
131 WorldImpact flush({bool forResolution}) { 134 WorldImpact flush({bool forResolution}) {
132 if (forResolution) return const WorldImpact(); 135 if (forResolution) {
133 return impactBuilder.flush(); 136 return impactBuilderForResolution.flush();
137 } else {
138 return impactBuilderForCodegen.flush();
139 }
134 } 140 }
135 141
136 /// Whether this analysis and optimization is enabled. 142 /// Whether this analysis and optimization is enabled.
137 bool get _isEnabled { 143 bool get _isEnabled {
138 // `lookupMap==off` kept here to make it easy to test disabling this feature 144 // `lookupMap==off` kept here to make it easy to test disabling this feature
139 if (const String.fromEnvironment('lookupMap') == 'off') return false; 145 if (const String.fromEnvironment('lookupMap') == 'off') return false;
140 return typeLookupMapClass != null; 146 return typeLookupMapClass != null;
141 } 147 }
142 148
143 /// Initializes this analysis by providing the resolved library. This is 149 /// Initializes this analysis by providing the resolved library. This is
144 /// invoked during resolution when the `lookup_map` library is discovered. 150 /// invoked during resolution when the `lookup_map` library is discovered.
145 void init(LibraryElement library) { 151 void init(LibraryElement library) {
146 lookupMapLibrary = library; 152 lookupMapLibrary = library;
147 // We will enable the lookupMapAnalysis as long as we get a known version of 153 // We will enable the lookupMapAnalysis as long as we get a known version of
148 // the lookup_map package. We otherwise produce a warning. 154 // the lookup_map package. We otherwise produce a warning.
149 lookupMapVersionVariable = library.implementation.findLocal('_version'); 155 lookupMapVersionVariable = library.implementation.findLocal('_version');
150 if (lookupMapVersionVariable == null) { 156 if (lookupMapVersionVariable == null) {
151 reporter.reportInfo( 157 reporter.reportInfo(
152 library, MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP); 158 library, MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP);
153 } else { 159 } else {
154 backend.compiler.enqueuer.resolution 160 impactBuilderForResolution.registerStaticUse(
155 .addToWorkList(lookupMapVersionVariable); 161 new StaticUse.foreignUse(lookupMapVersionVariable));
156 } 162 }
157 } 163 }
158 164
159 /// Checks if the version of lookup_map is valid, and if so, enable this 165 /// Checks if the version of lookup_map is valid, and if so, enable this
160 /// analysis during codegen. 166 /// analysis during codegen.
161 void onCodegenStart() { 167 void onCodegenStart() {
162 _inCodegen = true; 168 _inCodegen = true;
163 if (lookupMapVersionVariable == null) return; 169 if (lookupMapVersionVariable == null) return;
164 170
165 // At this point, the lookupMapVersionVariable should be resolved and it's 171 // At this point, the lookupMapVersionVariable should be resolved and it's
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 /// returned using a type-argument expression. 276 /// returned using a type-argument expression.
271 void _addGenerics(InterfaceType type) { 277 void _addGenerics(InterfaceType type) {
272 if (!type.isGeneric) return; 278 if (!type.isGeneric) return;
273 for (var arg in type.typeArguments) { 279 for (var arg in type.typeArguments) {
274 if (arg is InterfaceType) { 280 if (arg is InterfaceType) {
275 _addClassUse(arg.element); 281 _addClassUse(arg.element);
276 // Note: this call was needed to generate correct code for 282 // Note: this call was needed to generate correct code for
277 // type_lookup_map/generic_type_test 283 // type_lookup_map/generic_type_test
278 // TODO(sigmund): can we get rid of this? 284 // TODO(sigmund): can we get rid of this?
279 backend.computeImpactForInstantiatedConstantType( 285 backend.computeImpactForInstantiatedConstantType(
280 backend.backendClasses.typeImplementation.rawType, impactBuilder); 286 backend.backendClasses.typeImplementation.rawType,
287 impactBuilderForCodegen);
281 _addGenerics(arg); 288 _addGenerics(arg);
282 } 289 }
283 } 290 }
284 } 291 }
285 292
286 /// Callback from the codegen enqueuer, invoked when a constant (which is 293 /// Callback from the codegen enqueuer, invoked when a constant (which is
287 /// possibly a const key or a type literal) is used in the program. 294 /// possibly a const key or a type literal) is used in the program.
288 void registerTypeConstant(ClassElement element) { 295 void registerTypeConstant(ClassElement element) {
289 if (!_isEnabled || !_inCodegen) return; 296 if (!_isEnabled || !_inCodegen) return;
290 _addClassUse(element); 297 _addClassUse(element);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 418
412 /// Marks that [key] has been seen, and thus, the corresponding entry in this 419 /// Marks that [key] has been seen, and thus, the corresponding entry in this
413 /// map should be considered reachable. 420 /// map should be considered reachable.
414 _markUsed(ConstantValue key) { 421 _markUsed(ConstantValue key) {
415 assert(!emitted); 422 assert(!emitted);
416 assert(unusedEntries.containsKey(key)); 423 assert(unusedEntries.containsKey(key));
417 assert(!usedEntries.containsKey(key)); 424 assert(!usedEntries.containsKey(key));
418 ConstantValue constant = unusedEntries.remove(key); 425 ConstantValue constant = unusedEntries.remove(key);
419 usedEntries[key] = constant; 426 usedEntries[key] = constant;
420 analysis.backend.computeImpactForCompileTimeConstant( 427 analysis.backend.computeImpactForCompileTimeConstant(
421 constant, analysis.impactBuilder, false); 428 constant, analysis.impactBuilderForCodegen, false);
422 } 429 }
423 430
424 /// Restores [original] to contain all of the entries marked as possibly used. 431 /// Restores [original] to contain all of the entries marked as possibly used.
425 void _prepareForEmission() { 432 void _prepareForEmission() {
426 ListConstantValue originalEntries = original.fields[analysis.entriesField]; 433 ListConstantValue originalEntries = original.fields[analysis.entriesField];
427 DartType listType = originalEntries.type; 434 DartType listType = originalEntries.type;
428 List<ConstantValue> keyValuePairs = <ConstantValue>[]; 435 List<ConstantValue> keyValuePairs = <ConstantValue>[];
429 usedEntries.forEach((key, value) { 436 usedEntries.forEach((key, value) {
430 keyValuePairs.add(key); 437 keyValuePairs.add(key);
431 keyValuePairs.add(value); 438 keyValuePairs.add(value);
432 }); 439 });
433 440
434 // Note: we are restoring the entries here, see comment in [original]. 441 // Note: we are restoring the entries here, see comment in [original].
435 if (singlePair) { 442 if (singlePair) {
436 assert(keyValuePairs.length == 0 || keyValuePairs.length == 2); 443 assert(keyValuePairs.length == 0 || keyValuePairs.length == 2);
437 if (keyValuePairs.length == 2) { 444 if (keyValuePairs.length == 2) {
438 original.fields[analysis.keyField] = keyValuePairs[0]; 445 original.fields[analysis.keyField] = keyValuePairs[0];
439 original.fields[analysis.valueField] = keyValuePairs[1]; 446 original.fields[analysis.valueField] = keyValuePairs[1];
440 } 447 }
441 } else { 448 } else {
442 original.fields[analysis.entriesField] = 449 original.fields[analysis.entriesField] =
443 new ListConstantValue(listType, keyValuePairs); 450 new ListConstantValue(listType, keyValuePairs);
444 } 451 }
445 } 452 }
446 } 453 }
447 454
448 final _validLookupMapVersionConstraint = new VersionConstraint.parse('^0.0.1'); 455 final _validLookupMapVersionConstraint = new VersionConstraint.parse('^0.0.1');
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/enqueuer.dart ('k') | pkg/compiler/lib/src/js_backend/type_variable_handler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698