| Index: src/x64/code-stubs-x64.cc
|
| ===================================================================
|
| --- src/x64/code-stubs-x64.cc (revision 5457)
|
| +++ src/x64/code-stubs-x64.cc (working copy)
|
| @@ -1404,33 +1404,35 @@
|
| Label slow, done;
|
|
|
| if (op_ == Token::SUB) {
|
| - // Check whether the value is a smi.
|
| - Label try_float;
|
| - __ JumpIfNotSmi(rax, &try_float);
|
| + if (include_smi_code_) {
|
| + // Check whether the value is a smi.
|
| + Label try_float;
|
| + __ JumpIfNotSmi(rax, &try_float);
|
| + if (negative_zero_ == kIgnoreNegativeZero) {
|
| + __ SmiCompare(rax, Smi::FromInt(0));
|
| + __ j(equal, &done);
|
| + }
|
| + __ SmiNeg(rax, rax, &done);
|
|
|
| - if (negative_zero_ == kIgnoreNegativeZero) {
|
| - __ SmiCompare(rax, Smi::FromInt(0));
|
| - __ j(equal, &done);
|
| + // Either zero or Smi::kMinValue, neither of which become a smi when
|
| + // negated. We handle negative zero here if required. We always enter
|
| + // the runtime system if we have Smi::kMinValue.
|
| + if (negative_zero_ == kStrictNegativeZero) {
|
| + __ SmiCompare(rax, Smi::FromInt(0));
|
| + __ j(not_equal, &slow);
|
| + __ Move(rax, Factory::minus_zero_value());
|
| + __ jmp(&done);
|
| + } else {
|
| + __ SmiCompare(rax, Smi::FromInt(Smi::kMinValue));
|
| + __ j(equal, &slow);
|
| + __ jmp(&done);
|
| + }
|
| + // Try floating point case.
|
| + __ bind(&try_float);
|
| + } else if (FLAG_debug_code) {
|
| + __ AbortIfSmi(rax);
|
| }
|
|
|
| - // Enter runtime system if the value of the smi is zero
|
| - // to make sure that we switch between 0 and -0.
|
| - // Also enter it if the value of the smi is Smi::kMinValue.
|
| - __ SmiNeg(rax, rax, &done);
|
| -
|
| - // Either zero or Smi::kMinValue, neither of which become a smi when
|
| - // negated.
|
| - if (negative_zero_ == kStrictNegativeZero) {
|
| - __ SmiCompare(rax, Smi::FromInt(0));
|
| - __ j(not_equal, &slow);
|
| - __ Move(rax, Factory::minus_zero_value());
|
| - __ jmp(&done);
|
| - } else {
|
| - __ jmp(&slow);
|
| - }
|
| -
|
| - // Try floating point case.
|
| - __ bind(&try_float);
|
| __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
|
| __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex);
|
| __ j(not_equal, &slow);
|
| @@ -1449,6 +1451,17 @@
|
| __ movq(rax, rcx);
|
| }
|
| } else if (op_ == Token::BIT_NOT) {
|
| + if (include_smi_code_) {
|
| + Label try_float;
|
| + __ JumpIfNotSmi(rax, &try_float);
|
| + __ SmiNot(rax, rax);
|
| + __ jmp(&done);
|
| + // Try floating point case.
|
| + __ bind(&try_float);
|
| + } else if (FLAG_debug_code) {
|
| + __ AbortIfSmi(rax);
|
| + }
|
| +
|
| // Check if the operand is a heap number.
|
| __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
|
| __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex);
|
| @@ -2115,6 +2128,26 @@
|
| ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg));
|
|
|
| Label check_unequal_objects, done;
|
| +
|
| + // Compare two smis if required.
|
| + if (include_smi_compare_) {
|
| + Label non_smi, smi_done;
|
| + __ JumpIfNotBothSmi(rax, rdx, &non_smi);
|
| + __ subq(rdx, rax);
|
| + __ j(no_overflow, &smi_done);
|
| + __ neg(rdx); // Correct sign in case of overflow.
|
| + __ bind(&smi_done);
|
| + __ movq(rax, rdx);
|
| + __ ret(0);
|
| + __ bind(&non_smi);
|
| + } else if (FLAG_debug_code) {
|
| + Label ok;
|
| + __ JumpIfNotSmi(rdx, &ok);
|
| + __ JumpIfNotSmi(rax, &ok);
|
| + __ Abort("CompareStub: smi operands");
|
| + __ bind(&ok);
|
| + }
|
| +
|
| // The compare stub returns a positive, negative, or zero 64-bit integer
|
| // value in rax, corresponding to result of comparing the two inputs.
|
| // NOTICE! This code is only reached after a smi-fast-case check, so
|
| @@ -3001,7 +3034,8 @@
|
| | RegisterField::encode(false) // lhs_ and rhs_ are not used
|
| | StrictField::encode(strict_)
|
| | NeverNanNanField::encode(cc_ == equal ? never_nan_nan_ : false)
|
| - | IncludeNumberCompareField::encode(include_number_compare_);
|
| + | IncludeNumberCompareField::encode(include_number_compare_)
|
| + | IncludeSmiCompareField::encode(include_smi_compare_);
|
| }
|
|
|
|
|
| @@ -3041,12 +3075,18 @@
|
| include_number_compare_name = "_NO_NUMBER";
|
| }
|
|
|
| + const char* include_smi_compare_name = "";
|
| + if (!include_smi_compare_) {
|
| + include_smi_compare_name = "_NO_SMI";
|
| + }
|
| +
|
| OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
|
| "CompareStub_%s%s%s%s",
|
| cc_name,
|
| strict_name,
|
| never_nan_nan_name,
|
| - include_number_compare_name);
|
| + include_number_compare_name,
|
| + include_smi_compare_name);
|
| return name_;
|
| }
|
|
|
|
|