Index: src/x64/full-codegen-x64.cc |
=================================================================== |
--- src/x64/full-codegen-x64.cc (revision 3667) |
+++ src/x64/full-codegen-x64.cc (working copy) |
@@ -1489,7 +1489,7 @@ |
if (assign_type == VARIABLE) { |
ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); |
Location saved_location = location_; |
- location_ = kStack; |
+ location_ = kAccumulator; |
EmitVariableLoad(expr->expression()->AsVariableProxy()->var(), |
Expression::kValue); |
location_ = saved_location; |
@@ -1505,11 +1505,16 @@ |
VisitForValue(prop->key(), kStack); |
EmitKeyedPropertyLoad(prop); |
} |
- __ push(rax); |
} |
- // Convert to number. |
+ // Call ToNumber only if operand is not a smi. |
+ Label no_conversion; |
+ Condition is_smi; |
+ is_smi = masm_->CheckSmi(rax); |
+ __ j(is_smi, &no_conversion); |
+ __ push(rax); |
__ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); |
+ __ bind(&no_conversion); |
// Save result for postfix expressions. |
if (expr->is_postfix()) { |
@@ -1541,6 +1546,27 @@ |
} |
} |
+ // Inline smi case if we are in a loop. |
+ Label stub_call, done; |
+ if (loop_depth() > 0) { |
+ if (expr->op() == Token::INC) { |
+ __ SmiAddConstant(rax, rax, Smi::FromInt(1)); |
+ } else { |
+ __ SmiSubConstant(rax, rax, Smi::FromInt(1)); |
+ } |
+ __ j(overflow, &stub_call); |
+ // We could eliminate this smi check if we split the code at |
+ // the first smi check before calling ToNumber. |
+ is_smi = masm_->CheckSmi(rax); |
+ __ j(is_smi, &done); |
+ __ 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)); |
+ } |
+ } |
// Call stub for +1/-1. |
__ push(rax); |
__ Push(Smi::FromInt(1)); |
@@ -1548,6 +1574,7 @@ |
NO_OVERWRITE, |
NO_GENERIC_BINARY_FLAGS); |
__ CallStub(&stub); |
+ __ bind(&done); |
// Store the value returned in rax. |
switch (assign_type) { |