Chromium Code Reviews| OLD | NEW |
|---|---|
| 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; | 5 part of dart2js; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * If true, print a warning for each method that was resolved, but not | 8 * If true, print a warning for each method that was resolved, but not |
| 9 * compiled. | 9 * compiled. |
| 10 */ | 10 */ |
| 11 const bool REPORT_EXCESS_RESOLUTION = false; | 11 const bool REPORT_EXCESS_RESOLUTION = false; |
| 12 | 12 |
| 13 /** | 13 /** |
| 14 * If true, dump the inferred types after compilation. | |
| 15 */ | |
| 16 const bool DUMP_INFERRED_TYPES = false; | |
| 17 | |
| 18 /** | |
| 19 * Contains backend-specific data that is used throughout the compilation of | 14 * Contains backend-specific data that is used throughout the compilation of |
| 20 * one work item. | 15 * one work item. |
| 21 */ | 16 */ |
| 22 class ItemCompilationContext { | 17 class ItemCompilationContext { |
| 23 } | 18 } |
| 24 | 19 |
| 25 abstract class WorkItem { | 20 abstract class WorkItem { |
| 26 final ItemCompilationContext compilationContext; | 21 final ItemCompilationContext compilationContext; |
| 27 /** | 22 /** |
| 28 * Documentation wanted -- johnniwinther | 23 * Documentation wanted -- johnniwinther |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 78 } | 73 } |
| 79 | 74 |
| 80 abstract class Backend { | 75 abstract class Backend { |
| 81 final Compiler compiler; | 76 final Compiler compiler; |
| 82 final ConstantSystem constantSystem; | 77 final ConstantSystem constantSystem; |
| 83 | 78 |
| 84 Backend(this.compiler, | 79 Backend(this.compiler, |
| 85 [ConstantSystem constantSystem = DART_CONSTANT_SYSTEM]) | 80 [ConstantSystem constantSystem = DART_CONSTANT_SYSTEM]) |
| 86 : this.constantSystem = constantSystem; | 81 : this.constantSystem = constantSystem; |
| 87 | 82 |
| 83 /** | |
| 84 * Map each library to the size of the generated code for that library. | |
| 85 */ | |
| 86 final CodeSizeCounter codeSizeCounter = new CodeSizeCounter(); | |
|
ahe
2013/11/27 19:28:53
It doesn't seem appropriate for the backend to exp
sigurdm
2013/11/29 10:39:37
Done.
| |
| 87 | |
| 88 CodeBuffer emitCodeFor(Element element); | |
|
ahe
2013/11/27 19:28:53
Please document this method.
sigurdm
2013/11/29 10:39:37
Done.
| |
| 89 | |
| 88 void initializeHelperClasses() {} | 90 void initializeHelperClasses() {} |
| 89 | 91 |
| 90 void enqueueAllTopLevelFunctions(LibraryElement lib, Enqueuer world) { | 92 void enqueueAllTopLevelFunctions(LibraryElement lib, Enqueuer world) { |
| 91 lib.forEachExport((Element e) { | 93 lib.forEachExport((Element e) { |
| 92 if (e.isFunction()) world.addToWorkList(e); | 94 if (e.isFunction()) world.addToWorkList(e); |
| 93 }); | 95 }); |
| 94 } | 96 } |
| 95 | 97 |
| 96 void enqueueHelpers(ResolutionEnqueuer world, TreeElements elements); | 98 void enqueueHelpers(ResolutionEnqueuer world, TreeElements elements); |
| 97 void codegen(CodegenWorkItem work); | 99 void codegen(CodegenWorkItem work); |
| 98 | 100 |
| 99 // The backend determines the native resolution enqueuer, with a no-op | 101 // The backend determines the native resolution enqueuer, with a no-op |
| 100 // default, so tools like dart2dart can ignore the native classes. | 102 // default, so tools like dart2dart can ignore the native classes. |
| 101 native.NativeEnqueuer nativeResolutionEnqueuer(world) { | 103 native.NativeEnqueuer nativeResolutionEnqueuer(world) { |
| 102 return new native.NativeEnqueuer(); | 104 return new native.NativeEnqueuer(); |
| 103 } | 105 } |
| 104 native.NativeEnqueuer nativeCodegenEnqueuer(world) { | 106 native.NativeEnqueuer nativeCodegenEnqueuer(world) { |
| 105 return new native.NativeEnqueuer(); | 107 return new native.NativeEnqueuer(); |
| 106 } | 108 } |
| 107 | 109 |
| 108 void assembleProgram(); | 110 void assembleProgram(); |
| 109 List<CompilerTask> get tasks; | 111 List<CompilerTask> get tasks; |
| 110 | 112 |
| 111 void onResolutionComplete() {} | 113 void onResolutionComplete() {} |
| 112 | 114 |
| 113 // TODO(ahe,karlklose): rename this? | 115 Map collectDumpInfo() { |
|
ahe
2013/11/27 19:28:53
This seems like an odd fit for this functionality.
sigurdm
2013/11/29 10:39:37
Done.
| |
| 114 void dumpInferredTypes() {} | 116 List<LibraryElement> sortedLibraries = compiler.libraries.values.toList(); |
| 117 sortedLibraries.sort( | |
|
karlklose
2013/11/27 14:19:23
You could also write it as follows: (we usually fo
sigurdm
2013/11/29 10:39:37
Much better
| |
| 118 (LibraryElement l1, LibraryElement l2) { | |
| 119 if (l1.isPlatformLibrary && !l2.isPlatformLibrary) { | |
| 120 return 1; | |
| 121 } else if (!l1.isPlatformLibrary && l2.isPlatformLibrary) { | |
| 122 return -1; | |
| 123 } | |
| 124 return l1.getLibraryName(). | |
| 125 compareTo(l2.getLibraryName()); | |
| 126 }); | |
| 127 List libraryInfos = []; | |
|
karlklose
2013/11/27 14:19:23
'List' -> 'List<Map>', maybe even add the key and
sigurdm
2013/11/29 10:39:37
Problem is, that the value type is not fixed.
But
| |
| 128 for (LibraryElement library in sortedLibraries) { | |
|
karlklose
2013/11/27 14:19:23
How about:
libraryInfos.addAll(sortedLibraries
sigurdm
2013/11/29 10:39:37
Nice
| |
| 129 Map libraryInfo = library.collectInferredTypes(compiler); | |
| 130 if (libraryInfo != null) { | |
| 131 libraryInfos.add(libraryInfo); | |
| 132 } | |
| 133 } | |
| 134 Map info = { | |
| 135 "compilation duration" : compiler.totalCompileTime.elapsedTicks, | |
|
karlklose
2013/11/27 14:19:23
Remove the space between the map key and ':'.
sigurdm
2013/11/29 10:39:37
Done.
| |
| 136 // TODO (sigurdm) Also count the size of deferred code | |
| 137 "generated size" : compiler.assembledCode.length, | |
| 138 "libraries" : libraryInfos, | |
| 139 "compilation time" : new DateTime.now().toString() | |
| 140 }; | |
| 141 if (commandline.BUILD_ID != null) { | |
| 142 info["dart2js version"] = commandline.BUILD_ID.toString(); | |
| 143 } | |
| 144 return info; | |
| 145 } | |
| 146 | |
| 147 void dumpInfo() { | |
| 148 Map info = collectDumpInfo(); | |
| 149 StringBuffer buffer = new StringBuffer(); | |
| 150 dumpInfoHtml(info, buffer); | |
| 151 compiler.outputProvider('', 'info.html') | |
| 152 ..add(buffer.toString()) | |
| 153 ..close(); | |
| 154 } | |
| 115 | 155 |
| 116 ItemCompilationContext createItemCompilationContext() { | 156 ItemCompilationContext createItemCompilationContext() { |
| 117 return new ItemCompilationContext(); | 157 return new ItemCompilationContext(); |
| 118 } | 158 } |
| 119 | 159 |
| 120 bool classNeedsRti(ClassElement cls); | 160 bool classNeedsRti(ClassElement cls); |
| 121 bool methodNeedsRti(FunctionElement function); | 161 bool methodNeedsRti(FunctionElement function); |
| 122 | 162 |
| 123 | 163 |
| 124 /// Called during codegen when [constant] has been used. | 164 /// Called during codegen when [constant] has been used. |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 360 * associated with a particular element. | 400 * associated with a particular element. |
| 361 */ | 401 */ |
| 362 final TreeElements globalDependencies = new TreeElementMapping(null); | 402 final TreeElements globalDependencies = new TreeElementMapping(null); |
| 363 | 403 |
| 364 final bool enableMinification; | 404 final bool enableMinification; |
| 365 final bool enableTypeAssertions; | 405 final bool enableTypeAssertions; |
| 366 final bool enableUserAssertions; | 406 final bool enableUserAssertions; |
| 367 final bool trustTypeAnnotations; | 407 final bool trustTypeAnnotations; |
| 368 final bool enableConcreteTypeInference; | 408 final bool enableConcreteTypeInference; |
| 369 final bool disableTypeInferenceFlag; | 409 final bool disableTypeInferenceFlag; |
| 410 final bool dumpInfo; | |
| 370 | 411 |
| 371 /** | 412 /** |
| 372 * The maximum size of a concrete type before it widens to dynamic during | 413 * The maximum size of a concrete type before it widens to dynamic during |
| 373 * concrete type inference. | 414 * concrete type inference. |
| 374 */ | 415 */ |
| 375 final int maxConcreteTypeSize; | 416 final int maxConcreteTypeSize; |
| 376 final bool analyzeAllFlag; | 417 final bool analyzeAllFlag; |
| 377 final bool analyzeOnly; | 418 final bool analyzeOnly; |
| 378 /** | 419 /** |
| 379 * If true, skip analysis of method bodies and field initializers. Implies | 420 * If true, skip analysis of method bodies and field initializers. Implies |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 621 bool generateSourceMap: true, | 662 bool generateSourceMap: true, |
| 622 this.analyzeAllFlag: false, | 663 this.analyzeAllFlag: false, |
| 623 bool analyzeOnly: false, | 664 bool analyzeOnly: false, |
| 624 bool analyzeSignaturesOnly: false, | 665 bool analyzeSignaturesOnly: false, |
| 625 this.preserveComments: false, | 666 this.preserveComments: false, |
| 626 this.verbose: false, | 667 this.verbose: false, |
| 627 this.sourceMapUri: null, | 668 this.sourceMapUri: null, |
| 628 this.buildId: UNDETERMINED_BUILD_ID, | 669 this.buildId: UNDETERMINED_BUILD_ID, |
| 629 this.globalJsName: r'$', | 670 this.globalJsName: r'$', |
| 630 this.terseDiagnostics: false, | 671 this.terseDiagnostics: false, |
| 672 this.dumpInfo: false, | |
| 631 outputProvider, | 673 outputProvider, |
| 632 List<String> strips: const []}) | 674 List<String> strips: const []}) |
| 633 : this.analyzeOnly = analyzeOnly || analyzeSignaturesOnly, | 675 : this.analyzeOnly = analyzeOnly || analyzeSignaturesOnly, |
| 634 this.analyzeSignaturesOnly = analyzeSignaturesOnly, | 676 this.analyzeSignaturesOnly = analyzeSignaturesOnly, |
| 635 this.outputProvider = (outputProvider == null) | 677 this.outputProvider = (outputProvider == null) |
| 636 ? NullSink.outputProvider | 678 ? NullSink.outputProvider |
| 637 : outputProvider { | 679 : outputProvider { |
| 638 world = new World(this); | 680 world = new World(this); |
| 639 | 681 |
| 640 closureMapping.ClosureNamer closureNamer; | 682 closureMapping.ClosureNamer closureNamer; |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1128 libraries.forEach((_, lib) => fullyEnqueueLibrary(lib, | 1170 libraries.forEach((_, lib) => fullyEnqueueLibrary(lib, |
| 1129 enqueuer.codegen)); | 1171 enqueuer.codegen)); |
| 1130 } | 1172 } |
| 1131 processQueue(enqueuer.codegen, main); | 1173 processQueue(enqueuer.codegen, main); |
| 1132 enqueuer.codegen.logSummary(log); | 1174 enqueuer.codegen.logSummary(log); |
| 1133 | 1175 |
| 1134 if (compilationFailed) return; | 1176 if (compilationFailed) return; |
| 1135 | 1177 |
| 1136 backend.assembleProgram(); | 1178 backend.assembleProgram(); |
| 1137 | 1179 |
| 1180 if (dumpInfo) { | |
| 1181 backend.dumpInfo(); | |
|
ahe
2013/11/27 19:28:53
This should be its own task. Then we can see how l
sigurdm
2013/11/29 10:39:37
Done.
| |
| 1182 } | |
| 1183 | |
| 1138 checkQueues(); | 1184 checkQueues(); |
| 1139 | 1185 |
| 1140 if (compilationFailed) { | 1186 if (compilationFailed) { |
| 1141 assembledCode = null; // Signals failure. | 1187 assembledCode = null; // Signals failure. |
| 1142 } | 1188 } |
| 1143 } | 1189 } |
| 1144 | 1190 |
| 1145 void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) { | 1191 void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) { |
| 1146 void enqueueAll(Element element) { | 1192 void enqueueAll(Element element) { |
| 1147 fullyEnqueueTopLevelElement(element, world); | 1193 fullyEnqueueTopLevelElement(element, world); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1187 } | 1233 } |
| 1188 world.addToWorkList(main); | 1234 world.addToWorkList(main); |
| 1189 } | 1235 } |
| 1190 progress.reset(); | 1236 progress.reset(); |
| 1191 world.forEach((WorkItem work) { | 1237 world.forEach((WorkItem work) { |
| 1192 withCurrentElement(work.element, () => work.run(this, world)); | 1238 withCurrentElement(work.element, () => work.run(this, world)); |
| 1193 }); | 1239 }); |
| 1194 world.queueIsClosed = true; | 1240 world.queueIsClosed = true; |
| 1195 if (compilationFailed) return; | 1241 if (compilationFailed) return; |
| 1196 assert(world.checkNoEnqueuedInvokedInstanceMethods()); | 1242 assert(world.checkNoEnqueuedInvokedInstanceMethods()); |
| 1197 if (DUMP_INFERRED_TYPES && phase == PHASE_COMPILING) { | |
| 1198 backend.dumpInferredTypes(); | |
| 1199 } | |
| 1200 } | 1243 } |
| 1201 | 1244 |
| 1202 /** | 1245 /** |
| 1203 * Perform various checks of the queues. This includes checking that | 1246 * Perform various checks of the queues. This includes checking that |
| 1204 * the queues are empty (nothing was added after we stopped | 1247 * the queues are empty (nothing was added after we stopped |
| 1205 * processing the queues). Also compute the number of methods that | 1248 * processing the queues). Also compute the number of methods that |
| 1206 * were resolved, but not compiled (aka excess resolution). | 1249 * were resolved, but not compiled (aka excess resolution). |
| 1207 */ | 1250 */ |
| 1208 checkQueues() { | 1251 checkQueues() { |
| 1209 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) { | 1252 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) { |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1655 | 1698 |
| 1656 void close() {} | 1699 void close() {} |
| 1657 | 1700 |
| 1658 toString() => name; | 1701 toString() => name; |
| 1659 | 1702 |
| 1660 /// Convenience method for getting an [api.CompilerOutputProvider]. | 1703 /// Convenience method for getting an [api.CompilerOutputProvider]. |
| 1661 static NullSink outputProvider(String name, String extension) { | 1704 static NullSink outputProvider(String name, String extension) { |
| 1662 return new NullSink('$name.$extension'); | 1705 return new NullSink('$name.$extension'); |
| 1663 } | 1706 } |
| 1664 } | 1707 } |
| OLD | NEW |