Index: src/arm/code-stubs-arm.cc |
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc |
index 6133281a6354f9c85da42917b7eab9c169ad4295..4bd2687e90f4ad705ea495c1a10636b621f96113 100644 |
--- a/src/arm/code-stubs-arm.cc |
+++ b/src/arm/code-stubs-arm.cc |
@@ -93,9 +93,8 @@ void InternalArrayNArgumentsConstructorStub::InitializeDescriptor( |
#define __ ACCESS_MASM(masm) |
-static void EmitIdenticalObjectComparison(MacroAssembler* masm, |
- Label* slow, |
- Condition cond); |
+static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow, |
+ Condition cond, bool strong); |
static void EmitSmiNonsmiComparison(MacroAssembler* masm, |
Register lhs, |
Register rhs, |
@@ -238,9 +237,8 @@ void DoubleToIStub::Generate(MacroAssembler* masm) { |
// Handle the case where the lhs and rhs are the same object. |
// Equality is almost reflexive (everything but NaN), so this is a test |
// for "identity and not NaN". |
-static void EmitIdenticalObjectComparison(MacroAssembler* masm, |
- Label* slow, |
- Condition cond) { |
+static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow, |
+ Condition cond, bool strong) { |
Label not_identical; |
Label heap_number, return_equal; |
__ cmp(r0, r1); |
@@ -251,10 +249,20 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm, |
// They are both equal and they are not both Smis so both of them are not |
// Smis. If it's not a heap number, then return equal. |
if (cond == lt || cond == gt) { |
+ // Call runtime on identical JSObjects. |
__ CompareObjectType(r0, r4, r4, FIRST_SPEC_OBJECT_TYPE); |
__ b(ge, slow); |
+ // Call runtime on identical symbols since we need to throw a TypeError. |
__ cmp(r4, Operand(SYMBOL_TYPE)); |
__ b(eq, slow); |
+ if (strong) { |
+ // Call the runtime on anything that is converted in the semantics, since |
+ // we need to throw a TypeError. Smis have already been ruled out. |
+ __ cmp(r4, Operand(HEAP_NUMBER_TYPE)); |
+ __ b(eq, &return_equal); |
+ __ tst(r4, Operand(kIsNotStringMask)); |
+ __ b(ne, slow); |
+ } |
} else { |
__ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE); |
__ b(eq, &heap_number); |
@@ -262,8 +270,16 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm, |
if (cond != eq) { |
__ cmp(r4, Operand(FIRST_SPEC_OBJECT_TYPE)); |
__ b(ge, slow); |
+ // Call runtime on identical symbols since we need to throw a TypeError. |
__ cmp(r4, Operand(SYMBOL_TYPE)); |
__ b(eq, slow); |
+ if (strong) { |
+ // Call the runtime on anything that is converted in the semantics, |
+ // since we need to throw a TypeError. Smis and heap numbers have |
+ // already been ruled out. |
+ __ tst(r4, Operand(kIsNotStringMask)); |
+ __ b(ne, slow); |
+ } |
// Normally here we fall through to return_equal, but undefined is |
// special: (undefined == undefined) == true, but |
// (undefined <= undefined) == false! See ECMAScript 11.8.5. |
@@ -561,7 +577,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) { |
// Handle the case where the objects are identical. Either returns the answer |
// or goes to slow. Only falls through if the objects were not identical. |
- EmitIdenticalObjectComparison(masm, &slow, cc); |
+ EmitIdenticalObjectComparison(masm, &slow, cc, strong()); |
// If either is a Smi (we know that not both are), then they can only |
// be strictly equal if the other is a HeapNumber. |
@@ -663,7 +679,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) { |
if (cc == eq) { |
native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS; |
} else { |
- native = Builtins::COMPARE; |
+ native = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE; |
int ncr; // NaN compare result |
if (cc == lt || cc == le) { |
ncr = GREATER; |
@@ -3567,7 +3583,7 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) { |
__ bind(&unordered); |
__ bind(&generic_stub); |
- CompareICStub stub(isolate(), op(), CompareICState::GENERIC, |
+ CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC, |
CompareICState::GENERIC, CompareICState::GENERIC); |
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); |