| Index: src/code-stubs.cc
|
| diff --git a/src/code-stubs.cc b/src/code-stubs.cc
|
| index 2bc3de9e8c6a5876ddfed46002824b16091c2ca3..b8529ec1ae238da41abc9a35b53785bb529d865c 100644
|
| --- a/src/code-stubs.cc
|
| +++ b/src/code-stubs.cc
|
| @@ -19,6 +19,15 @@
|
| namespace v8 {
|
| namespace internal {
|
|
|
| +enum class StrictEqualsFlags : unsigned char {
|
| + Normal = 0,
|
| + NanEqualsNan = 1 << 0,
|
| +};
|
| +
|
| +static inline bool operator&(StrictEqualsFlags lhs, StrictEqualsFlags rhs) {
|
| + return (static_cast<unsigned char>(lhs) & static_cast<unsigned char>(rhs)) !=
|
| + 0;
|
| +}
|
|
|
| RUNTIME_FUNCTION(UnexpectedStubMiss) {
|
| FATAL("Unexpected deopt of a stub");
|
| @@ -2266,7 +2275,8 @@ enum ResultMode { kDontNegateResult, kNegateResult };
|
|
|
| void GenerateEqual_Same(CodeStubAssembler* assembler, compiler::Node* value,
|
| CodeStubAssembler::Label* if_equal,
|
| - CodeStubAssembler::Label* if_notequal) {
|
| + CodeStubAssembler::Label* if_notequal,
|
| + StrictEqualsFlags flags) {
|
| // In case of abstract or strict equality checks, we need additional checks
|
| // for NaN values because they are not considered equal, even if both the
|
| // left and the right hand side reference exactly the same value.
|
| @@ -2294,11 +2304,16 @@ void GenerateEqual_Same(CodeStubAssembler* assembler, compiler::Node* value,
|
|
|
| assembler->Bind(&if_valueisnumber);
|
| {
|
| - // Convert {value} (and therefore {rhs}) to floating point value.
|
| - Node* value_value = assembler->LoadHeapNumberValue(value);
|
| -
|
| - // Check if the HeapNumber value is a NaN.
|
| - assembler->BranchIfFloat64IsNaN(value_value, if_notequal, if_equal);
|
| + if (flags & StrictEqualsFlags::NanEqualsNan) {
|
| + // NaN === NaN --- No special treatment
|
| + assembler->Goto(if_equal);
|
| + } else {
|
| + // Convert {value} (and therefore {rhs}) to floating point value.
|
| + Node* value_value = assembler->LoadHeapNumberValue(value);
|
| +
|
| + // Check if the HeapNumber value is a NaN.
|
| + assembler->BranchIfFloat64IsNaN(value_value, if_notequal, if_equal);
|
| + }
|
| }
|
|
|
| assembler->Bind(&if_valueisnotnumber);
|
| @@ -2431,7 +2446,8 @@ compiler::Node* GenerateEqual(CodeStubAssembler* assembler, ResultMode mode,
|
| {
|
| // The {lhs} and {rhs} reference the exact same value, yet we need special
|
| // treatment for HeapNumber, as NaN is not equal to NaN.
|
| - GenerateEqual_Same(assembler, lhs, &if_equal, &if_notequal);
|
| + GenerateEqual_Same(assembler, lhs, &if_equal, &if_notequal,
|
| + StrictEqualsFlags::Normal);
|
| }
|
|
|
| assembler->Bind(&if_notsame);
|
| @@ -2931,7 +2947,8 @@ compiler::Node* GenerateEqual(CodeStubAssembler* assembler, ResultMode mode,
|
| compiler::Node* GenerateStrictEqual(CodeStubAssembler* assembler,
|
| ResultMode mode, compiler::Node* lhs,
|
| compiler::Node* rhs,
|
| - compiler::Node* context) {
|
| + compiler::Node* context,
|
| + StrictEqualsFlags flags) {
|
| // Here's pseudo-code for the algorithm below in case of kDontNegateResult
|
| // mode; for kNegateResult mode we properly negate the result.
|
| //
|
| @@ -2995,7 +3012,7 @@ compiler::Node* GenerateStrictEqual(CodeStubAssembler* assembler,
|
| {
|
| // The {lhs} and {rhs} reference the exact same value, yet we need special
|
| // treatment for HeapNumber, as NaN is not equal to NaN.
|
| - GenerateEqual_Same(assembler, lhs, &if_equal, &if_notequal);
|
| + GenerateEqual_Same(assembler, lhs, &if_equal, &if_notequal, flags);
|
| }
|
|
|
| assembler->Bind(&if_notsame);
|
| @@ -3052,6 +3069,16 @@ compiler::Node* GenerateStrictEqual(CodeStubAssembler* assembler,
|
| Node* lhs_value = assembler->LoadHeapNumberValue(lhs);
|
| Node* rhs_value = assembler->LoadHeapNumberValue(rhs);
|
|
|
| + if (flags & StrictEqualsFlags::NanEqualsNan) {
|
| + Label isnan(assembler), isnotnan(assembler);
|
| + assembler->BranchIfFloat64IsNaN(lhs_value, &isnan, &isnotnan);
|
| +
|
| + assembler->Bind(&isnan);
|
| + assembler->BranchIfFloat64IsNaN(rhs_value, &if_equal, &isnotnan);
|
| +
|
| + assembler->Bind(&isnotnan);
|
| + }
|
| +
|
| // Perform a floating point comparison of {lhs} and {rhs}.
|
| assembler->BranchIfFloat64Equal(lhs_value, rhs_value, &if_equal,
|
| &if_notequal);
|
| @@ -3627,7 +3654,8 @@ compiler::Node* StrictEqualStub::Generate(CodeStubAssembler* assembler,
|
| compiler::Node* lhs,
|
| compiler::Node* rhs,
|
| compiler::Node* context) {
|
| - return GenerateStrictEqual(assembler, kDontNegateResult, lhs, rhs, context);
|
| + return GenerateStrictEqual(assembler, kDontNegateResult, lhs, rhs, context,
|
| + StrictEqualsFlags::Normal);
|
| }
|
|
|
| // static
|
| @@ -3635,7 +3663,16 @@ compiler::Node* StrictNotEqualStub::Generate(CodeStubAssembler* assembler,
|
| compiler::Node* lhs,
|
| compiler::Node* rhs,
|
| compiler::Node* context) {
|
| - return GenerateStrictEqual(assembler, kNegateResult, lhs, rhs, context);
|
| + return GenerateStrictEqual(assembler, kNegateResult, lhs, rhs, context,
|
| + StrictEqualsFlags::Normal);
|
| +}
|
| +
|
| +compiler::Node* SameValueZeroStub::Generate(CodeStubAssembler* assembler,
|
| + compiler::Node* lhs,
|
| + compiler::Node* rhs,
|
| + compiler::Node* context) {
|
| + return GenerateStrictEqual(assembler, kDontNegateResult, lhs, rhs, context,
|
| + StrictEqualsFlags::NanEqualsNan);
|
| }
|
|
|
| void StringEqualStub::GenerateAssembly(CodeStubAssembler* assembler) const {
|
|
|