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

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

Issue 2860733002: Remove ClosedWorld.allFunctions (Closed)
Patch Set: Created 3 years, 7 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.function_set; 5 library universe.function_set;
6 6
7 import '../common/names.dart' show Identifiers, Selectors; 7 import '../common/names.dart' show Identifiers, Selectors;
8 import '../elements/entities.dart'; 8 import '../elements/entities.dart';
9 import '../types/types.dart'; 9 import '../types/types.dart';
10 import '../util/util.dart' show Hashing, Setlet; 10 import '../util/util.dart' show Hashing, Setlet;
(...skipping 17 matching lines...) Expand all
28 void remove(MemberEntity element) { 28 void remove(MemberEntity element) {
29 assert(element.isInstanceMember); 29 assert(element.isInstanceMember);
30 assert(!element.isAbstract); 30 assert(!element.isAbstract);
31 String name = element.name; 31 String name = element.name;
32 FunctionSetNode node = nodes[name]; 32 FunctionSetNode node = nodes[name];
33 if (node != null) { 33 if (node != null) {
34 node.remove(element); 34 node.remove(element);
35 } 35 }
36 } 36 }
37 37
38 FunctionSet close(ClosedWorld closedWorld) { 38 FunctionSet close() {
39 return new FunctionSet(closedWorld, nodes); 39 return new FunctionSet(nodes);
40 } 40 }
41 } 41 }
42 42
43 // TODO(kasperl): This actually holds getters and setters just fine 43 // TODO(kasperl): This actually holds getters and setters just fine
44 // too and stricly they aren't functions. Maybe this needs a better 44 // too and stricly they aren't functions. Maybe this needs a better
45 // name -- something like ElementSet seems a bit too generic. 45 // name -- something like ElementSet seems a bit too generic.
46 class FunctionSet { 46 class FunctionSet {
47 final ClosedWorld closedWorld; 47 final Map<String, FunctionSetNode> _nodes;
48 final Map<String, FunctionSetNode> nodes;
49 48
50 FunctionSet(this.closedWorld, this.nodes); 49 FunctionSet(this._nodes);
51 50
52 bool contains(MemberEntity element) { 51 bool contains(MemberEntity element) {
53 assert(element.isInstanceMember); 52 assert(element.isInstanceMember);
54 assert(!element.isAbstract); 53 assert(!element.isAbstract);
55 String name = element.name; 54 String name = element.name;
56 FunctionSetNode node = nodes[name]; 55 FunctionSetNode node = _nodes[name];
57 return (node != null) ? node.contains(element) : false; 56 return (node != null) ? node.contains(element) : false;
58 } 57 }
59 58
60 /// Returns all the functions that may be invoked with the [selector] on a 59 /// Returns all the functions that may be invoked with the [selector] on a
61 /// receiver with the given [constraint]. The returned elements may include 60 /// receiver with the given [constraint]. The returned elements may include
62 /// noSuchMethod handlers that are potential targets indirectly through the 61 /// noSuchMethod handlers that are potential targets indirectly through the
63 /// noSuchMethod mechanism. 62 /// noSuchMethod mechanism.
64 Iterable<MemberEntity> filter( 63 Iterable<MemberEntity> filter(Selector selector,
65 Selector selector, ReceiverConstraint constraint) { 64 ReceiverConstraint constraint, ClosedWorld closedWorld) {
66 return query(selector, constraint).functions; 65 return query(selector, constraint, closedWorld).functions;
67 } 66 }
68 67
69 /// Returns the mask for the potential receivers of a dynamic call to 68 /// Returns the mask for the potential receivers of a dynamic call to
70 /// [selector] on [constraint]. 69 /// [selector] on [constraint].
71 /// 70 ///
72 /// This will narrow the constraints of [constraint] to a [TypeMask] of the 71 /// This will narrow the constraints of [constraint] to a [TypeMask] of the
73 /// set of classes that actually implement the selected member or implement 72 /// set of classes that actually implement the selected member or implement
74 /// the handling 'noSuchMethod' where the selected member is unimplemented. 73 /// the handling 'noSuchMethod' where the selected member is unimplemented.
75 TypeMask receiverType(Selector selector, ReceiverConstraint constraint) { 74 TypeMask receiverType(Selector selector, ReceiverConstraint constraint,
76 return query(selector, constraint).computeMask(closedWorld); 75 ClosedWorld closedWorld) {
76 return query(selector, constraint, closedWorld).computeMask(closedWorld);
77 } 77 }
78 78
79 SelectorMask _createSelectorMask(Selector selector, 79 SelectorMask _createSelectorMask(Selector selector,
80 ReceiverConstraint constraint, ClosedWorld closedWorld) { 80 ReceiverConstraint constraint, ClosedWorld closedWorld) {
81 return constraint != null 81 return constraint != null
82 ? new SelectorMask(selector, constraint) 82 ? new SelectorMask(selector, constraint)
83 : new SelectorMask( 83 : new SelectorMask(
84 selector, 84 selector,
85 new TypeMask.subclass( 85 new TypeMask.subclass(
86 closedWorld.commonElements.objectClass, closedWorld)); 86 closedWorld.commonElements.objectClass, closedWorld));
87 } 87 }
88 88
89 /// Returns the set of functions that can be the target of a call to 89 /// Returns the set of functions that can be the target of a call to
90 /// [selector] on a receiver constrained by [constraint] including 90 /// [selector] on a receiver constrained by [constraint] including
91 /// 'noSuchMethod' methods where applicable. 91 /// 'noSuchMethod' methods where applicable.
92 FunctionSetQuery query(Selector selector, ReceiverConstraint constraint) { 92 FunctionSetQuery query(Selector selector, ReceiverConstraint constraint,
93 ClosedWorld closedWorld) {
93 String name = selector.name; 94 String name = selector.name;
94 SelectorMask selectorMask = 95 SelectorMask selectorMask =
95 _createSelectorMask(selector, constraint, closedWorld); 96 _createSelectorMask(selector, constraint, closedWorld);
96 SelectorMask noSuchMethodMask = 97 SelectorMask noSuchMethodMask =
97 new SelectorMask(Selectors.noSuchMethod_, selectorMask.constraint); 98 new SelectorMask(Selectors.noSuchMethod_, selectorMask.constraint);
98 FunctionSetNode node = nodes[name]; 99 FunctionSetNode node = _nodes[name];
99 FunctionSetNode noSuchMethods = nodes[Identifiers.noSuchMethod_]; 100 FunctionSetNode noSuchMethods = _nodes[Identifiers.noSuchMethod_];
100 if (node != null) { 101 if (node != null) {
101 return node.query( 102 return node.query(
102 selectorMask, closedWorld, noSuchMethods, noSuchMethodMask); 103 selectorMask, closedWorld, noSuchMethods, noSuchMethodMask);
103 } 104 }
104 // If there is no method that matches [selector] we know we can 105 // If there is no method that matches [selector] we know we can
105 // only hit [:noSuchMethod:]. 106 // only hit [:noSuchMethod:].
106 if (noSuchMethods == null) { 107 if (noSuchMethods == null) {
107 return const EmptyFunctionSetQuery(); 108 return const EmptyFunctionSetQuery();
108 } 109 }
109 return noSuchMethods.query(noSuchMethodMask, closedWorld); 110 return noSuchMethods.query(noSuchMethodMask, closedWorld);
110 } 111 }
111 112
112 void forEach(Function action) { 113 void forEach(void action(MemberEntity member)) {
113 nodes.forEach((String name, FunctionSetNode node) { 114 _nodes.forEach((String name, FunctionSetNode node) {
114 node.forEach(action); 115 node.forEach(action);
115 }); 116 });
116 } 117 }
117 } 118 }
118 119
119 /// A selector/constraint pair representing the dynamic invocation of [selector] 120 /// A selector/constraint pair representing the dynamic invocation of [selector]
120 /// on a receiver constrained by [constraint]. 121 /// on a receiver constrained by [constraint].
121 class SelectorMask { 122 class SelectorMask {
122 final Selector selector; 123 final Selector selector;
123 final ReceiverConstraint constraint; 124 final ReceiverConstraint constraint;
(...skipping 27 matching lines...) Expand all
151 } 152 }
152 153
153 /// A node in the [FunctionSet] caching all [FunctionSetQuery] object for 154 /// A node in the [FunctionSet] caching all [FunctionSetQuery] object for
154 /// selectors with the same [name]. 155 /// selectors with the same [name].
155 class FunctionSetNode { 156 class FunctionSetNode {
156 final String name; 157 final String name;
157 final Map<SelectorMask, FunctionSetQuery> cache = 158 final Map<SelectorMask, FunctionSetQuery> cache =
158 <SelectorMask, FunctionSetQuery>{}; 159 <SelectorMask, FunctionSetQuery>{};
159 160
160 // Initially, we keep the elements in a list because it is more 161 // Initially, we keep the elements in a list because it is more
161 // compact than a hash set. Once we get enough elements, we change 162 // compact than a hash set. Once we get enough elements, we change
Siggi Cherem (dart-lang) 2017/05/03 17:03:24 do you know if this is still the case, or does has
Johnni Winther 2017/05/08 09:10:53 I think this is built in now, I'll check at update
162 // the representation to be a set to get faster contains checks. 163 // the representation to be a set to get faster contains checks.
163 static const int MAX_ELEMENTS_IN_LIST = 8; 164 static const int MAX_ELEMENTS_IN_LIST = 8;
164 var elements = <MemberEntity>[]; 165 Iterable<MemberEntity> elements = <MemberEntity>[];
165 bool isList = true; 166 bool isList = true;
166 167
167 FunctionSetNode(this.name); 168 FunctionSetNode(this.name);
168 169
169 void add(MemberEntity element) { 170 void add(MemberEntity element) {
170 assert(element.name == name); 171 assert(element.name == name);
171 // We try to avoid clearing the cache unless we have to. For that 172 // We try to avoid clearing the cache unless we have to. For that
172 // reason we keep the explicit contains check even though the add 173 // reason we keep the explicit contains check even though the add
173 // method ends up doing the work again (for sets). 174 // method ends up doing the work again (for sets).
174 if (!elements.contains(element)) { 175 if (!elements.contains(element)) {
175 if (isList && elements.length >= MAX_ELEMENTS_IN_LIST) { 176 if (isList && elements.length >= MAX_ELEMENTS_IN_LIST) {
176 elements = elements.toSet(); 177 elements = elements.toSet();
177 isList = false; 178 isList = false;
178 } 179 }
179 elements.add(element); 180 if (isList) {
181 List list = elements;
182 list.add(element);
183 } else {
184 Set set = elements;
185 set.add(element);
186 }
180 if (!cache.isEmpty) cache.clear(); 187 if (!cache.isEmpty) cache.clear();
181 } 188 }
182 } 189 }
183 190
184 void remove(MemberEntity element) { 191 void remove(MemberEntity element) {
185 assert(element.name == name); 192 assert(element.name == name);
186 if (isList) { 193 if (isList) {
187 List list = elements; 194 List list = elements;
188 int index = list.indexOf(element); 195 int index = list.indexOf(element);
189 if (index < 0) return; 196 if (index < 0) return;
(...skipping 11 matching lines...) Expand all
201 if (!cache.isEmpty) cache.clear(); 208 if (!cache.isEmpty) cache.clear();
202 } 209 }
203 } 210 }
204 } 211 }
205 212
206 bool contains(MemberEntity element) { 213 bool contains(MemberEntity element) {
207 assert(element.name == name); 214 assert(element.name == name);
208 return elements.contains(element); 215 return elements.contains(element);
209 } 216 }
210 217
211 void forEach(Function action) { 218 void forEach(void action(MemberEntity member)) {
212 elements.forEach(action); 219 elements.forEach(action);
213 } 220 }
214 221
215 /// Returns the set of functions that can be the target of [selectorMask] 222 /// Returns the set of functions that can be the target of [selectorMask]
216 /// including no such method handling where applicable. 223 /// including no such method handling where applicable.
217 FunctionSetQuery query(SelectorMask selectorMask, ClosedWorld closedWorld, 224 FunctionSetQuery query(SelectorMask selectorMask, ClosedWorld closedWorld,
218 [FunctionSetNode noSuchMethods, SelectorMask noSuchMethodMask]) { 225 [FunctionSetNode noSuchMethods, SelectorMask noSuchMethodMask]) {
219 assert(selectorMask.name == name); 226 assert(selectorMask.name == name);
220 FunctionSetQuery result = cache[selectorMask]; 227 FunctionSetQuery result = cache[selectorMask];
221 if (result != null) return result; 228 if (result != null) return result;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 } else if (closedWorld.isInstantiated(cls)) { 309 } else if (closedWorld.isInstantiated(cls)) {
303 return new TypeMask.nonNullSubclass(cls, closedWorld); 310 return new TypeMask.nonNullSubclass(cls, closedWorld);
304 } else { 311 } else {
305 // TODO(johnniwinther): Avoid the need for this case. 312 // TODO(johnniwinther): Avoid the need for this case.
306 return const TypeMask.empty(); 313 return const TypeMask.empty();
307 } 314 }
308 }), 315 }),
309 closedWorld); 316 closedWorld);
310 } 317 }
311 } 318 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698