Index: src/mips64/code-stubs-mips64.cc |
diff --git a/src/mips64/code-stubs-mips64.cc b/src/mips64/code-stubs-mips64.cc |
index 752396e008cd0f6ad6f573555e1a054e9f0a12ad..7ab0ebf611eacaa9441f3ba69232f074afbce377 100644 |
--- a/src/mips64/code-stubs-mips64.cc |
+++ b/src/mips64/code-stubs-mips64.cc |
@@ -510,45 +510,55 @@ static void EmitCheckForTwoHeapNumbers(MacroAssembler* masm, |
// Fast negative check for internalized-to-internalized equality. |
static void EmitCheckForInternalizedStringsOrObjects(MacroAssembler* masm, |
- Register lhs, |
- Register rhs, |
+ Register lhs, Register rhs, |
Label* possible_strings, |
- Label* not_both_strings) { |
+ Label* runtime_call) { |
DCHECK((lhs.is(a0) && rhs.is(a1)) || |
(lhs.is(a1) && rhs.is(a0))); |
// a2 is object type of rhs. |
- Label object_test; |
+ Label object_test, return_unequal, undetectable; |
STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); |
__ And(at, a2, Operand(kIsNotStringMask)); |
__ Branch(&object_test, ne, at, Operand(zero_reg)); |
__ And(at, a2, Operand(kIsNotInternalizedMask)); |
__ Branch(possible_strings, ne, at, Operand(zero_reg)); |
__ GetObjectType(rhs, a3, a3); |
- __ Branch(not_both_strings, ge, a3, Operand(FIRST_NONSTRING_TYPE)); |
+ __ Branch(runtime_call, ge, a3, Operand(FIRST_NONSTRING_TYPE)); |
__ And(at, a3, Operand(kIsNotInternalizedMask)); |
__ Branch(possible_strings, ne, at, Operand(zero_reg)); |
- // Both are internalized strings. We already checked they weren't the same |
- // pointer so they are not equal. |
+ // Both are internalized. We already checked they weren't the same pointer so |
+ // they are not equal. Return non-equal by returning the non-zero object |
+ // pointer in v0. |
__ Ret(USE_DELAY_SLOT); |
- __ li(v0, Operand(1)); // Non-zero indicates not equal. |
+ __ mov(v0, a0); // In delay slot. |
__ bind(&object_test); |
- __ Branch(not_both_strings, lt, a2, Operand(FIRST_JS_RECEIVER_TYPE)); |
- __ GetObjectType(rhs, a2, a3); |
- __ Branch(not_both_strings, lt, a3, Operand(FIRST_JS_RECEIVER_TYPE)); |
- |
- // If both objects are undetectable, they are equal. Otherwise, they |
- // are not equal, since they are different objects and an object is not |
- // equal to undefined. |
- __ ld(a3, FieldMemOperand(lhs, HeapObject::kMapOffset)); |
- __ lbu(a2, FieldMemOperand(a2, Map::kBitFieldOffset)); |
- __ lbu(a3, FieldMemOperand(a3, Map::kBitFieldOffset)); |
- __ and_(a0, a2, a3); |
- __ And(a0, a0, Operand(1 << Map::kIsUndetectable)); |
+ __ ld(a2, FieldMemOperand(lhs, HeapObject::kMapOffset)); |
+ __ ld(a3, FieldMemOperand(rhs, HeapObject::kMapOffset)); |
+ __ lbu(t0, FieldMemOperand(a2, Map::kBitFieldOffset)); |
+ __ lbu(t1, FieldMemOperand(a3, Map::kBitFieldOffset)); |
+ __ And(at, t0, Operand(1 << Map::kIsUndetectable)); |
+ __ Branch(&undetectable, ne, at, Operand(zero_reg)); |
+ __ And(at, t1, Operand(1 << Map::kIsUndetectable)); |
+ __ Branch(&return_unequal, ne, at, Operand(zero_reg)); |
+ |
+ __ GetInstanceType(a2, a2); |
+ __ Branch(runtime_call, lt, a2, Operand(FIRST_JS_RECEIVER_TYPE)); |
+ __ GetInstanceType(a3, a3); |
+ __ Branch(runtime_call, lt, a3, Operand(FIRST_JS_RECEIVER_TYPE)); |
+ |
+ __ bind(&return_unequal); |
+ // Return non-equal by returning the non-zero object pointer in v0. |
__ Ret(USE_DELAY_SLOT); |
- __ xori(v0, a0, 1 << Map::kIsUndetectable); |
+ __ mov(v0, a0); // In delay slot. |
+ |
+ __ bind(&undetectable); |
+ __ And(at, t1, Operand(1 << Map::kIsUndetectable)); |
+ __ Branch(&return_unequal, eq, at, Operand(zero_reg)); |
+ __ Ret(USE_DELAY_SLOT); |
+ __ li(v0, Operand(EQUAL)); // In delay slot. |
} |