| 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 /** | 7 /** |
| 8 * A special element for the extra parameter taken by intercepted | 8 * A special element for the extra parameter taken by intercepted |
| 9 * methods. We need to override [Element.computeType] because our | 9 * methods. We need to override [Element.computeType] because our |
| 10 * optimizers may look at its declared type. | 10 * optimizers may look at its declared type. |
| (...skipping 2895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2906 } | 2906 } |
| 2907 | 2907 |
| 2908 visitDynamicSend(Send node, {bool inline: true}) { | 2908 visitDynamicSend(Send node, {bool inline: true}) { |
| 2909 Selector selector = elements.getSelector(node); | 2909 Selector selector = elements.getSelector(node); |
| 2910 | 2910 |
| 2911 List<HInstruction> inputs = <HInstruction>[]; | 2911 List<HInstruction> inputs = <HInstruction>[]; |
| 2912 HInstruction receiver = generateInstanceSendReceiver(node); | 2912 HInstruction receiver = generateInstanceSendReceiver(node); |
| 2913 inputs.add(receiver); | 2913 inputs.add(receiver); |
| 2914 addDynamicSendArgumentsToList(node, inputs); | 2914 addDynamicSendArgumentsToList(node, inputs); |
| 2915 | 2915 |
| 2916 // We prefer to not inline certain operations on indexables, |
| 2917 // because the constant folder will handle them better and turn |
| 2918 // them into simpler instructions that allow further |
| 2919 // optimizations. |
| 2920 bool isOptimizableOperationOnIndexable(Selector selector, Element element) { |
| 2921 bool isLength = selector.isGetter() |
| 2922 && selector.name == const SourceString("length"); |
| 2923 if (isLength || selector.isIndex()) { |
| 2924 DartType classType = element.getEnclosingClass().computeType(compiler); |
| 2925 HType type = new HType.nonNullExact(classType, compiler); |
| 2926 return type.isIndexable(compiler); |
| 2927 } else if (selector.isIndexSet()) { |
| 2928 DartType classType = element.getEnclosingClass().computeType(compiler); |
| 2929 HType type = new HType.nonNullExact(classType, compiler); |
| 2930 return type.isMutableIndexable(compiler); |
| 2931 } else { |
| 2932 return false; |
| 2933 } |
| 2934 } |
| 2935 |
| 2916 Element element = compiler.world.locateSingleElement(selector); | 2936 Element element = compiler.world.locateSingleElement(selector); |
| 2917 // TODO(ngeoffray): If [element] is a getter, then this send is | 2937 // TODO(ngeoffray): If [element] is a getter, then this send is |
| 2918 // a closure send. We should teach that to [ResolvedVisitor]. | 2938 // a closure send. We should teach that to [ResolvedVisitor]. |
| 2919 if (inline | 2939 if (inline |
| 2920 && element != null | 2940 && element != null |
| 2921 && !element.isGetter() | 2941 && !element.isGetter() |
| 2922 // This check is to ensure we don't regress compared to our | 2942 // This check is to ensure we don't regress compared to our |
| 2923 // previous limited inlining. We currently don't want to | 2943 // previous limited inlining. We currently don't want to |
| 2924 // inline methods on intercepted classes because the | 2944 // inline methods on intercepted classes because the |
| 2925 // optimizers apply their own optimizations on these methods. | 2945 // optimizers apply their own optimizations on these methods. |
| 2926 && (!backend.interceptedClasses.contains(element.getEnclosingClass()) | 2946 && (!backend.interceptedClasses.contains(element.getEnclosingClass()) |
| 2927 || isThisSend(node))) { | 2947 || isThisSend(node)) |
| 2948 // Avoid inlining optimizable operations on indexables. |
| 2949 && !isOptimizableOperationOnIndexable(selector, element)) { |
| 2928 if (tryInlineMethod(element, selector, node.arguments, inputs, node)) { | 2950 if (tryInlineMethod(element, selector, node.arguments, inputs, node)) { |
| 2929 return; | 2951 return; |
| 2930 } | 2952 } |
| 2931 } | 2953 } |
| 2932 | 2954 |
| 2933 HInstruction invoke = buildInvokeDynamic(node, selector, inputs); | 2955 HInstruction invoke = buildInvokeDynamic(node, selector, inputs); |
| 2934 pushWithPosition(invoke, node); | 2956 pushWithPosition(invoke, node); |
| 2935 } | 2957 } |
| 2936 | 2958 |
| 2937 visitClosureSend(Send node) { | 2959 visitClosureSend(Send node) { |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3365 isListConstructor = true; | 3387 isListConstructor = true; |
| 3366 return HType.FIXED_ARRAY; | 3388 return HType.FIXED_ARRAY; |
| 3367 } else if (Elements.isGrowableListConstructorCall( | 3389 } else if (Elements.isGrowableListConstructorCall( |
| 3368 originalElement, node, compiler)) { | 3390 originalElement, node, compiler)) { |
| 3369 isListConstructor = true; | 3391 isListConstructor = true; |
| 3370 return HType.EXTENDABLE_ARRAY; | 3392 return HType.EXTENDABLE_ARRAY; |
| 3371 } else if (element.isGenerativeConstructor()) { | 3393 } else if (element.isGenerativeConstructor()) { |
| 3372 ClassElement cls = element.getEnclosingClass(); | 3394 ClassElement cls = element.getEnclosingClass(); |
| 3373 return new HType.nonNullExact(cls.thisType, compiler); | 3395 return new HType.nonNullExact(cls.thisType, compiler); |
| 3374 } else { | 3396 } else { |
| 3375 return HType.UNKNOWN; | 3397 return new HType.inferredTypeForElement(originalElement, compiler); |
| 3376 } | 3398 } |
| 3377 } | 3399 } |
| 3378 | 3400 |
| 3379 Element constructor = elements[node]; | 3401 Element constructor = elements[node]; |
| 3380 Selector selector = elements.getSelector(node); | 3402 Selector selector = elements.getSelector(node); |
| 3381 if (compiler.enqueuer.resolution.getCachedElements(constructor) == null) { | 3403 if (compiler.enqueuer.resolution.getCachedElements(constructor) == null) { |
| 3382 compiler.internalError("Unresolved element: $constructor", node: node); | 3404 compiler.internalError("Unresolved element: $constructor", node: node); |
| 3383 } | 3405 } |
| 3384 FunctionElement functionElement = constructor; | 3406 FunctionElement functionElement = constructor; |
| 3385 constructor = functionElement.redirectionTarget; | 3407 constructor = functionElement.redirectionTarget; |
| (...skipping 1862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5248 new HSubGraphBlockInformation(elseBranch.graph)); | 5270 new HSubGraphBlockInformation(elseBranch.graph)); |
| 5249 | 5271 |
| 5250 HBasicBlock conditionStartBlock = conditionBranch.block; | 5272 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 5251 conditionStartBlock.setBlockFlow(info, joinBlock); | 5273 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 5252 SubGraph conditionGraph = conditionBranch.graph; | 5274 SubGraph conditionGraph = conditionBranch.graph; |
| 5253 HIf branch = conditionGraph.end.last; | 5275 HIf branch = conditionGraph.end.last; |
| 5254 assert(branch is HIf); | 5276 assert(branch is HIf); |
| 5255 branch.blockInformation = conditionStartBlock.blockFlow; | 5277 branch.blockInformation = conditionStartBlock.blockFlow; |
| 5256 } | 5278 } |
| 5257 } | 5279 } |
| OLD | NEW |