Skip to content

Commit bc9e467

Browse files
isheludkoCommit Bot
authored andcommitted
[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: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64969}
1 parent bcdbf97 commit bc9e467

3 files changed

Lines changed: 39 additions & 19 deletions

File tree

src/builtins/typed-array-sort.tq

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,17 @@ namespace typed_array {
104104
const array: JSTypedArray =
105105
ValidateTypedArray(context, obj, kBuiltinNameSort);
106106

107-
// Default sorting is done in C++ using std::sort
108-
if (comparefnObj == Undefined) {
109-
return TypedArraySortFast(context, obj);
110-
}
111-
112107
// 4. Let len be obj.[[ArrayLength]].
113108
const len: uintptr = array.length;
114109

115110
// Arrays of length 1 or less are considered sorted.
116111
if (len < 2) return array;
117112

113+
// Default sorting is done in C++ using std::sort
114+
if (comparefnObj == Undefined) {
115+
return TypedArraySortFast(context, obj);
116+
}
117+
118118
const comparefn: Callable =
119119
Cast<Callable>(comparefnObj) otherwise unreachable;
120120
const accessor: TypedArrayAccessor =

src/runtime/runtime-typedarray.cc

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ RUNTIME_FUNCTION(Runtime_TypedArraySortFast) {
8585
DCHECK(!array->WasDetached());
8686

8787
size_t length = array->length();
88-
if (length <= 1) return *array;
88+
DCHECK_LT(1, length);
8989

9090
// In case of a SAB, the data is copied into temporary memory, as
9191
// std::sort might crash in case the underlying data is concurrently
@@ -95,25 +95,29 @@ RUNTIME_FUNCTION(Runtime_TypedArraySortFast) {
9595
const bool copy_data = buffer->is_shared();
9696

9797
Handle<ByteArray> array_copy;
98+
std::vector<uint8_t> offheap_copy;
99+
void* data_copy_ptr = nullptr;
98100
if (copy_data) {
99101
const size_t bytes = array->byte_length();
100-
// TODO(szuend): Re-check this approach once support for larger typed
101-
// arrays has landed.
102-
CHECK_LE(bytes, INT_MAX);
103-
array_copy = isolate->factory()->NewByteArray(static_cast<int>(bytes));
104-
std::memcpy(static_cast<void*>(array_copy->GetDataStartAddress()),
105-
static_cast<void*>(array->DataPtr()), bytes);
102+
if (bytes <= static_cast<unsigned>(
103+
ByteArray::LengthFor(kMaxRegularHeapObjectSize))) {
104+
array_copy = isolate->factory()->NewByteArray(static_cast<int>(bytes));
105+
data_copy_ptr = array_copy->GetDataStartAddress();
106+
} else {
107+
// Allocate copy in C++ heap.
108+
offheap_copy.resize(bytes);
109+
data_copy_ptr = &offheap_copy[0];
110+
}
111+
std::memcpy(data_copy_ptr, static_cast<void*>(array->DataPtr()), bytes);
106112
}
107113

108114
DisallowHeapAllocation no_gc;
109115

110116
switch (array->type()) {
111117
#define TYPED_ARRAY_SORT(Type, type, TYPE, ctype) \
112118
case kExternal##Type##Array: { \
113-
ctype* data = \
114-
copy_data \
115-
? reinterpret_cast<ctype*>(array_copy->GetDataStartAddress()) \
116-
: static_cast<ctype*>(array->DataPtr()); \
119+
ctype* data = copy_data ? reinterpret_cast<ctype*>(data_copy_ptr) \
120+
: static_cast<ctype*>(array->DataPtr()); \
117121
if (kExternal##Type##Array == kExternalFloat64Array || \
118122
kExternal##Type##Array == kExternalFloat32Array) { \
119123
if (COMPRESS_POINTERS_BOOL && alignof(ctype) > kTaggedSize) { \
@@ -140,10 +144,10 @@ RUNTIME_FUNCTION(Runtime_TypedArraySortFast) {
140144
}
141145

142146
if (copy_data) {
143-
DCHECK(!array_copy.is_null());
147+
DCHECK_NOT_NULL(data_copy_ptr);
148+
DCHECK_NE(array_copy.is_null(), offheap_copy.empty());
144149
const size_t bytes = array->byte_length();
145-
std::memcpy(static_cast<void*>(array->DataPtr()),
146-
static_cast<void*>(array_copy->GetDataStartAddress()), bytes);
150+
std::memcpy(static_cast<void*>(array->DataPtr()), data_copy_ptr, bytes);
147151
}
148152

149153
return *array;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2019 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
let len = 0x20000;
6+
let ar = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * len));
7+
ar[7] = -13;
8+
ar[0x1673] = -42;
9+
ar[0x1f875] = -153;
10+
11+
ar.sort();
12+
13+
assertEquals(ar[0], -153);
14+
assertEquals(ar[1], -42);
15+
assertEquals(ar[2], -13);
16+
assertEquals(ar[3], 0);

0 commit comments

Comments
 (0)