Index: src/ia32/full-codegen-ia32.cc |
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc |
index 09f5de1f10a239ac32e3a42c14b1b8a02cff8d89..82d23e7791d05d9ab58e98cb393ab08e4f04ee21 100644 |
--- a/src/ia32/full-codegen-ia32.cc |
+++ b/src/ia32/full-codegen-ia32.cc |
@@ -4394,14 +4394,50 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
PrepareForBailoutForId(prop->LoadId(), TOS_REG); |
} |
- // Call ToNumber only if operand is not a smi. |
- Label no_conversion; |
+ // Inline smi case if we are in a loop. |
+ Label done, stub_call; |
+ JumpPatchSite patch_site(masm_); |
if (ShouldInlineSmiCase(expr->op())) { |
- __ JumpIfSmi(eax, &no_conversion, Label::kNear); |
+ Label slow; |
+ patch_site.EmitJumpIfNotSmi(eax, &slow, Label::kNear); |
+ |
+ // Save result for postfix expressions. |
+ if (expr->is_postfix()) { |
+ if (!context()->IsEffect()) { |
+ // Save the result on the stack. If we have a named or keyed property |
+ // we store the result under the receiver that is currently on top |
+ // of the stack. |
+ switch (assign_type) { |
+ case VARIABLE: |
+ __ push(eax); |
+ break; |
+ case NAMED_PROPERTY: |
+ __ mov(Operand(esp, kPointerSize), eax); |
+ break; |
+ case KEYED_PROPERTY: |
+ __ mov(Operand(esp, 2 * kPointerSize), eax); |
+ break; |
+ } |
+ } |
+ } |
+ |
+ if (expr->op() == Token::INC) { |
+ __ add(eax, Immediate(Smi::FromInt(1))); |
+ } else { |
+ __ sub(eax, Immediate(Smi::FromInt(1))); |
+ } |
+ __ j(no_overflow, &done, Label::kNear); |
+ // Call stub. Undo operation first. |
+ if (expr->op() == Token::INC) { |
+ __ sub(eax, Immediate(Smi::FromInt(1))); |
+ } else { |
+ __ add(eax, Immediate(Smi::FromInt(1))); |
+ } |
+ __ jmp(&stub_call, Label::kNear); |
+ __ bind(&slow); |
} |
ToNumberStub convert_stub; |
__ CallStub(&convert_stub); |
- __ bind(&no_conversion); |
// Save result for postfix expressions. |
if (expr->is_postfix()) { |
@@ -4423,34 +4459,11 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
} |
} |
- // Inline smi case if we are in a loop. |
- Label done, stub_call; |
- JumpPatchSite patch_site(masm_); |
- |
- if (ShouldInlineSmiCase(expr->op())) { |
- if (expr->op() == Token::INC) { |
- __ add(eax, Immediate(Smi::FromInt(1))); |
- } else { |
- __ sub(eax, Immediate(Smi::FromInt(1))); |
- } |
- __ j(overflow, &stub_call, Label::kNear); |
- // We could eliminate this smi check if we split the code at |
- // the first smi check before calling ToNumber. |
- patch_site.EmitJumpIfSmi(eax, &done, Label::kNear); |
- |
- __ bind(&stub_call); |
- // Call stub. Undo operation first. |
- if (expr->op() == Token::INC) { |
- __ sub(eax, Immediate(Smi::FromInt(1))); |
- } else { |
- __ add(eax, Immediate(Smi::FromInt(1))); |
- } |
- } |
- |
// Record position before stub call. |
SetSourcePosition(expr->position()); |
// Call stub for +1/-1. |
+ __ bind(&stub_call); |
__ mov(edx, eax); |
__ mov(eax, Immediate(Smi::FromInt(1))); |
BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); |