| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 import '../common.dart'; |
| 6 import '../core_types.dart'; |
| 7 import '../elements/elements.dart'; |
| 8 import 'backend_helpers.dart'; |
| 9 |
| 10 class BackendUsage { |
| 11 final CommonElements commonElements; |
| 12 final BackendHelpers helpers; |
| 13 |
| 14 /// List of elements that the backend may use. |
| 15 final Set<Element> helpersUsed = new Set<Element>(); |
| 16 |
| 17 bool needToInitializeIsolateAffinityTag = false; |
| 18 bool needToInitializeDispatchProperty = false; |
| 19 |
| 20 BackendUsage(this.commonElements, this.helpers); |
| 21 |
| 22 /// The backend must *always* call this method when enqueuing an |
| 23 /// element. Calls done by the backend are not seen by global |
| 24 /// optimizations, so they would make these optimizations unsound. |
| 25 /// Therefore we need to collect the list of helpers the backend may |
| 26 /// use. |
| 27 // TODO(johnniwinther): Replace this with a more precise modelling; type |
| 28 // inference of these elements is disabled. |
| 29 Element registerBackendUse(Element element) { |
| 30 if (element == null) return null; |
| 31 assert(invariant(element, _isValidBackendUse(element), |
| 32 message: "Backend use of $element is not allowed.")); |
| 33 helpersUsed.add(element.declaration); |
| 34 if (element.isClass && element.isPatched) { |
| 35 // Both declaration and implementation may declare fields, so we |
| 36 // add both to the list of helpers. |
| 37 helpersUsed.add(element.implementation); |
| 38 } |
| 39 return element; |
| 40 } |
| 41 |
| 42 bool _isValidBackendUse(Element element) { |
| 43 assert(invariant(element, element.isDeclaration, message: "")); |
| 44 if (element is ConstructorElement && |
| 45 (element == helpers.streamIteratorConstructor || |
| 46 commonElements.isSymbolConstructor(element) || |
| 47 helpers.isSymbolValidatedConstructor(element) || |
| 48 element == helpers.syncCompleterConstructor)) { |
| 49 // TODO(johnniwinther): These are valid but we could be more precise. |
| 50 return true; |
| 51 } else if (element == commonElements.symbolClass || |
| 52 element == helpers.objectNoSuchMethod) { |
| 53 // TODO(johnniwinther): These are valid but we could be more precise. |
| 54 return true; |
| 55 } else if (element.implementationLibrary.isPatch || |
| 56 // Needed to detect deserialized injected elements, that is |
| 57 // element declared in patch files. |
| 58 (element.library.isPlatformLibrary && |
| 59 element.sourcePosition.uri.path |
| 60 .contains('_internal/js_runtime/lib/')) || |
| 61 element.library == helpers.jsHelperLibrary || |
| 62 element.library == helpers.interceptorsLibrary || |
| 63 element.library == helpers.isolateHelperLibrary) { |
| 64 // TODO(johnniwinther): We should be more precise about these. |
| 65 return true; |
| 66 } else if (element == commonElements.listClass || |
| 67 element == helpers.mapLiteralClass || |
| 68 element == commonElements.functionClass || |
| 69 element == commonElements.stringClass) { |
| 70 // TODO(johnniwinther): Avoid these. |
| 71 return true; |
| 72 } else if (element == helpers.genericNoSuchMethod || |
| 73 element == helpers.unresolvedConstructorError || |
| 74 element == helpers.malformedTypeError) { |
| 75 return true; |
| 76 } |
| 77 return false; |
| 78 } |
| 79 |
| 80 bool usedByBackend(Element element) { |
| 81 if (element.isRegularParameter || |
| 82 element.isInitializingFormal || |
| 83 element.isField) { |
| 84 if (usedByBackend(element.enclosingElement)) return true; |
| 85 } |
| 86 return helpersUsed.contains(element.declaration); |
| 87 } |
| 88 } |
| OLD | NEW |