Chromium Code Reviews| 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 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 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 151 String get generateAccessorHolder | 151 String get generateAccessorHolder |
| 152 => '$isolatePropertiesName.\$generateAccessor'; | 152 => '$isolatePropertiesName.\$generateAccessor'; |
| 153 String get finishClassesProperty | 153 String get finishClassesProperty |
| 154 => r'$finishClasses'; | 154 => r'$finishClasses'; |
| 155 String get finishClassesName | 155 String get finishClassesName |
| 156 => '${namer.isolateName}.$finishClassesProperty'; | 156 => '${namer.isolateName}.$finishClassesProperty'; |
| 157 String get finishIsolateConstructorName | 157 String get finishIsolateConstructorName |
| 158 => '${namer.isolateName}.\$finishIsolateConstructor'; | 158 => '${namer.isolateName}.\$finishIsolateConstructor'; |
| 159 String get isolatePropertiesName | 159 String get isolatePropertiesName |
| 160 => '${namer.isolateName}.${namer.isolatePropertiesName}'; | 160 => '${namer.isolateName}.${namer.isolatePropertiesName}'; |
| 161 String get lazyInitializerProperty | |
| 162 => r'$lazy'; | |
| 161 String get lazyInitializerName | 163 String get lazyInitializerName |
| 162 => '${namer.isolateName}.\$lazy'; | 164 => '${namer.isolateName}.${lazyInitializerProperty}'; |
| 163 String get initName => 'init'; | 165 String get initName => 'init'; |
| 164 String get makeConstListProperty | 166 String get makeConstListProperty |
| 165 => namer.getMappedInstanceName('makeConstantList'); | 167 => namer.getMappedInstanceName('makeConstantList'); |
| 166 | 168 |
| 167 /// For deferred loading we communicate the initializers via this global var. | 169 /// For deferred loading we communicate the initializers via this global var. |
| 168 final String deferredInitializers = r"$dart_deferred_initializers"; | 170 final String deferredInitializers = r"$dart_deferred_initializers"; |
| 169 | 171 |
| 170 /// All the global state can be passed around with this variable. | 172 /// All the global state can be passed around with this variable. |
| 171 String get globalsHolder => namer.getMappedGlobalName("globalsHolder"); | 173 String get globalsHolder => namer.getMappedGlobalName("globalsHolder"); |
| 172 | 174 |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 589 interceptorsByTagAccess, | 591 interceptorsByTagAccess, |
| 590 leafTagsAccess]); | 592 leafTagsAccess]); |
| 591 } | 593 } |
| 592 | 594 |
| 593 jsAst.Fun get finishIsolateConstructorFunction { | 595 jsAst.Fun get finishIsolateConstructorFunction { |
| 594 // We replace the old Isolate function with a new one that initializes | 596 // We replace the old Isolate function with a new one that initializes |
| 595 // all its fields with the initial (and often final) value of all globals. | 597 // all its fields with the initial (and often final) value of all globals. |
| 596 // | 598 // |
| 597 // We also copy over old values like the prototype, and the | 599 // We also copy over old values like the prototype, and the |
| 598 // isolateProperties themselves. | 600 // isolateProperties themselves. |
| 599 return js(''' | 601 return js( |
| 602 """ | |
| 600 function (oldIsolate) { | 603 function (oldIsolate) { |
| 601 var isolateProperties = oldIsolate.#; // isolatePropertiesName | 604 var isolateProperties = oldIsolate.#isolatePropertiesName; |
| 602 function Isolate() { | 605 function Isolate() { |
| 603 var hasOwnProperty = Object.prototype.hasOwnProperty; | 606 var hasOwnProperty = Object.prototype.hasOwnProperty; |
| 604 for (var staticName in isolateProperties) | 607 for (var staticName in isolateProperties) |
| 605 if (hasOwnProperty.call(isolateProperties, staticName)) | 608 if (hasOwnProperty.call(isolateProperties, staticName)) |
| 606 this[staticName] = isolateProperties[staticName]; | 609 this[staticName] = isolateProperties[staticName]; |
| 607 | 610 |
| 608 // Reset lazy initializers to null. | 611 // Reset lazy initializers to null. |
| 609 // When forcing the object to fast mode (below) v8 will consider | 612 // When forcing the object to fast mode (below) v8 will consider |
| 610 // functions as part the object's map. Since we will change them | 613 // functions as part the object's map. Since we will change them |
| 611 // (after the first call to the getter), we would have a map | 614 // (after the first call to the getter), we would have a map |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 623 new ForceEfficientMap(); | 626 new ForceEfficientMap(); |
| 624 | 627 |
| 625 // Now, after being a fast map we can set the lazies again. | 628 // Now, after being a fast map we can set the lazies again. |
| 626 for (var lazyInit in lazies) { | 629 for (var lazyInit in lazies) { |
| 627 var lazyInitName = lazies[lazyInit]; | 630 var lazyInitName = lazies[lazyInit]; |
| 628 this[lazyInitName] = isolateProperties[lazyInitName]; | 631 this[lazyInitName] = isolateProperties[lazyInitName]; |
| 629 } | 632 } |
| 630 } | 633 } |
| 631 Isolate.prototype = oldIsolate.prototype; | 634 Isolate.prototype = oldIsolate.prototype; |
| 632 Isolate.prototype.constructor = Isolate; | 635 Isolate.prototype.constructor = Isolate; |
| 633 Isolate.# = isolateProperties; // isolatePropertiesName | 636 Isolate.#isolatePropertiesName = isolateProperties; |
| 634 if (#) // needsDefineClass. | 637 if (#needsDefineClass) |
| 635 Isolate.# = oldIsolate.#; // finishClassesProperty * 2 | 638 Isolate.#finishClassesProperty = oldIsolate.#finishClassesProperty; |
| 636 if (#) // outputContainsConstantList | 639 if (#outputContainsConstantList) |
| 637 Isolate.# = oldIsolate.#; // makeConstListProperty * 2 | 640 Isolate.#makeConstListProperty = oldIsolate.#makeConstListProperty; |
| 638 return Isolate; | 641 if (#hasIncrementalSupport) |
| 639 }''', | 642 Isolate.#lazyInitializerProperty = oldIsolate.#lazyInitializerProperty ; |
|
Johnni Winther
2014/12/09 11:53:52
Long line
ahe
2014/12/10 14:00:04
Done.
| |
| 640 [namer.isolatePropertiesName, namer.isolatePropertiesName, | 643 return Isolate; |
| 641 needsDefineClass, finishClassesProperty, finishClassesProperty, | 644 } |
| 642 task.outputContainsConstantList, | 645 """, |
| 643 makeConstListProperty, makeConstListProperty ]); | 646 { 'isolatePropertiesName': namer.isolatePropertiesName, |
| 647 'needsDefineClass': needsDefineClass, | |
| 648 'finishClassesProperty': finishClassesProperty, | |
| 649 'outputContainsConstantList': task.outputContainsConstantList, | |
| 650 'makeConstListProperty': makeConstListProperty, | |
| 651 'hasIncrementalSupport': compiler.hasIncrementalSupport, | |
| 652 'lazyInitializerProperty': lazyInitializerProperty, | |
| 653 }); | |
| 644 } | 654 } |
| 645 | 655 |
| 646 jsAst.Fun get lazyInitializerFunction { | 656 jsAst.Fun get lazyInitializerFunction { |
| 647 String isolate = namer.currentIsolate; | 657 String isolate = namer.currentIsolate; |
| 648 jsAst.Expression cyclicThrow = | 658 jsAst.Expression cyclicThrow = |
| 649 namer.elementAccess(backend.getCyclicThrowHelper()); | 659 namer.elementAccess(backend.getCyclicThrowHelper()); |
| 650 jsAst.Expression laziesAccess = | 660 jsAst.Expression laziesAccess = |
| 651 generateEmbeddedGlobalAccess(embeddedNames.LAZIES); | 661 generateEmbeddedGlobalAccess(embeddedNames.LAZIES); |
| 652 | 662 |
| 653 return js(''' | 663 return js(''' |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 924 } | 934 } |
| 925 } | 935 } |
| 926 | 936 |
| 927 void emitLazilyInitializedStaticFields(CodeBuffer buffer) { | 937 void emitLazilyInitializedStaticFields(CodeBuffer buffer) { |
| 928 JavaScriptConstantCompiler handler = backend.constants; | 938 JavaScriptConstantCompiler handler = backend.constants; |
| 929 List<VariableElement> lazyFields = | 939 List<VariableElement> lazyFields = |
| 930 handler.getLazilyInitializedFieldsForEmission(); | 940 handler.getLazilyInitializedFieldsForEmission(); |
| 931 if (!lazyFields.isEmpty) { | 941 if (!lazyFields.isEmpty) { |
| 932 needsLazyInitializer = true; | 942 needsLazyInitializer = true; |
| 933 for (VariableElement element in Elements.sortedByPosition(lazyFields)) { | 943 for (VariableElement element in Elements.sortedByPosition(lazyFields)) { |
| 934 jsAst.Expression code = backend.generatedCode[element]; | 944 jsAst.Expression init = |
| 935 // The code is null if we ended up not needing the lazily | 945 buildLazilyInitializedStaticField(element, isolateProperties); |
| 936 // initialized field after all because of constant folding | 946 if (init == null) continue; |
| 937 // before code generation. | 947 buffer.write( |
| 938 if (code == null) continue; | 948 jsAst.prettyPrint(init, compiler, monitor: compiler.dumpInfoTask)); |
| 939 // The code only computes the initial value. We build the lazy-check | |
| 940 // here: | |
| 941 // lazyInitializer(prototype, 'name', fieldName, getterName, initial); | |
| 942 // The name is used for error reporting. The 'initial' must be a | |
| 943 // closure that constructs the initial value. | |
| 944 jsAst.Expression init = js('#(#,#,#,#,#)', | |
| 945 [js(lazyInitializerName), | |
| 946 js(isolateProperties), | |
| 947 js.string(element.name), | |
| 948 js.string(namer.getNameX(element)), | |
| 949 js.string(namer.getLazyInitializerName(element)), | |
| 950 code]); | |
| 951 buffer.write(jsAst.prettyPrint(init, compiler, | |
| 952 monitor: compiler.dumpInfoTask)); | |
| 953 buffer.write("$N"); | 949 buffer.write("$N"); |
| 954 } | 950 } |
| 955 } | 951 } |
| 956 } | 952 } |
| 957 | 953 |
| 954 jsAst.Expression buildLazilyInitializedStaticField( | |
| 955 VariableElement element, String isolateProperties) { | |
| 956 jsAst.Expression code = backend.generatedCode[element]; | |
| 957 // The code is null if we ended up not needing the lazily | |
| 958 // initialized field after all because of constant folding | |
| 959 // before code generation. | |
| 960 if (code == null) return null; | |
| 961 // The code only computes the initial value. We build the lazy-check | |
| 962 // here: | |
| 963 // lazyInitializer(prototype, 'name', fieldName, getterName, initial); | |
| 964 // The name is used for error reporting. The 'initial' must be a | |
| 965 // closure that constructs the initial value. | |
| 966 return js('#(#,#,#,#,#)', | |
| 967 [js(lazyInitializerName), | |
| 968 js(isolateProperties), | |
| 969 js.string(element.name), | |
| 970 js.string(namer.getNameX(element)), | |
| 971 js.string(namer.getLazyInitializerName(element)), | |
| 972 code]); | |
| 973 } | |
| 974 | |
| 958 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) { | 975 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) { |
| 959 if (constant.isFunction) return true; // Already emitted. | 976 if (constant.isFunction) return true; // Already emitted. |
| 960 if (constant.isPrimitive) return true; // Inlined. | 977 if (constant.isPrimitive) return true; // Inlined. |
| 961 if (constant.isDummy) return true; // Inlined. | 978 if (constant.isDummy) return true; // Inlined. |
| 962 // The name is null when the constant is already a JS constant. | 979 // The name is null when the constant is already a JS constant. |
| 963 // TODO(floitsch): every constant should be registered, so that we can | 980 // TODO(floitsch): every constant should be registered, so that we can |
| 964 // share the ones that take up too much space (like some strings). | 981 // share the ones that take up too much space (like some strings). |
| 965 if (namer.constantName(constant) == null) return true; | 982 if (namer.constantName(constant) == null) return true; |
| 966 return false; | 983 return false; |
| 967 } | 984 } |
| (...skipping 1125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2093 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 2110 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
| 2094 if (element.isInstanceMember) { | 2111 if (element.isInstanceMember) { |
| 2095 cachedClassBuilders.remove(element.enclosingClass); | 2112 cachedClassBuilders.remove(element.enclosingClass); |
| 2096 | 2113 |
| 2097 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 2114 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
| 2098 | 2115 |
| 2099 } | 2116 } |
| 2100 } | 2117 } |
| 2101 } | 2118 } |
| 2102 } | 2119 } |
| OLD | NEW |