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

Side by Side Diff: pkg/compiler/lib/src/world.dart

Issue 2488353004: Remove Compiler access from ResolutionEnqueuer (Closed)
Patch Set: Updated cf. comments. Created 4 years, 1 month 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 'cache_strategy.dart';
7 import 'closure.dart' show SynthesizedCallMethodElementX; 8 import 'closure.dart' show SynthesizedCallMethodElementX;
8 import 'common/backend_api.dart' show BackendClasses; 9 import 'common/backend_api.dart' show BackendClasses;
9 import 'common.dart'; 10 import 'common.dart';
10 import 'compiler.dart' show Compiler;
11 import 'core_types.dart' show CoreClasses; 11 import 'core_types.dart' show CoreClasses;
12 import 'dart_types.dart'; 12 import 'dart_types.dart';
13 import 'elements/elements.dart' 13 import 'elements/elements.dart'
14 show 14 show
15 ClassElement, 15 ClassElement,
16 Element, 16 Element,
17 FunctionElement, 17 FunctionElement,
18 MixinApplicationElement, 18 MixinApplicationElement,
19 TypedefElement, 19 TypedefElement,
20 FieldElement; 20 FieldElement;
21 import 'js_backend/backend.dart' show JavaScriptBackend; 21 import 'js_backend/backend.dart' show JavaScriptBackend;
22 import 'ordered_typeset.dart'; 22 import 'ordered_typeset.dart';
23 import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask; 23 import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask;
24 import 'universe/class_set.dart'; 24 import 'universe/class_set.dart';
25 import 'universe/function_set.dart' show FunctionSet; 25 import 'universe/function_set.dart' show FunctionSet;
26 import 'universe/selector.dart' show Selector; 26 import 'universe/selector.dart' show Selector;
27 import 'universe/side_effects.dart' show SideEffects; 27 import 'universe/side_effects.dart' show SideEffects;
28 import 'universe/world_builder.dart' show ResolutionWorldBuilder;
28 import 'util/enumset.dart'; 29 import 'util/enumset.dart';
29 import 'util/util.dart' show Link; 30 import 'util/util.dart' show Link;
30 31
31 /// Common superinterface for [OpenWorld] and [ClosedWorld]. 32 /// Common superinterface for [OpenWorld] and [ClosedWorld].
32 abstract class World {} 33 abstract class World {}
33 34
34 /// The [ClosedWorld] represents the information known about a program when 35 /// The [ClosedWorld] represents the information known about a program when
35 /// compiling with closed-world semantics. 36 /// compiling with closed-world semantics.
36 /// 37 ///
37 /// Given the entrypoint of an application, we can track what's reachable from 38 /// Given the entrypoint of an application, we can track what's reachable from
38 /// it, what functions are called, what classes are allocated, which native 39 /// it, what functions are called, what classes are allocated, which native
39 /// JavaScript types are touched, what language features are used, and so on. 40 /// JavaScript types are touched, what language features are used, and so on.
40 /// This precise knowledge about what's live in the program is later used in 41 /// This precise knowledge about what's live in the program is later used in
41 /// optimizations and other compiler decisions during code generation. 42 /// optimizations and other compiler decisions during code generation.
42 abstract class ClosedWorld implements World { 43 abstract class ClosedWorld implements World {
43 /// Access to core classes used by the backend. 44 /// Access to core classes used by the backend.
44 BackendClasses get backendClasses; 45 BackendClasses get backendClasses;
45 46
46 /// Access to core classes used in the Dart language. 47 /// Access to core classes used in the Dart language.
47 CoreClasses get coreClasses; 48 CoreClasses get coreClasses;
48 49
50 CommonMasks get commonMasks;
51
49 /// Returns `true` if [cls] is either directly or indirectly instantiated. 52 /// Returns `true` if [cls] is either directly or indirectly instantiated.
50 bool isInstantiated(ClassElement cls); 53 bool isInstantiated(ClassElement cls);
51 54
52 /// Returns `true` if [cls] is directly instantiated. This means that at 55 /// Returns `true` if [cls] is directly instantiated. This means that at
53 /// runtime instances of exactly [cls] are assumed to exist. 56 /// runtime instances of exactly [cls] are assumed to exist.
54 bool isDirectlyInstantiated(ClassElement cls); 57 bool isDirectlyInstantiated(ClassElement cls);
55 58
56 /// Returns `true` if [cls] is abstractly instantiated. This means that at 59 /// Returns `true` if [cls] is abstractly instantiated. This means that at
57 /// runtime instances of [cls] or unknown subclasses of [cls] are assumed to 60 /// runtime instances of [cls] or unknown subclasses of [cls] are assumed to
58 /// exist. 61 /// exist.
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 abstract class OpenWorld implements World { 330 abstract class OpenWorld implements World {
328 /// Called to add [cls] to the set of known classes. 331 /// Called to add [cls] to the set of known classes.
329 /// 332 ///
330 /// This ensures that class hierarchy queries can be performed on [cls] and 333 /// This ensures that class hierarchy queries can be performed on [cls] and
331 /// classes that extend or implement it. 334 /// classes that extend or implement it.
332 void registerClass(ClassElement cls); 335 void registerClass(ClassElement cls);
333 336
334 void registerUsedElement(Element element); 337 void registerUsedElement(Element element);
335 void registerTypedef(TypedefElement typedef); 338 void registerTypedef(TypedefElement typedef);
336 339
337 ClosedWorld closeWorld(); 340 ClosedWorld closeWorld(DiagnosticReporter reporter);
338 341
339 /// Returns an iterable over all mixin applications that mixin [cls]. 342 /// Returns an iterable over all mixin applications that mixin [cls].
340 Iterable<MixinApplicationElement> allMixinUsesOf(ClassElement cls); 343 Iterable<MixinApplicationElement> allMixinUsesOf(ClassElement cls);
341 } 344 }
342 345
343 class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld { 346 class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
344 bool _closed = false; 347 bool _closed = false;
345 348
346 TypeMask getCachedMask(ClassElement base, int flags, TypeMask createMask()) { 349 TypeMask getCachedMask(ClassElement base, int flags, TypeMask createMask()) {
347 Map<ClassElement, TypeMask> cachedMasks = 350 Map<ClassElement, TypeMask> cachedMasks =
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 ClassHierarchyNode node = _classHierarchyNodes[cls.declaration]; 433 ClassHierarchyNode node = _classHierarchyNodes[cls.declaration];
431 return node != null && node.isIndirectlyInstantiated; 434 return node != null && node.isIndirectlyInstantiated;
432 } 435 }
433 436
434 @override 437 @override
435 bool isAbstract(ClassElement cls) => cls.isAbstract; 438 bool isAbstract(ClassElement cls) => cls.isAbstract;
436 439
437 /// Returns `true` if [cls] is implemented by an instantiated class. 440 /// Returns `true` if [cls] is implemented by an instantiated class.
438 bool isImplemented(ClassElement cls) { 441 bool isImplemented(ClassElement cls) {
439 assert(isClosed); 442 assert(isClosed);
440 return _compiler.resolverWorld.isImplemented(cls); 443 return resolverWorld.isImplemented(cls);
441 } 444 }
442 445
443 /// Returns an iterable over the directly instantiated classes that extend 446 /// Returns an iterable over the directly instantiated classes that extend
444 /// [cls] possibly including [cls] itself, if it is live. 447 /// [cls] possibly including [cls] itself, if it is live.
445 Iterable<ClassElement> subclassesOf(ClassElement cls) { 448 Iterable<ClassElement> subclassesOf(ClassElement cls) {
446 assert(isClosed); 449 assert(isClosed);
447 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration]; 450 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration];
448 if (hierarchy == null) return const <ClassElement>[]; 451 if (hierarchy == null) return const <ClassElement>[];
449 return hierarchy 452 return hierarchy
450 .subclassesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED); 453 .subclassesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED);
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 return subclassesNeedNoSuchMethod(node); 832 return subclassesNeedNoSuchMethod(node);
830 } else { 833 } else {
831 if (subclassesNeedNoSuchMethod(node)) return true; 834 if (subclassesNeedNoSuchMethod(node)) return true;
832 for (ClassHierarchyNode subtypeNode in classSet.subtypeNodes) { 835 for (ClassHierarchyNode subtypeNode in classSet.subtypeNodes) {
833 if (subclassesNeedNoSuchMethod(subtypeNode)) return true; 836 if (subclassesNeedNoSuchMethod(subtypeNode)) return true;
834 } 837 }
835 return false; 838 return false;
836 } 839 }
837 } 840 }
838 841
839 final Compiler _compiler; 842 final JavaScriptBackend _backend;
840 BackendClasses get backendClasses => _backend.backendClasses; 843 BackendClasses get backendClasses => _backend.backendClasses;
841 JavaScriptBackend get _backend => _compiler.backend; 844 FunctionSet _allFunctions;
842 CommonMasks get commonMasks => _compiler.commonMasks;
843 final FunctionSet allFunctions;
844 final Set<Element> functionsCalledInLoop = new Set<Element>(); 845 final Set<Element> functionsCalledInLoop = new Set<Element>();
845 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); 846 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>();
846 847
847 final Set<TypedefElement> _allTypedefs = new Set<TypedefElement>(); 848 final Set<TypedefElement> _allTypedefs = new Set<TypedefElement>();
848 849
849 final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses = 850 final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses =
850 new Map<ClassElement, Set<MixinApplicationElement>>(); 851 new Map<ClassElement, Set<MixinApplicationElement>>();
851 Map<ClassElement, List<MixinApplicationElement>> _liveMixinUses; 852 Map<ClassElement, List<MixinApplicationElement>> _liveMixinUses;
852 853
853 final Map<ClassElement, Set<ClassElement>> _typesImplementedBySubclasses = 854 final Map<ClassElement, Set<ClassElement>> _typesImplementedBySubclasses =
(...skipping 10 matching lines...) Expand all
864 865
865 final Set<Element> sideEffectsFreeElements = new Set<Element>(); 866 final Set<Element> sideEffectsFreeElements = new Set<Element>();
866 867
867 final Set<Element> elementsThatCannotThrow = new Set<Element>(); 868 final Set<Element> elementsThatCannotThrow = new Set<Element>();
868 869
869 final Set<Element> functionsThatMightBePassedToApply = 870 final Set<Element> functionsThatMightBePassedToApply =
870 new Set<FunctionElement>(); 871 new Set<FunctionElement>();
871 872
872 final Set<Element> alreadyPopulated; 873 final Set<Element> alreadyPopulated;
873 874
875 CommonMasks _commonMasks;
876
877 final CoreClasses coreClasses;
878
879 final CacheStrategy cacheStrategy;
880
881 final ResolutionWorldBuilder resolverWorld;
882
874 bool get isClosed => _closed; 883 bool get isClosed => _closed;
875 884
876 Set<ClassElement> typesImplementedBySubclassesOf(ClassElement cls) { 885 Set<ClassElement> typesImplementedBySubclassesOf(ClassElement cls) {
877 return _typesImplementedBySubclasses[cls.declaration]; 886 return _typesImplementedBySubclasses[cls.declaration];
878 } 887 }
879 888
880 WorldImpl(Compiler compiler) 889 WorldImpl(this.resolverWorld, this._backend, this.coreClasses,
881 : allFunctions = new FunctionSet(compiler), 890 CacheStrategy cacheStrategy)
882 this._compiler = compiler, 891 : this.cacheStrategy = cacheStrategy,
883 alreadyPopulated = compiler.cacheStrategy.newSet(); 892 alreadyPopulated = cacheStrategy.newSet() {
893 _allFunctions = new FunctionSet(this);
894 }
884 895
885 CoreClasses get coreClasses => _compiler.coreClasses; 896 FunctionSet get allFunctions => _allFunctions;
886 897
887 DiagnosticReporter get reporter => _compiler.reporter; 898 CommonMasks get commonMasks {
899 assert(isClosed);
900 return _commonMasks;
901 }
888 902
889 /// Called to add [cls] to the set of known classes. 903 /// Called to add [cls] to the set of known classes.
890 /// 904 ///
891 /// This ensures that class hierarchy queries can be performed on [cls] and 905 /// This ensures that class hierarchy queries can be performed on [cls] and
892 /// classes that extend or implement it. 906 /// classes that extend or implement it.
893 void registerClass(ClassElement cls) => _registerClass(cls); 907 void registerClass(ClassElement cls) => _registerClass(cls);
894 908
895 void registerClosureClass(ClassElement cls) { 909 void registerClosureClass(ClassElement cls) {
896 _registerClass(cls, isDirectlyInstantiated: true); 910 _registerClass(cls, isDirectlyInstantiated: true);
897 } 911 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 ClassSet subtypeSet = _ensureClassSet(coreClasses.functionClass); 986 ClassSet subtypeSet = _ensureClassSet(coreClasses.functionClass);
973 subtypeSet.addSubtype(node); 987 subtypeSet.addSubtype(node);
974 } 988 }
975 if (!node.isInstantiated && node.parentNode != null) { 989 if (!node.isInstantiated && node.parentNode != null) {
976 _updateSuperClassHierarchyNodeForClass(node.parentNode); 990 _updateSuperClassHierarchyNodeForClass(node.parentNode);
977 } 991 }
978 } 992 }
979 993
980 void _updateClassHierarchyNodeForClass(ClassElement cls, 994 void _updateClassHierarchyNodeForClass(ClassElement cls,
981 {bool directlyInstantiated: false, bool abstractlyInstantiated: false}) { 995 {bool directlyInstantiated: false, bool abstractlyInstantiated: false}) {
982 ClassHierarchyNode node = getClassHierarchyNode(cls); 996 ClassHierarchyNode node = _ensureClassHierarchyNode(cls);
983 _updateSuperClassHierarchyNodeForClass(node); 997 _updateSuperClassHierarchyNodeForClass(node);
984 if (directlyInstantiated) { 998 if (directlyInstantiated) {
985 node.isDirectlyInstantiated = true; 999 node.isDirectlyInstantiated = true;
986 } 1000 }
987 if (abstractlyInstantiated) { 1001 if (abstractlyInstantiated) {
988 node.isAbstractlyInstantiated = true; 1002 node.isAbstractlyInstantiated = true;
989 } 1003 }
990 } 1004 }
991 1005
992 ClosedWorld closeWorld() { 1006 ClosedWorld closeWorld(DiagnosticReporter reporter) {
993 /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated` 1007 /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated`
994 /// properties of the [ClassHierarchyNode] for [cls]. 1008 /// properties of the [ClassHierarchyNode] for [cls].
995 1009
996 void addSubtypes(ClassElement cls, EnumSet<Instantiation> instantiations) { 1010 void addSubtypes(ClassElement cls, EnumSet<Instantiation> instantiations) {
997 if (_compiler.options.hasIncrementalSupport && 1011 if (cacheStrategy.hasIncrementalSupport && !alreadyPopulated.add(cls)) {
998 !alreadyPopulated.add(cls)) {
999 return; 1012 return;
1000 } 1013 }
1001 assert(cls.isDeclaration); 1014 assert(cls.isDeclaration);
1002 if (!cls.isResolved) { 1015 if (!cls.isResolved) {
1003 reporter.internalError(cls, 'Class "${cls.name}" is not resolved.'); 1016 reporter.internalError(cls, 'Class "${cls.name}" is not resolved.');
1004 } 1017 }
1005 1018
1006 _updateClassHierarchyNodeForClass(cls, 1019 _updateClassHierarchyNodeForClass(cls,
1007 directlyInstantiated: 1020 directlyInstantiated:
1008 instantiations.contains(Instantiation.DIRECTLY_INSTANTIATED), 1021 instantiations.contains(Instantiation.DIRECTLY_INSTANTIATED),
(...skipping 11 matching lines...) Expand all
1020 typesImplementedBySubclassesOfCls.add(current.element); 1033 typesImplementedBySubclassesOfCls.add(current.element);
1021 } 1034 }
1022 superclass = superclass.superclass; 1035 superclass = superclass.superclass;
1023 } 1036 }
1024 } 1037 }
1025 1038
1026 // Use the [:seenClasses:] set to include non-instantiated 1039 // Use the [:seenClasses:] set to include non-instantiated
1027 // classes: if the superclass of these classes require RTI, then 1040 // classes: if the superclass of these classes require RTI, then
1028 // they also need RTI, so that a constructor passes the type 1041 // they also need RTI, so that a constructor passes the type
1029 // variables to the super constructor. 1042 // variables to the super constructor.
1030 _compiler.resolverWorld.forEachInstantiatedClass(addSubtypes); 1043 resolverWorld.forEachInstantiatedClass(addSubtypes);
1031 1044
1032 _closed = true; 1045 _closed = true;
1046 _commonMasks = new CommonMasks(this);
1033 return this; 1047 return this;
1034 } 1048 }
1035 1049
1036 @override 1050 @override
1037 String dump([ClassElement cls]) { 1051 String dump([ClassElement cls]) {
1038 StringBuffer sb = new StringBuffer(); 1052 StringBuffer sb = new StringBuffer();
1039 if (cls != null) { 1053 if (cls != null) {
1040 sb.write("Classes in the closed world related to $cls:\n"); 1054 sb.write("Classes in the closed world related to $cls:\n");
1041 } else { 1055 } else {
1042 sb.write("Instantiated classes in the closed world:\n"); 1056 sb.write("Instantiated classes in the closed world:\n");
(...skipping 22 matching lines...) Expand all
1065 allFunctions.add(element); 1079 allFunctions.add(element);
1066 } 1080 }
1067 } 1081 }
1068 1082
1069 FieldElement locateSingleField(Selector selector, TypeMask mask) { 1083 FieldElement locateSingleField(Selector selector, TypeMask mask) {
1070 Element result = locateSingleElement(selector, mask); 1084 Element result = locateSingleElement(selector, mask);
1071 return (result != null && result.isField) ? result : null; 1085 return (result != null && result.isField) ? result : null;
1072 } 1086 }
1073 1087
1074 Element locateSingleElement(Selector selector, TypeMask mask) { 1088 Element locateSingleElement(Selector selector, TypeMask mask) {
1089 assert(isClosed);
1075 mask ??= commonMasks.dynamicType; 1090 mask ??= commonMasks.dynamicType;
1076 return mask.locateSingleElement(selector, _compiler); 1091 return mask.locateSingleElement(selector, this);
1077 } 1092 }
1078 1093
1079 TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) { 1094 TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) {
1095 assert(isClosed);
1080 bool canReachAll = true; 1096 bool canReachAll = true;
1081 if (mask != null) { 1097 if (mask != null) {
1082 canReachAll = _compiler.enabledInvokeOn && 1098 canReachAll = _backend.hasInvokeOnSupport &&
1083 mask.needsNoSuchMethodHandling(selector, this); 1099 mask.needsNoSuchMethodHandling(selector, this);
1084 } 1100 }
1085 return canReachAll ? commonMasks.dynamicType : mask; 1101 return canReachAll ? commonMasks.dynamicType : mask;
1086 } 1102 }
1087 1103
1088 void addFunctionCalledInLoop(Element element) { 1104 void addFunctionCalledInLoop(Element element) {
1089 functionsCalledInLoop.add(element.declaration); 1105 functionsCalledInLoop.add(element.declaration);
1090 } 1106 }
1091 1107
1092 bool isCalledInLoop(Element element) { 1108 bool isCalledInLoop(Element element) {
1093 return functionsCalledInLoop.contains(element.declaration); 1109 return functionsCalledInLoop.contains(element.declaration);
1094 } 1110 }
1095 1111
1096 bool fieldNeverChanges(Element element) { 1112 bool fieldNeverChanges(Element element) {
1097 if (!element.isField) return false; 1113 if (!element.isField) return false;
1098 if (_backend.isNative(element)) { 1114 if (_backend.isNative(element)) {
1099 // Some native fields are views of data that may be changed by operations. 1115 // Some native fields are views of data that may be changed by operations.
1100 // E.g. node.firstChild depends on parentNode.removeBefore(n1, n2). 1116 // E.g. node.firstChild depends on parentNode.removeBefore(n1, n2).
1101 // TODO(sra): Refine the effect classification so that native effects are 1117 // TODO(sra): Refine the effect classification so that native effects are
1102 // distinct from ordinary Dart effects. 1118 // distinct from ordinary Dart effects.
1103 return false; 1119 return false;
1104 } 1120 }
1105 1121
1106 if (element.isFinal || element.isConst) { 1122 if (element.isFinal || element.isConst) {
1107 return true; 1123 return true;
1108 } 1124 }
1109 if (element.isInstanceMember) { 1125 if (element.isInstanceMember) {
1110 return !_compiler.resolverWorld.hasInvokedSetter(element, this) && 1126 return !resolverWorld.hasInvokedSetter(element, this) &&
1111 !_compiler.resolverWorld.fieldSetters.contains(element); 1127 !resolverWorld.fieldSetters.contains(element);
1112 } 1128 }
1113 return false; 1129 return false;
1114 } 1130 }
1115 1131
1116 SideEffects getSideEffectsOfElement(Element element) { 1132 SideEffects getSideEffectsOfElement(Element element) {
1117 // The type inferrer (where the side effects are being computed), 1133 // The type inferrer (where the side effects are being computed),
1118 // does not see generative constructor bodies because they are 1134 // does not see generative constructor bodies because they are
1119 // created by the backend. Also, it does not make any distinction 1135 // created by the backend. Also, it does not make any distinction
1120 // between a constructor and its body for side effects. This 1136 // between a constructor and its body for side effects. This
1121 // implies that currently, the side effects of a constructor body 1137 // implies that currently, the side effects of a constructor body
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1202 /// Only the class itself is included. 1218 /// Only the class itself is included.
1203 EXACT, 1219 EXACT,
1204 1220
1205 /// The class and all subclasses (transitively) are included. 1221 /// The class and all subclasses (transitively) are included.
1206 SUBCLASS, 1222 SUBCLASS,
1207 1223
1208 /// The class and all classes that implement or subclass it (transitively) 1224 /// The class and all classes that implement or subclass it (transitively)
1209 /// are included. 1225 /// are included.
1210 SUBTYPE, 1226 SUBTYPE,
1211 } 1227 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/universe/world_builder.dart ('k') | pkg/dart2js_incremental/lib/caching_compiler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698