| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 part of type_graph_inferrer; | 5 library compiler.src.inferrer.node_tracer; |
| 6 |
| 7 import '../common/names.dart' show Identifiers; |
| 8 import '../compiler.dart' show Compiler; |
| 9 import '../elements/elements.dart'; |
| 10 import '../types/types.dart' show ContainerTypeMask, MapTypeMask; |
| 11 import '../util/util.dart' show Setlet; |
| 12 |
| 13 import 'type_graph_inferrer.dart' show TypeGraphInferrerEngine; |
| 14 import 'type_graph_nodes.dart'; |
| 15 import 'debug.dart' as debug; |
| 6 | 16 |
| 7 // A set of selectors we know do not escape the elements inside the | 17 // A set of selectors we know do not escape the elements inside the |
| 8 // list. | 18 // list. |
| 9 Set<String> doesNotEscapeListSet = new Set<String>.from( | 19 Set<String> doesNotEscapeListSet = new Set<String>.from( |
| 10 const <String>[ | 20 const <String>[ |
| 11 // From Object. | 21 // From Object. |
| 12 '==', | 22 '==', |
| 13 'hashCode', | 23 'hashCode', |
| 14 'toString', | 24 'toString', |
| 15 'noSuchMethod', | 25 'noSuchMethod', |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 'isNotEmpty', | 67 'isNotEmpty', |
| 58 'length', | 68 'length', |
| 59 'clear', | 69 'clear', |
| 60 'containsKey', | 70 'containsKey', |
| 61 'containsValue', | 71 'containsValue', |
| 62 '[]=', | 72 '[]=', |
| 63 // [keys] only allows key values to escape, which we do not track. | 73 // [keys] only allows key values to escape, which we do not track. |
| 64 'keys' | 74 'keys' |
| 65 ]); | 75 ]); |
| 66 | 76 |
| 77 /// Common logic to trace a value through the type inference graph nodes. |
| 67 abstract class TracerVisitor<T extends TypeInformation> | 78 abstract class TracerVisitor<T extends TypeInformation> |
| 68 implements TypeInformationVisitor { | 79 implements TypeInformationVisitor { |
| 69 final T tracedType; | 80 final T tracedType; |
| 70 final TypeGraphInferrerEngine inferrer; | 81 final TypeGraphInferrerEngine inferrer; |
| 71 final Compiler compiler; | 82 final Compiler compiler; |
| 72 | 83 |
| 73 static const int MAX_ANALYSIS_COUNT = 16; | 84 static const int MAX_ANALYSIS_COUNT = 16; |
| 74 final Setlet<Element> analyzedElements = new Setlet<Element>(); | 85 final Setlet<Element> analyzedElements = new Setlet<Element>(); |
| 75 | 86 |
| 76 TracerVisitor(this.tracedType, TypeGraphInferrerEngine inferrer) | 87 TracerVisitor(this.tracedType, TypeGraphInferrerEngine inferrer) |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 analyzeStoredIntoList(listsToAnalyze.removeLast()); | 140 analyzeStoredIntoList(listsToAnalyze.removeLast()); |
| 130 } | 141 } |
| 131 while (!mapsToAnalyze.isEmpty) { | 142 while (!mapsToAnalyze.isEmpty) { |
| 132 analyzeStoredIntoMap(mapsToAnalyze.removeLast()); | 143 analyzeStoredIntoMap(mapsToAnalyze.removeLast()); |
| 133 } | 144 } |
| 134 if (!continueAnalyzing) break; | 145 if (!continueAnalyzing) break; |
| 135 } | 146 } |
| 136 } | 147 } |
| 137 | 148 |
| 138 void bailout(String reason) { | 149 void bailout(String reason) { |
| 139 if (_VERBOSE) { | 150 if (debug.VERBOSE) { |
| 140 print('Bailing out on $tracedType because: $reason'); | 151 print('Bailing out on $tracedType because: $reason'); |
| 141 } | 152 } |
| 142 continueAnalyzing = false; | 153 continueAnalyzing = false; |
| 143 } | 154 } |
| 144 | 155 |
| 145 void visitAwaitTypeInformation(AwaitTypeInformation info) { | 156 void visitAwaitTypeInformation(AwaitTypeInformation info) { |
| 146 bailout("Passed through await"); | 157 bailout("Passed through await"); |
| 147 } | 158 } |
| 148 | 159 |
| 149 void visitNarrowTypeInformation(NarrowTypeInformation info) { | 160 void visitNarrowTypeInformation(NarrowTypeInformation info) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 | 206 |
| 196 void analyzeStoredIntoList(ListTypeInformation list) { | 207 void analyzeStoredIntoList(ListTypeInformation list) { |
| 197 inferrer.analyzeListAndEnqueue(list); | 208 inferrer.analyzeListAndEnqueue(list); |
| 198 if (list.bailedOut) { | 209 if (list.bailedOut) { |
| 199 bailout('Stored in a list that bailed out'); | 210 bailout('Stored in a list that bailed out'); |
| 200 } else { | 211 } else { |
| 201 list.flowsInto.forEach((flow) { | 212 list.flowsInto.forEach((flow) { |
| 202 flow.users.forEach((user) { | 213 flow.users.forEach((user) { |
| 203 if (user is !DynamicCallSiteTypeInformation) return; | 214 if (user is !DynamicCallSiteTypeInformation) return; |
| 204 if (user.receiver != flow) return; | 215 if (user.receiver != flow) return; |
| 205 if (inferrer._returnsListElementTypeSet.contains(user.selector)) { | 216 if (inferrer.returnsListElementTypeSet.contains(user.selector)) { |
| 206 addNewEscapeInformation(user); | 217 addNewEscapeInformation(user); |
| 207 } else if (!doesNotEscapeListSet.contains(user.selector.name)) { | 218 } else if (!doesNotEscapeListSet.contains(user.selector.name)) { |
| 208 bailout('Escape from a list via [${user.selector.name}]'); | 219 bailout('Escape from a list via [${user.selector.name}]'); |
| 209 } | 220 } |
| 210 }); | 221 }); |
| 211 }); | 222 }); |
| 212 } | 223 } |
| 213 } | 224 } |
| 214 | 225 |
| 215 void analyzeStoredIntoMap(MapTypeInformation map) { | 226 void analyzeStoredIntoMap(MapTypeInformation map) { |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 } | 400 } |
| 390 if (isParameterOfListAddingMethod(info.element) || | 401 if (isParameterOfListAddingMethod(info.element) || |
| 391 isParameterOfMapAddingMethod(info.element)) { | 402 isParameterOfMapAddingMethod(info.element)) { |
| 392 // These elements are being handled in | 403 // These elements are being handled in |
| 393 // [visitDynamicCallSiteTypeInformation]. | 404 // [visitDynamicCallSiteTypeInformation]. |
| 394 return; | 405 return; |
| 395 } | 406 } |
| 396 addNewEscapeInformation(info); | 407 addNewEscapeInformation(info); |
| 397 } | 408 } |
| 398 } | 409 } |
| OLD | NEW |