| Index: src/codegen-ia32.cc
|
| ===================================================================
|
| --- src/codegen-ia32.cc (revision 629)
|
| +++ src/codegen-ia32.cc (working copy)
|
| @@ -175,7 +175,8 @@
|
| cc_reg_(no_condition),
|
| state_(NULL),
|
| is_inside_try_(false),
|
| - break_stack_height_(0) {
|
| + break_stack_height_(0),
|
| + loop_nesting_(0) {
|
| }
|
|
|
|
|
| @@ -786,6 +787,7 @@
|
|
|
|
|
| void CodeGenerator::GenericBinaryOperation(Token::Value op,
|
| + StaticType* type,
|
| OverwriteMode overwrite_mode) {
|
| Comment cmnt(masm_, "[ BinaryOperation");
|
| Comment cmnt_token(masm_, Token::String(op));
|
| @@ -808,11 +810,19 @@
|
| case Token::SHL:
|
| case Token::SHR:
|
| case Token::SAR:
|
| - flags = SMI_CODE_INLINED;
|
| + // Bit operations always assume they likely operate on Smis. Still only
|
| + // generate the inline Smi check code if this operation is part of a loop.
|
| + flags = (loop_nesting() > 0)
|
| + ? SMI_CODE_INLINED
|
| + : SMI_CODE_IN_STUB;
|
| break;
|
|
|
| default:
|
| - flags = SMI_CODE_IN_STUB;
|
| + // By default only inline the Smi check code for likely smis if this
|
| + // operation is part of a loop.
|
| + flags = ((loop_nesting() > 0) && type->IsLikelySmi())
|
| + ? SMI_CODE_INLINED
|
| + : SMI_CODE_IN_STUB;
|
| break;
|
| }
|
|
|
| @@ -985,6 +995,7 @@
|
|
|
|
|
| void CodeGenerator::SmiOperation(Token::Value op,
|
| + StaticType* type,
|
| Handle<Object> value,
|
| bool reversed,
|
| OverwriteMode overwrite_mode) {
|
| @@ -1046,7 +1057,7 @@
|
| frame_->Pop(eax);
|
| frame_->Push(Immediate(value));
|
| frame_->Push(eax);
|
| - GenericBinaryOperation(op, overwrite_mode);
|
| + GenericBinaryOperation(op, type, overwrite_mode);
|
| } else {
|
| int shift_value = int_value & 0x1f; // only least significant 5 bits
|
| DeferredCode* deferred =
|
| @@ -1068,7 +1079,7 @@
|
| frame_->Pop(eax);
|
| frame_->Push(Immediate(value));
|
| frame_->Push(eax);
|
| - GenericBinaryOperation(op, overwrite_mode);
|
| + GenericBinaryOperation(op, type, overwrite_mode);
|
| } else {
|
| int shift_value = int_value & 0x1f; // only least significant 5 bits
|
| DeferredCode* deferred =
|
| @@ -1096,7 +1107,7 @@
|
| frame_->Pop(eax);
|
| frame_->Push(Immediate(value));
|
| frame_->Push(eax);
|
| - GenericBinaryOperation(op, overwrite_mode);
|
| + GenericBinaryOperation(op, type, overwrite_mode);
|
| } else {
|
| int shift_value = int_value & 0x1f; // only least significant 5 bits
|
| DeferredCode* deferred =
|
| @@ -1155,7 +1166,7 @@
|
| frame_->Push(Immediate(value));
|
| frame_->Push(eax);
|
| }
|
| - GenericBinaryOperation(op, overwrite_mode);
|
| + GenericBinaryOperation(op, type, overwrite_mode);
|
| break;
|
| }
|
| }
|
| @@ -1747,6 +1758,8 @@
|
| __ jmp(&entry);
|
| }
|
|
|
| + IncrementLoopNesting();
|
| +
|
| // body
|
| __ bind(&loop);
|
| CheckStack(); // TODO(1222600): ignore if body contains calls.
|
| @@ -1779,6 +1792,8 @@
|
| break;
|
| }
|
|
|
| + DecrementLoopNesting();
|
| +
|
| // exit
|
| __ bind(node->break_target());
|
| }
|
| @@ -2587,10 +2602,11 @@
|
| target.GetValue(NOT_INSIDE_TYPEOF);
|
| Literal* literal = node->value()->AsLiteral();
|
| if (IsInlineSmi(literal)) {
|
| - SmiOperation(node->binary_op(), literal->handle(), false, NO_OVERWRITE);
|
| + SmiOperation(node->binary_op(), node->type(), literal->handle(), false,
|
| + NO_OVERWRITE);
|
| } else {
|
| Load(node->value());
|
| - GenericBinaryOperation(node->binary_op());
|
| + GenericBinaryOperation(node->binary_op(), node->type());
|
| }
|
| }
|
|
|
| @@ -3452,16 +3468,16 @@
|
|
|
| if (IsInlineSmi(rliteral)) {
|
| Load(node->left());
|
| - SmiOperation(node->op(), rliteral->handle(), false, overwrite_mode);
|
| -
|
| + SmiOperation(node->op(), node->type(), rliteral->handle(), false,
|
| + overwrite_mode);
|
| } else if (IsInlineSmi(lliteral)) {
|
| Load(node->right());
|
| - SmiOperation(node->op(), lliteral->handle(), true, overwrite_mode);
|
| -
|
| + SmiOperation(node->op(), node->type(), lliteral->handle(), true,
|
| + overwrite_mode);
|
| } else {
|
| Load(node->left());
|
| Load(node->right());
|
| - GenericBinaryOperation(node->op(), overwrite_mode);
|
| + GenericBinaryOperation(node->op(), node->type(), overwrite_mode);
|
| }
|
| }
|
| }
|
|
|