Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
83b5efe
doc: reserve ABI 130 for Electron 33
clavin Aug 19, 2024
2541991
doc: add esm examples to node:https
mfdebian Aug 19, 2024
6ccbd32
doc, meta: add missing `,` to `BUILDING.md`
avivkeller Aug 19, 2024
c4996c1
meta: run coverage-windows when `vcbuild.bat` updated
avivkeller Aug 19, 2024
909c532
src: move more crypto code to ncrypto
jasnell Aug 11, 2024
cbe30a0
test_runner: finish build phase before running tests
cjihrig Aug 20, 2024
3a74c40
src: improve `buffer.transcode` performance
anonrig Aug 20, 2024
1c29e74
test_runner: make `mock.module`'s `specifier` consistent with `import()`
aduh95 Aug 20, 2024
336496b
module: add sourceURL magic comment hinting generated source
legendecas Aug 20, 2024
45b0250
test_runner: account for newline in source maps
cjihrig Aug 21, 2024
858b583
test_runner: defer inheriting hooks until run()
cjihrig Jul 19, 2024
97fa075
test_runner: support running tests in process
cjihrig Jul 13, 2024
3caf29e
deps: update sqlite to 3.46.1
nodejs-github-bot Aug 18, 2024
a5ce241
deps: sqlite: fix Windows compilation
cjihrig Jun 12, 2024
0cf78aa
test_runner: refactor `mock_loader`
aduh95 Aug 21, 2024
b0ed8db
test: prevent V8 from writing into the system's tmpdir
targos Aug 21, 2024
da6c61d
tools: add swc license
marco-ippolito Aug 22, 2024
9c70920
deps: update undici to 6.19.8
nodejs-github-bot Aug 22, 2024
0d7171d
meta: add more labels to dep-updaters
avivkeller Aug 22, 2024
61affd7
doc: fix capitalization in module.md
shallow-beach Aug 23, 2024
b584356
deps: update amaro to 0.1.7
nodejs-github-bot Aug 23, 2024
fffc300
stream: change stream to use index instead of `for...of`
HBSPS Aug 23, 2024
1e01bdc
net: exclude ipv6 loopback addresses from server.listen
Aug 23, 2024
eef3030
src: remove cached data tag from snapshot metadata
joyeecheung Aug 23, 2024
b5a23c9
meta: remind users to use a supported version in bug reports
avivkeller Aug 23, 2024
d4310fe
test_runner: add support for coverage thresholds
avivkeller Aug 23, 2024
71fdf96
build: update required python version to 3.8
avivkeller Aug 23, 2024
8a4f8a9
test: add tests for runner coverage with different stdout column widths
pmarchini Aug 24, 2024
467ac3a
build: don't clean obj.target directory if it doesn't exist
joyeecheung Aug 24, 2024
fc08a9b
fs: refactor handleTimestampsAndMode to remove redundant call
rayark1 Aug 24, 2024
16d4c43
typings: provide internal types for wasi bindings
RulerOfCakes Aug 24, 2024
1800a58
doc: update websocket flag description to reflect stable API status
debbs061 Aug 24, 2024
02d664b
test: fix improper path to URL conversion
aduh95 Aug 24, 2024
8a4b26f
timers: fix validation
ShogunPanda Aug 25, 2024
290f6ce
deps: update amaro to 0.1.8
nodejs-github-bot Aug 25, 2024
72c554a
sqlite: return results with null prototype
targos Aug 25, 2024
94985df
benchmark: fix benchmark for file path and URL conversion
injunchoi98 Aug 25, 2024
66ae9f4
test: use valid hostnames
lpinca Aug 25, 2024
7d9e994
src: change SetEncodedValue to return Maybe<void>
tniessen Aug 26, 2024
b5eb24c
test: force spec reporter in test-runner-watch-mode.mjs
cjihrig Aug 26, 2024
4578e94
src: use better return types in KVStore
targos Aug 24, 2024
4938188
src: return `v8::Object` from error constructors
targos Aug 24, 2024
1ff3f63
src: handle errors correctly in `permission.cc`
targos Aug 24, 2024
3879814
tools: remove unused python files
avivkeller Aug 26, 2024
846e2b2
test: refactor test_runner tests to change default reporter
cjihrig Aug 27, 2024
fe56949
deps: update c-ares to v1.33.1
nodejs-github-bot Aug 27, 2024
afd8c1e
buffer: allow invalid encoding in from
ronag Aug 27, 2024
e6e1f4e
src: remove redundant AESCipherMode
tniessen Aug 27, 2024
ac178b0
buffer: truncate instead of throw when writing beyond buffer
ronag Aug 27, 2024
3cd10a3
node-api: remove RefBase and CallbackWrapper
vmoroz Aug 27, 2024
101e299
src: move more crypto_dh.cc code to ncrypto
jasnell Aug 19, 2024
3cf6457
module: use amaro default transform values
marco-ippolito Aug 23, 2024
8ffdd1e
zlib: simplify validators
anonrig Aug 27, 2024
fc57bea
doc: add note about shasum generation failure
marco-ippolito Aug 27, 2024
a9ce2b6
lib: fix emit warning for debuglog.time when disabled
H4ad Aug 27, 2024
c3dc83b
doc: support collaborators - talk amplification
mhdawson Aug 22, 2024
33a6b3c
deps: backport ICU-22787 to fix ClangCL on Windows
StefanStojanovic Aug 27, 2024
c499913
doc: fix information about including coverage files
avivkeller Aug 27, 2024
72345de
test: fix embedding test for Windows
vmoroz Aug 27, 2024
7fd033f
doc: run license-builder
github-actions[bot] Aug 28, 2024
04f83b5
Revert "net: validate host name for server listen"
jakecastelli Aug 25, 2024
4a664b5
lib: respect terminal capabilities on styleText
RafaelGSS Aug 28, 2024
4baf463
src: add JS APIs for compile cache and NODE_DISABLE_COMPILE_CACHE
joyeecheung Aug 28, 2024
64442fc
test: refactor test-abortcontroller to use node:test
jasnell Aug 26, 2024
dbbc790
test: update test-aborted-util to use node:test
jasnell Aug 26, 2024
c10aff6
test: move a couple of tests over to using node:test
jasnell Aug 27, 2024
b00c087
deps: V8: cherry-pick e74d0f437fcd
joyeecheung Aug 19, 2024
f8cbbc6
src: use v8::Isolate::GetDefaultLocale() to compute navigator.language
joyeecheung Aug 9, 2024
80e5150
doc: fix module compile cache description
ShenHongFei Aug 29, 2024
825d933
doc: add getHeapStatistics() property descriptions
bcmarinacci Aug 29, 2024
e071651
src: disable fast methods for `buffer.write`
targos Aug 29, 2024
a0be95e
test: merge ongc and gcutil into gc.js
tannal Aug 13, 2024
a4bebf8
test_runner: ensure test watcher picks up new test files
pmarchini Aug 29, 2024
db80eac
vm: introduce vanilla contexts via vm.constants.DONT_CONTEXTIFY
joyeecheung Aug 29, 2024
73604cf
deps: update nghttp2 to 1.63.0
nodejs-github-bot Aug 29, 2024
5ee234a
test,crypto: update WebCryptoAPI WPT
panva Aug 29, 2024
c74f2ae
test: update test-assert to use node:test
jasnell Aug 27, 2024
9f1ce73
test: update test-assert-typedarray-deepequal to use node:test
jasnell Aug 27, 2024
bf82448
doc: fix typo in styleText description
RafaelGSS Aug 29, 2024
bc976cf
test: update test-abortsignal-cloneable to use node:test
jasnell Aug 27, 2024
edbecf5
test: increase key size for ca2-cert.pem
mhdawson Aug 29, 2024
522d5a3
test: run V8 Fast API tests in release mode too
targos Aug 30, 2024
fe5666f
vm: return all own names and symbols in property enumerator interceptor
legendecas Aug 30, 2024
9ba75fa
src,lib: add performance.uvMetricsInfo
RafaelGSS Aug 30, 2024
f5c5529
doc: add alert on REPL from TCP socket
RafaelGSS Aug 30, 2024
68758d4
doc: add support me link for anonrig
anonrig Aug 30, 2024
76345a5
test: update TLS test for OpenSSL 3.2
richardlau Aug 30, 2024
a4a6ef8
test: fix test-tls-client-auth test for OpenSSL32
mhdawson Aug 28, 2024
6f0cf35
build: reclaim disk space on macOS GHA runner
jakecastelli Aug 30, 2024
78ee90e
2024-09-03, Version 22.8.0 (Current)
RafaelGSS Aug 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
src: improve buffer.transcode performance
PR-URL: #54153
Reviewed-By: Daniel Lemire <daniel@lemire.me>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
anonrig authored and RafaelGSS committed Aug 25, 2024
commit 3a74c400d5458e92a04f96d44a11ea8067921278
35 changes: 35 additions & 0 deletions benchmark/buffers/buffer-transcode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use strict';
const common = require('../common.js');
const assert = require('node:assert');
const buffer = require('node:buffer');

