Skip to content

Commit

Permalink
src: avoid deferred gc/cleanup for Buffer.from
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
jasnell authored and targos committed Jun 11, 2021
1 parent a9ff9c0 commit e279b02
Showing 1 changed file with 18 additions and 10 deletions.
28 changes: 18 additions & 10 deletions src/node_buffer.cc
Expand Up @@ -301,28 +301,36 @@ MaybeLocal<Object> New(Isolate* isolate,
if (!StringBytes::Size(isolate, string, enc).To(&length))
return Local<Object>();
size_t actual = 0;
char* data = nullptr;
std::unique_ptr<BackingStore> store;

if (length > 0) {
data = UncheckedMalloc(length);
store = ArrayBuffer::NewBackingStore(isolate, length);

if (data == nullptr) {
if (UNLIKELY(!store)) {
THROW_ERR_MEMORY_ALLOCATION_FAILED(isolate);
return Local<Object>();
}

actual = StringBytes::Write(isolate, data, length, string, enc);
actual = StringBytes::Write(
isolate,
static_cast<char*>(store->Data()),
length,
string,
enc);
CHECK(actual <= length);

if (actual == 0) {
free(data);
data = nullptr;
} else if (actual < length) {
data = node::Realloc(data, actual);
if (LIKELY(actual > 0)) {
if (actual < length)
store = BackingStore::Reallocate(isolate, std::move(store), actual);
Local<ArrayBuffer> buf = ArrayBuffer::New(isolate, std::move(store));
Local<Object> obj;
if (UNLIKELY(!New(isolate, buf, 0, actual).ToLocal(&obj)))
return MaybeLocal<Object>();
return scope.Escape(obj);
}
}

return scope.EscapeMaybe(New(isolate, data, actual));
return scope.EscapeMaybe(New(isolate, 0));
}


Expand Down

0 comments on commit e279b02

Please sign in to comment.