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 { |