From bededee46ed289e652793e2ba09cd540196ac81d Mon Sep 17 00:00:00 2001 From: Peter Marshall Date: Thu, 21 Jun 2018 13:30:15 +0200 Subject: [PATCH] [typedarray] Use slow case more aggressively in CopyElementsHandleImpl Change-Id: If133fe47a086ed273446ee7e8f8af85bf9fc8389 Reviewed-on: https://chromium-review.googlesource.com/1108203 Commit-Queue: Peter Marshall Reviewed-by: Jakob Gruber Cr-Commit-Position: refs/heads/master@{#53921} --- src/elements.cc | 25 ++++++++++++++++++++---- test/mjsunit/regress/regress-854066-2.js | 14 +++++++++++++ test/mjsunit/regress/regress-854066.js | 2 +- 3 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 test/mjsunit/regress/regress-854066-2.js diff --git a/src/elements.cc b/src/elements.cc index 28aa5a614e..3eb5a98bbe 100644 --- a/src/elements.cc +++ b/src/elements.cc @@ -3408,6 +3408,16 @@ class TypedElementsAccessor DisallowHeapAllocation no_gc; DisallowJavascriptExecution no_js(isolate); + size_t current_length; + DCHECK(source->length()->IsNumber() && + TryNumberToSize(source->length(), ¤t_length) && + length <= current_length); + USE(current_length); + + size_t dest_length = destination->length_value(); + DCHECK(length + offset <= dest_length); + USE(dest_length); + ElementsKind kind = source->GetElementsKind(); BackingStore* dest = BackingStore::cast(destination->elements()); @@ -3553,10 +3563,17 @@ class TypedElementsAccessor // Fast cases for packed numbers kinds where we don't need to allocate. if (source->IsJSArray()) { - Handle source_array = Handle::cast(source); - if (TryCopyElementsFastNumber(isolate->context(), *source_array, - *destination_ta, length, offset)) { - return *isolate->factory()->undefined_value(); + Handle source_js_array = Handle::cast(source); + size_t current_length; + if (source_js_array->length()->IsNumber() && + TryNumberToSize(source_js_array->length(), ¤t_length)) { + if (length <= current_length) { + Handle source_array = Handle::cast(source); + if (TryCopyElementsFastNumber(isolate->context(), *source_array, + *destination_ta, length, offset)) { + return *isolate->factory()->undefined_value(); + } + } } } // Final generic case that handles prototype chain lookups, getters, proxies diff --git a/test/mjsunit/regress/regress-854066-2.js b/test/mjsunit/regress/regress-854066-2.js new file mode 100644 index 0000000000..d37126b0f6 --- /dev/null +++ b/test/mjsunit/regress/regress-854066-2.js @@ -0,0 +1,14 @@ +// Copyright 2018 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. + +oobArray = []; +delete oobArray.__proto__[Symbol.iterator]; +for (let i = 0; i < 1e5; ++i) { + oobArray[i] = 1.1; +} +floatArray = new Float64Array(oobArray.length); +Float64Array.from.call(function(length) { + oobArray.length = 0; + return floatArray; +}, oobArray); diff --git a/test/mjsunit/regress/regress-854066.js b/test/mjsunit/regress/regress-854066.js index a65b31ff08..418084b2a7 100644 --- a/test/mjsunit/regress/regress-854066.js +++ b/test/mjsunit/regress/regress-854066.js @@ -3,7 +3,7 @@ // found in the LICENSE file. oobArray = []; -for (let i = 0; i < 1024 * 1024; ++i) { +for (let i = 0; i < 1e5; ++i) { oobArray[i] = 1.1; } floatArray = new Float64Array(oobArray.length);