| Index: src/ia32/codegen-ia32.cc
|
| ===================================================================
|
| --- src/ia32/codegen-ia32.cc (revision 3862)
|
| +++ src/ia32/codegen-ia32.cc (working copy)
|
| @@ -840,13 +840,13 @@
|
| }
|
|
|
| OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
|
| - "GenericBinaryOpStub_%s_%s%s_%s%s%s",
|
| + "GenericBinaryOpStub_%s_%s%s_%s%s_%s",
|
| op_name,
|
| overwrite_name,
|
| (flags_ & NO_SMI_CODE_IN_STUB) ? "_NoSmiInStub" : "",
|
| args_in_registers_ ? "RegArgs" : "StackArgs",
|
| args_reversed_ ? "_R" : "",
|
| - only_numbers_in_stub_ ? "_OnlyNumbers" : "");
|
| + NumberInfo::ToString(operands_type_));
|
| return name_;
|
| }
|
|
|
| @@ -1010,8 +1010,8 @@
|
| }
|
|
|
| // 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) {
|
| @@ -1019,7 +1019,7 @@
|
| 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(),
|
| @@ -1039,46 +1039,64 @@
|
| 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;
|
| + // Rely on the fact that smis have a 31 bit payload on ia32.
|
| + ASSERT(kSmiValueSize == 31);
|
| + 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 number. Smi property of inputs is preserved.
|
| + result_type = (operands_type == NumberInfo::kSmi)
|
| + ? NumberInfo::kSmi
|
| + : NumberInfo::kNumber;
|
| + break;
|
| case Token::SAR:
|
| + // Result is a smi if we shift by a constant >= 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::SHR:
|
| - info = only_smis ? NumberInfo::kSmi : NumberInfo::kNumber;
|
| + // Result is a smi if we shift by a constant >= 2, otherwise a number.
|
| + result_type = (right.is_constant() && right.handle()->IsSmi()
|
| + && Smi::cast(*right.handle())->value() >= 2)
|
| + ? 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::SHL:
|
| 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);
|
| }
|
|
|
| @@ -7616,7 +7634,7 @@
|
| case Token::DIV: {
|
| if (CpuFeatures::IsSupported(SSE2)) {
|
| CpuFeatures::Scope use_sse2(SSE2);
|
| - if (only_numbers_in_stub_) {
|
| + if (NumberInfo::IsNumber(operands_type_)) {
|
| if (FLAG_debug_code) {
|
| // Assert at runtime that inputs are only numbers.
|
| __ AbortIfNotNumber(edx,
|
| @@ -7640,7 +7658,7 @@
|
| __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
|
| GenerateReturn(masm);
|
| } else { // SSE2 not available, use FPU.
|
| - if (only_numbers_in_stub_) {
|
| + if (NumberInfo::IsNumber(operands_type_)) {
|
| if (FLAG_debug_code) {
|
| // Assert at runtime that inputs are only numbers.
|
| __ AbortIfNotNumber(edx,
|
|
|