OLD | NEW |
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 '../common_elements.dart'; | 11 import '../common_elements.dart'; |
12 import '../common/backend_api.dart'; | |
13 import '../compile_time_constants.dart'; | 12 import '../compile_time_constants.dart'; |
14 import '../constants/constant_system.dart'; | 13 import '../constants/constant_system.dart'; |
15 import '../constants/values.dart' | 14 import '../constants/values.dart' |
16 show | 15 show |
17 ConstantValue, | 16 ConstantValue, |
18 ConstructedConstantValue, | 17 ConstructedConstantValue, |
19 ListConstantValue, | 18 ListConstantValue, |
20 NullConstantValue, | 19 NullConstantValue, |
21 StringConstantValue, | 20 StringConstantValue, |
22 TypeConstantValue; | 21 TypeConstantValue; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 // TODO(sigmund): detect uses of mirrors | 119 // TODO(sigmund): detect uses of mirrors |
121 class LookupMapAnalysis { | 120 class LookupMapAnalysis { |
122 const LookupMapAnalysis._(); | 121 const LookupMapAnalysis._(); |
123 | 122 |
124 factory LookupMapAnalysis( | 123 factory LookupMapAnalysis( |
125 DiagnosticReporter reporter, | 124 DiagnosticReporter reporter, |
126 ConstantSystem constantSystem, | 125 ConstantSystem constantSystem, |
127 ConstantEnvironment constants, | 126 ConstantEnvironment constants, |
128 ElementEnvironment elementEnvironment, | 127 ElementEnvironment elementEnvironment, |
129 CommonElements commonElements, | 128 CommonElements commonElements, |
130 BackendClasses backendClasses, | |
131 LookupMapResolutionAnalysis analysis) { | 129 LookupMapResolutionAnalysis analysis) { |
132 /// Checks if the version of lookup_map is valid, and if so, enable this | 130 /// Checks if the version of lookup_map is valid, and if so, enable this |
133 /// analysis during codegen. | 131 /// analysis during codegen. |
134 FieldElement lookupMapVersionVariable = analysis.lookupMapVersionVariable; | 132 FieldElement lookupMapVersionVariable = analysis.lookupMapVersionVariable; |
135 if (lookupMapVersionVariable == null) return const LookupMapAnalysis._(); | 133 if (lookupMapVersionVariable == null) return const LookupMapAnalysis._(); |
136 | 134 |
137 // At this point, the lookupMapVersionVariable should be resolved and it's | 135 // At this point, the lookupMapVersionVariable should be resolved and it's |
138 // constant value should be available. | 136 // constant value should be available. |
139 StringConstantValue value = | 137 StringConstantValue value = |
140 constants.getConstantValue(lookupMapVersionVariable.constant); | 138 constants.getConstantValue(lookupMapVersionVariable.constant); |
(...skipping 19 matching lines...) Expand all Loading... |
160 ClassEntity typeLookupMapClass = | 158 ClassEntity typeLookupMapClass = |
161 elementEnvironment.lookupClass(analysis.lookupMapLibrary, 'LookupMap'); | 159 elementEnvironment.lookupClass(analysis.lookupMapLibrary, 'LookupMap'); |
162 FieldElement entriesField = | 160 FieldElement entriesField = |
163 elementEnvironment.lookupClassMember(typeLookupMapClass, '_entries'); | 161 elementEnvironment.lookupClassMember(typeLookupMapClass, '_entries'); |
164 FieldElement keyField = | 162 FieldElement keyField = |
165 elementEnvironment.lookupClassMember(typeLookupMapClass, '_key'); | 163 elementEnvironment.lookupClassMember(typeLookupMapClass, '_key'); |
166 FieldElement valueField = | 164 FieldElement valueField = |
167 elementEnvironment.lookupClassMember(typeLookupMapClass, '_value'); | 165 elementEnvironment.lookupClassMember(typeLookupMapClass, '_value'); |
168 // TODO(sigmund): Maybe inline nested maps to make the output code smaller? | 166 // TODO(sigmund): Maybe inline nested maps to make the output code smaller? |
169 | 167 |
170 return new _LookupMapAnalysis(constantSystem, commonElements, | 168 return new _LookupMapAnalysis(constantSystem, commonElements, entriesField, |
171 backendClasses, entriesField, keyField, valueField, typeLookupMapClass); | 169 keyField, valueField, typeLookupMapClass); |
172 } | 170 } |
173 | 171 |
174 /// Compute the [WorldImpact] for the constants registered since last flush. | 172 /// Compute the [WorldImpact] for the constants registered since last flush. |
175 WorldImpact flush() => const WorldImpact(); | 173 WorldImpact flush() => const WorldImpact(); |
176 | 174 |
177 /// Whether [constant] is an instance of a `LookupMap`. | 175 /// Whether [constant] is an instance of a `LookupMap`. |
178 bool isLookupMap(ConstantValue constant) => false; | 176 bool isLookupMap(ConstantValue constant) => false; |
179 | 177 |
180 /// Registers an instance of a lookup-map with the analysis. | 178 /// Registers an instance of a lookup-map with the analysis. |
181 void registerLookupMapReference(ConstantValue lookupMap) {} | 179 void registerLookupMapReference(ConstantValue lookupMap) {} |
(...skipping 16 matching lines...) Expand all Loading... |
198 } | 196 } |
199 | 197 |
200 class _LookupMapAnalysis implements LookupMapAnalysis { | 198 class _LookupMapAnalysis implements LookupMapAnalysis { |
201 static final Uri PACKAGE_LOOKUP_MAP = | 199 static final Uri PACKAGE_LOOKUP_MAP = |
202 new Uri(scheme: 'package', path: 'lookup_map/lookup_map.dart'); | 200 new Uri(scheme: 'package', path: 'lookup_map/lookup_map.dart'); |
203 | 201 |
204 final ConstantSystem _constantSystem; | 202 final ConstantSystem _constantSystem; |
205 | 203 |
206 final CommonElements _commonElements; | 204 final CommonElements _commonElements; |
207 | 205 |
208 final BackendClasses _backendClasses; | |
209 | |
210 /// The resolved [ClassElement] associated with `LookupMap`. | 206 /// The resolved [ClassElement] associated with `LookupMap`. |
211 final ClassElement _typeLookupMapClass; | 207 final ClassElement _typeLookupMapClass; |
212 | 208 |
213 /// The resolved [FieldElement] for `LookupMap._entries`. | 209 /// The resolved [FieldElement] for `LookupMap._entries`. |
214 final FieldElement _entriesField; | 210 final FieldElement _entriesField; |
215 | 211 |
216 /// The resolved [FieldElement] for `LookupMap._key`. | 212 /// The resolved [FieldElement] for `LookupMap._key`. |
217 final FieldElement _keyField; | 213 final FieldElement _keyField; |
218 | 214 |
219 /// The resolved [FieldElement] for `LookupMap._value`. | 215 /// The resolved [FieldElement] for `LookupMap._value`. |
(...skipping 23 matching lines...) Expand all Loading... |
243 /// that we haven't seen, we record the list of lookup-maps that contain an | 239 /// that we haven't seen, we record the list of lookup-maps that contain an |
244 /// entry with that key. | 240 /// entry with that key. |
245 final _pending = <ConstantValue, List<_LookupMapInfo>>{}; | 241 final _pending = <ConstantValue, List<_LookupMapInfo>>{}; |
246 | 242 |
247 final StagedWorldImpactBuilder _impactBuilder = | 243 final StagedWorldImpactBuilder _impactBuilder = |
248 new StagedWorldImpactBuilder(); | 244 new StagedWorldImpactBuilder(); |
249 | 245 |
250 _LookupMapAnalysis( | 246 _LookupMapAnalysis( |
251 this._constantSystem, | 247 this._constantSystem, |
252 this._commonElements, | 248 this._commonElements, |
253 this._backendClasses, | |
254 this._entriesField, | 249 this._entriesField, |
255 this._keyField, | 250 this._keyField, |
256 this._valueField, | 251 this._valueField, |
257 this._typeLookupMapClass); | 252 this._typeLookupMapClass); |
258 | 253 |
259 /// Compute the [WorldImpact] for the constants registered since last flush. | 254 /// Compute the [WorldImpact] for the constants registered since last flush. |
260 WorldImpact flush() { | 255 WorldImpact flush() { |
261 return _impactBuilder.flush(); | 256 return _impactBuilder.flush(); |
262 } | 257 } |
263 | 258 |
(...skipping 24 matching lines...) Expand all Loading... |
288 } | 283 } |
289 | 284 |
290 /// Whether we need to preserve [key]. This is true for keys that are not | 285 /// Whether we need to preserve [key]. This is true for keys that are not |
291 /// candidates for tree-shaking in the first place (primitives and non-type | 286 /// candidates for tree-shaking in the first place (primitives and non-type |
292 /// const values overriding equals) and keys that we have seen in the program. | 287 /// const values overriding equals) and keys that we have seen in the program. |
293 bool _shouldKeep(ConstantValue key) => | 288 bool _shouldKeep(ConstantValue key) => |
294 key.isPrimitive || _inUse.contains(key) || _overridesEquals(key); | 289 key.isPrimitive || _inUse.contains(key) || _overridesEquals(key); |
295 | 290 |
296 void _addClassUse(ClassElement cls) { | 291 void _addClassUse(ClassElement cls) { |
297 ConstantValue key = _typeConstants.putIfAbsent( | 292 ConstantValue key = _typeConstants.putIfAbsent( |
298 cls, | 293 cls, () => _constantSystem.createType(_commonElements, cls.rawType)); |
299 () => _constantSystem.createType( | |
300 _commonElements, _backendClasses, cls.rawType)); | |
301 _addUse(key); | 294 _addUse(key); |
302 } | 295 } |
303 | 296 |
304 /// Record that [key] is used and update every lookup map that contains it. | 297 /// Record that [key] is used and update every lookup map that contains it. |
305 void _addUse(ConstantValue key) { | 298 void _addUse(ConstantValue key) { |
306 if (_inUse.add(key)) { | 299 if (_inUse.add(key)) { |
307 _pending[key]?.forEach((info) => info._markUsed(key)); | 300 _pending[key]?.forEach((info) => info._markUsed(key)); |
308 _pending.remove(key); | 301 _pending.remove(key); |
309 } | 302 } |
310 } | 303 } |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 original.fields[analysis._valueField] = keyValuePairs[1]; | 497 original.fields[analysis._valueField] = keyValuePairs[1]; |
505 } | 498 } |
506 } else { | 499 } else { |
507 original.fields[analysis._entriesField] = | 500 original.fields[analysis._entriesField] = |
508 new ListConstantValue(listType, keyValuePairs); | 501 new ListConstantValue(listType, keyValuePairs); |
509 } | 502 } |
510 } | 503 } |
511 } | 504 } |
512 | 505 |
513 final _validLookupMapVersionConstraint = new VersionConstraint.parse('^0.0.1'); | 506 final _validLookupMapVersionConstraint = new VersionConstraint.parse('^0.0.1'); |
OLD | NEW |