From 47d8af76160999a851dc3fd8b0ae20cbe2d570e3 Mon Sep 17 00:00:00 2001 From: "dslomov@chromium.org" Date: Thu, 28 Mar 2013 13:30:16 +0000 Subject: [PATCH] Canonicalize NaNs on store to Fast(Float|Double) arrays Also treat holey NaN coming from external float/double arrays correctly BUG=2596 Review URL: https://codereview.chromium.org/12918028 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14094 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/elements-kind.h | 9 ++++-- src/hydrogen-instructions.cc | 19 +++++++++++- test/mjsunit/regress/regress-2596.js | 56 ++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 test/mjsunit/regress/regress-2596.js diff --git a/src/elements-kind.h b/src/elements-kind.h index cb3bb9c..da15192 100644 --- a/src/elements-kind.h +++ b/src/elements-kind.h @@ -110,10 +110,15 @@ inline bool IsFastDoubleElementsKind(ElementsKind kind) { } +inline bool IsExternalFloatOrDoubleElementsKind(ElementsKind kind) { + return kind == EXTERNAL_DOUBLE_ELEMENTS || + kind == EXTERNAL_FLOAT_ELEMENTS; +} + + inline bool IsDoubleOrFloatElementsKind(ElementsKind kind) { return IsFastDoubleElementsKind(kind) || - kind == EXTERNAL_DOUBLE_ELEMENTS || - kind == EXTERNAL_FLOAT_ELEMENTS; + IsExternalFloatOrDoubleElementsKind(kind); } diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index 9b96cfe..8e0d89e 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -2590,6 +2590,10 @@ bool HLoadKeyed::UsesMustHandleHole() const { return false; } + if (IsExternalArrayElementsKind(elements_kind())) { + return false; + } + if (hole_mode() == ALLOW_RETURN_HOLE) return true; if (IsFastDoubleElementsKind(elements_kind())) { @@ -2612,6 +2616,10 @@ bool HLoadKeyed::RequiresHoleCheck() const { return false; } + if (IsExternalArrayElementsKind(elements_kind())) { + return false; + } + return !UsesMustHandleHole(); } @@ -3037,10 +3045,19 @@ bool HStoreKeyed::NeedsCanonicalization() { // If value is an integer or smi or comes from the result of a keyed load or // constant then it is either be a non-hole value or in the case of a constant // the hole is only being stored explicitly: no need for canonicalization. - if (value()->IsLoadKeyed() || value()->IsConstant()) { + // + // The exception to that is keyed loads from external float or double arrays: + // these can load arbitrary representation of NaN. + + if (value()->IsConstant()) { return false; } + if (value()->IsLoadKeyed()) { + return IsExternalFloatOrDoubleElementsKind( + HLoadKeyed::cast(value())->elements_kind()); + } + if (value()->IsChange()) { if (HChange::cast(value())->from().IsInteger32()) { return false; diff --git a/test/mjsunit/regress/regress-2596.js b/test/mjsunit/regress/regress-2596.js new file mode 100644 index 0000000..1d327fe --- /dev/null +++ b/test/mjsunit/regress/regress-2596.js @@ -0,0 +1,56 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --allow-natives-syntax + +var bytes = new Uint8Array([ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]); // kHoleNaN +var doubles = new Float64Array(bytes.buffer); +assertTrue(isNaN(doubles[0])); + +var prototype = [2.5, 2.5]; +var array = [3.5, 3.5]; +array.__proto__ = prototype; +assertTrue(%HasFastDoubleElements(array)); + +function boom(index) { + array[index] = doubles[0]; + return array[index]; +} + +assertTrue(isNaN(boom(0))); +assertTrue(isNaN(boom(0))); +assertTrue(isNaN(boom(0))); + +// Test hydrogen +%OptimizeFunctionOnNextCall(boom); +assertTrue(isNaN(boom(0))); +assertTrue(isNaN(boom(0))); +assertTrue(isNaN(boom(0))); + + + -- 2.7.4