Index: src/x64/code-stubs-x64.cc |
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc |
index b28e53bd9835542dd1c81926fff69cb6177d9133..3c83411388b64778e35dc8f76d592ac30242b1b8 100644 |
--- a/src/x64/code-stubs-x64.cc |
+++ b/src/x64/code-stubs-x64.cc |
@@ -1695,7 +1695,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) { |
// Not strict equality. Objects are unequal if |
// they are both JSObjects and not undetectable, |
// and their pointers are different. |
- Label return_unequal; |
+ Label return_unequal, undetectable; |
// At most one is a smi, so we can test for smi by adding the two. |
// A smi plus a heap object has the low bit set, a heap object plus |
// a heap object has the low bit clear. |
@@ -1704,22 +1704,30 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) { |
__ leap(rcx, Operand(rax, rdx, times_1, 0)); |
__ testb(rcx, Immediate(kSmiTagMask)); |
__ j(not_zero, &runtime_call, Label::kNear); |
- __ CmpObjectType(rax, FIRST_JS_RECEIVER_TYPE, rbx); |
- __ j(below, &runtime_call, Label::kNear); |
- __ CmpObjectType(rdx, FIRST_JS_RECEIVER_TYPE, rcx); |
- __ j(below, &runtime_call, Label::kNear); |
+ |
+ __ movp(rbx, FieldOperand(rax, HeapObject::kMapOffset)); |
+ __ movp(rcx, FieldOperand(rdx, HeapObject::kMapOffset)); |
__ testb(FieldOperand(rbx, Map::kBitFieldOffset), |
Immediate(1 << Map::kIsUndetectable)); |
- __ j(zero, &return_unequal, Label::kNear); |
+ __ j(not_zero, &undetectable); |
__ testb(FieldOperand(rcx, Map::kBitFieldOffset), |
Immediate(1 << Map::kIsUndetectable)); |
- __ j(zero, &return_unequal, Label::kNear); |
- // The objects are both undetectable, so they both compare as the value |
- // undefined, and are equal. |
- __ Set(rax, EQUAL); |
+ __ j(not_zero, &return_unequal); |
+ |
+ __ CmpInstanceType(rbx, FIRST_JS_RECEIVER_TYPE); |
+ __ j(below, &runtime_call, Label::kNear); |
+ __ CmpInstanceType(rcx, FIRST_JS_RECEIVER_TYPE); |
+ __ j(below, &runtime_call, Label::kNear); |
+ |
__ bind(&return_unequal); |
- // Return non-equal by returning the non-zero object pointer in rax, |
- // or return equal if we fell through to here. |
+ // Return non-equal by returning the non-zero object pointer in rax. |
+ __ ret(0); |
+ |
+ __ bind(&undetectable); |
+ __ testb(FieldOperand(rcx, Map::kBitFieldOffset), |
+ Immediate(1 << Map::kIsUndetectable)); |
+ __ j(zero, &return_unequal); |
+ __ Set(rax, EQUAL); |
__ ret(0); |
} |
__ bind(&runtime_call); |