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

Side by Side 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 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 library dart2js.world; 5 library dart2js.world;
6 6
7 import 'closure.dart' show SynthesizedCallMethodElementX; 7 import 'closure.dart' show SynthesizedCallMethodElementX;
8 import 'common/backend_api.dart' show BackendClasses; 8 import 'common/backend_api.dart' show BackendClasses;
9 import 'common.dart'; 9 import 'common.dart';
10 import 'compiler.dart' show Compiler; 10 import 'compiler.dart' show Compiler;
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 @override 721 @override
722 bool hasElementIn(ClassElement cls, Selector selector, Element element) { 722 bool hasElementIn(ClassElement cls, Selector selector, Element element) {
723 // Use [:implementation:] of [element] 723 // Use [:implementation:] of [element]
724 // because our function set only stores declarations. 724 // because our function set only stores declarations.
725 Element result = findMatchIn(cls, selector); 725 Element result = findMatchIn(cls, selector);
726 return result == null 726 return result == null
727 ? false 727 ? false
728 : result.implementation == element.implementation; 728 : result.implementation == element.implementation;
729 } 729 }
730 730
731 Element findMatchIn(ClassElement cls, Selector selector, 731 Element findMatchIn(ClassElement cls, Selector selector) {
732 {ClassElement stopAtSuperclass}) {
733 // Use the [:implementation] of [cls] in case the found [element] 732 // Use the [:implementation] of [cls] in case the found [element]
734 // is in the patch class. 733 // is in the patch class.
735 var result = cls.implementation 734 var result = cls.implementation.lookupByName(selector.memberName);
736 .lookupByName(selector.memberName, stopAt: stopAtSuperclass);
737 return result; 735 return result;
738 } 736 }
739 737
740 /// Returns whether a [selector] call on an instance of [cls] 738 /// Returns whether a [selector] call on an instance of [cls]
741 /// will hit a method at runtime, and not go through [noSuchMethod]. 739 /// will hit a method at runtime, and not go through [noSuchMethod].
742 bool hasConcreteMatch(ClassElement cls, Selector selector, 740 bool hasConcreteMatch(ClassElement cls, Selector selector) {
743 {ClassElement stopAtSuperclass}) {
744 assert(invariant(cls, isInstantiated(cls), 741 assert(invariant(cls, isInstantiated(cls),
745 message: '$cls has not been instantiated.')); 742 message: '$cls has not been instantiated.'));
746 Element element = findMatchIn(cls, selector); 743 Element element = findMatchIn(cls, selector);
747 if (element == null) return false; 744 if (element == null) return false;
748 745
749 if (element.isAbstract) { 746 if (element.isAbstract) {
750 ClassElement enclosingClass = element.enclosingClass; 747 ClassElement enclosingClass = element.enclosingClass;
751 return hasConcreteMatch(enclosingClass.superclass, selector); 748 return hasConcreteMatch(enclosingClass.superclass, selector);
752 } 749 }
753 return selector.appliesUntyped(element); 750 return selector.appliesUntyped(element);
754 } 751 }
755 752
756 @override 753 @override
757 bool needsNoSuchMethod( 754 bool needsNoSuchMethod(
758 ClassElement base, Selector selector, ClassQuery query) { 755 ClassElement base, Selector selector, ClassQuery query) {
759 /// Returns `true` if subclasses in the [rootNode] tree needs noSuchMethod 756 /// Returns `true` if [cls] is an instantiated class that does not have
760 /// handling. 757 /// a concrete method matching [selector].
761 bool subclassesNeedNoSuchMethod(ClassHierarchyNode rootNode) { 758 bool needsNoSuchMethod(ClassElement cls) {
762 if (!rootNode.isInstantiated) { 759 // We can skip uninstantiated subclasses.
763 // No subclass needs noSuchMethod handling since they are all 760 if (!isInstantiated(cls)) {
764 // uninstantiated.
765 return false; 761 return false;
766 } 762 }
767 ClassElement rootClass = rootNode.cls; 763 // We can just skip abstract classes because we know no
768 if (hasConcreteMatch(rootClass, selector)) { 764 // instance of them will be created at runtime, and
769 // The root subclass has a concrete implementation so no subclass needs 765 // therefore there is no instance that will require
770 // noSuchMethod handling. 766 // [noSuchMethod] handling.
771 return false; 767 return !cls.isAbstract && !hasConcreteMatch(cls, selector);
772 } else if (rootNode.isDirectlyInstantiated) {
773 // The root class need noSuchMethod handling.
774 return true;
775 }
776 IterationStep result = rootNode.forEachSubclass((ClassElement subclass) {
777 if (hasConcreteMatch(subclass, selector, stopAtSuperclass: rootClass)) {
778 // Found a match - skip all subclasses.
779 return IterationStep.SKIP_SUBCLASSES;
780 } else {
781 // Stop fast - we found a need for noSuchMethod handling.
782 return IterationStep.STOP;
783 }
784 }, ClassHierarchyNode.DIRECTLY_INSTANTIATED, strict: true);
785 // We stopped fast so we need noSuchMethod handling.
786 return result == IterationStep.STOP;
787 } 768 }
788 769
789 ClassSet classSet = getClassSet(base); 770 bool baseNeedsNoSuchMethod = needsNoSuchMethod(base);
790 ClassHierarchyNode node = classSet.node; 771 if (query == ClassQuery.EXACT || baseNeedsNoSuchMethod) {
791 if (query == ClassQuery.EXACT) { 772 return baseNeedsNoSuchMethod;
792 return node.isDirectlyInstantiated && !hasConcreteMatch(base, selector); 773 }
793 } else if (query == ClassQuery.SUBCLASS) { 774
794 return subclassesNeedNoSuchMethod(node); 775 Iterable<ClassElement> subclassesToCheck;
776 if (query == ClassQuery.SUBTYPE) {
777 subclassesToCheck = strictSubtypesOf(base);
795 } else { 778 } else {
796 if (subclassesNeedNoSuchMethod(node)) return true; 779 assert(query == ClassQuery.SUBCLASS);
797 for (ClassHierarchyNode subtypeNode in classSet.subtypeNodes) { 780 subclassesToCheck = strictSubclassesOf(base);
798 if (subclassesNeedNoSuchMethod(subtypeNode)) return true;
799 }
800 return false;
801 } 781 }
782
783 return subclassesToCheck != null &&
784 subclassesToCheck.any(needsNoSuchMethod);
802 } 785 }
803 786
804 final Compiler _compiler; 787 final Compiler _compiler;
805 BackendClasses get backendClasses => _backend.backendClasses; 788 BackendClasses get backendClasses => _backend.backendClasses;
806 JavaScriptBackend get _backend => _compiler.backend; 789 JavaScriptBackend get _backend => _compiler.backend;
807 CommonMasks get commonMasks => _compiler.commonMasks; 790 CommonMasks get commonMasks => _compiler.commonMasks;
808 final FunctionSet allFunctions; 791 final FunctionSet allFunctions;
809 final Set<Element> functionsCalledInLoop = new Set<Element>(); 792 final Set<Element> functionsCalledInLoop = new Set<Element>();
810 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); 793 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>();
811 794
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 /// Only the class itself is included. 1143 /// Only the class itself is included.
1161 EXACT, 1144 EXACT,
1162 1145
1163 /// The class and all subclasses (transitively) are included. 1146 /// The class and all subclasses (transitively) are included.
1164 SUBCLASS, 1147 SUBCLASS,
1165 1148
1166 /// The class and all classes that implement or subclass it (transitively) 1149 /// The class and all classes that implement or subclass it (transitively)
1167 /// are included. 1150 /// are included.
1168 SUBTYPE, 1151 SUBTYPE,
1169 } 1152 }
OLDNEW
« 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