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 ClosureTask, ClosureFieldElement; | 10 import '../../closure.dart' show ClosureTask, 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 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
973 } | 975 } |
974 } | 976 } |
975 | 977 |
976 List<ParameterStubMethod> _generateParameterStubs( | 978 List<ParameterStubMethod> _generateParameterStubs( |
977 FunctionEntity element, bool canTearOff) { | 979 FunctionEntity element, bool canTearOff) { |
978 if (!_methodNeedsStubs(element)) return const <ParameterStubMethod>[]; | 980 if (!_methodNeedsStubs(element)) return const <ParameterStubMethod>[]; |
979 | 981 |
980 ParameterStubGenerator generator = new ParameterStubGenerator( | 982 ParameterStubGenerator generator = new ParameterStubGenerator( |
981 _commonElements, | 983 _commonElements, |
982 _task, | 984 _task, |
983 _constantHandler, | |
984 _namer, | 985 _namer, |
985 _nativeData, | 986 _nativeData, |
986 _interceptorData, | 987 _interceptorData, |
987 _worldBuilder, | 988 _worldBuilder, |
988 _closedWorld); | 989 _closedWorld); |
989 return generator.generateParameterStubs(element, canTearOff: canTearOff); | 990 return generator.generateParameterStubs(element, canTearOff: canTearOff); |
990 } | 991 } |
991 | 992 |
992 /// Builds a stub method. | 993 /// Builds a stub method. |
993 /// | 994 /// |
994 /// Stub methods may have an element that can be used for code-size | 995 /// Stub methods may have an element that can be used for code-size |
995 /// attribution. | 996 /// attribution. |
996 Method _buildStubMethod(js.Name name, js.Expression code, | 997 Method _buildStubMethod(js.Name name, js.Expression code, |
997 {MemberElement element}) { | 998 {MemberElement element}) { |
998 return new StubMethod(name, code, element: element); | 999 return new StubMethod(name, code, element: element); |
999 } | 1000 } |
1000 | 1001 |
1001 // The getInterceptor methods directly access the prototype of classes. | 1002 // The getInterceptor methods directly access the prototype of classes. |
1002 // We must evaluate these classes eagerly so that the prototype is | 1003 // We must evaluate these classes eagerly so that the prototype is |
1003 // accessible. | 1004 // accessible. |
1004 void _markEagerInterceptorClasses() { | 1005 void _markEagerInterceptorClasses() { |
1005 Iterable<js.Name> names = | 1006 Iterable<js.Name> names = |
1006 _oneShotInterceptorData.specializedGetInterceptorNames; | 1007 _oneShotInterceptorData.specializedGetInterceptorNames; |
1007 for (js.Name name in names) { | 1008 for (js.Name name in names) { |
1008 for (ClassElement element | 1009 for (ClassEntity element |
1009 in _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name)) { | 1010 in _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name)) { |
1010 Class cls = _classes[element]; | 1011 Class cls = _classes[element]; |
1011 if (cls != null) cls.isEager = true; | 1012 if (cls != null) cls.isEager = true; |
1012 } | 1013 } |
1013 } | 1014 } |
1014 } | 1015 } |
1015 | 1016 |
1016 Iterable<StaticStubMethod> _generateGetInterceptorMethods() { | 1017 Iterable<StaticStubMethod> _generateGetInterceptorMethods() { |
1017 InterceptorStubGenerator stubGenerator = new InterceptorStubGenerator( | 1018 InterceptorStubGenerator stubGenerator = new InterceptorStubGenerator( |
1018 _options, | 1019 _options, |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1186 Constant constant = new Constant(name, holder, constantValue); | 1187 Constant constant = new Constant(name, holder, constantValue); |
1187 _constants[constantValue] = constant; | 1188 _constants[constantValue] = constant; |
1188 } | 1189 } |
1189 } | 1190 } |
1190 | 1191 |
1191 Holder _registerStaticStateHolder() { | 1192 Holder _registerStaticStateHolder() { |
1192 return _registry.registerHolder(_namer.staticStateHolder, | 1193 return _registry.registerHolder(_namer.staticStateHolder, |
1193 isStaticStateHolder: true); | 1194 isStaticStateHolder: true); |
1194 } | 1195 } |
1195 } | 1196 } |
OLD | NEW |