Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/ssa/optimize.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart |
| index 962edb76c5b1bd0deb466755ce71ca121892c3a8..5ec778460da7343da9b11b551179372f751536c8 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart |
| @@ -234,7 +234,16 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
| HInstruction tryOptimizeLengthInterceptedGetter(HInvokeDynamic node) { |
| HInstruction actualReceiver = node.inputs[1]; |
| - if (actualReceiver.isIndexablePrimitive()) { |
| + |
| + // TODO(kasperl): Get rid of HType.isIndexablePrimitive() and use |
| + // something like this everywhere instead. |
| + TypeMask mask = actualReceiver.instructionType.computeMask(compiler); |
| + DartType base = backend.jsIndexableClass.computeType(compiler); |
| + TypeMask indexable = new TypeMask.nonNullSubtype(base); |
| + TypeMask union = indexable.union(mask, compiler); |
| + bool isIndexable = (union == indexable); |
| + |
| + if (isIndexable) { |
| if (actualReceiver.isConstantString()) { |
| HConstant constantInput = actualReceiver; |
| StringConstant constant = constantInput.constant; |
| @@ -244,15 +253,9 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
| ListConstant constant = constantInput.constant; |
| return graph.addConstantInt(constant.length, constantSystem); |
| } |
| - Element element; |
| - bool isAssignable; |
| - if (actualReceiver.isString()) { |
| - element = backend.jsStringLength; |
| - isAssignable = false; |
| - } else { |
| - element = backend.jsArrayLength; |
| - isAssignable = !actualReceiver.isFixedArray(); |
| - } |
| + Element element = backend.jsIndexableLength; |
| + bool isAssignable = !actualReceiver.isFixedArray() && |
| + !actualReceiver.isString(); |
| HFieldGet result = new HFieldGet( |
| element, actualReceiver, isAssignable: isAssignable); |
| result.instructionType = HType.INTEGER; |
| @@ -323,8 +326,7 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
| return result; |
| } |
| } else if (selector.isGetter()) { |
| - if (selector.applies(backend.jsArrayLength, compiler) |
| - || selector.applies(backend.jsStringLength, compiler)) { |
| + if (selector.asUntyped.applies(backend.jsIndexableLength, compiler)) { |
|
ngeoffray
2013/04/23 14:23:41
As discussed, you could use appliesUntyped.
|
| HInstruction optimized = tryOptimizeLengthInterceptedGetter(node); |
| if (optimized != null) return optimized; |
| } |
| @@ -625,7 +627,7 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
| } |
| HInstruction visitFieldGet(HFieldGet node) { |
| - if (node.element == backend.jsArrayLength) { |
| + if (node.element == backend.jsIndexableLength) { |
| if (node.receiver is HInvokeStatic) { |
| // Try to recognize the length getter with input |
| // [:new List(int):]. |
| @@ -640,16 +642,12 @@ class SsaConstantFolder extends HBaseVisitor implements OptimizationPhase { |
| && call.inputs[1].isInteger()) { |
| return call.inputs[1]; |
| } |
| - } else if (node.receiver.isConstantList()) { |
| + } else if (node.receiver.isConstantList() || |
| + node.receiver.isConstantString()) { |
| var instruction = node.receiver; |
| return graph.addConstantInt( |
| instruction.constant.length, backend.constantSystem); |
| } |
| - } else if (node.element == backend.jsStringLength |
| - && node.receiver.isConstantString()) { |
| - var instruction = node.receiver; |
| - return graph.addConstantInt( |
| - instruction.constant.length, backend.constantSystem); |
| } |
| return node; |
| } |
| @@ -941,12 +939,8 @@ class SsaCheckInserter extends HBaseVisitor implements OptimizationPhase { |
| HInstruction receiver, |
| HInstruction index) { |
| bool isAssignable = !receiver.isFixedArray() && !receiver.isString(); |
| - Element element = receiver.isString() |
| - ? backend.jsStringLength |
| - : backend.jsArrayLength; |
| HFieldGet length = new HFieldGet( |
| - element, receiver, isAssignable: isAssignable); |
| - length.instructionType = HType.INTEGER; |
| + backend.jsIndexableLength, receiver, isAssignable: isAssignable); |
| length.instructionType = HType.INTEGER; |
| node.block.addBefore(node, length); |