| 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 ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * This phase simplifies interceptors in multiple ways: | 8 * This phase simplifies interceptors in multiple ways: |
| 9 * | 9 * |
| 10 * 1) If the interceptor is for an object whose type is known, it | 10 * 1) If the interceptor is for an object whose type is known, it |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 // interceptor directly. | 123 // interceptor directly. |
| 124 | 124 |
| 125 // TODO(sra): Key DOM classes like Node, Element and Event are not leaf | 125 // TODO(sra): Key DOM classes like Node, Element and Event are not leaf |
| 126 // classes. When the receiver type is not a leaf class, we might still be | 126 // classes. When the receiver type is not a leaf class, we might still be |
| 127 // able to use the receiver class as a constant interceptor. It is | 127 // able to use the receiver class as a constant interceptor. It is |
| 128 // usually the case that methods defined on a non-leaf class don't test | 128 // usually the case that methods defined on a non-leaf class don't test |
| 129 // for a subclass or call methods defined on a subclass. Provided the | 129 // for a subclass or call methods defined on a subclass. Provided the |
| 130 // code is completely insensitive to the specific instance subclasses, we | 130 // code is completely insensitive to the specific instance subclasses, we |
| 131 // can use the non-leaf class directly. | 131 // can use the non-leaf class directly. |
| 132 ClassElement element = input.instructionType.singleClass(compiler); | 132 ClassElement element = input.instructionType.singleClass(compiler); |
| 133 if (element != null && element.isNative()) { | 133 if (element != null && element.isNative) { |
| 134 constantInterceptor = element; | 134 constantInterceptor = element; |
| 135 } | 135 } |
| 136 } | 136 } |
| 137 | 137 |
| 138 if (constantInterceptor == null) return null; | 138 if (constantInterceptor == null) return null; |
| 139 | 139 |
| 140 // If we just happen to be in an instance method of the constant | 140 // If we just happen to be in an instance method of the constant |
| 141 // interceptor, `this` is a shorter alias. | 141 // interceptor, `this` is a shorter alias. |
| 142 if (constantInterceptor == work.element.getEnclosingClass() && | 142 if (constantInterceptor == work.element.enclosingClass && |
| 143 graph.thisInstruction != null) { | 143 graph.thisInstruction != null) { |
| 144 return graph.thisInstruction; | 144 return graph.thisInstruction; |
| 145 } | 145 } |
| 146 | 146 |
| 147 Constant constant = new InterceptorConstant(constantInterceptor.thisType); | 147 Constant constant = new InterceptorConstant(constantInterceptor.thisType); |
| 148 return graph.addConstant(constant, compiler); | 148 return graph.addConstant(constant, compiler); |
| 149 } | 149 } |
| 150 | 150 |
| 151 HInstruction findDominator(Iterable<HInstruction> instructions) { | 151 HInstruction findDominator(Iterable<HInstruction> instructions) { |
| 152 HInstruction result; | 152 HInstruction result; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 } | 256 } |
| 257 | 257 |
| 258 bool visitOneShotInterceptor(HOneShotInterceptor node) { | 258 bool visitOneShotInterceptor(HOneShotInterceptor node) { |
| 259 HInstruction constant = tryComputeConstantInterceptor( | 259 HInstruction constant = tryComputeConstantInterceptor( |
| 260 node.inputs[1], node.interceptedClasses); | 260 node.inputs[1], node.interceptedClasses); |
| 261 | 261 |
| 262 if (constant == null) return false; | 262 if (constant == null) return false; |
| 263 | 263 |
| 264 Selector selector = node.selector; | 264 Selector selector = node.selector; |
| 265 HInstruction instruction; | 265 HInstruction instruction; |
| 266 if (selector.isGetter()) { | 266 if (selector.isGetter) { |
| 267 instruction = new HInvokeDynamicGetter( | 267 instruction = new HInvokeDynamicGetter( |
| 268 selector, | 268 selector, |
| 269 node.element, | 269 node.element, |
| 270 <HInstruction>[constant, node.inputs[1]], | 270 <HInstruction>[constant, node.inputs[1]], |
| 271 node.instructionType); | 271 node.instructionType); |
| 272 } else if (selector.isSetter()) { | 272 } else if (selector.isSetter) { |
| 273 instruction = new HInvokeDynamicSetter( | 273 instruction = new HInvokeDynamicSetter( |
| 274 selector, | 274 selector, |
| 275 node.element, | 275 node.element, |
| 276 <HInstruction>[constant, node.inputs[1], node.inputs[2]], | 276 <HInstruction>[constant, node.inputs[1], node.inputs[2]], |
| 277 node.instructionType); | 277 node.instructionType); |
| 278 } else { | 278 } else { |
| 279 List<HInstruction> inputs = new List<HInstruction>.from(node.inputs); | 279 List<HInstruction> inputs = new List<HInstruction>.from(node.inputs); |
| 280 inputs[0] = constant; | 280 inputs[0] = constant; |
| 281 instruction = new HInvokeDynamicMethod( | 281 instruction = new HInvokeDynamicMethod( |
| 282 selector, inputs, node.instructionType, true); | 282 selector, inputs, node.instructionType, true); |
| 283 } | 283 } |
| 284 | 284 |
| 285 HBasicBlock block = node.block; | 285 HBasicBlock block = node.block; |
| 286 block.addAfter(node, instruction); | 286 block.addAfter(node, instruction); |
| 287 block.rewrite(node, instruction); | 287 block.rewrite(node, instruction); |
| 288 return true; | 288 return true; |
| 289 } | 289 } |
| 290 } | 290 } |
| OLD | NEW |