Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: pkg/compiler/lib/src/universe/universe.dart

Issue 1182913003: Split TypedSelector into Selector and TypeMask. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comments. Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 '../elements/elements.dart'; 7 import '../elements/elements.dart';
8 import '../dart2jslib.dart'; 8 import '../dart2jslib.dart';
9 import '../dart_types.dart'; 9 import '../dart_types.dart';
10 import '../types/types.dart'; 10 import '../types/types.dart';
11 import '../tree/tree.dart'; 11 import '../tree/tree.dart';
12 import '../util/util.dart'; 12 import '../util/util.dart';
13 13
14 part 'function_set.dart'; 14 part 'function_set.dart';
15 part 'side_effects.dart'; 15 part 'side_effects.dart';
16 16
17 class UniverseSelector {
18 final Selector selector;
19 final TypeMask mask;
20
21 UniverseSelector(this.selector, this.mask);
22
23 bool appliesUnnamed(Element element, ClassWorld world) {
24 return selector.appliesUnnamed(element, world) &&
25 (mask == null || mask.canHit(element, selector, world));
26 }
27
28 String toString() => '$selector,$mask';
29 }
30
31 abstract class TypeMaskSet {
32 bool applies(Element element, Selector selector, ClassWorld world);
33 Iterable<TypeMask> get masks;
34 }
35
36 /// An implementation of a [TypeMaskSet] that is only increasing, that is, once
37 /// a mask is added it cannot be removed.
38 class IncreasingTypeMaskSet extends TypeMaskSet {
39 bool isAll = false;
40 Set<TypeMask> _masks;
41
42 bool applies(Element element, Selector selector, ClassWorld world) {
43 if (isAll) return true;
44 if (_masks == null) return false;
45 for (TypeMask mask in _masks) {
46 if (mask.canHit(element, selector, world)) return true;
47 }
48 return false;
49 }
50
51 bool add(TypeMask mask) {
52 if (isAll) return false;
53 if (mask == null) {
54 isAll = true;
55 _masks = null;
56 return true;
57 }
58 if (_masks == null) {
59 _masks = new Setlet<TypeMask>();
60 }
61 return _masks.add(mask);
62 }
63
64 Iterable<TypeMask> get masks {
65 if (isAll) return const [null];
66 if (_masks == null) return const [];
67 return _masks;
68 }
69
70 String toString() {
71 if (isAll) {
72 return '<all>';
73 } else if (_masks != null) {
74 return '$_masks';
75 } else {
76 return '<none>';
77 }
78 }
79 }
80
81
82
17 class Universe { 83 class Universe {
18 /// The set of all directly instantiated classes, that is, classes with a 84 /// The set of all directly instantiated classes, that is, classes with a
19 /// generative constructor that has been called directly and not only through 85 /// generative constructor that has been called directly and not only through
20 /// a super-call. 86 /// a super-call.
21 /// 87 ///
22 /// Invariant: Elements are declaration elements. 88 /// Invariant: Elements are declaration elements.
23 // TODO(johnniwinther): [_directlyInstantiatedClasses] and 89 // TODO(johnniwinther): [_directlyInstantiatedClasses] and
24 // [_instantiatedTypes] sets should be merged. 90 // [_instantiatedTypes] sets should be merged.
25 final Set<ClassElement> _directlyInstantiatedClasses = 91 final Set<ClassElement> _directlyInstantiatedClasses =
26 new Set<ClassElement>(); 92 new Set<ClassElement>();
(...skipping 17 matching lines...) Expand all
44 110
45 /** 111 /**
46 * Documentation wanted -- johnniwinther 112 * Documentation wanted -- johnniwinther
47 * 113 *
48 * Invariant: Elements are declaration elements. 114 * Invariant: Elements are declaration elements.
49 */ 115 */
50 final Set<FunctionElement> staticFunctionsNeedingGetter = 116 final Set<FunctionElement> staticFunctionsNeedingGetter =
51 new Set<FunctionElement>(); 117 new Set<FunctionElement>();
52 final Set<FunctionElement> methodsNeedingSuperGetter = 118 final Set<FunctionElement> methodsNeedingSuperGetter =
53 new Set<FunctionElement>(); 119 new Set<FunctionElement>();
54 final Map<String, Set<Selector>> invokedNames = 120 final Map<String, Map<Selector, TypeMaskSet>> _invokedNames =
55 new Map<String, Set<Selector>>(); 121 <String, Map<Selector, TypeMaskSet>>{};
56 final Map<String, Set<Selector>> invokedGetters = 122 final Map<String, Map<Selector, TypeMaskSet>> _invokedGetters =
57 new Map<String, Set<Selector>>(); 123 <String, Map<Selector, TypeMaskSet>>{};
58 final Map<String, Set<Selector>> invokedSetters = 124 final Map<String, Map<Selector, TypeMaskSet>> _invokedSetters =
59 new Map<String, Set<Selector>>(); 125 <String, Map<Selector, TypeMaskSet>>{};
60 126
61 /** 127 /**
62 * Fields accessed. Currently only the codegen knows this 128 * Fields accessed. Currently only the codegen knows this
63 * information. The resolver is too conservative when seeing a 129 * information. The resolver is too conservative when seeing a
64 * getter and only registers an invoked getter. 130 * getter and only registers an invoked getter.
65 */ 131 */
66 final Set<Element> fieldGetters = new Set<Element>(); 132 final Set<Element> fieldGetters = new Set<Element>();
67 133
68 /** 134 /**
69 * Fields set. See comment in [fieldGetters]. 135 * Fields set. See comment in [fieldGetters].
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 _directlyInstantiatedClasses.add(cls); 218 _directlyInstantiatedClasses.add(cls);
153 } 219 }
154 220
155 // TODO(johnniwinther): Replace this by separate more specific mappings. 221 // TODO(johnniwinther): Replace this by separate more specific mappings.
156 if (!_allInstantiatedClasses.add(cls)) return; 222 if (!_allInstantiatedClasses.add(cls)) return;
157 cls.allSupertypes.forEach((InterfaceType supertype) { 223 cls.allSupertypes.forEach((InterfaceType supertype) {
158 _allInstantiatedClasses.add(supertype.element); 224 _allInstantiatedClasses.add(supertype.element);
159 }); 225 });
160 } 226 }
161 227
162 bool hasMatchingSelector(Set<Selector> selectors, 228 bool _hasMatchingSelector(Map<Selector, TypeMaskSet> selectors,
163 Element member, 229 Element member,
164 World world) { 230 World world) {
165 if (selectors == null) return false; 231 if (selectors == null) return false;
166 for (Selector selector in selectors) { 232 for (Selector selector in selectors.keys) {
167 if (selector.appliesUnnamed(member, world)) return true; 233 if (selector.appliesUnnamed(member, world)) {
234 TypeMaskSet masks = selectors[selector];
235 if (masks.applies(member, selector, world)) {
236 return true;
237 }
238 }
168 } 239 }
169 return false; 240 return false;
170 } 241 }
171 242
172 bool hasInvocation(Element member, World world) { 243 bool hasInvocation(Element member, World world) {
173 return hasMatchingSelector(invokedNames[member.name], member, world); 244 return _hasMatchingSelector(_invokedNames[member.name], member, world);
174 } 245 }
175 246
176 bool hasInvokedGetter(Element member, World world) { 247 bool hasInvokedGetter(Element member, World world) {
177 return hasMatchingSelector(invokedGetters[member.name], member, world); 248 return _hasMatchingSelector(_invokedGetters[member.name], member, world);
178 } 249 }
179 250
180 bool hasInvokedSetter(Element member, World world) { 251 bool hasInvokedSetter(Element member, World world) {
181 return hasMatchingSelector(invokedSetters[member.name], member, world); 252 return _hasMatchingSelector(_invokedSetters[member.name], member, world);
253 }
254
255 bool registerInvocation(UniverseSelector selector) {
256 return _registerNewSelector(selector, _invokedNames);
257 }
258
259 bool registerInvokedGetter(UniverseSelector selector) {
260 return _registerNewSelector(selector, _invokedGetters);
261 }
262
263 bool registerInvokedSetter(UniverseSelector selector) {
264 return _registerNewSelector(selector, _invokedSetters);
265 }
266
267 bool _registerNewSelector(
268 UniverseSelector universeSelector,
269 Map<String, Map<Selector, TypeMaskSet>> selectorMap) {
270 Selector selector = universeSelector.selector;
271 String name = selector.name;
272 TypeMask mask = universeSelector.mask;
273 Map<Selector, TypeMaskSet> selectors = selectorMap.putIfAbsent(
274 name, () => new Maplet<Selector, TypeMaskSet>());
275 IncreasingTypeMaskSet masks = selectors.putIfAbsent(
276 selector, () => new IncreasingTypeMaskSet());
277 return masks.add(mask);
278 }
279
280 Map<Selector, TypeMaskSet> invocationsByName(String name) {
281 return _invokedNames[name];
282 }
283
284 void forEachInvokedName(
285 f(String name, Map<Selector, TypeMaskSet> selectors)) {
286 _invokedNames.forEach(f);
287 }
288
289 void forEachInvokedGetter(
290 f(String name, Map<Selector, TypeMaskSet> selectors)) {
291 _invokedGetters.forEach(f);
292 }
293
294 void forEachInvokedSetter(
295 f(String name, Map<Selector, TypeMaskSet> selectors)) {
296 _invokedSetters.forEach(f);
182 } 297 }
183 298
184 DartType registerIsCheck(DartType type, Compiler compiler) { 299 DartType registerIsCheck(DartType type, Compiler compiler) {
185 type = type.unalias(compiler); 300 type = type.unalias(compiler);
186 // Even in checked mode, type annotations for return type and argument 301 // Even in checked mode, type annotations for return type and argument
187 // types do not imply type checks, so there should never be a check 302 // types do not imply type checks, so there should never be a check
188 // against the type variable of a typedef. 303 // against the type variable of a typedef.
189 isChecks.add(type); 304 isChecks.add(type);
190 return type; 305 return type;
191 } 306 }
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 Name name, 676 Name name,
562 CallStructure callStructure) { 677 CallStructure callStructure) {
563 // TODO(johnniwinther): Maybe use equality instead of implicit hashing. 678 // TODO(johnniwinther): Maybe use equality instead of implicit hashing.
564 int hashCode = computeHashCode(kind, name, callStructure); 679 int hashCode = computeHashCode(kind, name, callStructure);
565 List<Selector> list = canonicalizedValues.putIfAbsent(hashCode, 680 List<Selector> list = canonicalizedValues.putIfAbsent(hashCode,
566 () => <Selector>[]); 681 () => <Selector>[]);
567 for (int i = 0; i < list.length; i++) { 682 for (int i = 0; i < list.length; i++) {
568 Selector existing = list[i]; 683 Selector existing = list[i];
569 if (existing.match(kind, name, callStructure)) { 684 if (existing.match(kind, name, callStructure)) {
570 assert(existing.hashCode == hashCode); 685 assert(existing.hashCode == hashCode);
571 assert(existing.mask == null);
572 return existing; 686 return existing;
573 } 687 }
574 } 688 }
575 Selector result = new Selector.internal( 689 Selector result = new Selector.internal(
576 kind, name, callStructure, hashCode); 690 kind, name, callStructure, hashCode);
577 list.add(result); 691 list.add(result);
578 return result; 692 return result;
579 } 693 }
580 694
581 factory Selector.fromElement(Element element) { 695 factory Selector.fromElement(Element element) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 800
687 bool get isIndex => kind == SelectorKind.INDEX && argumentCount == 1; 801 bool get isIndex => kind == SelectorKind.INDEX && argumentCount == 1;
688 bool get isIndexSet => kind == SelectorKind.INDEX && argumentCount == 2; 802 bool get isIndexSet => kind == SelectorKind.INDEX && argumentCount == 2;
689 803
690 bool get isOperator => kind == SelectorKind.OPERATOR; 804 bool get isOperator => kind == SelectorKind.OPERATOR;
691 bool get isUnaryOperator => isOperator && argumentCount == 0; 805 bool get isUnaryOperator => isOperator && argumentCount == 0;
692 806
693 /** Check whether this is a call to 'assert'. */ 807 /** Check whether this is a call to 'assert'. */
694 bool get isAssert => isCall && identical(name, "assert"); 808 bool get isAssert => isCall && identical(name, "assert");
695 809
696 bool get hasExactMask => false;
697 TypeMask get mask => null;
698 Selector get asUntyped => this;
699
700 /** 810 /**
701 * The member name for invocation mirrors created from this selector. 811 * The member name for invocation mirrors created from this selector.
702 */ 812 */
703 String get invocationMirrorMemberName => 813 String get invocationMirrorMemberName =>
704 isSetter ? '$name=' : name; 814 isSetter ? '$name=' : name;
705 815
706 int get invocationMirrorKind { 816 int get invocationMirrorKind {
707 const int METHOD = 0; 817 const int METHOD = 0;
708 const int GETTER = 1; 818 const int GETTER = 1;
709 const int SETTER = 2; 819 const int SETTER = 2;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 static int computeHashCode(SelectorKind kind, 879 static int computeHashCode(SelectorKind kind,
770 Name name, 880 Name name,
771 CallStructure callStructure) { 881 CallStructure callStructure) {
772 // Add bits from name and kind. 882 // Add bits from name and kind.
773 int hash = Hashing.mixHashCodeBits(name.hashCode, kind.hashCode); 883 int hash = Hashing.mixHashCodeBits(name.hashCode, kind.hashCode);
774 // Add bits from the call structure. 884 // Add bits from the call structure.
775 return Hashing.mixHashCodeBits(hash, callStructure.hashCode); 885 return Hashing.mixHashCodeBits(hash, callStructure.hashCode);
776 } 886 }
777 887
778 String toString() { 888 String toString() {
779 String type = ''; 889 return 'Selector($kind, $name, ${callStructure.structureToString()})';
780 if (mask != null) type = ', mask=$mask';
781 return 'Selector($kind, $name, ${callStructure.structureToString()}$type)';
782 }
783
784 Selector extendIfReachesAll(Compiler compiler) {
785 return new TypedSelector(
786 compiler.typesTask.dynamicType, this, compiler.world);
787 } 890 }
788 891
789 Selector toCallSelector() => new Selector.callClosureFrom(this); 892 Selector toCallSelector() => new Selector.callClosureFrom(this);
790 } 893 }
791
792 class TypedSelector extends Selector {
793 final Selector asUntyped;
794 final TypeMask mask;
795
796 TypedSelector.internal(this.mask, Selector selector, int hashCode)
797 : asUntyped = selector,
798 super.internal(selector.kind,
799 selector.memberName,
800 selector.callStructure,
801 hashCode) {
802 assert(mask != null);
803 assert(asUntyped.mask == null);
804 }
805
806
807 factory TypedSelector(TypeMask mask, Selector selector, World world) {
808 if (!world.hasClosedWorldAssumption) {
809 // TODO(johnniwinther): Improve use of TypedSelector in an open world.
810 bool isNullable = mask.isNullable;
811 mask = world.compiler.typesTask.dynamicType;
812 if (isNullable) {
813 mask = mask.nullable();
814 }
815 }
816 // TODO(johnniwinther): Allow more TypeSelector kinds during resoluton.
817 assert(world.isClosed || mask.isExact);
818 if (selector.mask == mask) return selector;
819 Selector untyped = selector.asUntyped;
820 Map<TypeMask, TypedSelector> map = world.canonicalizedValues
821 .putIfAbsent(untyped, () => new Map<TypeMask, TypedSelector>());
822 TypedSelector result = map[mask];
823 if (result == null) {
824 int hashCode = Hashing.mixHashCodeBits(untyped.hashCode, mask.hashCode);
825 result = map[mask] = new TypedSelector.internal(mask, untyped, hashCode);
826 }
827 return result;
828 }
829
830 factory TypedSelector.exact(
831 ClassElement base, Selector selector, World world)
832 => new TypedSelector(new TypeMask.exact(base, world), selector,
833 world);
834
835 factory TypedSelector.subclass(
836 ClassElement base, Selector selector, World world)
837 => new TypedSelector(new TypeMask.subclass(base, world),
838 selector, world);
839
840 factory TypedSelector.subtype(
841 ClassElement base, Selector selector, World world)
842 => new TypedSelector(new TypeMask.subtype(base, world),
843 selector, world);
844
845 bool appliesUnnamed(Element element, World world) {
846 assert(sameNameHack(element, world));
847 if (!mask.canHit(element, this, world)) return false;
848 return appliesUntyped(element, world);
849 }
850
851 Selector extendIfReachesAll(Compiler compiler) {
852 bool canReachAll = compiler.enabledInvokeOn
853 && mask.needsNoSuchMethodHandling(this, compiler.world);
854 return canReachAll
855 ? new TypedSelector(
856 compiler.typesTask.dynamicType, this, compiler.world)
857 : this;
858 }
859 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/universe/function_set.dart ('k') | pkg/compiler/lib/src/use_unused_api.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698