Skip to content

Commit 68cc51b

Browse files
committed
fixup: fast call
1 parent ce07761 commit 68cc51b

File tree

2 files changed

+43
-13
lines changed

2 files changed

+43
-13
lines changed

lib/buffer.js

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const {
5858
byteLengthUtf8,
5959
compare: _compare,
6060
compareOffset,
61-
copyArrayBuffer,
61+
copy: _copy,
6262
createFromString,
6363
fill: bindingFill,
6464
isAscii: bindingIsAscii,
@@ -204,7 +204,7 @@ function toInteger(n, defaultVal) {
204204
return defaultVal;
205205
}
206206

207-
function _copy(source, target, targetStart, sourceStart, sourceEnd) {
207+
function copyImpl(source, target, targetStart, sourceStart, sourceEnd) {
208208
if (!isUint8Array(source))
209209
throw new ERR_INVALID_ARG_TYPE('source', ['Buffer', 'Uint8Array'], source);
210210
if (!isUint8Array(target))
@@ -253,13 +253,7 @@ function _copyActual(source, target, targetStart, sourceStart, sourceEnd) {
253253
return 0;
254254

255255
if (sourceStart !== 0 || sourceEnd < source.length) {
256-
copyArrayBuffer(
257-
target.buffer,
258-
target.byteOffset + targetStart,
259-
source.buffer,
260-
source.byteOffset + sourceStart,
261-
nb,
262-
);
256+
_copy(source, target, targetStart, sourceStart, sourceEnd);
263257
} else {
264258
TypedArrayPrototypeSet(target, source, targetStart);
265259
}
@@ -816,7 +810,7 @@ ObjectDefineProperty(Buffer.prototype, 'offset', {
816810

817811
Buffer.prototype.copy =
818812
function copy(target, targetStart, sourceStart, sourceEnd) {
819-
return _copy(this, target, targetStart, sourceStart, sourceEnd);
813+
return copyImpl(this, target, targetStart, sourceStart, sourceEnd);
820814
};
821815

822816
// No need to verify that "buf.length <= MAX_UINT32" since it's a read-only

src/node_buffer.cc

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ void StringSlice(const FunctionCallbackInfo<Value>& args) {
569569
}
570570

571571
// bytesCopied = copy(buffer, target[, targetStart][, sourceStart][, sourceEnd])
572-
void Copy(const FunctionCallbackInfo<Value> &args) {
572+
void SlowCopy(const FunctionCallbackInfo<Value> &args) {
573573
Environment* env = Environment::GetCurrent(args);
574574

575575
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
@@ -606,6 +606,40 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
606606
args.GetReturnValue().Set(to_copy);
607607
}
608608

609+
uint32_t FastCopy(Local<Value> receiver,
610+
Local<Value> source_obj,
611+
Local<Value> target_obj,
612+
uint32_t target_start,
613+
uint32_t source_start,
614+
uint32_t source_end) {
615+
ArrayBufferViewContents<char> source(source_obj);
616+
617+
SPREAD_BUFFER_ARG(target_obj, target);
618+
619+
// Copy 0 bytes; we're done
620+
if (target_start >= target_length || source_start >= source_end)
621+
return 0;
622+
623+
if (source_start > source.length()) {
624+
// TODO (fix): V8 12.8 allows throwing in fast call.
625+
assert(false);
626+
return 0;
627+
}
628+
629+
if (source_end - source_start > target_length - target_start)
630+
source_end = source_start + target_length - target_start;
631+
632+
uint32_t to_copy = std::min<size_t>(
633+
std::min<size_t>(source_end - source_start, target_length - target_start),
634+
source.length() - source_start);
635+
636+
memmove(target_data + target_start, source.data() + source_start, to_copy);
637+
638+
return to_copy;
639+
}
640+
641+
static v8::CFunction fast_copy(
642+
v8::CFunction::Make(FastCopy));
609643

610644
void Fill(const FunctionCallbackInfo<Value>& args) {
611645
Environment* env = Environment::GetCurrent(args);
@@ -1275,7 +1309,7 @@ void Initialize(Local<Object> target,
12751309
"byteLengthUtf8",
12761310
SlowByteLengthUtf8,
12771311
&fast_byte_length_utf8);
1278-
SetMethod(context, target, "copy", Copy);
1312+
SetFastMethod(context, target, "copy", SlowCopy, &fast_copy);
12791313
SetMethodNoSideEffect(context, target, "compare", Compare);
12801314
SetMethodNoSideEffect(context, target, "compareOffset", CompareOffset);
12811315
SetMethod(context, target, "fill", Fill);
@@ -1334,7 +1368,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
13341368
registry->Register(SlowByteLengthUtf8);
13351369
registry->Register(fast_byte_length_utf8.GetTypeInfo());
13361370
registry->Register(FastByteLengthUtf8);
1337-
registry->Register(Copy);
1371+
registry->Register(SlowCopy);
1372+
registry->Register(fast_copy.GetTypeInfo());
1373+
registry->Register(FastCopy);
13381374
registry->Register(Compare);
13391375
registry->Register(CompareOffset);
13401376
registry->Register(Fill);

0 commit comments

Comments
 (0)