Skip to content

Commit e279b02

Browse files
jasnelltargos
authored andcommitted
src: avoid deferred gc/cleanup for Buffer.from
Previously, the code path would allocated a tracked ArrayBuffer that defers cleanup and deallocation of the underlying data with a SetImmediate. Avoid the unnecessary deferral by just allocating a `BackingStore` directly and writing into it. Fixes: #38300 Refs: #38336 PR-URL: #38337 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Khaidi Chu <i@2333.moe> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
1 parent a9ff9c0 commit e279b02

File tree

1 file changed

+18
-10
lines changed

1 file changed

+18
-10
lines changed

src/node_buffer.cc

+18-10
Original file line numberDiff line numberDiff line change
@@ -301,28 +301,36 @@ MaybeLocal<Object> New(Isolate* isolate,
301301
if (!StringBytes::Size(isolate, string, enc).To(&length))
302302
return Local<Object>();
303303
size_t actual = 0;
304-
char* data = nullptr;
304+
std::unique_ptr<BackingStore> store;
305305

306306
if (length > 0) {
307-
data = UncheckedMalloc(length);
307+
store = ArrayBuffer::NewBackingStore(isolate, length);
308308

309-
if (data == nullptr) {
309+
if (UNLIKELY(!store)) {
310310
THROW_ERR_MEMORY_ALLOCATION_FAILED(isolate);
311311
return Local<Object>();
312312
}
313313

314-
actual = StringBytes::Write(isolate, data, length, string, enc);
314+
actual = StringBytes::Write(
315+
isolate,
316+
static_cast<char*>(store->Data()),
317+
length,
318+
string,
319+
enc);
315320
CHECK(actual <= length);
316321

317-
if (actual == 0) {
318-
free(data);
319-
data = nullptr;
320-
} else if (actual < length) {
321-
data = node::Realloc(data, actual);
322+
if (LIKELY(actual > 0)) {
323+
if (actual < length)
324+
store = BackingStore::Reallocate(isolate, std::move(store), actual);
325+
Local<ArrayBuffer> buf = ArrayBuffer::New(isolate, std::move(store));
326+
Local<Object> obj;
327+
if (UNLIKELY(!New(isolate, buf, 0, actual).ToLocal(&obj)))
328+
return MaybeLocal<Object>();
329+
return scope.Escape(obj);
322330
}
323331
}
324332

325-
return scope.EscapeMaybe(New(isolate, data, actual));
333+
return scope.EscapeMaybe(New(isolate, 0));
326334
}
327335

328336

0 commit comments

Comments
 (0)