From b4e069a5c3ffd967beb37547666b6dc954ca592b Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Fri, 22 Feb 2019 21:55:14 -0500 Subject: [PATCH] Convert grpc malloc slice to use grpc_core::RefCount. This shows up in profiles. Using grpc_core::RefCount lowers the time spent in grpc_slice_malloc_large() by 8%. --- src/core/lib/slice/slice.cc | 44 +++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/core/lib/slice/slice.cc b/src/core/lib/slice/slice.cc index e842d84f11f..31437aa4600 100644 --- a/src/core/lib/slice/slice.cc +++ b/src/core/lib/slice/slice.cc @@ -26,6 +26,7 @@ #include +#include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/iomgr/exec_ctx.h" char* grpc_slice_to_c_string(grpc_slice slice) { @@ -213,21 +214,35 @@ grpc_slice grpc_slice_from_copied_string(const char* source) { return grpc_slice_from_copied_buffer(source, strlen(source)); } -typedef struct { +namespace { + +struct MallocRefCount { + MallocRefCount(const grpc_slice_refcount_vtable* vtable) { + base.vtable = vtable; + base.sub_refcount = &base; + } + + void Ref() { refs.Ref(); } + void Unref() { + if (refs.Unref()) { + gpr_free(this); + } + } + grpc_slice_refcount base; - gpr_refcount refs; -} malloc_refcount; + grpc_core::RefCount refs; +}; + +} // namespace static void malloc_ref(void* p) { - malloc_refcount* r = static_cast(p); - gpr_ref(&r->refs); + MallocRefCount* r = static_cast(p); + r->Ref(); } static void malloc_unref(void* p) { - malloc_refcount* r = static_cast(p); - if (gpr_unref(&r->refs)) { - gpr_free(r); - } + MallocRefCount* r = static_cast(p); + r->Unref(); } static const grpc_slice_refcount_vtable malloc_vtable = { @@ -246,15 +261,10 @@ grpc_slice grpc_slice_malloc_large(size_t length) { refcount is a malloc_refcount bytes is an array of bytes of the requested length Both parts are placed in the same allocation returned from gpr_malloc */ - malloc_refcount* rc = static_cast( - gpr_malloc(sizeof(malloc_refcount) + length)); - - /* Initial refcount on rc is 1 - and it's up to the caller to release - this reference. */ - gpr_ref_init(&rc->refs, 1); + void* data = + static_cast(gpr_malloc(sizeof(MallocRefCount) + length)); - rc->base.vtable = &malloc_vtable; - rc->base.sub_refcount = &rc->base; + auto* rc = new (data) MallocRefCount(&malloc_vtable); /* Build up the slice to be returned. */ /* The slices refcount points back to the allocated block. */