| 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 part of type_graph_inferrer; |
| 6 | 6 |
| 7 // A set of selectors we know do not escape the elements inside the | 7 // A set of selectors we know do not escape the elements inside the |
| 8 // list. | 8 // list. |
| 9 Set<String> doesNotEscapeListSet = new Set<String>.from( | 9 Set<String> doesNotEscapeListSet = new Set<String>.from( |
| 10 const <String>[ | 10 const <String>[ |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 | 201 |
| 202 void analyzeStoredIntoMap(MapTypeInformation map) { | 202 void analyzeStoredIntoMap(MapTypeInformation map) { |
| 203 inferrer.analyzeMapAndEnqueue(map); | 203 inferrer.analyzeMapAndEnqueue(map); |
| 204 if (map.bailedOut) { | 204 if (map.bailedOut) { |
| 205 bailout('Stored in a map that bailed out'); | 205 bailout('Stored in a map that bailed out'); |
| 206 } else { | 206 } else { |
| 207 map.flowsInto.forEach((flow) { | 207 map.flowsInto.forEach((flow) { |
| 208 flow.users.forEach((user) { | 208 flow.users.forEach((user) { |
| 209 if (user is !DynamicCallSiteTypeInformation) return; | 209 if (user is !DynamicCallSiteTypeInformation) return; |
| 210 if (user.receiver != flow) return; | 210 if (user.receiver != flow) return; |
| 211 if (user.selector.isIndex()) { | 211 if (user.selector.isIndex) { |
| 212 addNewEscapeInformation(user); | 212 addNewEscapeInformation(user); |
| 213 } else if (!doesNotEscapeMapSet.contains(user.selector.name)) { | 213 } else if (!doesNotEscapeMapSet.contains(user.selector.name)) { |
| 214 bailout('Escape from a map via [${user.selector.name}]'); | 214 bailout('Escape from a map via [${user.selector.name}]'); |
| 215 } | 215 } |
| 216 }); | 216 }); |
| 217 }); | 217 }); |
| 218 } | 218 } |
| 219 } | 219 } |
| 220 | 220 |
| 221 /** | 221 /** |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 addNewEscapeInformation(info); | 301 addNewEscapeInformation(info); |
| 302 } | 302 } |
| 303 } | 303 } |
| 304 | 304 |
| 305 /** | 305 /** |
| 306 * Check whether element is the parameter of a list adding method. | 306 * Check whether element is the parameter of a list adding method. |
| 307 * The definition of what a list adding method is has to stay in sync with | 307 * The definition of what a list adding method is has to stay in sync with |
| 308 * [isAddedToContainer]. | 308 * [isAddedToContainer]. |
| 309 */ | 309 */ |
| 310 bool isParameterOfListAddingMethod(Element element) { | 310 bool isParameterOfListAddingMethod(Element element) { |
| 311 if (!element.isParameter()) return false; | 311 if (!element.isParameter) return false; |
| 312 if (element.getEnclosingClass() != compiler.backend.listImplementation) { | 312 if (element.enclosingClass != compiler.backend.listImplementation) { |
| 313 return false; | 313 return false; |
| 314 } | 314 } |
| 315 Element method = element.enclosingElement; | 315 Element method = element.enclosingElement; |
| 316 return (method.name == '[]=') | 316 return (method.name == '[]=') |
| 317 || (method.name == 'add') | 317 || (method.name == 'add') |
| 318 || (method.name == 'insert'); | 318 || (method.name == 'insert'); |
| 319 } | 319 } |
| 320 | 320 |
| 321 /** | 321 /** |
| 322 * Check whether element is the parameter of a list adding method. | 322 * Check whether element is the parameter of a list adding method. |
| 323 * The definition of what a list adding method is has to stay in sync with | 323 * The definition of what a list adding method is has to stay in sync with |
| 324 * [isValueAddedToMap] and [isKeyAddedToMap]. | 324 * [isValueAddedToMap] and [isKeyAddedToMap]. |
| 325 */ | 325 */ |
| 326 bool isParameterOfMapAddingMethod(Element element) { | 326 bool isParameterOfMapAddingMethod(Element element) { |
| 327 if (!element.isParameter()) return false; | 327 if (!element.isParameter) return false; |
| 328 if (element.getEnclosingClass() != compiler.backend.mapImplementation) { | 328 if (element.enclosingClass != compiler.backend.mapImplementation) { |
| 329 return false; | 329 return false; |
| 330 } | 330 } |
| 331 Element method = element.enclosingElement; | 331 Element method = element.enclosingElement; |
| 332 return (method.name == '[]='); | 332 return (method.name == '[]='); |
| 333 } | 333 } |
| 334 | 334 |
| 335 bool isClosure(Element element) { | 335 bool isClosure(Element element) { |
| 336 if (!element.isFunction()) return false; | 336 if (!element.isFunction) return false; |
| 337 /// Creating an instance of a class that implements [Function] also | 337 /// Creating an instance of a class that implements [Function] also |
| 338 /// closurizes the corresponding [call] member. We do not currently | 338 /// closurizes the corresponding [call] member. We do not currently |
| 339 /// track these, thus the check for [isClosurized] on such a method will | 339 /// track these, thus the check for [isClosurized] on such a method will |
| 340 /// return false. Instead we catch that case here for now. | 340 /// return false. Instead we catch that case here for now. |
| 341 // TODO(herhut): Handle creation of closures from instances of Function. | 341 // TODO(herhut): Handle creation of closures from instances of Function. |
| 342 if (element.isInstanceMember() && | 342 if (element.isInstanceMember && |
| 343 element.name == Compiler.CALL_OPERATOR_NAME) { | 343 element.name == Compiler.CALL_OPERATOR_NAME) { |
| 344 return true; | 344 return true; |
| 345 } | 345 } |
| 346 Element outermost = element.getOutermostEnclosingMemberOrTopLevel(); | 346 Element outermost = element.outermostEnclosingMemberOrTopLevel; |
| 347 return outermost.declaration != element.declaration; | 347 return outermost.declaration != element.declaration; |
| 348 } | 348 } |
| 349 | 349 |
| 350 void visitElementTypeInformation(ElementTypeInformation info) { | 350 void visitElementTypeInformation(ElementTypeInformation info) { |
| 351 Element element = info.element; | 351 Element element = info.element; |
| 352 if (element.isParameter() | 352 if (element.isParameter |
| 353 && inferrer.isNativeElement(element.enclosingElement)) { | 353 && inferrer.isNativeElement(element.enclosingElement)) { |
| 354 bailout('Passed to a native method'); | 354 bailout('Passed to a native method'); |
| 355 } | 355 } |
| 356 if (info.isClosurized) { | 356 if (info.isClosurized) { |
| 357 bailout('Returned from a closurized method'); | 357 bailout('Returned from a closurized method'); |
| 358 } | 358 } |
| 359 if (isClosure(info.element)) { | 359 if (isClosure(info.element)) { |
| 360 bailout('Returned from a closure'); | 360 bailout('Returned from a closure'); |
| 361 } | 361 } |
| 362 if (compiler.backend.isNeededForReflection(info.element)) { | 362 if (compiler.backend.isNeededForReflection(info.element)) { |
| 363 bailout('Escape in reflection'); | 363 bailout('Escape in reflection'); |
| 364 } | 364 } |
| 365 if (!inferrer.compiler.backend | 365 if (!inferrer.compiler.backend |
| 366 .canBeUsedForGlobalOptimizations(info.element)) { | 366 .canBeUsedForGlobalOptimizations(info.element)) { |
| 367 bailout('Escape to code that has special backend treatment'); | 367 bailout('Escape to code that has special backend treatment'); |
| 368 } | 368 } |
| 369 if (isParameterOfListAddingMethod(info.element) || | 369 if (isParameterOfListAddingMethod(info.element) || |
| 370 isParameterOfMapAddingMethod(info.element)) { | 370 isParameterOfMapAddingMethod(info.element)) { |
| 371 // These elements are being handled in | 371 // These elements are being handled in |
| 372 // [visitDynamicCallSiteTypeInformation]. | 372 // [visitDynamicCallSiteTypeInformation]. |
| 373 return; | 373 return; |
| 374 } | 374 } |
| 375 addNewEscapeInformation(info); | 375 addNewEscapeInformation(info); |
| 376 } | 376 } |
| 377 } | 377 } |
| OLD | NEW |