| Index: src/ia32/code-stubs-ia32.cc
|
| ===================================================================
|
| --- src/ia32/code-stubs-ia32.cc (revision 5449)
|
| +++ src/ia32/code-stubs-ia32.cc (working copy)
|
| @@ -1879,36 +1879,36 @@
|
|
|
|
|
| void GenericUnaryOpStub::Generate(MacroAssembler* masm) {
|
| - Label slow, done;
|
| + Label slow, done, undo;
|
|
|
| if (op_ == Token::SUB) {
|
| - // Check whether the value is a smi.
|
| - Label try_float;
|
| - __ test(eax, Immediate(kSmiTagMask));
|
| - __ j(not_zero, &try_float, not_taken);
|
| + if (include_smi_code_) {
|
| + // Check whether the value is a smi.
|
| + Label try_float;
|
| + __ test(eax, Immediate(kSmiTagMask));
|
| + __ j(not_zero, &try_float, not_taken);
|
|
|
| - if (negative_zero_ == kStrictNegativeZero) {
|
| - // Go slow case if the value of the expression is zero
|
| - // to make sure that we switch between 0 and -0.
|
| - __ test(eax, Operand(eax));
|
| - __ j(zero, &slow, not_taken);
|
| - }
|
| + if (negative_zero_ == kStrictNegativeZero) {
|
| + // Go slow case if the value of the expression is zero
|
| + // to make sure that we switch between 0 and -0.
|
| + __ test(eax, Operand(eax));
|
| + __ j(zero, &slow, not_taken);
|
| + }
|
|
|
| - // The value of the expression is a smi that is not zero. Try
|
| - // optimistic subtraction '0 - value'.
|
| - Label undo;
|
| - __ mov(edx, Operand(eax));
|
| - __ Set(eax, Immediate(0));
|
| - __ sub(eax, Operand(edx));
|
| - __ j(no_overflow, &done, taken);
|
| + // The value of the expression is a smi that is not zero. Try
|
| + // optimistic subtraction '0 - value'.
|
| + __ mov(edx, Operand(eax));
|
| + __ Set(eax, Immediate(0));
|
| + __ sub(eax, Operand(edx));
|
| + __ j(overflow, &undo, not_taken);
|
| + __ StubReturn(1);
|
|
|
| - // Restore eax and go slow case.
|
| - __ bind(&undo);
|
| - __ mov(eax, Operand(edx));
|
| - __ jmp(&slow);
|
| + // Try floating point case.
|
| + __ bind(&try_float);
|
| + } else if (FLAG_debug_code) {
|
| + __ AbortIfSmi(eax);
|
| + }
|
|
|
| - // Try floating point case.
|
| - __ bind(&try_float);
|
| __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
|
| __ cmp(edx, Factory::heap_number_map());
|
| __ j(not_equal, &slow);
|
| @@ -1928,6 +1928,18 @@
|
| __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx);
|
| }
|
| } else if (op_ == Token::BIT_NOT) {
|
| + if (include_smi_code_) {
|
| + Label non_smi;
|
| + __ test(eax, Immediate(kSmiTagMask));
|
| + __ j(not_zero, &non_smi);
|
| + __ not_(eax);
|
| + __ and_(eax, ~kSmiTagMask); // Remove inverted smi-tag.
|
| + __ ret(0);
|
| + __ bind(&non_smi);
|
| + } else if (FLAG_debug_code) {
|
| + __ AbortIfSmi(eax);
|
| + }
|
| +
|
| // Check if the operand is a heap number.
|
| __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
|
| __ cmp(edx, Factory::heap_number_map());
|
| @@ -1978,6 +1990,10 @@
|
| __ bind(&done);
|
| __ StubReturn(1);
|
|
|
| + // Restore eax and go slow case.
|
| + __ bind(&undo);
|
| + __ mov(eax, Operand(edx));
|
| +
|
| // Handle the slow case by jumping to the JavaScript builtin.
|
| __ bind(&slow);
|
| __ pop(ecx); // pop return address.
|
| @@ -2613,6 +2629,27 @@
|
|
|
| Label check_unequal_objects, done;
|
|
|
| + // Compare two smis if required.
|
| + if (include_smi_compare_) {
|
| + Label non_smi, smi_done;
|
| + __ mov(ecx, Operand(edx));
|
| + __ or_(ecx, Operand(eax));
|
| + __ test(ecx, Immediate(kSmiTagMask));
|
| + __ j(not_zero, &non_smi, not_taken);
|
| + __ sub(edx, Operand(eax)); // Return on the result of the subtraction.
|
| + __ j(no_overflow, &smi_done);
|
| + __ neg(edx); // Correct sign in case of overflow.
|
| + __ bind(&smi_done);
|
| + __ mov(eax, edx);
|
| + __ ret(0);
|
| + __ bind(&non_smi);
|
| + } else if (FLAG_debug_code) {
|
| + __ mov(ecx, Operand(edx));
|
| + __ or_(ecx, Operand(eax));
|
| + __ test(ecx, Immediate(kSmiTagMask));
|
| + __ Assert(not_zero, "Unexpected smi operands.");
|
| + }
|
| +
|
| // NOTICE! This code is only reached after a smi-fast-case check, so
|
| // it is certain that at least one operand isn't a smi.
|
|
|
| @@ -3501,7 +3538,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_);
|
| }
|
|
|
|
|
| @@ -3541,12 +3579,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",
|
| + "CompareStub_%s%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_;
|
| }
|
|
|
|
|