| Index: src/arm/code-stubs-arm.cc
|
| ===================================================================
|
| --- src/arm/code-stubs-arm.cc (revision 5449)
|
| +++ src/arm/code-stubs-arm.cc (working copy)
|
| @@ -930,6 +930,24 @@
|
| Label slow; // Call builtin.
|
| Label not_smis, both_loaded_as_doubles, lhs_not_nan;
|
|
|
| + if (include_smi_compare_) {
|
| + Label not_two_smis, smi_done;
|
| + __ orr(r2, r1, r0);
|
| + __ tst(r2, Operand(kSmiTagMask));
|
| + __ b(ne, ¬_two_smis);
|
| + __ sub(r0, r1, r0);
|
| + __ b(vc, &smi_done);
|
| + // Correct the sign in case of overflow.
|
| + __ rsb(r0, r0, Operand(0, RelocInfo::NONE));
|
| + __ bind(&smi_done);
|
| + __ Ret();
|
| + __ bind(¬_two_smis);
|
| + } else if (FLAG_debug_code) {
|
| + __ orr(r2, r1, r0);
|
| + __ tst(r2, Operand(kSmiTagMask));
|
| + __ Assert(nz, "CompareStub: 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.
|
|
|
| @@ -2288,7 +2306,7 @@
|
| __ push(r0);
|
| __ TailCallRuntime(Runtime::kStackGuard, 1, 1);
|
|
|
| - __ StubReturn(1);
|
| + __ Ret();
|
| }
|
|
|
|
|
| @@ -2299,32 +2317,37 @@
|
| __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
|
|
|
| if (op_ == Token::SUB) {
|
| - // Check whether the value is a smi.
|
| - Label try_float;
|
| - __ tst(r0, Operand(kSmiTagMask));
|
| - __ b(ne, &try_float);
|
| + if (include_smi_code_) {
|
| + // Check whether the value is a smi.
|
| + Label try_float;
|
| + __ tst(r0, Operand(kSmiTagMask));
|
| + __ b(ne, &try_float);
|
|
|
| - // Go slow case if the value of the expression is zero
|
| - // to make sure that we switch between 0 and -0.
|
| - if (negative_zero_ == kStrictNegativeZero) {
|
| - // If we have to check for zero, then we can check for the max negative
|
| - // smi while we are at it.
|
| - __ bic(ip, r0, Operand(0x80000000), SetCC);
|
| - __ b(eq, &slow);
|
| - __ rsb(r0, r0, Operand(0, RelocInfo::NONE));
|
| - __ StubReturn(1);
|
| - } else {
|
| - // The value of the expression is a smi and 0 is OK for -0. Try
|
| - // optimistic subtraction '0 - value'.
|
| - __ rsb(r0, r0, Operand(0, RelocInfo::NONE), SetCC);
|
| - __ StubReturn(1, vc);
|
| - // We don't have to reverse the optimistic neg since the only case
|
| - // where we fall through is the minimum negative Smi, which is the case
|
| - // where the neg leaves the register unchanged.
|
| - __ jmp(&slow); // Go slow on max negative Smi.
|
| + // Go slow case if the value of the expression is zero
|
| + // to make sure that we switch between 0 and -0.
|
| + if (negative_zero_ == kStrictNegativeZero) {
|
| + // If we have to check for zero, then we can check for the max negative
|
| + // smi while we are at it.
|
| + __ bic(ip, r0, Operand(0x80000000), SetCC);
|
| + __ b(eq, &slow);
|
| + __ rsb(r0, r0, Operand(0, RelocInfo::NONE));
|
| + __ Ret();
|
| + } else {
|
| + // The value of the expression is a smi and 0 is OK for -0. Try
|
| + // optimistic subtraction '0 - value'.
|
| + __ rsb(r0, r0, Operand(0, RelocInfo::NONE), SetCC);
|
| + __ Ret(vc);
|
| + // We don't have to reverse the optimistic neg since the only case
|
| + // where we fall through is the minimum negative Smi, which is the case
|
| + // where the neg leaves the register unchanged.
|
| + __ jmp(&slow); // Go slow on max negative Smi.
|
| + }
|
| + __ bind(&try_float);
|
| + } else if (FLAG_debug_code) {
|
| + __ tst(r0, Operand(kSmiTagMask));
|
| + __ Assert(ne, "Unexpected smi operand.");
|
| }
|
|
|
| - __ bind(&try_float);
|
| __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
|
| __ AssertRegisterIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
|
| __ cmp(r1, heap_number_map);
|
| @@ -2344,6 +2367,19 @@
|
| __ mov(r0, Operand(r1));
|
| }
|
| } else if (op_ == Token::BIT_NOT) {
|
| + if (include_smi_code_) {
|
| + Label non_smi;
|
| + __ BranchOnNotSmi(r0, &non_smi);
|
| + __ mvn(r0, Operand(r0));
|
| + // Bit-clear inverted smi-tag.
|
| + __ bic(r0, r0, Operand(kSmiTagMask));
|
| + __ Ret();
|
| + __ bind(&non_smi);
|
| + } else if (FLAG_debug_code) {
|
| + __ tst(r0, Operand(kSmiTagMask));
|
| + __ Assert(ne, "Unexpected smi operand.");
|
| + }
|
| +
|
| // Check if the operand is a heap number.
|
| __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
|
| __ AssertRegisterIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
|
| @@ -2391,7 +2427,7 @@
|
| }
|
|
|
| __ bind(&done);
|
| - __ StubReturn(1);
|
| + __ Ret();
|
|
|
| // Handle the slow case by jumping to the JavaScript builtin.
|
| __ bind(&slow);
|
| @@ -3499,6 +3535,11 @@
|
| 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%s%s",
|
| cc_name,
|
| @@ -3506,7 +3547,8 @@
|
| rhs_name,
|
| strict_name,
|
| never_nan_nan_name,
|
| - include_number_compare_name);
|
| + include_number_compare_name,
|
| + include_smi_compare_name);
|
| return name_;
|
| }
|
|
|
| @@ -3522,7 +3564,8 @@
|
| | RegisterField::encode(lhs_.is(r0))
|
| | StrictField::encode(strict_)
|
| | NeverNanNanField::encode(cc_ == eq ? never_nan_nan_ : false)
|
| - | IncludeNumberCompareField::encode(include_number_compare_);
|
| + | IncludeNumberCompareField::encode(include_number_compare_)
|
| + | IncludeSmiCompareField::encode(include_smi_compare_);
|
| }
|
|
|
|
|
|
|