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

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: Updated cf. comments. 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
« no previous file with comments | « pkg/compiler/lib/src/use_unused_api.dart ('k') | tests/compiler/dart2js/class_set_test.dart » ('j') | 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 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, if it is live.
154 Iterable<ClassElement> subclassesOf(ClassElement cls) {
155 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration];
156 if (hierarchy == null) return const <ClassElement>[];
157 assert(invariant(cls, isInstantiated(cls.declaration),
158 message: 'Class $cls has not been instantiated.'));
159 return hierarchy.subclasses();
160 }
161
162 /// Returns an iterable over the directly instantiated classes that extend
163 /// [cls] _not_ including [cls] itself.
150 Iterable<ClassElement> strictSubclassesOf(ClassElement cls) { 164 Iterable<ClassElement> strictSubclassesOf(ClassElement cls) {
151 Set<ClassElement> subclasses = _subclasses[cls.declaration]; 165 ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
152 if (subclasses == null) return const <ClassElement>[]; 166 if (subclasses == null) return const <ClassElement>[];
153 assert(invariant(cls, isInstantiated(cls.declaration), 167 assert(invariant(cls, isInstantiated(cls.declaration),
154 message: 'Class $cls has not been instantiated.')); 168 message: 'Class $cls has not been instantiated.'));
155 return subclasses; 169 return subclasses.strictSubclasses();
156 } 170 }
157 171
158 /// Returns an iterable over the live classes that implement [cls] _not_ 172 /// Returns an iterable over the directly instantiated that implement [cls]
159 /// including [cls] if it is live. 173 /// _not_ including [cls].
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 ClassHierarchyNode subclasses = _classHierarchyNodes[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, ClassHierarchyNode> _classHierarchyNodes =
288 new Map<ClassElement, Set<ClassElement>>(); 309 <ClassElement, ClassHierarchyNode>{};
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 ClassHierarchyNode classHierarchyNode(ClassElement cls) {
344 return _classHierarchyNodes[cls];
345 }
346
322 void populate() { 347 void populate() {
348
349 /// Ensure that a [ClassHierarchyNode] exists for [cls]. Updates the
350 /// `isDirectlyInstantiated` and `isIndirectlyInstantiated` property of the
351 /// node according the provided arguments and returns the node.
352 ClassHierarchyNode createClassHierarchyNodeForClass(
353 ClassElement cls,
354 {bool directlyInstantiated: false,
355 bool indirectlyInstantiated: false}) {
356 assert(isInstantiated(cls));
357
358 ClassHierarchyNode node = _classHierarchyNodes.putIfAbsent(cls, () {
359 ClassHierarchyNode node = new ClassHierarchyNode(cls);
360 if (cls.superclass != null) {
361 createClassHierarchyNodeForClass(cls.superclass,
362 indirectlyInstantiated:
363 directlyInstantiated || indirectlyInstantiated)
364 .addDirectSubclass(node);
365 }
366 return node;
367 });
368 if (directlyInstantiated) {
369 node.isDirectlyInstantiated = true;
370 }
371 if (indirectlyInstantiated) {
372 node.isIndirectlyInstantiated = true;
373 }
374 return node;
375 }
376
323 void addSubtypes(ClassElement cls) { 377 void addSubtypes(ClassElement cls) {
324 if (compiler.hasIncrementalSupport && !alreadyPopulated.add(cls)) { 378 if (compiler.hasIncrementalSupport && !alreadyPopulated.add(cls)) {
325 return; 379 return;
326 } 380 }
327 assert(cls.isDeclaration); 381 assert(cls.isDeclaration);
328 if (!cls.isResolved) { 382 if (!cls.isResolved) {
329 compiler.internalError(cls, 'Class "${cls.name}" is not resolved.'); 383 compiler.internalError(cls, 'Class "${cls.name}" is not resolved.');
330 } 384 }
331 385
386 createClassHierarchyNodeForClass(cls, directlyInstantiated: true);
387
332 for (DartType type in cls.allSupertypes) { 388 for (DartType type in cls.allSupertypes) {
333 Set<Element> subtypesOfSupertype = 389 Set<Element> subtypesOfSupertype =
334 _subtypes.putIfAbsent(type.element, () => new Set<ClassElement>()); 390 _subtypes.putIfAbsent(type.element, () => new Set<ClassElement>());
335 subtypesOfSupertype.add(cls); 391 subtypesOfSupertype.add(cls);
336 } 392 }
337 393
338 // Walk through the superclasses, and record the types 394 // Walk through the superclasses, and record the types
339 // implemented by that type on the superclasses. 395 // implemented by that type on the superclasses.
340 ClassElement superclass = cls.superclass; 396 ClassElement superclass = cls.superclass;
341 while (superclass != null) { 397 while (superclass != null) {
342 Set<Element> subclassesOfSuperclass =
343 _subclasses.putIfAbsent(superclass, () => new Set<ClassElement>());
344 subclassesOfSuperclass.add(cls);
345
346 Set<Element> typesImplementedBySubclassesOfCls = 398 Set<Element> typesImplementedBySubclassesOfCls =
347 _typesImplementedBySubclasses.putIfAbsent( 399 _typesImplementedBySubclasses.putIfAbsent(
348 superclass, () => new Set<ClassElement>()); 400 superclass, () => new Set<ClassElement>());
349 for (DartType current in cls.allSupertypes) { 401 for (DartType current in cls.allSupertypes) {
350 typesImplementedBySubclassesOfCls.add(current.element); 402 typesImplementedBySubclassesOfCls.add(current.element);
351 } 403 }
352 superclass = superclass.superclass; 404 superclass = superclass.superclass;
353 } 405 }
354 } 406 }
355 407
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 // function expressions's element. 552 // function expressions's element.
501 // TODO(herhut): Generate classes for function expressions earlier. 553 // TODO(herhut): Generate classes for function expressions earlier.
502 if (element is closureMapping.SynthesizedCallMethodElementX) { 554 if (element is closureMapping.SynthesizedCallMethodElementX) {
503 return getMightBePassedToApply(element.expression); 555 return getMightBePassedToApply(element.expression);
504 } 556 }
505 return functionsThatMightBePassedToApply.contains(element); 557 return functionsThatMightBePassedToApply.contains(element);
506 } 558 }
507 559
508 bool get hasClosedWorldAssumption => !compiler.hasIncrementalSupport; 560 bool get hasClosedWorldAssumption => !compiler.hasIncrementalSupport;
509 } 561 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/use_unused_api.dart ('k') | tests/compiler/dart2js/class_set_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698