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

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

Issue 2568723007: Create Namer and Emitter on codegen start. (Closed)
Patch Set: Small fix. Created 4 years 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 '../../closure.dart' show ClosureFieldElement; 7 import '../../closure.dart' show ClosureFieldElement;
8 import '../../common.dart'; 8 import '../../common.dart';
9 import '../../common/names.dart' show Names, Selectors; 9 import '../../common/names.dart' show Names, Selectors;
10 import '../../compiler.dart' show Compiler; 10 import '../../compiler.dart' show Compiler;
(...skipping 16 matching lines...) Expand all
27 ParameterElement, 27 ParameterElement,
28 TypedefElement, 28 TypedefElement,
29 VariableElement; 29 VariableElement;
30 import '../../js/js.dart' as js; 30 import '../../js/js.dart' as js;
31 import '../../js_backend/backend_helpers.dart' show BackendHelpers; 31 import '../../js_backend/backend_helpers.dart' show BackendHelpers;
32 import '../../js_backend/js_backend.dart' 32 import '../../js_backend/js_backend.dart'
33 show Namer, JavaScriptBackend, JavaScriptConstantCompiler, StringBackedName; 33 show Namer, JavaScriptBackend, JavaScriptConstantCompiler, StringBackedName;
34 import '../../universe/selector.dart' show Selector; 34 import '../../universe/selector.dart' show Selector;
35 import '../../universe/world_builder.dart' 35 import '../../universe/world_builder.dart'
36 show CodegenWorldBuilder, SelectorConstraints; 36 show CodegenWorldBuilder, SelectorConstraints;
37 import '../../world.dart' show ClosedWorld;
37 import '../js_emitter.dart' 38 import '../js_emitter.dart'
38 show 39 show
39 ClassStubGenerator, 40 ClassStubGenerator,
40 CodeEmitterTask, 41 CodeEmitterTask,
41 computeMixinClass, 42 computeMixinClass,
42 Emitter, 43 Emitter,
43 InterceptorStubGenerator, 44 InterceptorStubGenerator,
44 MainCallStubGenerator, 45 MainCallStubGenerator,
45 ParameterStubGenerator, 46 ParameterStubGenerator,
46 RuntimeTypeGenerator, 47 RuntimeTypeGenerator,
47 TypeTestProperties; 48 TypeTestProperties;
48 import '../model.dart'; 49 import '../model.dart';
49 50
50 part 'collector.dart'; 51 part 'collector.dart';
51 part 'field_visitor.dart'; 52 part 'field_visitor.dart';
52 part 'registry.dart'; 53 part 'registry.dart';
53 54
54 /// Builds a self-contained representation of the program that can then be 55 /// Builds a self-contained representation of the program that can then be
55 /// emitted more easily by the individual emitters. 56 /// emitted more easily by the individual emitters.
56 class ProgramBuilder { 57 class ProgramBuilder {
57 final Compiler _compiler; 58 final Compiler _compiler;
58 final Namer namer; 59 final Namer namer;
59 final CodeEmitterTask _task; 60 final CodeEmitterTask _task;
61 final ClosedWorld closedWorld;
60 62
61 /// Contains the collected information the program builder used to build 63 /// Contains the collected information the program builder used to build
62 /// the model. 64 /// the model.
63 // The collector will be filled on the first call to `buildProgram`. 65 // The collector will be filled on the first call to `buildProgram`.
64 // It is stored and publicly exposed for backwards compatibility. New code 66 // It is stored and publicly exposed for backwards compatibility. New code
65 // (and in particular new emitters) should not use it. 67 // (and in particular new emitters) should not use it.
66 final Collector collector; 68 final Collector collector;
67 69
68 final Registry _registry; 70 final Registry _registry;
69 71
70 /// True if the program should store function types in the metadata. 72 /// True if the program should store function types in the metadata.
71 bool _storeFunctionTypesInMetadata = false; 73 bool _storeFunctionTypesInMetadata = false;
72 74
73 ProgramBuilder(Compiler compiler, Namer namer, this._task, Emitter emitter, 75 ProgramBuilder(Compiler compiler, Namer namer, this._task, Emitter emitter,
74 Set<ClassElement> rtiNeededClasses) 76 ClosedWorld closedWorld, Set<ClassElement> rtiNeededClasses)
75 : this._compiler = compiler, 77 : this._compiler = compiler,
76 this.namer = namer, 78 this.namer = namer,
77 this.collector = 79 this.closedWorld = closedWorld,
78 new Collector(compiler, namer, rtiNeededClasses, emitter), 80 this.collector = new Collector(
81 compiler, namer, closedWorld, rtiNeededClasses, emitter),
79 this._registry = new Registry(compiler); 82 this._registry = new Registry(compiler);
80 83
81 JavaScriptBackend get backend => _compiler.backend; 84 JavaScriptBackend get backend => _compiler.backend;
82 BackendHelpers get helpers => backend.helpers; 85 BackendHelpers get helpers => backend.helpers;
83 CodegenWorldBuilder get universe => _compiler.codegenWorld; 86 CodegenWorldBuilder get universe => _compiler.codegenWorld;
84 87
85 /// Mapping from [ClassElement] to constructed [Class]. We need this to 88 /// Mapping from [ClassElement] to constructed [Class]. We need this to
86 /// update the superclass in the [Class]. 89 /// update the superclass in the [Class].
87 final Map<ClassElement, Class> _classes = <ClassElement, Class>{}; 90 final Map<ClassElement, Class> _classes = <ClassElement, Class>{};
88 91
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 .forEach((String loadId, List<OutputUnit> outputUnits) { 201 .forEach((String loadId, List<OutputUnit> outputUnits) {
199 loadMap[loadId] = outputUnits 202 loadMap[loadId] = outputUnits
200 .map((OutputUnit unit) => _outputs[unit]) 203 .map((OutputUnit unit) => _outputs[unit])
201 .toList(growable: false); 204 .toList(growable: false);
202 }); 205 });
203 return loadMap; 206 return loadMap;
204 } 207 }
205 208
206 js.Expression _buildTypeToInterceptorMap() { 209 js.Expression _buildTypeToInterceptorMap() {
207 InterceptorStubGenerator stubGenerator = 210 InterceptorStubGenerator stubGenerator =
208 new InterceptorStubGenerator(_compiler, namer, backend); 211 new InterceptorStubGenerator(_compiler, namer, backend, closedWorld);
209 return stubGenerator.generateTypeToInterceptorMap(); 212 return stubGenerator.generateTypeToInterceptorMap();
210 } 213 }
211 214
212 MainFragment _buildMainFragment(LibrariesMap librariesMap) { 215 MainFragment _buildMainFragment(LibrariesMap librariesMap) {
213 // Construct the main output from the libraries and the registered holders. 216 // Construct the main output from the libraries and the registered holders.
214 MainFragment result = new MainFragment( 217 MainFragment result = new MainFragment(
215 librariesMap.outputUnit, 218 librariesMap.outputUnit,
216 "", // The empty string is the name for the main output file. 219 "", // The empty string is the name for the main output file.
217 _buildInvokeMain(), 220 _buildInvokeMain(),
218 _buildLibraries(librariesMap), 221 _buildLibraries(librariesMap),
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 bool hasRtiField = backend.classNeedsRtiField(element); 513 bool hasRtiField = backend.classNeedsRtiField(element);
511 if (backend.isJsInterop(element)) { 514 if (backend.isJsInterop(element)) {
512 // TODO(jacobr): check whether the class has any active static fields 515 // TODO(jacobr): check whether the class has any active static fields
513 // if it does not we can suppress it completely. 516 // if it does not we can suppress it completely.
514 onlyForRti = true; 517 onlyForRti = true;
515 } 518 }
516 519
517 List<Method> methods = []; 520 List<Method> methods = [];
518 List<StubMethod> callStubs = <StubMethod>[]; 521 List<StubMethod> callStubs = <StubMethod>[];
519 522
520 ClassStubGenerator classStubGenerator = 523 ClassStubGenerator classStubGenerator = new ClassStubGenerator(
521 new ClassStubGenerator(_compiler, namer, backend); 524 namer, backend, universe, closedWorld,
525 enableMinification: _compiler.options.enableMinification);
522 RuntimeTypeGenerator runtimeTypeGenerator = 526 RuntimeTypeGenerator runtimeTypeGenerator =
523 new RuntimeTypeGenerator(_compiler, _task, namer); 527 new RuntimeTypeGenerator(_compiler, _task, namer);
524 528
525 void visitMember(ClassElement enclosing, Element member) { 529 void visitMember(ClassElement enclosing, Element member) {
526 assert(invariant(element, member.isDeclaration)); 530 assert(invariant(element, member.isDeclaration));
527 assert(invariant(element, element == enclosing)); 531 assert(invariant(element, element == enclosing));
528 532
529 if (Elements.isNonAbstractInstanceMember(member)) { 533 if (Elements.isNonAbstractInstanceMember(member)) {
530 // TODO(herhut): Remove once _buildMethod can no longer return null. 534 // TODO(herhut): Remove once _buildMethod can no longer return null.
531 Method method = _buildMethod(member); 535 Method method = _buildMethod(member);
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 673
670 bool _methodCanBeReflected(FunctionElement method) { 674 bool _methodCanBeReflected(FunctionElement method) {
671 return backend.isAccessibleByReflection(method) || 675 return backend.isAccessibleByReflection(method) ||
672 // During incremental compilation, we have to assume that reflection 676 // During incremental compilation, we have to assume that reflection
673 // *might* get enabled. 677 // *might* get enabled.
674 _compiler.options.hasIncrementalSupport; 678 _compiler.options.hasIncrementalSupport;
675 } 679 }
676 680
677 bool _methodCanBeApplied(FunctionElement method) { 681 bool _methodCanBeApplied(FunctionElement method) {
678 return backend.hasFunctionApplySupport && 682 return backend.hasFunctionApplySupport &&
679 _compiler.closedWorld.getMightBePassedToApply(method); 683 closedWorld.getMightBePassedToApply(method);
680 } 684 }
681 685
682 // TODO(herhut): Refactor incremental compilation and remove method. 686 // TODO(herhut): Refactor incremental compilation and remove method.
683 Method buildMethodHackForIncrementalCompilation(FunctionElement element) { 687 Method buildMethodHackForIncrementalCompilation(FunctionElement element) {
684 assert(_compiler.options.hasIncrementalSupport); 688 assert(_compiler.options.hasIncrementalSupport);
685 if (element.isInstanceMember) { 689 if (element.isInstanceMember) {
686 return _buildMethod(element); 690 return _buildMethod(element);
687 } else { 691 } else {
688 return _buildStaticMethod(element); 692 return _buildStaticMethod(element);
689 } 693 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 : null; 733 : null;
730 734
731 if (isNotApplyTarget) { 735 if (isNotApplyTarget) {
732 canTearOff = false; 736 canTearOff = false;
733 } else { 737 } else {
734 if (element.enclosingClass.isClosure) { 738 if (element.enclosingClass.isClosure) {
735 canTearOff = false; 739 canTearOff = false;
736 isClosureCallMethod = true; 740 isClosureCallMethod = true;
737 } else { 741 } else {
738 // Careful with operators. 742 // Careful with operators.
739 canTearOff = 743 canTearOff = universe.hasInvokedGetter(element, closedWorld) ||
740 universe.hasInvokedGetter(element, _compiler.closedWorld) || 744 (canBeReflected && !element.isOperator);
741 (canBeReflected && !element.isOperator);
742 assert(canTearOff || 745 assert(canTearOff ||
743 !universe.methodsNeedingSuperGetter.contains(element)); 746 !universe.methodsNeedingSuperGetter.contains(element));
744 tearOffName = namer.getterForElement(element); 747 tearOffName = namer.getterForElement(element);
745 } 748 }
746 } 749 }
747 750
748 if (canTearOff) { 751 if (canTearOff) {
749 assert(invariant(element, !element.isGenerativeConstructor)); 752 assert(invariant(element, !element.isGenerativeConstructor));
750 assert(invariant(element, !element.isGenerativeConstructorBody)); 753 assert(invariant(element, !element.isGenerativeConstructorBody));
751 assert(invariant(element, !element.isConstructor)); 754 assert(invariant(element, !element.isConstructor));
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 return backend.emitter.metadataCollector 809 return backend.emitter.metadataCollector
807 .reifyTypeForOutputUnit(type, outputUnit); 810 .reifyTypeForOutputUnit(type, outputUnit);
808 } 811 }
809 } 812 }
810 813
811 List<ParameterStubMethod> _generateParameterStubs( 814 List<ParameterStubMethod> _generateParameterStubs(
812 MethodElement element, bool canTearOff) { 815 MethodElement element, bool canTearOff) {
813 if (!_methodNeedsStubs(element)) return const <ParameterStubMethod>[]; 816 if (!_methodNeedsStubs(element)) return const <ParameterStubMethod>[];
814 817
815 ParameterStubGenerator generator = 818 ParameterStubGenerator generator =
816 new ParameterStubGenerator(_compiler, namer, backend); 819 new ParameterStubGenerator(_compiler, namer, backend, closedWorld);
817 return generator.generateParameterStubs(element, canTearOff: canTearOff); 820 return generator.generateParameterStubs(element, canTearOff: canTearOff);
818 } 821 }
819 822
820 /// Builds a stub method. 823 /// Builds a stub method.
821 /// 824 ///
822 /// Stub methods may have an element that can be used for code-size 825 /// Stub methods may have an element that can be used for code-size
823 /// attribution. 826 /// attribution.
824 Method _buildStubMethod(js.Name name, js.Expression code, {Element element}) { 827 Method _buildStubMethod(js.Name name, js.Expression code, {Element element}) {
825 return new StubMethod(name, code, element: element); 828 return new StubMethod(name, code, element: element);
826 } 829 }
827 830
828 // The getInterceptor methods directly access the prototype of classes. 831 // The getInterceptor methods directly access the prototype of classes.
829 // We must evaluate these classes eagerly so that the prototype is 832 // We must evaluate these classes eagerly so that the prototype is
830 // accessible. 833 // accessible.
831 void _markEagerInterceptorClasses() { 834 void _markEagerInterceptorClasses() {
832 Map<js.Name, Set<ClassElement>> specializedGetInterceptors = 835 Map<js.Name, Set<ClassElement>> specializedGetInterceptors =
833 backend.specializedGetInterceptors; 836 backend.specializedGetInterceptors;
834 for (Set<ClassElement> classes in specializedGetInterceptors.values) { 837 for (Set<ClassElement> classes in specializedGetInterceptors.values) {
835 for (ClassElement element in classes) { 838 for (ClassElement element in classes) {
836 Class cls = _classes[element]; 839 Class cls = _classes[element];
837 if (cls != null) cls.isEager = true; 840 if (cls != null) cls.isEager = true;
838 } 841 }
839 } 842 }
840 } 843 }
841 844
842 Iterable<StaticStubMethod> _generateGetInterceptorMethods() { 845 Iterable<StaticStubMethod> _generateGetInterceptorMethods() {
843 InterceptorStubGenerator stubGenerator = 846 InterceptorStubGenerator stubGenerator =
844 new InterceptorStubGenerator(_compiler, namer, backend); 847 new InterceptorStubGenerator(_compiler, namer, backend, closedWorld);
845 848
846 String holderName = namer.globalObjectFor(helpers.interceptorsLibrary); 849 String holderName = namer.globalObjectFor(helpers.interceptorsLibrary);
847 // TODO(floitsch): we shouldn't update the registry in the middle of 850 // TODO(floitsch): we shouldn't update the registry in the middle of
848 // generating the interceptor methods. 851 // generating the interceptor methods.
849 Holder holder = _registry.registerHolder(holderName); 852 Holder holder = _registry.registerHolder(holderName);
850 853
851 Map<js.Name, Set<ClassElement>> specializedGetInterceptors = 854 Map<js.Name, Set<ClassElement>> specializedGetInterceptors =
852 backend.specializedGetInterceptors; 855 backend.specializedGetInterceptors;
853 List<js.Name> names = specializedGetInterceptors.keys.toList()..sort(); 856 List<js.Name> names = specializedGetInterceptors.keys.toList()..sort();
854 return names.map((js.Name name) { 857 return names.map((js.Name name) {
855 Set<ClassElement> classes = specializedGetInterceptors[name]; 858 Set<ClassElement> classes = specializedGetInterceptors[name];
856 js.Expression code = stubGenerator.generateGetInterceptorMethod(classes); 859 js.Expression code = stubGenerator.generateGetInterceptorMethod(classes);
857 return new StaticStubMethod(name, holder, code); 860 return new StaticStubMethod(name, holder, code);
858 }); 861 });
859 } 862 }
860 863
861 List<Field> _buildFields(Element holder, bool visitStatics) { 864 List<Field> _buildFields(Element holder, bool visitStatics) {
862 List<Field> fields = <Field>[]; 865 List<Field> fields = <Field>[];
863 new FieldVisitor(_compiler, namer).visitFields(holder, visitStatics, 866 new FieldVisitor(_compiler, namer, closedWorld)
864 (VariableElement field, js.Name name, js.Name accessorName, 867 .visitFields(holder, visitStatics, (VariableElement field,
865 bool needsGetter, bool needsSetter, bool needsCheckedSetter) { 868 js.Name name,
869 js.Name accessorName,
870 bool needsGetter,
871 bool needsSetter,
872 bool needsCheckedSetter) {
866 assert(invariant(field, field.isDeclaration)); 873 assert(invariant(field, field.isDeclaration));
867 874
868 int getterFlags = 0; 875 int getterFlags = 0;
869 if (needsGetter) { 876 if (needsGetter) {
870 if (visitStatics || !backend.fieldHasInterceptedGetter(field)) { 877 if (visitStatics || !backend.fieldHasInterceptedGetter(field)) {
871 getterFlags = 1; 878 getterFlags = 1;
872 } else { 879 } else {
873 getterFlags += 2; 880 getterFlags += 2;
874 // TODO(sra): 'isInterceptorClass' might not be the correct test 881 // TODO(sra): 'isInterceptorClass' might not be the correct test
875 // for methods forced to use the interceptor convention because 882 // for methods forced to use the interceptor convention because
(...skipping 18 matching lines...) Expand all
894 901
895 fields.add(new Field(field, name, accessorName, getterFlags, setterFlags, 902 fields.add(new Field(field, name, accessorName, getterFlags, setterFlags,
896 needsCheckedSetter)); 903 needsCheckedSetter));
897 }); 904 });
898 905
899 return fields; 906 return fields;
900 } 907 }
901 908
902 Iterable<StaticStubMethod> _generateOneShotInterceptors() { 909 Iterable<StaticStubMethod> _generateOneShotInterceptors() {
903 InterceptorStubGenerator stubGenerator = 910 InterceptorStubGenerator stubGenerator =
904 new InterceptorStubGenerator(_compiler, namer, backend); 911 new InterceptorStubGenerator(_compiler, namer, backend, closedWorld);
905 912
906 String holderName = namer.globalObjectFor(helpers.interceptorsLibrary); 913 String holderName = namer.globalObjectFor(helpers.interceptorsLibrary);
907 // TODO(floitsch): we shouldn't update the registry in the middle of 914 // TODO(floitsch): we shouldn't update the registry in the middle of
908 // generating the interceptor methods. 915 // generating the interceptor methods.
909 Holder holder = _registry.registerHolder(holderName); 916 Holder holder = _registry.registerHolder(holderName);
910 917
911 List<js.Name> names = backend.oneShotInterceptors.keys.toList()..sort(); 918 List<js.Name> names = backend.oneShotInterceptors.keys.toList()..sort();
912 return names.map((js.Name name) { 919 return names.map((js.Name name) {
913 js.Expression code = stubGenerator.generateOneShotInterceptor(name); 920 js.Expression code = stubGenerator.generateOneShotInterceptor(name);
914 return new StaticStubMethod(name, holder, code); 921 return new StaticStubMethod(name, holder, code);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 Constant constant = new Constant(name, holder, constantValue); 988 Constant constant = new Constant(name, holder, constantValue);
982 _constants[constantValue] = constant; 989 _constants[constantValue] = constant;
983 } 990 }
984 } 991 }
985 992
986 Holder _registerStaticStateHolder() { 993 Holder _registerStaticStateHolder() {
987 return _registry.registerHolder(namer.staticStateHolder, 994 return _registry.registerHolder(namer.staticStateHolder,
988 isStaticStateHolder: true); 995 isStaticStateHolder: true);
989 } 996 }
990 } 997 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698