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

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

Issue 764023002: Incremental compilation of new lazy statics. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address comments and also test for needsDefineClass to see if defineClass is needed. Created 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | dart/pkg/dart2js_incremental/lib/caching_compiler.dart » ('j') | 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 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 String get generateAccessorHolder 152 String get generateAccessorHolder
153 => '$isolatePropertiesName.\$generateAccessor'; 153 => '$isolatePropertiesName.\$generateAccessor';
154 String get finishClassesProperty 154 String get finishClassesProperty
155 => r'$finishClasses'; 155 => r'$finishClasses';
156 String get finishClassesName 156 String get finishClassesName
157 => '${namer.isolateName}.$finishClassesProperty'; 157 => '${namer.isolateName}.$finishClassesProperty';
158 String get finishIsolateConstructorName 158 String get finishIsolateConstructorName
159 => '${namer.isolateName}.\$finishIsolateConstructor'; 159 => '${namer.isolateName}.\$finishIsolateConstructor';
160 String get isolatePropertiesName 160 String get isolatePropertiesName
161 => '${namer.isolateName}.${namer.isolatePropertiesName}'; 161 => '${namer.isolateName}.${namer.isolatePropertiesName}';
162 String get lazyInitializerProperty
163 => r'$lazy';
162 String get lazyInitializerName 164 String get lazyInitializerName
163 => '${namer.isolateName}.\$lazy'; 165 => '${namer.isolateName}.${lazyInitializerProperty}';
164 String get initName => 'init'; 166 String get initName => 'init';
165 String get makeConstListProperty 167 String get makeConstListProperty
166 => namer.getMappedInstanceName('makeConstantList'); 168 => namer.getMappedInstanceName('makeConstantList');
167 169
168 /// The name of the property that contains all field names. 170 /// The name of the property that contains all field names.
169 /// 171 ///
170 /// This property is added to constructors when isolate support is enabled. 172 /// This property is added to constructors when isolate support is enabled.
171 static const String FIELD_NAMES_PROPERTY_NAME = r"$__fields__"; 173 static const String FIELD_NAMES_PROPERTY_NAME = r"$__fields__";
172 174
173 /// For deferred loading we communicate the initializers via this global var. 175 /// For deferred loading we communicate the initializers via this global var.
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 'leafTagsAccess': leafTagsAccess, 683 'leafTagsAccess': leafTagsAccess,
682 'allowNativesSubclassing': true}); 684 'allowNativesSubclassing': true});
683 } 685 }
684 686
685 jsAst.Fun get finishIsolateConstructorFunction { 687 jsAst.Fun get finishIsolateConstructorFunction {
686 // We replace the old Isolate function with a new one that initializes 688 // We replace the old Isolate function with a new one that initializes
687 // all its fields with the initial (and often final) value of all globals. 689 // all its fields with the initial (and often final) value of all globals.
688 // 690 //
689 // We also copy over old values like the prototype, and the 691 // We also copy over old values like the prototype, and the
690 // isolateProperties themselves. 692 // isolateProperties themselves.
691 return js(''' 693 return js(
694 """
692 function (oldIsolate) { 695 function (oldIsolate) {
693 var isolateProperties = oldIsolate.#; // isolatePropertiesName 696 var isolateProperties = oldIsolate.#isolatePropertiesName;
694 function Isolate() { 697 function Isolate() {
695 var hasOwnProperty = Object.prototype.hasOwnProperty; 698 var hasOwnProperty = Object.prototype.hasOwnProperty;
696 for (var staticName in isolateProperties) 699 for (var staticName in isolateProperties)
697 if (hasOwnProperty.call(isolateProperties, staticName)) 700 if (hasOwnProperty.call(isolateProperties, staticName))
698 this[staticName] = isolateProperties[staticName]; 701 this[staticName] = isolateProperties[staticName];
699 702
700 // Reset lazy initializers to null. 703 // Reset lazy initializers to null.
701 // When forcing the object to fast mode (below) v8 will consider 704 // When forcing the object to fast mode (below) v8 will consider
702 // functions as part the object's map. Since we will change them 705 // functions as part the object's map. Since we will change them
703 // (after the first call to the getter), we would have a map 706 // (after the first call to the getter), we would have a map
(...skipping 11 matching lines...) Expand all
715 new ForceEfficientMap(); 718 new ForceEfficientMap();
716 719
717 // Now, after being a fast map we can set the lazies again. 720 // Now, after being a fast map we can set the lazies again.
718 for (var lazyInit in lazies) { 721 for (var lazyInit in lazies) {
719 var lazyInitName = lazies[lazyInit]; 722 var lazyInitName = lazies[lazyInit];
720 this[lazyInitName] = isolateProperties[lazyInitName]; 723 this[lazyInitName] = isolateProperties[lazyInitName];
721 } 724 }
722 } 725 }
723 Isolate.prototype = oldIsolate.prototype; 726 Isolate.prototype = oldIsolate.prototype;
724 Isolate.prototype.constructor = Isolate; 727 Isolate.prototype.constructor = Isolate;
725 Isolate.# = isolateProperties; // isolatePropertiesName 728 Isolate.#isolatePropertiesName = isolateProperties;
726 if (#) // needsDefineClass. 729 if (#needsDefineClass)
727 Isolate.# = oldIsolate.#; // finishClassesProperty * 2 730 Isolate.#finishClassesProperty = oldIsolate.#finishClassesProperty;
728 if (#) // outputContainsConstantList 731 if (#outputContainsConstantList)
729 Isolate.# = oldIsolate.#; // makeConstListProperty * 2 732 Isolate.#makeConstListProperty = oldIsolate.#makeConstListProperty;
730 return Isolate; 733 if (#hasIncrementalSupport)
731 }''', 734 Isolate.#lazyInitializerProperty =
732 [namer.isolatePropertiesName, namer.isolatePropertiesName, 735 oldIsolate.#lazyInitializerProperty;
733 needsDefineClass, finishClassesProperty, finishClassesProperty, 736 return Isolate;
734 task.outputContainsConstantList, 737 }
735 makeConstListProperty, makeConstListProperty ]); 738 """,
739 { 'isolatePropertiesName': namer.isolatePropertiesName,
740 'needsDefineClass': needsDefineClass,
741 'finishClassesProperty': finishClassesProperty,
742 'outputContainsConstantList': task.outputContainsConstantList,
743 'makeConstListProperty': makeConstListProperty,
744 'hasIncrementalSupport': compiler.hasIncrementalSupport,
745 'lazyInitializerProperty': lazyInitializerProperty,
746 });
736 } 747 }
737 748
738 jsAst.Fun get lazyInitializerFunction { 749 jsAst.Fun get lazyInitializerFunction {
739 String isolate = namer.currentIsolate; 750 String isolate = namer.currentIsolate;
740 jsAst.Expression cyclicThrow = 751 jsAst.Expression cyclicThrow =
741 staticFunctionAccess(backend.getCyclicThrowHelper()); 752 staticFunctionAccess(backend.getCyclicThrowHelper());
742 jsAst.Expression laziesAccess = 753 jsAst.Expression laziesAccess =
743 generateEmbeddedGlobalAccess(embeddedNames.LAZIES); 754 generateEmbeddedGlobalAccess(embeddedNames.LAZIES);
744 755
745 return js(''' 756 return js('''
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 } 1027 }
1017 } 1028 }
1018 1029
1019 void emitLazilyInitializedStaticFields(CodeBuffer buffer) { 1030 void emitLazilyInitializedStaticFields(CodeBuffer buffer) {
1020 JavaScriptConstantCompiler handler = backend.constants; 1031 JavaScriptConstantCompiler handler = backend.constants;
1021 List<VariableElement> lazyFields = 1032 List<VariableElement> lazyFields =
1022 handler.getLazilyInitializedFieldsForEmission(); 1033 handler.getLazilyInitializedFieldsForEmission();
1023 if (!lazyFields.isEmpty) { 1034 if (!lazyFields.isEmpty) {
1024 needsLazyInitializer = true; 1035 needsLazyInitializer = true;
1025 for (VariableElement element in Elements.sortedByPosition(lazyFields)) { 1036 for (VariableElement element in Elements.sortedByPosition(lazyFields)) {
1026 jsAst.Expression code = backend.generatedCode[element]; 1037 jsAst.Expression init =
1027 // The code is null if we ended up not needing the lazily 1038 buildLazilyInitializedStaticField(element, isolateProperties);
1028 // initialized field after all because of constant folding 1039 if (init == null) continue;
1029 // before code generation. 1040 buffer.write(
1030 if (code == null) continue; 1041 jsAst.prettyPrint(init, compiler, monitor: compiler.dumpInfoTask));
1031 // The code only computes the initial value. We build the lazy-check
1032 // here:
1033 // lazyInitializer(prototype, 'name', fieldName, getterName, initial);
1034 // The name is used for error reporting. The 'initial' must be a
1035 // closure that constructs the initial value.
1036 jsAst.Expression init = js('#(#,#,#,#,#)',
1037 [js(lazyInitializerName),
1038 js(isolateProperties),
1039 js.string(element.name),
1040 js.string(namer.getNameX(element)),
1041 js.string(namer.getLazyInitializerName(element)),
1042 code]);
1043 buffer.write(jsAst.prettyPrint(init, compiler,
1044 monitor: compiler.dumpInfoTask));
1045 buffer.write("$N"); 1042 buffer.write("$N");
1046 } 1043 }
1047 } 1044 }
1048 } 1045 }
1049 1046
1047 jsAst.Expression buildLazilyInitializedStaticField(
1048 VariableElement element, String isolateProperties) {
1049 jsAst.Expression code = backend.generatedCode[element];
1050 // The code is null if we ended up not needing the lazily
1051 // initialized field after all because of constant folding
1052 // before code generation.
1053 if (code == null) return null;
1054 // The code only computes the initial value. We build the lazy-check
1055 // here:
1056 // lazyInitializer(prototype, 'name', fieldName, getterName, initial);
1057 // The name is used for error reporting. The 'initial' must be a
1058 // closure that constructs the initial value.
1059 return js('#(#,#,#,#,#)',
1060 [js(lazyInitializerName),
1061 js(isolateProperties),
1062 js.string(element.name),
1063 js.string(namer.getNameX(element)),
1064 js.string(namer.getLazyInitializerName(element)),
1065 code]);
1066 }
1067
1050 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) { 1068 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) {
1051 if (constant.isFunction) return true; // Already emitted. 1069 if (constant.isFunction) return true; // Already emitted.
1052 if (constant.isPrimitive) return true; // Inlined. 1070 if (constant.isPrimitive) return true; // Inlined.
1053 if (constant.isDummy) return true; // Inlined. 1071 if (constant.isDummy) return true; // Inlined.
1054 // The name is null when the constant is already a JS constant. 1072 // The name is null when the constant is already a JS constant.
1055 // TODO(floitsch): every constant should be registered, so that we can 1073 // TODO(floitsch): every constant should be registered, so that we can
1056 // share the ones that take up too much space (like some strings). 1074 // share the ones that take up too much space (like some strings).
1057 if (namer.constantName(constant) == null) return true; 1075 if (namer.constantName(constant) == null) return true;
1058 return false; 1076 return false;
1059 } 1077 }
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
1591 .write('${globalsHolder}.${namer.isolateName}$_=$_' 1609 .write('${globalsHolder}.${namer.isolateName}$_=$_'
1592 '${namer.isolateName}$N' 1610 '${namer.isolateName}$N'
1593 '${globalsHolder}.$initName$_=${_}$initName$N'); 1611 '${globalsHolder}.$initName$_=${_}$initName$N');
1594 } 1612 }
1595 mainBuffer.add('init()$N$n'); 1613 mainBuffer.add('init()$N$n');
1596 mainBuffer.add('$isolateProperties$_=$_$isolatePropertiesName$N'); 1614 mainBuffer.add('$isolateProperties$_=$_$isolatePropertiesName$N');
1597 1615
1598 emitStaticFunctions(task.outputStaticLists[mainOutputUnit]); 1616 emitStaticFunctions(task.outputStaticLists[mainOutputUnit]);
1599 1617
1600 // Only output the classesCollector if we actually have any classes. 1618 // Only output the classesCollector if we actually have any classes.
1601 if (!(nativeClasses.isEmpty && 1619 if (needsDefineClass ||
1620 !(nativeClasses.isEmpty &&
1602 compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty && 1621 compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty &&
1603 outputClassLists.values.every((classList) => classList.isEmpty) && 1622 outputClassLists.values.every((classList) => classList.isEmpty) &&
1604 typedefsNeededForReflection.isEmpty)) { 1623 typedefsNeededForReflection.isEmpty)) {
1605 // Shorten the code by using "$$" as temporary. 1624 // Shorten the code by using "$$" as temporary.
1606 classesCollector = r"$$"; 1625 classesCollector = r"$$";
1607 mainBuffer.add('var $classesCollector$_=${_}Object.create(null)$N$n'); 1626 mainBuffer.add('var $classesCollector$_=${_}Object.create(null)$N$n');
1608 } 1627 }
1609 1628
1610 if (!nativeClasses.isEmpty) { 1629 if (!nativeClasses.isEmpty) {
1611 addComment('Native classes', mainBuffer); 1630 addComment('Native classes', mainBuffer);
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after
2197 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { 2216 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) {
2198 if (element.isInstanceMember) { 2217 if (element.isInstanceMember) {
2199 cachedClassBuilders.remove(element.enclosingClass); 2218 cachedClassBuilders.remove(element.enclosingClass);
2200 2219
2201 nativeEmitter.cachedBuilders.remove(element.enclosingClass); 2220 nativeEmitter.cachedBuilders.remove(element.enclosingClass);
2202 2221
2203 } 2222 }
2204 } 2223 }
2205 } 2224 }
2206 } 2225 }
OLDNEW
« no previous file with comments | « no previous file | dart/pkg/dart2js_incremental/lib/caching_compiler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698