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); |
} |
} |
} |