Commit bc9e4675 authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[builtins] Fix sorting of huge shared TypedArrays

Bug: v8:4153, chromium:1024099
Change-Id: Ia7a53c710ad2e2abcfa6fbc4ea1b2229b8690308
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1914564
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64969}
parent bcdbf978
......@@ -104,17 +104,17 @@ namespace typed_array {
const array: JSTypedArray =
ValidateTypedArray(context, obj, kBuiltinNameSort);
// Default sorting is done in C++ using std::sort
if (comparefnObj == Undefined) {
return TypedArraySortFast(context, obj);
}
// 4. Let len be obj.[[ArrayLength]].
const len: uintptr = array.length;
// Arrays of length 1 or less are considered sorted.
if (len < 2) return array;
// Default sorting is done in C++ using std::sort
if (comparefnObj == Undefined) {
return TypedArraySortFast(context, obj);
}
const comparefn: Callable =
Cast<Callable>(comparefnObj) otherwise unreachable;
const accessor: TypedArrayAccessor =
......
......@@ -85,7 +85,7 @@ RUNTIME_FUNCTION(Runtime_TypedArraySortFast) {
DCHECK(!array->WasDetached());
size_t length = array->length();
if (length <= 1) return *array;
DCHECK_LT(1, length);
// In case of a SAB, the data is copied into temporary memory, as
// std::sort might crash in case the underlying data is concurrently
......@@ -95,14 +95,20 @@ RUNTIME_FUNCTION(Runtime_TypedArraySortFast) {
const bool copy_data = buffer->is_shared();
Handle<ByteArray> array_copy;
std::vector<uint8_t> offheap_copy;
void* data_copy_ptr = nullptr;
if (copy_data) {
const size_t bytes = array->byte_length();
// TODO(szuend): Re-check this approach once support for larger typed
// arrays has landed.
CHECK_LE(bytes, INT_MAX);
if (bytes <= static_cast<unsigned>(
ByteArray::LengthFor(kMaxRegularHeapObjectSize))) {
array_copy = isolate->factory()->NewByteArray(static_cast<int>(bytes));
std::memcpy(static_cast<void*>(array_copy->GetDataStartAddress()),
static_cast<void*>(array->DataPtr()), bytes);
data_copy_ptr = array_copy->GetDataStartAddress();
} else {
// Allocate copy in C++ heap.
offheap_copy.resize(bytes);
data_copy_ptr = &offheap_copy[0];
}
std::memcpy(data_copy_ptr, static_cast<void*>(array->DataPtr()), bytes);
}
DisallowHeapAllocation no_gc;
......@@ -110,9 +116,7 @@ RUNTIME_FUNCTION(Runtime_TypedArraySortFast) {
switch (array->type()) {
#define TYPED_ARRAY_SORT(Type, type, TYPE, ctype) \
case kExternal##Type##Array: { \
ctype* data = \
copy_data \
? reinterpret_cast<ctype*>(array_copy->GetDataStartAddress()) \
ctype* data = copy_data ? reinterpret_cast<ctype*>(data_copy_ptr) \
: static_cast<ctype*>(array->DataPtr()); \
if (kExternal##Type##Array == kExternalFloat64Array || \
kExternal##Type##Array == kExternalFloat32Array) { \
......@@ -140,10 +144,10 @@ RUNTIME_FUNCTION(Runtime_TypedArraySortFast) {
}
if (copy_data) {
DCHECK(!array_copy.is_null());
DCHECK_NOT_NULL(data_copy_ptr);
DCHECK_NE(array_copy.is_null(), offheap_copy.empty());
const size_t bytes = array->byte_length();
std::memcpy(static_cast<void*>(array->DataPtr()),
static_cast<void*>(array_copy->GetDataStartAddress()), bytes);
std::memcpy(static_cast<void*>(array->DataPtr()), data_copy_ptr, bytes);
}
return *array;
......
// Copyright 2019 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.
let len = 0x20000;
let ar = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * len));
ar[7] = -13;
ar[0x1673] = -42;
ar[0x1f875] = -153;
ar.sort();
assertEquals(ar[0], -153);
assertEquals(ar[1], -42);
assertEquals(ar[2], -13);
assertEquals(ar[3], 0);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment