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

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
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.
karlklose 2015/07/21 12:47:21 Maybe extend to '... including [cls] itself, if it
Johnni Winther 2015/07/21 14:22:00 Done.
150 Iterable<ClassElement> strictSubclassesOf(ClassElement cls) { 154 Iterable<ClassElement> subclassesOf(ClassElement cls) {
151 Set<ClassElement> subclasses = _subclasses[cls.declaration]; 155 ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
karlklose 2015/07/21 12:47:21 'subclasses' -> 'hierarchy'?
Johnni Winther 2015/07/21 14:22:01 Done.
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 ClassHierarchyNode subclasses = _classHierarchyNodes[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.
karlklose 2015/07/21 12:47:21 Remove 'if it is live', it is implied.
Johnni Winther 2015/07/21 14:22:00 Done.
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
347 /// Ensure that a [ClassHierarchyNode] exists for [cls]. Updates the
348 /// `isDirectlyInstantiated` and `isIndirectlyInstantiated` property of the
349 /// node according the provided arguments and returns the node.
350 ClassHierarchyNode createNodeForClass(
karlklose 2015/07/21 12:47:21 'create[Class]HierarchyNodeForClass'?
Johnni Winther 2015/07/21 14:22:01 Done.
351 ClassElement cls,
352 {bool directlyInstantiated: false,
353 bool indirectlyInstantiated: false}) {
354 ClassHierarchyNode node = _classHierarchyNodes.putIfAbsent(cls, () {
355 ClassHierarchyNode node = new ClassHierarchyNode(cls);
356 if (cls.superclass != null) {
357 createNodeForClass(cls.superclass,
358 indirectlyInstantiated:
359 directlyInstantiated || indirectlyInstantiated)
360 .addDirectSubclass(node);
361 }
362 return node;
363 });
364 if (directlyInstantiated) {
365 node.isDirectlyInstantiated = true;
366 }
367 if (indirectlyInstantiated) {
368 node.isIndirectlyInstantiated = true;
369 }
370 return node;
karlklose 2015/07/21 12:47:21 Is there a contract to only call this method for a
Johnni Winther 2015/07/21 14:22:00 Moved into [populate] and assertion added.
371 }
372
322 void populate() { 373 void populate() {
374
323 void addSubtypes(ClassElement cls) { 375 void addSubtypes(ClassElement cls) {
324 if (compiler.hasIncrementalSupport && !alreadyPopulated.add(cls)) { 376 if (compiler.hasIncrementalSupport && !alreadyPopulated.add(cls)) {
325 return; 377 return;
326 } 378 }
327 assert(cls.isDeclaration); 379 assert(cls.isDeclaration);
328 if (!cls.isResolved) { 380 if (!cls.isResolved) {
329 compiler.internalError(cls, 'Class "${cls.name}" is not resolved.'); 381 compiler.internalError(cls, 'Class "${cls.name}" is not resolved.');
330 } 382 }
331 383
384 createNodeForClass(cls, directlyInstantiated: true);
385
332 for (DartType type in cls.allSupertypes) { 386 for (DartType type in cls.allSupertypes) {
333 Set<Element> subtypesOfSupertype = 387 Set<Element> subtypesOfSupertype =
334 _subtypes.putIfAbsent(type.element, () => new Set<ClassElement>()); 388 _subtypes.putIfAbsent(type.element, () => new Set<ClassElement>());
335 subtypesOfSupertype.add(cls); 389 subtypesOfSupertype.add(cls);
336 } 390 }
337 391
338 // Walk through the superclasses, and record the types 392 // Walk through the superclasses, and record the types
339 // implemented by that type on the superclasses. 393 // implemented by that type on the superclasses.
340 ClassElement superclass = cls.superclass; 394 ClassElement superclass = cls.superclass;
341 while (superclass != null) { 395 while (superclass != null) {
342 Set<Element> subclassesOfSuperclass =
343 _subclasses.putIfAbsent(superclass, () => new Set<ClassElement>());
344 subclassesOfSuperclass.add(cls);
345
346 Set<Element> typesImplementedBySubclassesOfCls = 396 Set<Element> typesImplementedBySubclassesOfCls =
347 _typesImplementedBySubclasses.putIfAbsent( 397 _typesImplementedBySubclasses.putIfAbsent(
348 superclass, () => new Set<ClassElement>()); 398 superclass, () => new Set<ClassElement>());
349 for (DartType current in cls.allSupertypes) { 399 for (DartType current in cls.allSupertypes) {
350 typesImplementedBySubclassesOfCls.add(current.element); 400 typesImplementedBySubclassesOfCls.add(current.element);
351 } 401 }
352 superclass = superclass.superclass; 402 superclass = superclass.superclass;
353 } 403 }
354 } 404 }
355 405
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 // function expressions's element. 550 // function expressions's element.
501 // TODO(herhut): Generate classes for function expressions earlier. 551 // TODO(herhut): Generate classes for function expressions earlier.
502 if (element is closureMapping.SynthesizedCallMethodElementX) { 552 if (element is closureMapping.SynthesizedCallMethodElementX) {
503 return getMightBePassedToApply(element.expression); 553 return getMightBePassedToApply(element.expression);
504 } 554 }
505 return functionsThatMightBePassedToApply.contains(element); 555 return functionsThatMightBePassedToApply.contains(element);
506 } 556 }
507 557
508 bool get hasClosedWorldAssumption => !compiler.hasIncrementalSupport; 558 bool get hasClosedWorldAssumption => !compiler.hasIncrementalSupport;
509 } 559 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698