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 library dart2js.compiler_base; | 5 library dart2js.compiler_base; |
6 | 6 |
7 import 'dart:async' show EventSink, Future; | 7 import 'dart:async' show EventSink, Future; |
8 | 8 |
9 import '../compiler_new.dart' as api; | 9 import '../compiler_new.dart' as api; |
10 import 'closure.dart' as closureMapping show ClosureTask; | 10 import 'closure.dart' as closureMapping show ClosureTask; |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 DietParserTask dietParser; | 145 DietParserTask dietParser; |
146 ParserTask parser; | 146 ParserTask parser; |
147 PatchParserTask patchParser; | 147 PatchParserTask patchParser; |
148 LibraryLoaderTask libraryLoader; | 148 LibraryLoaderTask libraryLoader; |
149 SerializationTask serialization; | 149 SerializationTask serialization; |
150 ResolverTask resolver; | 150 ResolverTask resolver; |
151 closureMapping.ClosureTask closureToClassMapper; | 151 closureMapping.ClosureTask closureToClassMapper; |
152 TypeCheckerTask checker; | 152 TypeCheckerTask checker; |
153 GlobalTypeInferenceTask globalInference; | 153 GlobalTypeInferenceTask globalInference; |
154 JavaScriptBackend backend; | 154 JavaScriptBackend backend; |
| 155 CodegenWorldBuilder _codegenWorldBuilder; |
155 | 156 |
156 GenericTask selfTask; | 157 GenericTask selfTask; |
157 | 158 |
158 /// The constant environment for the frontend interpretation of compile-time | 159 /// The constant environment for the frontend interpretation of compile-time |
159 /// constants. | 160 /// constants. |
160 ConstantEnvironment constants; | 161 ConstantEnvironment constants; |
161 | 162 |
162 EnqueueTask enqueuer; | 163 EnqueueTask enqueuer; |
163 DeferredLoadTask deferredLoadTask; | 164 DeferredLoadTask deferredLoadTask; |
164 MirrorUsageAnalyzerTask mirrorUsageAnalyzerTask; | 165 MirrorUsageAnalyzerTask mirrorUsageAnalyzerTask; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 | 274 |
274 /// Creates the resolver task. | 275 /// Creates the resolver task. |
275 /// | 276 /// |
276 /// Override this to mock the resolver for testing. | 277 /// Override this to mock the resolver for testing. |
277 ResolverTask createResolverTask() { | 278 ResolverTask createResolverTask() { |
278 return new ResolverTask(resolution, backend.constantCompilerTask, measurer); | 279 return new ResolverTask(resolution, backend.constantCompilerTask, measurer); |
279 } | 280 } |
280 | 281 |
281 ResolutionWorldBuilder get resolutionWorldBuilder => | 282 ResolutionWorldBuilder get resolutionWorldBuilder => |
282 enqueuer.resolution.worldBuilder; | 283 enqueuer.resolution.worldBuilder; |
283 CodegenWorldBuilder get codegenWorldBuilder => enqueuer.codegen.worldBuilder; | 284 CodegenWorldBuilder get codegenWorldBuilder { |
| 285 assert(invariant(NO_LOCATION_SPANNABLE, _codegenWorldBuilder != null, |
| 286 message: "CodegenWorldBuilder has not been created yet.")); |
| 287 return _codegenWorldBuilder; |
| 288 } |
284 | 289 |
285 bool get analyzeAll => options.analyzeAll || compileAll; | 290 bool get analyzeAll => options.analyzeAll || compileAll; |
286 | 291 |
287 bool get compileAll => false; | 292 bool get compileAll => false; |
288 | 293 |
289 bool get disableTypeInference => | 294 bool get disableTypeInference => |
290 options.disableTypeInference || compilationFailed; | 295 options.disableTypeInference || compilationFailed; |
291 | 296 |
292 // TODO(het): remove this from here. Either inline at all use sites or add it | 297 // TODO(het): remove this from here. Either inline at all use sites or add it |
293 // to Reporter. | 298 // to Reporter. |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 globalInference.runGlobalTypeInference( | 680 globalInference.runGlobalTypeInference( |
676 mainFunction, closedWorld, closedWorldRefiner); | 681 mainFunction, closedWorld, closedWorldRefiner); |
677 | 682 |
678 if (stopAfterTypeInference) return; | 683 if (stopAfterTypeInference) return; |
679 | 684 |
680 backend.onTypeInferenceComplete(); | 685 backend.onTypeInferenceComplete(); |
681 | 686 |
682 reporter.log('Compiling...'); | 687 reporter.log('Compiling...'); |
683 phase = PHASE_COMPILING; | 688 phase = PHASE_COMPILING; |
684 | 689 |
685 codegenWorldBuilder.open(closedWorld); | 690 Enqueuer codegenEnqueuer = enqueuer.createCodegenEnqueuer(closedWorld); |
686 enqueuer.codegen.applyImpact(backend.onCodegenStart(closedWorld)); | 691 _codegenWorldBuilder = codegenEnqueuer.worldBuilder; |
| 692 _codegenWorldBuilder.open(closedWorld); |
| 693 codegenEnqueuer.applyImpact( |
| 694 backend.onCodegenStart(closedWorld, _codegenWorldBuilder)); |
687 if (compileAll) { | 695 if (compileAll) { |
688 libraryLoader.libraries.forEach((LibraryElement library) { | 696 libraryLoader.libraries.forEach((LibraryElement library) { |
689 enqueuer.codegen.applyImpact(computeImpactForLibrary(library)); | 697 codegenEnqueuer.applyImpact(computeImpactForLibrary(library)); |
690 }); | 698 }); |
691 } | 699 } |
692 processQueue(enqueuer.codegen, mainMethod, libraryLoader.libraries, | 700 processQueue(codegenEnqueuer, mainMethod, libraryLoader.libraries, |
693 onProgress: showCodegenProgress); | 701 onProgress: showCodegenProgress); |
694 enqueuer.codegen.logSummary(reporter.log); | 702 codegenEnqueuer.logSummary(reporter.log); |
695 | 703 |
696 int programSize = backend.assembleProgram(closedWorld); | 704 int programSize = backend.assembleProgram(closedWorld); |
697 | 705 |
698 if (options.dumpInfo) { | 706 if (options.dumpInfo) { |
699 dumpInfoTask.reportSize(programSize); | 707 dumpInfoTask.reportSize(programSize); |
700 dumpInfoTask.dumpInfo(closedWorld); | 708 dumpInfoTask.dumpInfo(closedWorld); |
701 } | 709 } |
702 | 710 |
703 backend.onCodegenEnd(); | 711 backend.onCodegenEnd(); |
704 | 712 |
705 checkQueues(); | 713 checkQueues(enqueuer.resolution, codegenEnqueuer); |
706 }); | 714 }); |
707 | 715 |
708 /// Perform the steps needed to fully end the resolution phase. | 716 /// Perform the steps needed to fully end the resolution phase. |
709 ClosedWorldRefiner closeResolution() { | 717 ClosedWorldRefiner closeResolution() { |
710 phase = PHASE_DONE_RESOLVING; | 718 phase = PHASE_DONE_RESOLVING; |
711 | 719 |
712 ClosedWorldImpl world = resolutionWorldBuilder.closeWorld(reporter); | 720 ClosedWorldImpl world = resolutionWorldBuilder.closeWorld(reporter); |
713 // Compute whole-program-knowledge that the backend needs. (This might | 721 // Compute whole-program-knowledge that the backend needs. (This might |
714 // require the information computed in [world.closeWorld].) | 722 // require the information computed in [world.closeWorld].) |
715 backend.onResolutionComplete(world, world); | 723 backend.onResolutionComplete(world, world); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 for (MetadataAnnotation metadata in library.metadata) { | 793 for (MetadataAnnotation metadata in library.metadata) { |
786 metadata.ensureResolved(resolution); | 794 metadata.ensureResolved(resolution); |
787 } | 795 } |
788 } | 796 } |
789 } | 797 } |
790 } | 798 } |
791 | 799 |
792 /** | 800 /** |
793 * Empty the [enqueuer] queue. | 801 * Empty the [enqueuer] queue. |
794 */ | 802 */ |
795 void emptyQueue(Enqueuer enqueuer, {void onProgress()}) { | 803 void emptyQueue(Enqueuer enqueuer, {void onProgress(Enqueuer enqueuer)}) { |
796 selfTask.measureSubtask("Compiler.emptyQueue", () { | 804 selfTask.measureSubtask("Compiler.emptyQueue", () { |
797 enqueuer.forEach((WorkItem work) { | 805 enqueuer.forEach((WorkItem work) { |
798 if (onProgress != null) { | 806 if (onProgress != null) { |
799 onProgress(); | 807 onProgress(enqueuer); |
800 } | 808 } |
801 reporter.withCurrentElement( | 809 reporter.withCurrentElement( |
802 work.element, | 810 work.element, |
803 () => selfTask.measureSubtask("world.applyImpact", () { | 811 () => selfTask.measureSubtask("world.applyImpact", () { |
804 enqueuer.applyImpact( | 812 enqueuer.applyImpact( |
805 selfTask.measureSubtask("work.run", () => work.run()), | 813 selfTask.measureSubtask("work.run", () => work.run()), |
806 impactSource: work.element); | 814 impactSource: work.element); |
807 })); | 815 })); |
808 }); | 816 }); |
809 }); | 817 }); |
810 } | 818 } |
811 | 819 |
812 void processQueue(Enqueuer enqueuer, MethodElement mainMethod, | 820 void processQueue(Enqueuer enqueuer, MethodElement mainMethod, |
813 Iterable<LibraryEntity> libraries, | 821 Iterable<LibraryEntity> libraries, |
814 {void onProgress()}) { | 822 {void onProgress(Enqueuer enqueuer)}) { |
815 selfTask.measureSubtask("Compiler.processQueue", () { | 823 selfTask.measureSubtask("Compiler.processQueue", () { |
816 enqueuer.open(impactStrategy, mainMethod, libraries); | 824 enqueuer.open(impactStrategy, mainMethod, libraries); |
817 if (options.verbose) { | 825 if (options.verbose) { |
818 progress.reset(); | 826 progress.reset(); |
819 } | 827 } |
820 emptyQueue(enqueuer, onProgress: onProgress); | 828 emptyQueue(enqueuer, onProgress: onProgress); |
821 enqueuer.queueIsClosed = true; | 829 enqueuer.queueIsClosed = true; |
822 enqueuer.close(); | 830 enqueuer.close(); |
823 // Notify the impact strategy impacts are no longer needed for this | 831 // Notify the impact strategy impacts are no longer needed for this |
824 // enqueuer. | 832 // enqueuer. |
825 impactStrategy.onImpactUsed(enqueuer.impactUse); | 833 impactStrategy.onImpactUsed(enqueuer.impactUse); |
826 backend.onQueueClosed(); | 834 backend.onQueueClosed(); |
827 assert(compilationFailed || | 835 assert(compilationFailed || |
828 enqueuer.checkNoEnqueuedInvokedInstanceMethods()); | 836 enqueuer.checkNoEnqueuedInvokedInstanceMethods()); |
829 }); | 837 }); |
830 } | 838 } |
831 | 839 |
832 /** | 840 /** |
833 * Perform various checks of the queues. This includes checking that | 841 * Perform various checks of the queues. This includes checking that |
834 * the queues are empty (nothing was added after we stopped | 842 * the queues are empty (nothing was added after we stopped |
835 * processing the queues). Also compute the number of methods that | 843 * processing the queues). Also compute the number of methods that |
836 * were resolved, but not compiled (aka excess resolution). | 844 * were resolved, but not compiled (aka excess resolution). |
837 */ | 845 */ |
838 checkQueues() { | 846 checkQueues(Enqueuer resolutionEnqueuer, Enqueuer codegenEnqueuer) { |
839 for (Enqueuer enqueuer in [enqueuer.resolution, enqueuer.codegen]) { | 847 for (Enqueuer enqueuer in [resolutionEnqueuer, codegenEnqueuer]) { |
840 enqueuer.checkQueueIsEmpty(); | 848 enqueuer.checkQueueIsEmpty(); |
841 } | 849 } |
842 if (!REPORT_EXCESS_RESOLUTION) return; | 850 if (!REPORT_EXCESS_RESOLUTION) return; |
843 var resolved = new Set.from(enqueuer.resolution.processedEntities); | 851 var resolved = new Set.from(resolutionEnqueuer.processedEntities); |
844 for (Element e in enqueuer.codegen.processedEntities) { | 852 for (Element e in codegenEnqueuer.processedEntities) { |
845 resolved.remove(e); | 853 resolved.remove(e); |
846 } | 854 } |
847 for (Element e in new Set.from(resolved)) { | 855 for (Element e in new Set.from(resolved)) { |
848 if (e.isClass || | 856 if (e.isClass || |
849 e.isField || | 857 e.isField || |
850 e.isTypeVariable || | 858 e.isTypeVariable || |
851 e.isTypedef || | 859 e.isTypedef || |
852 identical(e.kind, ElementKind.ABSTRACT_FIELD)) { | 860 identical(e.kind, ElementKind.ABSTRACT_FIELD)) { |
853 resolved.remove(e); | 861 resolved.remove(e); |
854 } | 862 } |
855 if (identical(e.kind, ElementKind.GENERATIVE_CONSTRUCTOR)) { | 863 if (identical(e.kind, ElementKind.GENERATIVE_CONSTRUCTOR)) { |
856 resolved.remove(e); | 864 resolved.remove(e); |
857 } | 865 } |
858 if (backend.isTargetSpecificLibrary(e.library)) { | 866 if (backend.isTargetSpecificLibrary(e.library)) { |
859 resolved.remove(e); | 867 resolved.remove(e); |
860 } | 868 } |
861 } | 869 } |
862 reporter.log('Excess resolution work: ${resolved.length}.'); | 870 reporter.log('Excess resolution work: ${resolved.length}.'); |
863 for (Element e in resolved) { | 871 for (Element e in resolved) { |
864 reporter.reportWarningMessage(e, MessageKind.GENERIC, | 872 reporter.reportWarningMessage(e, MessageKind.GENERIC, |
865 {'text': 'Warning: $e resolved but not compiled.'}); | 873 {'text': 'Warning: $e resolved but not compiled.'}); |
866 } | 874 } |
867 } | 875 } |
868 | 876 |
869 void showResolutionProgress() { | 877 void showResolutionProgress(Enqueuer enqueuer) { |
870 if (shouldPrintProgress) { | 878 if (shouldPrintProgress) { |
871 // TODO(ahe): Add structured diagnostics to the compiler API and | 879 // TODO(ahe): Add structured diagnostics to the compiler API and |
872 // use it to separate this from the --verbose option. | 880 // use it to separate this from the --verbose option. |
873 assert(phase == PHASE_RESOLVING); | 881 assert(phase == PHASE_RESOLVING); |
874 reporter.log('Resolved ${enqueuer.resolution.processedEntities.length} ' | 882 reporter.log('Resolved ${enqueuer.processedEntities.length} ' |
875 'elements.'); | 883 'elements.'); |
876 progress.reset(); | 884 progress.reset(); |
877 } | 885 } |
878 } | 886 } |
879 | 887 |
880 void showCodegenProgress() { | 888 void showCodegenProgress(Enqueuer enqueuer) { |
881 if (shouldPrintProgress) { | 889 if (shouldPrintProgress) { |
882 // TODO(ahe): Add structured diagnostics to the compiler API and | 890 // TODO(ahe): Add structured diagnostics to the compiler API and |
883 // use it to separate this from the --verbose option. | 891 // use it to separate this from the --verbose option. |
884 reporter.log( | 892 reporter.log('Compiled ${enqueuer.processedEntities.length} methods.'); |
885 'Compiled ${enqueuer.codegen.processedEntities.length} methods.'); | |
886 progress.reset(); | 893 progress.reset(); |
887 } | 894 } |
888 } | 895 } |
889 | 896 |
890 void reportDiagnostic(DiagnosticMessage message, | 897 void reportDiagnostic(DiagnosticMessage message, |
891 List<DiagnosticMessage> infos, api.Diagnostic kind); | 898 List<DiagnosticMessage> infos, api.Diagnostic kind); |
892 | 899 |
893 void reportCrashInUserCode(String message, exception, stackTrace) { | 900 void reportCrashInUserCode(String message, exception, stackTrace) { |
894 reporter.onCrashInUserCode(message, exception, stackTrace); | 901 reporter.onCrashInUserCode(message, exception, stackTrace); |
895 } | 902 } |
(...skipping 923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1819 } | 1826 } |
1820 return transformResolutionImpact(element, resolutionImpact); | 1827 return transformResolutionImpact(element, resolutionImpact); |
1821 }); | 1828 }); |
1822 }); | 1829 }); |
1823 } | 1830 } |
1824 | 1831 |
1825 @override | 1832 @override |
1826 WorldImpact transformResolutionImpact( | 1833 WorldImpact transformResolutionImpact( |
1827 Element element, ResolutionImpact resolutionImpact) { | 1834 Element element, ResolutionImpact resolutionImpact) { |
1828 WorldImpact worldImpact = _compiler.backend.impactTransformer | 1835 WorldImpact worldImpact = _compiler.backend.impactTransformer |
1829 .transformResolutionImpact( | 1836 .transformResolutionImpact(enqueuer, resolutionImpact); |
1830 _compiler.enqueuer.resolution, resolutionImpact); | |
1831 _worldImpactCache[element] = worldImpact; | 1837 _worldImpactCache[element] = worldImpact; |
1832 return worldImpact; | 1838 return worldImpact; |
1833 } | 1839 } |
1834 | 1840 |
1835 @override | 1841 @override |
1836 void uncacheWorldImpact(Element element) { | 1842 void uncacheWorldImpact(Element element) { |
1837 assert(invariant(element, element.isDeclaration, | 1843 assert(invariant(element, element.isDeclaration, |
1838 message: "Element $element must be the declaration.")); | 1844 message: "Element $element must be the declaration.")); |
1839 if (retainCachesForTesting) return; | 1845 if (retainCachesForTesting) return; |
1840 if (_compiler.serialization.isDeserialized(element)) return; | 1846 if (_compiler.serialization.isDeserialized(element)) return; |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2037 if (library != null && library.isSynthesized) { | 2043 if (library != null && library.isSynthesized) { |
2038 return null; | 2044 return null; |
2039 } | 2045 } |
2040 if (library == null && required) { | 2046 if (library == null && required) { |
2041 throw new SpannableAssertionFailure( | 2047 throw new SpannableAssertionFailure( |
2042 library, "The library '${uri}' was not found."); | 2048 library, "The library '${uri}' was not found."); |
2043 } | 2049 } |
2044 return library; | 2050 return library; |
2045 } | 2051 } |
2046 } | 2052 } |
OLD | NEW |