| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 dart2js.world; | 5 library dart2js.world; |
| 6 | 6 |
| 7 import 'closure.dart' show SynthesizedCallMethodElementX; | 7 import 'closure.dart' show SynthesizedCallMethodElementX; |
| 8 import 'common/backend_api.dart' show Backend; | 8 import 'common/backend_api.dart' show Backend; |
| 9 import 'common.dart'; | 9 import 'common.dart'; |
| 10 import 'compiler.dart' show Compiler; | 10 import 'compiler.dart' show Compiler; |
| 11 import 'core_types.dart' show CoreClasses; | 11 import 'core_types.dart' show CoreClasses; |
| 12 import 'dart_types.dart'; | 12 import 'dart_types.dart'; |
| 13 import 'elements/elements.dart' | 13 import 'elements/elements.dart' |
| 14 show | 14 show |
| 15 ClassElement, | 15 ClassElement, |
| 16 Element, | 16 Element, |
| 17 FunctionElement, | 17 FunctionElement, |
| 18 MixinApplicationElement, | 18 MixinApplicationElement, |
| 19 TypedefElement, | 19 TypedefElement, |
| 20 VariableElement; | 20 VariableElement; |
| 21 import 'js_backend/backend.dart' show JavaScriptBackend; | 21 import 'js_backend/backend.dart' show JavaScriptBackend; |
| 22 import 'ordered_typeset.dart'; | 22 import 'ordered_typeset.dart'; |
| 23 import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask; | 23 import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask; |
| 24 import 'universe/class_set.dart'; | 24 import 'universe/class_set.dart'; |
| 25 import 'universe/function_set.dart' show FunctionSet; | 25 import 'universe/function_set.dart' show FunctionSet; |
| 26 import 'universe/selector.dart' show Selector; | 26 import 'universe/selector.dart' show Selector; |
| 27 import 'universe/side_effects.dart' show SideEffects; | 27 import 'universe/side_effects.dart' show SideEffects; |
| 28 import 'util/util.dart' show Link; | 28 import 'util/util.dart' show Link; |
| 29 | 29 |
| 30 /// The [ClassWorld] represents the information known about a program when | 30 /// Common superinterface for [OpenWorld] and [ClosedWorld]. |
| 31 abstract class World {} |
| 32 |
| 33 /// The [ClosedWorld] represents the information known about a program when |
| 31 /// compiling with closed-world semantics. | 34 /// compiling with closed-world semantics. |
| 32 /// | 35 /// |
| 33 /// Given the entrypoint of an application, we can track what's reachable from | 36 /// Given the entrypoint of an application, we can track what's reachable from |
| 34 /// it, what functions are called, what classes are allocated, which native | 37 /// it, what functions are called, what classes are allocated, which native |
| 35 /// JavaScript types are touched, what language features are used, and so on. | 38 /// JavaScript types are touched, what language features are used, and so on. |
| 36 /// This precise knowledge about what's live in the program is later used in | 39 /// This precise knowledge about what's live in the program is later used in |
| 37 /// optimizations and other compiler decisions during code generation. | 40 /// optimizations and other compiler decisions during code generation. |
| 38 abstract class ClassWorld { | 41 abstract class ClosedWorld implements World { |
| 39 // TODO(johnniwinther): Refine this into a `BackendClasses` interface. | 42 // TODO(johnniwinther): Refine this into a `BackendClasses` interface. |
| 40 Backend get backend; | 43 Backend get backend; |
| 41 | 44 |
| 42 CoreClasses get coreClasses; | 45 CoreClasses get coreClasses; |
| 43 | 46 |
| 44 /// Returns `true` if the class world is closed. | |
| 45 bool get isClosed; | |
| 46 | |
| 47 /// Returns `true` if closed-world assumptions can be made, that is, | |
| 48 /// incremental compilation isn't enabled. | |
| 49 bool get hasClosedWorldAssumption; | |
| 50 | |
| 51 /// Returns a string representation of the closed world. | |
| 52 /// | |
| 53 /// If [cls] is provided, the dump will contain only classes related to [cls]. | |
| 54 String dump([ClassElement cls]); | |
| 55 | |
| 56 /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies | |
| 57 /// of known classes. | |
| 58 /// | |
| 59 /// This method is only provided for testing. For queries on classes, use the | |
| 60 /// methods defined in [ClassWorld]. | |
| 61 ClassHierarchyNode getClassHierarchyNode(ClassElement cls); | |
| 62 | |
| 63 /// Returns [ClassSet] for [cls] used to model the extends and implements | |
| 64 /// relations of known classes. | |
| 65 /// | |
| 66 /// This method is only provided for testing. For queries on classes, use the | |
| 67 /// methods defined in [ClassWorld]. | |
| 68 ClassSet getClassSet(ClassElement cls); | |
| 69 | |
| 70 // TODO(johnniwinther): Find a better strategy for caching these. | |
| 71 @deprecated | |
| 72 List<Map<ClassElement, TypeMask>> get canonicalizedTypeMasks; | |
| 73 } | |
| 74 | |
| 75 /// The [ClosedWorld] represents the information known about a program when | |
| 76 /// compiling with closed-world semantics. | |
| 77 /// | |
| 78 /// This expands [ClassWorld] with information about live functions, | |
| 79 /// side effects, and selectors with known single targets. | |
| 80 abstract class ClosedWorld extends ClassWorld { | |
| 81 /// Returns `true` if [cls] is either directly or indirectly instantiated. | 47 /// Returns `true` if [cls] is either directly or indirectly instantiated. |
| 82 bool isInstantiated(ClassElement cls); | 48 bool isInstantiated(ClassElement cls); |
| 83 | 49 |
| 84 /// Returns `true` if [cls] is directly instantiated. | 50 /// Returns `true` if [cls] is directly instantiated. |
| 85 bool isDirectlyInstantiated(ClassElement cls); | 51 bool isDirectlyInstantiated(ClassElement cls); |
| 86 | 52 |
| 87 /// Returns `true` if [cls] is indirectly instantiated, that is through a | 53 /// Returns `true` if [cls] is indirectly instantiated, that is through a |
| 88 /// subclass. | 54 /// subclass. |
| 89 bool isIndirectlyInstantiated(ClassElement cls); | 55 bool isIndirectlyInstantiated(ClassElement cls); |
| 90 | 56 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 /// Returns `true` if [cls] or any superclass mixes in [mixin]. | 148 /// Returns `true` if [cls] or any superclass mixes in [mixin]. |
| 183 bool isSubclassOfMixinUseOf(ClassElement cls, ClassElement mixin); | 149 bool isSubclassOfMixinUseOf(ClassElement cls, ClassElement mixin); |
| 184 | 150 |
| 185 /// Returns `true` if every subtype of [x] is a subclass of [y] or a subclass | 151 /// Returns `true` if every subtype of [x] is a subclass of [y] or a subclass |
| 186 /// of a mixin application of [y]. | 152 /// of a mixin application of [y]. |
| 187 bool everySubtypeIsSubclassOfOrMixinUseOf(ClassElement x, ClassElement y); | 153 bool everySubtypeIsSubclassOfOrMixinUseOf(ClassElement x, ClassElement y); |
| 188 | 154 |
| 189 /// Returns `true` if any subclass of [superclass] implements [type]. | 155 /// Returns `true` if any subclass of [superclass] implements [type]. |
| 190 bool hasAnySubclassThatImplements(ClassElement superclass, ClassElement type); | 156 bool hasAnySubclassThatImplements(ClassElement superclass, ClassElement type); |
| 191 | 157 |
| 158 /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies |
| 159 /// of known classes. |
| 160 /// |
| 161 /// This method is only provided for testing. For queries on classes, use the |
| 162 /// methods defined in [ClosedWorld]. |
| 163 ClassHierarchyNode getClassHierarchyNode(ClassElement cls); |
| 164 |
| 165 /// Returns [ClassSet] for [cls] used to model the extends and implements |
| 166 /// relations of known classes. |
| 167 /// |
| 168 /// This method is only provided for testing. For queries on classes, use the |
| 169 /// methods defined in [ClosedWorld]. |
| 170 ClassSet getClassSet(ClassElement cls); |
| 171 |
| 172 // TODO(johnniwinther): Find a better strategy for caching these. |
| 173 @deprecated |
| 174 List<Map<ClassElement, TypeMask>> get canonicalizedTypeMasks; |
| 175 |
| 192 /// Returns the [FunctionSet] containing all live functions in the closed | 176 /// Returns the [FunctionSet] containing all live functions in the closed |
| 193 /// world. | 177 /// world. |
| 194 FunctionSet get allFunctions; | 178 FunctionSet get allFunctions; |
| 195 | 179 |
| 196 /// Returns `true` if the field [element] is known to be effectively final. | 180 /// Returns `true` if the field [element] is known to be effectively final. |
| 197 bool fieldNeverChanges(Element element); | 181 bool fieldNeverChanges(Element element); |
| 198 | 182 |
| 199 /// Extends the receiver type [mask] for calling [selector] to take live | 183 /// Extends the receiver type [mask] for calling [selector] to take live |
| 200 /// `noSuchMethod` handlers into account. | 184 /// `noSuchMethod` handlers into account. |
| 201 TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask); | 185 TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 223 bool getCannotThrow(Element element); | 207 bool getCannotThrow(Element element); |
| 224 | 208 |
| 225 /// Returns `true` if [element] is called in a loop. | 209 /// Returns `true` if [element] is called in a loop. |
| 226 // TODO(johnniwinther): Is this 'potentially called' or 'known to be called'? | 210 // TODO(johnniwinther): Is this 'potentially called' or 'known to be called'? |
| 227 bool isCalledInLoop(Element element); | 211 bool isCalledInLoop(Element element); |
| 228 | 212 |
| 229 /// Returns `true` if [element] might be passed to `Function.apply`. | 213 /// Returns `true` if [element] might be passed to `Function.apply`. |
| 230 // TODO(johnniwinther): Is this 'passed invocation target` or | 214 // TODO(johnniwinther): Is this 'passed invocation target` or |
| 231 // `passed as argument`? | 215 // `passed as argument`? |
| 232 bool getMightBePassedToApply(Element element); | 216 bool getMightBePassedToApply(Element element); |
| 217 |
| 218 /// Returns a string representation of the closed world. |
| 219 /// |
| 220 /// If [cls] is provided, the dump will contain only classes related to [cls]. |
| 221 String dump([ClassElement cls]); |
| 233 } | 222 } |
| 234 | 223 |
| 235 /// Interface for computing side effects and uses of elements. This is used | 224 /// Interface for computing side effects and uses of elements. This is used |
| 236 /// during type inference to compute the [ClosedWorld] for code generation. | 225 /// during type inference to compute the [ClosedWorld] for code generation. |
| 237 abstract class ClosedWorldRefiner { | 226 abstract class ClosedWorldRefiner { |
| 238 /// Registers the side [effects] of executing [element]. | 227 /// Registers the side [effects] of executing [element]. |
| 239 void registerSideEffects(Element element, SideEffects effects); | 228 void registerSideEffects(Element element, SideEffects effects); |
| 240 | 229 |
| 241 /// Registers the executing of [element] as without side effects. | 230 /// Registers the executing of [element] as without side effects. |
| 242 void registerSideEffectsFree(Element element); | 231 void registerSideEffectsFree(Element element); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 258 void addFunctionCalledInLoop(Element element); | 247 void addFunctionCalledInLoop(Element element); |
| 259 | 248 |
| 260 /// Registers that [element] is guaranteed not to throw an exception. | 249 /// Registers that [element] is guaranteed not to throw an exception. |
| 261 void registerCannotThrow(Element element); | 250 void registerCannotThrow(Element element); |
| 262 | 251 |
| 263 /// Adds the closure class [cls] to the inference world. The class is | 252 /// Adds the closure class [cls] to the inference world. The class is |
| 264 /// considered directly instantiated. | 253 /// considered directly instantiated. |
| 265 void registerClosureClass(ClassElement cls); | 254 void registerClosureClass(ClassElement cls); |
| 266 } | 255 } |
| 267 | 256 |
| 268 abstract class OpenWorld implements ClassWorld { | 257 abstract class OpenWorld implements World { |
| 269 /// Called to add [cls] to the set of known classes. | 258 /// Called to add [cls] to the set of known classes. |
| 270 /// | 259 /// |
| 271 /// This ensures that class hierarchy queries can be performed on [cls] and | 260 /// This ensures that class hierarchy queries can be performed on [cls] and |
| 272 /// classes that extend or implement it. | 261 /// classes that extend or implement it. |
| 273 void registerClass(ClassElement cls); | 262 void registerClass(ClassElement cls); |
| 274 | 263 |
| 275 void registerUsedElement(Element element); | 264 void registerUsedElement(Element element); |
| 276 void registerTypedef(TypedefElement typedef); | 265 void registerTypedef(TypedefElement typedef); |
| 277 | 266 |
| 278 ClosedWorld closeWorld(); | 267 ClosedWorld closeWorld(); |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 void registerTypedef(TypedefElement typdef) { | 731 void registerTypedef(TypedefElement typdef) { |
| 743 _allTypedefs.add(typdef); | 732 _allTypedefs.add(typdef); |
| 744 } | 733 } |
| 745 | 734 |
| 746 Iterable<TypedefElement> get allTypedefs => _allTypedefs; | 735 Iterable<TypedefElement> get allTypedefs => _allTypedefs; |
| 747 | 736 |
| 748 /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies | 737 /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies |
| 749 /// of known classes. | 738 /// of known classes. |
| 750 /// | 739 /// |
| 751 /// This method is only provided for testing. For queries on classes, use the | 740 /// This method is only provided for testing. For queries on classes, use the |
| 752 /// methods defined in [ClassWorld]. | 741 /// methods defined in [ClosedWorld]. |
| 753 ClassHierarchyNode getClassHierarchyNode(ClassElement cls) { | 742 ClassHierarchyNode getClassHierarchyNode(ClassElement cls) { |
| 754 return _classHierarchyNodes[cls.declaration]; | 743 return _classHierarchyNodes[cls.declaration]; |
| 755 } | 744 } |
| 756 | 745 |
| 757 ClassHierarchyNode _ensureClassHierarchyNode(ClassElement cls) { | 746 ClassHierarchyNode _ensureClassHierarchyNode(ClassElement cls) { |
| 758 cls = cls.declaration; | 747 cls = cls.declaration; |
| 759 return _classHierarchyNodes.putIfAbsent(cls, () { | 748 return _classHierarchyNodes.putIfAbsent(cls, () { |
| 760 ClassHierarchyNode parentNode; | 749 ClassHierarchyNode parentNode; |
| 761 if (cls.superclass != null) { | 750 if (cls.superclass != null) { |
| 762 parentNode = _ensureClassHierarchyNode(cls.superclass); | 751 parentNode = _ensureClassHierarchyNode(cls.superclass); |
| 763 } | 752 } |
| 764 return new ClassHierarchyNode(parentNode, cls); | 753 return new ClassHierarchyNode(parentNode, cls); |
| 765 }); | 754 }); |
| 766 } | 755 } |
| 767 | 756 |
| 768 /// Returns [ClassSet] for [cls] used to model the extends and implements | 757 /// Returns [ClassSet] for [cls] used to model the extends and implements |
| 769 /// relations of known classes. | 758 /// relations of known classes. |
| 770 /// | 759 /// |
| 771 /// This method is only provided for testing. For queries on classes, use the | 760 /// This method is only provided for testing. For queries on classes, use the |
| 772 /// methods defined in [ClassWorld]. | 761 /// methods defined in [ClosedWorld]. |
| 773 ClassSet getClassSet(ClassElement cls) { | 762 ClassSet getClassSet(ClassElement cls) { |
| 774 return _classSets[cls.declaration]; | 763 return _classSets[cls.declaration]; |
| 775 } | 764 } |
| 776 | 765 |
| 777 ClassSet _ensureClassSet(ClassElement cls) { | 766 ClassSet _ensureClassSet(ClassElement cls) { |
| 778 cls = cls.declaration; | 767 cls = cls.declaration; |
| 779 return _classSets.putIfAbsent(cls, () { | 768 return _classSets.putIfAbsent(cls, () { |
| 780 ClassHierarchyNode node = _ensureClassHierarchyNode(cls); | 769 ClassHierarchyNode node = _ensureClassHierarchyNode(cls); |
| 781 ClassSet classSet = new ClassSet(node); | 770 ClassSet classSet = new ClassSet(node); |
| 782 | 771 |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1017 if (element is SynthesizedCallMethodElementX) { | 1006 if (element is SynthesizedCallMethodElementX) { |
| 1018 return getMightBePassedToApply(element.expression); | 1007 return getMightBePassedToApply(element.expression); |
| 1019 } | 1008 } |
| 1020 return functionsThatMightBePassedToApply.contains(element); | 1009 return functionsThatMightBePassedToApply.contains(element); |
| 1021 } | 1010 } |
| 1022 | 1011 |
| 1023 @override | 1012 @override |
| 1024 bool getCurrentlyKnownMightBePassedToApply(Element element) { | 1013 bool getCurrentlyKnownMightBePassedToApply(Element element) { |
| 1025 return getMightBePassedToApply(element); | 1014 return getMightBePassedToApply(element); |
| 1026 } | 1015 } |
| 1027 | |
| 1028 bool get hasClosedWorldAssumption => !_compiler.options.hasIncrementalSupport; | |
| 1029 } | 1016 } |
| OLD | NEW |