n-api: improve performance creating strings

Improve performance creating strings using N-API by ensuring that the
strings are not internalized.

Added test cases for latin-1 and utf-16 strings.

PR-URL: https://github.com/nodejs/node/pull/26439
Fixes: https://github.com/nodejs/node/issues/26437
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Anthony Tuininga 2019-03-04 15:02:27 -07:00 committed by Myles Borins
parent 705935d620
commit d3de1ed653
No known key found for this signature in database
GPG Key ID: 933B01F40B5CA946
3 changed files with 55 additions and 6 deletions

View File

@ -1993,12 +1993,15 @@ napi_status napi_create_string_latin1(napi_env env,
napi_value* result) {
CHECK_ENV(env);
CHECK_ARG(env, result);
RETURN_STATUS_IF_FALSE(env,
(length == NAPI_AUTO_LENGTH) || length <= INT_MAX,
napi_invalid_arg);
auto isolate = env->isolate;
auto str_maybe =
v8::String::NewFromOneByte(isolate,
reinterpret_cast<const uint8_t*>(str),
v8::NewStringType::kInternalized,
v8::NewStringType::kNormal,
length);
CHECK_MAYBE_EMPTY(env, str_maybe, napi_generic_failure);
@ -2012,11 +2015,18 @@ napi_status napi_create_string_utf8(napi_env env,
napi_value* result) {
CHECK_ENV(env);
CHECK_ARG(env, result);
RETURN_STATUS_IF_FALSE(env,
(length == NAPI_AUTO_LENGTH) || length <= INT_MAX,
napi_invalid_arg);
v8::Local<v8::String> s;
CHECK_NEW_FROM_UTF8_LEN(env, s, str, length);
*result = v8impl::JsValueFromV8LocalValue(s);
auto isolate = env->isolate;
auto str_maybe =
v8::String::NewFromUtf8(isolate,
str,
v8::NewStringType::kNormal,
static_cast<int>(length));
CHECK_MAYBE_EMPTY(env, str_maybe, napi_generic_failure);
*result = v8impl::JsValueFromV8LocalValue(str_maybe.ToLocalChecked());
return napi_clear_last_error(env);
}
@ -2026,12 +2036,15 @@ napi_status napi_create_string_utf16(napi_env env,
napi_value* result) {
CHECK_ENV(env);
CHECK_ARG(env, result);
RETURN_STATUS_IF_FALSE(env,
(length == NAPI_AUTO_LENGTH) || length <= INT_MAX,
napi_invalid_arg);
auto isolate = env->isolate;
auto str_maybe =
v8::String::NewFromTwoByte(isolate,
reinterpret_cast<const uint16_t*>(str),
v8::NewStringType::kInternalized,
v8::NewStringType::kNormal,
length);
CHECK_MAYBE_EMPTY(env, str_maybe, napi_generic_failure);

View File

@ -73,3 +73,11 @@ assert.strictEqual(test_string.Utf8Length(str6), 14);
assert.throws(() => {
test_string.TestLargeUtf8();
}, /^Error: Invalid argument$/);
assert.throws(() => {
test_string.TestLargeLatin1();
}, /^Error: Invalid argument$/);
assert.throws(() => {
test_string.TestLargeUtf16();
}, /^Error: Invalid argument$/);

View File

@ -215,6 +215,32 @@ napi_value TestLargeUtf8(napi_env env, napi_callback_info info) {
return output;
}
static napi_value TestLargeLatin1(napi_env env, napi_callback_info info) {
napi_value output;
if (SIZE_MAX > INT_MAX) {
NAPI_CALL(env, napi_create_string_latin1(env, "", ((size_t)INT_MAX) + 1, &output));
} else {
// just throw the expected error as there is nothing to test
// in this case since we can't overflow
NAPI_CALL(env, napi_throw_error(env, NULL, "Invalid argument"));
}
return output;
}
static napi_value TestLargeUtf16(napi_env env, napi_callback_info info) {
napi_value output;
if (SIZE_MAX > INT_MAX) {
NAPI_CALL(env, napi_create_string_utf16(env, "", ((size_t)INT_MAX) + 1, &output));
} else {
// just throw the expected error as there is nothing to test
// in this case since we can't overflow
NAPI_CALL(env, napi_throw_error(env, NULL, "Invalid argument"));
}
return output;
}
napi_value Init(napi_env env, napi_value exports) {
napi_property_descriptor properties[] = {
DECLARE_NAPI_PROPERTY("TestLatin1", TestLatin1),
@ -226,6 +252,8 @@ napi_value Init(napi_env env, napi_value exports) {
DECLARE_NAPI_PROPERTY("Utf16Length", Utf16Length),
DECLARE_NAPI_PROPERTY("Utf8Length", Utf8Length),
DECLARE_NAPI_PROPERTY("TestLargeUtf8", TestLargeUtf8),
DECLARE_NAPI_PROPERTY("TestLargeLatin1", TestLargeLatin1),
DECLARE_NAPI_PROPERTY("TestLargeUtf16", TestLargeUtf16),
};
NAPI_CALL(env, napi_define_properties(