 Chromium Code Reviews
 Chromium Code Reviews Issue 2847343002:
  Add support for profile-based startup optimizations.  (Closed)
    
  
    Issue 2847343002:
  Add support for profile-based startup optimizations.  (Closed) 
  | 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'; | |
| 8 import 'dart:convert' show JSON; | |
| 9 | |
| 7 import '../../closure.dart' show ClosureTask, ClosureFieldElement; | 10 import '../../closure.dart' show ClosureTask, ClosureFieldElement; | 
| 8 import '../../common.dart'; | 11 import '../../common.dart'; | 
| 9 import '../../common/names.dart' show Names, Selectors; | 12 import '../../common/names.dart' show Names, Selectors; | 
| 10 import '../../constants/values.dart' | 13 import '../../constants/values.dart' | 
| 11 show ConstantValue, InterceptorConstantValue; | 14 show ConstantValue, InterceptorConstantValue; | 
| 12 import '../../common_elements.dart' show CommonElements, ElementEnvironment; | 15 import '../../common_elements.dart' show CommonElements, ElementEnvironment; | 
| 13 import '../../deferred_load.dart' show DeferredLoadTask, OutputUnit; | 16 import '../../deferred_load.dart' show DeferredLoadTask, OutputUnit; | 
| 14 import '../../elements/elements.dart' | 17 import '../../elements/elements.dart' | 
| 15 show | 18 show | 
| 16 ClassElement, | 19 ClassElement, | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 60 computeMixinClass, | 63 computeMixinClass, | 
| 61 Emitter, | 64 Emitter, | 
| 62 InterceptorStubGenerator, | 65 InterceptorStubGenerator, | 
| 63 MainCallStubGenerator, | 66 MainCallStubGenerator, | 
| 64 ParameterStubGenerator, | 67 ParameterStubGenerator, | 
| 65 RuntimeTypeGenerator, | 68 RuntimeTypeGenerator, | 
| 66 TypeTestProperties; | 69 TypeTestProperties; | 
| 67 import '../model.dart'; | 70 import '../model.dart'; | 
| 68 import '../sorter.dart'; | 71 import '../sorter.dart'; | 
| 69 | 72 | 
| 73 part 'allocated_classes_profile.dart'; | |
| 70 part 'collector.dart'; | 74 part 'collector.dart'; | 
| 71 part 'field_visitor.dart'; | 75 part 'field_visitor.dart'; | 
| 72 part 'registry.dart'; | 76 part 'registry.dart'; | 
| 73 | 77 | 
| 78 const allocatedClassesPath = | |
| 79 const String.fromEnvironment("dart2js.allocatedClasses"); | |
| 
sra1
2017/05/02 20:40:12
Can you make this a command-line option?
 
floitsch
2017/05/06 19:25:43
done.
 | |
