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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/universe/function_set.dart

Issue 694353007: Move dart2js from sdk/lib/_internal/compiler to pkg/compiler (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 part of universe;
6
7 // TODO(kasperl): This actually holds getters and setters just fine
8 // too and stricly they aren't functions. Maybe this needs a better
9 // name -- something like ElementSet seems a bit too generic.
10 class FunctionSet {
11 final Compiler compiler;
12 final Map<String, FunctionSetNode> nodes =
13 new Map<String, FunctionSetNode>();
14 FunctionSet(this.compiler);
15
16 FunctionSetNode newNode(String name)
17 => new FunctionSetNode(name);
18
19 void add(Element element) {
20 assert(element.isInstanceMember);
21 assert(!element.isAbstract);
22 String name = element.name;
23 FunctionSetNode node = nodes.putIfAbsent(name, () => newNode(name));
24 node.add(element);
25 }
26
27 void remove(Element element) {
28 assert(element.isInstanceMember);
29 assert(!element.isAbstract);
30 String name = element.name;
31 FunctionSetNode node = nodes[name];
32 if (node != null) {
33 node.remove(element);
34 }
35 }
36
37 bool contains(Element element) {
38 assert(element.isInstanceMember);
39 assert(!element.isAbstract);
40 String name = element.name;
41 FunctionSetNode node = nodes[name];
42 return (node != null)
43 ? node.contains(element)
44 : false;
45 }
46
47 /**
48 * Returns an object that allows iterating over all the functions
49 * that may be invoked with the given [selector].
50 */
51 Iterable<Element> filter(Selector selector) {
52 return query(selector).functions;
53 }
54
55 TypeMask receiverType(Selector selector) {
56 return query(selector).computeMask(compiler.world);
57 }
58
59 FunctionSetQuery query(Selector selector) {
60 String name = selector.name;
61 FunctionSetNode node = nodes[name];
62 FunctionSetNode noSuchMethods = nodes[Compiler.NO_SUCH_METHOD];
63 if (node != null) {
64 return node.query(selector, compiler, noSuchMethods);
65 }
66 // If there is no method that matches [selector] we know we can
67 // only hit [:noSuchMethod:].
68 if (noSuchMethods == null) return const FunctionSetQuery(const <Element>[]);
69 selector = (selector.mask == null)
70 ? compiler.noSuchMethodSelector
71 : new TypedSelector(selector.mask, compiler.noSuchMethodSelector,
72 compiler.world);
73
74 return noSuchMethods.query(selector, compiler, null);
75 }
76
77 void forEach(Function action) {
78 nodes.forEach((String name, FunctionSetNode node) {
79 node.forEach(action);
80 });
81 }
82 }
83
84
85 class FunctionSetNode {
86 final String name;
87 final Map<Selector, FunctionSetQuery> cache =
88 new Map<Selector, FunctionSetQuery>();
89
90 // Initially, we keep the elements in a list because it is more
91 // compact than a hash set. Once we get enough elements, we change
92 // the representation to be a set to get faster contains checks.
93 static const int MAX_ELEMENTS_IN_LIST = 8;
94 var elements = <Element>[];
95 bool isList = true;
96
97 FunctionSetNode(this.name);
98
99 void add(Element element) {
100 assert(element.name == name);
101 // We try to avoid clearing the cache unless we have to. For that
102 // reason we keep the explicit contains check even though the add
103 // method ends up doing the work again (for sets).
104 if (!elements.contains(element)) {
105 if (isList && elements.length >= MAX_ELEMENTS_IN_LIST) {
106 elements = elements.toSet();
107 isList = false;
108 }
109 elements.add(element);
110 if (!cache.isEmpty) cache.clear();
111 }
112 }
113
114 void remove(Element element) {
115 assert(element.name == name);
116 if (isList) {
117 List list = elements;
118 int index = list.indexOf(element);
119 if (index < 0) return;
120 Element last = list.removeLast();
121 if (index != list.length) {
122 list[index] = last;
123 }
124 if (!cache.isEmpty) cache.clear();
125 } else {
126 Set set = elements;
127 if (set.remove(element)) {
128 // To avoid wobbling between the two representations, we do
129 // not transition back to the list representation even if we
130 // end up with few enough elements at this point.
131 if (!cache.isEmpty) cache.clear();
132 }
133 }
134 }
135
136 bool contains(Element element) {
137 assert(element.name == name);
138 return elements.contains(element);
139 }
140
141 void forEach(Function action) {
142 elements.forEach(action);
143 }
144
145 TypeMask getNonNullTypeMaskOfSelector(Selector selector, Compiler compiler) {
146 // TODO(ngeoffray): We should probably change untyped selector
147 // to always be a subclass of Object.
148 return selector.mask != null
149 ? selector.mask
150 : new TypeMask.subclass(compiler.objectClass, compiler.world);
151 }
152
153 FunctionSetQuery query(Selector selector,
154 Compiler compiler,
155 FunctionSetNode noSuchMethods) {
156 ClassWorld classWorld = compiler.world;
157 assert(selector.name == name);
158 FunctionSetQuery result = cache[selector];
159 if (result != null) return result;
160 Setlet<Element> functions;
161 for (Element element in elements) {
162 if (selector.appliesUnnamed(element, classWorld)) {
163 if (functions == null) {
164 // Defer the allocation of the functions set until we are
165 // sure we need it. This allows us to return immutable empty
166 // lists when the filtering produced no results.
167 functions = new Setlet<Element>();
168 }
169 functions.add(element);
170 }
171 }
172
173 TypeMask mask = getNonNullTypeMaskOfSelector(selector, compiler);
174 // If we cannot ensure a method will be found at runtime, we also
175 // add [noSuchMethod] implementations that apply to [mask] as
176 // potential targets.
177 if (noSuchMethods != null
178 && mask.needsNoSuchMethodHandling(selector, classWorld)) {
179 FunctionSetQuery noSuchMethodQuery = noSuchMethods.query(
180 new TypedSelector(
181 mask, compiler.noSuchMethodSelector, classWorld),
182 compiler,
183 null);
184 if (!noSuchMethodQuery.functions.isEmpty) {
185 if (functions == null) {
186 functions = new Setlet<Element>.from(noSuchMethodQuery.functions);
187 } else {
188 functions.addAll(noSuchMethodQuery.functions);
189 }
190 }
191 }
192 cache[selector] = result = (functions != null)
193 ? newQuery(functions, selector, compiler)
194 : const FunctionSetQuery(const <Element>[]);
195 return result;
196 }
197
198 FunctionSetQuery newQuery(Iterable<Element> functions,
199 Selector selector,
200 Compiler compiler) {
201 return new FullFunctionSetQuery(functions);
202 }
203 }
204
205 class FunctionSetQuery {
206 final Iterable<Element> functions;
207 TypeMask computeMask(ClassWorld classWorld) => const TypeMask.nonNullEmpty();
208 const FunctionSetQuery(this.functions);
209 }
210
211 class FullFunctionSetQuery extends FunctionSetQuery {
212 TypeMask _mask;
213
214 /**
215 * Compute the type of all potential receivers of this function set.
216 */
217 TypeMask computeMask(ClassWorld classWorld) {
218 assert(classWorld.hasAnySubclass(classWorld.objectClass));
219 if (_mask != null) return _mask;
220 return _mask = new TypeMask.unionOf(functions
221 .expand((element) {
222 ClassElement cls = element.enclosingClass;
223 return [cls]..addAll(classWorld.mixinUsesOf(cls));
224 })
225 .map((cls) {
226 if (classWorld.backend.isNullImplementation(cls)) {
227 return const TypeMask.empty();
228 } else {
229 return new TypeMask.nonNullSubclass(cls.declaration, classWorld);
230 }
231 }),
232 classWorld);
233 }
234
235 FullFunctionSetQuery(functions) : super(functions);
236 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698