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 | |
200 Program buildProgram({bool storeFunctionTypesInMetadata: false}) { | 198 Program buildProgram({bool storeFunctionTypesInMetadata: false}) { |
201 collector.collect(); | 199 collector.collect(); |
202 _initializeSoftDeferredMap(); | 200 _initializeSoftDeferredMap(); |
203 | 201 |
204 this._storeFunctionTypesInMetadata = storeFunctionTypesInMetadata; | 202 this._storeFunctionTypesInMetadata = storeFunctionTypesInMetadata; |
205 // Note: In rare cases (mostly tests) output units can be empty. This | 203 // Note: In rare cases (mostly tests) output units can be empty. This |
206 // happens when the deferred code is dead-code eliminated but we still need | 204 // happens when the deferred code is dead-code eliminated but we still need |
207 // to check that the library has been loaded. | 205 // to check that the library has been loaded. |
208 _deferredLoadTask.allOutputUnits.forEach(_registry.registerOutputUnit); | 206 _deferredLoadTask.allOutputUnits.forEach(_registry.registerOutputUnit); |
209 collector.outputClassLists.forEach(_registry.registerClasses); | 207 collector.outputClassLists.forEach(_registry.registerClasses); |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 } | 431 } |
434 | 432 |
435 List<StaticField> _buildStaticNonFinalFields(LibrariesMap librariesMap) { | 433 List<StaticField> _buildStaticNonFinalFields(LibrariesMap librariesMap) { |
436 List<FieldEntity> staticNonFinalFields = | 434 List<FieldEntity> staticNonFinalFields = |
437 collector.outputStaticNonFinalFieldLists[librariesMap.outputUnit]; | 435 collector.outputStaticNonFinalFieldLists[librariesMap.outputUnit]; |
438 if (staticNonFinalFields == null) return const <StaticField>[]; | 436 if (staticNonFinalFields == null) return const <StaticField>[]; |
439 | 437 |
440 return staticNonFinalFields.map(_buildStaticField).toList(growable: false); | 438 return staticNonFinalFields.map(_buildStaticField).toList(growable: false); |
441 } | 439 } |
442 | 440 |
443 StaticField _buildStaticField(FieldEntity element) { | 441 StaticField _buildStaticField(FieldElement element) { |
444 ConstantValue initialValue = | 442 ConstantValue initialValue = |
445 _worldBuilder.getConstantFieldInitializer(element); | 443 _constantHandler.getConstantValue(element.constant); |
446 // TODO(zarah): The holder should not be registered during building of | 444 // TODO(zarah): The holder should not be registered during building of |
447 // a static field. | 445 // a static field. |
448 _registry.registerHolder(_namer.globalObjectForConstant(initialValue), | 446 _registry.registerHolder(_namer.globalObjectForConstant(initialValue), |
449 isConstantsHolder: true); | 447 isConstantsHolder: true); |
450 js.Expression code = _task.emitter.constantReference(initialValue); | 448 js.Expression code = _task.emitter.constantReference(initialValue); |
451 js.Name name = _namer.globalPropertyNameForMember(element); | 449 js.Name name = _namer.globalPropertyNameForMember(element); |
452 bool isFinal = false; | 450 bool isFinal = false; |
453 bool isLazy = false; | 451 bool isLazy = false; |
454 | 452 |
455 // TODO(floitsch): we shouldn't update the registry in the middle of | 453 // TODO(floitsch): we shouldn't update the registry in the middle of |
456 // building a static field. (Note that the static-state holder was | 454 // building a static field. (Note that the static-state holder was |
457 // already registered earlier, and that we just call the register to get | 455 // already registered earlier, and that we just call the register to get |
458 // the holder-instance. | 456 // the holder-instance. |
459 return new StaticField( | 457 return new StaticField( |
460 element, name, _registerStaticStateHolder(), code, isFinal, isLazy); | 458 element, name, _registerStaticStateHolder(), code, isFinal, isLazy); |
461 } | 459 } |
462 | 460 |
463 List<StaticField> _buildStaticLazilyInitializedFields( | 461 List<StaticField> _buildStaticLazilyInitializedFields( |
464 LibrariesMap librariesMap) { | 462 LibrariesMap librariesMap) { |
465 Iterable<FieldEntity> lazyFields = _constantHandler | 463 Iterable<FieldElement> lazyFields = _constantHandler |
466 .getLazilyInitializedFieldsForEmission() | 464 .getLazilyInitializedFieldsForEmission() |
467 .where((FieldEntity element) => | 465 .where((element) => |
468 _deferredLoadTask.outputUnitForMember(element) == | 466 _deferredLoadTask.outputUnitForElement(element) == |
469 librariesMap.outputUnit); | 467 librariesMap.outputUnit); |
470 return _sorter | 468 return Elements |
471 .sortMembers(lazyFields) | 469 .sortedByPosition(lazyFields) |
472 .map(_buildLazyField) | 470 .map(_buildLazyField) |
473 .where((field) => field != null) // Happens when the field was unused. | 471 .where((field) => field != null) // Happens when the field was unused. |
474 .toList(growable: false); | 472 .toList(growable: false); |
475 } | 473 } |
476 | 474 |
477 StaticField _buildLazyField(FieldEntity element) { | 475 StaticField _buildLazyField(FieldElement element) { |
478 js.Expression code = _generatedCode[element]; | 476 js.Expression code = _generatedCode[element]; |
479 // The code is null if we ended up not needing the lazily | 477 // The code is null if we ended up not needing the lazily |
480 // initialized field after all because of constant folding | 478 // initialized field after all because of constant folding |
481 // before code generation. | 479 // before code generation. |
482 if (code == null) return null; | 480 if (code == null) return null; |
483 | 481 |
484 js.Name name = _namer.globalPropertyNameForMember(element); | 482 js.Name name = _namer.globalPropertyNameForMember(element); |
485 bool isFinal = !element.isAssignable; | 483 bool isFinal = element.isFinal; |
486 bool isLazy = true; | 484 bool isLazy = true; |
487 // TODO(floitsch): we shouldn't update the registry in the middle of | 485 // TODO(floitsch): we shouldn't update the registry in the middle of |
488 // building a static field. (Note that the static-state holder was | 486 // building a static field. (Note that the static-state holder was |
489 // already registered earlier, and that we just call the register to get | 487 // already registered earlier, and that we just call the register to get |
490 // the holder-instance. | 488 // the holder-instance. |
491 return new StaticField( | 489 return new StaticField( |
492 element, name, _registerStaticStateHolder(), code, isFinal, isLazy); | 490 element, name, _registerStaticStateHolder(), code, isFinal, isLazy); |
493 } | 491 } |
494 | 492 |
495 List<Library> _buildLibraries(LibrariesMap librariesMap) { | 493 List<Library> _buildLibraries(LibrariesMap librariesMap) { |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 } | 976 } |
979 } | 977 } |
980 | 978 |
981 List<ParameterStubMethod> _generateParameterStubs( | 979 List<ParameterStubMethod> _generateParameterStubs( |
982 FunctionEntity element, bool canTearOff) { | 980 FunctionEntity element, bool canTearOff) { |
983 if (!_methodNeedsStubs(element)) return const <ParameterStubMethod>[]; | 981 if (!_methodNeedsStubs(element)) return const <ParameterStubMethod>[]; |
984 | 982 |
985 ParameterStubGenerator generator = new ParameterStubGenerator( | 983 ParameterStubGenerator generator = new ParameterStubGenerator( |
986 _commonElements, | 984 _commonElements, |
987 _task, | 985 _task, |
| 986 _constantHandler, |
988 _namer, | 987 _namer, |
989 _nativeData, | 988 _nativeData, |
990 _interceptorData, | 989 _interceptorData, |
991 _worldBuilder, | 990 _worldBuilder, |
992 _closedWorld); | 991 _closedWorld); |
993 return generator.generateParameterStubs(element, canTearOff: canTearOff); | 992 return generator.generateParameterStubs(element, canTearOff: canTearOff); |
994 } | 993 } |
995 | 994 |
996 /// Builds a stub method. | 995 /// Builds a stub method. |
997 /// | 996 /// |
998 /// Stub methods may have an element that can be used for code-size | 997 /// Stub methods may have an element that can be used for code-size |
999 /// attribution. | 998 /// attribution. |
1000 Method _buildStubMethod(js.Name name, js.Expression code, | 999 Method _buildStubMethod(js.Name name, js.Expression code, |
1001 {MemberElement element}) { | 1000 {MemberElement element}) { |
1002 return new StubMethod(name, code, element: element); | 1001 return new StubMethod(name, code, element: element); |
1003 } | 1002 } |
1004 | 1003 |
1005 // The getInterceptor methods directly access the prototype of classes. | 1004 // The getInterceptor methods directly access the prototype of classes. |
1006 // We must evaluate these classes eagerly so that the prototype is | 1005 // We must evaluate these classes eagerly so that the prototype is |
1007 // accessible. | 1006 // accessible. |
1008 void _markEagerInterceptorClasses() { | 1007 void _markEagerInterceptorClasses() { |
1009 Iterable<js.Name> names = | 1008 Iterable<js.Name> names = |
1010 _oneShotInterceptorData.specializedGetInterceptorNames; | 1009 _oneShotInterceptorData.specializedGetInterceptorNames; |
1011 for (js.Name name in names) { | 1010 for (js.Name name in names) { |
1012 for (ClassEntity element | 1011 for (ClassElement element |
1013 in _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name)) { | 1012 in _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name)) { |
1014 Class cls = _classes[element]; | 1013 Class cls = _classes[element]; |
1015 if (cls != null) cls.isEager = true; | 1014 if (cls != null) cls.isEager = true; |
1016 } | 1015 } |
1017 } | 1016 } |
1018 } | 1017 } |
1019 | 1018 |
1020 Iterable<StaticStubMethod> _generateGetInterceptorMethods() { | 1019 Iterable<StaticStubMethod> _generateGetInterceptorMethods() { |
1021 InterceptorStubGenerator stubGenerator = new InterceptorStubGenerator( | 1020 InterceptorStubGenerator stubGenerator = new InterceptorStubGenerator( |
1022 _options, | 1021 _options, |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1190 Constant constant = new Constant(name, holder, constantValue); | 1189 Constant constant = new Constant(name, holder, constantValue); |
1191 _constants[constantValue] = constant; | 1190 _constants[constantValue] = constant; |
1192 } | 1191 } |
1193 } | 1192 } |
1194 | 1193 |
1195 Holder _registerStaticStateHolder() { | 1194 Holder _registerStaticStateHolder() { |
1196 return _registry.registerHolder(_namer.staticStateHolder, | 1195 return _registry.registerHolder(_namer.staticStateHolder, |
1197 isStaticStateHolder: true); | 1196 isStaticStateHolder: true); |
1198 } | 1197 } |
1199 } | 1198 } |
OLD | NEW |