| 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.dart'; | 7 import 'common.dart'; |
| 8 import 'common/backend_api.dart' show | 8 import 'common/backend_api.dart' show |
| 9 Backend; | 9 Backend; |
| 10 import 'common/tasks.dart' show | 10 import 'common/tasks.dart' show |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 AccessorElement, | 21 AccessorElement, |
| 22 AstElement, | 22 AstElement, |
| 23 ClassElement, | 23 ClassElement, |
| 24 Element, | 24 Element, |
| 25 ElementKind, | 25 ElementKind, |
| 26 Elements, | 26 Elements, |
| 27 ExportElement, | 27 ExportElement, |
| 28 FunctionElement, | 28 FunctionElement, |
| 29 ImportElement, | 29 ImportElement, |
| 30 LibraryElement, | 30 LibraryElement, |
| 31 LocalFunctionElement, |
| 31 MetadataAnnotation, | 32 MetadataAnnotation, |
| 32 PrefixElement, | 33 PrefixElement, |
| 33 ScopeContainerElement, | 34 ScopeContainerElement, |
| 34 TypedefElement; | 35 TypedefElement; |
| 35 import 'js_backend/js_backend.dart' show | 36 import 'js_backend/js_backend.dart' show |
| 36 JavaScriptBackend; | 37 JavaScriptBackend; |
| 37 import 'resolution/resolution.dart' show | 38 import 'resolution/resolution.dart' show |
| 38 AnalyzableElementX; | 39 AnalyzableElementX; |
| 39 import 'resolution/tree_elements.dart' show | 40 import 'resolution/tree_elements.dart' show |
| 40 TreeElements; | 41 TreeElements; |
| 41 import 'tree/tree.dart' as ast; | 42 import 'tree/tree.dart' as ast; |
| 42 import 'tree/tree.dart' show | 43 import 'tree/tree.dart' show |
| 43 Import, | 44 Import, |
| 44 LibraryTag, | 45 LibraryTag, |
| 45 LibraryDependency, | 46 LibraryDependency, |
| 46 LiteralDartString, | 47 LiteralDartString, |
| 47 LiteralString, | 48 LiteralString, |
| 48 NewExpression, | 49 NewExpression, |
| 49 Node; | 50 Node; |
| 50 import 'universe/use.dart' show | 51 import 'universe/use.dart' show |
| 52 DynamicUse, |
| 51 StaticUse, | 53 StaticUse, |
| 52 TypeUse, | 54 TypeUse, |
| 53 TypeUseKind; | 55 TypeUseKind; |
| 54 import 'universe/world_impact.dart' show | 56 import 'universe/world_impact.dart' show |
| 55 WorldImpact; | 57 ImpactUseCase, |
| 58 WorldImpact, |
| 59 WorldImpactVisitorImpl; |
| 56 import 'util/setlet.dart' show | 60 import 'util/setlet.dart' show |
| 57 Setlet; | 61 Setlet; |
| 58 import 'util/uri_extras.dart' as uri_extras; | 62 import 'util/uri_extras.dart' as uri_extras; |
| 59 import 'util/util.dart' show | 63 import 'util/util.dart' show |
| 60 Link, makeUnique; | 64 Link, makeUnique; |
| 61 | 65 |
| 62 /// A "hunk" of the program that will be loaded whenever one of its [imports] | 66 /// A "hunk" of the program that will be loaded whenever one of its [imports] |
| 63 /// are loaded. | 67 /// are loaded. |
| 64 /// | 68 /// |
| 65 /// Elements that are only used in one deferred import, is in an OutputUnit with | 69 /// Elements that are only used in one deferred import, is in an OutputUnit with |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 /// The OutputUnit that will be loaded when the program starts. | 119 /// The OutputUnit that will be loaded when the program starts. |
| 116 final OutputUnit mainOutputUnit = new OutputUnit(isMainOutput: true); | 120 final OutputUnit mainOutputUnit = new OutputUnit(isMainOutput: true); |
| 117 | 121 |
| 118 /// A set containing (eventually) all output units that will result from the | 122 /// A set containing (eventually) all output units that will result from the |
| 119 /// program. | 123 /// program. |
| 120 final Set<OutputUnit> allOutputUnits = new Set<OutputUnit>(); | 124 final Set<OutputUnit> allOutputUnits = new Set<OutputUnit>(); |
| 121 | 125 |
| 122 /// Will be `true` if the program contains deferred libraries. | 126 /// Will be `true` if the program contains deferred libraries. |
| 123 bool isProgramSplit = false; | 127 bool isProgramSplit = false; |
| 124 | 128 |
| 129 static const ImpactUseCase IMPACT_USE = const ImpactUseCase('Deferred load'); |
| 130 |
| 125 /// A mapping from the name of a defer import to all the output units it | 131 /// A mapping from the name of a defer import to all the output units it |
| 126 /// depends on in a list of lists to be loaded in the order they appear. | 132 /// depends on in a list of lists to be loaded in the order they appear. |
| 127 /// | 133 /// |
| 128 /// For example {"lib1": [[lib1_lib2_lib3], [lib1_lib2, lib1_lib3], | 134 /// For example {"lib1": [[lib1_lib2_lib3], [lib1_lib2, lib1_lib3], |
| 129 /// [lib1]]} would mean that in order to load "lib1" first the hunk | 135 /// [lib1]]} would mean that in order to load "lib1" first the hunk |
| 130 /// lib1_lib2_lib2 should be loaded, then the hunks lib1_lib2 and lib1_lib3 | 136 /// lib1_lib2_lib2 should be loaded, then the hunks lib1_lib2 and lib1_lib3 |
| 131 /// can be loaded in parallel. And finally lib1 can be loaded. | 137 /// can be loaded in parallel. And finally lib1 can be loaded. |
| 132 final Map<String, List<OutputUnit>> hunksToLoad = | 138 final Map<String, List<OutputUnit>> hunksToLoad = |
| 133 new Map<String, List<OutputUnit>>(); | 139 new Map<String, List<OutputUnit>>(); |
| 134 | 140 |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 } else { | 317 } else { |
| 312 // TODO(sigurdm): We want to be more specific about this - need a better | 318 // TODO(sigurdm): We want to be more specific about this - need a better |
| 313 // way to query "liveness". | 319 // way to query "liveness". |
| 314 AstElement analyzableElement = element.analyzableElement.declaration; | 320 AstElement analyzableElement = element.analyzableElement.declaration; |
| 315 if (!compiler.enqueuer.resolution.hasBeenProcessed(analyzableElement)) { | 321 if (!compiler.enqueuer.resolution.hasBeenProcessed(analyzableElement)) { |
| 316 return; | 322 return; |
| 317 } | 323 } |
| 318 | 324 |
| 319 WorldImpact worldImpact = | 325 WorldImpact worldImpact = |
| 320 compiler.resolution.getWorldImpact(analyzableElement); | 326 compiler.resolution.getWorldImpact(analyzableElement); |
| 321 worldImpact.staticUses.forEach((StaticUse staticUse) { | 327 compiler.impactStrategy.visitImpact( |
| 322 elements.add(staticUse.element); | 328 analyzableElement, |
| 323 }); | 329 worldImpact, |
| 324 for (TypeUse typeUse in worldImpact.typeUses) { | 330 new WorldImpactVisitorImpl( |
| 325 DartType type = typeUse.type; | 331 visitStaticUse: (StaticUse staticUse) { |
| 326 switch (typeUse.kind) { | 332 elements.add(staticUse.element); |
| 327 case TypeUseKind.TYPE_LITERAL: | 333 }, |
| 328 if (type.isTypedef || type.isInterfaceType) { | 334 visitTypeUse: (TypeUse typeUse) { |
| 329 elements.add(type.element); | 335 DartType type = typeUse.type; |
| 330 } | 336 switch (typeUse.kind) { |
| 331 break; | 337 case TypeUseKind.TYPE_LITERAL: |
| 332 case TypeUseKind.INSTANTIATION: | 338 if (type.isTypedef || type.isInterfaceType) { |
| 333 case TypeUseKind.IS_CHECK: | 339 elements.add(type.element); |
| 334 case TypeUseKind.AS_CAST: | 340 } |
| 335 case TypeUseKind.CATCH_TYPE: | 341 break; |
| 336 collectTypeDependencies(type); | 342 case TypeUseKind.INSTANTIATION: |
| 337 break; | 343 case TypeUseKind.IS_CHECK: |
| 338 case TypeUseKind.CHECKED_MODE_CHECK: | 344 case TypeUseKind.AS_CAST: |
| 339 if (compiler.enableTypeAssertions) { | 345 case TypeUseKind.CATCH_TYPE: |
| 340 collectTypeDependencies(type); | 346 collectTypeDependencies(type); |
| 341 } | 347 break; |
| 342 break; | 348 case TypeUseKind.CHECKED_MODE_CHECK: |
| 343 } | 349 if (compiler.enableTypeAssertions) { |
| 344 } | 350 collectTypeDependencies(type); |
| 351 } |
| 352 break; |
| 353 } |
| 354 }), |
| 355 IMPACT_USE); |
| 345 | 356 |
| 346 TreeElements treeElements = analyzableElement.resolvedAst.elements; | 357 TreeElements treeElements = analyzableElement.resolvedAst.elements; |
| 347 assert(treeElements != null); | 358 assert(treeElements != null); |
| 348 | 359 |
| 349 treeElements.forEachConstantNode((Node node, _) { | 360 treeElements.forEachConstantNode((Node node, _) { |
| 350 // Explicitly depend on the backend constants. | 361 // Explicitly depend on the backend constants. |
| 351 ConstantValue value = | 362 ConstantValue value = |
| 352 backend.constants.getConstantValueForNode(node, treeElements); | 363 backend.constants.getConstantValueForNode(node, treeElements); |
| 353 if (value != null) { | 364 if (value != null) { |
| 354 // TODO(johnniwinther): Assert that all constants have values when | 365 // TODO(johnniwinther): Assert that all constants have values when |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 if (representative == null) { | 715 if (representative == null) { |
| 705 representative = outputUnit; | 716 representative = outputUnit; |
| 706 allOutputUnits.add(representative); | 717 allOutputUnits.add(representative); |
| 707 } | 718 } |
| 708 _constantToOutputUnit[constant] = representative; | 719 _constantToOutputUnit[constant] = representative; |
| 709 }); | 720 }); |
| 710 | 721 |
| 711 // Generate a unique name for each OutputUnit. | 722 // Generate a unique name for each OutputUnit. |
| 712 _assignNamesToOutputUnits(allOutputUnits); | 723 _assignNamesToOutputUnits(allOutputUnits); |
| 713 }); | 724 }); |
| 725 // Notify the impact strategy impacts are no longer needed for deferred |
| 726 // load. |
| 727 compiler.impactStrategy.onImpactUsed(IMPACT_USE); |
| 714 } | 728 } |
| 715 | 729 |
| 716 void beforeResolution(Compiler compiler) { | 730 void beforeResolution(Compiler compiler) { |
| 717 if (compiler.mainApp == null) return; | 731 if (compiler.mainApp == null) return; |
| 718 _allDeferredImports[_fakeMainImport] = compiler.mainApp; | 732 _allDeferredImports[_fakeMainImport] = compiler.mainApp; |
| 719 var lastDeferred; | 733 var lastDeferred; |
| 720 // When detecting duplicate prefixes of deferred libraries there are 4 | 734 // When detecting duplicate prefixes of deferred libraries there are 4 |
| 721 // cases of duplicate prefixes: | 735 // cases of duplicate prefixes: |
| 722 // 1. | 736 // 1. |
| 723 // import "lib.dart" deferred as a; | 737 // import "lib.dart" deferred as a; |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 998 return result; | 1012 return result; |
| 999 } | 1013 } |
| 1000 | 1014 |
| 1001 bool operator ==(other) { | 1015 bool operator ==(other) { |
| 1002 if (other is! _DeclaredDeferredImport) return false; | 1016 if (other is! _DeclaredDeferredImport) return false; |
| 1003 return declaration == other.declaration; | 1017 return declaration == other.declaration; |
| 1004 } | 1018 } |
| 1005 | 1019 |
| 1006 int get hashCode => declaration.hashCode * 17; | 1020 int get hashCode => declaration.hashCode * 17; |
| 1007 } | 1021 } |
| OLD | NEW |