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