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, |