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

Unified Diff: pkg/compiler/lib/src/universe/class_set.dart

Issue 2443953002: Introduce isAbstractlyInstantiated to avoid exact masks of abstract classes. (Closed)
Patch Set: Updated cf. comments. Created 4 years, 2 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
« no previous file with comments | « pkg/compiler/lib/src/types/union_type_mask.dart ('k') | pkg/compiler/lib/src/universe/world_builder.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/universe/class_set.dart
diff --git a/pkg/compiler/lib/src/universe/class_set.dart b/pkg/compiler/lib/src/universe/class_set.dart
index 637fd168f1c891cd59fa934c21897837dd8384d3..39f507a30305c91a64405129c793c8d6486fdfa6 100644
--- a/pkg/compiler/lib/src/universe/class_set.dart
+++ b/pkg/compiler/lib/src/universe/class_set.dart
@@ -6,6 +6,7 @@ library dart2js.world.class_set;
import 'dart:collection' show IterableBase;
+import '../common.dart';
import '../elements/elements.dart' show ClassElement;
import '../util/enumset.dart' show EnumSet;
import '../util/util.dart' show Link;
@@ -15,6 +16,7 @@ enum Instantiation {
UNINSTANTIATED,
DIRECTLY_INSTANTIATED,
INDIRECTLY_INSTANTIATED,
+ ABSTRACTLY_INSTANTIATED,
}
/// Node for [cls] in a tree forming the subclass relation of [ClassElement]s.
@@ -49,16 +51,18 @@ class ClassHierarchyNode {
static final EnumSet<Instantiation> INSTANTIATED =
new EnumSet<Instantiation>.fromValues(const <Instantiation>[
Instantiation.DIRECTLY_INSTANTIATED,
- Instantiation.INDIRECTLY_INSTANTIATED
+ Instantiation.INDIRECTLY_INSTANTIATED,
+ Instantiation.ABSTRACTLY_INSTANTIATED,
], fixed: true);
- /// Enum set for selecting directly instantiated classes in
+ /// Enum set for selecting directly and abstractly instantiated classes in
/// [ClassHierarchyNode.subclassesByMask],
/// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
- static final EnumSet<Instantiation> DIRECTLY_INSTANTIATED =
- new EnumSet<Instantiation>.fromValues(
- const <Instantiation>[Instantiation.DIRECTLY_INSTANTIATED],
- fixed: true);
+ static final EnumSet<Instantiation> EXPLICITLY_INSTANTIATED =
+ new EnumSet<Instantiation>.fromValues(const <Instantiation>[
+ Instantiation.DIRECTLY_INSTANTIATED,
+ Instantiation.ABSTRACTLY_INSTANTIATED
+ ], fixed: true);
/// Enum set for selecting all classes in
/// [ClassHierarchyNode.subclassesByMask],
@@ -72,7 +76,8 @@ class ClassHierarchyNode {
static EnumSet<Instantiation> createMask(
{bool includeDirectlyInstantiated: true,
bool includeIndirectlyInstantiated: true,
- bool includeUninstantiated: true}) {
+ bool includeUninstantiated: true,
+ bool includeAbstractlyInstantiated: true}) {
EnumSet<Instantiation> mask = new EnumSet<Instantiation>();
if (includeDirectlyInstantiated) {
mask.add(Instantiation.DIRECTLY_INSTANTIATED);
@@ -83,6 +88,9 @@ class ClassHierarchyNode {
if (includeUninstantiated) {
mask.add(Instantiation.UNINSTANTIATED);
}
+ if (includeAbstractlyInstantiated) {
+ mask.add(Instantiation.ABSTRACTLY_INSTANTIATED);
+ }
return mask;
}
@@ -106,23 +114,54 @@ class ClassHierarchyNode {
void set isDirectlyInstantiated(bool value) {
if (value != isDirectlyInstantiated) {
- ClassHierarchyNode parent = parentNode;
- if (value) {
- _mask.remove(Instantiation.UNINSTANTIATED);
- _mask.add(Instantiation.DIRECTLY_INSTANTIATED);
- while (parent != null) {
- parent._updateInstantiatedSubclassCount(1);
- parent = parent.parentNode;
- }
- } else {
- _mask.remove(Instantiation.DIRECTLY_INSTANTIATED);
- if (_mask.isEmpty) {
- _mask.add(Instantiation.UNINSTANTIATED);
- }
- while (parent != null) {
- parent._updateInstantiatedSubclassCount(-1);
- parent = parent.parentNode;
- }
+ _updateParentInstantiatedSubclassCount(
+ Instantiation.DIRECTLY_INSTANTIATED,
+ add: value);
+ }
+ }
+
+ /// `true` if [cls] has been abstractly instantiated. This means that at
+ /// runtime instances of [cls] or unknown subclasses of [cls] are assumed to
+ /// exist.
+ ///
+ /// This is used to mark native and/or reflectable classes as instantiated.
+ /// For native classes we do not know the exact class that instantiates [cls]
+ /// so [cls] here represents the root of the subclasses. For reflectable
+ /// classes we need event abstract classes to be 'live' even though they
+ /// cannot themselves be instantiated.
+ bool get isAbstractlyInstantiated =>
+ _mask.contains(Instantiation.ABSTRACTLY_INSTANTIATED);
+
+ void set isAbstractlyInstantiated(bool value) {
+ if (value != isAbstractlyInstantiated) {
+ _updateParentInstantiatedSubclassCount(
+ Instantiation.ABSTRACTLY_INSTANTIATED,
+ add: value);
+ }
+ }
+
+ /// `true` if [cls] is either directly or abstractly instantiated.
+ bool get isExplicitlyInstantiated =>
+ isDirectlyInstantiated || isAbstractlyInstantiated;
+
+ void _updateParentInstantiatedSubclassCount(Instantiation instantiation,
+ {bool add}) {
+ ClassHierarchyNode parent = parentNode;
+ if (add) {
+ _mask.remove(Instantiation.UNINSTANTIATED);
+ _mask.add(instantiation);
+ while (parent != null) {
+ parent._updateInstantiatedSubclassCount(1);
+ parent = parent.parentNode;
+ }
+ } else {
+ _mask.remove(instantiation);
+ if (_mask.isEmpty) {
+ _mask.add(Instantiation.UNINSTANTIATED);
+ }
+ while (parent != null) {
+ parent._updateInstantiatedSubclassCount(-1);
+ parent = parent.parentNode;
}
}
}
@@ -188,8 +227,9 @@ class ClassHierarchyNode {
return false;
}
- /// `true` if [cls] has been directly or indirectly instantiated.
- bool get isInstantiated => isDirectlyInstantiated || isIndirectlyInstantiated;
+ /// `true` if [cls] has been directly, indirectly, or abstractly instantiated.
+ bool get isInstantiated =>
+ isExplicitlyInstantiated || isIndirectlyInstantiated;
/// Returns an [Iterable] of the subclasses of [cls] possibly including [cls].
///
@@ -270,9 +310,12 @@ class ClassHierarchyNode {
}
ClassElement _computeLeastUpperInstantiatedSubclass() {
- if (isDirectlyInstantiated) {
+ if (isExplicitlyInstantiated) {
return cls;
}
+ if (!isInstantiated) {
+ return null;
+ }
ClassHierarchyNode subclass;
for (Link<ClassHierarchyNode> link = _directSubclasses;
!link.isEmpty;
@@ -311,6 +354,9 @@ class ClassHierarchyNode {
if (isIndirectlyInstantiated) {
sb.write(' indirectly');
}
+ if (isAbstractlyInstantiated) {
+ sb.write(' abstractly');
+ }
sb.write(' [');
if (_directSubclasses.isEmpty) {
sb.write(']');
@@ -439,7 +485,7 @@ class ClassSet {
int count = node.instantiatedSubclassCount;
if (_subtypes != null) {
for (ClassHierarchyNode subtypeNode in _subtypes) {
- if (subtypeNode.isDirectlyInstantiated) {
+ if (subtypeNode.isExplicitlyInstantiated) {
count++;
}
count += subtypeNode.instantiatedSubclassCount;
@@ -647,7 +693,7 @@ class ClassSet {
}
ClassElement _computeLeastUpperInstantiatedSubtype() {
- if (node.isDirectlyInstantiated) {
+ if (node.isExplicitlyInstantiated) {
return cls;
}
if (_subtypes == null) {
« no previous file with comments | « pkg/compiler/lib/src/types/union_type_mask.dart ('k') | pkg/compiler/lib/src/universe/world_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698