From a09e5eda26d9cfe4c71d42b34bc1944c527e60bf Mon Sep 17 00:00:00 2001 From: cbruni Date: Mon, 28 Nov 2016 02:06:07 -0800 Subject: [PATCH] [runtime] Add missing @@IsConcatSpreadable check for FAST_DOUBLE_ELEMENTS A missing @@IsConcatSpreadable check caused the fast path inside the slow path to be incorrect and follow the default concat strategy when the arguments arrays contain only doubles. BUG=chromium:668414 Review-Url: https://codereview.chromium.org/2527173002 Cr-Commit-Position: refs/heads/master@{#41301} --- src/builtins/builtins-array.cc | 5 +- test/mjsunit/regress/regress-crbug-668414.js | 58 ++++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 test/mjsunit/regress/regress-crbug-668414.js diff --git a/src/builtins/builtins-array.cc b/src/builtins/builtins-array.cc index a6388e6003..9bfd68ff2f 100644 --- a/src/builtins/builtins-array.cc +++ b/src/builtins/builtins-array.cc @@ -991,8 +991,9 @@ Object* Slow_ArrayConcat(BuiltinArguments* args, Handle species, // If estimated number of elements is more than half of length, a // fixed array (fast case) is more time and space-efficient than a // dictionary. - bool fast_case = - is_array_species && (estimate_nof_elements * 2) >= estimate_result_length; + bool fast_case = is_array_species && + (estimate_nof_elements * 2) >= estimate_result_length && + isolate->IsIsConcatSpreadableLookupChainIntact(); if (fast_case && kind == FAST_DOUBLE_ELEMENTS) { Handle storage = diff --git a/test/mjsunit/regress/regress-crbug-668414.js b/test/mjsunit/regress/regress-crbug-668414.js new file mode 100644 index 0000000000..c37442081a --- /dev/null +++ b/test/mjsunit/regress/regress-crbug-668414.js @@ -0,0 +1,58 @@ +// Copyright 2016 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. + +(function testSmiArrayConcat() { + var result = [].concat([-12]); + + assertEquals(1, result.length); + assertEquals([-12], result); +})(); + +(function testDoubleArrayConcat() { + var result = [].concat([-1073741825]); + + assertEquals(1, result.length); + assertEquals([-1073741825], result); +})(); + +(function testSmiArrayNonConcatSpreadable() { + var array = [-10]; + array[Symbol.isConcatSpreadable] = false; + var result = [].concat(array); + + assertEquals(1, result.length); + assertEquals(1, result[0].length); + assertEquals([-10], result[0]); +})(); + +(function testDoubleArrayNonConcatSpreadable() { + var array = [-1073741825]; + array[Symbol.isConcatSpreadable] = false; + var result = [].concat(array); + + assertEquals(1, result.length); + assertEquals(1, result[0].length); + assertEquals([-1073741825], result[0]); +})(); + +Array.prototype[Symbol.isConcatSpreadable] = false; + + +(function testSmiArray() { + var result = [].concat([-12]); + + assertEquals(2, result.length); + assertEquals(0, result[0].length); + assertEquals(1, result[1].length); + assertEquals([-12], result[1]); +})(); + +(function testDoubleArray() { + var result = [].concat([-1073741825]); + + assertEquals(2, result.length); + assertEquals(0, result[0].length); + assertEquals(1, result[1].length); + assertEquals([-1073741825], result[1]); +})();