Chromium Code Reviews| Index: src/x64/full-codegen-x64.cc |
| diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc |
| index 6333e87bea1b6c2ed82cd2b4ea153dd0cc917890..d4f6ee88a2d67ef1e31e94163dd858c333aa6676 100644 |
| --- a/src/x64/full-codegen-x64.cc |
| +++ b/src/x64/full-codegen-x64.cc |
| @@ -4395,14 +4395,51 @@ 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(rax, &no_conversion, Label::kNear); |
| + Label slow; |
| + patch_site.EmitJumpIfNotSmi(rax, &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(rax); |
| + break; |
| + case NAMED_PROPERTY: |
| + __ movq(Operand(rsp, kPointerSize), rax); |
| + break; |
| + case KEYED_PROPERTY: |
| + __ movq(Operand(rsp, 2 * kPointerSize), rax); |
| + break; |
| + } |
| + } |
| + } |
| + |
| + if (expr->op() == Token::INC) { |
|
haitao.feng
2013/08/13 09:05:57
An alternative is:
if (expr->op() == Token::IN
danno
2013/08/19 19:36:58
I think the shorter sequence is better without the
haitao.feng
2013/08/20 14:36:05
Thanks for the review and recommendation. I will m
danno
2013/08/20 15:39:37
I like your current approach where the Smi/no Smi
haitao.feng
2013/08/20 23:21:47
Thanks for the comments. Then I will port it to IA
|
| + __ SmiAddConstant(rax, rax, Smi::FromInt(1)); |
| + } else { |
| + __ SmiSubConstant(rax, rax, Smi::FromInt(1)); |
| + } |
| + __ j(no_overflow, &done, Label::kNear); |
| + // Call stub. Undo operation first. |
| + if (expr->op() == Token::INC) { |
| + __ SmiSubConstant(rax, rax, Smi::FromInt(1)); |
| + } else { |
| + __ SmiAddConstant(rax, rax, 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()) { |
| @@ -4424,34 +4461,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) { |
| - __ SmiAddConstant(rax, rax, Smi::FromInt(1)); |
|
haitao.feng
2013/08/13 09:05:57
It takes me some time to understand that the origi
|
| - } else { |
| - __ SmiSubConstant(rax, rax, 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. |
|
haitao.feng
2013/08/13 09:05:57
This Cl splits the code at the first smi check.
|
| - patch_site.EmitJumpIfSmi(rax, &done, Label::kNear); |
| - |
| - __ bind(&stub_call); |
| - // Call stub. Undo operation first. |
| - if (expr->op() == Token::INC) { |
| - __ SmiSubConstant(rax, rax, Smi::FromInt(1)); |
| - } else { |
| - __ SmiAddConstant(rax, rax, Smi::FromInt(1)); |
| - } |
| - } |
| - |
| // Record position before stub call. |
| SetSourcePosition(expr->position()); |
| // Call stub for +1/-1. |
| + __ bind(&stub_call); |
| __ movq(rdx, rax); |
| __ Move(rax, Smi::FromInt(1)); |
| BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); |