| Index: src/hydrogen-instructions.cc
|
| diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
|
| index 074054ce1d0c414ce12c6e8230400a1acd798cba..4bf4f2fbcb371952b508b5edadf2cfa4d2844835 100644
|
| --- a/src/hydrogen-instructions.cc
|
| +++ b/src/hydrogen-instructions.cc
|
| @@ -1457,7 +1457,22 @@ void HGoto::PrintDataTo(StringStream* stream) {
|
| void HCompareIDAndBranch::SetInputRepresentation(Representation r) {
|
| input_representation_ = r;
|
| if (r.IsDouble()) {
|
| - SetFlag(kDeoptimizeOnUndefined);
|
| + // According to the ES5 spec (11.9.3, 11.8.5), Equality comparisons (==, ===
|
| + // and !=) have special handling of undefined, e.g. undefined == undefined
|
| + // is 'true'. Relational comparisons have a different semantic, first
|
| + // calling ToPrimitive() on their arguments. The standard Crankshaft
|
| + // tagged-to-double conversion to ensure the HCompareIDAndBranch's inputs
|
| + // are doubles caused 'undefined' to be converted to NaN. That's compatible
|
| + // out-of-the box with ordered relational comparisons (<, >, <=,
|
| + // >=). However, for equality comparisons (and for 'in' and 'instanceof'),
|
| + // it is not consistent with the spec. For example, it would cause undefined
|
| + // == undefined (should be true) to be evaluated as NaN == NaN
|
| + // (false). Therefore, any comparisons other than ordered relational
|
| + // comparisons must cause a deopt when one of their arguments is undefined.
|
| + // See also v8:1434
|
| + if (!Token::IsOrderedRelationalCompareOp(token_)) {
|
| + SetFlag(kDeoptimizeOnUndefined);
|
| + }
|
| } else {
|
| ASSERT(r.IsInteger32());
|
| }
|
|
|