| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 7b641bc commit a5a60e6
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,20 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const common = require('../common.js'); | ||
| 4 | + const bench = common.createBenchmark(main, { | ||
| 5 | + encoding: [ | ||
| 6 | + 'utf8', 'ascii', 'latin1', | ||
| 7 | + ], | ||
| 8 | + len: [1, 8, 16, 32], | ||
| 9 | + n: [1e6], | ||
| 10 | + }); | ||
| 11 | + | ||
| 12 | + function main({ len, n, encoding }) { | ||
| 13 | + const buf = Buffer.allocUnsafe(len); | ||
| 14 | + const string = Buffer.from('a'.repeat(len)).toString(); | ||
| 15 | + bench.start(); | ||
| 16 | + for (let i = 0; i < n; ++i) { | ||
| 17 | + buf.write(string, 0, encoding); | ||
| 18 | + } | ||
| 19 | + bench.end(n); | ||
| 20 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,13 +23,13 @@ const { | |||
| 23 | 23 | hexSlice, | |
| 24 | 24 | ucs2Slice, | |
| 25 | 25 | utf8Slice, | |
| 26 | - asciiWrite, | ||
| 26 | + asciiWriteStatic, | ||
| 27 | 27 | base64Write, | |
| 28 | 28 | base64urlWrite, | |
| 29 | - latin1Write, | ||
| 29 | + latin1WriteStatic, | ||
| 30 | 30 | hexWrite, | |
| 31 | 31 | ucs2Write, | |
| 32 | - utf8Write, | ||
| 32 | + utf8WriteStatic, | ||
| 33 | 33 | getZeroFillToggle, | |
| 34 | 34 | } = internalBinding('buffer'); | |
| 35 | 35 | ||
@@ -1036,13 +1036,37 @@ function addBufferPrototypeMethods(proto) { | |||
| 1036 | 1036 | proto.hexSlice = hexSlice; | |
| 1037 | 1037 | proto.ucs2Slice = ucs2Slice; | |
| 1038 | 1038 | proto.utf8Slice = utf8Slice; | |
| 1039 | - proto.asciiWrite = asciiWrite; | ||
| 1039 | + proto.asciiWrite = function(string, offset = 0, length = this.byteLength) { | ||
| 1040 | + if (offset < 0 || offset > this.byteLength) { | ||
| 1041 | + throw new ERR_BUFFER_OUT_OF_BOUNDS('offset'); | ||
| 1042 | + } | ||
| 1043 | + if (length < 0 || length > this.byteLength - offset) { | ||
| 1044 | + throw new ERR_BUFFER_OUT_OF_BOUNDS('length'); | ||
| 1045 | + } | ||
| 1046 | + return asciiWriteStatic(this, string, offset, length); | ||
| 1047 | + }; | ||
| 1040 | 1048 | proto.base64Write = base64Write; | |
| 1041 | 1049 | proto.base64urlWrite = base64urlWrite; | |
| 1042 | - proto.latin1Write = latin1Write; | ||
| 1050 | + proto.latin1Write = function(string, offset = 0, length = this.byteLength) { | ||
| 1051 | + if (offset < 0 || offset > this.byteLength) { | ||
| 1052 | + throw new ERR_BUFFER_OUT_OF_BOUNDS('offset'); | ||
| 1053 | + } | ||
| 1054 | + if (length < 0 || length > this.byteLength - offset) { | ||
| 1055 | + throw new ERR_BUFFER_OUT_OF_BOUNDS('length'); | ||
| 1056 | + } | ||
| 1057 | + return latin1WriteStatic(this, string, offset, length); | ||
| 1058 | + }; | ||
| 1043 | 1059 | proto.hexWrite = hexWrite; | |
| 1044 | 1060 | proto.ucs2Write = ucs2Write; | |
| 1045 | - proto.utf8Write = utf8Write; | ||
| 1061 | + proto.utf8Write = function(string, offset = 0, length = this.byteLength) { | ||
| 1062 | + if (offset < 0 || offset > this.byteLength) { | ||
| 1063 | + throw new ERR_BUFFER_OUT_OF_BOUNDS('offset'); | ||
| 1064 | + } | ||
| 1065 | + if (length < 0 || length > this.byteLength - offset) { | ||
| 1066 | + throw new ERR_BUFFER_OUT_OF_BOUNDS('length'); | ||
| 1067 | + } | ||
| 1068 | + return utf8WriteStatic(this, string, offset, length); | ||
| 1069 | + }; | ||
| 1046 | 1070 | } | |
| 1047 | 1071 | ||
| 1048 | 1072 | // This would better be placed in internal/worker/io.js, but that doesn't work | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1442,6 +1442,52 @@ void CopyArrayBuffer(const FunctionCallbackInfo<Value>& args) { | |||
| 1442 | 1442 | memcpy(dest, src, bytes_to_copy); | |
| 1443 | 1443 | } | |
| 1444 | 1444 | ||
| 1445 | + template <encoding encoding> | ||
| 1446 | + void SlowWriteString(const FunctionCallbackInfo<Value>& args) { | ||
| 1447 | + Environment* env = Environment::GetCurrent(args); | ||
| 1448 | + | ||
| 1449 | + THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]); | ||
| 1450 | + SPREAD_BUFFER_ARG(args[0], ts_obj); | ||
| 1451 | + | ||
| 1452 | + THROW_AND_RETURN_IF_NOT_STRING(env, args[1], "argument"); | ||
| 1453 | + | ||
| 1454 | + Local<String> str = args[1]->ToString(env->context()).ToLocalChecked(); | ||
| 1455 | + | ||
| 1456 | + size_t offset = 0; | ||
| 1457 | + size_t max_length = 0; | ||
| 1458 | + | ||
| 1459 | + THROW_AND_RETURN_IF_OOB(ParseArrayIndex(env, args[2], 0, &offset)); | ||
| 1460 | + THROW_AND_RETURN_IF_OOB( | ||
| 1461 | + ParseArrayIndex(env, args[3], ts_obj_length - offset, &max_length)); | ||
| 1462 | + | ||
| 1463 | + max_length = std::min(ts_obj_length - offset, max_length); | ||
| 1464 | + | ||
| 1465 | + if (max_length == 0) return args.GetReturnValue().Set(0); | ||
| 1466 | + | ||
| 1467 | + uint32_t written = StringBytes::Write( | ||
| 1468 | + env->isolate(), ts_obj_data + offset, max_length, str, encoding); | ||
| 1469 | + args.GetReturnValue().Set(written); | ||
| 1470 | + } | ||
| 1471 | + | ||
| 1472 | + uint32_t FastWriteString(Local<Value> receiver, | ||
| 1473 | + const v8::FastApiTypedArray<uint8_t>& dst, | ||
| 1474 | + const v8::FastOneByteString& src, | ||
| 1475 | + uint32_t offset, | ||
| 1476 | + uint32_t max_length) { | ||
| 1477 | + uint8_t* dst_data; | ||
| 1478 | + CHECK(dst.getStorageIfAligned(&dst_data)); | ||
| 1479 | + CHECK(offset <= dst.length()); | ||
| 1480 | + CHECK(dst.length() - offset <= std::numeric_limits<uint32_t>::max()); | ||
| 1481 | + | ||
| 1482 | + max_length = std::min<uint32_t>(dst.length() - offset, max_length); | ||
| 1483 | + | ||
| 1484 | + memcpy(dst_data, src.data, max_length); | ||
| 1485 | + | ||
| 1486 | + return max_length; | ||
| 1487 | + } | ||
| 1488 | + | ||
| 1489 | + static v8::CFunction fast_write_string(v8::CFunction::Make(FastWriteString)); | ||
| 1490 | + | ||
| 1445 | 1491 | void Initialize(Local<Object> target, | |
| 1446 | 1492 | Local<Value> unused, | |
| 1447 | 1493 | Local<Context> context, | |
@@ -1502,13 +1548,26 @@ void Initialize(Local<Object> target, | |||
| 1502 | 1548 | SetMethodNoSideEffect(context, target, "ucs2Slice", StringSlice<UCS2>); | |
| 1503 | 1549 | SetMethodNoSideEffect(context, target, "utf8Slice", StringSlice<UTF8>); | |
| 1504 | 1550 | ||
| 1505 | - SetMethod(context, target, "asciiWrite", StringWrite<ASCII>); | ||
| 1506 | 1551 | SetMethod(context, target, "base64Write", StringWrite<BASE64>); | |
| 1507 | 1552 | SetMethod(context, target, "base64urlWrite", StringWrite<BASE64URL>); | |
| 1508 | - SetMethod(context, target, "latin1Write", StringWrite<LATIN1>); | ||
| 1509 | 1553 | SetMethod(context, target, "hexWrite", StringWrite<HEX>); | |
| 1510 | 1554 | SetMethod(context, target, "ucs2Write", StringWrite<UCS2>); | |
| 1511 | - SetMethod(context, target, "utf8Write", StringWrite<UTF8>); | ||
| 1555 | + | ||
| 1556 | + SetFastMethod(context, | ||
| 1557 | + target, | ||
| 1558 | + "asciiWriteStatic", | ||
| 1559 | + SlowWriteString<ASCII>, | ||
| 1560 | + &fast_write_string); | ||
| 1561 | + SetFastMethod(context, | ||
| 1562 | + target, | ||
| 1563 | + "latin1WriteStatic", | ||
| 1564 | + SlowWriteString<LATIN1>, | ||
| 1565 | + &fast_write_string); | ||
| 1566 | + SetFastMethod(context, | ||
| 1567 | + target, | ||
| 1568 | + "utf8WriteStatic", | ||
| 1569 | + SlowWriteString<UTF8>, | ||
| 1570 | + &fast_write_string); | ||
| 1512 | 1571 | ||
| 1513 | 1572 | SetMethod(context, target, "getZeroFillToggle", GetZeroFillToggle); | |
| 1514 | 1573 | } | |
@@ -1550,6 +1609,11 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { | |||
| 1550 | 1609 | registry->Register(StringSlice<UCS2>); | |
| 1551 | 1610 | registry->Register(StringSlice<UTF8>); | |
| 1552 | 1611 | ||
| 1612 | + registry->Register(SlowWriteString<ASCII>); | ||
| 1613 | + registry->Register(SlowWriteString<LATIN1>); | ||
| 1614 | + registry->Register(SlowWriteString<UTF8>); | ||
| 1615 | + registry->Register(fast_write_string.GetTypeInfo()); | ||
| 1616 | + registry->Register(FastWriteString); | ||
| 1553 | 1617 | registry->Register(StringWrite<ASCII>); | |
| 1554 | 1618 | registry->Register(StringWrite<BASE64>); | |
| 1555 | 1619 | registry->Register(StringWrite<BASE64URL>); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -56,6 +56,13 @@ using CFunctionWithInt64Fallback = void (*)(v8::Local<v8::Value>, | |||
| 56 | 56 | v8::FastApiCallbackOptions&); | |
| 57 | 57 | using CFunctionWithBool = void (*)(v8::Local<v8::Value>, bool); | |
| 58 | 58 | ||
| 59 | + using CFunctionWriteString = | ||
| 60 | + uint32_t (*)(v8::Local<v8::Value> receiver, | ||
| 61 | + const v8::FastApiTypedArray<uint8_t>& dst, | ||
| 62 | + const v8::FastOneByteString& src, | ||
| 63 | + uint32_t offset, | ||
| 64 | + uint32_t max_length); | ||
| 65 | + | ||
| 59 | 66 | using CFunctionBufferCopy = | |
| 60 | 67 | uint32_t (*)(v8::Local<v8::Value> receiver, | |
| 61 | 68 | const v8::FastApiTypedArray<uint8_t>& source, | |
@@ -88,6 +95,7 @@ class ExternalReferenceRegistry { | |||
| 88 | 95 | V(CFunctionWithInt64Fallback) \ | |
| 89 | 96 | V(CFunctionWithBool) \ | |
| 90 | 97 | V(CFunctionBufferCopy) \ | |
| 98 | + V(CFunctionWriteString) \ | ||
| 91 | 99 | V(const v8::CFunctionInfo*) \ | |
| 92 | 100 | V(v8::FunctionCallback) \ | |
| 93 | 101 | V(v8::AccessorNameGetterCallback) \ | |
| Back | FazBrowse Home | New Git URL |
0 commit comments