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

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

Issue 1318383002: Extract ReceiverMask interface from TypeMask. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comments. Created 5 years, 3 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
« no previous file with comments | « pkg/compiler/lib/src/types/type_mask.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 'dart:collection'; 7 import 'dart:collection';
8 8
9 import '../common/names.dart' show 9 import '../common/names.dart' show
10 Identifiers, 10 Identifiers,
11 Names, 11 Names,
12 Selectors; 12 Selectors;
13 import '../compiler.dart' show 13 import '../compiler.dart' show
14 Compiler; 14 Compiler;
15 import '../diagnostics/invariant.dart' show 15 import '../diagnostics/invariant.dart' show
16 invariant; 16 invariant;
17 import '../diagnostics/spannable.dart' show 17 import '../diagnostics/spannable.dart' show
18 SpannableAssertionFailure; 18 SpannableAssertionFailure;
19 import '../elements/elements.dart'; 19 import '../elements/elements.dart';
20 import '../dart_types.dart'; 20 import '../dart_types.dart';
21 import '../tree/tree.dart';
21 import '../types/types.dart'; 22 import '../types/types.dart';
22 import '../tree/tree.dart';
23 import '../util/util.dart'; 23 import '../util/util.dart';
24 import '../world.dart' show 24 import '../world.dart' show
25 ClassWorld, 25 ClassWorld,
26 World; 26 World;
27 27
28 part 'function_set.dart'; 28 part 'function_set.dart';
29 part 'side_effects.dart'; 29 part 'side_effects.dart';
30 30
31 class UniverseSelector { 31 class UniverseSelector {
32 final Selector selector; 32 final Selector selector;
33 final TypeMask mask; 33 final ReceiverMask mask;
34 34
35 UniverseSelector(this.selector, this.mask); 35 UniverseSelector(this.selector, this.mask);
36 36
37 bool appliesUnnamed(Element element, ClassWorld world) { 37 bool appliesUnnamed(Element element, ClassWorld world) {
38 return selector.appliesUnnamed(element, world) && 38 return selector.appliesUnnamed(element, world) &&
39 (mask == null || mask.canHit(element, selector, world)); 39 (mask == null || mask.canHit(element, selector, world));
40 } 40 }
41 41
42 String toString() => '$selector,$mask'; 42 String toString() => '$selector,$mask';
43 } 43 }
44 44
45 abstract class TypeMaskSet { 45 /// A potential receiver for a dynamic call site.
46 bool applies(Element element, Selector selector, ClassWorld world); 46 abstract class ReceiverMask {
47 Iterable<TypeMask> get masks; 47 /// Returns whether [element] is a potential target when being
48 /// invoked on this receiver mask. [selector] is used to ensure library
49 /// privacy is taken into account.
50 bool canHit(Element element, Selector selector, ClassWorld classWorld);
48 } 51 }
49 52
50 /// An implementation of a [TypeMaskSet] that is only increasing, that is, once 53 /// A set of potential receivers for the dynamic call sites of the same
51 /// a mask is added it cannot be removed. 54 /// selector.
52 class IncreasingTypeMaskSet extends TypeMaskSet { 55 ///
53 bool isAll = false; 56 /// For instance for these calls
54 Set<TypeMask> _masks; 57 ///
58 /// new A().foo(a, b);
59 /// new B().foo(0, 42);
60 ///
61 /// the receiver mask set for dynamic calls to 'foo' with to positional
62 /// arguments will contain receiver masks abstracting `new A()` and `new B()`.
63 abstract class ReceiverMaskSet {
64 /// Returns `true` if [selector] applies to any of the potential receivers
65 /// in this set given the closed [world].
66 bool applies(Element element, Selector selector, ClassWorld world);
55 67
56 bool applies(Element element, Selector selector, ClassWorld world) { 68 /// Returns `true` if any potential receivers in this set given the closed
57 if (isAll) return true; 69 /// [world] have no implementation matching [selector].
58 if (_masks == null) return false; 70 ///
59 for (TypeMask mask in _masks) { 71 /// For instance for this code snippet
60 if (mask.canHit(element, selector, world)) return true; 72 ///
61 } 73 /// class A {}
62 return false; 74 /// class B { foo() {} }
63 } 75 /// m(b) => (b ? new A() : new B()).foo();
64 76 ///
65 bool add(TypeMask mask) { 77 /// the potential receiver `new A()` have no implementation of `foo` and thus
66 if (isAll) return false; 78 /// needs to handle the call though its `noSuchMethod` handler.
67 if (mask == null) { 79 bool needsNoSuchMethodHandling(Selector selector, ClassWorld world);
68 isAll = true;
69 _masks = null;
70 return true;
71 }
72 if (_masks == null) {
73 _masks = new Setlet<TypeMask>();
74 }
75 return _masks.add(mask);
76 }
77
78 Iterable<TypeMask> get masks {
79 if (isAll) return const [null];
80 if (_masks == null) return const [];
81 return _masks;
82 }
83
84 String toString() {
85 if (isAll) {
86 return '<all>';
87 } else if (_masks != null) {
88 return '$_masks';
89 } else {
90 return '<none>';
91 }
92 }
93 } 80 }
94 81
82 /// A mutable [ReceiverMaskSet] used in [Universe].
83 abstract class UniverseReceiverMaskSet extends ReceiverMaskSet {
84 /// Adds [mask] to this set of potential receivers. Return `true` if the
85 /// set expanded due to the new mask.
86 bool addReceiverMask(ReceiverMask mask);
87 }
95 88
89 /// Strategy for computing potential receivers of dynamic call sites.
90 abstract class ReceiverMaskStrategy {
91 /// Create a [UniverseReceiverMaskSet] to represent the potential receiver for
92 /// a dynamic call site with [selector].
93 UniverseReceiverMaskSet createReceiverMaskSet(Selector selector);
94 }
96 95
97 class Universe { 96 class Universe {
98 /// The set of all directly instantiated classes, that is, classes with a 97 /// The set of all directly instantiated classes, that is, classes with a
99 /// generative constructor that has been called directly and not only through 98 /// generative constructor that has been called directly and not only through
100 /// a super-call. 99 /// a super-call.
101 /// 100 ///
102 /// Invariant: Elements are declaration elements. 101 /// Invariant: Elements are declaration elements.
103 // TODO(johnniwinther): [_directlyInstantiatedClasses] and 102 // TODO(johnniwinther): [_directlyInstantiatedClasses] and
104 // [_instantiatedTypes] sets should be merged. 103 // [_instantiatedTypes] sets should be merged.
105 final Set<ClassElement> _directlyInstantiatedClasses = 104 final Set<ClassElement> _directlyInstantiatedClasses =
(...skipping 18 matching lines...) Expand all
124 123
125 /** 124 /**
126 * Documentation wanted -- johnniwinther 125 * Documentation wanted -- johnniwinther
127 * 126 *
128 * Invariant: Elements are declaration elements. 127 * Invariant: Elements are declaration elements.
129 */ 128 */
130 final Set<FunctionElement> staticFunctionsNeedingGetter = 129 final Set<FunctionElement> staticFunctionsNeedingGetter =
131 new Set<FunctionElement>(); 130 new Set<FunctionElement>();
132 final Set<FunctionElement> methodsNeedingSuperGetter = 131 final Set<FunctionElement> methodsNeedingSuperGetter =
133 new Set<FunctionElement>(); 132 new Set<FunctionElement>();
134 final Map<String, Map<Selector, TypeMaskSet>> _invokedNames = 133 final Map<String, Map<Selector, ReceiverMaskSet>> _invokedNames =
135 <String, Map<Selector, TypeMaskSet>>{}; 134 <String, Map<Selector, ReceiverMaskSet>>{};
136 final Map<String, Map<Selector, TypeMaskSet>> _invokedGetters = 135 final Map<String, Map<Selector, ReceiverMaskSet>> _invokedGetters =
137 <String, Map<Selector, TypeMaskSet>>{}; 136 <String, Map<Selector, ReceiverMaskSet>>{};
138 final Map<String, Map<Selector, TypeMaskSet>> _invokedSetters = 137 final Map<String, Map<Selector, ReceiverMaskSet>> _invokedSetters =
139 <String, Map<Selector, TypeMaskSet>>{}; 138 <String, Map<Selector, ReceiverMaskSet>>{};
140 139
141 /** 140 /**
142 * Fields accessed. Currently only the codegen knows this 141 * Fields accessed. Currently only the codegen knows this
143 * information. The resolver is too conservative when seeing a 142 * information. The resolver is too conservative when seeing a
144 * getter and only registers an invoked getter. 143 * getter and only registers an invoked getter.
145 */ 144 */
146 final Set<Element> fieldGetters = new Set<Element>(); 145 final Set<Element> fieldGetters = new Set<Element>();
147 146
148 /** 147 /**
149 * Fields set. See comment in [fieldGetters]. 148 * Fields set. See comment in [fieldGetters].
(...skipping 21 matching lines...) Expand all
171 * to find all live closure instances. 170 * to find all live closure instances.
172 */ 171 */
173 final Set<LocalFunctionElement> allClosures = new Set<LocalFunctionElement>(); 172 final Set<LocalFunctionElement> allClosures = new Set<LocalFunctionElement>();
174 173
175 /** 174 /**
176 * Set of methods in instantiated classes that are potentially 175 * Set of methods in instantiated classes that are potentially
177 * closurized. 176 * closurized.
178 */ 177 */
179 final Set<Element> closurizedMembers = new Set<Element>(); 178 final Set<Element> closurizedMembers = new Set<Element>();
180 179
180 final ReceiverMaskStrategy receiverMaskStrategy;
181
182 Universe(this.receiverMaskStrategy);
183
181 /// All directly instantiated classes, that is, classes with a generative 184 /// All directly instantiated classes, that is, classes with a generative
182 /// constructor that has been called directly and not only through a 185 /// constructor that has been called directly and not only through a
183 /// super-call. 186 /// super-call.
184 // TODO(johnniwinther): Improve semantic precision. 187 // TODO(johnniwinther): Improve semantic precision.
185 Iterable<ClassElement> get directlyInstantiatedClasses { 188 Iterable<ClassElement> get directlyInstantiatedClasses {
186 return _directlyInstantiatedClasses; 189 return _directlyInstantiatedClasses;
187 } 190 }
188 191
189 /// All instantiated classes, either directly, as superclasses or as 192 /// All instantiated classes, either directly, as superclasses or as
190 /// supertypes. 193 /// supertypes.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 _directlyInstantiatedClasses.add(cls); 235 _directlyInstantiatedClasses.add(cls);
233 } 236 }
234 237
235 // TODO(johnniwinther): Replace this by separate more specific mappings. 238 // TODO(johnniwinther): Replace this by separate more specific mappings.
236 if (!_allInstantiatedClasses.add(cls)) return; 239 if (!_allInstantiatedClasses.add(cls)) return;
237 cls.allSupertypes.forEach((InterfaceType supertype) { 240 cls.allSupertypes.forEach((InterfaceType supertype) {
238 _allInstantiatedClasses.add(supertype.element); 241 _allInstantiatedClasses.add(supertype.element);
239 }); 242 });
240 } 243 }
241 244
242 bool _hasMatchingSelector(Map<Selector, TypeMaskSet> selectors, 245 bool _hasMatchingSelector(Map<Selector, ReceiverMaskSet> selectors,
243 Element member, 246 Element member,
244 World world) { 247 World world) {
245 if (selectors == null) return false; 248 if (selectors == null) return false;
246 for (Selector selector in selectors.keys) { 249 for (Selector selector in selectors.keys) {
247 if (selector.appliesUnnamed(member, world)) { 250 if (selector.appliesUnnamed(member, world)) {
248 TypeMaskSet masks = selectors[selector]; 251 ReceiverMaskSet masks = selectors[selector];
249 if (masks.applies(member, selector, world)) { 252 if (masks.applies(member, selector, world)) {
250 return true; 253 return true;
251 } 254 }
252 } 255 }
253 } 256 }
254 return false; 257 return false;
255 } 258 }
256 259
257 bool hasInvocation(Element member, World world) { 260 bool hasInvocation(Element member, World world) {
258 return _hasMatchingSelector(_invokedNames[member.name], member, world); 261 return _hasMatchingSelector(_invokedNames[member.name], member, world);
(...skipping 14 matching lines...) Expand all
273 bool registerInvokedGetter(UniverseSelector selector) { 276 bool registerInvokedGetter(UniverseSelector selector) {
274 return _registerNewSelector(selector, _invokedGetters); 277 return _registerNewSelector(selector, _invokedGetters);
275 } 278 }
276 279
277 bool registerInvokedSetter(UniverseSelector selector) { 280 bool registerInvokedSetter(UniverseSelector selector) {
278 return _registerNewSelector(selector, _invokedSetters); 281 return _registerNewSelector(selector, _invokedSetters);
279 } 282 }
280 283
281 bool _registerNewSelector( 284 bool _registerNewSelector(
282 UniverseSelector universeSelector, 285 UniverseSelector universeSelector,
283 Map<String, Map<Selector, TypeMaskSet>> selectorMap) { 286 Map<String, Map<Selector, ReceiverMaskSet>> selectorMap) {
284 Selector selector = universeSelector.selector; 287 Selector selector = universeSelector.selector;
285 String name = selector.name; 288 String name = selector.name;
286 TypeMask mask = universeSelector.mask; 289 ReceiverMask mask = universeSelector.mask;
287 Map<Selector, TypeMaskSet> selectors = selectorMap.putIfAbsent( 290 Map<Selector, ReceiverMaskSet> selectors = selectorMap.putIfAbsent(
288 name, () => new Maplet<Selector, TypeMaskSet>()); 291 name, () => new Maplet<Selector, ReceiverMaskSet>());
289 IncreasingTypeMaskSet masks = selectors.putIfAbsent( 292 UniverseReceiverMaskSet masks = selectors.putIfAbsent(
290 selector, () => new IncreasingTypeMaskSet()); 293 selector, () => receiverMaskStrategy.createReceiverMaskSet(selector));
291 return masks.add(mask); 294 return masks.addReceiverMask(mask);
292 } 295 }
293 296
294 Map<Selector, TypeMaskSet> _asUnmodifiable(Map<Selector, TypeMaskSet> map) { 297 Map<Selector, ReceiverMaskSet> _asUnmodifiable(
298 Map<Selector, ReceiverMaskSet> map) {
295 if (map == null) return null; 299 if (map == null) return null;
296 return new UnmodifiableMapView(map); 300 return new UnmodifiableMapView(map);
297 } 301 }
298 302
299 Map<Selector, TypeMaskSet> invocationsByName(String name) { 303 Map<Selector, ReceiverMaskSet> invocationsByName(String name) {
300 return _asUnmodifiable(_invokedNames[name]); 304 return _asUnmodifiable(_invokedNames[name]);
301 } 305 }
302 306
303 Map<Selector, TypeMaskSet> getterInvocationsByName(String name) { 307 Map<Selector, ReceiverMaskSet> getterInvocationsByName(String name) {
304 return _asUnmodifiable(_invokedGetters[name]); 308 return _asUnmodifiable(_invokedGetters[name]);
305 } 309 }
306 310
307 Map<Selector, TypeMaskSet> setterInvocationsByName(String name) { 311 Map<Selector, ReceiverMaskSet> setterInvocationsByName(String name) {
308 return _asUnmodifiable(_invokedSetters[name]); 312 return _asUnmodifiable(_invokedSetters[name]);
309 } 313 }
310 314
311 void forEachInvokedName( 315 void forEachInvokedName(
312 f(String name, Map<Selector, TypeMaskSet> selectors)) { 316 f(String name, Map<Selector, ReceiverMaskSet> selectors)) {
313 _invokedNames.forEach(f); 317 _invokedNames.forEach(f);
314 } 318 }
315 319
316 void forEachInvokedGetter( 320 void forEachInvokedGetter(
317 f(String name, Map<Selector, TypeMaskSet> selectors)) { 321 f(String name, Map<Selector, ReceiverMaskSet> selectors)) {
318 _invokedGetters.forEach(f); 322 _invokedGetters.forEach(f);
319 } 323 }
320 324
321 void forEachInvokedSetter( 325 void forEachInvokedSetter(
322 f(String name, Map<Selector, TypeMaskSet> selectors)) { 326 f(String name, Map<Selector, ReceiverMaskSet> selectors)) {
323 _invokedSetters.forEach(f); 327 _invokedSetters.forEach(f);
324 } 328 }
325 329
326 DartType registerIsCheck(DartType type, Compiler compiler) { 330 DartType registerIsCheck(DartType type, Compiler compiler) {
327 type = type.unalias(compiler); 331 type = type.unalias(compiler);
328 // Even in checked mode, type annotations for return type and argument 332 // Even in checked mode, type annotations for return type and argument
329 // types do not imply type checks, so there should never be a check 333 // types do not imply type checks, so there should never be a check
330 // against the type variable of a typedef. 334 // against the type variable of a typedef.
331 isChecks.add(type); 335 isChecks.add(type);
332 return type; 336 return type;
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 // Add bits from the call structure. 907 // Add bits from the call structure.
904 return Hashing.mixHashCodeBits(hash, callStructure.hashCode); 908 return Hashing.mixHashCodeBits(hash, callStructure.hashCode);
905 } 909 }
906 910
907 String toString() { 911 String toString() {
908 return 'Selector($kind, $name, ${callStructure.structureToString()})'; 912 return 'Selector($kind, $name, ${callStructure.structureToString()})';
909 } 913 }
910 914
911 Selector toCallSelector() => new Selector.callClosureFrom(this); 915 Selector toCallSelector() => new Selector.callClosureFrom(this);
912 } 916 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/types/type_mask.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698