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 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 backend = jsBackend; | 249 backend = jsBackend; |
250 } | 250 } |
251 enqueuer = backend.makeEnqueuer(); | 251 enqueuer = backend.makeEnqueuer(); |
252 | 252 |
253 if (options.dumpInfo && options.useStartupEmitter) { | 253 if (options.dumpInfo && options.useStartupEmitter) { |
254 throw new ArgumentError( | 254 throw new ArgumentError( |
255 '--dump-info is not supported with the fast startup emitter'); | 255 '--dump-info is not supported with the fast startup emitter'); |
256 } | 256 } |
257 | 257 |
258 tasks = [ | 258 tasks = [ |
259 dietParser = | 259 dietParser = new DietParserTask(idGenerator, backend, reporter, measurer), |
260 new DietParserTask(idGenerator, backend, reporter, measurer), | |
261 scanner = createScannerTask(), | 260 scanner = createScannerTask(), |
262 serialization = new SerializationTask(this), | 261 serialization = new SerializationTask(this), |
263 libraryLoader = new LibraryLoaderTask( | 262 libraryLoader = new LibraryLoaderTask( |
264 resolvedUriTranslator, | 263 resolvedUriTranslator, |
265 options.compileOnly | 264 options.compileOnly |
266 ? new _NoScriptLoader(this) | 265 ? new _NoScriptLoader(this) |
267 : new _ScriptLoader(this), | 266 : new _ScriptLoader(this), |
268 new _ElementScanner(scanner), | 267 new _ElementScanner(scanner), |
269 serialization, | 268 serialization, |
270 this, | 269 this, |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 } | 545 } |
547 return libraryLoader.loadLibrary(uri).then((LibraryElement library) { | 546 return libraryLoader.loadLibrary(uri).then((LibraryElement library) { |
548 mainApp = library; | 547 mainApp = library; |
549 }); | 548 }); |
550 } | 549 } |
551 }).then((_) { | 550 }).then((_) { |
552 compileLoadedLibraries(); | 551 compileLoadedLibraries(); |
553 }); | 552 }); |
554 } | 553 } |
555 | 554 |
556 void computeMain() { | 555 WorldImpact computeMain() { |
557 if (mainApp == null) return; | 556 if (mainApp == null) return const WorldImpact(); |
558 | 557 |
| 558 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); |
559 Element main = mainApp.findExported(Identifiers.main); | 559 Element main = mainApp.findExported(Identifiers.main); |
560 ErroneousElement errorElement = null; | 560 ErroneousElement errorElement = null; |
561 if (main == null) { | 561 if (main == null) { |
562 if (options.analyzeOnly) { | 562 if (options.analyzeOnly) { |
563 if (!analyzeAll) { | 563 if (!analyzeAll) { |
564 errorElement = new ErroneousElementX(MessageKind.CONSIDER_ANALYZE_ALL, | 564 errorElement = new ErroneousElementX(MessageKind.CONSIDER_ANALYZE_ALL, |
565 {'main': Identifiers.main}, Identifiers.main, mainApp); | 565 {'main': Identifiers.main}, Identifiers.main, mainApp); |
566 } | 566 } |
567 } else { | 567 } else { |
568 // Compilation requires a main method. | 568 // Compilation requires a main method. |
(...skipping 20 matching lines...) Expand all Loading... |
589 int index = 0; | 589 int index = 0; |
590 parameters.orderedForEachParameter((Element parameter) { | 590 parameters.orderedForEachParameter((Element parameter) { |
591 if (index++ < 2) return; | 591 if (index++ < 2) return; |
592 errorElement = new ErroneousElementX( | 592 errorElement = new ErroneousElementX( |
593 MessageKind.MAIN_WITH_EXTRA_PARAMETER, | 593 MessageKind.MAIN_WITH_EXTRA_PARAMETER, |
594 {'main': Identifiers.main}, | 594 {'main': Identifiers.main}, |
595 Identifiers.main, | 595 Identifiers.main, |
596 parameter); | 596 parameter); |
597 mainFunction = backend.helperForMainArity(); | 597 mainFunction = backend.helperForMainArity(); |
598 // Don't warn about main not being used: | 598 // Don't warn about main not being used: |
599 enqueuer.resolution.registerStaticUse(new StaticUse.foreignUse(main)); | 599 impactBuilder.registerStaticUse(new StaticUse.foreignUse(main)); |
600 }); | 600 }); |
601 } | 601 } |
602 } | 602 } |
603 if (mainFunction == null) { | 603 if (mainFunction == null) { |
604 if (errorElement == null && !options.analyzeOnly && !analyzeAll) { | 604 if (errorElement == null && !options.analyzeOnly && !analyzeAll) { |
605 reporter.internalError(mainApp, "Problem with '${Identifiers.main}'."); | 605 reporter.internalError(mainApp, "Problem with '${Identifiers.main}'."); |
606 } else { | 606 } else { |
607 mainFunction = errorElement; | 607 mainFunction = errorElement; |
608 } | 608 } |
609 } | 609 } |
610 if (errorElement != null && | 610 if (errorElement != null && |
611 errorElement.isSynthesized && | 611 errorElement.isSynthesized && |
612 !mainApp.isSynthesized) { | 612 !mainApp.isSynthesized) { |
613 reporter.reportWarningMessage(errorElement, errorElement.messageKind, | 613 reporter.reportWarningMessage(errorElement, errorElement.messageKind, |
614 errorElement.messageArguments); | 614 errorElement.messageArguments); |
615 } | 615 } |
| 616 return impactBuilder; |
616 } | 617 } |
617 | 618 |
618 /// Analyze all members of the library in [libraryUri]. | 619 /// Analyze all members of the library in [libraryUri]. |
619 /// | 620 /// |
620 /// If [skipLibraryWithPartOfTag] is `true`, member analysis is skipped if the | 621 /// If [skipLibraryWithPartOfTag] is `true`, member analysis is skipped if the |
621 /// library has a `part of` tag, assuming it is a part and not a library. | 622 /// library has a `part of` tag, assuming it is a part and not a library. |
622 /// | 623 /// |
623 /// This operation assumes an unclosed resolution queue and is only supported | 624 /// This operation assumes an unclosed resolution queue and is only supported |
624 /// when the '--analyze-main' option is used. | 625 /// when the '--analyze-main' option is used. |
625 Future<LibraryElement> analyzeUri(Uri libraryUri, | 626 Future<LibraryElement> analyzeUri(Uri libraryUri, |
626 {bool skipLibraryWithPartOfTag: true}) { | 627 {bool skipLibraryWithPartOfTag: true}) { |
627 assert(options.analyzeMain); | 628 assert(options.analyzeMain); |
628 reporter.log('Analyzing $libraryUri (${options.buildId})'); | 629 reporter.log('Analyzing $libraryUri (${options.buildId})'); |
629 return libraryLoader | 630 return libraryLoader |
630 .loadLibrary(libraryUri, skipFileWithPartOfTag: true) | 631 .loadLibrary(libraryUri, skipFileWithPartOfTag: true) |
631 .then((LibraryElement library) { | 632 .then((LibraryElement library) { |
632 if (library == null) return null; | 633 if (library == null) return null; |
633 fullyEnqueueLibrary(library, enqueuer.resolution); | 634 fullyEnqueueLibrary(library, enqueuer.resolution); |
634 emptyQueue(enqueuer.resolution); | 635 emptyQueue(enqueuer.resolution); |
635 enqueuer.resolution.logSummary(reporter.log); | 636 enqueuer.resolution.logSummary(reporter.log); |
636 return library; | 637 return library; |
637 }); | 638 }); |
638 } | 639 } |
639 | 640 |
640 /// Performs the compilation when all libraries have been loaded. | 641 /// Performs the compilation when all libraries have been loaded. |
641 void compileLoadedLibraries() => | 642 void compileLoadedLibraries() => |
642 selfTask.measureSubtask("Compiler.compileLoadedLibraries", () { | 643 selfTask.measureSubtask("Compiler.compileLoadedLibraries", () { |
643 computeMain(); | 644 WorldImpact mainImpact = computeMain(); |
644 | 645 |
645 mirrorUsageAnalyzerTask.analyzeUsage(mainApp); | 646 mirrorUsageAnalyzerTask.analyzeUsage(mainApp); |
646 | 647 |
647 // In order to see if a library is deferred, we must compute the | 648 // In order to see if a library is deferred, we must compute the |
648 // compile-time constants that are metadata. This means adding | 649 // compile-time constants that are metadata. This means adding |
649 // something to the resolution queue. So we cannot wait with | 650 // something to the resolution queue. So we cannot wait with |
650 // this until after the resolution queue is processed. | 651 // this until after the resolution queue is processed. |
651 deferredLoadTask.beforeResolution(this); | 652 deferredLoadTask.beforeResolution(this); |
652 ImpactStrategy impactStrategy = backend.createImpactStrategy( | 653 impactStrategy = backend.createImpactStrategy( |
653 supportDeferredLoad: deferredLoadTask.isProgramSplit, | 654 supportDeferredLoad: deferredLoadTask.isProgramSplit, |
654 supportDumpInfo: options.dumpInfo, | 655 supportDumpInfo: options.dumpInfo, |
655 supportSerialization: serialization.supportSerialization); | 656 supportSerialization: serialization.supportSerialization); |
656 | 657 |
657 phase = PHASE_RESOLVING; | 658 phase = PHASE_RESOLVING; |
| 659 enqueuer.resolution.applyImpact(mainImpact); |
658 if (options.resolveOnly) { | 660 if (options.resolveOnly) { |
659 libraryLoader.libraries.where((LibraryElement library) { | 661 libraryLoader.libraries.where((LibraryElement library) { |
660 return !serialization.isDeserialized(library); | 662 return !serialization.isDeserialized(library); |
661 }).forEach((LibraryElement library) { | 663 }).forEach((LibraryElement library) { |
662 reporter.log('Enqueuing ${library.canonicalUri}'); | 664 reporter.log('Enqueuing ${library.canonicalUri}'); |
663 fullyEnqueueLibrary(library, enqueuer.resolution); | 665 fullyEnqueueLibrary(library, enqueuer.resolution); |
664 }); | 666 }); |
665 } else if (analyzeAll) { | 667 } else if (analyzeAll) { |
666 libraryLoader.libraries.forEach((LibraryElement library) { | 668 libraryLoader.libraries.forEach((LibraryElement library) { |
667 reporter.log('Enqueuing ${library.canonicalUri}'); | 669 reporter.log('Enqueuing ${library.canonicalUri}'); |
668 fullyEnqueueLibrary(library, enqueuer.resolution); | 670 fullyEnqueueLibrary(library, enqueuer.resolution); |
669 }); | 671 }); |
670 } else if (options.analyzeMain) { | 672 } else if (options.analyzeMain) { |
671 if (mainApp != null) { | 673 if (mainApp != null) { |
672 fullyEnqueueLibrary(mainApp, enqueuer.resolution); | 674 fullyEnqueueLibrary(mainApp, enqueuer.resolution); |
673 } | 675 } |
674 if (librariesToAnalyzeWhenRun != null) { | 676 if (librariesToAnalyzeWhenRun != null) { |
675 for (Uri libraryUri in librariesToAnalyzeWhenRun) { | 677 for (Uri libraryUri in librariesToAnalyzeWhenRun) { |
676 fullyEnqueueLibrary( | 678 fullyEnqueueLibrary( |
677 libraryLoader.lookupLibrary(libraryUri), enqueuer.resolution); | 679 libraryLoader.lookupLibrary(libraryUri), enqueuer.resolution); |
678 } | 680 } |
679 } | 681 } |
680 } | 682 } |
| 683 if (deferredLoadTask.isProgramSplit) { |
| 684 enqueuer.resolution |
| 685 .applyImpact(backend.computeDeferredLoadingImpact()); |
| 686 } |
681 // Elements required by enqueueHelpers are global dependencies | 687 // Elements required by enqueueHelpers are global dependencies |
682 // that are not pulled in by a particular element. | 688 // that are not pulled in by a particular element. |
683 backend.enqueueHelpers(enqueuer.resolution); | 689 enqueuer.resolution.applyImpact(backend.computeHelpersImpact()); |
684 resolveLibraryMetadata(); | 690 resolveLibraryMetadata(); |
685 reporter.log('Resolving...'); | 691 reporter.log('Resolving...'); |
686 if (mainFunction != null && !mainFunction.isMalformed) { | 692 if (mainFunction != null && !mainFunction.isMalformed) { |
687 mainFunction.computeType(resolution); | 693 mainFunction.computeType(resolution); |
688 } | 694 } |
689 | 695 |
690 processQueue(enqueuer.resolution, mainFunction); | 696 processQueue(enqueuer.resolution, mainFunction); |
691 enqueuer.resolution.logSummary(reporter.log); | 697 enqueuer.resolution.logSummary(reporter.log); |
692 | 698 |
693 _reporter.reportSuppressedMessagesSummary(); | 699 _reporter.reportSuppressedMessagesSummary(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 globalInference.runGlobalTypeInference(mainFunction); | 734 globalInference.runGlobalTypeInference(mainFunction); |
729 | 735 |
730 if (stopAfterTypeInference) return; | 736 if (stopAfterTypeInference) return; |
731 | 737 |
732 backend.onTypeInferenceComplete(); | 738 backend.onTypeInferenceComplete(); |
733 | 739 |
734 reporter.log('Compiling...'); | 740 reporter.log('Compiling...'); |
735 phase = PHASE_COMPILING; | 741 phase = PHASE_COMPILING; |
736 backend.onCodegenStart(); | 742 backend.onCodegenStart(); |
737 if (hasIsolateSupport) { | 743 if (hasIsolateSupport) { |
738 backend.enableIsolateSupport(enqueuer.codegen); | 744 enqueuer.codegen |
| 745 .applyImpact(backend.enableIsolateSupport(forResolution: false)); |
739 } | 746 } |
740 if (compileAll) { | 747 if (compileAll) { |
741 libraryLoader.libraries.forEach((LibraryElement library) { | 748 libraryLoader.libraries.forEach((LibraryElement library) { |
742 fullyEnqueueLibrary(library, enqueuer.codegen); | 749 fullyEnqueueLibrary(library, enqueuer.codegen); |
743 }); | 750 }); |
744 } | 751 } |
745 processQueue(enqueuer.codegen, mainFunction); | 752 processQueue(enqueuer.codegen, mainFunction); |
746 enqueuer.codegen.logSummary(reporter.log); | 753 enqueuer.codegen.logSummary(reporter.log); |
747 | 754 |
748 int programSize = backend.assembleProgram(); | 755 int programSize = backend.assembleProgram(); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 /** | 842 /** |
836 * Empty the [enqueuer] queue. | 843 * Empty the [enqueuer] queue. |
837 */ | 844 */ |
838 void emptyQueue(Enqueuer enqueuer) { | 845 void emptyQueue(Enqueuer enqueuer) { |
839 selfTask.measureSubtask("Compiler.emptyQueue", () { | 846 selfTask.measureSubtask("Compiler.emptyQueue", () { |
840 enqueuer.forEach((WorkItem work) { | 847 enqueuer.forEach((WorkItem work) { |
841 reporter.withCurrentElement( | 848 reporter.withCurrentElement( |
842 work.element, | 849 work.element, |
843 () => selfTask.measureSubtask("world.applyImpact", () { | 850 () => selfTask.measureSubtask("world.applyImpact", () { |
844 enqueuer.applyImpact( | 851 enqueuer.applyImpact( |
845 impactStrategy, | |
846 selfTask.measureSubtask( | 852 selfTask.measureSubtask( |
847 "work.run", () => work.run(this, enqueuer)), | 853 "work.run", () => work.run(this, enqueuer)), |
848 impactSource: work.element); | 854 impactSource: work.element); |
849 })); | 855 })); |
850 }); | 856 }); |
851 }); | 857 }); |
852 } | 858 } |
853 | 859 |
854 void processQueue(Enqueuer enqueuer, MethodElement mainMethod) { | 860 void processQueue(Enqueuer enqueuer, MethodElement mainMethod) { |
855 selfTask.measureSubtask("Compiler.processQueue", () { | 861 selfTask.measureSubtask("Compiler.processQueue", () { |
856 enqueuer.applyImpact( | 862 enqueuer.open(impactStrategy); |
857 impactStrategy, | 863 enqueuer.applyImpact(enqueuer.nativeEnqueuer |
858 enqueuer.nativeEnqueuer | 864 .processNativeClasses(libraryLoader.libraries)); |
859 .processNativeClasses(libraryLoader.libraries)); | |
860 if (mainMethod != null && !mainMethod.isMalformed) { | 865 if (mainMethod != null && !mainMethod.isMalformed) { |
861 enqueuer.applyImpact( | 866 enqueuer.applyImpact(backend.computeMainImpact(mainMethod, |
862 impactStrategy, backend.computeMainImpact(enqueuer, mainMethod)); | 867 forResolution: enqueuer.isResolutionQueue)); |
863 } | 868 } |
864 if (options.verbose) { | 869 if (options.verbose) { |
865 progress.reset(); | 870 progress.reset(); |
866 } | 871 } |
867 emptyQueue(enqueuer); | 872 emptyQueue(enqueuer); |
868 enqueuer.queueIsClosed = true; | 873 enqueuer.queueIsClosed = true; |
| 874 enqueuer.close(); |
869 // Notify the impact strategy impacts are no longer needed for this | 875 // Notify the impact strategy impacts are no longer needed for this |
870 // enqueuer. | 876 // enqueuer. |
871 impactStrategy.onImpactUsed(enqueuer.impactUse); | 877 impactStrategy.onImpactUsed(enqueuer.impactUse); |
872 backend.onQueueClosed(); | 878 backend.onQueueClosed(); |
873 assert(compilationFailed || | 879 assert(compilationFailed || |
874 enqueuer.checkNoEnqueuedInvokedInstanceMethods()); | 880 enqueuer.checkNoEnqueuedInvokedInstanceMethods()); |
875 }); | 881 }); |
876 } | 882 } |
877 | 883 |
878 /** | 884 /** |
(...skipping 1369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2248 _ElementScanner(this.scanner); | 2254 _ElementScanner(this.scanner); |
2249 void scanLibrary(LibraryElement library) => scanner.scanLibrary(library); | 2255 void scanLibrary(LibraryElement library) => scanner.scanLibrary(library); |
2250 void scanUnit(CompilationUnitElement unit) => scanner.scan(unit); | 2256 void scanUnit(CompilationUnitElement unit) => scanner.scan(unit); |
2251 } | 2257 } |
2252 | 2258 |
2253 class _EmptyEnvironment implements Environment { | 2259 class _EmptyEnvironment implements Environment { |
2254 const _EmptyEnvironment(); | 2260 const _EmptyEnvironment(); |
2255 | 2261 |
2256 String valueOf(String key) => null; | 2262 String valueOf(String key) => null; |
2257 } | 2263 } |
OLD | NEW |