| Index: src/arm/code-stubs-arm.cc
|
| diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
|
| index 8b0779bcf26fb41621d0b9e606f966f30326eb90..8c6d17e563c3be2d0d098e7b381f28783b9ba135 100644
|
| --- a/src/arm/code-stubs-arm.cc
|
| +++ b/src/arm/code-stubs-arm.cc
|
| @@ -6007,23 +6007,28 @@ void SubStringStub::Generate(MacroAssembler* masm) {
|
| STATIC_ASSERT(kSmiTag == 0);
|
| STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
|
|
|
| - // I.e., arithmetic shift right by one un-smi-tags.
|
| - __ mov(r2, Operand(r2, ASR, 1), SetCC);
|
| - __ mov(r3, Operand(r3, ASR, 1), SetCC, cc);
|
| - // If either to or from had the smi tag bit set, then carry is set now.
|
| - __ b(cs, &runtime); // Either "from" or "to" is not a smi.
|
| + // Arithmetic shift right by one un-smi-tags. In this case we rotate right
|
| + // instead because we bail out on non-smi values: ROR and ASR are equivalent
|
| + // for smis but they set the flags in a way that's easier to optimize.
|
| + __ mov(r2, Operand(r2, ROR, 1), SetCC);
|
| + __ mov(r3, Operand(r3, ROR, 1), SetCC, cc);
|
| + // If either to or from had the smi tag bit set, then C is set now, and N
|
| + // has the same value: we rotated by 1, so the bottom bit is now the top bit.
|
| // We want to bailout to runtime here if From is negative. In that case, the
|
| // next instruction is not executed and we fall through to bailing out to
|
| - // runtime. pl is the opposite of mi.
|
| - // Both r2 and r3 are untagged integers.
|
| - __ sub(r2, r2, Operand(r3), SetCC, pl);
|
| - __ b(mi, &runtime); // Fail if from > to.
|
| + // runtime.
|
| + // Executed if both r2 and r3 are untagged integers.
|
| + __ sub(r2, r2, Operand(r3), SetCC, cc);
|
| + // One of the above un-smis or the above SUB could have set N==1.
|
| + __ b(mi, &runtime); // Either "from" or "to" is not an smi, or from > to.
|
|
|
| // Make sure first argument is a string.
|
| __ ldr(r0, MemOperand(sp, kStringOffset));
|
| STATIC_ASSERT(kSmiTag == 0);
|
| - __ JumpIfSmi(r0, &runtime);
|
| - Condition is_string = masm->IsObjectStringType(r0, r1);
|
| + // Do a JumpIfSmi, but fold its jump into the subsequent string test.
|
| + __ tst(r0, Operand(kSmiTagMask));
|
| + Condition is_string = masm->IsObjectStringType(r0, r1, ne);
|
| + ASSERT(is_string == eq);
|
| __ b(NegateCondition(is_string), &runtime);
|
|
|
| // Short-cut for the case of trivial substring.
|
|
|