deps: V8: revert 6d6c1e680c7b

It depends on `std::atomic_ref`, which is not available in Xcode 16.1.

Refs: 6d6c1e680c
PR-URL: https://github.com/nodejs/node/pull/58064
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
This commit is contained in:
Michaël Zasso 2025-04-29 07:58:11 +02:00 committed by Node.js GitHub Bot
parent 8c508b9399
commit 754d28e34f
6 changed files with 39 additions and 187 deletions

View File

@ -38,7 +38,7 @@
# Reset this number to 0 on major V8 upgrades.
# Increment by one for each non-official patch applied to deps/v8.
'v8_embedder_string': '-node.7',
'v8_embedder_string': '-node.8',
##### V8 defaults for Node.js #####

View File

@ -883,14 +883,14 @@ BUILTIN(Uint8ArrayFromHex) {
base::Vector<const uint8_t> input_vector =
input_content.ToOneByteVector();
result = ArrayBufferFromHex(
input_vector, /*is_shared*/ false,
static_cast<uint8_t*>(buffer->backing_store()), output_length);
input_vector, static_cast<uint8_t*>(buffer->backing_store()),
output_length);
} else {
base::Vector<const base::uc16> input_vector =
input_content.ToUC16Vector();
result = ArrayBufferFromHex(
input_vector, /*is_shared*/ false,
static_cast<uint8_t*>(buffer->backing_store()), output_length);
input_vector, static_cast<uint8_t*>(buffer->backing_store()),
output_length);
}
}
@ -959,6 +959,11 @@ BUILTIN(Uint8ArrayPrototypeSetFromHex) {
size_t output_length = (input_length / 2);
output_length = std::min(output_length, array_length);
// TODO(rezvan): Add path for typed arrays backed by SharedArrayBuffer
if (uint8array->buffer()->is_shared()) {
UNIMPLEMENTED();
}
// 7. Let result be FromHex(string, byteLength).
// 8. Let bytes be result.[[Bytes]].
// 9. Let written be the length of bytes.
@ -974,15 +979,15 @@ BUILTIN(Uint8ArrayPrototypeSetFromHex) {
if (input_content.IsOneByte()) {
base::Vector<const uint8_t> input_vector =
input_content.ToOneByteVector();
result = ArrayBufferFromHex(
input_vector, uint8array->buffer()->is_shared(),
static_cast<uint8_t*>(uint8array->DataPtr()), output_length);
result = ArrayBufferFromHex(input_vector,
static_cast<uint8_t*>(uint8array->DataPtr()),
output_length);
} else {
base::Vector<const base::uc16> input_vector =
input_content.ToUC16Vector();
result = ArrayBufferFromHex(
input_vector, uint8array->buffer()->is_shared(),
static_cast<uint8_t*>(uint8array->DataPtr()), output_length);
result = ArrayBufferFromHex(input_vector,
static_cast<uint8_t*>(uint8array->DataPtr()),
output_length);
}
}
@ -1052,8 +1057,7 @@ BUILTIN(Uint8ArrayPrototypeToHex) {
// b. Set hex to StringPad(hex, 2, "0", start).
// c. Set out to the string-concatenation of out and hex.
// 6. Return out.
return Uint8ArrayToHex(bytes, length, uint8array->buffer()->is_shared(),
output);
return Uint8ArrayToHex(bytes, length, output);
}
} // namespace internal

View File

