| 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 universe; | 5 library universe; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import '../cache_strategy.dart'; | |
| 10 import '../common.dart'; | 9 import '../common.dart'; |
| 11 import '../common/backend_api.dart' show Backend; | 10 import '../common/backend_api.dart' show Backend; |
| 12 import '../common/names.dart' show Identifiers; | 11 import '../common/names.dart' show Identifiers; |
| 13 import '../common/resolution.dart' show Resolution; | 12 import '../common/resolution.dart' show Resolution; |
| 14 import '../compiler.dart' show Compiler; | |
| 15 import '../core_types.dart'; | 13 import '../core_types.dart'; |
| 16 import '../elements/elements.dart'; | 14 import '../elements/elements.dart'; |
| 17 import '../elements/entities.dart'; | 15 import '../elements/entities.dart'; |
| 18 import '../elements/resolution_types.dart'; | 16 import '../elements/resolution_types.dart'; |
| 19 import '../elements/types.dart'; | 17 import '../elements/types.dart'; |
| 20 import '../universe/class_set.dart'; | 18 import '../universe/class_set.dart'; |
| 21 import '../universe/function_set.dart' show FunctionSetBuilder; | 19 import '../universe/function_set.dart' show FunctionSetBuilder; |
| 22 import '../util/enumset.dart'; | 20 import '../util/enumset.dart'; |
| 23 import '../util/util.dart'; | 21 import '../util/util.dart'; |
| 24 import '../world.dart' show World, ClosedWorld, ClosedWorldImpl, OpenWorld; | 22 import '../world.dart' show World, ClosedWorld, ClosedWorldImpl, OpenWorld; |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 | 471 |
| 474 final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses = | 472 final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses = |
| 475 new Map<ClassElement, Set<MixinApplicationElement>>(); | 473 new Map<ClassElement, Set<MixinApplicationElement>>(); |
| 476 | 474 |
| 477 // We keep track of subtype and subclass relationships in four | 475 // We keep track of subtype and subclass relationships in four |
| 478 // distinct sets to make class hierarchy analysis faster. | 476 // distinct sets to make class hierarchy analysis faster. |
| 479 final Map<ClassElement, ClassHierarchyNode> _classHierarchyNodes = | 477 final Map<ClassElement, ClassHierarchyNode> _classHierarchyNodes = |
| 480 <ClassElement, ClassHierarchyNode>{}; | 478 <ClassElement, ClassHierarchyNode>{}; |
| 481 final Map<ClassElement, ClassSet> _classSets = <ClassElement, ClassSet>{}; | 479 final Map<ClassElement, ClassSet> _classSets = <ClassElement, ClassSet>{}; |
| 482 | 480 |
| 483 final Set<Element> alreadyPopulated; | |
| 484 | |
| 485 final CacheStrategy cacheStrategy; | |
| 486 | |
| 487 bool get isClosed => _closed; | 481 bool get isClosed => _closed; |
| 488 | 482 |
| 489 ResolutionWorldBuilderImpl(Backend backend, Resolution resolution, | 483 ResolutionWorldBuilderImpl( |
| 490 CacheStrategy cacheStrategy, this.selectorConstraintsStrategy) | 484 Backend backend, Resolution resolution, this.selectorConstraintsStrategy) |
| 491 : this._backend = backend, | 485 : this._backend = backend, |
| 492 this._resolution = resolution, | 486 this._resolution = resolution { |
| 493 this.cacheStrategy = cacheStrategy, | |
| 494 alreadyPopulated = cacheStrategy.newSet() { | |
| 495 _allFunctions = new FunctionSetBuilder(); | 487 _allFunctions = new FunctionSetBuilder(); |
| 496 } | 488 } |
| 497 | 489 |
| 498 Iterable<ClassElement> get processedClasses => _processedClasses.keys | 490 Iterable<ClassElement> get processedClasses => _processedClasses.keys |
| 499 .where((cls) => _processedClasses[cls].isInstantiated); | 491 .where((cls) => _processedClasses[cls].isInstantiated); |
| 500 | 492 |
| 501 CommonElements get commonElements => _resolution.commonElements; | 493 CommonElements get commonElements => _resolution.commonElements; |
| 502 | 494 |
| 503 ClosedWorld get closedWorldForTesting { | 495 ClosedWorld get closedWorldForTesting { |
| 504 if (!_closed) { | 496 if (!_closed) { |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 790 case StaticUseKind.DIRECT_INVOKE: | 782 case StaticUseKind.DIRECT_INVOKE: |
| 791 invariant( | 783 invariant( |
| 792 element, 'Direct static use is not supported for resolution.'); | 784 element, 'Direct static use is not supported for resolution.'); |
| 793 break; | 785 break; |
| 794 } | 786 } |
| 795 if (useSet.isNotEmpty) { | 787 if (useSet.isNotEmpty) { |
| 796 memberUsed(usage.entity, useSet); | 788 memberUsed(usage.entity, useSet); |
| 797 } | 789 } |
| 798 } | 790 } |
| 799 | 791 |
| 800 void forgetEntity(Entity entity, Compiler compiler) { | |
| 801 allClosures.remove(entity); | |
| 802 slowDirectlyNestedClosures(entity).forEach(compiler.forgetElement); | |
| 803 closurizedMembers.remove(entity); | |
| 804 fieldSetters.remove(entity); | |
| 805 _instantiationInfo.remove(entity); | |
| 806 | |
| 807 void removeUsage(Set<_MemberUsage> set, Entity entity) { | |
| 808 if (set == null) return; | |
| 809 set.removeAll( | |
| 810 set.where((_MemberUsage usage) => usage.entity == entity).toList()); | |
| 811 } | |
| 812 | |
| 813 _processedClasses.remove(entity); | |
| 814 removeUsage(_instanceMembersByName[entity.name], entity); | |
| 815 removeUsage(_instanceFunctionsByName[entity.name], entity); | |
| 816 } | |
| 817 | |
| 818 // TODO(ahe): Replace this method with something that is O(1), for example, | 792 // TODO(ahe): Replace this method with something that is O(1), for example, |
| 819 // by using a map. | 793 // by using a map. |
| 820 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { | 794 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { |
| 821 // Return new list to guard against concurrent modifications. | 795 // Return new list to guard against concurrent modifications. |
| 822 return new List<LocalFunctionElement>.from( | 796 return new List<LocalFunctionElement>.from( |
| 823 allClosures.where((LocalFunctionElement closure) { | 797 allClosures.where((LocalFunctionElement closure) { |
| 824 return closure.executableContext == element; | 798 return closure.executableContext == element; |
| 825 })); | 799 })); |
| 826 } | 800 } |
| 827 | 801 |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 Map<ClassElement, Set<ClassElement>> typesImplementedBySubclasses = | 1001 Map<ClassElement, Set<ClassElement>> typesImplementedBySubclasses = |
| 1028 new Map<ClassElement, Set<ClassElement>>(); | 1002 new Map<ClassElement, Set<ClassElement>>(); |
| 1029 | 1003 |
| 1030 /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated` | 1004 /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated` |
| 1031 /// properties of the [ClassHierarchyNode] for [cls]. | 1005 /// properties of the [ClassHierarchyNode] for [cls]. |
| 1032 | 1006 |
| 1033 void addSubtypes(ClassElement cls, InstantiationInfo info) { | 1007 void addSubtypes(ClassElement cls, InstantiationInfo info) { |
| 1034 if (!info.hasInstantiation) { | 1008 if (!info.hasInstantiation) { |
| 1035 return; | 1009 return; |
| 1036 } | 1010 } |
| 1037 if (cacheStrategy.hasIncrementalSupport && !alreadyPopulated.add(cls)) { | |
| 1038 return; | |
| 1039 } | |
| 1040 assert(cls.isDeclaration); | 1011 assert(cls.isDeclaration); |
| 1041 if (!cls.isResolved) { | 1012 if (!cls.isResolved) { |
| 1042 reporter.internalError(cls, 'Class "${cls.name}" is not resolved.'); | 1013 reporter.internalError(cls, 'Class "${cls.name}" is not resolved.'); |
| 1043 } | 1014 } |
| 1044 | 1015 |
| 1045 _updateClassHierarchyNodeForClass(cls, | 1016 _updateClassHierarchyNodeForClass(cls, |
| 1046 directlyInstantiated: info.isDirectlyInstantiated, | 1017 directlyInstantiated: info.isDirectlyInstantiated, |
| 1047 abstractlyInstantiated: info.isAbstractlyInstantiated); | 1018 abstractlyInstantiated: info.isAbstractlyInstantiated); |
| 1048 | 1019 |
| 1049 // Walk through the superclasses, and record the types | 1020 // Walk through the superclasses, and record the types |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1498 _getMemberUsage(staticUse.element, memberUsed); | 1469 _getMemberUsage(staticUse.element, memberUsed); |
| 1499 memberUsed(instanceUsage.entity, instanceUsage.invoke()); | 1470 memberUsed(instanceUsage.entity, instanceUsage.invoke()); |
| 1500 _instanceMembersByName[instanceUsage.entity.name] | 1471 _instanceMembersByName[instanceUsage.entity.name] |
| 1501 ?.remove(instanceUsage); | 1472 ?.remove(instanceUsage); |
| 1502 useSet.addAll(usage.normalUse()); | 1473 useSet.addAll(usage.normalUse()); |
| 1503 break; | 1474 break; |
| 1504 } | 1475 } |
| 1505 memberUsed(usage.entity, useSet); | 1476 memberUsed(usage.entity, useSet); |
| 1506 } | 1477 } |
| 1507 | 1478 |
| 1508 void forgetElement(Element element, Compiler compiler) { | |
| 1509 _processedClasses.remove(element); | |
| 1510 _directlyInstantiatedClasses.remove(element); | |
| 1511 if (element is ClassElement) { | |
| 1512 assert(invariant(element, element.thisType.isRaw, | |
| 1513 message: 'Generic classes not supported (${element.thisType}).')); | |
| 1514 _instantiatedTypes..remove(element.rawType)..remove(element.thisType); | |
| 1515 } | |
| 1516 removeFromSet(_instanceMembersByName, element); | |
| 1517 removeFromSet(_instanceFunctionsByName, element); | |
| 1518 if (element is MemberElement) { | |
| 1519 for (Element closure in element.nestedClosures) { | |
| 1520 removeFromSet(_instanceMembersByName, closure); | |
| 1521 removeFromSet(_instanceFunctionsByName, closure); | |
| 1522 } | |
| 1523 } | |
| 1524 } | |
| 1525 | |
| 1526 void processClassMembers(ClassElement cls, MemberUsedCallback memberUsed) { | 1479 void processClassMembers(ClassElement cls, MemberUsedCallback memberUsed) { |
| 1527 cls.implementation.forEachMember((_, MemberElement member) { | 1480 cls.implementation.forEachMember((_, MemberElement member) { |
| 1528 assert(invariant(member, member.isDeclaration)); | 1481 assert(invariant(member, member.isDeclaration)); |
| 1529 if (!member.isInstanceMember) return; | 1482 if (!member.isInstanceMember) return; |
| 1530 _getMemberUsage(member, memberUsed); | 1483 _getMemberUsage(member, memberUsed); |
| 1531 }); | 1484 }); |
| 1532 } | 1485 } |
| 1533 | 1486 |
| 1534 _MemberUsage _getMemberUsage( | 1487 _MemberUsage _getMemberUsage( |
| 1535 MemberElement member, MemberUsedCallback memberUsed) { | 1488 MemberElement member, MemberUsedCallback memberUsed) { |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1975 if (hasClosurization) { | 1928 if (hasClosurization) { |
| 1976 return MemberUses.NONE; | 1929 return MemberUses.NONE; |
| 1977 } | 1930 } |
| 1978 hasNormalUse = hasClosurization = true; | 1931 hasNormalUse = hasClosurization = true; |
| 1979 return _pendingUse.removeAll(MemberUses.ALL_STATIC); | 1932 return _pendingUse.removeAll(MemberUses.ALL_STATIC); |
| 1980 } | 1933 } |
| 1981 | 1934 |
| 1982 @override | 1935 @override |
| 1983 EnumSet<MemberUse> get _originalUse => MemberUses.ALL_STATIC; | 1936 EnumSet<MemberUse> get _originalUse => MemberUses.ALL_STATIC; |
| 1984 } | 1937 } |
| 1985 | |
| 1986 void removeFromSet(Map<String, Set<_MemberUsage>> map, Element element) { | |
| 1987 Set<_MemberUsage> set = map[element.name]; | |
| 1988 if (set == null) return; | |
| 1989 set.removeAll( | |
| 1990 set.where((_MemberUsage usage) => usage.entity == element).toList()); | |
| 1991 } | |
| OLD | NEW |