Index: src/x64/codegen-x64.cc |
=================================================================== |
--- src/x64/codegen-x64.cc (revision 3660) |
+++ src/x64/codegen-x64.cc (working copy) |
@@ -5030,31 +5030,6 @@ |
return; |
} |
- // Set the flags based on the operation, type and loop nesting level. |
- GenericBinaryFlags flags; |
- switch (op) { |
- case Token::BIT_OR: |
- case Token::BIT_AND: |
- case Token::BIT_XOR: |
- case Token::SHL: |
- case Token::SHR: |
- case Token::SAR: |
- // 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) |
- ? NO_SMI_CODE_IN_STUB |
- : NO_GENERIC_BINARY_FLAGS; |
- break; |
- |
- default: |
- // 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()) |
- ? NO_SMI_CODE_IN_STUB |
- : NO_GENERIC_BINARY_FLAGS; |
- break; |
- } |
- |
Result right = frame_->Pop(); |
Result left = frame_->Pop(); |
@@ -5088,7 +5063,6 @@ |
bool left_is_non_smi = left.is_constant() && !left.handle()->IsSmi(); |
bool right_is_smi = right.is_constant() && right.handle()->IsSmi(); |
bool right_is_non_smi = right.is_constant() && !right.handle()->IsSmi(); |
- bool generate_no_smi_code = false; // No smi code at all, inline or in stub. |
if (left_is_smi && right_is_smi) { |
// Compute the constant result at compile time, and leave it on the frame. |
@@ -5097,34 +5071,35 @@ |
if (FoldConstantSmis(op, left_int, right_int)) return; |
} |
+ Result answer; |
if (left_is_non_smi || right_is_non_smi) { |
- // Set flag so that we go straight to the slow case, with no smi code. |
- generate_no_smi_code = true; |
+ // Go straight to the slow case, with no smi code |
+ frame_->Push(&left); |
+ frame_->Push(&right); |
+ GenericBinaryOpStub stub(op, overwrite_mode, NO_SMI_CODE_IN_STUB); |
+ answer = frame_->CallStub(&stub, 2); |
} else if (right_is_smi) { |
- ConstantSmiBinaryOperation(op, &left, right.handle(), |
- type, false, overwrite_mode); |
- return; |
+ answer = ConstantSmiBinaryOperation(op, &left, right.handle(), |
+ type, false, overwrite_mode); |
} else if (left_is_smi) { |
- ConstantSmiBinaryOperation(op, &right, left.handle(), |
- type, true, overwrite_mode); |
- return; |
- } |
- |
- if ((flags & NO_SMI_CODE_IN_STUB) != 0 && !generate_no_smi_code) { |
- LikelySmiBinaryOperation(op, &left, &right, overwrite_mode); |
+ answer = ConstantSmiBinaryOperation(op, &right, left.handle(), |
+ type, true, overwrite_mode); |
} else { |
- frame_->Push(&left); |
- frame_->Push(&right); |
- // If we know the arguments aren't smis, use the binary operation stub |
- // that does not check for the fast smi case. |
- // The same stub is used for NO_SMI_CODE and SMI_CODE_INLINED. |
- if (generate_no_smi_code) { |
- flags = NO_SMI_CODE_IN_STUB; |
+ // Set the flags based on the operation, type and loop nesting level. |
+ // 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. |
+ // For all other operations only inline the Smi check code for likely smis |
+ // if the operation is part of a loop. |
+ if (loop_nesting() > 0 && (Token::IsBitOp(op) || type->IsLikelySmi())) { |
+ answer = LikelySmiBinaryOperation(op, &left, &right, overwrite_mode); |
+ } else { |
+ frame_->Push(&left); |
+ frame_->Push(&right); |
+ GenericBinaryOpStub stub(op, overwrite_mode, NO_GENERIC_BINARY_FLAGS); |
+ answer = frame_->CallStub(&stub, 2); |
} |
- GenericBinaryOpStub stub(op, overwrite_mode, flags); |
- Result answer = frame_->CallStub(&stub, 2); |
- frame_->Push(&answer); |
} |
+ frame_->Push(&answer); |
} |
@@ -5205,12 +5180,12 @@ |
} |
-void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, |
- Result* operand, |
- Handle<Object> value, |
- StaticType* type, |
- bool reversed, |
- OverwriteMode overwrite_mode) { |
+Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, |
+ Result* operand, |
+ Handle<Object> value, |
+ StaticType* type, |
+ bool reversed, |
+ OverwriteMode overwrite_mode) { |
// NOTE: This is an attempt to inline (a bit) more of the code for |
// some possible smi operations (like + and -) when (at least) one |
// of the operands is a constant smi. |
@@ -5221,20 +5196,19 @@ |
if (IsUnsafeSmi(value)) { |
Result unsafe_operand(value); |
if (reversed) { |
- LikelySmiBinaryOperation(op, &unsafe_operand, operand, |
+ return LikelySmiBinaryOperation(op, &unsafe_operand, operand, |
overwrite_mode); |
} else { |
- LikelySmiBinaryOperation(op, operand, &unsafe_operand, |
+ return LikelySmiBinaryOperation(op, operand, &unsafe_operand, |
overwrite_mode); |
} |
- ASSERT(!operand->is_valid()); |
- return; |
} |
// Get the literal value. |
Smi* smi_value = Smi::cast(*value); |
int int_value = smi_value->value(); |
+ Result answer; |
switch (op) { |
case Token::ADD: { |
operand->ToRegister(); |
@@ -5255,15 +5229,15 @@ |
smi_value, |
deferred->entry_label()); |
deferred->BindExit(); |
- frame_->Push(operand); |
+ answer = *operand; |
break; |
} |
case Token::SUB: { |
if (reversed) { |
Result constant_operand(value); |
- LikelySmiBinaryOperation(op, &constant_operand, operand, |
- overwrite_mode); |
+ answer = LikelySmiBinaryOperation(op, &constant_operand, operand, |
+ overwrite_mode); |
} else { |
operand->ToRegister(); |
frame_->Spill(operand->reg()); |
@@ -5277,7 +5251,7 @@ |
smi_value, |
deferred->entry_label()); |
deferred->BindExit(); |
- frame_->Push(operand); |
+ answer = *operand; |
} |
break; |
} |
@@ -5285,8 +5259,8 @@ |
case Token::SAR: |
if (reversed) { |
Result constant_operand(value); |
- LikelySmiBinaryOperation(op, &constant_operand, operand, |
- overwrite_mode); |
+ answer = LikelySmiBinaryOperation(op, &constant_operand, operand, |
+ overwrite_mode); |
} else { |
// Only the least significant 5 bits of the shift value are used. |
// In the slow case, this masking is done inside the runtime call. |
@@ -5304,21 +5278,21 @@ |
operand->reg(), |
shift_value); |
deferred->BindExit(); |
- frame_->Push(operand); |
+ answer = *operand; |
} |
break; |
case Token::SHR: |
if (reversed) { |
Result constant_operand(value); |
- LikelySmiBinaryOperation(op, &constant_operand, operand, |
- overwrite_mode); |
+ answer = LikelySmiBinaryOperation(op, &constant_operand, operand, |
+ overwrite_mode); |
} else { |
// Only the least significant 5 bits of the shift value are used. |
// In the slow case, this masking is done inside the runtime call. |
int shift_value = int_value & 0x1f; |
operand->ToRegister(); |
- Result answer = allocator()->Allocate(); |
+ answer = allocator()->Allocate(); |
ASSERT(answer.is_valid()); |
DeferredInlineSmiOperation* deferred = |
new DeferredInlineSmiOperation(op, |
@@ -5333,15 +5307,14 @@ |
deferred->entry_label()); |
deferred->BindExit(); |
operand->Unuse(); |
- frame_->Push(&answer); |
} |
break; |
case Token::SHL: |
if (reversed) { |
Result constant_operand(value); |
- LikelySmiBinaryOperation(op, &constant_operand, operand, |
- overwrite_mode); |
+ answer = LikelySmiBinaryOperation(op, &constant_operand, operand, |
+ overwrite_mode); |
} else { |
// Only the least significant 5 bits of the shift value are used. |
// In the slow case, this masking is done inside the runtime call. |
@@ -5358,10 +5331,10 @@ |
overwrite_mode); |
__ JumpIfNotSmi(operand->reg(), deferred->entry_label()); |
deferred->BindExit(); |
- frame_->Push(operand); |
+ answer = *operand; |
} else { |
// Use a fresh temporary for nonzero shift values. |
- Result answer = allocator()->Allocate(); |
+ answer = allocator()->Allocate(); |
ASSERT(answer.is_valid()); |
DeferredInlineSmiOperation* deferred = |
new DeferredInlineSmiOperation(op, |
@@ -5376,7 +5349,6 @@ |
deferred->entry_label()); |
deferred->BindExit(); |
operand->Unuse(); |
- frame_->Push(&answer); |
} |
} |
break; |
@@ -5411,7 +5383,7 @@ |
} |
} |
deferred->BindExit(); |
- frame_->Push(operand); |
+ answer = *operand; |
break; |
} |
@@ -5439,7 +5411,7 @@ |
Smi::FromInt(int_value - 1)); |
} |
deferred->BindExit(); |
- frame_->Push(operand); |
+ answer = *operand; |
break; // This break only applies if we generated code for MOD. |
} |
// Fall through if we did not find a power of 2 on the right hand side! |
@@ -5448,22 +5420,24 @@ |
default: { |
Result constant_operand(value); |
if (reversed) { |
- LikelySmiBinaryOperation(op, &constant_operand, operand, |
- overwrite_mode); |
+ answer = LikelySmiBinaryOperation(op, &constant_operand, operand, |
+ overwrite_mode); |
} else { |
- LikelySmiBinaryOperation(op, operand, &constant_operand, |
- overwrite_mode); |
+ answer = LikelySmiBinaryOperation(op, operand, &constant_operand, |
+ overwrite_mode); |
} |
break; |
} |
} |
- ASSERT(!operand->is_valid()); |
+ ASSERT(answer.is_valid()); |
+ return answer; |
} |
-void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, |
- Result* left, |
- Result* right, |
- OverwriteMode overwrite_mode) { |
+Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op, |
+ Result* left, |
+ Result* right, |
+ OverwriteMode overwrite_mode) { |
+ Result answer; |
// Special handling of div and mod because they use fixed registers. |
if (op == Token::DIV || op == Token::MOD) { |
// We need rax as the quotient register, rdx as the remainder |
@@ -5545,16 +5519,17 @@ |
deferred->BindExit(); |
left->Unuse(); |
right->Unuse(); |
- frame_->Push("ient); |
+ answer = quotient; |
} else { |
ASSERT(op == Token::MOD); |
__ SmiMod(rdx, left->reg(), right->reg(), deferred->entry_label()); |
deferred->BindExit(); |
left->Unuse(); |
right->Unuse(); |
- frame_->Push(&remainder); |
+ answer = remainder; |
} |
- return; |
+ ASSERT(answer.is_valid()); |
+ return answer; |
} |
// Special handling of shift operations because they use fixed |
@@ -5575,7 +5550,7 @@ |
frame_->Spill(rcx); |
// Use a fresh answer register to avoid spilling the left operand. |
- Result answer = allocator_->Allocate(); |
+ answer = allocator_->Allocate(); |
ASSERT(answer.is_valid()); |
// Check that both operands are smis using the answer register as a |
// temporary. |
@@ -5614,8 +5589,8 @@ |
deferred->BindExit(); |
left->Unuse(); |
right->Unuse(); |
- frame_->Push(&answer); |
- return; |
+ ASSERT(answer.is_valid()); |
+ return answer; |
} |
// Handle the other binary operations. |
@@ -5624,7 +5599,7 @@ |
// A newly allocated register answer is used to hold the answer. The |
// registers containing left and right are not modified so they don't |
// need to be spilled in the fast case. |
- Result answer = allocator_->Allocate(); |
+ answer = allocator_->Allocate(); |
ASSERT(answer.is_valid()); |
// Perform the smi tag check. |
@@ -5678,7 +5653,8 @@ |
deferred->BindExit(); |
left->Unuse(); |
right->Unuse(); |
- frame_->Push(&answer); |
+ ASSERT(answer.is_valid()); |
+ return answer; |
} |