@ -458,38 +458,16 @@ char NibbleToHex(uint8_t nibble) {
return c + (mask & correction);
}
void PerformNibbleToHexAndWriteIntoStringOutPut(
uint8_t byte, int index, DirectHandle<SeqOneByteString> string_output) {
uint8_t high = byte >> 4;
uint8_t low = byte & 0x0F;
string_output->SeqOneByteStringSet(index++, NibbleToHex(high));
string_output->SeqOneByteStringSet(index, NibbleToHex(low));
}
void Uint8ArrayToHexSlow(const char* bytes, size_t length,
DirectHandle<SeqOneByteString> string_output) {
int index = 0;
for (size_t i = 0; i < length; i++) {
uint8_t byte = bytes[i];
PerformNibbleToHexAndWriteIntoStringOutPut(byte, index, string_output);
index += 2;
}
}
uint8_t high = byte >> 4;
uint8_t low = byte & 0x0F;
void AtomicUint8ArrayToHexSlow(const char* bytes, size_t length,
DirectHandle<SeqOneByteString> string_output) {
int index = 0;
// std::atomic_ref<T> must not have a const T, see
// https://cplusplus.github.io/LWG/issue3508
// we instead provide a mutable input, which is ok since we are only reading
// from it.
char* mutable_bytes = const_cast<char*>(bytes);
for (size_t i = 0; i < length; i++) {
uint8_t byte =
std::atomic_ref<char>(mutable_bytes[i]).load(std::memory_order_relaxed);
PerformNibbleToHexAndWriteIntoStringOutPut(byte, index, string_output);
index += 2;
string_output->SeqOneByteStringSet(index++, NibbleToHex(high));
string_output->SeqOneByteStringSet(index++, NibbleToHex(low));
}
}
@ -618,14 +596,11 @@ void Uint8ArrayToHexFastWithNeon(const char* bytes, uint8_t* output,
#endif
} // namespace
Tagged<Object> Uint8ArrayToHex(const char* bytes, size_t length, bool is_shared,
Tagged<Object> Uint8ArrayToHex(const char* bytes, size_t length,
DirectHandle<SeqOneByteString> string_output) {
// TODO(rezvan): Add relaxed version for simd methods to handle shared array
// buffers.
#ifdef __SSE3__
if (!is_shared && (get_vectorization_kind() == SimdKinds::kAVX2 ||
get_vectorization_kind() == SimdKinds::kSSE)) {
if (get_vectorization_kind() == SimdKinds::kAVX2 ||
get_vectorization_kind() == SimdKinds::kSSE) {
{
DisallowGarbageCollection no_gc;
Uint8ArrayToHexFastWithSSE(bytes, string_output->GetChars(no_gc), length);
@ -635,7 +610,7 @@ Tagged<Object> Uint8ArrayToHex(const char* bytes, size_t length, bool is_shared,
#endif
#ifdef NEON64
if (!is_shared && get_vectorization_kind() == SimdKinds::kNeon) {
if (get_vectorization_kind() == SimdKinds::kNeon) {
{
DisallowGarbageCollection no_gc;
Uint8ArrayToHexFastWithNeon(bytes, string_output->GetChars(no_gc),
@ -645,11 +620,7 @@ Tagged<Object> Uint8ArrayToHex(const char* bytes, size_t length, bool is_shared,
}
#endif
if (is_shared) {
AtomicUint8ArrayToHexSlow(bytes, length, string_output);
} else {
Uint8ArrayToHexSlow(bytes, length, string_output);
}
return *string_output;
}
@ -1055,23 +1026,20 @@ bool Uint8ArrayFromHexWithNeon(const base::Vector<T>& input_vector,
} // namespace
template <typename T>
bool ArrayBufferFromHex(const base::Vector<T>& input_vector, bool is_shared,
uint8_t* buffer, size_t output_length) {
bool ArrayBufferFromHex(const base::Vector<T>& input_vector, uint8_t* buffer,
size_t output_length) {
size_t input_length = input_vector.size();
DCHECK_LE(output_length, input_length / 2);
// TODO(rezvan): Add relaxed version for simd methods to handle shared array
// buffers.
#ifdef __SSE3__
if (!is_shared && (get_vectorization_kind() == SimdKinds::kAVX2 ||
get_vectorization_kind() == SimdKinds::kSSE)) {
if (get_vectorization_kind() == SimdKinds::kAVX2 ||
get_vectorization_kind() == SimdKinds::kSSE) {
return Uint8ArrayFromHexWithSSE(input_vector, buffer, output_length);
}
#endif
#ifdef NEON64
if (!is_shared && get_vectorization_kind() == SimdKinds::kNeon) {
if (get_vectorization_kind() == SimdKinds::kNeon) {
return Uint8ArrayFromHexWithNeon(input_vector, buffer, output_length);
}
#endif
@ -1081,12 +1049,7 @@ bool ArrayBufferFromHex(const base::Vector<T>& input_vector, bool is_shared,
for (uint32_t i = 0; i < input_length; i += 2) {
result = HandleRemainingHexValues(input_vector, i);
if (result.has_value()) {
if (is_shared) {
std::atomic_ref<uint8_t>(buffer[index++])
.store(result.value(), std::memory_order_relaxed);
} else {
buffer[index++] = result.value();
}
} else {
return false;
}
@ -1095,11 +1058,11 @@ bool ArrayBufferFromHex(const base::Vector<T>& input_vector, bool is_shared,
}
template bool ArrayBufferFromHex(
const base::Vector<const uint8_t>& input_vector, bool is_shared,
uint8_t* buffer, size_t output_length);
const base::Vector<const uint8_t>& input_vector, uint8_t* buffer,
size_t output_length);
template bool ArrayBufferFromHex(
const base::Vector<const base::uc16>& input_vector, bool is_shared,
uint8_t* buffer, size_t output_length);
const base::Vector<const base::uc16>& input_vector, uint8_t* buffer,
size_t output_length);
#ifdef NEON64
#undef NEON64

View File

@ -20,11 +20,11 @@ uintptr_t ArrayIndexOfIncludesSmiOrObject(Address array_start,
uintptr_t ArrayIndexOfIncludesDouble(Address array_start, uintptr_t array_len,
uintptr_t from_index,
Address search_element);
Tagged<Object> Uint8ArrayToHex(const char* bytes, size_t length, bool is_shared,
Tagged<Object> Uint8ArrayToHex(const char* bytes, size_t length,
DirectHandle<SeqOneByteString> string_output);
template <typename T>
bool ArrayBufferFromHex(const base::Vector<T>& input_vector, bool is_shared,
uint8_t* buffer, size_t output_length);
bool ArrayBufferFromHex(const base::Vector<T>& input_vector, uint8_t* buffer,
size_t output_length);
} // namespace internal
} // namespace v8

View File

@ -1,59 +0,0 @@
// Copyright 2025 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.
// Flags: --js-base-64 --allow-natives-syntax
const workerScript = `
onmessage = function(event) {
const sab = event.data.buffer;
const uint8Array = new Uint8Array(sab);
const dataToWrite = [102, 111, 111, 98, 97, 114, 255, 255];
for (let i = 0; i < dataToWrite.length; ++i) {
uint8Array[i] = dataToWrite[i];
}
postMessage("started");
while (true) {
for (let i = 0; i < dataToWrite.length; ++i) {
uint8Array[i] = dataToWrite[i];
}
}
};
`;
function testConcurrentSharedArrayBufferUint8ArraySetFromHex() {
const sab = new SharedArrayBuffer(8);
const uint8ArrayMain = new Uint8Array(sab);
// Create a worker
const worker = new Worker(workerScript, {type: 'string'});
// Send the SharedArrayBuffer
worker.postMessage({buffer: sab});
assertEquals('started', worker.getMessage());
// Give the worker a little time to write
for (let i = 0; i < 10000; ++i) {
}
// Call setFromHex on the main thread's view of the SAB
for (let i = 0; i < 100; i++) {
const result = uint8ArrayMain.setFromHex('666f6f626172');
const actual = Array.from(uint8ArrayMain);
assertEquals(
actual, [102, 111, 111, 98, 97, 114, 255, 255],
'setFromHex result mismatch with concurrent writes');
}
// Terminate the worker (now it should exit its loop)
worker.terminate();
}
// Run the test function
testConcurrentSharedArrayBufferUint8ArraySetFromHex();

View File

@ -1,56 +0,0 @@
// Copyright 2025 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.
// Flags: --js-base-64 --allow-natives-syntax
const workerScript = `
onmessage = function(event) {
const sab = event.data.buffer;
const uint8Array = new Uint8Array(sab);
const dataToWrite = [102, 111, 111, 98, 97, 114];
for (let i = 0; i < dataToWrite.length; ++i) {
uint8Array[i] = dataToWrite[i];
}
postMessage("started");
while (true) {
for (let i = 0; i < dataToWrite.length; ++i) {
uint8Array[i] = dataToWrite[i];
}
}
};
`;
function testConcurrentSharedArrayBufferUint8ArrayToHex() {
const sab = new SharedArrayBuffer(6);
const uint8ArrayMain = new Uint8Array(sab);
// Create a worker
const worker = new Worker(workerScript, {type: 'string'});
// Send the SharedArrayBuffer
worker.postMessage({buffer: sab});
assertEquals('started', worker.getMessage());
// Give the worker a little time to write
for (let i = 0; i < 10000; ++i) {
}
// Call toHex on the main thread's view of the SAB
for (let i = 0; i < 100; i++) {
const hexString = uint8ArrayMain.toHex();
assertEquals(
'666f6f626172', hexString,
'toHex result mismatch with concurrent writes');
}
// Terminate the worker (now it should exit its loop)
worker.terminate();
}
// Run the test function
testConcurrentSharedArrayBufferUint8ArrayToHex();