Index: src/ia32/full-codegen-ia32.cc |
=================================================================== |
--- src/ia32/full-codegen-ia32.cc (revision 3667) |
+++ src/ia32/full-codegen-ia32.cc (working copy) |
@@ -1482,7 +1482,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; |
@@ -1498,11 +1498,15 @@ |
VisitForValue(prop->key(), kStack); |
EmitKeyedPropertyLoad(prop); |
} |
- __ push(eax); |
} |
- // Convert to number. |
+ // Call ToNumber only if operand is not a smi. |
+ Label no_conversion; |
+ __ test(eax, Immediate(kSmiTagMask)); |
+ __ j(zero, &no_conversion); |
+ __ push(eax); |
__ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); |
+ __ bind(&no_conversion); |
// Save result for postfix expressions. |
if (expr->is_postfix()) { |
@@ -1534,6 +1538,27 @@ |
} |
} |
+ // Inline smi case if we are in a loop. |
+ Label stub_call, done; |
+ if (loop_depth() > 0) { |
+ if (expr->op() == Token::INC) { |
+ __ add(Operand(eax), Immediate(Smi::FromInt(1))); |
+ } else { |
+ __ sub(Operand(eax), Immediate(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. |
+ __ test(eax, Immediate(kSmiTagMask)); |
+ __ j(zero, &done); |
+ __ bind(&stub_call); |
+ // Call stub. Undo operation first. |
+ if (expr->op() == Token::INC) { |
+ __ sub(Operand(eax), Immediate(Smi::FromInt(1))); |
+ } else { |
+ __ add(Operand(eax), Immediate(Smi::FromInt(1))); |
+ } |
+ } |
// Call stub for +1/-1. |
__ push(eax); |
__ push(Immediate(Smi::FromInt(1))); |
@@ -1541,6 +1566,7 @@ |
NO_OVERWRITE, |
NO_GENERIC_BINARY_FLAGS); |
__ CallStub(&stub); |
+ __ bind(&done); |
// Store the value returned in eax. |
switch (assign_type) { |