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

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

Issue 1182053010: Revert "Split TypedSelector into Selector and TypeMask." (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 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
83 class Universe { 17 class Universe {
84 /// The set of all directly instantiated classes, that is, classes with a 18 /// The set of all directly instantiated classes, that is, classes with a
85 /// generative constructor that has been called directly and not only through 19 /// generative constructor that has been called directly and not only through
86 /// a super-call. 20 /// a super-call.
87 /// 21 ///
88 /// Invariant: Elements are declaration elements. 22 /// Invariant: Elements are declaration elements.
89 // TODO(johnniwinther): [_directlyInstantiatedClasses] and 23 // TODO(johnniwinther): [_directlyInstantiatedClasses] and
90 // [_instantiatedTypes] sets should be merged. 24 // [_instantiatedTypes] sets should be merged.
91 final Set<ClassElement> _directlyInstantiatedClasses = 25 final Set<ClassElement> _directlyInstantiatedClasses =
92 new Set<ClassElement>(); 26 new Set<ClassElement>();
(...skipping 17 matching lines...) Expand all
110 44
111 /** 45 /**
112 * Documentation wanted -- johnniwinther 46 * Documentation wanted -- johnniwinther
113 * 47 *
114 * Invariant: Elements are declaration elements. 48 * Invariant: Elements are declaration elements.
115 */ 49 */
116 final Set<FunctionElement> staticFunctionsNeedingGetter = 50 final Set<FunctionElement> staticFunctionsNeedingGetter =
117 new Set<FunctionElement>(); 51 new Set<FunctionElement>();
118 final Set<FunctionElement> methodsNeedingSuperGetter = 52 final Set<FunctionElement> methodsNeedingSuperGetter =
119 new Set<FunctionElement>(); 53 new Set<FunctionElement>();
120 final Map<String, Map<Selector, TypeMaskSet>> _invokedNames = 54 final Map<String, Set<Selector>> invokedNames =
121 <String, Map<Selector, TypeMaskSet>>{}; 55 new Map<String, Set<Selector>>();
122 final Map<String, Map<Selector, TypeMaskSet>> _invokedGetters = 56 final Map<String, Set<Selector>> invokedGetters =
123 <String, Map<Selector, TypeMaskSet>>{}; 57 new Map<String, Set<Selector>>();
124 final Map<String, Map<Selector, TypeMaskSet>> _invokedSetters = 58 final Map<String, Set<Selector>> invokedSetters =
125 <String, Map<Selector, TypeMaskSet>>{}; 59 new Map<String, Set<Selector>>();
126 60
127 /** 61 /**
128 * Fields accessed. Currently only the codegen knows this 62 * Fields accessed. Currently only the codegen knows this
129 * information. The resolver is too conservative when seeing a 63 * information. The resolver is too conservative when seeing a
130 * getter and only registers an invoked getter. 64 * getter and only registers an invoked getter.
131 */ 65 */
132 final Set<Element> fieldGetters = new Set<Element>(); 66 final Set<Element> fieldGetters = new Set<Element>();
133 67
134 /** 68 /**
135 * Fields set. See comment in [fieldGetters]. 69 * Fields set. See comment in [fieldGetters].
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 _directlyInstantiatedClasses.add(cls); 152 _directlyInstantiatedClasses.add(cls);
219 } 153 }
220 154
221 // TODO(johnniwinther): Replace this by separate more specific mappings. 155 // TODO(johnniwinther): Replace this by separate more specific mappings.
222 if (!_allInstantiatedClasses.add(cls)) return; 156 if (!_allInstantiatedClasses.add(cls)) return;
223 cls.allSupertypes.forEach((InterfaceType supertype) { 157 cls.allSupertypes.forEach((InterfaceType supertype) {
224 _allInstantiatedClasses.add(supertype.element); 158 _allInstantiatedClasses.add(supertype.element);
225 }); 159 });
226 } 160 }
227 161
228 bool _hasMatchingSelector(Map<Selector, TypeMaskSet> selectors, 162 bool hasMatchingSelector(Set<Selector> selectors,
229 Element member, 163 Element member,
230 World world) { 164 World world) {
231 if (selectors == null) return false; 165 if (selectors == null) return false;
232 for (Selector selector in selectors.keys) { 166 for (Selector selector in selectors) {
233 if (selector.appliesUnnamed(member, world)) { 167 if (selector.appliesUnnamed(member, world)) return true;
234 TypeMaskSet masks = selectors[selector];
235 if (masks.applies(member, selector, world)) {
236 return true;
237 }
238 }
239 } 168 }
240 return false; 169 return false;
241 } 170 }
242 171
243 bool hasInvocation(Element member, World world) { 172 bool hasInvocation(Element member, World world) {
244 return _hasMatchingSelector(_invokedNames[member.name], member, world); 173 return hasMatchingSelector(invokedNames[member.name], member, world);
245 } 174 }
246 175
247 bool hasInvokedGetter(Element member, World world) { 176 bool hasInvokedGetter(Element member, World world) {
248 return _hasMatchingSelector(_invokedGetters[member.name], member, world); 177 return hasMatchingSelector(invokedGetters[member.name], member, world);
249 } 178 }
250 179
251 bool hasInvokedSetter(Element member, World world) { 180 bool hasInvokedSetter(Element member, World world) {
252 return _hasMatchingSelector(_invokedSetters[member.name], member, world); 181 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);
297 } 182 }
298 183
299 DartType registerIsCheck(DartType type, Compiler compiler) { 184 DartType registerIsCheck(DartType type, Compiler compiler) {
300 type = type.unalias(compiler); 185 type = type.unalias(compiler);
301 // Even in checked mode, type annotations for return type and argument 186 // Even in checked mode, type annotations for return type and argument
302 // types do not imply type checks, so there should never be a check 187 // types do not imply type checks, so there should never be a check
303 // against the type variable of a typedef. 188 // against the type variable of a typedef.
304 isChecks.add(type); 189 isChecks.add(type);
305 return type; 190 return type;
306 } 191 }
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 Name name, 561 Name name,
677 CallStructure callStructure) { 562 CallStructure callStructure) {
678 // TODO(johnniwinther): Maybe use equality instead of implicit hashing. 563 // TODO(johnniwinther): Maybe use equality instead of implicit hashing.
679 int hashCode = computeHashCode(kind, name, callStructure); 564 int hashCode = computeHashCode(kind, name, callStructure);
680 List<Selector> list = canonicalizedValues.putIfAbsent(hashCode, 565 List<Selector> list = canonicalizedValues.putIfAbsent(hashCode,
681 () => <Selector>[]); 566 () => <Selector>[]);
682 for (int i = 0; i < list.length; i++) { 567 for (int i = 0; i < list.length; i++) {
683 Selector existing = list[i]; 568 Selector existing = list[i];
684 if (existing.match(kind, name, callStructure)) { 569 if (existing.match(kind, name, callStructure)) {
685 assert(existing.hashCode == hashCode); 570 assert(existing.hashCode == hashCode);
571 assert(existing.mask == null);
686 return existing; 572 return existing;
687 } 573 }
688 } 574 }
689 Selector result = new Selector.internal( 575 Selector result = new Selector.internal(
690 kind, name, callStructure, hashCode); 576 kind, name, callStructure, hashCode);
691 list.add(result); 577 list.add(result);
692 return result; 578 return result;
693 } 579 }
694 580
695 factory Selector.fromElement(Element element) { 581 factory Selector.fromElement(Element element) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 686
801 bool get isIndex => kind == SelectorKind.INDEX && argumentCount == 1; 687 bool get isIndex => kind == SelectorKind.INDEX && argumentCount == 1;
802 bool get isIndexSet => kind == SelectorKind.INDEX && argumentCount == 2; 688 bool get isIndexSet => kind == SelectorKind.INDEX && argumentCount == 2;
803 689
804 bool get isOperator => kind == SelectorKind.OPERATOR; 690 bool get isOperator => kind == SelectorKind.OPERATOR;
805 bool get isUnaryOperator => isOperator && argumentCount == 0; 691 bool get isUnaryOperator => isOperator && argumentCount == 0;
806 692
807 /** Check whether this is a call to 'assert'. */ 693 /** Check whether this is a call to 'assert'. */
808 bool get isAssert => isCall && identical(name, "assert"); 694 bool get isAssert => isCall && identical(name, "assert");
809 695
696 bool get hasExactMask => false;
697 TypeMask get mask => null;
698 Selector get asUntyped => this;
699
810 /** 700 /**
811 * The member name for invocation mirrors created from this selector. 701 * The member name for invocation mirrors created from this selector.
812 */ 702 */
813 String get invocationMirrorMemberName => 703 String get invocationMirrorMemberName =>
814 isSetter ? '$name=' : name; 704 isSetter ? '$name=' : name;
815 705
816 int get invocationMirrorKind { 706 int get invocationMirrorKind {
817 const int METHOD = 0; 707 const int METHOD = 0;
818 const int GETTER = 1; 708 const int GETTER = 1;
819 const int SETTER = 2; 709 const int SETTER = 2;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 static int computeHashCode(SelectorKind kind, 769 static int computeHashCode(SelectorKind kind,
880 Name name, 770 Name name,
881 CallStructure callStructure) { 771 CallStructure callStructure) {
882 // Add bits from name and kind. 772 // Add bits from name and kind.
883 int hash = Hashing.mixHashCodeBits(name.hashCode, kind.hashCode); 773 int hash = Hashing.mixHashCodeBits(name.hashCode, kind.hashCode);
884 // Add bits from the call structure. 774 // Add bits from the call structure.
885 return Hashing.mixHashCodeBits(hash, callStructure.hashCode); 775 return Hashing.mixHashCodeBits(hash, callStructure.hashCode);
886 } 776 }
887 777
888 String toString() { 778 String toString() {
889 return 'Selector($kind, $name, ${callStructure.structureToString()})'; 779 String type = '';
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);
890 } 787 }
891 788
892 Selector toCallSelector() => new Selector.callClosureFrom(this); 789 Selector toCallSelector() => new Selector.callClosureFrom(this);
893 } 790 }
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