Skip to content

Commit b3e1034

Browse files
joyeecheungtargos
authored andcommitted
buffer: use v8 fast API calls for Buffer.byteLength implementation
Use v8 fast API calls for Buffer.byteLength with sequential one-byte strings. PR-URL: #46616 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 04166fe commit b3e1034

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

src/node_buffer.cc

+25-3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "string_bytes.h"
3333
#include "string_search.h"
3434
#include "util-inl.h"
35+
#include "v8-fast-api-calls.h"
3536
#include "v8.h"
3637

3738
#include <cstring>
@@ -786,14 +787,29 @@ void StringWrite(const FunctionCallbackInfo<Value>& args) {
786787
args.GetReturnValue().Set(written);
787788
}
788789

789-
void ByteLengthUtf8(const FunctionCallbackInfo<Value> &args) {
790+
void SlowByteLengthUtf8(const FunctionCallbackInfo<Value>& args) {
790791
Environment* env = Environment::GetCurrent(args);
791792
CHECK(args[0]->IsString());
792793

793794
// Fast case: avoid StringBytes on UTF8 string. Jump to v8.
794795
args.GetReturnValue().Set(args[0].As<String>()->Utf8Length(env->isolate()));
795796
}
796797

798+
uint32_t FastByteLengthUtf8(Local<Value> receiver,
799+
const v8::FastOneByteString& source) {
800+
uint32_t result = 0;
801+
uint32_t length = source.length;
802+
const uint8_t* data = reinterpret_cast<const uint8_t*>(source.data);
803+
for (uint32_t i = 0; i < length; ++i) {
804+
result += (data[i] >> 7);
805+
}
806+
result += length;
807+
return result;
808+
}
809+
810+
static v8::CFunction fast_byte_length_utf8(
811+
v8::CFunction::Make(FastByteLengthUtf8));
812+
797813
// Normalize val to be an integer in the range of [1, -1] since
798814
// implementations of memcmp() can vary by platform.
799815
static int normalizeCompareVal(int val, size_t a_length, size_t b_length) {
@@ -1368,7 +1384,11 @@ void Initialize(Local<Object> target,
13681384
SetMethodNoSideEffect(context, target, "createFromString", CreateFromString);
13691385
SetMethodNoSideEffect(context, target, "decodeUTF8", DecodeUTF8);
13701386

1371-
SetMethodNoSideEffect(context, target, "byteLengthUtf8", ByteLengthUtf8);
1387+
SetFastMethodNoSideEffect(context,
1388+
target,
1389+
"byteLengthUtf8",
1390+
SlowByteLengthUtf8,
1391+
&fast_byte_length_utf8);
13721392
SetMethod(context, target, "copy", Copy);
13731393
SetMethodNoSideEffect(context, target, "compare", Compare);
13741394
SetMethodNoSideEffect(context, target, "compareOffset", CompareOffset);
@@ -1429,7 +1449,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
14291449
registry->Register(CreateFromString);
14301450
registry->Register(DecodeUTF8);
14311451

1432-
registry->Register(ByteLengthUtf8);
1452+
registry->Register(SlowByteLengthUtf8);
1453+
registry->Register(fast_byte_length_utf8.GetTypeInfo());
1454+
registry->Register(FastByteLengthUtf8);
14331455
registry->Register(Copy);
14341456
registry->Register(Compare);
14351457
registry->Register(CompareOffset);

src/node_external_reference.h

+3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
namespace node {
1212

13+
using CFunctionCallbackWithOneByteString =
14+
uint32_t (*)(v8::Local<v8::Value>, const v8::FastOneByteString&);
1315
using CFunctionCallback = void (*)(v8::Local<v8::Value> receiver);
1416

1517
// This class manages the external references from the V8 heap
@@ -20,6 +22,7 @@ class ExternalReferenceRegistry {
2022

2123
#define ALLOWED_EXTERNAL_REFERENCE_TYPES(V) \
2224
V(CFunctionCallback) \
25+
V(CFunctionCallbackWithOneByteString) \
2326
V(const v8::CFunctionInfo*) \
2427
V(v8::FunctionCallback) \
2528
V(v8::AccessorGetterCallback) \

0 commit comments

Comments
 (0)