| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import '../common.dart'; | 5 import '../common.dart'; |
| 6 import '../common/resolution.dart' show Resolution; | 6 import '../common/resolution.dart' show Resolution; |
| 7 import '../core_types.dart'; | 7 import '../core_types.dart'; |
| 8 import '../elements/elements.dart'; | 8 import '../elements/elements.dart'; |
| 9 import '../elements/resolution_types.dart'; | 9 import '../elements/resolution_types.dart'; |
| 10 import '../universe/selector.dart'; | 10 import '../universe/selector.dart'; |
| 11 import '../universe/use.dart'; | 11 import '../universe/use.dart'; |
| 12 import '../universe/world_impact.dart' | 12 import '../universe/world_impact.dart' |
| 13 show WorldImpact, WorldImpactBuilder, WorldImpactBuilderImpl; | 13 show WorldImpact, WorldImpactBuilder, WorldImpactBuilderImpl; |
| 14 import '../util/util.dart' show Setlet; | 14 import '../util/util.dart' show Setlet; |
| 15 import 'backend_helpers.dart'; | 15 import 'backend_helpers.dart'; |
| 16 import 'backend_impact.dart'; | 16 import 'backend_impact.dart'; |
| 17 | 17 |
| 18 class BackendUsage { | 18 abstract class BackendUsage { |
| 19 final CommonElements commonElements; | 19 bool get needToInitializeIsolateAffinityTag; |
| 20 final BackendHelpers helpers; | 20 bool get needToInitializeDispatchProperty; |
| 21 final Resolution resolution; | 21 bool usedByBackend(Element element); |
| 22 Iterable<Element> get globalDependencies; |
| 23 } |
| 24 |
| 25 abstract class BackendUsageBuilder { |
| 26 Element registerBackendUse(Element element); |
| 27 void registerGlobalDependency(Element element); |
| 28 void registerBackendImpact( |
| 29 WorldImpactBuilder worldImpact, BackendImpact backendImpact); |
| 30 void registerBackendStaticUse( |
| 31 WorldImpactBuilder worldImpact, MethodElement element, |
| 32 {bool isGlobal: false}); |
| 33 void registerBackendInstantiation( |
| 34 WorldImpactBuilder worldImpact, ClassElement cls, |
| 35 {bool isGlobal: false}); |
| 36 WorldImpact createImpactFor(BackendImpact impact); |
| 37 void registerUsedMember(MemberElement member); |
| 38 } |
| 39 |
| 40 class BackendUsageImpl implements BackendUsage, BackendUsageBuilder { |
| 41 final CommonElements _commonElements; |
| 42 final BackendHelpers _helpers; |
| 43 final Resolution _resolution; |
| 22 // TODO(johnniwinther): Remove the need for this. | 44 // TODO(johnniwinther): Remove the need for this. |
| 23 Setlet<Element> _globalDependencies; | 45 Setlet<Element> _globalDependencies; |
| 24 | 46 |
| 25 /// List of elements that the backend may use. | 47 /// List of elements that the backend may use. |
| 26 final Set<Element> helpersUsed = new Set<Element>(); | 48 final Set<Element> _helpersUsed = new Set<Element>(); |
| 27 | 49 |
| 28 bool needToInitializeIsolateAffinityTag = false; | 50 bool _needToInitializeIsolateAffinityTag = false; |
| 29 bool needToInitializeDispatchProperty = false; | 51 bool _needToInitializeDispatchProperty = false; |
| 30 | 52 |
| 31 BackendUsage(this.commonElements, this.helpers, this.resolution); | 53 BackendUsageImpl(this._commonElements, this._helpers, this._resolution); |
| 54 |
| 55 bool get needToInitializeIsolateAffinityTag => |
| 56 _needToInitializeIsolateAffinityTag; |
| 57 bool get needToInitializeDispatchProperty => |
| 58 _needToInitializeDispatchProperty; |
| 32 | 59 |
| 33 /// The backend must *always* call this method when enqueuing an | 60 /// The backend must *always* call this method when enqueuing an |
| 34 /// element. Calls done by the backend are not seen by global | 61 /// element. Calls done by the backend are not seen by global |
| 35 /// optimizations, so they would make these optimizations unsound. | 62 /// optimizations, so they would make these optimizations unsound. |
| 36 /// Therefore we need to collect the list of helpers the backend may | 63 /// Therefore we need to collect the list of _helpers the backend may |
| 37 /// use. | 64 /// use. |
| 38 // TODO(johnniwinther): Replace this with a more precise modelling; type | 65 // TODO(johnniwinther): Replace this with a more precise modelling; type |
| 39 // inference of these elements is disabled. | 66 // inference of these elements is disabled. |
| 40 Element registerBackendUse(Element element) { | 67 Element registerBackendUse(Element element) { |
| 41 if (element == null) return null; | 68 if (element == null) return null; |
| 42 assert(invariant(element, _isValidBackendUse(element), | 69 assert(invariant(element, _isValidBackendUse(element), |
| 43 message: "Backend use of $element is not allowed.")); | 70 message: "Backend use of $element is not allowed.")); |
| 44 helpersUsed.add(element.declaration); | 71 _helpersUsed.add(element.declaration); |
| 45 if (element.isClass && element.isPatched) { | 72 if (element.isClass && element.isPatched) { |
| 46 // Both declaration and implementation may declare fields, so we | 73 // Both declaration and implementation may declare fields, so we |
| 47 // add both to the list of helpers. | 74 // add both to the list of _helpers. |
| 48 helpersUsed.add(element.implementation); | 75 _helpersUsed.add(element.implementation); |
| 49 } | 76 } |
| 50 return element; | 77 return element; |
| 51 } | 78 } |
| 52 | 79 |
| 53 bool _isValidBackendUse(Element element) { | 80 bool _isValidBackendUse(Element element) { |
| 54 assert(invariant(element, element.isDeclaration, message: "")); | 81 assert(invariant(element, element.isDeclaration, message: "")); |
| 55 if (element is ConstructorElement && | 82 if (element is ConstructorElement && |
| 56 (element == helpers.streamIteratorConstructor || | 83 (element == _helpers.streamIteratorConstructor || |
| 57 commonElements.isSymbolConstructor(element) || | 84 _commonElements.isSymbolConstructor(element) || |
| 58 helpers.isSymbolValidatedConstructor(element) || | 85 _helpers.isSymbolValidatedConstructor(element) || |
| 59 element == helpers.syncCompleterConstructor)) { | 86 element == _helpers.syncCompleterConstructor)) { |
| 60 // TODO(johnniwinther): These are valid but we could be more precise. | 87 // TODO(johnniwinther): These are valid but we could be more precise. |
| 61 return true; | 88 return true; |
| 62 } else if (element == commonElements.symbolClass || | 89 } else if (element == _commonElements.symbolClass || |
| 63 element == helpers.objectNoSuchMethod) { | 90 element == _helpers.objectNoSuchMethod) { |
| 64 // TODO(johnniwinther): These are valid but we could be more precise. | 91 // TODO(johnniwinther): These are valid but we could be more precise. |
| 65 return true; | 92 return true; |
| 66 } else if (element.implementationLibrary.isPatch || | 93 } else if (element.implementationLibrary.isPatch || |
| 67 // Needed to detect deserialized injected elements, that is | 94 // Needed to detect deserialized injected elements, that is |
| 68 // element declared in patch files. | 95 // element declared in patch files. |
| 69 (element.library.isPlatformLibrary && | 96 (element.library.isPlatformLibrary && |
| 70 element.sourcePosition.uri.path | 97 element.sourcePosition.uri.path |
| 71 .contains('_internal/js_runtime/lib/')) || | 98 .contains('_internal/js_runtime/lib/')) || |
| 72 element.library == helpers.jsHelperLibrary || | 99 element.library == _helpers.jsHelperLibrary || |
| 73 element.library == helpers.interceptorsLibrary || | 100 element.library == _helpers.interceptorsLibrary || |
| 74 element.library == helpers.isolateHelperLibrary) { | 101 element.library == _helpers.isolateHelperLibrary) { |
| 75 // TODO(johnniwinther): We should be more precise about these. | 102 // TODO(johnniwinther): We should be more precise about these. |
| 76 return true; | 103 return true; |
| 77 } else if (element == commonElements.listClass || | 104 } else if (element == _commonElements.listClass || |
| 78 element == helpers.mapLiteralClass || | 105 element == _helpers.mapLiteralClass || |
| 79 element == commonElements.functionClass || | 106 element == _commonElements.functionClass || |
| 80 element == commonElements.stringClass) { | 107 element == _commonElements.stringClass) { |
| 81 // TODO(johnniwinther): Avoid these. | 108 // TODO(johnniwinther): Avoid these. |
| 82 return true; | 109 return true; |
| 83 } else if (element == helpers.genericNoSuchMethod || | 110 } else if (element == _helpers.genericNoSuchMethod || |
| 84 element == helpers.unresolvedConstructorError || | 111 element == _helpers.unresolvedConstructorError || |
| 85 element == helpers.malformedTypeError) { | 112 element == _helpers.malformedTypeError) { |
| 86 return true; | 113 return true; |
| 87 } | 114 } |
| 88 return false; | 115 return false; |
| 89 } | 116 } |
| 90 | 117 |
| 91 bool usedByBackend(Element element) { | 118 bool usedByBackend(Element element) { |
| 92 if (element.isRegularParameter || | 119 if (element.isRegularParameter || |
| 93 element.isInitializingFormal || | 120 element.isInitializingFormal || |
| 94 element.isField) { | 121 element.isField) { |
| 95 if (usedByBackend(element.enclosingElement)) return true; | 122 if (usedByBackend(element.enclosingElement)) return true; |
| 96 } | 123 } |
| 97 return helpersUsed.contains(element.declaration); | 124 return _helpersUsed.contains(element.declaration); |
| 98 } | 125 } |
| 99 | 126 |
| 100 WorldImpact createImpactFor(BackendImpact impact) { | 127 WorldImpact createImpactFor(BackendImpact impact) { |
| 101 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); | 128 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); |
| 102 registerBackendImpact(impactBuilder, impact); | 129 registerBackendImpact(impactBuilder, impact); |
| 103 return impactBuilder; | 130 return impactBuilder; |
| 104 } | 131 } |
| 105 | 132 |
| 106 void registerBackendStaticUse( | 133 void registerBackendStaticUse( |
| 107 WorldImpactBuilder worldImpact, MethodElement element, | 134 WorldImpactBuilder worldImpact, MethodElement element, |
| 108 {bool isGlobal: false}) { | 135 {bool isGlobal: false}) { |
| 109 registerBackendUse(element); | 136 registerBackendUse(element); |
| 110 worldImpact.registerStaticUse( | 137 worldImpact.registerStaticUse( |
| 111 // TODO(johnniwinther): Store the correct use in impacts. | 138 // TODO(johnniwinther): Store the correct use in impacts. |
| 112 new StaticUse.foreignUse(element)); | 139 new StaticUse.foreignUse(element)); |
| 113 if (isGlobal) { | 140 if (isGlobal) { |
| 114 registerGlobalDependency(element); | 141 registerGlobalDependency(element); |
| 115 } | 142 } |
| 116 } | 143 } |
| 117 | 144 |
| 118 void registerBackendInstantiation( | 145 void registerBackendInstantiation( |
| 119 WorldImpactBuilder worldImpact, ClassElement cls, | 146 WorldImpactBuilder worldImpact, ClassElement cls, |
| 120 {bool isGlobal: false}) { | 147 {bool isGlobal: false}) { |
| 121 cls.ensureResolved(resolution); | 148 cls.ensureResolved(_resolution); |
| 122 registerBackendUse(cls); | 149 registerBackendUse(cls); |
| 123 worldImpact.registerTypeUse(new TypeUse.instantiation(cls.rawType)); | 150 worldImpact.registerTypeUse(new TypeUse.instantiation(cls.rawType)); |
| 124 if (isGlobal) { | 151 if (isGlobal) { |
| 125 registerGlobalDependency(cls); | 152 registerGlobalDependency(cls); |
| 126 } | 153 } |
| 127 } | 154 } |
| 128 | 155 |
| 129 void registerBackendImpact( | 156 void registerBackendImpact( |
| 130 WorldImpactBuilder worldImpact, BackendImpact backendImpact) { | 157 WorldImpactBuilder worldImpact, BackendImpact backendImpact) { |
| 131 for (Element staticUse in backendImpact.staticUses) { | 158 for (Element staticUse in backendImpact.staticUses) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 150 } | 177 } |
| 151 for (ClassElement cls in backendImpact.globalClasses) { | 178 for (ClassElement cls in backendImpact.globalClasses) { |
| 152 registerBackendInstantiation(worldImpact, cls, isGlobal: true); | 179 registerBackendInstantiation(worldImpact, cls, isGlobal: true); |
| 153 } | 180 } |
| 154 for (BackendImpact otherImpact in backendImpact.otherImpacts) { | 181 for (BackendImpact otherImpact in backendImpact.otherImpacts) { |
| 155 registerBackendImpact(worldImpact, otherImpact); | 182 registerBackendImpact(worldImpact, otherImpact); |
| 156 } | 183 } |
| 157 for (BackendFeature feature in backendImpact.features) { | 184 for (BackendFeature feature in backendImpact.features) { |
| 158 switch (feature) { | 185 switch (feature) { |
| 159 case BackendFeature.needToInitializeDispatchProperty: | 186 case BackendFeature.needToInitializeDispatchProperty: |
| 160 needToInitializeDispatchProperty = true; | 187 _needToInitializeDispatchProperty = true; |
| 161 break; | 188 break; |
| 162 case BackendFeature.needToInitializeIsolateAffinityTag: | 189 case BackendFeature.needToInitializeIsolateAffinityTag: |
| 163 needToInitializeIsolateAffinityTag = true; | 190 _needToInitializeIsolateAffinityTag = true; |
| 164 break; | 191 break; |
| 165 } | 192 } |
| 166 } | 193 } |
| 167 } | 194 } |
| 168 | 195 |
| 196 void registerUsedMember(MemberElement member) { |
| 197 if (member == _helpers.getIsolateAffinityTagMarker) { |
| 198 _needToInitializeIsolateAffinityTag = true; |
| 199 } |
| 200 } |
| 201 |
| 169 void registerGlobalDependency(Element element) { | 202 void registerGlobalDependency(Element element) { |
| 170 if (element == null) return; | 203 if (element == null) return; |
| 171 if (_globalDependencies == null) { | 204 if (_globalDependencies == null) { |
| 172 _globalDependencies = new Setlet<Element>(); | 205 _globalDependencies = new Setlet<Element>(); |
| 173 } | 206 } |
| 174 _globalDependencies.add(element.implementation); | 207 _globalDependencies.add(element.implementation); |
| 175 } | 208 } |
| 176 | 209 |
| 177 Iterable<Element> get globalDependencies => _globalDependencies; | 210 Iterable<Element> get globalDependencies => _globalDependencies; |
| 178 } | 211 } |
| OLD | NEW |