From 6dc967e2e0224d8f83b70d21c6b5118ec45a8968 Mon Sep 17 00:00:00 2001 From: "ishell@chromium.org" Date: Tue, 10 Jun 2014 09:01:45 +0000 Subject: [PATCH] Bugfix in inlined versions of Array.indexOf() and Array.lastIndexOf() with a regression test. BUG=chromium:381534 LOG=N R=bmeurer@chromium.org Review URL: https://codereview.chromium.org/319343002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21733 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/hydrogen-instructions.cc | 5 ++- src/hydrogen.cc | 50 ++++++++++++++++------------ test/mjsunit/regress/regress-crbug-381534.js | 40 ++++++++++++++++++++++ 3 files changed, 72 insertions(+), 23 deletions(-) create mode 100644 test/mjsunit/regress/regress-crbug-381534.js diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index 96cd016..8b40a24 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -1540,7 +1540,10 @@ HInstruction* HForceRepresentation::New(Zone* zone, HValue* context, HConstant* c = HConstant::cast(value); if (c->HasNumberValue()) { double double_res = c->DoubleValue(); - if (representation.CanContainDouble(double_res)) { + if (representation.IsDouble()) { + return HConstant::New(zone, context, double_res); + + } else if (representation.CanContainDouble(double_res)) { return HConstant::New(zone, context, static_cast(double_res), representation); diff --git a/src/hydrogen.cc b/src/hydrogen.cc index c7acf95..4db3c7f 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -8524,41 +8524,47 @@ HValue* HOptimizedGraphBuilder::BuildArrayIndexOf(HValue* receiver, } if_isstring.Else(); { - IfBuilder if_isheapnumber(this); - if_isheapnumber.IfNot(search_element); - HCompareMap* isheapnumber = if_isheapnumber.AndIf( + IfBuilder if_isnumber(this); + if_isnumber.If(search_element); + if_isnumber.OrIf( search_element, isolate()->factory()->heap_number_map()); - if_isheapnumber.Then(); + if_isnumber.Then(); { - HValue* search_number = Add( - search_element, isheapnumber, - HObjectAccess::ForHeapNumberValue()); + HValue* search_number = + AddUncasted(search_element, + Representation::Double()); LoopBuilder loop(this, context(), direction); { HValue* index = loop.BeginBody(initial, terminating, token); HValue* element = AddUncasted( elements, index, static_cast(NULL), kind, ALLOW_RETURN_HOLE); - IfBuilder if_issame(this); - if_issame.IfNot(element); - HCompareMap* issame = if_issame.AndIf( + + IfBuilder if_element_isnumber(this); + if_element_isnumber.If(element); + if_element_isnumber.OrIf( element, isolate()->factory()->heap_number_map()); - if_issame.And(); - HValue* number = Add( - element, issame, HObjectAccess::ForHeapNumberValue()); - if_issame.If( - number, search_number, Token::EQ_STRICT); - if_issame.Then(); + if_element_isnumber.Then(); { - Drop(1); - Push(index); - loop.Break(); + HValue* number = + AddUncasted(element, + Representation::Double()); + IfBuilder if_issame(this); + if_issame.If( + number, search_number, Token::EQ_STRICT); + if_issame.Then(); + { + Drop(1); + Push(index); + loop.Break(); + } + if_issame.End(); } - if_issame.End(); + if_element_isnumber.End(); } loop.EndBody(); } - if_isheapnumber.Else(); + if_isnumber.Else(); { LoopBuilder loop(this, context(), direction); { @@ -8579,7 +8585,7 @@ HValue* HOptimizedGraphBuilder::BuildArrayIndexOf(HValue* receiver, } loop.EndBody(); } - if_isheapnumber.End(); + if_isnumber.End(); } if_isstring.End(); } diff --git a/test/mjsunit/regress/regress-crbug-381534.js b/test/mjsunit/regress/regress-crbug-381534.js new file mode 100644 index 0000000..2aa3929 --- /dev/null +++ b/test/mjsunit/regress/regress-crbug-381534.js @@ -0,0 +1,40 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +var obj = {}; + +function f(v) { + var v1 = -(4/3); + var v2 = 1; + var arr = new Array(+0, true, 0, -0, false, undefined, null, "0", obj, v1, -(4/3), -1.3333333333333, "str", v2, 1, false); + assertEquals(10, arr.lastIndexOf(-(4/3))); + assertEquals(9, arr.indexOf(-(4/3))); + + assertEquals(10, arr.lastIndexOf(v)); + assertEquals(9, arr.indexOf(v)); + + assertEquals(8, arr.lastIndexOf(obj)); + assertEquals(8, arr.indexOf(obj)); +} + +function g(v, x, index) { + var arr = new Array({}, x-1.1, x-2, x-3.1); + assertEquals(index, arr.indexOf(0)); + assertEquals(index, arr.lastIndexOf(0)); + + assertEquals(index, arr.indexOf(v)); + assertEquals(index, arr.lastIndexOf(v)); +} + +f(-(4/3)); +f(-(4/3)); +%OptimizeFunctionOnNextCall(f); +f(-(4/3)); + +g(0, 2, 2); +g(0, 3.1, 3); +%OptimizeFunctionOnNextCall(g); +g(0, 1.1, 1); -- 2.7.4