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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart

Issue 569583002: Make dart2js deferred loading work in cps mode. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 const USE_NEW_EMITTER = const bool.fromEnvironment("dart2js.use.new.emitter"); 7 const USE_NEW_EMITTER = const bool.fromEnvironment("dart2js.use.new.emitter");
8 8
9 /** 9 /**
10 * Generates the code for all used classes in the program. Static fields (even 10 * Generates the code for all used classes in the program. Static fields (even
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 80
81 /** 81 /**
82 * List of expressions and statements that will be included in the 82 * List of expressions and statements that will be included in the
83 * precompiled function. 83 * precompiled function.
84 * 84 *
85 * To save space, dart2js normally generates constructors and accessors 85 * To save space, dart2js normally generates constructors and accessors
86 * dynamically. This doesn't work in CSP mode, and may impact startup time 86 * dynamically. This doesn't work in CSP mode, and may impact startup time
87 * negatively. So dart2js will emit these functions to a separate file that 87 * negatively. So dart2js will emit these functions to a separate file that
88 * can be optionally included to support CSP mode or for faster startup. 88 * can be optionally included to support CSP mode or for faster startup.
89 */ 89 */
90 List<jsAst.Node> precompiledFunction = <jsAst.Node>[]; 90 Map<OutputUnit, List<jsAst.Node>> _precompiledFunctions =
91 new Map<OutputUnit, List<jsAst.Node>>();
91 92
92 List<jsAst.Expression> precompiledConstructorNames = <jsAst.Expression>[]; 93 Map<OutputUnit, List<jsAst.Expression>> _precompiledConstructorNames =
94 new Map<OutputUnit, List<jsAst.Expression>>();
93 95
94 // True if Isolate.makeConstantList is needed. 96 // True if Isolate.makeConstantList is needed.
95 bool hasMakeConstantList = false; 97 bool hasMakeConstantList = false;
96 98
97 /** 99 /**
98 * Accumulate properties for classes and libraries, describing their 100 * Accumulate properties for classes and libraries, describing their
99 * static/top-level members. 101 * static/top-level members.
100 * Later, these members are emitted when the class or library is emitted. 102 * Later, these members are emitted when the class or library is emitted.
101 * 103 *
102 * For supporting deferred loading we keep one list per output unit. 104 * For supporting deferred loading we keep one list per output unit.
(...skipping 19 matching lines...) Expand all
122 classEmitter.task = this; 124 classEmitter.task = this;
123 nsmEmitter.task = this; 125 nsmEmitter.task = this;
124 typeTestEmitter.task = this; 126 typeTestEmitter.task = this;
125 interceptorEmitter.task = this; 127 interceptorEmitter.task = this;
126 metadataEmitter.task = this; 128 metadataEmitter.task = this;
127 // TODO(18886): Remove this call (and the show in the import) once the 129 // TODO(18886): Remove this call (and the show in the import) once the
128 // memory-leak in the VM is fixed. 130 // memory-leak in the VM is fixed.
129 templateManager.clear(); 131 templateManager.clear();
130 } 132 }
131 133
134 List<jsAst.Node> precompiledFunction(OutputUnit outputUnit) {
floitsch 2014/09/12 17:00:18 precompiledFunctionsFor
sigurdm 2014/09/15 13:10:48 Done.
135 return _precompiledFunctions
136 .putIfAbsent(outputUnit, () => new List<jsAst.Node>());
137 }
138
139 List<jsAst.Expression> precompiledConstructorNames(OutputUnit outputUnit) {
floitsch 2014/09/12 17:00:17 precompiledConstructorNamesFor
sigurdm 2014/09/15 13:10:48 Done.
140 return _precompiledConstructorNames
141 .putIfAbsent(outputUnit, () => new List<jsAst.Expression>());
142 }
143
132 void addComment(String comment, CodeBuffer buffer) { 144 void addComment(String comment, CodeBuffer buffer) {
133 buffer.write(jsAst.prettyPrint(js.comment(comment), compiler)); 145 buffer.write(jsAst.prettyPrint(js.comment(comment), compiler));
134 } 146 }
135 147
136 jsAst.Expression constantReference(Constant value) { 148 jsAst.Expression constantReference(Constant value) {
137 return constantEmitter.reference(value); 149 return constantEmitter.reference(value);
138 } 150 }
139 151
140 jsAst.Expression constantInitializerExpression(Constant value) { 152 jsAst.Expression constantInitializerExpression(Constant value) {
141 return constantEmitter.initializationExpression(value); 153 return constantEmitter.initializationExpression(value);
(...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 throw compiler.internalError(element, 828 throw compiler.internalError(element,
817 'Do not know how to reflect on this $element.'); 829 'Do not know how to reflect on this $element.');
818 } 830 }
819 831
820 String namedParametersAsReflectionNames(Selector selector) { 832 String namedParametersAsReflectionNames(Selector selector) {
821 if (selector.getOrderedNamedArguments().isEmpty) return ''; 833 if (selector.getOrderedNamedArguments().isEmpty) return '';
822 String names = selector.getOrderedNamedArguments().join(':'); 834 String names = selector.getOrderedNamedArguments().join(':');
823 return ':$names'; 835 return ':$names';
824 } 836 }
825 837
826 jsAst.FunctionDeclaration buildPrecompiledFunction() { 838 jsAst.FunctionDeclaration buildPrecompiledFunction(OutputUnit outputUnit) {
827 // TODO(ahe): Compute a hash code. 839 // TODO(ahe): Compute a hash code.
828 return js.statement(''' 840 return js.statement('''
829 function dart_precompiled(\$collectedClasses) { 841 function dart_precompiled(\$collectedClasses) {
830 var \$desc; 842 var \$desc;
831 #; 843 #;
832 return #; 844 return #;
833 }''', [ 845 }''', [
834 precompiledFunction, 846 precompiledFunction(outputUnit),
835 new jsAst.ArrayInitializer.from(precompiledConstructorNames)]); 847 new jsAst.ArrayInitializer.from(
848 precompiledConstructorNames(outputUnit))]);
836 } 849 }
837 850
838 void generateClass(ClassElement classElement, ClassBuilder properties) { 851 void generateClass(ClassElement classElement, ClassBuilder properties) {
839 compiler.withCurrentElement(classElement, () { 852 compiler.withCurrentElement(classElement, () {
840 if (compiler.hasIncrementalSupport) { 853 if (compiler.hasIncrementalSupport) {
841 ClassBuilder builder = 854 ClassBuilder builder =
842 cachedClassBuilders.putIfAbsent(classElement, () { 855 cachedClassBuilders.putIfAbsent(classElement, () {
843 ClassBuilder builder = new ClassBuilder(classElement, namer); 856 ClassBuilder builder = new ClassBuilder(classElement, namer);
844 classEmitter.generateClass( 857 classEmitter.generateClass(
845 classElement, builder, additionalProperties[classElement]); 858 classElement, builder, additionalProperties[classElement]);
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after
1426 ..write(namer.globalObjectFor(library)) 1439 ..write(namer.globalObjectFor(library))
1427 ..write(',$_') 1440 ..write(',$_')
1428 ..write(jsAst.prettyPrint(initializers, 1441 ..write(jsAst.prettyPrint(initializers,
1429 compiler, 1442 compiler,
1430 monitor: compiler.dumpInfoTask)) 1443 monitor: compiler.dumpInfoTask))
1431 ..write(library == compiler.mainApp ? ',${n}1' : "") 1444 ..write(library == compiler.mainApp ? ',${n}1' : "")
1432 ..write('],$n'); 1445 ..write('],$n');
1433 } 1446 }
1434 } 1447 }
1435 1448
1436 void emitPrecompiledConstructor(String constructorName, 1449 void emitPrecompiledConstructor(OutputUnit outputUnit,
1450 String constructorName,
1437 jsAst.Expression constructorAst) { 1451 jsAst.Expression constructorAst) {
1438 precompiledFunction.add( 1452 precompiledFunction(outputUnit).add(
1439 new jsAst.FunctionDeclaration( 1453 new jsAst.FunctionDeclaration(
1440 new jsAst.VariableDeclaration(constructorName), constructorAst)); 1454 new jsAst.VariableDeclaration(constructorName), constructorAst));
1441 precompiledFunction.add( 1455 precompiledFunction(outputUnit).add(
1442 js.statement(r'''{ 1456 js.statement(r'''{
1443 #.builtin$cls = #; 1457 #.builtin$cls = #;
1444 if (!"name" in #) 1458 if (!"name" in #)
1445 #.name = #; 1459 #.name = #;
1446 $desc=$collectedClasses.#; 1460 $desc=$collectedClasses.#;
1447 if ($desc instanceof Array) $desc = $desc[1]; 1461 if ($desc instanceof Array) $desc = $desc[1];
1448 #.prototype = $desc; 1462 #.prototype = $desc;
1449 }''', 1463 }''',
1450 [ constructorName, js.string(constructorName), 1464 [ constructorName, js.string(constructorName),
1451 constructorName, 1465 constructorName,
1452 constructorName, js.string(constructorName), 1466 constructorName, js.string(constructorName),
1453 constructorName, 1467 constructorName,
1454 constructorName 1468 constructorName
1455 ])); 1469 ]));
1456 1470
1457 precompiledConstructorNames.add(js('#', constructorName)); 1471 precompiledConstructorNames(outputUnit).add(js('#', constructorName));
1458 } 1472 }
1459 1473
1460 void assembleProgram() { 1474 void assembleProgram() {
1461 measure(() { 1475 measure(() {
1462 invalidateCaches(); 1476 invalidateCaches();
1463 1477
1464 // Compute the required type checks to know which classes need a 1478 // Compute the required type checks to know which classes need a
1465 // 'is$' method. 1479 // 'is$' method.
1466 typeTestEmitter.computeRequiredTypeChecks(); 1480 typeTestEmitter.computeRequiredTypeChecks();
1467 1481
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1614 js.string(typeReference)); 1628 js.string(typeReference));
1615 jsAst.Node declaration = new jsAst.ObjectInitializer([descriptor]); 1629 jsAst.Node declaration = new jsAst.ObjectInitializer([descriptor]);
1616 String mangledName = namer.getNameX(typedef); 1630 String mangledName = namer.getNameX(typedef);
1617 String reflectionName = getReflectionName(typedef, mangledName); 1631 String reflectionName = getReflectionName(typedef, mangledName);
1618 getElementDescriptorForOutputUnit(library, mainUnit) 1632 getElementDescriptorForOutputUnit(library, mainUnit)
1619 ..addProperty(mangledName, declaration) 1633 ..addProperty(mangledName, declaration)
1620 ..addProperty("+$reflectionName", js.string('')); 1634 ..addProperty("+$reflectionName", js.string(''));
1621 // Also emit a trivial constructor for CSP mode. 1635 // Also emit a trivial constructor for CSP mode.
1622 String constructorName = mangledName; 1636 String constructorName = mangledName;
1623 jsAst.Expression constructorAst = js('function() {}'); 1637 jsAst.Expression constructorAst = js('function() {}');
1624 emitPrecompiledConstructor(constructorName, constructorAst); 1638 emitPrecompiledConstructor(mainOutputUnit,
1639 constructorName,
1640 constructorAst);
1625 } 1641 }
1626 1642
1627 if (!mangledFieldNames.isEmpty) { 1643 if (!mangledFieldNames.isEmpty) {
1628 var keys = mangledFieldNames.keys.toList(); 1644 var keys = mangledFieldNames.keys.toList();
1629 keys.sort(); 1645 keys.sort();
1630 var properties = []; 1646 var properties = [];
1631 for (String key in keys) { 1647 for (String key in keys) {
1632 var value = js.string('${mangledFieldNames[key]}'); 1648 var value = js.string('${mangledFieldNames[key]}');
1633 properties.add(new jsAst.Property(js.string(key), value)); 1649 properties.add(new jsAst.Property(js.string(key), value));
1634 } 1650 }
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1783 if (typeof print === "function") { 1799 if (typeof print === "function") {
1784 print("Size of $object: " 1800 print("Size of $object: "
1785 + String(Object.getOwnPropertyNames($object).length) 1801 + String(Object.getOwnPropertyNames($object).length)
1786 + ", fast properties " + HasFastProperties($object)); 1802 + ", fast properties " + HasFastProperties($object));
1787 } 1803 }
1788 '''); 1804 ''');
1789 } 1805 }
1790 } 1806 }
1791 1807
1792 jsAst.FunctionDeclaration precompiledFunctionAst = 1808 jsAst.FunctionDeclaration precompiledFunctionAst =
1793 buildPrecompiledFunction(); 1809 buildPrecompiledFunction(mainOutputUnit);
1794 emitInitFunction(mainBuffer); 1810 emitInitFunction(mainBuffer);
1795 emitMain(mainBuffer); 1811 emitMain(mainBuffer);
1796 mainBuffer.add('})()\n'); 1812 mainBuffer.add('})()\n');
1797 1813
1798 if (compiler.useContentSecurityPolicy) { 1814 if (compiler.useContentSecurityPolicy) {
1799 mainBuffer.write( 1815 mainBuffer.write(
1800 jsAst.prettyPrint( 1816 jsAst.prettyPrint(
1801 precompiledFunctionAst, compiler, 1817 precompiledFunctionAst, compiler,
1802 monitor: compiler.dumpInfoTask, 1818 monitor: compiler.dumpInfoTask,
1803 allowVariableMinification: false).getText()); 1819 allowVariableMinification: false).getText());
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
2020 2036
2021 typeTestEmitter.emitRuntimeTypeSupport(outputBuffer, outputUnit); 2037 typeTestEmitter.emitRuntimeTypeSupport(outputBuffer, outputUnit);
2022 2038
2023 emitCompileTimeConstants(outputBuffer, outputUnit); 2039 emitCompileTimeConstants(outputBuffer, outputUnit);
2024 outputBuffer.write('}$N'); 2040 outputBuffer.write('}$N');
2025 String code = outputBuffer.getText(); 2041 String code = outputBuffer.getText();
2026 2042
2027 // Make a unique hash of the code (before the sourcemaps are added) 2043 // Make a unique hash of the code (before the sourcemaps are added)
2028 // This will be used to retrieve the initializing function from the global 2044 // This will be used to retrieve the initializing function from the global
2029 // variable. 2045 // variable.
2030 String hash = hashOfString(code); 2046 String hash = hashOfString(code);
floitsch 2014/09/12 17:00:17 Can't you do the hash after the cspcode?
sigurdm 2014/09/15 13:10:48 My thinking was that the csp-code follows determin
2031 2047
2048 CodeBuffer cspCode = new CodeBuffer();
2049 if (compiler.useContentSecurityPolicy) {
2050 jsAst.FunctionDeclaration precompiledFunctionAst =
2051 buildPrecompiledFunction(outputUnit);
2052
2053 cspCode.write(
2054 jsAst.prettyPrint(
2055 precompiledFunctionAst, compiler,
2056 monitor: compiler.dumpInfoTask,
2057 allowVariableMinification: false).getText());
2058 }
2059
2032 outputBuffers[outputUnit] = outputBuffer; 2060 outputBuffers[outputUnit] = outputBuffer;
2033 compiler.outputProvider(outputUnit.partFileName(compiler), 'part.js') 2061 compiler.outputProvider(outputUnit.partFileName(compiler), 'part.js')
2034 ..add(code) 2062 ..add(code)
2035 ..add('${deferredInitializers}["$hash"]$_=$_' 2063 ..add('${deferredInitializers}["$hash"]$_=$_'
2036 '${deferredInitializers}.current') 2064 '${deferredInitializers}.current$N')
2065 ..add(cspCode.getText())
2037 ..close(); 2066 ..close();
2038 2067
2039 hunkHashes[outputUnit] = hash; 2068 hunkHashes[outputUnit] = hash;
2040 // TODO(johnniwinther): Support source maps for deferred code. 2069 // TODO(johnniwinther): Support source maps for deferred code.
2041 } 2070 }
2042 return hunkHashes; 2071 return hunkHashes;
2043 } 2072 }
2044 2073
2045 String buildGeneratedBy() { 2074 String buildGeneratedBy() {
2046 var suffix = ''; 2075 var suffix = '';
(...skipping 26 matching lines...) Expand all
2073 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { 2102 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) {
2074 if (element.isInstanceMember) { 2103 if (element.isInstanceMember) {
2075 cachedClassBuilders.remove(element.enclosingClass); 2104 cachedClassBuilders.remove(element.enclosingClass);
2076 2105
2077 nativeEmitter.cachedBuilders.remove(element.enclosingClass); 2106 nativeEmitter.cachedBuilders.remove(element.enclosingClass);
2078 2107
2079 } 2108 }
2080 } 2109 }
2081 } 2110 }
2082 } 2111 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698