diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc index b3df929d78..8ed9817cd6 100644 --- a/src/x64/codegen-x64.cc +++ b/src/x64/codegen-x64.cc @@ -3084,26 +3084,36 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) { is_increment); } + // If we have a free register, combine the smi and overflow checks. Result tmp = allocator_->AllocateWithoutSpilling(); ASSERT(kSmiTagMask == 1 && kSmiTag == 0); - __ movl(tmp.reg(), Immediate(kSmiTagMask)); - // Smi test. + if (tmp.is_valid()) { + __ movl(tmp.reg(), Immediate(kSmiTagMask)); + } + + // Try incrementing or decrementing the smi. __ movq(kScratchRegister, new_value.reg()); if (is_increment) { __ addl(kScratchRegister, Immediate(Smi::FromInt(1))); } else { __ subl(kScratchRegister, Immediate(Smi::FromInt(1))); } - // deferred->Branch(overflow); - __ cmovl(overflow, kScratchRegister, tmp.reg()); - __ testl(kScratchRegister, tmp.reg()); - tmp.Unuse(); - deferred->Branch(not_zero); + + // Go to the deferred case if the result overflows or is non-smi. + if (tmp.is_valid()){ + __ cmovl(overflow, kScratchRegister, tmp.reg()); + __ testl(kScratchRegister, tmp.reg()); + tmp.Unuse(); + deferred->Branch(not_zero); + } else { + deferred->Branch(overflow); + __ testl(kScratchRegister, Immediate(kSmiTagMask)); + deferred->Branch(not_zero); + } + __ movq(new_value.reg(), kScratchRegister); - deferred->BindExit(); - // Postfix: store the old value in the allocated slot under the // reference. if (is_postfix) frame_->SetElementAt(target.size(), &old_value);