Skip to content

Commit 39318a1

Browse files
committed
stream: reuse unexposed managed read buffers
Signed-off-by: GetThatCookie <NimmenKeks@gmx.de>
1 parent bb58fcd commit 39318a1

3 files changed

Lines changed: 25 additions & 4 deletions

File tree

src/env.cc

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ using v8::Undefined;
7777
using v8::Value;
7878
using worker::Worker;
7979

80+
constexpr size_t kManagedBufferCacheSize = 64 * 1024;
81+
8082
int const ContextEmbedderTag::kNodeContextTag = 0x6e6f64;
8183
void* const ContextEmbedderTag::kNodeContextTagPtr = const_cast<void*>(
8284
static_cast<const void*>(&ContextEmbedderTag::kNodeContextTag));
@@ -746,10 +748,16 @@ void Environment::add_refs(int64_t diff) {
746748
}
747749

748750
uv_buf_t Environment::allocate_managed_buffer(const size_t suggested_size) {
749-
std::unique_ptr<BackingStore> bs = ArrayBuffer::NewBackingStore(
750-
isolate(),
751-
suggested_size,
752-
BackingStoreInitializationMode::kUninitialized);
751+
std::unique_ptr<BackingStore> bs;
752+
if (suggested_size == kManagedBufferCacheSize &&
753+
managed_buffer_cache_ != nullptr) {
754+
bs = std::move(managed_buffer_cache_);
755+
} else {
756+
bs = ArrayBuffer::NewBackingStore(
757+
isolate(),
758+
suggested_size,
759+
BackingStoreInitializationMode::kUninitialized);
760+
}
753761
uv_buf_t buf = uv_buf_init(static_cast<char*>(bs->Data()), bs->ByteLength());
754762
released_allocated_buffers_.emplace(buf.base, std::move(bs));
755763
return buf;
@@ -767,6 +775,11 @@ std::unique_ptr<BackingStore> Environment::release_managed_buffer(
767775
return bs;
768776
}
769777

778+
void Environment::recycle_managed_buffer(std::unique_ptr<BackingStore> bs) {
779+
if (bs != nullptr && bs->ByteLength() == kManagedBufferCacheSize)
780+
managed_buffer_cache_ = std::move(bs);
781+
}
782+
770783
std::string Environment::GetExecPath(const std::vector<std::string>& argv) {
771784
char exec_path_buf[2 * PATH_MAX];
772785
size_t exec_path_len = sizeof(exec_path_buf);

src/env.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,9 @@ class Environment final : public MemoryRetainer {
10411041

10421042
uv_buf_t allocate_managed_buffer(const size_t suggested_size);
10431043
std::unique_ptr<v8::BackingStore> release_managed_buffer(const uv_buf_t& buf);
1044+
// Only buffers that were not exposed externally may be recycled.
1045+
void recycle_managed_buffer(
1046+
std::unique_ptr<v8::BackingStore> backing_store);
10441047

10451048
void AddUnmanagedFd(int fd);
10461049
void RemoveUnmanagedFd(int fd);
@@ -1257,6 +1260,9 @@ class Environment final : public MemoryRetainer {
12571260
std::unordered_map<char*, std::unique_ptr<v8::BackingStore>>
12581261
released_allocated_buffers_;
12591262

1263+
// Retains at most one unexposed read buffer for reuse.
1264+
std::unique_ptr<v8::BackingStore> managed_buffer_cache_;
1265+
12601266
v8::CpuProfiler* cpu_profiler_ = nullptr;
12611267
std::vector<v8::ProfilerId> pending_profiles_;
12621268
};

src/stream_base.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,7 @@ void EmitToJSStreamListener::OnStreamRead(ssize_t nread, const uv_buf_t& buf_) {
764764
std::unique_ptr<BackingStore> bs = env->release_managed_buffer(buf_);
765765

766766
if (nread <= 0) {
767+
env->recycle_managed_buffer(std::move(bs));
767768
if (nread < 0)
768769
stream->CallJSOnreadMethod(nread, Local<ArrayBuffer>());
769770
return;
@@ -775,6 +776,7 @@ void EmitToJSStreamListener::OnStreamRead(ssize_t nread, const uv_buf_t& buf_) {
775776
bs = ArrayBuffer::NewBackingStore(
776777
isolate, nread, BackingStoreInitializationMode::kUninitialized);
777778
memcpy(bs->Data(), old_bs->Data(), nread);
779+
env->recycle_managed_buffer(std::move(old_bs));
778780
}
779781

780782
stream->CallJSOnreadMethod(nread, ArrayBuffer::New(isolate, std::move(bs)));

0 commit comments

Comments
 (0)