const hasIntl = !!process.config.variables.v8_enable_i18n_support;
const encodings = ['latin1', 'ascii', 'ucs2', 'utf8'];

if (!hasIntl) {
console.log('Skipping: `transcode` is only available on platforms that support i18n`');
process.exit(0);
}

const bench = common.createBenchmark(main, {
fromEncoding: encodings,
toEncoding: encodings,
length: [1, 10, 1000],
n: [1e5],
}, {
combinationFilter(p) {
return !(p.fromEncoding === 'ucs2' && p.toEncoding === 'utf8');
},
});

function main({ n, fromEncoding, toEncoding, length }) {
const input = Buffer.from('a'.repeat(length));
let out = 0;
bench.start();
for (let i = 0; i < n; i++) {
const dest = buffer.transcode(input, fromEncoding, toEncoding);
out += dest.buffer.byteLength;
}
bench.end(n);
assert.ok(out >= 0);
}
107 changes: 44 additions & 63 deletions src/node_i18n.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

#include "node_i18n.h"
#include "node_external_reference.h"
#include "simdutf.h"

#if defined(NODE_HAVE_I18N_SUPPORT)

Expand Down Expand Up @@ -147,7 +148,6 @@ MaybeLocal<Object> Transcode(Environment* env,
const char* source,
const size_t source_length,
UErrorCode* status) {
*status = U_ZERO_ERROR;
MaybeLocal<Object> ret;
MaybeStackBuffer<char> result;
Converter to(toEncoding);
Expand All @@ -170,22 +170,21 @@ MaybeLocal<Object> Transcode(Environment* env,
return ret;
}

MaybeLocal<Object> TranscodeToUcs2(Environment* env,
const char* fromEncoding,
const char* toEncoding,
const char* source,
const size_t source_length,
UErrorCode* status) {
*status = U_ZERO_ERROR;
MaybeLocal<Object> ret;
MaybeLocal<Object> TranscodeLatin1ToUcs2(Environment* env,
const char* fromEncoding,
const char* toEncoding,
const char* source,
const size_t source_length,
UErrorCode* status) {
MaybeStackBuffer<UChar> destbuf(source_length);
Converter from(fromEncoding);
const size_t length_in_chars = source_length * sizeof(UChar);
ucnv_toUChars(from.conv(), *destbuf, length_in_chars,
source, source_length, status);
if (U_SUCCESS(*status))
ret = ToBufferEndian(env, &destbuf);
return ret;
auto actual_length =
simdutf::convert_latin1_to_utf16le(source, source_length, destbuf.out());
if (actual_length == 0) {
*status = U_INVALID_CHAR_FOUND;
return {};
}

return Buffer::New(env, &destbuf);
}

MaybeLocal<Object> TranscodeFromUcs2(Environment* env,
Expand All @@ -194,13 +193,11 @@ MaybeLocal<Object> TranscodeFromUcs2(Environment* env,
const char* source,
const size_t source_length,
UErrorCode* status) {
*status = U_ZERO_ERROR;
MaybeStackBuffer<UChar> sourcebuf;
MaybeLocal<Object> ret;
Converter to(toEncoding);

size_t sublen = ucnv_getMinCharSize(to.conv());
std::string sub(sublen, '?');
std::string sub(to.min_char_size(), '?');
to.set_subst_chars(sub.c_str());

const size_t length_in_chars = source_length / sizeof(UChar);
Expand All @@ -221,26 +218,18 @@ MaybeLocal<Object> TranscodeUcs2FromUtf8(Environment* env,
const char* source,
const size_t source_length,
UErrorCode* status) {
*status = U_ZERO_ERROR;
MaybeStackBuffer<UChar> destbuf;
int32_t result_length;
u_strFromUTF8(*destbuf, destbuf.capacity(), &result_length,
source, source_length, status);
MaybeLocal<Object> ret;
if (U_SUCCESS(*status)) {
destbuf.SetLength(result_length);
ret = ToBufferEndian(env, &destbuf);
} else if (*status == U_BUFFER_OVERFLOW_ERROR) {
*status = U_ZERO_ERROR;
destbuf.AllocateSufficientStorage(result_length);
u_strFromUTF8(*destbuf, result_length, &result_length,
source, source_length, status);
if (U_SUCCESS(*status)) {
destbuf.SetLength(result_length);
ret = ToBufferEndian(env, &destbuf);
}
size_t expected_utf16_length =
simdutf::utf16_length_from_utf8(source, source_length);
MaybeStackBuffer<UChar> destbuf(expected_utf16_length);
auto actual_length =
simdutf::convert_utf8_to_utf16le(source, source_length, destbuf.out());

if (actual_length == 0) {
*status = U_INVALID_CHAR_FOUND;
return {};
}
return ret;

return Buffer::New(env, &destbuf);
}

MaybeLocal<Object> TranscodeUtf8FromUcs2(Environment* env,
Expand All @@ -249,32 +238,25 @@ MaybeLocal<Object> TranscodeUtf8FromUcs2(Environment* env,
const char* source,
const size_t source_length,
UErrorCode* status) {
*status = U_ZERO_ERROR;
MaybeLocal<Object> ret;
const size_t length_in_chars = source_length / sizeof(UChar);
int32_t result_length;
MaybeStackBuffer<UChar> sourcebuf;
MaybeStackBuffer<char> destbuf;
CopySourceBuffer(&sourcebuf, source, source_length, length_in_chars);
u_strToUTF8(*destbuf, destbuf.capacity(), &result_length,
*sourcebuf, length_in_chars, status);
if (U_SUCCESS(*status)) {
destbuf.SetLength(result_length);
ret = ToBufferEndian(env, &destbuf);
} else if (*status == U_BUFFER_OVERFLOW_ERROR) {
*status = U_ZERO_ERROR;
destbuf.AllocateSufficientStorage(result_length);
u_strToUTF8(*destbuf, result_length, &result_length, *sourcebuf,
length_in_chars, status);
if (U_SUCCESS(*status)) {
destbuf.SetLength(result_length);
ret = ToBufferEndian(env, &destbuf);
}
size_t expected_utf8_length = simdutf::utf8_length_from_utf16le(
reinterpret_cast<const char16_t*>(source), length_in_chars);

MaybeStackBuffer<char> destbuf(expected_utf8_length);
auto actual_length = simdutf::convert_utf16le_to_utf8(
reinterpret_cast<const char16_t*>(source),
length_in_chars,
destbuf.out());

if (actual_length == 0) {
*status = U_INVALID_CHAR_FOUND;
return {};
}
return ret;

return Buffer::New(env, &destbuf);
}

const char* EncodingName(const enum encoding encoding) {
constexpr const char* EncodingName(const enum encoding encoding) {
switch (encoding) {
case ASCII: return "us-ascii";
case LATIN1: return "iso8859-1";
Expand All @@ -284,7 +266,7 @@ const char* EncodingName(const enum encoding encoding) {
}
}

bool SupportedEncoding(const enum encoding encoding) {
constexpr bool SupportedEncoding(const enum encoding encoding) {
switch (encoding) {
case ASCII:
case LATIN1:
Expand All @@ -309,8 +291,7 @@ void Transcode(const FunctionCallbackInfo<Value>&args) {
switch (fromEncoding) {
case ASCII:
case LATIN1:
if (toEncoding == UCS2)
tfn = &TranscodeToUcs2;
if (toEncoding == UCS2) tfn = &TranscodeLatin1ToUcs2;
break;
case UTF8:
if (toEncoding == UCS2)
Expand Down