Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 abstract class OptimizationPhase { | 7 abstract class OptimizationPhase { |
| 8 String get name; | 8 String get name; |
| 9 void visitGraph(HGraph graph); | 9 void visitGraph(HGraph graph); |
| 10 } | 10 } |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 272 | 272 |
| 273 // Try converting the instruction to a builtin instruction. | 273 // Try converting the instruction to a builtin instruction. |
| 274 HInstruction instruction = | 274 HInstruction instruction = |
| 275 node.specializer.tryConvertToBuiltin(node, types); | 275 node.specializer.tryConvertToBuiltin(node, types); |
| 276 if (instruction != null) return instruction; | 276 if (instruction != null) return instruction; |
| 277 | 277 |
| 278 // Check if this call does not need to be intercepted. | 278 // Check if this call does not need to be intercepted. |
| 279 HInstruction input = node.inputs[1]; | 279 HInstruction input = node.inputs[1]; |
| 280 HType type = types[input]; | 280 HType type = types[input]; |
| 281 var interceptor = node.inputs[0]; | 281 var interceptor = node.inputs[0]; |
| 282 | |
| 283 if (interceptor.isConstant() && selector.isCall()) { | |
| 284 DartType type = types[interceptor].computeType(compiler); | |
| 285 node.element = type.element.lookupSelector(selector); | |
| 286 } | |
| 287 | |
| 282 if (interceptor is !HThis && !type.canBePrimitive()) { | 288 if (interceptor is !HThis && !type.canBePrimitive()) { |
| 283 // If the type can be null, and the intercepted method can be in | 289 // If the type can be null, and the intercepted method can be in |
| 284 // the object class, keep the interceptor. | 290 // the object class, keep the interceptor. |
| 285 if (type.canBeNull()) { | 291 if (type.canBeNull()) { |
| 286 Set<ClassElement> interceptedClasses; | 292 Set<ClassElement> interceptedClasses; |
| 287 if (interceptor is HInterceptor) { | 293 if (interceptor is HInterceptor) { |
| 288 interceptedClasses = interceptor.interceptedClasses; | 294 interceptedClasses = interceptor.interceptedClasses; |
| 289 } else if (node is HOneShotInterceptor) { | 295 } else if (node is HOneShotInterceptor) { |
| 290 var oneShotInterceptor = node; | 296 var oneShotInterceptor = node; |
| 291 interceptedClasses = oneShotInterceptor.interceptedClasses; | 297 interceptedClasses = oneShotInterceptor.interceptedClasses; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 324 } | 330 } |
| 325 } else if (selector.applies(backend.jsStringConcat, compiler)) { | 331 } else if (selector.applies(backend.jsStringConcat, compiler)) { |
| 326 if (node.inputs[2].isString(types)) { | 332 if (node.inputs[2].isString(types)) { |
| 327 target = backend.jsStringConcat; | 333 target = backend.jsStringConcat; |
| 328 } | 334 } |
| 329 } else if (selector.applies(backend.jsStringToString, compiler)) { | 335 } else if (selector.applies(backend.jsStringToString, compiler)) { |
| 330 return input; | 336 return input; |
| 331 } | 337 } |
| 332 } | 338 } |
| 333 if (target != null) { | 339 if (target != null) { |
| 340 // There is a strong dependency between codegen and this | |
|
kasperl
2013/02/06 07:24:03
Is this a TODO? It's unclear from the comment whet
ngeoffray
2013/02/06 08:11:55
It's kind of a problem. The feature is that we're
| |
| 341 // optimization that the dynamic invoke does not need an | |
| 342 // interceptor. Once we start inlining, the dependency should | |
| 343 // go away. | |
| 334 HInvokeDynamicMethod result = new HInvokeDynamicMethod( | 344 HInvokeDynamicMethod result = new HInvokeDynamicMethod( |
| 335 node.selector, node.inputs.getRange(1, node.inputs.length - 1)); | 345 node.selector, node.inputs.getRange(1, node.inputs.length - 1)); |
| 336 result.element = target; | 346 result.element = target; |
| 337 return result; | 347 return result; |
| 338 } | 348 } |
| 339 } else if (selector.isGetter()) { | 349 } else if (selector.isGetter()) { |
| 340 if (selector.applies(backend.jsArrayLength, compiler)) { | 350 if (selector.applies(backend.jsArrayLength, compiler)) { |
| 341 return optimizeLengthInterceptedGetter(node); | 351 return optimizeLengthInterceptedGetter(node); |
| 342 } | 352 } |
| 343 } | 353 } |
| (...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 805 HInstruction index = node.index; | 815 HInstruction index = node.index; |
| 806 if (!node.index.isInteger(types)) { | 816 if (!node.index.isInteger(types)) { |
| 807 index = insertIntegerCheck(node, index); | 817 index = insertIntegerCheck(node, index); |
| 808 } | 818 } |
| 809 index = insertBoundsCheck(node, node.receiver, index); | 819 index = insertBoundsCheck(node, node.receiver, index); |
| 810 node.changeUse(node.index, index); | 820 node.changeUse(node.index, index); |
| 811 } | 821 } |
| 812 | 822 |
| 813 void visitInvokeDynamicMethod(HInvokeDynamicMethod node) { | 823 void visitInvokeDynamicMethod(HInvokeDynamicMethod node) { |
| 814 Element element = node.element; | 824 Element element = node.element; |
| 825 if (node.isInterceptorCall) return; | |
| 815 if (element != backend.jsArrayRemoveLast) return; | 826 if (element != backend.jsArrayRemoveLast) return; |
| 816 if (boundsChecked.contains(node)) return; | 827 if (boundsChecked.contains(node)) return; |
| 817 insertBoundsCheck( | 828 insertBoundsCheck( |
| 818 node, node.receiver, graph.addConstantInt(0, backend.constantSystem)); | 829 node, node.receiver, graph.addConstantInt(0, backend.constantSystem)); |
| 819 } | 830 } |
| 820 } | 831 } |
| 821 | 832 |
| 822 class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase { | 833 class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase { |
| 823 final HTypeMap types; | 834 final HTypeMap types; |
| 824 final String name = "SsaDeadCodeEliminator"; | 835 final String name = "SsaDeadCodeEliminator"; |
| (...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1520 HBasicBlock block = user.block; | 1531 HBasicBlock block = user.block; |
| 1521 block.addAfter(user, interceptor); | 1532 block.addAfter(user, interceptor); |
| 1522 block.rewrite(user, interceptor); | 1533 block.rewrite(user, interceptor); |
| 1523 block.remove(user); | 1534 block.remove(user); |
| 1524 | 1535 |
| 1525 // The interceptor will be removed in the dead code elimination | 1536 // The interceptor will be removed in the dead code elimination |
| 1526 // phase. Note that removing it here would not work because of how | 1537 // phase. Note that removing it here would not work because of how |
| 1527 // the [visitBasicBlock] is implemented. | 1538 // the [visitBasicBlock] is implemented. |
| 1528 } | 1539 } |
| 1529 } | 1540 } |
| OLD | NEW |