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

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

Issue 1234053002: Add SubclassNode to prepare for optimized queries on ClassWorld. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: 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 part of dart2js; 5 part of dart2js;
6 6
7 abstract class ClassWorld { 7 abstract class ClassWorld {
8 // TODO(johnniwinther): Refine this into a `BackendClasses` interface. 8 // TODO(johnniwinther): Refine this into a `BackendClasses` interface.
9 Backend get backend; 9 Backend get backend;
10 10
(...skipping 28 matching lines...) Expand all
39 /// Returns `true` if the class world is closed. 39 /// Returns `true` if the class world is closed.
40 bool get isClosed; 40 bool get isClosed;
41 41
42 /// Return `true` if [x] is a subclass of [y]. 42 /// Return `true` if [x] is a subclass of [y].
43 bool isSubclassOf(ClassElement x, ClassElement y); 43 bool isSubclassOf(ClassElement x, ClassElement y);
44 44
45 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an 45 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an
46 /// instance of [y]. 46 /// instance of [y].
47 bool isSubtypeOf(ClassElement x, ClassElement y); 47 bool isSubtypeOf(ClassElement x, ClassElement y);
48 48
49 /// Returns an iterable over the live classes that extend [cls] including
50 /// [cls] itself.
51 Iterable<ClassElement> subclassesOf(ClassElement cls);
52
49 /// Returns an iterable over the live classes that extend [cls] _not_ 53 /// Returns an iterable over the live classes that extend [cls] _not_
50 /// including [cls] itself. 54 /// including [cls] itself.
51 Iterable<ClassElement> strictSubclassesOf(ClassElement cls); 55 Iterable<ClassElement> strictSubclassesOf(ClassElement cls);
52 56
53 /// Returns an iterable over the live classes that implement [cls] _not_ 57 /// Returns an iterable over the live classes that implement [cls] _not_
54 /// including [cls] if it is live. 58 /// including [cls] if it is live.
55 Iterable<ClassElement> strictSubtypesOf(ClassElement cls); 59 Iterable<ClassElement> strictSubtypesOf(ClassElement cls);
56 60
57 /// Returns `true` if any live class other than [cls] extends [cls]. 61 /// Returns `true` if any live class other than [cls] extends [cls].
58 bool hasAnyStrictSubclass(ClassElement cls); 62 bool hasAnyStrictSubclass(ClassElement cls);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 x = x.superclass; 142 x = x.superclass;
139 } 143 }
140 return false; 144 return false;
141 } 145 }
142 146
143 /// Returns `true` if [cls] is instantiated. 147 /// Returns `true` if [cls] is instantiated.
144 bool isInstantiated(ClassElement cls) { 148 bool isInstantiated(ClassElement cls) {
145 return compiler.resolverWorld.isInstantiated(cls); 149 return compiler.resolverWorld.isInstantiated(cls);
146 } 150 }
147 151
148 /// Returns an iterable over the live classes that extend [cls] _not_ 152 /// Returns an iterable over the directly instantiated classes that extend
149 /// including [cls] itself. 153 /// [cls] possibly including [cls] itself.
150 Iterable<ClassElement> strictSubclassesOf(ClassElement cls) { 154 Iterable<ClassElement> subclassesOf(ClassElement cls) {
151 Set<ClassElement> subclasses = _subclasses[cls.declaration]; 155 SubclassNode subclasses = _subclassNodes[cls.declaration];
152 if (subclasses == null) return const <ClassElement>[]; 156 if (subclasses == null) return const <ClassElement>[];
153 assert(invariant(cls, isInstantiated(cls.declaration), 157 assert(invariant(cls, isInstantiated(cls.declaration),
154 message: 'Class $cls has not been instantiated.')); 158 message: 'Class $cls has not been instantiated.'));
155 return subclasses; 159 return subclasses.subclasses();
156 } 160 }
157 161
158 /// Returns an iterable over the live classes that implement [cls] _not_ 162 /// Returns an iterable over the directly instantiated classes that extend
159 /// including [cls] if it is live. 163 /// [cls] _not_ including [cls] itself.
164 Iterable<ClassElement> strictSubclassesOf(ClassElement cls) {
165 SubclassNode subclasses = _subclassNodes[cls.declaration];
166 if (subclasses == null) return const <ClassElement>[];
167 assert(invariant(cls, isInstantiated(cls.declaration),
168 message: 'Class $cls has not been instantiated.'));
169 return subclasses.strictSubclasses();
170 }
171
172 /// Returns an iterable over the directly instantiated that implement [cls]
173 /// _not_ including [cls] if it is live.
160 Iterable<ClassElement> strictSubtypesOf(ClassElement cls) { 174 Iterable<ClassElement> strictSubtypesOf(ClassElement cls) {
161 Set<ClassElement> subtypes = _subtypes[cls.declaration]; 175 Set<ClassElement> subtypes = _subtypes[cls.declaration];
162 return subtypes != null ? subtypes : const <ClassElement>[]; 176 return subtypes != null ? subtypes : const <ClassElement>[];
163 } 177 }
164 178
165 /// Returns `true` if any live class other than [cls] extends [cls]. 179 /// Returns `true` if any directly instantiated class other than [cls] extends
180 /// [cls].
166 bool hasAnyStrictSubclass(ClassElement cls) { 181 bool hasAnyStrictSubclass(ClassElement cls) {
167 return !strictSubclassesOf(cls).isEmpty; 182 SubclassNode subclasses = _subclassNodes[cls.declaration];
183 if (subclasses == null) return false;
184 assert(invariant(cls, isInstantiated(cls.declaration),
185 message: 'Class $cls has not been instantiated.'));
186 return subclasses.isIndirectlyInstantiated;
168 } 187 }
169 188
170 /// Returns `true` if any live class other than [cls] implements [cls]. 189 /// Returns `true` if any directly instantiated class other than [cls]
190 /// implements [cls].
171 bool hasAnyStrictSubtype(ClassElement cls) { 191 bool hasAnyStrictSubtype(ClassElement cls) {
172 return !strictSubtypesOf(cls).isEmpty; 192 return !strictSubtypesOf(cls).isEmpty;
173 } 193 }
174 194
175 /// Returns `true` if all live classes that implement [cls] extend it. 195 /// Returns `true` if all directly instantiated classes that implement [cls]
196 /// extend it.
176 bool hasOnlySubclasses(ClassElement cls) { 197 bool hasOnlySubclasses(ClassElement cls) {
177 Iterable<ClassElement> subtypes = strictSubtypesOf(cls); 198 Iterable<ClassElement> subtypes = strictSubtypesOf(cls);
178 if (subtypes == null) return true; 199 if (subtypes == null) return true;
179 Iterable<ClassElement> subclasses = strictSubclassesOf(cls); 200 Iterable<ClassElement> subclasses = strictSubclassesOf(cls);
180 return subclasses != null && (subclasses.length == subtypes.length); 201 return subclasses != null && (subclasses.length == subtypes.length);
181 } 202 }
182 203
183 /// Returns an iterable over the common supertypes of the [classes]. 204 /// Returns an iterable over the common supertypes of the [classes].
184 Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes) { 205 Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes) {
185 Iterator<ClassElement> iterator = classes.iterator; 206 Iterator<ClassElement> iterator = classes.iterator;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 298
278 final Map<ClassElement, List<MixinApplicationElement>> _mixinUses = 299 final Map<ClassElement, List<MixinApplicationElement>> _mixinUses =
279 new Map<ClassElement, List<MixinApplicationElement>>(); 300 new Map<ClassElement, List<MixinApplicationElement>>();
280 Map<ClassElement, List<MixinApplicationElement>> _liveMixinUses; 301 Map<ClassElement, List<MixinApplicationElement>> _liveMixinUses;
281 302
282 final Map<ClassElement, Set<ClassElement>> _typesImplementedBySubclasses = 303 final Map<ClassElement, Set<ClassElement>> _typesImplementedBySubclasses =
283 new Map<ClassElement, Set<ClassElement>>(); 304 new Map<ClassElement, Set<ClassElement>>();
284 305
285 // We keep track of subtype and subclass relationships in four 306 // We keep track of subtype and subclass relationships in four
286 // distinct sets to make class hierarchy analysis faster. 307 // distinct sets to make class hierarchy analysis faster.
287 final Map<ClassElement, Set<ClassElement>> _subclasses = 308 final Map<ClassElement, SubclassNode> _subclassNodes =
288 new Map<ClassElement, Set<ClassElement>>(); 309 <ClassElement, SubclassNode>{};
289 final Map<ClassElement, Set<ClassElement>> _subtypes = 310 final Map<ClassElement, Set<ClassElement>> _subtypes =
290 new Map<ClassElement, Set<ClassElement>>(); 311 new Map<ClassElement, Set<ClassElement>>();
291 312
292 final Set<Element> sideEffectsFreeElements = new Set<Element>(); 313 final Set<Element> sideEffectsFreeElements = new Set<Element>();
293 314
294 final Set<Element> elementsThatCannotThrow = new Set<Element>(); 315 final Set<Element> elementsThatCannotThrow = new Set<Element>();
295 316
296 final Set<Element> functionsThatMightBePassedToApply = 317 final Set<Element> functionsThatMightBePassedToApply =
297 new Set<FunctionElement>(); 318 new Set<FunctionElement>();
298 319
(...skipping 13 matching lines...) Expand all
312 333
313 Set<ClassElement> typesImplementedBySubclassesOf(ClassElement cls) { 334 Set<ClassElement> typesImplementedBySubclassesOf(ClassElement cls) {
314 return _typesImplementedBySubclasses[cls.declaration]; 335 return _typesImplementedBySubclasses[cls.declaration];
315 } 336 }
316 337
317 World(Compiler compiler) 338 World(Compiler compiler)
318 : allFunctions = new FunctionSet(compiler), 339 : allFunctions = new FunctionSet(compiler),
319 this.compiler = compiler, 340 this.compiler = compiler,
320 alreadyPopulated = compiler.cacheStrategy.newSet(); 341 alreadyPopulated = compiler.cacheStrategy.newSet();
321 342
343 SubclassNode subclassNode(ClassElement cls) {
344 return _subclassNodes[cls];
345 }
346
347 /// Ensure that a [SubclassNode] exists for [cls]. Updates the
348 /// `isDirectlyInstantiated` and `isIndirectlyInstantiated` property of the
349 /// node according the provided arguments and returns the node.
350 SubclassNode createNodeForClass(ClassElement cls,
Siggi Cherem (dart-lang) 2015/07/14 23:51:07 nit, rename to: `ensureNodeForClass` (that helps c
351 {bool directlyInstantiated: false,
352 bool indirectlyInstantiated: false}) {
353 SubclassNode node = _subclassNodes.putIfAbsent(cls, () {
354 SubclassNode node = new SubclassNode(cls);
355 if (cls.superclass != null) {
356 createNodeForClass(cls.superclass,
357 indirectlyInstantiated:
358 directlyInstantiated || indirectlyInstantiated)
359 .addDirectSubclass(node);
360 }
361 return node;
362 });
363 if (directlyInstantiated) {
364 node.isDirectlyInstantiated = true;
365 }
366 if (indirectlyInstantiated) {
367 node.isIndirectlyInstantiated = true;
368 }
369 return node;
370 }
371
322 void populate() { 372 void populate() {
373
323 void addSubtypes(ClassElement cls) { 374 void addSubtypes(ClassElement cls) {
324 if (compiler.hasIncrementalSupport && !alreadyPopulated.add(cls)) { 375 if (compiler.hasIncrementalSupport && !alreadyPopulated.add(cls)) {
325 return; 376 return;
326 } 377 }
327 assert(cls.isDeclaration); 378 assert(cls.isDeclaration);
328 if (!cls.isResolved) { 379 if (!cls.isResolved) {
329 compiler.internalError(cls, 'Class "${cls.name}" is not resolved.'); 380 compiler.internalError(cls, 'Class "${cls.name}" is not resolved.');
330 } 381 }
331 382
383 createNodeForClass(cls, directlyInstantiated: true);
384
332 for (DartType type in cls.allSupertypes) { 385 for (DartType type in cls.allSupertypes) {
333 Set<Element> subtypesOfSupertype = 386 Set<Element> subtypesOfSupertype =
334 _subtypes.putIfAbsent(type.element, () => new Set<ClassElement>()); 387 _subtypes.putIfAbsent(type.element, () => new Set<ClassElement>());
335 subtypesOfSupertype.add(cls); 388 subtypesOfSupertype.add(cls);
336 } 389 }
337 390
338 // Walk through the superclasses, and record the types 391 // Walk through the superclasses, and record the types
339 // implemented by that type on the superclasses. 392 // implemented by that type on the superclasses.
340 ClassElement superclass = cls.superclass; 393 ClassElement superclass = cls.superclass;
341 while (superclass != null) { 394 while (superclass != null) {
342 Set<Element> subclassesOfSuperclass =
343 _subclasses.putIfAbsent(superclass, () => new Set<ClassElement>());
344 subclassesOfSuperclass.add(cls);
345
346 Set<Element> typesImplementedBySubclassesOfCls = 395 Set<Element> typesImplementedBySubclassesOfCls =
347 _typesImplementedBySubclasses.putIfAbsent( 396 _typesImplementedBySubclasses.putIfAbsent(
348 superclass, () => new Set<ClassElement>()); 397 superclass, () => new Set<ClassElement>());
349 for (DartType current in cls.allSupertypes) { 398 for (DartType current in cls.allSupertypes) {
350 typesImplementedBySubclassesOfCls.add(current.element); 399 typesImplementedBySubclassesOfCls.add(current.element);
351 } 400 }
352 superclass = superclass.superclass; 401 superclass = superclass.superclass;
353 } 402 }
354 } 403 }
355 404
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 // function expressions's element. 549 // function expressions's element.
501 // TODO(herhut): Generate classes for function expressions earlier. 550 // TODO(herhut): Generate classes for function expressions earlier.
502 if (element is closureMapping.SynthesizedCallMethodElementX) { 551 if (element is closureMapping.SynthesizedCallMethodElementX) {
503 return getMightBePassedToApply(element.expression); 552 return getMightBePassedToApply(element.expression);
504 } 553 }
505 return functionsThatMightBePassedToApply.contains(element); 554 return functionsThatMightBePassedToApply.contains(element);
506 } 555 }
507 556
508 bool get hasClosedWorldAssumption => !compiler.hasIncrementalSupport; 557 bool get hasClosedWorldAssumption => !compiler.hasIncrementalSupport;
509 } 558 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698