Skip to content

Commit e3cddbe

Browse files
rmahdavV8 LUCI CQ
authored andcommitted
[base64] Add toBase64 path for SharedArrayBuffers
This CL, adds a path to make sure we have an atomic read when the TypedArray is backed with a SharedArrayBuffer. Bug: 42204568 Change-Id: Ic5d5e3fb4000a037611e4ccaaa6400c370956f17 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6449193 Commit-Queue: Rezvan Mahdavi Hezaveh <[email protected]> Reviewed-by: Shu-yu Guo <[email protected]> Cr-Commit-Position: refs/heads/main@{#99877}
1 parent 55c9364 commit e3cddbe

3 files changed

Lines changed: 72 additions & 5 deletions

File tree

BUILD.bazel

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4360,6 +4360,12 @@ cc_library(
43604360
name = "simdutf",
43614361
srcs = ["third_party/simdutf/simdutf.cpp"],
43624362
hdrs = ["third_party/simdutf/simdutf.h"],
4363+
copts = select({
4364+
"@v8//bazel/config:is_clang": ["-std=c++20"],
4365+
"@v8//bazel/config:is_gcc": ["-std=gnu++2a"],
4366+
"@v8//bazel/config:is_windows": ["/std:c++20"],
4367+
"//conditions:default": [],
4368+
}),
43634369
)
43644370

43654371
v8_library(

src/builtins/builtins-typed-array.cc

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -818,11 +818,16 @@ BUILTIN(Uint8ArrayPrototypeToBase64) {
818818
// is false.
819819
// 11. Return CodePointsToString(outAscii).
820820

821-
// TODO(rezvan): Make sure to add a path for SharedArrayBuffers when
822-
// simdutf library got updated. Also, add a test for it.
823-
size_t simd_result_size = simdutf::binary_to_base64(
824-
std::bit_cast<const char*>(uint8array->GetBuffer()->backing_store()),
825-
length, reinterpret_cast<char*>(output->GetChars(no_gc)), alphabet);
821+
size_t simd_result_size;
822+
if (uint8array->buffer()->is_shared()) {
823+
simd_result_size = simdutf::atomic_binary_to_base64(
824+
std::bit_cast<const char*>(uint8array->GetBuffer()->backing_store()),
825+
length, reinterpret_cast<char*>(output->GetChars(no_gc)), alphabet);
826+
} else {
827+
simd_result_size = simdutf::binary_to_base64(
828+
std::bit_cast<const char*>(uint8array->GetBuffer()->backing_store()),
829+
length, reinterpret_cast<char*>(output->GetChars(no_gc)), alphabet);
830+
}
826831
DCHECK_EQ(simd_result_size, output_length);
827832
USE(simd_result_size);
828833
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright 2025 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+
// Flags: --js-base-64 --allow-natives-syntax
6+
7+
const workerScript = `
8+
onmessage = function(event) {
9+
const sab = event.data.buffer;
10+
const uint8Array = new Uint8Array(sab);
11+
12+
const dataToWrite = [102, 111, 111, 98, 97, 114];
13+
14+
for (let i = 0; i < dataToWrite.length; ++i) {
15+
uint8Array[i] = dataToWrite[i];
16+
}
17+
18+
postMessage("started");
19+
20+
while (true) {
21+
for (let i = 0; i < dataToWrite.length; ++i) {
22+
uint8Array[i] = dataToWrite[i];
23+
}
24+
}
25+
};
26+
`;
27+
28+
function testConcurrentSharedArrayBufferUint8ArrayToBase64() {
29+
const sab = new SharedArrayBuffer(6);
30+
const uint8ArrayMain = new Uint8Array(sab);
31+
32+
// Create a worker
33+
const worker = new Worker(workerScript, {type: 'string'});
34+
35+
// Send the SharedArrayBuffer
36+
worker.postMessage({buffer: sab});
37+
assertEquals('started', worker.getMessage());
38+
39+
// Give the worker a little time to write
40+
for (let i = 0; i < 10000; ++i) {
41+
}
42+
43+
// Call toBase64 on the main thread's view of the SAB
44+
for (let i=0; i < 100; i++) {
45+
const base64String = uint8ArrayMain.toBase64();
46+
assertEquals(
47+
'Zm9vYmFy', base64String,
48+
'toBase64 result mismatch with concurrent writes');
49+
}
50+
51+
// Terminate the worker (now it should exit its loop)
52+
worker.terminate();
53+
}
54+
55+
// Run the test function
56+
testConcurrentSharedArrayBufferUint8ArrayToBase64();

0 commit comments

Comments
 (0)