| Index: src/x64/codegen-x64.cc
|
| ===================================================================
|
| --- src/x64/codegen-x64.cc (revision 3862)
|
| +++ src/x64/codegen-x64.cc (working copy)
|
| @@ -5187,15 +5187,15 @@
|
| }
|
|
|
| // Get number type of left and right sub-expressions.
|
| - bool only_numbers = left.is_number() && right.is_number();
|
| - bool only_smis = left.is_smi() && right.is_smi();
|
| + NumberInfo::Type operands_type =
|
| + NumberInfo::Combine(left.number_info(), right.number_info());
|
|
|
| Result answer;
|
| if (left_is_non_smi_constant || right_is_non_smi_constant) {
|
| GenericBinaryOpStub stub(op,
|
| overwrite_mode,
|
| NO_SMI_CODE_IN_STUB,
|
| - only_numbers);
|
| + operands_type);
|
| answer = stub.GenerateCall(masm_, frame_, &left, &right);
|
| } else if (right_is_smi_constant) {
|
| answer = ConstantSmiBinaryOperation(op, &left, right.handle(),
|
| @@ -5215,50 +5215,59 @@
|
| GenericBinaryOpStub stub(op,
|
| overwrite_mode,
|
| NO_GENERIC_BINARY_FLAGS,
|
| - only_numbers);
|
| + operands_type);
|
| answer = stub.GenerateCall(masm_, frame_, &left, &right);
|
| }
|
| }
|
|
|
| // Set NumberInfo of result according to the operation performed.
|
| - NumberInfo::Type info = NumberInfo::kUnknown;
|
| + // We rely on the fact that smis have a 32 bit payload on x64.
|
| + ASSERT(kSmiValueSize == 32);
|
| + NumberInfo::Type result_type = NumberInfo::kUnknown;
|
| switch (op) {
|
| case Token::COMMA:
|
| - info = right.number_info();
|
| + result_type = right.number_info();
|
| break;
|
| case Token::OR:
|
| case Token::AND:
|
| - // Could be anything. Check inputs.
|
| - if (only_numbers)
|
| - info = NumberInfo::kNumber;
|
| + // Result type can be either of the two input types.
|
| + result_type = operands_type;
|
| break;
|
| case Token::BIT_OR:
|
| case Token::BIT_XOR:
|
| case Token::BIT_AND:
|
| + // Result is always a smi.
|
| + result_type = NumberInfo::kSmi;
|
| + break;
|
| case Token::SAR:
|
| + case Token::SHL:
|
| + // Result is always a smi.
|
| + result_type = NumberInfo::kSmi;
|
| + break;
|
| case Token::SHR:
|
| - // TODO(fsc): Make use of the fact that smis are 32 bits on x64.
|
| - info = only_smis ? NumberInfo::kSmi : NumberInfo::kNumber;
|
| + // Result of x >>> y is always a smi if y >= 1, otherwise a number.
|
| + result_type = (right.is_constant() && right.handle()->IsSmi()
|
| + && Smi::cast(*right.handle())->value() >= 1)
|
| + ? NumberInfo::kSmi
|
| + : NumberInfo::kNumber;
|
| break;
|
| - case Token::SHL:
|
| - info = NumberInfo::kNumber;
|
| - break;
|
| case Token::ADD:
|
| - // Could be strings or numbers. Check types of inputs.
|
| - if (only_numbers) {
|
| - info = NumberInfo::kNumber;
|
| - }
|
| + // Result could be a string or a number. Check types of inputs.
|
| + result_type = NumberInfo::IsNumber(operands_type)
|
| + ? NumberInfo::kNumber
|
| + : NumberInfo::kUnknown;
|
| break;
|
| case Token::SUB:
|
| case Token::MUL:
|
| case Token::DIV:
|
| case Token::MOD:
|
| - info = NumberInfo::kNumber;
|
| + // Result is always a number.
|
| + result_type = NumberInfo::kNumber;
|
| break;
|
| default:
|
| UNREACHABLE();
|
| }
|
| - answer.set_number_info(info);
|
| + answer.set_number_info(result_type);
|
| frame_->Push(&answer);
|
| }
|
|
|
| @@ -8154,7 +8163,7 @@
|
| args_in_registers_ ? "RegArgs" : "StackArgs",
|
| args_reversed_ ? "_R" : "",
|
| use_sse3_ ? "SSE3" : "SSE2",
|
| - only_numbers_in_stub_ ? "_OnlyNumbers" : "");
|
| + NumberInfo::ToString(operands_type_));
|
| return name_;
|
| }
|
|
|
| @@ -8478,7 +8487,7 @@
|
| case Token::DIV: {
|
| // rax: y
|
| // rdx: x
|
| - if (only_numbers_in_stub_) {
|
| + if (NumberInfo::IsNumber(operands_type_)) {
|
| if (FLAG_debug_code) {
|
| // Assert at runtime that inputs are only numbers.
|
| __ AbortIfNotNumber(rdx, "GenericBinaryOpStub operand not a number.");
|
|
|