Fix data race in TypedArray constructor

Use Relaxed_Memcpy when making a new TypedArray that copies from a
SharedArrayBuffer.

Bug: chromium:1209639
Change-Id: Iaa1f069552f0aa42a1f423e5ee0a913b3330153c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2923274
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74842}
This commit is contained in:
Shu-yu Guo 2021-05-27 16:38:59 -07:00 committed by V8 LUCI CQ
parent 90363c7ac9
commit 47d2924593
6 changed files with 31 additions and 1 deletions

View File

@ -294,6 +294,17 @@ void TypedArrayBuiltinsAssembler::CallCMemcpy(TNode<RawPtrT> dest_ptr,
std::make_pair(MachineType::UintPtr(), byte_length));
}
void TypedArrayBuiltinsAssembler::CallCRelaxedMemcpy(
TNode<RawPtrT> dest_ptr, TNode<RawPtrT> src_ptr,
TNode<UintPtrT> byte_length) {
TNode<ExternalReference> relaxed_memcpy =
ExternalConstant(ExternalReference::relaxed_memcpy_function());
CallCFunction(relaxed_memcpy, MachineType::AnyTagged(),
std::make_pair(MachineType::Pointer(), dest_ptr),
std::make_pair(MachineType::Pointer(), src_ptr),
std::make_pair(MachineType::UintPtr(), byte_length));
}
void TypedArrayBuiltinsAssembler::CallCMemset(TNode<RawPtrT> dest_ptr,
TNode<IntPtrT> value,
TNode<UintPtrT> length) {

View File

@ -55,6 +55,9 @@ class TypedArrayBuiltinsAssembler : public CodeStubAssembler {
void CallCMemcpy(TNode<RawPtrT> dest_ptr, TNode<RawPtrT> src_ptr,
TNode<UintPtrT> byte_length);
void CallCRelaxedMemcpy(TNode<RawPtrT> dest_ptr, TNode<RawPtrT> src_ptr,
TNode<UintPtrT> byte_length);
void CallCMemset(TNode<RawPtrT> dest_ptr, TNode<IntPtrT> value,
TNode<UintPtrT> length);

View File

@ -166,7 +166,13 @@ transitioning macro ConstructByArrayLike(implicit context: Context)(
} else if (length > 0) {
const byteLength = typedArray.byte_length;
assert(byteLength <= kArrayBufferMaxByteLength);
typed_array::CallCMemcpy(typedArray.data_ptr, src.data_ptr, byteLength);
if (IsSharedArrayBuffer(src.buffer)) {
typed_array::CallCRelaxedMemcpy(
typedArray.data_ptr, src.data_ptr, byteLength);
} else {
typed_array::CallCMemcpy(
typedArray.data_ptr, src.data_ptr, byteLength);
}
}
} label IfSlow deferred {
if (length > 0) {

View File

@ -63,6 +63,8 @@ extern macro TypedArrayBuiltinsAssembler::CallCMemmove(
RawPtr, RawPtr, uintptr): void;
extern macro TypedArrayBuiltinsAssembler::CallCMemset(
RawPtr, intptr, uintptr): void;
extern macro TypedArrayBuiltinsAssembler::CallCRelaxedMemcpy(
RawPtr, RawPtr, uintptr): void;
extern macro GetTypedArrayBuffer(implicit context: Context)(JSTypedArray):
JSArrayBuffer;
extern macro TypedArrayBuiltinsAssembler::GetTypedArrayElementsInfo(

View File

@ -804,6 +804,13 @@ void* libc_memset(void* dest, int value, size_t n) {
FUNCTION_REFERENCE(libc_memset_function, libc_memset)
void relaxed_memcpy(volatile base::Atomic8* dest,
volatile const base::Atomic8* src, size_t n) {
base::Relaxed_Memcpy(dest, src, n);
}
FUNCTION_REFERENCE(relaxed_memcpy_function, relaxed_memcpy)
ExternalReference ExternalReference::printf_function() {
return ExternalReference(Redirect(FUNCTION_ADDR(std::printf)));
}

View File

@ -175,6 +175,7 @@ class StatsCounter;
V(libc_memcpy_function, "libc_memcpy") \
V(libc_memmove_function, "libc_memmove") \
V(libc_memset_function, "libc_memset") \
V(relaxed_memcpy_function, "relaxed_memcpy") \
V(mod_two_doubles_operation, "mod_two_doubles") \
V(mutable_big_int_absolute_add_and_canonicalize_function, \
"MutableBigInt_AbsoluteAddAndCanonicalize") \