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

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

Issue 947333004: dart2js: simplify constant expression generation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix long line. Created 5 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 part of dart2js.js_emitter; 5 part of dart2js.js_emitter;
6 6
7 7
8 class OldEmitter implements Emitter { 8 class OldEmitter implements Emitter {
9 final Compiler compiler; 9 final Compiler compiler;
10 final CodeEmitterTask task; 10 final CodeEmitterTask task;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 new Map<Element, ClassBuilder>(); 88 new Map<Element, ClassBuilder>();
89 89
90 final bool generateSourceMap; 90 final bool generateSourceMap;
91 91
92 OldEmitter(Compiler compiler, Namer namer, this.generateSourceMap, this.task) 92 OldEmitter(Compiler compiler, Namer namer, this.generateSourceMap, this.task)
93 : this.compiler = compiler, 93 : this.compiler = compiler,
94 this.namer = namer, 94 this.namer = namer,
95 cachedEmittedConstants = compiler.cacheStrategy.newSet(), 95 cachedEmittedConstants = compiler.cacheStrategy.newSet(),
96 cachedClassBuilders = compiler.cacheStrategy.newMap(), 96 cachedClassBuilders = compiler.cacheStrategy.newMap(),
97 cachedElements = compiler.cacheStrategy.newSet() { 97 cachedElements = compiler.cacheStrategy.newSet() {
98 constantEmitter = 98 constantEmitter = new ConstantEmitter(
99 new ConstantEmitter(compiler, namer, makeConstantListTemplate); 99 compiler, namer, this.constantReference, makeConstantListTemplate);
100 containerBuilder.emitter = this; 100 containerBuilder.emitter = this;
101 classEmitter.emitter = this; 101 classEmitter.emitter = this;
102 nsmEmitter.emitter = this; 102 nsmEmitter.emitter = this;
103 interceptorEmitter.emitter = this; 103 interceptorEmitter.emitter = this;
104 } 104 }
105 105
106 List<jsAst.Node> cspPrecompiledFunctionFor(OutputUnit outputUnit) { 106 List<jsAst.Node> cspPrecompiledFunctionFor(OutputUnit outputUnit) {
107 return _cspPrecompiledFunctions.putIfAbsent( 107 return _cspPrecompiledFunctions.putIfAbsent(
108 outputUnit, 108 outputUnit,
109 () => new List<jsAst.Node>()); 109 () => new List<jsAst.Node>());
(...skipping 11 matching lines...) Expand all
121 void clearCspPrecompiledNodes() { 121 void clearCspPrecompiledNodes() {
122 _cspPrecompiledFunctions.clear(); 122 _cspPrecompiledFunctions.clear();
123 _cspPrecompiledConstructorNames.clear(); 123 _cspPrecompiledConstructorNames.clear();
124 } 124 }
125 125
126 void addComment(String comment, CodeOutput output) { 126 void addComment(String comment, CodeOutput output) {
127 output.addBuffer(jsAst.prettyPrint(js.comment(comment), compiler)); 127 output.addBuffer(jsAst.prettyPrint(js.comment(comment), compiler));
128 } 128 }
129 129
130 @override 130 @override
131 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) {
132 if (constant.isFunction) return true; // Already emitted.
133 if (constant.isPrimitive) return true; // Inlined.
134 if (constant.isDummy) return true; // Inlined.
135 // The name is null when the constant is already a JS constant.
136 // TODO(floitsch): every constant should be registered, so that we can
137 // share the ones that take up too much space (like some strings).
138 if (namer.constantName(constant) == null) return true;
139 return false;
140 }
141
142 @override
143 int compareConstants(ConstantValue a, ConstantValue b) {
144 // Inlined constants don't affect the order and sometimes don't even have
145 // names.
146 int cmp1 = isConstantInlinedOrAlreadyEmitted(a) ? 0 : 1;
147 int cmp2 = isConstantInlinedOrAlreadyEmitted(b) ? 0 : 1;
148 if (cmp1 + cmp2 < 2) return cmp1 - cmp2;
149
150 // Emit constant interceptors first. Constant interceptors for primitives
151 // might be used by code that builds other constants. See Issue 18173.
152 if (a.isInterceptor != b.isInterceptor) {
153 return a.isInterceptor ? -1 : 1;
154 }
155
156 // Sorting by the long name clusters constants with the same constructor
157 // which compresses a tiny bit better.
158 int r = namer.constantLongName(a).compareTo(namer.constantLongName(b));
159 if (r != 0) return r;
160 // Resolve collisions in the long name by using the constant name (i.e. JS
161 // name) which is unique.
162 return namer.constantName(a).compareTo(namer.constantName(b));
163 }
164
165 @override
131 jsAst.Expression constantReference(ConstantValue value) { 166 jsAst.Expression constantReference(ConstantValue value) {
132 return constantEmitter.reference(value); 167 if (value.isFunction) {
168 FunctionConstantValue functionConstant = value;
169 return isolateStaticClosureAccess(functionConstant.element);
170 }
171
172 // We are only interested in the "isInlined" part, but it does not hurt to
173 // test for the other predicates.
174 if (isConstantInlinedOrAlreadyEmitted(value)) {
175 return constantEmitter.generate(value);
176 }
177 return js('#.#', [namer.globalObjectForConstant(value),
178 namer.constantName(value)]);
133 } 179 }
134 180
135 jsAst.Expression constantInitializerExpression(ConstantValue value) { 181 jsAst.Expression constantInitializerExpression(ConstantValue value) {
136 return constantEmitter.initializationExpression(value); 182 return constantEmitter.generate(value);
137 } 183 }
138 184
139 String get name => 'CodeEmitter'; 185 String get name => 'CodeEmitter';
140 186
141 String get finishIsolateConstructorName 187 String get finishIsolateConstructorName
142 => '${namer.isolateName}.\$finishIsolateConstructor'; 188 => '${namer.isolateName}.\$finishIsolateConstructor';
143 String get isolatePropertiesName 189 String get isolatePropertiesName
144 => '${namer.isolateName}.${namer.isolatePropertiesName}'; 190 => '${namer.isolateName}.${namer.isolatePropertiesName}';
145 String get lazyInitializerProperty 191 String get lazyInitializerProperty
146 => r'$lazy'; 192 => r'$lazy';
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 bool inMainUnit = (outputUnit == compiler.deferredLoadTask.mainOutputUnit); 781 bool inMainUnit = (outputUnit == compiler.deferredLoadTask.mainOutputUnit);
736 JavaScriptConstantCompiler handler = backend.constants; 782 JavaScriptConstantCompiler handler = backend.constants;
737 783
738 Iterable<Element> fields = task.outputStaticNonFinalFieldLists[outputUnit]; 784 Iterable<Element> fields = task.outputStaticNonFinalFieldLists[outputUnit];
739 // If the outputUnit does not contain any static non-final fields, then 785 // If the outputUnit does not contain any static non-final fields, then
740 // [fields] is `null`. 786 // [fields] is `null`.
741 if (fields != null) { 787 if (fields != null) {
742 for (Element element in fields) { 788 for (Element element in fields) {
743 compiler.withCurrentElement(element, () { 789 compiler.withCurrentElement(element, () {
744 ConstantValue constant = handler.getInitialValueFor(element).value; 790 ConstantValue constant = handler.getInitialValueFor(element).value;
745 emitInitialization( 791 emitInitialization(element, constantReference(constant));
746 element,
747 constantEmitter.referenceInInitializationContext(constant));
748 }); 792 });
749 } 793 }
750 } 794 }
751 795
752 if (inMainUnit && task.outputStaticNonFinalFieldLists.length > 1) { 796 if (inMainUnit && task.outputStaticNonFinalFieldLists.length > 1) {
753 // In the main output-unit we output a stub initializer for deferred 797 // In the main output-unit we output a stub initializer for deferred
754 // variables, so that `isolateProperties` stays a fast object. 798 // variables, so that `isolateProperties` stays a fast object.
755 task.outputStaticNonFinalFieldLists.forEach( 799 task.outputStaticNonFinalFieldLists.forEach(
756 (OutputUnit fieldsOutputUnit, Iterable<VariableElement> fields) { 800 (OutputUnit fieldsOutputUnit, Iterable<VariableElement> fields) {
757 if (fieldsOutputUnit == outputUnit) return; // Skip the main unit. 801 if (fieldsOutputUnit == outputUnit) return; // Skip the main unit.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 output.add(metadata); 856 output.add(metadata);
813 } 857 }
814 } else { 858 } else {
815 throw 'Unexpected value in metadata: ${Error.safeToString(metadata)}'; 859 throw 'Unexpected value in metadata: ${Error.safeToString(metadata)}';
816 } 860 }
817 output.add(',$n'); 861 output.add(',$n');
818 } 862 }
819 output.add('];$n'); 863 output.add('];$n');
820 } 864 }
821 865
822 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) {
823 if (constant.isFunction) return true; // Already emitted.
824 if (constant.isPrimitive) return true; // Inlined.
825 if (constant.isDummy) return true; // Inlined.
826 // The name is null when the constant is already a JS constant.
827 // TODO(floitsch): every constant should be registered, so that we can
828 // share the ones that take up too much space (like some strings).
829 if (namer.constantName(constant) == null) return true;
830 return false;
831 }
832
833 int compareConstants(ConstantValue a, ConstantValue b) {
834 // Inlined constants don't affect the order and sometimes don't even have
835 // names.
836 int cmp1 = isConstantInlinedOrAlreadyEmitted(a) ? 0 : 1;
837 int cmp2 = isConstantInlinedOrAlreadyEmitted(b) ? 0 : 1;
838 if (cmp1 + cmp2 < 2) return cmp1 - cmp2;
839
840 // Emit constant interceptors first. Constant interceptors for primitives
841 // might be used by code that builds other constants. See Issue 18173.
842 if (a.isInterceptor != b.isInterceptor) {
843 return a.isInterceptor ? -1 : 1;
844 }
845
846 // Sorting by the long name clusters constants with the same constructor
847 // which compresses a tiny bit better.
848 int r = namer.constantLongName(a).compareTo(namer.constantLongName(b));
849 if (r != 0) return r;
850 // Resolve collisions in the long name by using the constant name (i.e. JS
851 // name) which is unique.
852 return namer.constantName(a).compareTo(namer.constantName(b));
853 }
854
855 void emitCompileTimeConstants(CodeOutput output, 866 void emitCompileTimeConstants(CodeOutput output,
856 List<Constant> constants, 867 List<Constant> constants,
857 {bool isMainFragment}) { 868 {bool isMainFragment}) {
858 assert(isMainFragment != null); 869 assert(isMainFragment != null);
859 870
860 if (constants.isEmpty) return; 871 if (constants.isEmpty) return;
861 CodeOutput constantOutput = output; 872 CodeOutput constantOutput = output;
862 if (compiler.hasIncrementalSupport && isMainFragment) { 873 if (compiler.hasIncrementalSupport && isMainFragment) {
863 constantOutput = cachedEmittedConstantsBuffer; 874 constantOutput = cachedEmittedConstantsBuffer;
864 } 875 }
(...skipping 1136 matching lines...) Expand 10 before | Expand all | Expand 10 after
2001 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { 2012 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) {
2002 if (element.isInstanceMember) { 2013 if (element.isInstanceMember) {
2003 cachedClassBuilders.remove(element.enclosingClass); 2014 cachedClassBuilders.remove(element.enclosingClass);
2004 2015
2005 nativeEmitter.cachedBuilders.remove(element.enclosingClass); 2016 nativeEmitter.cachedBuilders.remove(element.enclosingClass);
2006 2017
2007 } 2018 }
2008 } 2019 }
2009 } 2020 }
2010 } 2021 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698