|
32 | 32 | #include "string_bytes.h" |
33 | 33 | #include "string_search.h" |
34 | 34 | #include "util-inl.h" |
| 35 | +#include "v8-fast-api-calls.h" |
35 | 36 | #include "v8.h" |
36 | 37 |
|
37 | 38 | #include <cstring> |
@@ -786,14 +787,29 @@ void StringWrite(const FunctionCallbackInfo<Value>& args) { |
786 | 787 | args.GetReturnValue().Set(written); |
787 | 788 | } |
788 | 789 |
|
789 | | -void ByteLengthUtf8(const FunctionCallbackInfo<Value> &args) { |
| 790 | +void SlowByteLengthUtf8(const FunctionCallbackInfo<Value>& args) { |
790 | 791 | Environment* env = Environment::GetCurrent(args); |
791 | 792 | CHECK(args[0]->IsString()); |
792 | 793 |
|
793 | 794 | // Fast case: avoid StringBytes on UTF8 string. Jump to v8. |
794 | 795 | args.GetReturnValue().Set(args[0].As<String>()->Utf8Length(env->isolate())); |
795 | 796 | } |
796 | 797 |
|
| 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 | + |
797 | 813 | // Normalize val to be an integer in the range of [1, -1] since |
798 | 814 | // implementations of memcmp() can vary by platform. |
799 | 815 | static int normalizeCompareVal(int val, size_t a_length, size_t b_length) { |
@@ -1368,7 +1384,11 @@ void Initialize(Local<Object> target, |
1368 | 1384 | SetMethodNoSideEffect(context, target, "createFromString", CreateFromString); |
1369 | 1385 | SetMethodNoSideEffect(context, target, "decodeUTF8", DecodeUTF8); |
1370 | 1386 |
|
1371 | | - SetMethodNoSideEffect(context, target, "byteLengthUtf8", ByteLengthUtf8); |
| 1387 | + SetFastMethodNoSideEffect(context, |
| 1388 | + target, |
| 1389 | + "byteLengthUtf8", |
| 1390 | + SlowByteLengthUtf8, |
| 1391 | + &fast_byte_length_utf8); |
1372 | 1392 | SetMethod(context, target, "copy", Copy); |
1373 | 1393 | SetMethodNoSideEffect(context, target, "compare", Compare); |
1374 | 1394 | SetMethodNoSideEffect(context, target, "compareOffset", CompareOffset); |
@@ -1429,7 +1449,9 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { |
1429 | 1449 | registry->Register(CreateFromString); |
1430 | 1450 | registry->Register(DecodeUTF8); |
1431 | 1451 |
|
1432 | | - registry->Register(ByteLengthUtf8); |
| 1452 | + registry->Register(SlowByteLengthUtf8); |
| 1453 | + registry->Register(fast_byte_length_utf8.GetTypeInfo()); |
| 1454 | + registry->Register(FastByteLengthUtf8); |
1433 | 1455 | registry->Register(Copy); |
1434 | 1456 | registry->Register(Compare); |
1435 | 1457 | registry->Register(CompareOffset); |
|
0 commit comments