Chromium Code Reviews| 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 OutputUnit representative = _getCanonicalUnit(outputUnit); | |
| 242 _constantToOutputUnit[constant] = representative; | |
| 230 } | 243 } |
| 231 | 244 |
| 232 /// Answers whether [element] is explicitly deferred when referred to from | 245 /// Answers whether [element] is explicitly deferred when referred to from |
| 233 /// [library]. | 246 /// [library]. |
| 234 bool _isExplicitlyDeferred(Element element, LibraryElement library) { | 247 bool _isExplicitlyDeferred(Element element, LibraryElement library) { |
| 235 Iterable<ImportElement> imports = _getImports(element, library); | 248 Iterable<ImportElement> imports = _getImports(element, library); |
| 236 // If the element is not imported explicitly, it is implicitly imported | 249 // If the element is not imported explicitly, it is implicitly imported |
| 237 // not deferred. | 250 // not deferred. |
| 238 if (imports.isEmpty) return false; | 251 if (imports.isEmpty) return false; |
| 239 // An element could potentially be loaded by several imports. If all of them | 252 // 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) { | 685 if (compiler.commonElements.mirrorsLibrary != null) { |
| 673 _addMirrorElements(); | 686 _addMirrorElements(); |
| 674 } | 687 } |
| 675 | 688 |
| 676 // Build the OutputUnits using these two maps. | 689 // Build the OutputUnits using these two maps. |
| 677 Map<Element, OutputUnit> elementToOutputUnitBuilder = | 690 Map<Element, OutputUnit> elementToOutputUnitBuilder = |
| 678 new Map<Element, OutputUnit>(); | 691 new Map<Element, OutputUnit>(); |
| 679 Map<ConstantValue, OutputUnit> constantToOutputUnitBuilder = | 692 Map<ConstantValue, OutputUnit> constantToOutputUnitBuilder = |
| 680 new Map<ConstantValue, OutputUnit>(); | 693 new Map<ConstantValue, OutputUnit>(); |
| 681 | 694 |
| 695 // Add all constants that may have been registered during | |
| 696 // resolution with [registerConstantDeferredUse]. | |
| 697 constantToOutputUnitBuilder.addAll(_constantToOutputUnit); | |
| 698 _constantToOutputUnit.clear(); | |
| 699 | |
| 682 // Reverse the mappings. For each element record an OutputUnit | 700 // Reverse the mappings. For each element record an OutputUnit |
| 683 // collecting all deferred imports mapped to this element. Same | 701 // collecting all deferred imports mapped to this element. Same |
| 684 // for constants. | 702 // for constants. |
| 685 for (_DeferredImport import in _importedDeferredBy.keys) { | 703 for (_DeferredImport import in _importedDeferredBy.keys) { |
| 686 for (Element element in _importedDeferredBy[import]) { | 704 for (Element element in _importedDeferredBy[import]) { |
| 687 // Only one file should be loaded when the program starts, so | 705 // Only one file should be loaded when the program starts, so |
| 688 // make sure that only one OutputUnit is created for | 706 // make sure that only one OutputUnit is created for |
| 689 // [fakeMainImport]. | 707 // [fakeMainImport]. |
| 690 if (import == _fakeMainImport) { | 708 if (import == _fakeMainImport) { |
| 691 elementToOutputUnitBuilder[element] = mainOutputUnit; | 709 elementToOutputUnitBuilder[element] = mainOutputUnit; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 714 } | 732 } |
| 715 | 733 |
| 716 // Release maps; | 734 // Release maps; |
| 717 _importedDeferredBy = null; | 735 _importedDeferredBy = null; |
| 718 _constantsDeferredBy = null; | 736 _constantsDeferredBy = null; |
| 719 | 737 |
| 720 // Find all the output units elements/constants have been mapped | 738 // Find all the output units elements/constants have been mapped |
| 721 // to, and canonicalize them. | 739 // to, and canonicalize them. |
| 722 elementToOutputUnitBuilder | 740 elementToOutputUnitBuilder |
| 723 .forEach((Element element, OutputUnit outputUnit) { | 741 .forEach((Element element, OutputUnit outputUnit) { |
| 724 OutputUnit representative = allOutputUnits.lookup(outputUnit); | 742 OutputUnit representative = _getCanonicalUnit(outputUnit); |
|
Siggi Cherem (dart-lang)
2016/09/07 23:57:50
now that the logic is pulled out, consider removin
Harry Terkelsen
2016/09/08 00:01:29
Done.
| |
| 725 if (representative == null) { | |
| 726 representative = outputUnit; | |
| 727 allOutputUnits.add(representative); | |
| 728 } | |
| 729 _elementToOutputUnit[element] = representative; | 743 _elementToOutputUnit[element] = representative; |
| 730 }); | 744 }); |
| 731 constantToOutputUnitBuilder | 745 constantToOutputUnitBuilder |
| 732 .forEach((ConstantValue constant, OutputUnit outputUnit) { | 746 .forEach((ConstantValue constant, OutputUnit outputUnit) { |
| 733 OutputUnit representative = allOutputUnits.lookup(outputUnit); | 747 OutputUnit representative = _getCanonicalUnit(outputUnit); |
| 734 if (representative == null) { | |
| 735 representative = outputUnit; | |
| 736 allOutputUnits.add(representative); | |
| 737 } | |
| 738 _constantToOutputUnit[constant] = representative; | 748 _constantToOutputUnit[constant] = representative; |
| 739 }); | 749 }); |
| 740 | 750 |
| 741 // Generate a unique name for each OutputUnit. | 751 // Generate a unique name for each OutputUnit. |
| 742 _assignNamesToOutputUnits(allOutputUnits); | 752 _assignNamesToOutputUnits(allOutputUnits); |
| 743 })); | 753 })); |
| 744 // Notify the impact strategy impacts are no longer needed for deferred | 754 // Notify the impact strategy impacts are no longer needed for deferred |
| 745 // load. | 755 // load. |
| 746 compiler.impactStrategy.onImpactUsed(IMPACT_USE); | 756 compiler.impactStrategy.onImpactUsed(IMPACT_USE); |
| 747 } | 757 } |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1036 | 1046 |
| 1037 bool operator ==(other) { | 1047 bool operator ==(other) { |
| 1038 if (other is! _DeclaredDeferredImport) return false; | 1048 if (other is! _DeclaredDeferredImport) return false; |
| 1039 return declaration == other.declaration; | 1049 return declaration == other.declaration; |
| 1040 } | 1050 } |
| 1041 | 1051 |
| 1042 int get hashCode => declaration.hashCode * 17; | 1052 int get hashCode => declaration.hashCode * 17; |
| 1043 | 1053 |
| 1044 String toString() => '$declaration'; | 1054 String toString() => '$declaration'; |
| 1045 } | 1055 } |
| OLD | NEW |