OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_emitter.program_builder; | 5 library dart2js.js_emitter.program_builder; |
6 | 6 |
7 import 'dart:io'; | 7 import 'dart:io'; |
8 import 'dart:convert' show JSON; | 8 import 'dart:convert' show JSON; |
9 | 9 |
10 import '../../closure.dart' show ClosureConversionTask, ClosureFieldElement; | 10 import '../../closure.dart' show ClosureConversionTask, ClosureFieldElement; |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 Set<Class> _unneededNativeClasses; | 188 Set<Class> _unneededNativeClasses; |
189 | 189 |
190 /// Classes that have been allocated during a profile run. | 190 /// Classes that have been allocated during a profile run. |
191 /// | 191 /// |
192 /// These classes should not be soft-deferred. | 192 /// These classes should not be soft-deferred. |
193 /// | 193 /// |
194 /// Also contains classes that are not tracked by the profile run (like | 194 /// Also contains classes that are not tracked by the profile run (like |
195 /// interceptors, ...). | 195 /// interceptors, ...). |
196 Set<ClassElement> _notSoftDeferred; | 196 Set<ClassElement> _notSoftDeferred; |
197 | 197 |
| 198 Sorter get _sorter => _task.sorter; |
| 199 |
198 Program buildProgram({bool storeFunctionTypesInMetadata: false}) { | 200 Program buildProgram({bool storeFunctionTypesInMetadata: false}) { |
199 collector.collect(); | 201 collector.collect(); |
200 _initializeSoftDeferredMap(); | 202 _initializeSoftDeferredMap(); |
201 | 203 |
202 this._storeFunctionTypesInMetadata = storeFunctionTypesInMetadata; | 204 this._storeFunctionTypesInMetadata = storeFunctionTypesInMetadata; |
203 // Note: In rare cases (mostly tests) output units can be empty. This | 205 // Note: In rare cases (mostly tests) output units can be empty. This |
204 // happens when the deferred code is dead-code eliminated but we still need | 206 // happens when the deferred code is dead-code eliminated but we still need |
205 // to check that the library has been loaded. | 207 // to check that the library has been loaded. |
206 _deferredLoadTask.allOutputUnits.forEach(_registry.registerOutputUnit); | 208 _deferredLoadTask.allOutputUnits.forEach(_registry.registerOutputUnit); |
207 collector.outputClassLists.forEach(_registry.registerClasses); | 209 collector.outputClassLists.forEach(_registry.registerClasses); |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 // TODO(floitsch): we shouldn't update the registry in the middle of | 455 // TODO(floitsch): we shouldn't update the registry in the middle of |
454 // building a static field. (Note that the static-state holder was | 456 // building a static field. (Note that the static-state holder was |
455 // already registered earlier, and that we just call the register to get | 457 // already registered earlier, and that we just call the register to get |
456 // the holder-instance. | 458 // the holder-instance. |
457 return new StaticField( | 459 return new StaticField( |
458 element, name, _registerStaticStateHolder(), code, isFinal, isLazy); | 460 element, name, _registerStaticStateHolder(), code, isFinal, isLazy); |
459 } | 461 } |
460 | 462 |
461 List<StaticField> _buildStaticLazilyInitializedFields( | 463 List<StaticField> _buildStaticLazilyInitializedFields( |
462 LibrariesMap librariesMap) { | 464 LibrariesMap librariesMap) { |
463 Iterable<FieldElement> lazyFields = _constantHandler | 465 Iterable<FieldEntity> lazyFields = _constantHandler |
464 .getLazilyInitializedFieldsForEmission() | 466 .getLazilyInitializedFieldsForEmission() |
465 .where((element) => | 467 .where((FieldEntity element) => |
466 _deferredLoadTask.outputUnitForElement(element) == | 468 _deferredLoadTask.outputUnitForMember(element) == |
467 librariesMap.outputUnit); | 469 librariesMap.outputUnit); |
468 return Elements | 470 return _sorter |
469 .sortedByPosition(lazyFields) | 471 .sortMembers(lazyFields) |
470 .map(_buildLazyField) | 472 .map(_buildLazyField) |
471 .where((field) => field != null) // Happens when the field was unused. | 473 .where((field) => field != null) // Happens when the field was unused. |
472 .toList(growable: false); | 474 .toList(growable: false); |
473 } | 475 } |
474 | 476 |
475 StaticField _buildLazyField(FieldElement element) { | 477 StaticField _buildLazyField(FieldEntity element) { |
476 js.Expression code = _generatedCode[element]; | 478 js.Expression code = _generatedCode[element]; |
477 // The code is null if we ended up not needing the lazily | 479 // The code is null if we ended up not needing the lazily |
478 // initialized field after all because of constant folding | 480 // initialized field after all because of constant folding |
479 // before code generation. | 481 // before code generation. |
480 if (code == null) return null; | 482 if (code == null) return null; |
481 | 483 |
482 js.Name name = _namer.globalPropertyNameForMember(element); | 484 js.Name name = _namer.globalPropertyNameForMember(element); |
483 bool isFinal = element.isFinal; | 485 bool isFinal = !element.isAssignable; |
484 bool isLazy = true; | 486 bool isLazy = true; |
485 // TODO(floitsch): we shouldn't update the registry in the middle of | 487 // TODO(floitsch): we shouldn't update the registry in the middle of |
486 // building a static field. (Note that the static-state holder was | 488 // building a static field. (Note that the static-state holder was |
487 // already registered earlier, and that we just call the register to get | 489 // already registered earlier, and that we just call the register to get |
488 // the holder-instance. | 490 // the holder-instance. |
489 return new StaticField( | 491 return new StaticField( |
490 element, name, _registerStaticStateHolder(), code, isFinal, isLazy); | 492 element, name, _registerStaticStateHolder(), code, isFinal, isLazy); |
491 } | 493 } |
492 | 494 |
493 List<Library> _buildLibraries(LibrariesMap librariesMap) { | 495 List<Library> _buildLibraries(LibrariesMap librariesMap) { |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
976 } | 978 } |
977 } | 979 } |
978 | 980 |
979 List<ParameterStubMethod> _generateParameterStubs( | 981 List<ParameterStubMethod> _generateParameterStubs( |
980 FunctionEntity element, bool canTearOff) { | 982 FunctionEntity element, bool canTearOff) { |
981 if (!_methodNeedsStubs(element)) return const <ParameterStubMethod>[]; | 983 if (!_methodNeedsStubs(element)) return const <ParameterStubMethod>[]; |
982 | 984 |
983 ParameterStubGenerator generator = new ParameterStubGenerator( | 985 ParameterStubGenerator generator = new ParameterStubGenerator( |
984 _commonElements, | 986 _commonElements, |
985 _task, | 987 _task, |
986 _constantHandler, | |
987 _namer, | 988 _namer, |
988 _nativeData, | 989 _nativeData, |
989 _interceptorData, | 990 _interceptorData, |
990 _worldBuilder, | 991 _worldBuilder, |
991 _closedWorld); | 992 _closedWorld); |
992 return generator.generateParameterStubs(element, canTearOff: canTearOff); | 993 return generator.generateParameterStubs(element, canTearOff: canTearOff); |
993 } | 994 } |
994 | 995 |
995 /// Builds a stub method. | 996 /// Builds a stub method. |
996 /// | 997 /// |
997 /// Stub methods may have an element that can be used for code-size | 998 /// Stub methods may have an element that can be used for code-size |
998 /// attribution. | 999 /// attribution. |
999 Method _buildStubMethod(js.Name name, js.Expression code, | 1000 Method _buildStubMethod(js.Name name, js.Expression code, |
1000 {MemberElement element}) { | 1001 {MemberElement element}) { |
1001 return new StubMethod(name, code, element: element); | 1002 return new StubMethod(name, code, element: element); |
1002 } | 1003 } |
1003 | 1004 |
1004 // The getInterceptor methods directly access the prototype of classes. | 1005 // The getInterceptor methods directly access the prototype of classes. |
1005 // We must evaluate these classes eagerly so that the prototype is | 1006 // We must evaluate these classes eagerly so that the prototype is |
1006 // accessible. | 1007 // accessible. |
1007 void _markEagerInterceptorClasses() { | 1008 void _markEagerInterceptorClasses() { |
1008 Iterable<js.Name> names = | 1009 Iterable<js.Name> names = |
1009 _oneShotInterceptorData.specializedGetInterceptorNames; | 1010 _oneShotInterceptorData.specializedGetInterceptorNames; |
1010 for (js.Name name in names) { | 1011 for (js.Name name in names) { |
1011 for (ClassElement element | 1012 for (ClassEntity element |
1012 in _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name)) { | 1013 in _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name)) { |
1013 Class cls = _classes[element]; | 1014 Class cls = _classes[element]; |
1014 if (cls != null) cls.isEager = true; | 1015 if (cls != null) cls.isEager = true; |
1015 } | 1016 } |
1016 } | 1017 } |
1017 } | 1018 } |
1018 | 1019 |
1019 Iterable<StaticStubMethod> _generateGetInterceptorMethods() { | 1020 Iterable<StaticStubMethod> _generateGetInterceptorMethods() { |
1020 InterceptorStubGenerator stubGenerator = new InterceptorStubGenerator( | 1021 InterceptorStubGenerator stubGenerator = new InterceptorStubGenerator( |
1021 _options, | 1022 _options, |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1189 Constant constant = new Constant(name, holder, constantValue); | 1190 Constant constant = new Constant(name, holder, constantValue); |
1190 _constants[constantValue] = constant; | 1191 _constants[constantValue] = constant; |
1191 } | 1192 } |
1192 } | 1193 } |
1193 | 1194 |
1194 Holder _registerStaticStateHolder() { | 1195 Holder _registerStaticStateHolder() { |
1195 return _registry.registerHolder(_namer.staticStateHolder, | 1196 return _registry.registerHolder(_namer.staticStateHolder, |
1196 isStaticStateHolder: true); | 1197 isStaticStateHolder: true); |
1197 } | 1198 } |
1198 } | 1199 } |
OLD | NEW |