Index: src/x64/code-stubs-x64.cc |
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc |
index b7923a7fbc6248332140def34eafbad7955f0de3..19ca8d6a7466bf2404ee7625fd9d8fa090b36c9c 100644 |
--- a/src/x64/code-stubs-x64.cc |
+++ b/src/x64/code-stubs-x64.cc |
@@ -1283,7 +1283,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, undetectable; |
+ Label return_equal, 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. |
@@ -1297,10 +1297,10 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) { |
__ movp(rcx, FieldOperand(rdx, HeapObject::kMapOffset)); |
__ testb(FieldOperand(rbx, Map::kBitFieldOffset), |
Immediate(1 << Map::kIsUndetectable)); |
- __ j(not_zero, &undetectable); |
+ __ j(not_zero, &undetectable, Label::kNear); |
__ testb(FieldOperand(rcx, Map::kBitFieldOffset), |
Immediate(1 << Map::kIsUndetectable)); |
- __ j(not_zero, &return_unequal); |
+ __ j(not_zero, &return_unequal, Label::kNear); |
__ CmpInstanceType(rbx, FIRST_JS_RECEIVER_TYPE); |
__ j(below, &runtime_call, Label::kNear); |
@@ -1314,7 +1314,17 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) { |
__ bind(&undetectable); |
__ testb(FieldOperand(rcx, Map::kBitFieldOffset), |
Immediate(1 << Map::kIsUndetectable)); |
- __ j(zero, &return_unequal); |
+ __ j(zero, &return_unequal, Label::kNear); |
+ |
+ // If both sides are JSReceivers, then the result is false according to |
+ // the HTML specification, which says that only comparisons with null or |
+ // undefined are affected by special casing for document.all. |
+ __ CmpInstanceType(rbx, ODDBALL_TYPE); |
+ __ j(zero, &return_equal, Label::kNear); |
+ __ CmpInstanceType(rcx, ODDBALL_TYPE); |
+ __ j(not_zero, &return_unequal, Label::kNear); |
+ |
+ __ bind(&return_equal); |
__ Set(rax, EQUAL); |
__ ret(0); |
} |