OLD | NEW |
---|---|
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
6 | 6 |
7 import '../common.dart'; | 7 import '../common.dart'; |
8 import '../common/names.dart'; | 8 import '../common/names.dart'; |
9 import '../compiler.dart'; | 9 import '../compiler.dart'; |
10 import '../constants/expressions.dart'; | 10 import '../constants/expressions.dart'; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
70 /// Parallel structure for concreteTypes. | 70 /// Parallel structure for concreteTypes. |
71 // TODO(efortuna): Remove concreteTypes and/or parameterize InferrerEngine by | 71 // TODO(efortuna): Remove concreteTypes and/or parameterize InferrerEngine by |
72 // ir.Node or ast.Node type. Then remove this in favor of `concreteTypes`. | 72 // ir.Node or ast.Node type. Then remove this in favor of `concreteTypes`. |
73 final Map<ir.Node, TypeInformation> concreteKernelTypes = | 73 final Map<ir.Node, TypeInformation> concreteKernelTypes = |
74 new Map<ir.Node, TypeInformation>(); | 74 new Map<ir.Node, TypeInformation>(); |
75 final Set<ConstructorElement> generativeConstructorsExposingThis = | 75 final Set<ConstructorElement> generativeConstructorsExposingThis = |
76 new Set<ConstructorElement>(); | 76 new Set<ConstructorElement>(); |
77 | 77 |
78 /// Data computed internally within elements, like the type-mask of a send a | 78 /// Data computed internally within elements, like the type-mask of a send a |
79 /// list allocation, or a for-in loop. | 79 /// list allocation, or a for-in loop. |
80 final Map<Element, GlobalTypeInferenceElementData> inTreeData = | 80 final Map<MemberElement, GlobalTypeInferenceElementData> _memberData = |
81 new Map<Element, GlobalTypeInferenceElementData>(); | 81 new Map<MemberElement, GlobalTypeInferenceElementData>(); |
82 | 82 |
83 InferrerEngine(this.compiler, ClosedWorld closedWorld, | 83 InferrerEngine(this.compiler, ClosedWorld closedWorld, |
84 this.closedWorldRefiner, this.mainElement) | 84 this.closedWorldRefiner, this.mainElement) |
85 : this.types = new TypeSystem(closedWorld), | 85 : this.types = new TypeSystem(closedWorld), |
86 this.closedWorld = closedWorld; | 86 this.closedWorld = closedWorld; |
87 | 87 |
88 CommonElements get commonElements => closedWorld.commonElements; | 88 CommonElements get commonElements => closedWorld.commonElements; |
89 | 89 |
90 /// Returns `true` if [element] has an `@AssumeDynamic()` annotation. | 90 /// Returns `true` if [element] has an `@AssumeDynamic()` annotation. |
91 bool assumeDynamic(Element element) { | 91 bool assumeDynamic(Element element) { |
(...skipping 11 matching lines...) Expand all Loading... | |
103 * [selector] and [mask]. If [f] returns false, aborts the iteration. | 103 * [selector] and [mask]. If [f] returns false, aborts the iteration. |
104 */ | 104 */ |
105 void forEachElementMatching( | 105 void forEachElementMatching( |
106 Selector selector, TypeMask mask, bool f(Element element)) { | 106 Selector selector, TypeMask mask, bool f(Element element)) { |
107 Iterable<MemberEntity> elements = closedWorld.locateMembers(selector, mask); | 107 Iterable<MemberEntity> elements = closedWorld.locateMembers(selector, mask); |
108 for (MemberElement e in elements) { | 108 for (MemberElement e in elements) { |
109 if (!f(e.implementation)) return; | 109 if (!f(e.implementation)) return; |
110 } | 110 } |
111 } | 111 } |
112 | 112 |
113 GlobalTypeInferenceElementData dataOfLocalFunction( | |
114 LocalFunctionElement element) => | |
115 _dataOf(element); | |
116 | |
117 // TODO(johnniwinther): Make this private again. | 113 // TODO(johnniwinther): Make this private again. |
118 GlobalTypeInferenceElementData dataOfMember(MemberElement element) => | 114 GlobalTypeInferenceElementData dataOfMember(MemberElement element) => |
119 _dataOf(element); | 115 _memberData.putIfAbsent( |
116 element, () => new GlobalTypeInferenceElementData()); | |
120 | 117 |
121 GlobalTypeInferenceElementData _dataOf(AstElement element) => inTreeData | 118 GlobalTypeInferenceElementData lookupDataOfMember(MemberElement element) => |
Johnni Winther
2017/06/29 17:00:28
It turned out that we never (after type inference)
| |
122 .putIfAbsent(element, () => new GlobalTypeInferenceElementData()); | 119 _memberData[element]; |
123 | 120 |
124 /** | 121 /** |
125 * Update [sideEffects] with the side effects of [callee] being | 122 * Update [sideEffects] with the side effects of [callee] being |
126 * called with [selector]. | 123 * called with [selector]. |
127 */ | 124 */ |
128 void updateSideEffects( | 125 void updateSideEffects( |
129 SideEffects sideEffects, Selector selector, Element callee) { | 126 SideEffects sideEffects, Selector selector, Element callee) { |
130 if (callee.isField) { | 127 if (callee.isField) { |
131 if (callee.isInstanceMember) { | 128 if (callee.isInstanceMember) { |
132 if (selector.isSetter) { | 129 if (selector.isSetter) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
191 mappedType = types.nonNullSubtype(type.element); | 188 mappedType = types.nonNullSubtype(type.element); |
192 } | 189 } |
193 returnType = types.computeLUB(returnType, mappedType); | 190 returnType = types.computeLUB(returnType, mappedType); |
194 if (returnType == types.dynamicType) { | 191 if (returnType == types.dynamicType) { |
195 break; | 192 break; |
196 } | 193 } |
197 } | 194 } |
198 return returnType; | 195 return returnType; |
199 } | 196 } |
200 | 197 |
201 @deprecated | |
202 void updateSelectorInLocalFunction(LocalFunctionElement owner, Spannable node, | |
203 Selector selector, TypeMask mask) { | |
204 GlobalTypeInferenceElementData data = dataOfLocalFunction(owner); | |
205 _updateSelectorInTree(data, node, selector, mask); | |
206 } | |
207 | |
208 void updateSelectorInMember( | 198 void updateSelectorInMember( |
209 MemberElement owner, Spannable node, Selector selector, TypeMask mask) { | 199 MemberElement owner, Spannable node, Selector selector, TypeMask mask) { |
210 GlobalTypeInferenceElementData data = dataOfMember(owner); | 200 GlobalTypeInferenceElementData data = dataOfMember(owner); |
211 _updateSelectorInTree(data, node, selector, mask); | |
212 } | |
213 | |
214 void _updateSelectorInTree(GlobalTypeInferenceElementData data, | |
215 Spannable node, Selector selector, TypeMask mask) { | |
216 ast.Node astNode = node; | 201 ast.Node astNode = node; |
217 if (astNode.asSendSet() != null) { | 202 if (astNode.asSendSet() != null) { |
218 if (selector.isSetter || selector.isIndexSet) { | 203 if (selector.isSetter || selector.isIndexSet) { |
219 data.setTypeMask(node, mask); | 204 data.setTypeMask(node, mask); |
220 } else if (selector.isGetter || selector.isIndex) { | 205 } else if (selector.isGetter || selector.isIndex) { |
221 data.setGetterTypeMaskInComplexSendSet(node, mask); | 206 data.setGetterTypeMaskInComplexSendSet(node, mask); |
222 } else { | 207 } else { |
223 assert(selector.isOperator); | 208 assert(selector.isOperator); |
224 data.setOperatorTypeMaskInComplexSendSet(node, mask); | 209 data.setOperatorTypeMaskInComplexSendSet(node, mask); |
225 } | 210 } |
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
915 * [sideEffects] will be updated to incorporate [callee]'s side | 900 * [sideEffects] will be updated to incorporate [callee]'s side |
916 * effects. | 901 * effects. |
917 * | 902 * |
918 * [inLoop] tells whether the call happens in a loop. | 903 * [inLoop] tells whether the call happens in a loop. |
919 */ | 904 */ |
920 @deprecated | 905 @deprecated |
921 TypeInformation registerCalledLocalFunction( | 906 TypeInformation registerCalledLocalFunction( |
922 Spannable node, | 907 Spannable node, |
923 Selector selector, | 908 Selector selector, |
924 TypeMask mask, | 909 TypeMask mask, |
925 Element caller, | 910 MemberElement caller, |
926 LocalFunctionElement callee, | 911 LocalFunctionElement callee, |
927 ArgumentsTypes arguments, | 912 ArgumentsTypes arguments, |
928 SideEffects sideEffects, | 913 SideEffects sideEffects, |
929 bool inLoop) { | 914 bool inLoop) { |
930 CallSiteTypeInformation info = new LocalFunctionCallSiteTypeInformation( | 915 CallSiteTypeInformation info = new LocalFunctionCallSiteTypeInformation( |
931 types.currentMember, | 916 types.currentMember, |
932 node, | 917 node, |
933 caller, | 918 caller, |
934 callee, | 919 callee, |
935 selector, | 920 selector, |
(...skipping 10 matching lines...) Expand all Loading... | |
946 * | 931 * |
947 * [sideEffects] will be updated to incorporate [callee]'s side | 932 * [sideEffects] will be updated to incorporate [callee]'s side |
948 * effects. | 933 * effects. |
949 * | 934 * |
950 * [inLoop] tells whether the call happens in a loop. | 935 * [inLoop] tells whether the call happens in a loop. |
951 */ | 936 */ |
952 TypeInformation registerCalledMember( | 937 TypeInformation registerCalledMember( |
953 Spannable node, | 938 Spannable node, |
954 Selector selector, | 939 Selector selector, |
955 TypeMask mask, | 940 TypeMask mask, |
956 Element caller, | 941 MemberElement caller, |
957 MemberElement callee, | 942 MemberElement callee, |
958 ArgumentsTypes arguments, | 943 ArgumentsTypes arguments, |
959 SideEffects sideEffects, | 944 SideEffects sideEffects, |
960 bool inLoop) { | 945 bool inLoop) { |
961 CallSiteTypeInformation info = new StaticCallSiteTypeInformation( | 946 CallSiteTypeInformation info = new StaticCallSiteTypeInformation( |
962 types.currentMember, | 947 types.currentMember, |
963 node, | 948 node, |
964 caller, | 949 caller, |
965 callee, | 950 callee, |
966 selector, | 951 selector, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1006 * [sideEffects] will be updated to incorporate the potential | 991 * [sideEffects] will be updated to incorporate the potential |
1007 * callees' side effects. | 992 * callees' side effects. |
1008 * | 993 * |
1009 * [inLoop] tells whether the call happens in a loop. | 994 * [inLoop] tells whether the call happens in a loop. |
1010 */ | 995 */ |
1011 TypeInformation registerCalledSelector( | 996 TypeInformation registerCalledSelector( |
1012 ast.Node node, | 997 ast.Node node, |
1013 Selector selector, | 998 Selector selector, |
1014 TypeMask mask, | 999 TypeMask mask, |
1015 TypeInformation receiverType, | 1000 TypeInformation receiverType, |
1016 Element caller, | 1001 MemberElement caller, |
1017 ArgumentsTypes arguments, | 1002 ArgumentsTypes arguments, |
1018 SideEffects sideEffects, | 1003 SideEffects sideEffects, |
1019 bool inLoop) { | 1004 bool inLoop) { |
1020 if (selector.isClosureCall) { | 1005 if (selector.isClosureCall) { |
1021 return registerCalledClosure(node, selector, mask, receiverType, caller, | 1006 return registerCalledClosure(node, selector, mask, receiverType, caller, |
1022 arguments, sideEffects, inLoop); | 1007 arguments, sideEffects, inLoop); |
1023 } | 1008 } |
1024 | 1009 |
1025 closedWorld.locateMembers(selector, mask).forEach((_callee) { | 1010 closedWorld.locateMembers(selector, mask).forEach((_callee) { |
1026 MemberElement callee = _callee; | 1011 MemberElement callee = _callee; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1072 * [sideEffects] will be updated to incorporate the potential | 1057 * [sideEffects] will be updated to incorporate the potential |
1073 * callees' side effects. | 1058 * callees' side effects. |
1074 * | 1059 * |
1075 * [inLoop] tells whether the call happens in a loop. | 1060 * [inLoop] tells whether the call happens in a loop. |
1076 */ | 1061 */ |
1077 TypeInformation registerCalledClosure( | 1062 TypeInformation registerCalledClosure( |
1078 ast.Node node, | 1063 ast.Node node, |
1079 Selector selector, | 1064 Selector selector, |
1080 TypeMask mask, | 1065 TypeMask mask, |
1081 TypeInformation closure, | 1066 TypeInformation closure, |
1082 Element caller, | 1067 MemberElement caller, |
1083 ArgumentsTypes arguments, | 1068 ArgumentsTypes arguments, |
1084 SideEffects sideEffects, | 1069 SideEffects sideEffects, |
1085 bool inLoop) { | 1070 bool inLoop) { |
1086 sideEffects.setDependsOnSomething(); | 1071 sideEffects.setDependsOnSomething(); |
1087 sideEffects.setAllSideEffects(); | 1072 sideEffects.setAllSideEffects(); |
1088 CallSiteTypeInformation info = new ClosureCallSiteTypeInformation( | 1073 CallSiteTypeInformation info = new ClosureCallSiteTypeInformation( |
1089 types.currentMember, | 1074 types.currentMember, |
1090 node, | 1075 node, |
1091 caller, | 1076 caller, |
1092 selector, | 1077 selector, |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1236 /** | 1221 /** |
1237 * Records that the captured variable [local] is read. | 1222 * Records that the captured variable [local] is read. |
1238 */ | 1223 */ |
1239 void recordCapturedLocalRead(Local local) {} | 1224 void recordCapturedLocalRead(Local local) {} |
1240 | 1225 |
1241 /** | 1226 /** |
1242 * Records that the variable [local] is being updated. | 1227 * Records that the variable [local] is being updated. |
1243 */ | 1228 */ |
1244 void recordLocalUpdate(Local local, TypeInformation type) {} | 1229 void recordLocalUpdate(Local local, TypeInformation type) {} |
1245 } | 1230 } |
OLD | NEW |