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

Unified Diff: pkg/compiler/lib/src/world.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/universe/world_builder.dart ('k') | tests/compiler/dart2js/class_set_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/world.dart
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index c6a20e07be0c3dee272dbb1560d2cbd0a9eaf229..dbeee8a9338826debdf0a4553368319e350acd46 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -25,6 +25,7 @@ import 'universe/class_set.dart';
import 'universe/function_set.dart' show FunctionSet;
import 'universe/selector.dart' show Selector;
import 'universe/side_effects.dart' show SideEffects;
+import 'util/enumset.dart';
import 'util/util.dart' show Link;
/// Common superinterface for [OpenWorld] and [ClosedWorld].
@@ -48,9 +49,26 @@ abstract class ClosedWorld implements World {
/// Returns `true` if [cls] is either directly or indirectly instantiated.
bool isInstantiated(ClassElement cls);
- /// Returns `true` if [cls] is directly instantiated.
+ /// Returns `true` if [cls] is directly instantiated. This means that at
+ /// runtime instances of exactly [cls] are assumed to exist.
bool isDirectlyInstantiated(ClassElement cls);
+ /// Returns `true` if [cls] is 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 isAbstractlyInstantiated(ClassElement cls);
+
+ /// Returns `true` if [cls] is either directly or abstractly instantiated.
+ ///
+ /// See [isDirectlyInstantiated] and [isAbstractlyInstantiated].
+ bool isExplicitlyInstantiated(ClassElement cls);
+
/// Returns `true` if [cls] is indirectly instantiated, that is through a
/// subclass.
bool isIndirectlyInstantiated(ClassElement cls);
@@ -393,6 +411,20 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
}
@override
+ bool isAbstractlyInstantiated(ClassElement cls) {
+ assert(isClosed);
+ ClassHierarchyNode node = _classHierarchyNodes[cls.declaration];
+ return node != null && node.isAbstractlyInstantiated;
+ }
+
+ @override
+ bool isExplicitlyInstantiated(ClassElement cls) {
+ assert(isClosed);
+ ClassHierarchyNode node = _classHierarchyNodes[cls.declaration];
+ return node != null && node.isExplicitlyInstantiated;
+ }
+
+ @override
bool isIndirectlyInstantiated(ClassElement cls) {
assert(isClosed);
ClassHierarchyNode node = _classHierarchyNodes[cls.declaration];
@@ -414,7 +446,8 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
assert(isClosed);
ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration];
if (hierarchy == null) return const <ClassElement>[];
- return hierarchy.subclassesByMask(ClassHierarchyNode.DIRECTLY_INSTANTIATED);
+ return hierarchy
+ .subclassesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED);
}
/// Returns an iterable over the directly instantiated classes that extend
@@ -423,7 +456,8 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
assert(isClosed);
ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
if (subclasses == null) return const <ClassElement>[];
- return subclasses.subclassesByMask(ClassHierarchyNode.DIRECTLY_INSTANTIATED,
+ return subclasses.subclassesByMask(
+ ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
strict: true);
}
@@ -443,7 +477,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
assert(isClosed);
ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
if (subclasses == null) return;
- subclasses.forEachSubclass(f, ClassHierarchyNode.DIRECTLY_INSTANTIATED,
+ subclasses.forEachSubclass(f, ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
strict: true);
}
@@ -454,7 +488,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
if (subclasses == null) return false;
return subclasses.anySubclass(
- predicate, ClassHierarchyNode.DIRECTLY_INSTANTIATED,
+ predicate, ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
strict: true);
}
@@ -466,7 +500,8 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
if (classSet == null) {
return const <ClassElement>[];
} else {
- return classSet.subtypesByMask(ClassHierarchyNode.DIRECTLY_INSTANTIATED);
+ return classSet
+ .subtypesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED);
}
}
@@ -478,7 +513,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
if (classSet == null) {
return const <ClassElement>[];
} else {
- return classSet.subtypesByMask(ClassHierarchyNode.DIRECTLY_INSTANTIATED,
+ return classSet.subtypesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
strict: true);
}
}
@@ -499,7 +534,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
assert(isClosed);
ClassSet classSet = _classSets[cls.declaration];
if (classSet == null) return;
- classSet.forEachSubtype(f, ClassHierarchyNode.DIRECTLY_INSTANTIATED,
+ classSet.forEachSubtype(f, ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
strict: true);
}
@@ -510,7 +545,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
ClassSet classSet = _classSets[cls.declaration];
if (classSet == null) return false;
return classSet.anySubtype(
- predicate, ClassHierarchyNode.DIRECTLY_INSTANTIATED,
+ predicate, ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
strict: true);
}
@@ -769,7 +804,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
// The root subclass has a concrete implementation so no subclass needs
// noSuchMethod handling.
return false;
- } else if (rootNode.isDirectlyInstantiated) {
+ } else if (rootNode.isExplicitlyInstantiated) {
// The root class need noSuchMethod handling.
return true;
}
@@ -781,7 +816,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
// Stop fast - we found a need for noSuchMethod handling.
return IterationStep.STOP;
}
- }, ClassHierarchyNode.DIRECTLY_INSTANTIATED, strict: true);
+ }, ClassHierarchyNode.EXPLICITLY_INSTANTIATED, strict: true);
// We stopped fast so we need noSuchMethod handling.
return result == IterationStep.STOP;
}
@@ -943,19 +978,22 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
}
void _updateClassHierarchyNodeForClass(ClassElement cls,
- {bool directlyInstantiated: false}) {
+ {bool directlyInstantiated: false, bool abstractlyInstantiated: false}) {
ClassHierarchyNode node = getClassHierarchyNode(cls);
_updateSuperClassHierarchyNodeForClass(node);
if (directlyInstantiated) {
node.isDirectlyInstantiated = true;
}
+ if (abstractlyInstantiated) {
+ node.isAbstractlyInstantiated = true;
+ }
}
ClosedWorld closeWorld() {
/// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated`
/// properties of the [ClassHierarchyNode] for [cls].
- void addSubtypes(ClassElement cls) {
+ void addSubtypes(ClassElement cls, EnumSet<Instantiation> instantiations) {
if (_compiler.options.hasIncrementalSupport &&
!alreadyPopulated.add(cls)) {
return;
@@ -965,7 +1003,11 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
reporter.internalError(cls, 'Class "${cls.name}" is not resolved.');
}
- _updateClassHierarchyNodeForClass(cls, directlyInstantiated: true);
+ _updateClassHierarchyNodeForClass(cls,
+ directlyInstantiated:
+ instantiations.contains(Instantiation.DIRECTLY_INSTANTIATED),
+ abstractlyInstantiated:
+ instantiations.contains(Instantiation.ABSTRACTLY_INSTANTIATED));
// Walk through the superclasses, and record the types
// implemented by that type on the superclasses.
@@ -985,7 +1027,7 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
// classes: if the superclass of these classes require RTI, then
// they also need RTI, so that a constructor passes the type
// variables to the super constructor.
- _compiler.resolverWorld.directlyInstantiatedClasses.forEach(addSubtypes);
+ _compiler.resolverWorld.forEachInstantiatedClass(addSubtypes);
_closed = true;
return this;
« no previous file with comments | « pkg/compiler/lib/src/universe/world_builder.dart ('k') | tests/compiler/dart2js/class_set_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698