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 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 instruction = instruction.accept(this); | 823 instruction = instruction.accept(this); |
824 instruction = next; | 824 instruction = next; |
825 } | 825 } |
826 } | 826 } |
827 | 827 |
828 HBoundsCheck insertBoundsCheck(HInstruction indexNode, | 828 HBoundsCheck insertBoundsCheck(HInstruction indexNode, |
829 HInstruction array, | 829 HInstruction array, |
830 HInstruction indexArgument) { | 830 HInstruction indexArgument) { |
831 Compiler compiler = backend.compiler; | 831 Compiler compiler = backend.compiler; |
832 HFieldGet length = new HFieldGet( | 832 HFieldGet length = new HFieldGet( |
833 backend.jsIndexableLength, array, backend.intType, | 833 backend.jsIndexableLength, array, backend.positiveIntType, |
834 isAssignable: !isFixedLength(array.instructionType, compiler)); | 834 isAssignable: !isFixedLength(array.instructionType, compiler)); |
835 indexNode.block.addBefore(indexNode, length); | 835 indexNode.block.addBefore(indexNode, length); |
836 | 836 |
| 837 TypeMask type = indexArgument.isPositiveInteger(compiler) |
| 838 ? indexArgument.instructionType |
| 839 : backend.positiveIntType; |
837 HBoundsCheck check = new HBoundsCheck( | 840 HBoundsCheck check = new HBoundsCheck( |
838 indexArgument, length, array, backend.intType); | 841 indexArgument, length, array, type); |
839 indexNode.block.addBefore(indexNode, check); | 842 indexNode.block.addBefore(indexNode, check); |
840 // If the index input to the bounds check was not known to be an integer | 843 // If the index input to the bounds check was not known to be an integer |
841 // then we replace its uses with the bounds check, which is known to be an | 844 // then we replace its uses with the bounds check, which is known to be an |
842 // integer. However, if the input was already an integer we don't do this | 845 // integer. However, if the input was already an integer we don't do this |
843 // because putting in a check instruction might obscure the real nature of | 846 // because putting in a check instruction might obscure the real nature of |
844 // the index eg. if it is a constant. The range information from the | 847 // the index eg. if it is a constant. The range information from the |
845 // BoundsCheck instruction is attached to the input directly by | 848 // BoundsCheck instruction is attached to the input directly by |
846 // visitBoundsCheck in the SsaValueRangeAnalyzer. | 849 // visitBoundsCheck in the SsaValueRangeAnalyzer. |
847 if (!indexArgument.isInteger(compiler)) { | 850 if (!indexArgument.isInteger(compiler)) { |
848 indexArgument.replaceAllUsersDominatedBy(indexNode, check); | 851 indexArgument.replaceAllUsersDominatedBy(indexNode, check); |
(...skipping 1073 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1922 | 1925 |
1923 keyedValues.forEach((receiver, values) { | 1926 keyedValues.forEach((receiver, values) { |
1924 result.keyedValues[receiver] = | 1927 result.keyedValues[receiver] = |
1925 new Map<HInstruction, HInstruction>.from(values); | 1928 new Map<HInstruction, HInstruction>.from(values); |
1926 }); | 1929 }); |
1927 | 1930 |
1928 result.nonEscapingReceivers.addAll(nonEscapingReceivers); | 1931 result.nonEscapingReceivers.addAll(nonEscapingReceivers); |
1929 return result; | 1932 return result; |
1930 } | 1933 } |
1931 } | 1934 } |
OLD | NEW |