| OLD | NEW |
| 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 'common/backend_api.dart' show Backend; | 7 import 'common/backend_api.dart' show Backend; |
| 8 import 'common/tasks.dart' show CompilerTask; | 8 import 'common/tasks.dart' show CompilerTask; |
| 9 import 'common.dart'; | 9 import 'common.dart'; |
| 10 import 'compiler.dart' show Compiler; | 10 import 'compiler.dart' show Compiler; |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 /// | 215 /// |
| 216 /// For example, if we have two deferred libraries `A` and `B` that both | 216 /// For example, if we have two deferred libraries `A` and `B` that both |
| 217 /// import a library `C`, then even though elements from `A` and `C` end up in | 217 /// import a library `C`, then even though elements from `A` and `C` end up in |
| 218 /// different output units, there is a non-deferred path between `A` and `C`. | 218 /// different output units, there is a non-deferred path between `A` and `C`. |
| 219 bool hasOnlyNonDeferredImportPaths(Element from, Element to) { | 219 bool hasOnlyNonDeferredImportPaths(Element from, Element to) { |
| 220 OutputUnit outputUnitFrom = outputUnitForElement(from); | 220 OutputUnit outputUnitFrom = outputUnitForElement(from); |
| 221 OutputUnit outputUnitTo = outputUnitForElement(to); | 221 OutputUnit outputUnitTo = outputUnitForElement(to); |
| 222 return outputUnitTo.imports.containsAll(outputUnitFrom.imports); | 222 return outputUnitTo.imports.containsAll(outputUnitFrom.imports); |
| 223 } | 223 } |
| 224 | 224 |
| 225 // TODO(het): use a union-find to canonicalize output units |
| 226 OutputUnit _getCanonicalUnit(OutputUnit outputUnit) { |
| 227 OutputUnit representative = allOutputUnits.lookup(outputUnit); |
| 228 if (representative == null) { |
| 229 representative = outputUnit; |
| 230 allOutputUnits.add(representative); |
| 231 } |
| 232 return representative; |
| 233 } |
| 234 |
| 225 void registerConstantDeferredUse( | 235 void registerConstantDeferredUse( |
| 226 DeferredConstantValue constant, PrefixElement prefix) { | 236 DeferredConstantValue constant, PrefixElement prefix) { |
| 227 OutputUnit outputUnit = new OutputUnit(); | 237 OutputUnit outputUnit = new OutputUnit(); |
| 228 outputUnit.imports.add(new _DeclaredDeferredImport(prefix.deferredImport)); | 238 outputUnit.imports.add(new _DeclaredDeferredImport(prefix.deferredImport)); |
| 229 _constantToOutputUnit[constant] = outputUnit; | 239 |
| 240 // Check to see if there is already a canonical output unit registered. |
| 241 _constantToOutputUnit[constant] = _getCanonicalUnit(outputUnit); |
| 230 } | 242 } |
| 231 | 243 |
| 232 /// Answers whether [element] is explicitly deferred when referred to from | 244 /// Answers whether [element] is explicitly deferred when referred to from |
| 233 /// [library]. | 245 /// [library]. |
| 234 bool _isExplicitlyDeferred(Element element, LibraryElement library) { | 246 bool _isExplicitlyDeferred(Element element, LibraryElement library) { |
| 235 Iterable<ImportElement> imports = _getImports(element, library); | 247 Iterable<ImportElement> imports = _getImports(element, library); |
| 236 // If the element is not imported explicitly, it is implicitly imported | 248 // If the element is not imported explicitly, it is implicitly imported |
| 237 // not deferred. | 249 // not deferred. |
| 238 if (imports.isEmpty) return false; | 250 if (imports.isEmpty) return false; |
| 239 // An element could potentially be loaded by several imports. If all of them | 251 // An element could potentially be loaded by several imports. If all of them |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 if (compiler.commonElements.mirrorsLibrary != null) { | 684 if (compiler.commonElements.mirrorsLibrary != null) { |
| 673 _addMirrorElements(); | 685 _addMirrorElements(); |
| 674 } | 686 } |
| 675 | 687 |
| 676 // Build the OutputUnits using these two maps. | 688 // Build the OutputUnits using these two maps. |
| 677 Map<Element, OutputUnit> elementToOutputUnitBuilder = | 689 Map<Element, OutputUnit> elementToOutputUnitBuilder = |
| 678 new Map<Element, OutputUnit>(); | 690 new Map<Element, OutputUnit>(); |
| 679 Map<ConstantValue, OutputUnit> constantToOutputUnitBuilder = | 691 Map<ConstantValue, OutputUnit> constantToOutputUnitBuilder = |
| 680 new Map<ConstantValue, OutputUnit>(); | 692 new Map<ConstantValue, OutputUnit>(); |
| 681 | 693 |
| 694 // Add all constants that may have been registered during |
| 695 // resolution with [registerConstantDeferredUse]. |
| 696 constantToOutputUnitBuilder.addAll(_constantToOutputUnit); |
| 697 _constantToOutputUnit.clear(); |
| 698 |
| 682 // Reverse the mappings. For each element record an OutputUnit | 699 // Reverse the mappings. For each element record an OutputUnit |
| 683 // collecting all deferred imports mapped to this element. Same | 700 // collecting all deferred imports mapped to this element. Same |
| 684 // for constants. | 701 // for constants. |
| 685 for (_DeferredImport import in _importedDeferredBy.keys) { | 702 for (_DeferredImport import in _importedDeferredBy.keys) { |
| 686 for (Element element in _importedDeferredBy[import]) { | 703 for (Element element in _importedDeferredBy[import]) { |
| 687 // Only one file should be loaded when the program starts, so | 704 // Only one file should be loaded when the program starts, so |
| 688 // make sure that only one OutputUnit is created for | 705 // make sure that only one OutputUnit is created for |
| 689 // [fakeMainImport]. | 706 // [fakeMainImport]. |
| 690 if (import == _fakeMainImport) { | 707 if (import == _fakeMainImport) { |
| 691 elementToOutputUnitBuilder[element] = mainOutputUnit; | 708 elementToOutputUnitBuilder[element] = mainOutputUnit; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 714 } | 731 } |
| 715 | 732 |
| 716 // Release maps; | 733 // Release maps; |
| 717 _importedDeferredBy = null; | 734 _importedDeferredBy = null; |
| 718 _constantsDeferredBy = null; | 735 _constantsDeferredBy = null; |
| 719 | 736 |
| 720 // Find all the output units elements/constants have been mapped | 737 // Find all the output units elements/constants have been mapped |
| 721 // to, and canonicalize them. | 738 // to, and canonicalize them. |
| 722 elementToOutputUnitBuilder | 739 elementToOutputUnitBuilder |
| 723 .forEach((Element element, OutputUnit outputUnit) { | 740 .forEach((Element element, OutputUnit outputUnit) { |
| 724 OutputUnit representative = allOutputUnits.lookup(outputUnit); | 741 _elementToOutputUnit[element] = _getCanonicalUnit(outputUnit); |
| 725 if (representative == null) { | |
| 726 representative = outputUnit; | |
| 727 allOutputUnits.add(representative); | |
| 728 } | |
| 729 _elementToOutputUnit[element] = representative; | |
| 730 }); | 742 }); |
| 731 constantToOutputUnitBuilder | 743 constantToOutputUnitBuilder |
| 732 .forEach((ConstantValue constant, OutputUnit outputUnit) { | 744 .forEach((ConstantValue constant, OutputUnit outputUnit) { |
| 733 OutputUnit representative = allOutputUnits.lookup(outputUnit); | 745 _constantToOutputUnit[constant] = _getCanonicalUnit(outputUnit); |
| 734 if (representative == null) { | |
| 735 representative = outputUnit; | |
| 736 allOutputUnits.add(representative); | |
| 737 } | |
| 738 _constantToOutputUnit[constant] = representative; | |
| 739 }); | 746 }); |
| 740 | 747 |
| 741 // Generate a unique name for each OutputUnit. | 748 // Generate a unique name for each OutputUnit. |
| 742 _assignNamesToOutputUnits(allOutputUnits); | 749 _assignNamesToOutputUnits(allOutputUnits); |
| 743 })); | 750 })); |
| 744 // Notify the impact strategy impacts are no longer needed for deferred | 751 // Notify the impact strategy impacts are no longer needed for deferred |
| 745 // load. | 752 // load. |
| 746 compiler.impactStrategy.onImpactUsed(IMPACT_USE); | 753 compiler.impactStrategy.onImpactUsed(IMPACT_USE); |
| 747 } | 754 } |
| 748 | 755 |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1036 | 1043 |
| 1037 bool operator ==(other) { | 1044 bool operator ==(other) { |
| 1038 if (other is! _DeclaredDeferredImport) return false; | 1045 if (other is! _DeclaredDeferredImport) return false; |
| 1039 return declaration == other.declaration; | 1046 return declaration == other.declaration; |
| 1040 } | 1047 } |
| 1041 | 1048 |
| 1042 int get hashCode => declaration.hashCode * 17; | 1049 int get hashCode => declaration.hashCode * 17; |
| 1043 | 1050 |
| 1044 String toString() => '$declaration'; | 1051 String toString() => '$declaration'; |
| 1045 } | 1052 } |
| OLD | NEW |