Skip to content

Commit 06f56a5

Browse files
Renegade334richardlau
authored andcommitted
src: use native CopyArrayBufferBytes for webstream buffer copy
Signed-off-by: Renegade334 <[email protected]> PR-URL: #66400 Reviewed-By: Anna Henningsen <[email protected]>
1 parent 82223ab commit 06f56a5

1 file changed

Lines changed: 37 additions & 43 deletions

File tree

‎src/node_buffer.cc‎

Lines changed: 37 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,65 +1775,54 @@ static void SetDetachKey(const FunctionCallbackInfo<Value>& args) {
17751775
ab->SetDetachKey(key);
17761776
}
17771777

1778-
namespace {
1779-
1780-
std::pair<void*, size_t> DecomposeBufferToParts(Local<Value> buffer) {
1781-
void* pointer;
1782-
size_t byte_length;
1783-
if (buffer->IsArrayBuffer()) {
1784-
Local<ArrayBuffer> ab = buffer.As<ArrayBuffer>();
1785-
pointer = ab->Data();
1786-
byte_length = ab->ByteLength();
1787-
} else if (buffer->IsSharedArrayBuffer()) {
1788-
Local<SharedArrayBuffer> ab = buffer.As<SharedArrayBuffer>();
1789-
pointer = ab->Data();
1790-
byte_length = ab->ByteLength();
1791-
} else {
1792-
UNREACHABLE(); // Caller must validate.
1793-
}
1794-
return {pointer, byte_length};
1778+
void CopyArrayBufferImpl(Local<ArrayBuffer> target,
1779+
uint32_t target_start,
1780+
Local<ArrayBuffer> source,
1781+
uint32_t source_start,
1782+
uint32_t bytes_to_copy) {
1783+
uint32_t bytes_copied = source->CopyArrayBufferBytes(
1784+
source_start, bytes_to_copy, target, target_start);
1785+
CHECK_EQ(bytes_copied, bytes_to_copy);
17951786
}
17961787

1797-
} // namespace
1798-
17991788
void CopyArrayBuffer(const FunctionCallbackInfo<Value>& args) {
18001789
// args[0] == Destination ArrayBuffer
18011790
// args[1] == Destination ArrayBuffer Offset
18021791
// args[2] == Source ArrayBuffer
18031792
// args[3] == Source ArrayBuffer Offset
18041793
// args[4] == bytesToCopy
18051794

1806-
CHECK(args[0]->IsArrayBuffer() || args[0]->IsSharedArrayBuffer());
1795+
CHECK(args[0]->IsArrayBuffer());
18071796
CHECK(args[1]->IsUint32());
1808-
CHECK(args[2]->IsArrayBuffer() || args[2]->IsSharedArrayBuffer());
1797+
CHECK(args[2]->IsArrayBuffer());
18091798
CHECK(args[3]->IsUint32());
18101799
CHECK(args[4]->IsUint32());
18111800

1812-
void* destination;
1813-
size_t destination_byte_length;
1814-
std::tie(destination, destination_byte_length) =
1815-
DecomposeBufferToParts(args[0]);
1816-
1817-
void* source;
1818-
size_t source_byte_length;
1819-
std::tie(source, source_byte_length) = DecomposeBufferToParts(args[2]);
1820-
1821-
uint32_t destination_offset = args[1].As<Uint32>()->Value();
1822-
uint32_t source_offset = args[3].As<Uint32>()->Value();
1823-
size_t bytes_to_copy = args[4].As<Uint32>()->Value();
1801+
CopyArrayBufferImpl(args[0].As<ArrayBuffer>(),
1802+
args[1].As<Uint32>()->Value(),
1803+
args[2].As<ArrayBuffer>(),
1804+
args[3].As<Uint32>()->Value(),
1805+
args[4].As<Uint32>()->Value());
1806+
}
18241807

1825-
// Assert the offsets are within bounds before the subtractions below, which
1826-
// would otherwise underflow and defeat the bytes_to_copy bounds checks.
1827-
CHECK_LE(destination_offset, destination_byte_length);
1828-
CHECK_LE(source_offset, source_byte_length);
1829-
CHECK_GE(destination_byte_length - destination_offset, bytes_to_copy);
1830-
CHECK_GE(source_byte_length - source_offset, bytes_to_copy);
1808+
void FastCopyArrayBuffer(Local<Value> receiver,
1809+
Local<Value> target,
1810+
uint32_t target_start,
1811+
Local<Value> source,
1812+
uint32_t source_start,
1813+
uint32_t bytes_to_copy) {
1814+
CHECK(target->IsArrayBuffer());
1815+
CHECK(source->IsArrayBuffer());
18311816

1832-
uint8_t* dest = static_cast<uint8_t*>(destination) + destination_offset;
1833-
uint8_t* src = static_cast<uint8_t*>(source) + source_offset;
1834-
memcpy(dest, src, bytes_to_copy);
1817+
CopyArrayBufferImpl(target.As<ArrayBuffer>(),
1818+
target_start,
1819+
source.As<ArrayBuffer>(),
1820+
source_start,
1821+
bytes_to_copy);
18351822
}
18361823

1824+
static CFunction fast_copy_array_buffer(CFunction::Make(FastCopyArrayBuffer));
1825+
18371826
// Converts a number parameter to size_t suitable for ArrayBuffer sizes
18381827
// Could be larger than uint32_t
18391828
// See v8::internal::TryNumberToSize and v8::internal::NumberToSize
@@ -2057,7 +2046,11 @@ void Initialize(Local<Object> target,
20572046
&fast_index_of_number);
20582047
SetMethodNoSideEffect(context, target, "indexOfString", IndexOfString);
20592048

2060-
SetMethod(context, target, "copyArrayBuffer", CopyArrayBuffer);
2049+
SetFastMethod(context,
2050+
target,
2051+
"copyArrayBuffer",
2052+
CopyArrayBuffer,
2053+
&fast_copy_array_buffer);
20612054
SetMethodNoSideEffect(
20622055
context, target, "createUnsafeArrayBuffer", CreateUnsafeArrayBuffer);
20632056
SetMethodNoSideEffect(
@@ -2183,6 +2176,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
21832176
registry->Register(StringWrite<UTF8>);
21842177

21852178
registry->Register(CopyArrayBuffer);
2179+
registry->Register(fast_copy_array_buffer);
21862180
registry->Register(CreateUnsafeArrayBuffer);
21872181
registry->Register(ArrayBufferAlignedOffset);
21882182

0 commit comments

Comments
 (0)