| 80 | |
| 74 /// Builds a self-contained representation of the program that can then be | 81 /// Builds a self-contained representation of the program that can then be | 
| 75 /// emitted more easily by the individual emitters. | 82 /// emitted more easily by the individual emitters. | 
| 76 class ProgramBuilder { | 83 class ProgramBuilder { | 
| 77 final CompilerOptions _options; | 84 final CompilerOptions _options; | 
| 78 final ElementEnvironment _elementEnvironment; | 85 final ElementEnvironment _elementEnvironment; | 
| 79 final CommonElements _commonElements; | 86 final CommonElements _commonElements; | 
| 80 final DartTypes _types; | 87 final DartTypes _types; | 
| 81 final DeferredLoadTask _deferredLoadTask; | 88 final DeferredLoadTask _deferredLoadTask; | 
| 82 final ClosureTask _closureToClassMapper; | 89 final ClosureTask _closureToClassMapper; | 
| 83 final CodegenWorldBuilder _worldBuilder; | 90 final CodegenWorldBuilder _worldBuilder; | 
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 259 List<js.TokenFinalizer> finalizers = [_task.metadataCollector]; | 266 List<js.TokenFinalizer> finalizers = [_task.metadataCollector]; | 
| 260 if (_namer is js.TokenFinalizer) { | 267 if (_namer is js.TokenFinalizer) { | 
| 261 var namingFinalizer = _namer; | 268 var namingFinalizer = _namer; | 
| 262 finalizers.add(namingFinalizer as js.TokenFinalizer); | 269 finalizers.add(namingFinalizer as js.TokenFinalizer); | 
| 263 } | 270 } | 
| 264 | 271 | 
| 265 return new Program(fragments, holders, _buildLoadMap(), _symbolsMap, | 272 return new Program(fragments, holders, _buildLoadMap(), _symbolsMap, | 
| 266 _buildTypeToInterceptorMap(), _task.metadataCollector, finalizers, | 273 _buildTypeToInterceptorMap(), _task.metadataCollector, finalizers, | 
| 267 needsNativeSupport: needsNativeSupport, | 274 needsNativeSupport: needsNativeSupport, | 
| 268 outputContainsConstantList: collector.outputContainsConstantList, | 275 outputContainsConstantList: collector.outputContainsConstantList, | 
| 269 hasIsolateSupport: _backendUsage.isIsolateInUse); | 276 hasIsolateSupport: _backendUsage.isIsolateInUse, | 
| 277 hasSoftDeferredClasses: _notSoftDeferred != null); | |
| 270 } | 278 } | 
| 271 | 279 | 
| 272 void _markEagerClasses() { | 280 void _markEagerClasses() { | 
| 273 _markEagerInterceptorClasses(); | 281 _markEagerInterceptorClasses(); | 
| 274 } | 282 } | 
| 275 | 283 | 
| 276 /// Builds a map from loadId to outputs-to-load. | 284 /// Builds a map from loadId to outputs-to-load. | 
| 277 Map<String, List<Fragment>> _buildLoadMap() { | 285 Map<String, List<Fragment>> _buildLoadMap() { | 
| 278 Map<String, List<Fragment>> loadMap = <String, List<Fragment>>{}; | 286 Map<String, List<Fragment>> loadMap = <String, List<Fragment>>{}; | 
| 279 _deferredLoadTask.hunksToLoad | 287 _deferredLoadTask.hunksToLoad | 
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 577 .toList(growable: false); | 585 .toList(growable: false); | 
| 578 | 586 | 
| 579 bool visitStatics = true; | 587 bool visitStatics = true; | 
| 580 List<Field> staticFieldsForReflection = | 588 List<Field> staticFieldsForReflection = | 
| 581 _buildFields(library, visitStatics: visitStatics); | 589 _buildFields(library, visitStatics: visitStatics); | 
| 582 | 590 | 
| 583 return new Library( | 591 return new Library( | 
| 584 library, uri, statics, classes, staticFieldsForReflection); | 592 library, uri, statics, classes, staticFieldsForReflection); | 
| 585 } | 593 } | 
| 586 | 594 | 
| 595 Set<ClassElement> _notSoftDeferred; | |
| 596 | |
| 597 bool _isSoftDeferred(ClassElement element) { | |
| 598 if (_notSoftDeferred == null && | |
| 599 (allocatedClassesPath != null || allocatedClassesJson != null)) { | |
| 
sra1
2017/05/02 20:40:13
Does this execute once?
Perhaps make it more clear
 
floitsch
2017/05/06 19:25:43
done.
 | |
| 600 var blackList = [ | |
| 601 'dart:_interceptors', | |
| 602 'dart:html', | |
| 603 'dart:typed_data_implementation', | |
| 604 'dart:_native_typed_data' | |
| 605 ].toSet(); | |
| 606 String data = allocatedClassesPath != null | |
| 607 ? new File(allocatedClassesPath).readAsStringSync() | |
| 608 : allocatedClassesJson; | |
| 609 Set<String> allocatedClassesKeys = JSON.decode(data).keys.toSet(); | |
| 610 Set<ClassElement> allocatedClasses = new Set<ClassElement>(); | |
| 611 | |
| 612 void collect(ClassElement element) { | |
| 613 allocatedClasses.add(element); | |
| 614 if (element.isMixinApplication) { | |
| 615 collect(computeMixinClass(element)); | |
| 616 } | |
| 617 if (element.superclass != null) { | |
| 618 collect(element.superclass); | |
| 619 } | |
| 620 } | |
| 621 | |
| 622 collector.outputClassLists.forEach((_, List<ClassElement> elements) { | |
| 623 for (ClassElement element in elements) { | |
| 624 var key = "${element.library.canonicalUri}:${element.name}"; | |
| 625 if (allocatedClassesKeys.contains(key) || | |
| 626 _nativeData.isJsInteropClass(element) || | |
| 627 blackList.contains(element.library.canonicalUri.toString())) { | |
| 628 collect(element); | |
| 629 } | |
| 630 } | |
| 631 }); | |
| 632 _notSoftDeferred = allocatedClasses; | |
| 633 } | |
| 634 if (_notSoftDeferred == null) return false; | |
| 635 return !_notSoftDeferred.contains(element); | |
| 636 } | |
| 637 | |
| 587 Class _buildClass(ClassElement element) { | 638 Class _buildClass(ClassElement element) { | 
| 588 bool onlyForRti = collector.classesOnlyNeededForRti.contains(element); | 639 bool onlyForRti = collector.classesOnlyNeededForRti.contains(element); | 
| 589 bool hasRtiField = _rtiNeed.classNeedsRtiField(element); | 640 bool hasRtiField = _rtiNeed.classNeedsRtiField(element); | 
| 590 if (_nativeData.isJsInteropClass(element)) { | 641 if (_nativeData.isJsInteropClass(element)) { | 
| 591 // TODO(jacobr): check whether the class has any active static fields | 642 // TODO(jacobr): check whether the class has any active static fields | 
| 592 // if it does not we can suppress it completely. | 643 // if it does not we can suppress it completely. | 
| 593 onlyForRti = true; | 644 onlyForRti = true; | 
| 594 } | 645 } | 
| 595 bool isClosureBaseClass = element == _commonElements.closureClass; | 646 bool isClosureBaseClass = element == _commonElements.closureClass; | 
| 596 | 647 | 
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 745 staticFieldsForReflection, | 796 staticFieldsForReflection, | 
| 746 callStubs, | 797 callStubs, | 
| 747 noSuchMethodStubs, | 798 noSuchMethodStubs, | 
| 748 checkedSetters, | 799 checkedSetters, | 
| 749 isChecks, | 800 isChecks, | 
| 750 typeTests.functionTypeIndex, | 801 typeTests.functionTypeIndex, | 
| 751 isDirectlyInstantiated: isInstantiated, | 802 isDirectlyInstantiated: isInstantiated, | 
| 752 hasRtiField: hasRtiField, | 803 hasRtiField: hasRtiField, | 
| 753 onlyForRti: onlyForRti, | 804 onlyForRti: onlyForRti, | 
| 754 isNative: _nativeData.isNativeClass(element), | 805 isNative: _nativeData.isNativeClass(element), | 
| 755 isClosureBaseClass: isClosureBaseClass); | 806 isClosureBaseClass: isClosureBaseClass, | 
| 807 isSoftDeferred: _isSoftDeferred(element)); | |
| 756 } | 808 } | 
| 757 _classes[element] = result; | 809 _classes[element] = result; | 
| 758 return result; | 810 return result; | 
| 759 } | 811 } | 
| 760 | 812 | 
| 761 bool _methodNeedsStubs(FunctionElement method) { | 813 bool _methodNeedsStubs(FunctionElement method) { | 
| 762 return !method.functionSignature.optionalParameters.isEmpty; | 814 return !method.functionSignature.optionalParameters.isEmpty; | 
| 763 } | 815 } | 
| 764 | 816 | 
| 765 bool _methodCanBeReflected(MethodElement method) { | 817 bool _methodCanBeReflected(MethodElement method) { | 
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1102 Constant constant = new Constant(name, holder, constantValue); | 1154 Constant constant = new Constant(name, holder, constantValue); | 
| 1103 _constants[constantValue] = constant; | 1155 _constants[constantValue] = constant; | 
| 1104 } | 1156 } | 
| 1105 } | 1157 } | 
| 1106 | 1158 | 
| 1107 Holder _registerStaticStateHolder() { | 1159 Holder _registerStaticStateHolder() { | 
| 1108 return _registry.registerHolder(_namer.staticStateHolder, | 1160 return _registry.registerHolder(_namer.staticStateHolder, | 
| 1109 isStaticStateHolder: true); | 1161 isStaticStateHolder: true); | 
| 1110 } | 1162 } | 
| 1111 } | 1163 } | 
| OLD | NEW |