From c757fa46043db201f3b27f33903ea7accc285afd Mon Sep 17 00:00:00 2001 From: "fschneider@chromium.org" Date: Wed, 20 Jan 2010 16:13:53 +0000 Subject: [PATCH] Refactor GenericBinaryOperation and its helper functions to always return a Result. This is a preparation step for including number type information in the virtual frame. We need a common place where we can update the number type information of the result of a binary operation since we should not modify the state of the virtual frame elements directly. Review URL: http://codereview.chromium.org/551080 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3661 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ia32/codegen-ia32.cc | 163 ++++++++++++++++---------------------- src/ia32/codegen-ia32.h | 20 ++--- src/x64/codegen-x64.cc | 164 +++++++++++++++++---------------------- src/x64/codegen-x64.h | 20 ++--- 4 files changed, 158 insertions(+), 209 deletions(-) diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc index 37b8acd754..b6f4cb77c7 100644 --- a/src/ia32/codegen-ia32.cc +++ b/src/ia32/codegen-ia32.cc @@ -913,31 +913,6 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op, 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(); @@ -971,7 +946,6 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op, 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. @@ -980,33 +954,35 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op, 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; - } else if (right_is_smi) { - ConstantSmiBinaryOperation(op, &left, right.handle(), - type, false, overwrite_mode); - return; - } 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); - } else { + // Go straight to the slow case, with no smi code. 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. - if (generate_no_smi_code) { - flags = NO_SMI_CODE_IN_STUB; + GenericBinaryOpStub stub(op, overwrite_mode, NO_SMI_CODE_IN_STUB); + answer = frame_->CallStub(&stub, 2); + } else if (right_is_smi) { + answer = ConstantSmiBinaryOperation(op, &left, right.handle(), + type, false, overwrite_mode); + } else if (left_is_smi) { + answer = ConstantSmiBinaryOperation(op, &right, left.handle(), + type, true, overwrite_mode); + } else { + // 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); } @@ -1093,10 +1069,11 @@ bool CodeGenerator::FoldConstantSmis(Token::Value op, int left, int right) { // Implements a binary operation using a deferred code object and some // inline code to operate on smis quickly. -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 eax as the quotient register, edx as the remainder @@ -1218,7 +1195,7 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, deferred->BindExit(); left->Unuse(); right->Unuse(); - frame_->Push("ient); + answer = quotient; } else { ASSERT(op == Token::MOD); // Check for a negative zero result. If the result is zero, and @@ -1234,9 +1211,10 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, 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 @@ -1257,7 +1235,7 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, frame_->Spill(ecx); // 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. @@ -1321,8 +1299,8 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, deferred->BindExit(); left->Unuse(); right->Unuse(); - frame_->Push(&answer); - return; + ASSERT(answer.is_valid()); + return answer; } // Handle the other binary operations. @@ -1331,7 +1309,7 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, // 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. @@ -1406,7 +1384,8 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, deferred->BindExit(); left->Unuse(); right->Unuse(); - frame_->Push(&answer); + ASSERT(answer.is_valid()); + return answer; } @@ -1575,36 +1554,34 @@ void DeferredInlineSmiSub::Generate() { } -void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, - Result* operand, - Handle value, - StaticType* type, - bool reversed, - OverwriteMode overwrite_mode) { +Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, + Result* operand, + Handle 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. // Consumes the argument "operand". - // TODO(199): Optimize some special cases of operations involving a // smi literal (multiply by 2, shift by 0, etc.). if (IsUnsafeSmi(value)) { Result unsafe_operand(value); if (reversed) { - LikelySmiBinaryOperation(op, &unsafe_operand, operand, - overwrite_mode); + return LikelySmiBinaryOperation(op, &unsafe_operand, operand, + overwrite_mode); } else { - LikelySmiBinaryOperation(op, operand, &unsafe_operand, - overwrite_mode); + 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(); @@ -1627,13 +1604,12 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, __ test(operand->reg(), Immediate(kSmiTagMask)); deferred->Branch(not_zero); deferred->BindExit(); - frame_->Push(operand); + answer = *operand; break; } case Token::SUB: { DeferredCode* deferred = NULL; - Result answer; // Only allocate a new register if reversed. if (reversed) { // The reversed case is only hit when the right operand is not a // constant. @@ -1661,15 +1637,14 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, deferred->Branch(not_zero); deferred->BindExit(); operand->Unuse(); - frame_->Push(&answer); break; } 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. @@ -1689,21 +1664,21 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, __ and_(operand->reg(), ~kSmiTagMask); } 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, @@ -1724,7 +1699,6 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, operand->Unuse(); __ SmiTag(answer.reg()); deferred->BindExit(); - frame_->Push(&answer); } break; @@ -1749,7 +1723,7 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, } operand->Unuse(); - Result answer = allocator()->Allocate(); + answer = allocator()->Allocate(); DeferredInlineSmiOperationReversed* deferred = new DeferredInlineSmiOperationReversed(op, answer.reg(), @@ -1765,7 +1739,6 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, __ SmiTag(answer.reg()); deferred->BindExit(); - frame_->Push(&answer); } 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. @@ -1783,10 +1756,10 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, __ test(operand->reg(), Immediate(kSmiTagMask)); deferred->Branch(not_zero); 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, @@ -1808,7 +1781,6 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, deferred->Branch(overflow); deferred->BindExit(); operand->Unuse(); - frame_->Push(&answer); } } break; @@ -1847,7 +1819,7 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, } } deferred->BindExit(); - frame_->Push(operand); + answer = *operand; break; } @@ -1873,7 +1845,7 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, __ and_(operand->reg(), (int_value << kSmiTagSize) - 1); } deferred->BindExit(); - frame_->Push(operand); + answer = *operand; break; } // Fall through if we did not find a power of 2 on the right hand side! @@ -1881,16 +1853,17 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, 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; } diff --git a/src/ia32/codegen-ia32.h b/src/ia32/codegen-ia32.h index d8c4ba1086..44753aa70b 100644 --- a/src/ia32/codegen-ia32.h +++ b/src/ia32/codegen-ia32.h @@ -444,20 +444,20 @@ class CodeGenerator: public AstVisitor { // Emit code to perform a binary operation on a constant // smi and a likely smi. Consumes the Result *operand. - void ConstantSmiBinaryOperation(Token::Value op, - Result* operand, - Handle constant_operand, - StaticType* type, - bool reversed, - OverwriteMode overwrite_mode); + Result ConstantSmiBinaryOperation(Token::Value op, + Result* operand, + Handle constant_operand, + StaticType* type, + bool reversed, + OverwriteMode overwrite_mode); // Emit code to perform a binary operation on two likely smis. // The code to handle smi arguments is produced inline. // Consumes the Results *left and *right. - void LikelySmiBinaryOperation(Token::Value op, - Result* left, - Result* right, - OverwriteMode overwrite_mode); + Result LikelySmiBinaryOperation(Token::Value op, + Result* left, + Result* right, + OverwriteMode overwrite_mode); void Comparison(AstNode* node, Condition cc, diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc index 3dcb75ed5a..2b0167b303 100644 --- a/src/x64/codegen-x64.cc +++ b/src/x64/codegen-x64.cc @@ -5030,31 +5030,6 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op, 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 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op, 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 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op, 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; - } else if (right_is_smi) { - ConstantSmiBinaryOperation(op, &left, right.handle(), - type, false, overwrite_mode); - return; - } 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); - } else { + // Go straight to the slow case, with no smi code 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; + GenericBinaryOpStub stub(op, overwrite_mode, NO_SMI_CODE_IN_STUB); + answer = frame_->CallStub(&stub, 2); + } else if (right_is_smi) { + answer = ConstantSmiBinaryOperation(op, &left, right.handle(), + type, false, overwrite_mode); + } else if (left_is_smi) { + answer = ConstantSmiBinaryOperation(op, &right, left.handle(), + type, true, overwrite_mode); + } else { + // 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 DeferredInlineSmiOperation::Generate() { } -void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, - Result* operand, - Handle value, - StaticType* type, - bool reversed, - OverwriteMode overwrite_mode) { +Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, + Result* operand, + Handle 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 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, 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 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, 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 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, smi_value, deferred->entry_label()); deferred->BindExit(); - frame_->Push(operand); + answer = *operand; } break; } @@ -5285,8 +5259,8 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, 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 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, 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 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, 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 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, 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 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, deferred->entry_label()); deferred->BindExit(); operand->Unuse(); - frame_->Push(&answer); } } break; @@ -5411,7 +5383,7 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, } } deferred->BindExit(); - frame_->Push(operand); + answer = *operand; break; } @@ -5439,7 +5411,7 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, 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 @@ void CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, 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 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, 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 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, 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 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, 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 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, // 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 @@ void CodeGenerator::LikelySmiBinaryOperation(Token::Value op, deferred->BindExit(); left->Unuse(); right->Unuse(); - frame_->Push(&answer); + ASSERT(answer.is_valid()); + return answer; } diff --git a/src/x64/codegen-x64.h b/src/x64/codegen-x64.h index a640b26d1d..766ca139de 100644 --- a/src/x64/codegen-x64.h +++ b/src/x64/codegen-x64.h @@ -446,20 +446,20 @@ class CodeGenerator: public AstVisitor { // Emit code to perform a binary operation on a constant // smi and a likely smi. Consumes the Result *operand. - void ConstantSmiBinaryOperation(Token::Value op, - Result* operand, - Handle constant_operand, - StaticType* type, - bool reversed, - OverwriteMode overwrite_mode); + Result ConstantSmiBinaryOperation(Token::Value op, + Result* operand, + Handle constant_operand, + StaticType* type, + bool reversed, + OverwriteMode overwrite_mode); // Emit code to perform a binary operation on two likely smis. // The code to handle smi arguments is produced inline. // Consumes the Results *left and *right. - void LikelySmiBinaryOperation(Token::Value op, - Result* left, - Result* right, - OverwriteMode overwrite_mode); + Result LikelySmiBinaryOperation(Token::Value op, + Result* left, + Result* right, + OverwriteMode overwrite_mode); void Comparison(Condition cc, bool strict,