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 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 StringConstant constant = constantInput.constant; | 207 StringConstant constant = constantInput.constant; |
208 return graph.addConstantInt(constant.length, compiler); | 208 return graph.addConstantInt(constant.length, compiler); |
209 } else if (actualReceiver.isConstantList()) { | 209 } else if (actualReceiver.isConstantList()) { |
210 HConstant constantInput = actualReceiver; | 210 HConstant constantInput = actualReceiver; |
211 ListConstant constant = constantInput.constant; | 211 ListConstant constant = constantInput.constant; |
212 return graph.addConstantInt(constant.length, compiler); | 212 return graph.addConstantInt(constant.length, compiler); |
213 } | 213 } |
214 Element element = backend.jsIndexableLength; | 214 Element element = backend.jsIndexableLength; |
215 bool isFixed = isFixedLength(actualReceiver.instructionType, compiler); | 215 bool isFixed = isFixedLength(actualReceiver.instructionType, compiler); |
216 HFieldGet result = new HFieldGet( | 216 HFieldGet result = new HFieldGet( |
217 element, actualReceiver, backend.intType, | 217 element, actualReceiver, backend.positiveIntType, |
218 isAssignable: !isFixed); | 218 isAssignable: !isFixed); |
219 return result; | 219 return result; |
220 } else if (actualReceiver.isConstantMap()) { | 220 } else if (actualReceiver.isConstantMap()) { |
221 HConstant constantInput = actualReceiver; | 221 HConstant constantInput = actualReceiver; |
222 MapConstant constant = constantInput.constant; | 222 MapConstant constant = constantInput.constant; |
223 return graph.addConstantInt(constant.length, compiler); | 223 return graph.addConstantInt(constant.length, compiler); |
224 } | 224 } |
225 return null; | 225 return null; |
226 } | 226 } |
227 | 227 |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
824 instruction = instruction.accept(this); | 824 instruction = instruction.accept(this); |
825 instruction = next; | 825 instruction = next; |
826 } | 826 } |
827 } | 827 } |
828 | 828 |
829 HBoundsCheck insertBoundsCheck(HInstruction indexNode, | 829 HBoundsCheck insertBoundsCheck(HInstruction indexNode, |
830 HInstruction array, | 830 HInstruction array, |
831 HInstruction indexArgument) { | 831 HInstruction indexArgument) { |
832 Compiler compiler = backend.compiler; | 832 Compiler compiler = backend.compiler; |
833 HFieldGet length = new HFieldGet( | 833 HFieldGet length = new HFieldGet( |
834 backend.jsIndexableLength, array, backend.intType, | 834 backend.jsIndexableLength, array, backend.positiveIntType, |
835 isAssignable: !isFixedLength(array.instructionType, compiler)); | 835 isAssignable: !isFixedLength(array.instructionType, compiler)); |
836 indexNode.block.addBefore(indexNode, length); | 836 indexNode.block.addBefore(indexNode, length); |
837 | 837 |
| 838 TypeMask type = indexArgument.isPositiveInteger(compiler) |
| 839 ? indexArgument.instructionType |
| 840 : backend.positiveIntType; |
838 HBoundsCheck check = new HBoundsCheck( | 841 HBoundsCheck check = new HBoundsCheck( |
839 indexArgument, length, array, backend.intType); | 842 indexArgument, length, array, type); |
840 indexNode.block.addBefore(indexNode, check); | 843 indexNode.block.addBefore(indexNode, check); |
841 // If the index input to the bounds check was not known to be an integer | 844 // If the index input to the bounds check was not known to be an integer |
842 // then we replace its uses with the bounds check, which is known to be an | 845 // then we replace its uses with the bounds check, which is known to be an |
843 // integer. However, if the input was already an integer we don't do this | 846 // integer. However, if the input was already an integer we don't do this |
844 // because putting in a check instruction might obscure the real nature of | 847 // because putting in a check instruction might obscure the real nature of |
845 // the index eg. if it is a constant. The range information from the | 848 // the index eg. if it is a constant. The range information from the |
846 // BoundsCheck instruction is attached to the input directly by | 849 // BoundsCheck instruction is attached to the input directly by |
847 // visitBoundsCheck in the SsaValueRangeAnalyzer. | 850 // visitBoundsCheck in the SsaValueRangeAnalyzer. |
848 if (!indexArgument.isInteger(compiler)) { | 851 if (!indexArgument.isInteger(compiler)) { |
849 indexArgument.replaceAllUsersDominatedBy(indexNode, check); | 852 indexArgument.replaceAllUsersDominatedBy(indexNode, check); |
(...skipping 1073 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1923 | 1926 |
1924 keyedValues.forEach((receiver, values) { | 1927 keyedValues.forEach((receiver, values) { |
1925 result.keyedValues[receiver] = | 1928 result.keyedValues[receiver] = |
1926 new Map<HInstruction, HInstruction>.from(values); | 1929 new Map<HInstruction, HInstruction>.from(values); |
1927 }); | 1930 }); |
1928 | 1931 |
1929 result.nonEscapingReceivers.addAll(nonEscapingReceivers); | 1932 result.nonEscapingReceivers.addAll(nonEscapingReceivers); |
1930 return result; | 1933 return result; |
1931 } | 1934 } |
1932 } | 1935 } |
OLD | NEW |