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 'cache_strategy.dart' show CacheStrategy; | 10 import 'cache_strategy.dart' show CacheStrategy; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 import 'tokens/token_map.dart' show TokenMap; | 69 import 'tokens/token_map.dart' show TokenMap; |
70 import 'tracer.dart' show Tracer; | 70 import 'tracer.dart' show Tracer; |
71 import 'tree/tree.dart' show Node, TypeAnnotation; | 71 import 'tree/tree.dart' show Node, TypeAnnotation; |
72 import 'typechecker.dart' show TypeCheckerTask; | 72 import 'typechecker.dart' show TypeCheckerTask; |
73 import 'types/types.dart' show GlobalTypeInferenceTask; | 73 import 'types/types.dart' show GlobalTypeInferenceTask; |
74 import 'types/masks.dart' show CommonMasks; | 74 import 'types/masks.dart' show CommonMasks; |
75 import 'universe/selector.dart' show Selector; | 75 import 'universe/selector.dart' show Selector; |
76 import 'universe/world_builder.dart' | 76 import 'universe/world_builder.dart' |
77 show ResolutionWorldBuilder, CodegenWorldBuilder; | 77 show ResolutionWorldBuilder, CodegenWorldBuilder; |
78 import 'universe/use.dart' show StaticUse; | 78 import 'universe/use.dart' show StaticUse; |
79 import 'universe/world_impact.dart' show ImpactStrategy, WorldImpact; | 79 import 'universe/world_impact.dart' |
| 80 show ImpactStrategy, WorldImpact, WorldImpactBuilderImpl; |
80 import 'util/util.dart' show Link, Setlet; | 81 import 'util/util.dart' show Link, Setlet; |
81 import 'world.dart' show ClosedWorld, ClosedWorldRefiner, OpenWorld, WorldImpl; | 82 import 'world.dart' show ClosedWorld, ClosedWorldRefiner, OpenWorld, WorldImpl; |
82 | 83 |
83 typedef Backend MakeBackendFuncion(Compiler compiler); | 84 typedef Backend MakeBackendFuncion(Compiler compiler); |
84 | 85 |
85 typedef CompilerDiagnosticReporter MakeReporterFunction( | 86 typedef CompilerDiagnosticReporter MakeReporterFunction( |
86 Compiler compiler, CompilerOptions options); | 87 Compiler compiler, CompilerOptions options); |
87 | 88 |
88 abstract class Compiler implements LibraryLoaderListener { | 89 abstract class Compiler implements LibraryLoaderListener { |
89 Measurer get measurer; | 90 Measurer get measurer; |
(...skipping 17 matching lines...) Expand all Loading... |
107 | 108 |
108 /** | 109 /** |
109 * Records global dependencies, that is, dependencies that don't | 110 * Records global dependencies, that is, dependencies that don't |
110 * correspond to a particular element. | 111 * correspond to a particular element. |
111 * | 112 * |
112 * We should get rid of this and ensure that all dependencies are | 113 * We should get rid of this and ensure that all dependencies are |
113 * associated with a particular element. | 114 * associated with a particular element. |
114 */ | 115 */ |
115 GlobalDependencyRegistry globalDependencies; | 116 GlobalDependencyRegistry globalDependencies; |
116 | 117 |
117 /** | |
118 * Dependencies that are only included due to mirrors. | |
119 * | |
120 * We should get rid of this and ensure that all dependencies are | |
121 * associated with a particular element. | |
122 */ | |
123 // TODO(johnniwinther): This should not be a [ResolutionRegistry]. | |
124 final Registry mirrorDependencies = | |
125 new ResolutionRegistry(null, new TreeElementMapping(null)); | |
126 | |
127 /// Options provided from command-line arguments. | 118 /// Options provided from command-line arguments. |
128 final CompilerOptions options; | 119 final CompilerOptions options; |
129 | 120 |
130 /** | 121 /** |
131 * If true, stop compilation after type inference is complete. Used for | 122 * If true, stop compilation after type inference is complete. Used for |
132 * debugging and testing purposes only. | 123 * debugging and testing purposes only. |
133 */ | 124 */ |
134 bool stopAfterTypeInference = false; | 125 bool stopAfterTypeInference = false; |
135 | 126 |
136 /// Output provider from user of Compiler API. | 127 /// Output provider from user of Compiler API. |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
680 } | 671 } |
681 if (librariesToAnalyzeWhenRun != null) { | 672 if (librariesToAnalyzeWhenRun != null) { |
682 for (Uri libraryUri in librariesToAnalyzeWhenRun) { | 673 for (Uri libraryUri in librariesToAnalyzeWhenRun) { |
683 fullyEnqueueLibrary( | 674 fullyEnqueueLibrary( |
684 libraryLoader.lookupLibrary(libraryUri), enqueuer.resolution); | 675 libraryLoader.lookupLibrary(libraryUri), enqueuer.resolution); |
685 } | 676 } |
686 } | 677 } |
687 } | 678 } |
688 // Elements required by enqueueHelpers are global dependencies | 679 // Elements required by enqueueHelpers are global dependencies |
689 // that are not pulled in by a particular element. | 680 // that are not pulled in by a particular element. |
690 backend.enqueueHelpers(enqueuer.resolution, globalDependencies); | 681 backend.enqueueHelpers(enqueuer.resolution); |
691 resolveLibraryMetadata(); | 682 resolveLibraryMetadata(); |
692 reporter.log('Resolving...'); | 683 reporter.log('Resolving...'); |
693 processQueue(enqueuer.resolution, mainFunction); | 684 processQueue(enqueuer.resolution, mainFunction); |
694 enqueuer.resolution.logSummary(reporter.log); | 685 enqueuer.resolution.logSummary(reporter.log); |
695 | 686 |
696 _reporter.reportSuppressedMessagesSummary(); | 687 _reporter.reportSuppressedMessagesSummary(); |
697 | 688 |
698 if (compilationFailed) { | 689 if (compilationFailed) { |
699 if (!options.generateCodeWithCompileTimeErrors) return; | 690 if (!options.generateCodeWithCompileTimeErrors) return; |
700 if (!backend | 691 if (!backend |
(...skipping 29 matching lines...) Expand all Loading... |
730 reporter.log('Inferring types...'); | 721 reporter.log('Inferring types...'); |
731 globalInference.runGlobalTypeInference(mainFunction); | 722 globalInference.runGlobalTypeInference(mainFunction); |
732 | 723 |
733 if (stopAfterTypeInference) return; | 724 if (stopAfterTypeInference) return; |
734 | 725 |
735 backend.onTypeInferenceComplete(); | 726 backend.onTypeInferenceComplete(); |
736 | 727 |
737 reporter.log('Compiling...'); | 728 reporter.log('Compiling...'); |
738 phase = PHASE_COMPILING; | 729 phase = PHASE_COMPILING; |
739 backend.onCodegenStart(); | 730 backend.onCodegenStart(); |
740 // TODO(johnniwinther): Move these to [CodegenEnqueuer]. | |
741 if (hasIsolateSupport) { | 731 if (hasIsolateSupport) { |
742 backend.enableIsolateSupport(enqueuer.codegen); | 732 backend.enableIsolateSupport(enqueuer.codegen); |
743 } | 733 } |
744 if (compileAll) { | 734 if (compileAll) { |
745 libraryLoader.libraries.forEach((LibraryElement library) { | 735 libraryLoader.libraries.forEach((LibraryElement library) { |
746 fullyEnqueueLibrary(library, enqueuer.codegen); | 736 fullyEnqueueLibrary(library, enqueuer.codegen); |
747 }); | 737 }); |
748 } | 738 } |
749 processQueue(enqueuer.codegen, mainFunction); | 739 processQueue(enqueuer.codegen, mainFunction); |
750 enqueuer.codegen.logSummary(reporter.log); | 740 enqueuer.codegen.logSummary(reporter.log); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 } | 800 } |
811 }); | 801 }); |
812 } | 802 } |
813 } | 803 } |
814 | 804 |
815 void fullyEnqueueTopLevelElement(Element element, Enqueuer world) { | 805 void fullyEnqueueTopLevelElement(Element element, Enqueuer world) { |
816 if (element.isClass) { | 806 if (element.isClass) { |
817 ClassElement cls = element; | 807 ClassElement cls = element; |
818 cls.ensureResolved(resolution); | 808 cls.ensureResolved(resolution); |
819 cls.forEachLocalMember(enqueuer.resolution.addToWorkList); | 809 cls.forEachLocalMember(enqueuer.resolution.addToWorkList); |
820 backend.registerInstantiatedType(cls.rawType, world, globalDependencies); | 810 world.registerInstantiatedType(cls.rawType); |
821 } else { | 811 } else { |
822 world.addToWorkList(element); | 812 world.addToWorkList(element); |
823 } | 813 } |
824 } | 814 } |
825 | 815 |
826 // Resolves metadata on library elements. This is necessary in order to | 816 // Resolves metadata on library elements. This is necessary in order to |
827 // resolve metadata classes referenced only from metadata on library tags. | 817 // resolve metadata classes referenced only from metadata on library tags. |
828 // TODO(ahe): Figure out how to do this lazily. | 818 // TODO(ahe): Figure out how to do this lazily. |
829 void resolveLibraryMetadata() { | 819 void resolveLibraryMetadata() { |
830 for (LibraryElement library in libraryLoader.libraries) { | 820 for (LibraryElement library in libraryLoader.libraries) { |
(...skipping 15 matching lines...) Expand all Loading... |
846 work.element, | 836 work.element, |
847 () => selfTask.measureSubtask("world.applyImpact", () { | 837 () => selfTask.measureSubtask("world.applyImpact", () { |
848 world.applyImpact( | 838 world.applyImpact( |
849 selfTask.measureSubtask( | 839 selfTask.measureSubtask( |
850 "work.run", () => work.run(this, world)), | 840 "work.run", () => work.run(this, world)), |
851 impactSource: work.element); | 841 impactSource: work.element); |
852 })); | 842 })); |
853 }); | 843 }); |
854 }); | 844 }); |
855 | 845 |
856 void processQueue(Enqueuer world, Element main) => | 846 void processQueue(Enqueuer enqueuer, Element main) { |
857 selfTask.measureSubtask("Compiler.processQueue", () { | 847 selfTask.measureSubtask("Compiler.processQueue", () { |
858 world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries); | 848 WorldImpactBuilderImpl nativeImpact = new WorldImpactBuilderImpl(); |
859 if (main != null && !main.isMalformed) { | 849 enqueuer.nativeEnqueuer |
860 FunctionElement mainMethod = main; | 850 .processNativeClasses(nativeImpact, libraryLoader.libraries); |
861 mainMethod.computeType(resolution); | 851 enqueuer.applyImpact(nativeImpact); |
862 if (mainMethod.functionSignature.parameterCount != 0) { | 852 if (main != null && !main.isMalformed) { |
863 // The first argument could be a list of strings. | 853 FunctionElement mainMethod = main; |
864 backend.backendClasses.listImplementation | 854 mainMethod.computeType(resolution); |
865 .ensureResolved(resolution); | 855 if (mainMethod.functionSignature.parameterCount != 0) { |
866 backend.registerInstantiatedType( | 856 // The first argument could be a list of strings. |
867 backend.backendClasses.listImplementation.rawType, | 857 backend.backendClasses.listImplementation.ensureResolved(resolution); |
868 world, | 858 enqueuer.registerInstantiatedType( |
869 globalDependencies); | 859 backend.backendClasses.listImplementation.rawType); |
870 backend.backendClasses.stringImplementation | 860 backend.backendClasses.stringImplementation |
871 .ensureResolved(resolution); | 861 .ensureResolved(resolution); |
872 backend.registerInstantiatedType( | 862 enqueuer.registerInstantiatedType( |
873 backend.backendClasses.stringImplementation.rawType, | 863 backend.backendClasses.stringImplementation.rawType); |
874 world, | |
875 globalDependencies); | |
876 | 864 |
877 backend.registerMainHasArguments(world); | 865 backend.registerMainHasArguments(enqueuer); |
878 } | |
879 world.addToWorkList(main); | |
880 } | 866 } |
881 if (options.verbose) { | 867 enqueuer.addToWorkList(main); |
882 progress.reset(); | 868 } |
883 } | 869 if (options.verbose) { |
884 emptyQueue(world); | 870 progress.reset(); |
885 world.queueIsClosed = true; | 871 } |
886 // Notify the impact strategy impacts are no longer needed for this | 872 emptyQueue(enqueuer); |
887 // enqueuer. | 873 enqueuer.queueIsClosed = true; |
888 impactStrategy.onImpactUsed(world.impactUse); | 874 // Notify the impact strategy impacts are no longer needed for this |
889 backend.onQueueClosed(); | 875 // enqueuer. |
890 assert( | 876 impactStrategy.onImpactUsed(enqueuer.impactUse); |
891 compilationFailed || world.checkNoEnqueuedInvokedInstanceMethods()); | 877 backend.onQueueClosed(); |
892 }); | 878 assert(compilationFailed || |
| 879 enqueuer.checkNoEnqueuedInvokedInstanceMethods()); |
| 880 }); |
| 881 } |
893 | 882 |
894 /** | 883 /** |
895 * Perform various checks of the queues. This includes checking that | 884 * Perform various checks of the queues. This includes checking that |
896 * the queues are empty (nothing was added after we stopped | 885 * the queues are empty (nothing was added after we stopped |
897 * processing the queues). Also compute the number of methods that | 886 * processing the queues). Also compute the number of methods that |
898 * were resolved, but not compiled (aka excess resolution). | 887 * were resolved, but not compiled (aka excess resolution). |
899 */ | 888 */ |
900 checkQueues() { | 889 checkQueues() { |
901 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) { | 890 for (Enqueuer world in [enqueuer.resolution, enqueuer.codegen]) { |
902 world.forEach((WorkItem work) { | 891 world.forEach((WorkItem work) { |
(...skipping 1240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2143 compiler.checker.check(element); | 2132 compiler.checker.check(element); |
2144 } | 2133 } |
2145 return transformResolutionImpact(element, resolutionImpact); | 2134 return transformResolutionImpact(element, resolutionImpact); |
2146 }); | 2135 }); |
2147 } | 2136 } |
2148 | 2137 |
2149 @override | 2138 @override |
2150 WorldImpact transformResolutionImpact( | 2139 WorldImpact transformResolutionImpact( |
2151 Element element, ResolutionImpact resolutionImpact) { | 2140 Element element, ResolutionImpact resolutionImpact) { |
2152 WorldImpact worldImpact = compiler.backend.impactTransformer | 2141 WorldImpact worldImpact = compiler.backend.impactTransformer |
2153 .transformResolutionImpact(resolutionImpact); | 2142 .transformResolutionImpact( |
| 2143 compiler.enqueuer.resolution, resolutionImpact); |
2154 _worldImpactCache[element] = worldImpact; | 2144 _worldImpactCache[element] = worldImpact; |
2155 return worldImpact; | 2145 return worldImpact; |
2156 } | 2146 } |
2157 | 2147 |
2158 @override | 2148 @override |
2159 void uncacheWorldImpact(Element element) { | 2149 void uncacheWorldImpact(Element element) { |
2160 assert(invariant(element, element.isDeclaration, | 2150 assert(invariant(element, element.isDeclaration, |
2161 message: "Element $element must be the declaration.")); | 2151 message: "Element $element must be the declaration.")); |
2162 if (retainCachesForTesting) return; | 2152 if (retainCachesForTesting) return; |
2163 if (compiler.serialization.isDeserialized(element)) return; | 2153 if (compiler.serialization.isDeserialized(element)) return; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2256 _ElementScanner(this.scanner); | 2246 _ElementScanner(this.scanner); |
2257 void scanLibrary(LibraryElement library) => scanner.scanLibrary(library); | 2247 void scanLibrary(LibraryElement library) => scanner.scanLibrary(library); |
2258 void scanUnit(CompilationUnitElement unit) => scanner.scan(unit); | 2248 void scanUnit(CompilationUnitElement unit) => scanner.scan(unit); |
2259 } | 2249 } |
2260 | 2250 |
2261 class _EmptyEnvironment implements Environment { | 2251 class _EmptyEnvironment implements Environment { |
2262 const _EmptyEnvironment(); | 2252 const _EmptyEnvironment(); |
2263 | 2253 |
2264 String valueOf(String key) => null; | 2254 String valueOf(String key) => null; |
2265 } | 2255 } |
OLD | NEW |