Skip to content

Commit cb3c875

Browse files
authored
Merge pull request #178 from staylor/fix/inspector-from-string-view-no-alloc
inspector: avoid v8::String allocation in fromStringView
2 parents 0eef7f5 + fc9444f commit cb3c875

1 file changed

Lines changed: 29 additions & 8 deletions

File tree

src/binding.cpp

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2440,14 +2440,35 @@ static inline v8_inspector::StringView toStringView(const std::string &str) {
24402440
}
24412441

24422442
static inline std::string fromStringView(v8::Isolate* isolate, const v8_inspector::StringView stringView) {
2443-
int length = static_cast<int>(stringView.length());
2444-
v8::Local<v8::String> message = (
2445-
stringView.is8Bit()
2446-
? v8::String::NewFromOneByte(isolate, stringView.characters8(), v8::NewStringType::kNormal, length)
2447-
: v8::String::NewFromTwoByte(isolate, stringView.characters16(), v8::NewStringType::kNormal, length)
2448-
).ToLocalChecked();
2449-
v8::String::Utf8Value result(isolate, message);
2450-
return *result;
2443+
// Convert the inspector StringView to UTF-8 *without* allocating a
2444+
// v8::String. The previous implementation round-tripped through
2445+
// v8::String::NewFromOneByte / NewFromTwoByte (just to use Utf8Value
2446+
// for the conversion), which calls into V8's heap allocator. That is
2447+
// forbidden during certain V8 internal phases -- in particular,
2448+
// weak callbacks during garbage collection, where V8's
2449+
// PromiseHandlerTracker can invoke EvaluateCallback::sendFailure,
2450+
// which lands in Channel::sendResponse, which calls this helper.
2451+
// Allocating in that context trips AllowHeapAllocation::IsAllowed()
2452+
// and aborts the process in debug builds (in release builds the
2453+
// allocation is undefined behavior).
2454+
//
2455+
// The 8-bit case can be a direct memcpy; the 16-bit case uses
2456+
// v8_inspector::UTF16ToUTF8 (a pure host-side helper that doesn't
2457+
// touch the V8 heap) -- the same path allocString() uses.
2458+
//
2459+
// The `isolate` parameter is preserved for API compatibility but is
2460+
// no longer needed.
2461+
(void)isolate;
2462+
if (stringView.is8Bit()) {
2463+
return std::string(
2464+
reinterpret_cast<const char*>(stringView.characters8()),
2465+
stringView.length()
2466+
);
2467+
}
2468+
return v8_inspector::UTF16ToUTF8(
2469+
reinterpret_cast<const char16_t*>(stringView.characters16()),
2470+
stringView.length()
2471+
);
24512472
}
24522473

24532474
/// Allocates a string as utf8 on the allocator without \0 terminator, for use in Zig.

0 commit comments

Comments
 (0)