Commit da45d855 authored by Shu-yu Guo's avatar Shu-yu Guo Committed by V8 LUCI CQ

Fix data races in TypedArray fill and reverse

Bug: chromium:1217573
Cq-Include-Trybots: luci.v8.try:v8_linux64_tsan_rel_ng
Change-Id: Ida9cabc4f46f0ad4f35e2b97f5803cc7c30fb972
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2947857
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75058}
parent d62df907
......@@ -3297,7 +3297,17 @@ class TypedElementsAccessor
DisallowGarbageCollection no_gc;
ElementType scalar = FromHandle(value);
ElementType* data = static_cast<ElementType*>(typed_array->DataPtr());
if (COMPRESS_POINTERS_BOOL && alignof(ElementType) > kTaggedSize) {
if (typed_array->buffer().is_shared()) {
// TypedArrays backed by shared buffers need to be filled using atomic
// operations. Since 8-byte data are not currently always 8-byte aligned,
// manually fill using SetImpl, which abstracts over alignment and atomic
// complexities.
ElementType* first = data + start;
ElementType* last = data + end;
for (; first != last; ++first) {
AccessorClass::SetImpl(first, scalar, kShared);
}
} else if (COMPRESS_POINTERS_BOOL && alignof(ElementType) > kTaggedSize) {
// TODO(ishell, v8:8875): See UnalignedSlot<T> for details.
std::fill(UnalignedSlot<ElementType>(data + start),
UnalignedSlot<ElementType>(data + end), scalar);
......@@ -3486,7 +3496,19 @@ class TypedElementsAccessor
if (len == 0) return;
ElementType* data = static_cast<ElementType*>(typed_array.DataPtr());
if (COMPRESS_POINTERS_BOOL && alignof(ElementType) > kTaggedSize) {
if (typed_array.buffer().is_shared()) {
// TypedArrays backed by shared buffers need to be reversed using atomic
// operations. Since 8-byte data are not currently always 8-byte aligned,
// manually reverse using GetImpl and SetImpl, which abstract over
// alignment and atomic complexities.
for (ElementType *first = data, *last = data + len - 1; first < last;
++first, --last) {
ElementType first_value = AccessorClass::GetImpl(first, kShared);
ElementType last_value = AccessorClass::GetImpl(last, kShared);
AccessorClass::SetImpl(first, last_value, kShared);
AccessorClass::SetImpl(last, first_value, kShared);
}
} else if (COMPRESS_POINTERS_BOOL && alignof(ElementType) > kTaggedSize) {
// TODO(ishell, v8:8875): See UnalignedSlot<T> for details.
std::reverse(UnalignedSlot<ElementType>(data),
UnalignedSlot<ElementType>(data + len));
......
// Copyright 2021 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.
const barrier_arr = new Int32Array(new SharedArrayBuffer(4));
function onmessage([data_arr, barrier_arr]) {
Atomics.store(barrier_arr, 0, 1);
for (let nr = 1; nr < 1000; ++nr) {
for (let idx = 0; idx < data_arr.length; ++idx) {
data_arr[idx] = nr;
}
}
}
const worker = new Worker(`onmessage = ${onmessage}`, {type: 'string'});
const data_arr = new Int32Array(new SharedArrayBuffer(1024));
worker.postMessage([data_arr, barrier_arr]);
while (Atomics.load(barrier_arr) == 0) { }
data_arr.reverse();
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