Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/deferred_load.dart

Issue 221663005: Load deferred chunks in the right order. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 deferred_load; 5 library deferred_load;
6 6
7 import 'dart2jslib.dart' show 7 import 'dart2jslib.dart' show
8 Compiler, 8 Compiler,
9 CompilerTask, 9 CompilerTask,
10 Constant, 10 Constant,
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 /// The OutputUnit that will be loaded when the program starts. 112 /// The OutputUnit that will be loaded when the program starts.
113 final OutputUnit mainOutputUnit = new OutputUnit(); 113 final OutputUnit mainOutputUnit = new OutputUnit();
114 114
115 /// A set containing (eventually) all output units that will result from the 115 /// A set containing (eventually) all output units that will result from the
116 /// program. 116 /// program.
117 final Set<OutputUnit> allOutputUnits = new Set<OutputUnit>(); 117 final Set<OutputUnit> allOutputUnits = new Set<OutputUnit>();
118 118
119 /// Will be `true` if the program contains deferred libraries. 119 /// Will be `true` if the program contains deferred libraries.
120 bool splitProgram = false; 120 bool splitProgram = false;
121 121
122 /// A mapping from the name of a [DeferredLibrary] annotation to all dependent 122 /// A mapping from the name of a defer import to all the output units it
123 /// output units. 123 /// depends on in a list of lists to be loaded in the order they appear.
124 final Map<String, Set<OutputUnit>> hunksToLoad = 124 ///
125 new Map<String, Set<OutputUnit>>(); 125 /// For example {"lib1": [[lib1_lib2_lib3], [lib1_lib2, lib1_lib3],
126 /// [lib1]]} would mean that in order to load "lib1" first the hunk
127 /// lib1_lib2_lib2 should be loaded, then the hunks lib1_lib2 and lib1_lib3
128 /// can be loaded in parallel. And finally lib1 can be loaded.
129 final Map<String, List<List<OutputUnit>>> hunksToLoad =
130 new Map<String, List<List<OutputUnit>>>();
126 final Map<Import, String> importDeferName = new Map<Import, String>(); 131 final Map<Import, String> importDeferName = new Map<Import, String>();
127 132
128 /// A mapping from elements and constants to their output unit. Query this via 133 /// A mapping from elements and constants to their output unit. Query this via
129 /// [outputUnitForElement] 134 /// [outputUnitForElement]
130 final Map<Element, OutputUnit> _elementToOutputUnit = 135 final Map<Element, OutputUnit> _elementToOutputUnit =
131 new Map<Element, OutputUnit>(); 136 new Map<Element, OutputUnit>();
132 137
133 /// A mapping from constants to their output unit. Query this via 138 /// A mapping from constants to their output unit. Query this via
134 /// [outputUnitForConstant] 139 /// [outputUnitForConstant]
135 final Map<Constant, OutputUnit> _constantToOutputUnit = 140 final Map<Constant, OutputUnit> _constantToOutputUnit =
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 mirrorTask.analyzer.collectMirrorsUsedAnnotation(); 444 mirrorTask.analyzer.collectMirrorsUsedAnnotation();
440 445
441 // If there is a MirrorsUsed annotation we add only the needed 446 // If there is a MirrorsUsed annotation we add only the needed
442 // things to the output units for the library. 447 // things to the output units for the library.
443 List<MirrorUsage> mirrorUsages = mirrorsResult[library]; 448 List<MirrorUsage> mirrorUsages = mirrorsResult[library];
444 if (mirrorUsages == null) continue; 449 if (mirrorUsages == null) continue;
445 450
446 void mapDependenciesIfResolved(Element element) { 451 void mapDependenciesIfResolved(Element element) {
447 // If there is a target for this class, but no use of mirrors the 452 // If there is a target for this class, but no use of mirrors the
448 // class will not be resolved. We just skip it. 453 // class will not be resolved. We just skip it.
449 if (element is ClassElement && 454 if (element is ClassElement &&!element.isResolved) {
450 !(element as ClassElement).isResolved) {
451 return; 455 return;
452 } 456 }
453 _mapDependencies(element, deferredImport); 457 _mapDependencies(element, deferredImport);
454 } 458 }
455 459
456 for (MirrorUsage usage in mirrorUsages) { 460 for (MirrorUsage usage in mirrorUsages) {
457 if (usage.targets != null) { 461 if (usage.targets != null) {
458 for (Element dependency in usage.targets) { 462 for (Element dependency in usage.targets) {
459 if (dependency.isLibrary()) { 463 if (dependency.isLibrary()) {
460 LibraryElement library = dependency; 464 LibraryElement library = dependency;
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 generatedNames[outputUnit] = outputUnit.name; 625 generatedNames[outputUnit] = outputUnit.name;
622 } 626 }
623 627
624 for (Import import in _allDeferredImports.keys) { 628 for (Import import in _allDeferredImports.keys) {
625 computeImportDeferName(import); 629 computeImportDeferName(import);
626 } 630 }
627 631
628 for (OutputUnit outputUnit in allOutputUnits) { 632 for (OutputUnit outputUnit in allOutputUnits) {
629 computeOutputUnitName(outputUnit); 633 computeOutputUnitName(outputUnit);
630 } 634 }
635 List sortedOutputUnits = new List.from(allOutputUnits);
636 // Sort the output units in descending order of the number of imports they
637 // include.
638
639 // The loading of the output units mut be ordered because a superclass needs
640 // to be initialized before its subclass.
641 // But a class can only depend on another class in an output unit shared by
642 // a strict superset of the imports:
643 // By contradiction: Assume a class C in output unit shared by imports in
644 // the set S1 = (lib1,.., lib_n) depends on a class D in an output unit
645 // shared by S2 such that S2 not a superset of S1. Let lib_s be a library in
646 // S1 not in S2. lib_s must depend on C, and then in turn on D therefore D
647 // is not in the right output unit.
648 sortedOutputUnits.sort((a, b) => b.imports.length - a.imports.length);
631 649
632 // For each deferred import we find out which outputUnits to load. 650 // For each deferred import we find out which outputUnits to load.
633 for (Import import in _allDeferredImports.keys) { 651 for (Import import in _allDeferredImports.keys) {
634 if (import == _fakeMainImport) continue; 652 if (import == _fakeMainImport) continue;
635 hunksToLoad[importDeferName[import]] = new Set<OutputUnit>(); 653 hunksToLoad[importDeferName[import]] = new List<List<OutputUnit>>();
636 for (OutputUnit outputUnit in allOutputUnits) { 654 int lastNumberOfImports = 0;
655 List<OutputUnit> currentLastList;
656 for (OutputUnit outputUnit in sortedOutputUnits) {
637 if (outputUnit == mainOutputUnit) continue; 657 if (outputUnit == mainOutputUnit) continue;
638 if (outputUnit.imports.contains(import)) { 658 if (outputUnit.imports.contains(import)) {
639 hunksToLoad[importDeferName[import]].add(outputUnit); 659 if (outputUnit.imports.length != lastNumberOfImports) {
660 lastNumberOfImports = outputUnit.imports.length;
661 currentLastList = new List<OutputUnit>();
662 hunksToLoad[importDeferName[import]].add(currentLastList);
663 }
664 currentLastList.add(outputUnit);
640 } 665 }
641 } 666 }
642 } 667 }
643 } 668 }
644 669
645 void onResolutionComplete(FunctionElement main) { 670 void onResolutionComplete(FunctionElement main) {
646 if (!splitProgram) { 671 if (!splitProgram) {
647 allOutputUnits.add(mainOutputUnit); 672 allOutputUnits.add(mainOutputUnit);
648 return; 673 return;
649 } 674 }
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 } 793 }
769 if (splitProgram && compiler.backend is DartBackend) { 794 if (splitProgram && compiler.backend is DartBackend) {
770 // TODO(sigurdm): Implement deferred loading for dart2dart. 795 // TODO(sigurdm): Implement deferred loading for dart2dart.
771 splitProgram = false; 796 splitProgram = false;
772 compiler.reportInfo( 797 compiler.reportInfo(
773 lastDeferred, 798 lastDeferred,
774 MessageKind.DEFERRED_LIBRARY_DART_2_DART); 799 MessageKind.DEFERRED_LIBRARY_DART_2_DART);
775 } 800 }
776 } 801 }
777 } 802 }
OLDNEW
« no previous file with comments | « runtime/lib/deferred_load_patch.dart ('k') | sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698