Fix Array.of crashing when called with lots of parameters

When the array created would exceed the maximum size for a regular heap
object, instead create it using Runtime::kNewArray directly rather than
via AllocateJSArray.

Bug: chromium:803750
Change-Id: I78cd82edf5a813a2ed69272361e0ca07f864c5ba
Reviewed-on: https://chromium-review.googlesource.com/876011
Commit-Queue: Dan Elphick <delphick@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50726}
This commit is contained in:
Dan Elphick 2018-01-19 15:38:32 +00:00 committed by Commit Bot
parent c509d025c7
commit 08b0ff26c5
2 changed files with 35 additions and 8 deletions

View File

@ -1867,15 +1867,35 @@ TF_BUILTIN(ArrayOf, ArrayBuiltinCodeStubAssembler) {
BIND(&is_not_constructor);
{
TNode<Map> array_map = CAST(LoadContextElement(
context, Context::JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX));
Label allocate_js_array(this), runtime(this);
// TODO(delphick): Consider using AllocateUninitializedJSArrayWithElements
// to avoid initializing an array and then writing over it.
array = CAST(AllocateJSArray(PACKED_SMI_ELEMENTS, array_map, length,
SmiConstant(0), nullptr,
ParameterMode::SMI_PARAMETERS));
Goto(&next);
Branch(
SmiAbove(length, SmiConstant(JSArray::kInitialMaxFastElementArray)),
&runtime, &allocate_js_array);
BIND(&allocate_js_array);
{
TNode<Map> array_map = CAST(LoadContextElement(
context, Context::JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX));
// TODO(delphick): Consider using
// AllocateUninitializedJSArrayWithElements to avoid initializing an
// array and then writing over it.
array = CAST(AllocateJSArray(PACKED_SMI_ELEMENTS, array_map, length,
SmiConstant(0), nullptr,
ParameterMode::SMI_PARAMETERS));
Goto(&next);
}
BIND(&runtime);
{
TNode<Context> native_context = LoadNativeContext(context);
TNode<JSFunction> array_function = CAST(
LoadContextElement(native_context, Context::ARRAY_FUNCTION_INDEX));
array = CallRuntime(Runtime::kNewArray, context, array_function, length,
array_function, UndefinedConstant());
Goto(&next);
}
}
BIND(&next);

View File

@ -0,0 +1,7 @@
// 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.
// Verify that very large arrays can be constructed.
assertEquals(Array.isArray(Array.of.apply(Array, Array(65536))), true);
assertEquals(Array.isArray(Array.of.apply(null, Array(65536))), true);