Chromium Code Reviews| 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, |
|
caitp
2016/07/14 18:01:18
Hacky approach to reuse StrictEqualStub
|
| +}; |
| + |
| +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 { |