Skip to content

Commit 264d031

Browse files
authored
src: fix inefficient usage of v8_inspector::StringView
v8_inspector::StringView can either be one-byte or two-byte strings. Node has currently two places where it's unconditionally assumed that it's a two-byte StringView. This requires the upstream V8 inspector to unnecessarily create a copy of the string: https://source.chromium.org/chromium/chromium/src/+/main:v8/src/inspector/v8-inspector-session-impl.cc;l=192-199;drc=05bacd38e7a31e92afe0fd66081dfa2cc03b934a This is particularly slow, especially for large CDP messages, as the serialized JSON is iterated 8-bit char by 8-bit char and each one widened to a 16-bit char. This PR introduces a small helper that correctly converts a StringView to a v8::String instance honoring the "is8Bit" flag. This allows upstream V8 to remove the unnecessary widening copy. PR-URL: nodejs#52372 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Joyee Cheung <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Minwoo Jung <[email protected]> Reviewed-By: Chengzhong Wu <[email protected]>
1 parent 3b34fd7 commit 264d031

File tree

3 files changed

+32
-4
lines changed

3 files changed

+32
-4
lines changed

src/inspector_js_api.cc

+2-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ using v8::HandleScope;
2323
using v8::Isolate;
2424
using v8::Local;
2525
using v8::MaybeLocal;
26-
using v8::NewStringType;
2726
using v8::Object;
2827
using v8::String;
2928
using v8::Uint32;
@@ -69,9 +68,8 @@ class JSBindingsConnection : public BaseObject {
6968
HandleScope handle_scope(isolate);
7069
Context::Scope context_scope(env_->context());
7170
Local<Value> argument;
72-
if (!String::NewFromTwoByte(isolate, message.characters16(),
73-
NewStringType::kNormal,
74-
message.length()).ToLocal(&argument)) return;
71+
if (!ToV8Value(env_->context(), message, isolate).ToLocal(&argument))
72+
return;
7573
connection_->OnMessage(argument);
7674
}
7775

src/util-inl.h

+26
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,32 @@ v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
344344
.FromMaybe(v8::Local<v8::String>());
345345
}
346346

347+
v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
348+
v8_inspector::StringView str,
349+
v8::Isolate* isolate) {
350+
if (isolate == nullptr) isolate = context->GetIsolate();
351+
if (str.length() >= static_cast<size_t>(v8::String::kMaxLength))
352+
[[unlikely]] {
353+
// V8 only has a TODO comment about adding an exception when the maximum
354+
// string size is exceeded.
355+
ThrowErrStringTooLong(isolate);
356+
return v8::MaybeLocal<v8::Value>();
357+
}
358+
359+
if (str.is8Bit()) {
360+
return v8::String::NewFromOneByte(isolate,
361+
str.characters8(),
362+
v8::NewStringType::kNormal,
363+
str.length())
364+
.FromMaybe(v8::Local<v8::String>());
365+
}
366+
return v8::String::NewFromTwoByte(isolate,
367+
str.characters16(),
368+
v8::NewStringType::kNormal,
369+
str.length())
370+
.FromMaybe(v8::Local<v8::String>());
371+
}
372+
347373
template <typename T>
348374
v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
349375
const std::vector<T>& vec,

src/util.h

+4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
2626

2727
#include "uv.h"
28+
#include "v8-inspector.h"
2829
#include "v8.h"
2930

3031
#include "node.h"
@@ -719,6 +720,9 @@ inline v8::Maybe<void> FromV8Array(v8::Local<v8::Context> context,
719720
inline v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
720721
std::string_view str,
721722
v8::Isolate* isolate = nullptr);
723+
inline v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,
724+
v8_inspector::StringView str,
725+
v8::Isolate* isolate);
722726
template <typename T, typename test_for_number =
723727
typename std::enable_if<std::numeric_limits<T>::is_specialized, bool>::type>
724728
inline v8::MaybeLocal<v8::Value> ToV8Value(v8::Local<v8::Context> context,

0 commit comments

Comments
 (0)