Skip to content

Commit 3649ec5

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 <[email protected]> Reviewed-By: Khaidi Chu <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Joyee Cheung <[email protected]>
1 parent 27d7588 commit 3649ec5

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
@@ -303,28 +303,36 @@ MaybeLocal<Object> New(Isolate* isolate,
303303
if (!StringBytes::Size(isolate, string, enc).To(&length))
304304
return Local<Object>();
305305
size_t actual = 0;
306-
char* data = nullptr;
306+
std::unique_ptr<BackingStore> store;
307307

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

311-
if (data == nullptr) {
311+
if (UNLIKELY(!store)) {
312312
THROW_ERR_MEMORY_ALLOCATION_FAILED(isolate);
313313
return Local<Object>();
314314
}
315315

316-
actual = StringBytes::Write(isolate, data, length, string, enc);
316+
actual = StringBytes::Write(
317+
isolate,
318+
static_cast<char*>(store->Data()),
319+
length,
320+
string,
321+
enc);
317322
CHECK(actual <= length);
318323

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

327-
return scope.EscapeMaybe(New(isolate, data, actual));
335+
return scope.EscapeMaybe(New(isolate, 0));
328336
}
329337

330338

0 commit comments

Comments
 (0)