mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
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: https://github.com/nodejs/node/issues/38300 Refs: https://github.com/nodejs/node/pull/38336 PR-URL: https://github.com/nodejs/node/pull/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>
This commit is contained in:
1 parent
f9e07e432b
commit
720fdf2f80
1 file changed
+18
-10
+18
-10
@@ -303,28 +303,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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user