| 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 |