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

Unified Diff: pkg/compiler/lib/src/world.dart

Issue 1627333002: Optimize subclass/subtype queries (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Use strictSubtypeCount Created 4 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: pkg/compiler/lib/src/world.dart
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 30b2081ab0e0010a56b36976a534a37e19e58d2e..da08fb67d7bffedde9e9e187e95d0a7cf3d08883 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -93,6 +93,18 @@ abstract class ClassWorld {
/// including [cls] itself.
Iterable<ClassElement> strictSubclassesOf(ClassElement cls);
+ /// Returns the number of live classes that extend [cls] _not_
+ /// including [cls] itself.
+ int strictSubclassCount(ClassElement cls);
+
+ /// Applies [f] to each live class that extend [cls] _not_ including [cls]
+ /// itself.
+ void forEachStrictSubclassOf(ClassElement cls, ForEach f(ClassElement cls));
+
+ /// Returns `true` if [predicate] applies to any live class that extend [cls]
+ /// _not_ including [cls] itself.
+ bool anyStrictSubclassOf(ClassElement cls, bool predicate(ClassElement cls));
+
/// Returns an iterable over the directly instantiated that implement [cls]
/// possibly including [cls] itself, if it is live.
Iterable<ClassElement> subtypesOf(ClassElement cls);
@@ -101,6 +113,18 @@ abstract class ClassWorld {
/// including [cls] if it is live.
Iterable<ClassElement> strictSubtypesOf(ClassElement cls);
+ /// Returns the number of live classes that implement [cls] _not_
+ /// including [cls] itself.
+ int strictSubtypeCount(ClassElement cls);
+
+ /// Applies [f] to each live class that implements [cls] _not_ including [cls]
+ /// itself.
+ void forEachStrictSubtypeOf(ClassElement cls, ForEach f(ClassElement cls));
+
+ /// Returns `true` if [predicate] applies to any live class that implements
+ /// [cls] _not_ including [cls] itself.
+ bool anyStrictSubtypeOf(ClassElement cls, bool predicate(ClassElement cls));
+
/// Returns `true` if [a] and [b] have any known common subtypes.
bool haveAnyCommonSubtypes(ClassElement a, ClassElement b);
@@ -248,6 +272,36 @@ class World implements ClassWorld {
ClassHierarchyNode.DIRECTLY_INSTANTIATED, strict: true);
}
+ /// Returns the number of live classes that extend [cls] _not_
+ /// including [cls] itself.
+ int strictSubclassCount(ClassElement cls) {
+ ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
+ if (subclasses == null) return 0;
+ return subclasses.instantiatedSubclassCount;
+ }
+
+ /// Applies [f] to each live class that extend [cls] _not_ including [cls]
+ /// itself.
+ void forEachStrictSubclassOf(ClassElement cls, ForEach f(ClassElement cls)) {
+ ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
+ if (subclasses == null) return;
+ subclasses.forEachSubclass(
+ f,
+ ClassHierarchyNode.DIRECTLY_INSTANTIATED,
+ strict: true);
+ }
+
+ /// Returns `true` if [predicate] applies to any live class that extend [cls]
+ /// _not_ including [cls] itself.
+ bool anyStrictSubclassOf(ClassElement cls, bool predicate(ClassElement cls)) {
+ ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
+ if (subclasses == null) return false;
+ return subclasses.anySubclass(
+ predicate,
+ ClassHierarchyNode.DIRECTLY_INSTANTIATED,
+ strict: true);
+ }
+
/// Returns an iterable over the directly instantiated that implement [cls]
/// possibly including [cls] itself, if it is live.
Iterable<ClassElement> subtypesOf(ClassElement cls) {
@@ -272,6 +326,36 @@ class World implements ClassWorld {
}
}
+ /// Returns the number of live classes that implement [cls] _not_
+ /// including [cls] itself.
+ int strictSubtypeCount(ClassElement cls) {
+ ClassSet classSet = _classSets[cls.declaration];
+ if (classSet == null) return 0;
+ return classSet.instantiatedSubtypeCount;
+ }
+
+ /// Applies [f] to each live class that implements [cls] _not_ including [cls]
+ /// itself.
+ void forEachStrictSubtypeOf(ClassElement cls, ForEach f(ClassElement cls)) {
+ ClassSet classSet = _classSets[cls.declaration];
+ if (classSet == null) return;
+ classSet.forEachSubtype(
+ f,
+ ClassHierarchyNode.DIRECTLY_INSTANTIATED,
+ strict: true);
+ }
+
+ /// Returns `true` if [predicate] applies to any live class that extend [cls]
+ /// _not_ including [cls] itself.
+ bool anyStrictSubtypeOf(ClassElement cls, bool predicate(ClassElement cls)) {
+ ClassSet classSet = _classSets[cls.declaration];
+ if (classSet == null) return false;
+ return classSet.anySubtype(
+ predicate,
+ ClassHierarchyNode.DIRECTLY_INSTANTIATED,
+ strict: true);
+ }
+
/// Returns `true` if [a] and [b] have any known common subtypes.
bool haveAnyCommonSubtypes(ClassElement a, ClassElement b) {
ClassSet classSetA = _classSets[a.declaration];
@@ -298,7 +382,7 @@ class World implements ClassWorld {
/// Returns `true` if any directly instantiated class other than [cls]
/// implements [cls].
bool hasAnyStrictSubtype(ClassElement cls) {
- return !strictSubtypesOf(cls).isEmpty;
+ return strictSubtypeCount(cls) > 0;
}
/// Returns `true` if all directly instantiated classes that implement [cls]
@@ -306,10 +390,12 @@ class World implements ClassWorld {
bool hasOnlySubclasses(ClassElement cls) {
// TODO(johnniwinther): move this to ClassSet?
if (cls == objectClass) return true;
- Iterable<ClassElement> subtypes = strictSubtypesOf(cls);
- if (subtypes == null) return true;
- Iterable<ClassElement> subclasses = strictSubclassesOf(cls);
- return subclasses != null && (subclasses.length == subtypes.length);
+ ClassSet classSet = _classSets[cls.declaration];
+ if (classSet == null) {
+ // Vacuously true.
+ return true;
+ }
+ return classSet.hasOnlyInstantiatedSubclasses;
}
@override
@@ -501,11 +587,11 @@ class World implements ClassWorld {
ClassHierarchyNode _ensureClassHierarchyNode(ClassElement cls) {
cls = cls.declaration;
return _classHierarchyNodes.putIfAbsent(cls, () {
- ClassHierarchyNode node = new ClassHierarchyNode(cls);
+ ClassHierarchyNode parentNode;
if (cls.superclass != null) {
- _ensureClassHierarchyNode(cls.superclass).addDirectSubclass(node);
+ parentNode = _ensureClassHierarchyNode(cls.superclass);
}
- return node;
+ return new ClassHierarchyNode(parentNode, cls);
});
}
@@ -534,31 +620,28 @@ class World implements ClassWorld {
});
}
- void _updateClassHierarchyNodeForClass(
- ClassElement cls,
- {bool directlyInstantiated: false,
- bool indirectlyInstantiated: false}) {
- ClassHierarchyNode node = getClassHierarchyNode(cls);
- bool changed = false;
- if (directlyInstantiated && !node.isDirectlyInstantiated) {
- node.isDirectlyInstantiated = true;
- changed = true;
- }
- if (indirectlyInstantiated && !node.isIndirectlyInstantiated) {
- node.isIndirectlyInstantiated = true;
- changed = true;
- }
- if (changed && cls.superclass != null) {
- _updateClassHierarchyNodeForClass(
- cls.superclass, indirectlyInstantiated: true);
- }
+ void _updateSuperClassHierarchyNodeForClass(ClassHierarchyNode node) {
// Ensure that classes implicitly implementing `Function` are in its
// subtype set.
+ ClassElement cls = node.cls;
if (cls != coreClasses.functionClass &&
- cls.implementsFunction(compiler)) {
+ cls.implementsFunction(coreClasses)) {
ClassSet subtypeSet = _ensureClassSet(coreClasses.functionClass);
subtypeSet.addSubtype(node);
}
+ if (!node.isInstantiated && node.parentNode != null) {
+ _updateSuperClassHierarchyNodeForClass(node.parentNode);
+ }
+ }
+
+ void _updateClassHierarchyNodeForClass(
+ ClassElement cls,
+ {bool directlyInstantiated: false}) {
+ ClassHierarchyNode node = getClassHierarchyNode(cls);
+ _updateSuperClassHierarchyNodeForClass(node);
+ if (directlyInstantiated) {
+ node.isDirectlyInstantiated = true;
+ }
}
void populate() {

Powered by Google App Engine
This is Rietveld 408576698