Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(221)

Side by Side Diff: pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart

Issue 2994333002: Various redemptions (Closed)
Patch Set: Fix + status updates Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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;
11 import '../../common.dart'; 11 import '../../common.dart';
12 import '../../common/names.dart' show Names, Selectors; 12 import '../../common/names.dart' show Names, Selectors;
13 import '../../constants/values.dart' 13 import '../../constants/values.dart'
14 show ConstantValue, InterceptorConstantValue; 14 show ConstantValue, InterceptorConstantValue;
15 import '../../common_elements.dart' show CommonElements, ElementEnvironment; 15 import '../../common_elements.dart' show CommonElements, ElementEnvironment;
16 import '../../deferred_load.dart' show DeferredLoadTask, OutputUnit; 16 import '../../deferred_load.dart' show DeferredLoadTask, OutputUnit;
17 import '../../elements/elements.dart' 17 import '../../elements/elements.dart'
18 show 18 show ClassElement, FieldElement, LibraryElement, MethodElement;
19 ClassElement,
20 FieldElement,
21 FunctionSignature,
22 LibraryElement,
23 MemberElement,
24 MethodElement,
25 ParameterElement;
26 import '../../elements/entities.dart'; 19 import '../../elements/entities.dart';
27 import '../../elements/resolution_types.dart' show ResolutionDartType;
28 import '../../elements/types.dart'; 20 import '../../elements/types.dart';
29 import '../../js/js.dart' as js; 21 import '../../js/js.dart' as js;
30 import '../../js_backend/backend.dart' show SuperMemberData; 22 import '../../js_backend/backend.dart' show SuperMemberData;
31 import '../../js_backend/backend_usage.dart'; 23 import '../../js_backend/backend_usage.dart';
32 import '../../js_backend/constant_handler_javascript.dart' 24 import '../../js_backend/constant_handler_javascript.dart'
33 show JavaScriptConstantCompiler; 25 show JavaScriptConstantCompiler;
34 import '../../js_backend/custom_elements_analysis.dart'; 26 import '../../js_backend/custom_elements_analysis.dart';
35 import '../../js_backend/namer.dart' show Namer, StringBackedName; 27 import '../../js_backend/namer.dart' show Namer, StringBackedName;
36 import '../../js_backend/native_data.dart'; 28 import '../../js_backend/native_data.dart';
37 import '../../js_backend/interceptor_data.dart'; 29 import '../../js_backend/interceptor_data.dart';
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 final Map<js.Name, String> _symbolsMap = <js.Name, String>{}; 177 final Map<js.Name, String> _symbolsMap = <js.Name, String>{};
186 178
187 Set<Class> _unneededNativeClasses; 179 Set<Class> _unneededNativeClasses;
188 180
189 /// Classes that have been allocated during a profile run. 181 /// Classes that have been allocated during a profile run.
190 /// 182 ///
191 /// These classes should not be soft-deferred. 183 /// These classes should not be soft-deferred.
192 /// 184 ///
193 /// Also contains classes that are not tracked by the profile run (like 185 /// Also contains classes that are not tracked by the profile run (like
194 /// interceptors, ...). 186 /// interceptors, ...).
195 Set<ClassElement> _notSoftDeferred; 187 Set<ClassEntity> _notSoftDeferred;
196 188
197 Program buildProgram({bool storeFunctionTypesInMetadata: false}) { 189 Program buildProgram({bool storeFunctionTypesInMetadata: false}) {
198 collector.collect(); 190 collector.collect();
199 _initializeSoftDeferredMap(); 191 _initializeSoftDeferredMap();
200 192
201 this._storeFunctionTypesInMetadata = storeFunctionTypesInMetadata; 193 this._storeFunctionTypesInMetadata = storeFunctionTypesInMetadata;
202 // Note: In rare cases (mostly tests) output units can be empty. This 194 // Note: In rare cases (mostly tests) output units can be empty. This
203 // happens when the deferred code is dead-code eliminated but we still need 195 // happens when the deferred code is dead-code eliminated but we still need
204 // to check that the library has been loaded. 196 // to check that the library has been loaded.
205 _deferredLoadTask.allOutputUnits.forEach(_registry.registerOutputUnit); 197 _deferredLoadTask.allOutputUnits.forEach(_registry.registerOutputUnit);
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 _reporter.log("Profile file does not exist: $allocatedClassesPath"); 311 _reporter.log("Profile file does not exist: $allocatedClassesPath");
320 return; 312 return;
321 } 313 }
322 if (file.lengthSync() == 0) { 314 if (file.lengthSync() == 0) {
323 _reporter.log("Profile information (allocated classes) is empty."); 315 _reporter.log("Profile information (allocated classes) is empty.");
324 return; 316 return;
325 } 317 }
326 318
327 String data = new File(allocatedClassesPath).readAsStringSync(); 319 String data = new File(allocatedClassesPath).readAsStringSync();
328 Set<String> allocatedClassesKeys = JSON.decode(data).keys.toSet(); 320 Set<String> allocatedClassesKeys = JSON.decode(data).keys.toSet();
329 Set<ClassElement> allocatedClasses = new Set<ClassElement>(); 321 Set<ClassEntity> allocatedClasses = new Set<ClassEntity>();
330 322
331 // Collects all super and mixin classes of a class. 323 // Collects all super and mixin classes of a class.
332 void collect(ClassElement element) { 324 void collect(ClassEntity element) {
333 allocatedClasses.add(element); 325 allocatedClasses.add(element);
334 if (element.isMixinApplication) { 326 if (_elementEnvironment.isMixinApplication(element)) {
335 collect(_elementEnvironment.getEffectiveMixinClass(element)); 327 collect(_elementEnvironment.getEffectiveMixinClass(element));
336 } 328 }
337 if (element.superclass != null) { 329 ClassEntity superclass = _elementEnvironment.getSuperClass(element);
338 collect(element.superclass); 330 if (superclass != null) {
331 collect(superclass);
339 } 332 }
340 } 333 }
341 334
342 // For every known class, see if it was allocated in the profile. If yes, 335 // For every known class, see if it was allocated in the profile. If yes,
343 // collect its dependencies (supers and mixins) and mark them as 336 // collect its dependencies (supers and mixins) and mark them as
344 // not-soft-deferrable. 337 // not-soft-deferrable.
345 collector.outputClassLists.forEach((_, List<ClassEntity> elements) { 338 collector.outputClassLists.forEach((_, List<ClassEntity> elements) {
346 for (ClassElement element in elements) { 339 for (ClassEntity element in elements) {
347 // TODO(29574): share the encoding of the element with the code 340 // TODO(29574): share the encoding of the element with the code
348 // that emits the profile-run. 341 // that emits the profile-run.
349 var key = "${element.library.canonicalUri}:${element.name}"; 342 var key = "${element.library.canonicalUri}:${element.name}";
350 if (allocatedClassesKeys.contains(key) || 343 if (allocatedClassesKeys.contains(key) ||
351 _nativeData.isJsInteropClass(element) || 344 _nativeData.isJsInteropClass(element) ||
352 blackList.contains(element.library.canonicalUri.toString())) { 345 blackList.contains(element.library.canonicalUri.toString())) {
353 collect(element); 346 collect(element);
354 } 347 }
355 } 348 }
356 }); 349 });
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 } 548 }
556 } 549 }
557 550
558 // Generating stubs for direct calls and stubs for call-through 551 // Generating stubs for direct calls and stubs for call-through
559 // of getters that happen to be functions. 552 // of getters that happen to be functions.
560 bool isFunctionLike = false; 553 bool isFunctionLike = false;
561 FunctionType functionType = null; 554 FunctionType functionType = null;
562 555
563 if (member.isFunction) { 556 if (member.isFunction) {
564 MethodElement fn = member; 557 MethodElement fn = member;
565 functionType = fn.type; 558 functionType = _elementEnvironment.getFunctionType(fn);
566 } else if (member.isGetter) { 559 } else if (member.isGetter) {
567 if (_options.trustTypeAnnotations) { 560 if (_options.trustTypeAnnotations) {
568 DartType returnType = 561 DartType returnType =
569 _elementEnvironment.getFunctionType(member).returnType; 562 _elementEnvironment.getFunctionType(member).returnType;
570 if (returnType.isFunctionType) { 563 if (returnType.isFunctionType) {
571 functionType = returnType; 564 functionType = returnType;
572 } else if (returnType.treatAsDynamic || 565 } else if (returnType.treatAsDynamic ||
573 _types.isSubtype( 566 _types.isSubtype(
574 returnType, 567 returnType,
575 // ignore: UNNECESSARY_CAST 568 // ignore: UNNECESSARY_CAST
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
779 if (_nativeData.isJsInteropClass(cls)) { 772 if (_nativeData.isJsInteropClass(cls)) {
780 typeTests.forEachProperty(_sorter, (js.Name name, js.Node code) { 773 typeTests.forEachProperty(_sorter, (js.Name name, js.Node code) {
781 _classes[_commonElements.jsInterceptorClass] 774 _classes[_commonElements.jsInterceptorClass]
782 .isChecks 775 .isChecks
783 .add(_buildStubMethod(name, code)); 776 .add(_buildStubMethod(name, code));
784 }); 777 });
785 } else { 778 } else {
786 for (Field field in instanceFields) { 779 for (Field field in instanceFields) {
787 if (field.needsCheckedSetter) { 780 if (field.needsCheckedSetter) {
788 assert(!field.needsUncheckedSetter); 781 assert(!field.needsUncheckedSetter);
789 FieldElement element = field.element; 782 FieldEntity element = field.element;
790 js.Expression code = _generatedCode[element]; 783 js.Expression code = _generatedCode[element];
791 assert(code != null); 784 assert(code != null);
792 js.Name name = _namer.deriveSetterName(field.accessorName); 785 js.Name name = _namer.deriveSetterName(field.accessorName);
793 checkedSetters.add(_buildStubMethod(name, code, element: element)); 786 checkedSetters.add(_buildStubMethod(name, code, element: element));
794 } 787 }
795 } 788 }
796 789
797 typeTests.forEachProperty(_sorter, (js.Name name, js.Node code) { 790 typeTests.forEachProperty(_sorter, (js.Name name, js.Node code) {
798 isChecks.add(_buildStubMethod(name, code)); 791 isChecks.add(_buildStubMethod(name, code));
799 }); 792 });
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 849
857 bool _methodCanBeReflected(FunctionEntity method) { 850 bool _methodCanBeReflected(FunctionEntity method) {
858 return _mirrorsData.isMemberAccessibleByReflection(method); 851 return _mirrorsData.isMemberAccessibleByReflection(method);
859 } 852 }
860 853
861 bool _methodCanBeApplied(FunctionEntity method) { 854 bool _methodCanBeApplied(FunctionEntity method) {
862 return _backendUsage.isFunctionApplyUsed && 855 return _backendUsage.isFunctionApplyUsed &&
863 _closedWorld.getMightBePassedToApply(method); 856 _closedWorld.getMightBePassedToApply(method);
864 } 857 }
865 858
866 /* Map | List */ _computeParameterDefaultValues(FunctionSignature signature) { 859 /* Map | List */ _computeParameterDefaultValues(FunctionEntity method) {
867 var /* Map | List */ optionalParameterDefaultValues; 860 var /* Map | List */ optionalParameterDefaultValues;
868 if (signature.optionalParametersAreNamed) { 861 ParameterStructure parameterStructure = method.parameterStructure;
862 if (parameterStructure.namedParameters.isNotEmpty) {
869 optionalParameterDefaultValues = new Map<String, ConstantValue>(); 863 optionalParameterDefaultValues = new Map<String, ConstantValue>();
870 signature.forEachOptionalParameter((_parameter) { 864 _worldBuilder.forEachParameter(method,
871 ParameterElement parameter = _parameter; 865 (DartType type, String name, ConstantValue defaultValue) {
872 ConstantValue def = 866 if (parameterStructure.namedParameters.contains(name)) {
873 _constantHandler.getConstantValue(parameter.constant); 867 assert(defaultValue != null);
874 optionalParameterDefaultValues[parameter.name] = def; 868 optionalParameterDefaultValues[name] = defaultValue;
869 }
875 }); 870 });
876 } else { 871 } else {
877 optionalParameterDefaultValues = <ConstantValue>[]; 872 optionalParameterDefaultValues = <ConstantValue>[];
878 signature.forEachOptionalParameter((_parameter) { 873 int index = 0;
879 ParameterElement parameter = _parameter; 874 _worldBuilder.forEachParameter(method,
880 ConstantValue def = 875 (DartType type, String name, ConstantValue defaultValue) {
881 _constantHandler.getConstantValue(parameter.constant); 876 if (index >= parameterStructure.requiredParameters) {
882 optionalParameterDefaultValues.add(def); 877 assert(defaultValue != null);
878 optionalParameterDefaultValues.add(defaultValue);
879 }
880 index++;
883 }); 881 });
884 } 882 }
885 return optionalParameterDefaultValues; 883 return optionalParameterDefaultValues;
886 } 884 }
887 885
888 DartMethod _buildMethod(FunctionEntity element) { 886 DartMethod _buildMethod(FunctionEntity element) {
889 assert(!(element is MethodElement && !element.isDeclaration)); 887 assert(!(element is MethodElement && !element.isDeclaration));
890 js.Name name = _namer.methodPropertyName(element); 888 js.Name name = _namer.methodPropertyName(element);
891 js.Expression code = _generatedCode[element]; 889 js.Expression code = _generatedCode[element];
892 890
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 js.Expression functionType; 936 js.Expression functionType;
939 if (canTearOff || canBeReflected) { 937 if (canTearOff || canBeReflected) {
940 OutputUnit outputUnit = _deferredLoadTask.outputUnitForMember(element); 938 OutputUnit outputUnit = _deferredLoadTask.outputUnitForMember(element);
941 functionType = _generateFunctionType(memberType, outputUnit); 939 functionType = _generateFunctionType(memberType, outputUnit);
942 } 940 }
943 941
944 int requiredParameterCount; 942 int requiredParameterCount;
945 var /* List | Map */ optionalParameterDefaultValues; 943 var /* List | Map */ optionalParameterDefaultValues;
946 if (canBeApplied || canBeReflected) { 944 if (canBeApplied || canBeReflected) {
947 // TODO(redemption): Handle function entities. 945 // TODO(redemption): Handle function entities.
948 MethodElement method = element; 946 FunctionEntity method = element;
949 FunctionSignature signature = method.functionSignature; 947 ParameterStructure parameterStructure = method.parameterStructure;
950 requiredParameterCount = signature.requiredParameterCount; 948 requiredParameterCount = parameterStructure.requiredParameters;
951 optionalParameterDefaultValues = 949 optionalParameterDefaultValues = _computeParameterDefaultValues(method);
952 _computeParameterDefaultValues(signature);
953 } 950 }
954 951
955 return new InstanceMethod(element, name, code, 952 return new InstanceMethod(element, name, code,
956 _generateParameterStubs(element, canTearOff), callName, 953 _generateParameterStubs(element, canTearOff), callName,
957 needsTearOff: canTearOff, 954 needsTearOff: canTearOff,
958 tearOffName: tearOffName, 955 tearOffName: tearOffName,
959 isClosureCallMethod: isClosureCallMethod, 956 isClosureCallMethod: isClosureCallMethod,
960 aliasName: aliasName, 957 aliasName: aliasName,
961 canBeApplied: canBeApplied, 958 canBeApplied: canBeApplied,
962 canBeReflected: canBeReflected, 959 canBeReflected: canBeReflected,
(...skipping 25 matching lines...) Expand all
988 _worldBuilder, 985 _worldBuilder,
989 _closedWorld); 986 _closedWorld);
990 return generator.generateParameterStubs(element, canTearOff: canTearOff); 987 return generator.generateParameterStubs(element, canTearOff: canTearOff);
991 } 988 }
992 989
993 /// Builds a stub method. 990 /// Builds a stub method.
994 /// 991 ///
995 /// Stub methods may have an element that can be used for code-size 992 /// Stub methods may have an element that can be used for code-size
996 /// attribution. 993 /// attribution.
997 Method _buildStubMethod(js.Name name, js.Expression code, 994 Method _buildStubMethod(js.Name name, js.Expression code,
998 {MemberElement element}) { 995 {MemberEntity element}) {
999 return new StubMethod(name, code, element: element); 996 return new StubMethod(name, code, element: element);
1000 } 997 }
1001 998
1002 // The getInterceptor methods directly access the prototype of classes. 999 // The getInterceptor methods directly access the prototype of classes.
1003 // We must evaluate these classes eagerly so that the prototype is 1000 // We must evaluate these classes eagerly so that the prototype is
1004 // accessible. 1001 // accessible.
1005 void _markEagerInterceptorClasses() { 1002 void _markEagerInterceptorClasses() {
1006 Iterable<js.Name> names = 1003 Iterable<js.Name> names =
1007 _oneShotInterceptorData.specializedGetInterceptorNames; 1004 _oneShotInterceptorData.specializedGetInterceptorNames;
1008 for (js.Name name in names) { 1005 for (js.Name name in names) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1078 setterFlags += 2; 1075 setterFlags += 2;
1079 if (!isHolderInterceptedClass) { 1076 if (!isHolderInterceptedClass) {
1080 setterFlags += 1; 1077 setterFlags += 1;
1081 } 1078 }
1082 } 1079 }
1083 } 1080 }
1084 fields.add(new Field(field, name, accessorName, getterFlags, setterFlags, 1081 fields.add(new Field(field, name, accessorName, getterFlags, setterFlags,
1085 needsCheckedSetter)); 1082 needsCheckedSetter));
1086 } 1083 }
1087 1084
1088 FieldVisitor visitor = new FieldVisitor(_options, _elementEnvironment, 1085 FieldVisitor visitor = new FieldVisitor(
1089 _worldBuilder, _nativeData, _mirrorsData, _namer, _closedWorld); 1086 _options,
1087 _elementEnvironment,
1088 _commonElements,
1089 _worldBuilder,
1090 _nativeData,
1091 _mirrorsData,
1092 _namer,
1093 _closedWorld);
1090 visitor.visitFields(visitField, 1094 visitor.visitFields(visitField,
1091 visitStatics: visitStatics, library: library, cls: cls); 1095 visitStatics: visitStatics, library: library, cls: cls);
1092 1096
1093 return fields; 1097 return fields;
1094 } 1098 }
1095 1099
1096 Iterable<StaticStubMethod> _generateOneShotInterceptors() { 1100 Iterable<StaticStubMethod> _generateOneShotInterceptors() {
1097 InterceptorStubGenerator stubGenerator = new InterceptorStubGenerator( 1101 InterceptorStubGenerator stubGenerator = new InterceptorStubGenerator(
1098 _options, 1102 _options,
1099 _commonElements, 1103 _commonElements,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1145 DartType type = _elementEnvironment.getFunctionType(element); 1149 DartType type = _elementEnvironment.getFunctionType(element);
1146 if (needsTearOff || canBeReflected) { 1150 if (needsTearOff || canBeReflected) {
1147 OutputUnit outputUnit = _deferredLoadTask.outputUnitForMember(element); 1151 OutputUnit outputUnit = _deferredLoadTask.outputUnitForMember(element);
1148 functionType = _generateFunctionType(type, outputUnit); 1152 functionType = _generateFunctionType(type, outputUnit);
1149 } 1153 }
1150 1154
1151 int requiredParameterCount; 1155 int requiredParameterCount;
1152 var /* List | Map */ optionalParameterDefaultValues; 1156 var /* List | Map */ optionalParameterDefaultValues;
1153 if (canBeApplied || canBeReflected) { 1157 if (canBeApplied || canBeReflected) {
1154 // TODO(redemption): Support entities; 1158 // TODO(redemption): Support entities;
1155 MethodElement method = element; 1159 FunctionEntity method = element;
1156 FunctionSignature signature = method.functionSignature; 1160 ParameterStructure parameterStructure = method.parameterStructure;
1157 requiredParameterCount = signature.requiredParameterCount; 1161 requiredParameterCount = parameterStructure.requiredParameters;
1158 optionalParameterDefaultValues = 1162 optionalParameterDefaultValues = _computeParameterDefaultValues(method);
1159 _computeParameterDefaultValues(signature);
1160 } 1163 }
1161 1164
1162 // TODO(floitsch): we shouldn't update the registry in the middle of 1165 // TODO(floitsch): we shouldn't update the registry in the middle of
1163 // building a static method. 1166 // building a static method.
1164 return new StaticDartMethod(element, name, _registry.registerHolder(holder), 1167 return new StaticDartMethod(element, name, _registry.registerHolder(holder),
1165 code, _generateParameterStubs(element, needsTearOff), callName, 1168 code, _generateParameterStubs(element, needsTearOff), callName,
1166 needsTearOff: needsTearOff, 1169 needsTearOff: needsTearOff,
1167 tearOffName: tearOffName, 1170 tearOffName: tearOffName,
1168 canBeApplied: canBeApplied, 1171 canBeApplied: canBeApplied,
1169 canBeReflected: canBeReflected, 1172 canBeReflected: canBeReflected,
(...skipping 16 matching lines...) Expand all
1186 Constant constant = new Constant(name, holder, constantValue); 1189 Constant constant = new Constant(name, holder, constantValue);
1187 _constants[constantValue] = constant; 1190 _constants[constantValue] = constant;
1188 } 1191 }
1189 } 1192 }
1190 1193
1191 Holder _registerStaticStateHolder() { 1194 Holder _registerStaticStateHolder() {
1192 return _registry.registerHolder(_namer.staticStateHolder, 1195 return _registry.registerHolder(_namer.staticStateHolder,
1193 isStaticStateHolder: true); 1196 isStaticStateHolder: true);
1194 } 1197 }
1195 } 1198 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698