| Index: src/x87/code-stubs-x87.cc
|
| diff --git a/src/x87/code-stubs-x87.cc b/src/x87/code-stubs-x87.cc
|
| index 1ee8484452be9e440306e3711368f12659291d97..ea22725dbfdacb85f48c0b5dcc65c51c4f105172 100644
|
| --- a/src/x87/code-stubs-x87.cc
|
| +++ b/src/x87/code-stubs-x87.cc
|
| @@ -1573,7 +1573,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
| // Non-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.
|
| @@ -1582,26 +1582,32 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
| __ lea(ecx, Operand(eax, edx, times_1, 0));
|
| __ test(ecx, Immediate(kSmiTagMask));
|
| __ j(not_zero, &runtime_call, Label::kNear);
|
| - __ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ecx);
|
| +
|
| + __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
|
| + __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
|
| +
|
| + __ test_b(FieldOperand(ebx, Map::kBitFieldOffset),
|
| + 1 << Map::kIsUndetectable);
|
| + __ j(not_zero, &undetectable, Label::kNear);
|
| + __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
|
| + 1 << Map::kIsUndetectable);
|
| + __ j(not_zero, &return_unequal, Label::kNear);
|
| +
|
| + __ CmpInstanceType(ebx, FIRST_JS_RECEIVER_TYPE);
|
| __ j(below, &runtime_call, Label::kNear);
|
| - __ CmpObjectType(edx, FIRST_JS_RECEIVER_TYPE, ebx);
|
| + __ CmpInstanceType(ecx, FIRST_JS_RECEIVER_TYPE);
|
| __ j(below, &runtime_call, Label::kNear);
|
| - // We do not bail out after this point. Both are JSObjects, and
|
| - // they are equal if and only if both are undetectable.
|
| - // The and of the undetectable flags is 1 if and only if they are equal.
|
| +
|
| + __ bind(&return_unequal);
|
| + // Return non-equal by returning the non-zero object pointer in eax.
|
| + __ ret(0); // eax, edx were pushed
|
| +
|
| + __ bind(&undetectable);
|
| __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
|
| 1 << Map::kIsUndetectable);
|
| __ j(zero, &return_unequal, Label::kNear);
|
| - __ test_b(FieldOperand(ebx, Map::kBitFieldOffset),
|
| - 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.
|
| __ Move(eax, Immediate(EQUAL));
|
| - __ bind(&return_unequal);
|
| - // Return non-equal by returning the non-zero object pointer in eax,
|
| - // or return equal if we fell through to here.
|
| - __ ret(0); // rax, rdx were pushed
|
| + __ ret(0); // eax, edx were pushed
|
| }
|
| __ bind(&runtime_call);
|
|
|
|
|