| 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; |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 /// | 164 /// |
| 165 /// If [cls] is provided, the dump will contain only classes related to [cls]. | 165 /// If [cls] is provided, the dump will contain only classes related to [cls]. |
| 166 String dump([ClassElement cls]); | 166 String dump([ClassElement cls]); |
| 167 | 167 |
| 168 /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies | 168 /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies |
| 169 /// of known classes. | 169 /// of known classes. |
| 170 /// | 170 /// |
| 171 /// This method is only provided for testing. For queries on classes, use the | 171 /// This method is only provided for testing. For queries on classes, use the |
| 172 /// methods defined in [ClassWorld]. | 172 /// methods defined in [ClassWorld]. |
| 173 ClassHierarchyNode getClassHierarchyNode(ClassElement cls); | 173 ClassHierarchyNode getClassHierarchyNode(ClassElement cls); |
| 174 |
| 175 /// Returns [ClassSet] for [cls] used to model the extends and implements |
| 176 /// relations of known classes. |
| 177 /// |
| 178 /// This method is only provided for testing. For queries on classes, use the |
| 179 /// methods defined in [ClassWorld]. |
| 180 ClassSet getClassSet(ClassElement cls); |
| 181 |
| 182 // TODO(johnniwinther): Find a better strategy for caching these. |
| 183 @deprecated |
| 184 List<Map<ClassElement, TypeMask>> get canonicalizedTypeMasks; |
| 174 } | 185 } |
| 175 | 186 |
| 176 abstract class ClosedWorld extends ClassWorld { | 187 abstract class ClosedWorld extends ClassWorld { |
| 177 /// Returns the [FunctionSet] containing all live functions in the closed | 188 /// Returns the [FunctionSet] containing all live functions in the closed |
| 178 /// world. | 189 /// world. |
| 179 FunctionSet get allFunctions; | 190 FunctionSet get allFunctions; |
| 180 | 191 |
| 181 /// Returns `true` if the field [element] is known to be effectively final. | 192 /// Returns `true` if the field [element] is known to be effectively final. |
| 182 bool fieldNeverChanges(Element element); | 193 bool fieldNeverChanges(Element element); |
| 183 | 194 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 void addFunctionCalledInLoop(Element element); | 252 void addFunctionCalledInLoop(Element element); |
| 242 | 253 |
| 243 /// Registers that [element] is guaranteed not to throw an exception. | 254 /// Registers that [element] is guaranteed not to throw an exception. |
| 244 void registerCannotThrow(Element element); | 255 void registerCannotThrow(Element element); |
| 245 | 256 |
| 246 /// Adds the closure class [cls] to the inference world. The class is | 257 /// Adds the closure class [cls] to the inference world. The class is |
| 247 /// considered directly instantiated. | 258 /// considered directly instantiated. |
| 248 void registerClosureClass(ClassElement cls); | 259 void registerClosureClass(ClassElement cls); |
| 249 } | 260 } |
| 250 | 261 |
| 251 class World implements ClosedWorld, InferenceWorld { | 262 abstract class OpenWorld implements ClassWorld { |
| 263 /// Called to add [cls] to the set of known classes. |
| 264 /// |
| 265 /// This ensures that class hierarchy queries can be performed on [cls] and |
| 266 /// classes that extend or implement it. |
| 267 void registerClass(ClassElement cls); |
| 268 |
| 269 void registerUsedElement(Element element); |
| 270 void registerTypedef(TypedefElement typedef); |
| 271 |
| 272 ClosedWorld populate(); |
| 273 |
| 274 /// Returns an iterable over all mixin applications that mixin [cls]. |
| 275 Iterable<MixinApplicationElement> allMixinUsesOf(ClassElement cls); |
| 276 } |
| 277 |
| 278 class WorldImpl implements ClosedWorld, InferenceWorld, OpenWorld { |
| 252 /// Cache of [FlatTypeMask]s grouped by the 8 possible values of the | 279 /// Cache of [FlatTypeMask]s grouped by the 8 possible values of the |
| 253 /// `FlatTypeMask.flags` property. | 280 /// `FlatTypeMask.flags` property. |
| 254 List<Map<ClassElement, TypeMask>> canonicalizedTypeMasks = | 281 List<Map<ClassElement, TypeMask>> canonicalizedTypeMasks = |
| 255 new List<Map<ClassElement, TypeMask>>.filled(8, null); | 282 new List<Map<ClassElement, TypeMask>>.filled(8, null); |
| 256 | 283 |
| 257 bool checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) { | 284 bool checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) { |
| 258 return invariant(cls, cls.isDeclaration, | 285 return invariant(cls, cls.isDeclaration, |
| 259 message: '$cls must be the declaration.') && | 286 message: '$cls must be the declaration.') && |
| 260 invariant(cls, cls.isResolved, | 287 invariant(cls, cls.isResolved, |
| 261 message: | 288 message: |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 return subclasses.contains(type); | 626 return subclasses.contains(type); |
| 600 } | 627 } |
| 601 | 628 |
| 602 final Compiler _compiler; | 629 final Compiler _compiler; |
| 603 Backend get backend => _compiler.backend; | 630 Backend get backend => _compiler.backend; |
| 604 CommonMasks get commonMasks => _compiler.commonMasks; | 631 CommonMasks get commonMasks => _compiler.commonMasks; |
| 605 final FunctionSet allFunctions; | 632 final FunctionSet allFunctions; |
| 606 final Set<Element> functionsCalledInLoop = new Set<Element>(); | 633 final Set<Element> functionsCalledInLoop = new Set<Element>(); |
| 607 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); | 634 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); |
| 608 | 635 |
| 609 final Set<TypedefElement> allTypedefs = new Set<TypedefElement>(); | 636 final Set<TypedefElement> _allTypedefs = new Set<TypedefElement>(); |
| 610 | 637 |
| 611 final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses = | 638 final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses = |
| 612 new Map<ClassElement, Set<MixinApplicationElement>>(); | 639 new Map<ClassElement, Set<MixinApplicationElement>>(); |
| 613 Map<ClassElement, List<MixinApplicationElement>> _liveMixinUses; | 640 Map<ClassElement, List<MixinApplicationElement>> _liveMixinUses; |
| 614 | 641 |
| 615 final Map<ClassElement, Set<ClassElement>> _typesImplementedBySubclasses = | 642 final Map<ClassElement, Set<ClassElement>> _typesImplementedBySubclasses = |
| 616 new Map<ClassElement, Set<ClassElement>>(); | 643 new Map<ClassElement, Set<ClassElement>>(); |
| 617 | 644 |
| 618 // We keep track of subtype and subclass relationships in four | 645 // We keep track of subtype and subclass relationships in four |
| 619 // distinct sets to make class hierarchy analysis faster. | 646 // distinct sets to make class hierarchy analysis faster. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 637 | 664 |
| 638 // Used by selectors. | 665 // Used by selectors. |
| 639 bool isForeign(Element element) { | 666 bool isForeign(Element element) { |
| 640 return backend.isForeign(element); | 667 return backend.isForeign(element); |
| 641 } | 668 } |
| 642 | 669 |
| 643 Set<ClassElement> typesImplementedBySubclassesOf(ClassElement cls) { | 670 Set<ClassElement> typesImplementedBySubclassesOf(ClassElement cls) { |
| 644 return _typesImplementedBySubclasses[cls.declaration]; | 671 return _typesImplementedBySubclasses[cls.declaration]; |
| 645 } | 672 } |
| 646 | 673 |
| 647 World(Compiler compiler) | 674 WorldImpl(Compiler compiler) |
| 648 : allFunctions = new FunctionSet(compiler), | 675 : allFunctions = new FunctionSet(compiler), |
| 649 this._compiler = compiler, | 676 this._compiler = compiler, |
| 650 alreadyPopulated = compiler.cacheStrategy.newSet(); | 677 alreadyPopulated = compiler.cacheStrategy.newSet(); |
| 651 | 678 |
| 652 CoreClasses get coreClasses => _compiler.coreClasses; | 679 CoreClasses get coreClasses => _compiler.coreClasses; |
| 653 | 680 |
| 654 DiagnosticReporter get reporter => _compiler.reporter; | 681 DiagnosticReporter get reporter => _compiler.reporter; |
| 655 | 682 |
| 656 /// Called to add [cls] to the set of known classes. | 683 /// Called to add [cls] to the set of known classes. |
| 657 /// | 684 /// |
| 658 /// This ensures that class hierarchy queries can be performed on [cls] and | 685 /// This ensures that class hierarchy queries can be performed on [cls] and |
| 659 /// classes that extend or implement it. | 686 /// classes that extend or implement it. |
| 660 void registerClass(ClassElement cls) => _registerClass(cls); | 687 void registerClass(ClassElement cls) => _registerClass(cls); |
| 661 | 688 |
| 662 void registerClosureClass(ClassElement cls) { | 689 void registerClosureClass(ClassElement cls) { |
| 663 _registerClass(cls, isDirectlyInstantiated: true); | 690 _registerClass(cls, isDirectlyInstantiated: true); |
| 664 } | 691 } |
| 665 | 692 |
| 666 void _registerClass(ClassElement cls, {bool isDirectlyInstantiated: false}) { | 693 void _registerClass(ClassElement cls, {bool isDirectlyInstantiated: false}) { |
| 667 _ensureClassSet(cls); | 694 _ensureClassSet(cls); |
| 668 if (isDirectlyInstantiated) { | 695 if (isDirectlyInstantiated) { |
| 669 _updateClassHierarchyNodeForClass(cls, directlyInstantiated: true); | 696 _updateClassHierarchyNodeForClass(cls, directlyInstantiated: true); |
| 670 } | 697 } |
| 671 } | 698 } |
| 672 | 699 |
| 700 void registerTypedef(TypedefElement typdef) { |
| 701 _allTypedefs.add(typdef); |
| 702 } |
| 703 |
| 704 Iterable<TypedefElement> get allTypedefs => _allTypedefs; |
| 705 |
| 673 /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies | 706 /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies |
| 674 /// of known classes. | 707 /// of known classes. |
| 675 /// | 708 /// |
| 676 /// This method is only provided for testing. For queries on classes, use the | 709 /// This method is only provided for testing. For queries on classes, use the |
| 677 /// methods defined in [ClassWorld]. | 710 /// methods defined in [ClassWorld]. |
| 678 ClassHierarchyNode getClassHierarchyNode(ClassElement cls) { | 711 ClassHierarchyNode getClassHierarchyNode(ClassElement cls) { |
| 679 return _classHierarchyNodes[cls.declaration]; | 712 return _classHierarchyNodes[cls.declaration]; |
| 680 } | 713 } |
| 681 | 714 |
| 682 ClassHierarchyNode _ensureClassHierarchyNode(ClassElement cls) { | 715 ClassHierarchyNode _ensureClassHierarchyNode(ClassElement cls) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 | 773 |
| 741 void _updateClassHierarchyNodeForClass(ClassElement cls, | 774 void _updateClassHierarchyNodeForClass(ClassElement cls, |
| 742 {bool directlyInstantiated: false}) { | 775 {bool directlyInstantiated: false}) { |
| 743 ClassHierarchyNode node = getClassHierarchyNode(cls); | 776 ClassHierarchyNode node = getClassHierarchyNode(cls); |
| 744 _updateSuperClassHierarchyNodeForClass(node); | 777 _updateSuperClassHierarchyNodeForClass(node); |
| 745 if (directlyInstantiated) { | 778 if (directlyInstantiated) { |
| 746 node.isDirectlyInstantiated = true; | 779 node.isDirectlyInstantiated = true; |
| 747 } | 780 } |
| 748 } | 781 } |
| 749 | 782 |
| 750 void populate() { | 783 ClosedWorld populate() { |
| 751 /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated` | 784 /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated` |
| 752 /// properties of the [ClassHierarchyNode] for [cls]. | 785 /// properties of the [ClassHierarchyNode] for [cls]. |
| 753 | 786 |
| 754 void addSubtypes(ClassElement cls) { | 787 void addSubtypes(ClassElement cls) { |
| 755 if (_compiler.options.hasIncrementalSupport && | 788 if (_compiler.options.hasIncrementalSupport && |
| 756 !alreadyPopulated.add(cls)) { | 789 !alreadyPopulated.add(cls)) { |
| 757 return; | 790 return; |
| 758 } | 791 } |
| 759 assert(cls.isDeclaration); | 792 assert(cls.isDeclaration); |
| 760 if (!cls.isResolved) { | 793 if (!cls.isResolved) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 775 } | 808 } |
| 776 superclass = superclass.superclass; | 809 superclass = superclass.superclass; |
| 777 } | 810 } |
| 778 } | 811 } |
| 779 | 812 |
| 780 // Use the [:seenClasses:] set to include non-instantiated | 813 // Use the [:seenClasses:] set to include non-instantiated |
| 781 // classes: if the superclass of these classes require RTI, then | 814 // classes: if the superclass of these classes require RTI, then |
| 782 // they also need RTI, so that a constructor passes the type | 815 // they also need RTI, so that a constructor passes the type |
| 783 // variables to the super constructor. | 816 // variables to the super constructor. |
| 784 _compiler.resolverWorld.directlyInstantiatedClasses.forEach(addSubtypes); | 817 _compiler.resolverWorld.directlyInstantiatedClasses.forEach(addSubtypes); |
| 818 |
| 819 return this; |
| 785 } | 820 } |
| 786 | 821 |
| 787 @override | 822 @override |
| 788 String dump([ClassElement cls]) { | 823 String dump([ClassElement cls]) { |
| 789 StringBuffer sb = new StringBuffer(); | 824 StringBuffer sb = new StringBuffer(); |
| 790 if (cls != null) { | 825 if (cls != null) { |
| 791 sb.write("Classes in the closed world related to $cls:\n"); | 826 sb.write("Classes in the closed world related to $cls:\n"); |
| 792 } else { | 827 } else { |
| 793 sb.write("Instantiated classes in the closed world:\n"); | 828 sb.write("Instantiated classes in the closed world:\n"); |
| 794 } | 829 } |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 932 // function expressions's element. | 967 // function expressions's element. |
| 933 // TODO(herhut): Generate classes for function expressions earlier. | 968 // TODO(herhut): Generate classes for function expressions earlier. |
| 934 if (element is SynthesizedCallMethodElementX) { | 969 if (element is SynthesizedCallMethodElementX) { |
| 935 return getMightBePassedToApply(element.expression); | 970 return getMightBePassedToApply(element.expression); |
| 936 } | 971 } |
| 937 return functionsThatMightBePassedToApply.contains(element); | 972 return functionsThatMightBePassedToApply.contains(element); |
| 938 } | 973 } |
| 939 | 974 |
| 940 bool get hasClosedWorldAssumption => !_compiler.options.hasIncrementalSupport; | 975 bool get hasClosedWorldAssumption => !_compiler.options.hasIncrementalSupport; |
| 941 } | 976 } |
| OLD | NEW |