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

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

Issue 2425933002: Revert "Change TypeInference to handle super calls as direct invocations." and "Optimize needNoSuch… (Closed)
Patch Set: 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
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..8c69baeb5c8c2653543e8988748a292d6d46405e 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -728,19 +728,16 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
: result.implementation == element.implementation;
}
- Element findMatchIn(ClassElement cls, Selector selector,
- {ClassElement stopAtSuperclass}) {
+ Element findMatchIn(ClassElement cls, Selector selector) {
// Use the [:implementation] of [cls] in case the found [element]
// is in the patch class.
- var result = cls.implementation
- .lookupByName(selector.memberName, stopAt: stopAtSuperclass);
+ var result = cls.implementation.lookupByName(selector.memberName);
return result;
}
/// Returns whether a [selector] call on an instance of [cls]
/// will hit a method at runtime, and not go through [noSuchMethod].
- bool hasConcreteMatch(ClassElement cls, Selector selector,
- {ClassElement stopAtSuperclass}) {
+ bool hasConcreteMatch(ClassElement cls, Selector selector) {
assert(invariant(cls, isInstantiated(cls),
message: '$cls has not been instantiated.'));
Element element = findMatchIn(cls, selector);
@@ -756,49 +753,35 @@ class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
@override
bool needsNoSuchMethod(
ClassElement base, Selector selector, ClassQuery query) {
- /// Returns `true` if subclasses in the [rootNode] tree needs noSuchMethod
- /// handling.
- bool subclassesNeedNoSuchMethod(ClassHierarchyNode rootNode) {
- if (!rootNode.isInstantiated) {
- // No subclass needs noSuchMethod handling since they are all
- // uninstantiated.
+ /// Returns `true` if [cls] is an instantiated class that does not have
+ /// a concrete method matching [selector].
+ bool needsNoSuchMethod(ClassElement cls) {
+ // We can skip uninstantiated subclasses.
+ if (!isInstantiated(cls)) {
return false;
}
- ClassElement rootClass = rootNode.cls;
- if (hasConcreteMatch(rootClass, selector)) {
- // The root subclass has a concrete implementation so no subclass needs
- // noSuchMethod handling.
- return false;
- } else if (rootNode.isDirectlyInstantiated) {
- // The root class need noSuchMethod handling.
- return true;
- }
- IterationStep result = rootNode.forEachSubclass((ClassElement subclass) {
- if (hasConcreteMatch(subclass, selector, stopAtSuperclass: rootClass)) {
- // Found a match - skip all subclasses.
- return IterationStep.SKIP_SUBCLASSES;
- } else {
- // Stop fast - we found a need for noSuchMethod handling.
- return IterationStep.STOP;
- }
- }, ClassHierarchyNode.DIRECTLY_INSTANTIATED, strict: true);
- // We stopped fast so we need noSuchMethod handling.
- return result == IterationStep.STOP;
+ // We can just skip abstract classes because we know no
+ // instance of them will be created at runtime, and
+ // therefore there is no instance that will require
+ // [noSuchMethod] handling.
+ return !cls.isAbstract && !hasConcreteMatch(cls, selector);
}
- ClassSet classSet = getClassSet(base);
- ClassHierarchyNode node = classSet.node;
- if (query == ClassQuery.EXACT) {
- return node.isDirectlyInstantiated && !hasConcreteMatch(base, selector);
- } else if (query == ClassQuery.SUBCLASS) {
- return subclassesNeedNoSuchMethod(node);
+ bool baseNeedsNoSuchMethod = needsNoSuchMethod(base);
+ if (query == ClassQuery.EXACT || baseNeedsNoSuchMethod) {
+ return baseNeedsNoSuchMethod;
+ }
+
+ Iterable<ClassElement> subclassesToCheck;
+ if (query == ClassQuery.SUBTYPE) {
+ subclassesToCheck = strictSubtypesOf(base);
} else {
- if (subclassesNeedNoSuchMethod(node)) return true;
- for (ClassHierarchyNode subtypeNode in classSet.subtypeNodes) {
- if (subclassesNeedNoSuchMethod(subtypeNode)) return true;
- }
- return false;
+ assert(query == ClassQuery.SUBCLASS);
+ subclassesToCheck = strictSubclassesOf(base);
}
+
+ return subclassesToCheck != null &&
+ subclassesToCheck.any(needsNoSuchMethod);
}
final Compiler _compiler;
« no previous file with comments | « pkg/compiler/lib/src/universe/world_builder.dart ('k') | tests/compiler/dart2js/needs_no_such_method_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698