Mark it unlikely for Unref() to return true.

In the hot path, specially when the dtor of a class is inlined,
we will have to skip quite a few instructions (for Delete and dtor)
before returning.

Mark Unref() as unlikely so that compiler moves the
decrement-refcnt-and-return code instructions to the front.
pull/18993/head
Soheil Hassas Yeganeh 6 years ago
parent e9672bfb99
commit 983f678cb8
  1. 2
      src/core/ext/transport/chttp2/transport/internal.h
  2. 4
      src/core/lib/gprpp/orphanable.h
  3. 4
      src/core/lib/gprpp/ref_counted.h
  4. 4
      src/core/lib/transport/metadata.cc
  5. 2
      src/core/lib/transport/transport.h

@ -238,7 +238,7 @@ class Chttp2IncomingByteStream : public ByteStream {
// switch to std::shared_ptr<>. // switch to std::shared_ptr<>.
void Ref() { refs_.Ref(); } void Ref() { refs_.Ref(); }
void Unref() { void Unref() {
if (refs_.Unref()) { if (GPR_UNLIKELY(refs_.Unref())) {
grpc_core::Delete(this); grpc_core::Delete(this);
} }
} }

@ -110,12 +110,12 @@ class InternallyRefCounted : public Orphanable {
} }
void Unref() { void Unref() {
if (refs_.Unref()) { if (GPR_UNLIKELY(refs_.Unref())) {
Delete(static_cast<Child*>(this)); Delete(static_cast<Child*>(this));
} }
} }
void Unref(const DebugLocation& location, const char* reason) { void Unref(const DebugLocation& location, const char* reason) {
if (refs_.Unref(location, reason)) { if (GPR_UNLIKELY(refs_.Unref(location, reason))) {
Delete(static_cast<Child*>(this)); Delete(static_cast<Child*>(this));
} }
} }

@ -211,12 +211,12 @@ class RefCounted : public Impl {
// private, since it will only be used by RefCountedPtr<>, which is a // private, since it will only be used by RefCountedPtr<>, which is a
// friend of this class. // friend of this class.
void Unref() { void Unref() {
if (refs_.Unref()) { if (GPR_UNLIKELY(refs_.Unref())) {
Delete(static_cast<Child*>(this)); Delete(static_cast<Child*>(this));
} }
} }
void Unref(const DebugLocation& location, const char* reason) { void Unref(const DebugLocation& location, const char* reason) {
if (refs_.Unref(location, reason)) { if (GPR_UNLIKELY(refs_.Unref(location, reason))) {
Delete(static_cast<Child*>(this)); Delete(static_cast<Child*>(this));
} }
} }

@ -466,7 +466,7 @@ void grpc_mdelem_do_unref(grpc_mdelem gmd DEBUG_ARGS) {
case GRPC_MDELEM_STORAGE_INTERNED: { case GRPC_MDELEM_STORAGE_INTERNED: {
auto* md = reinterpret_cast<InternedMetadata*> GRPC_MDELEM_DATA(gmd); auto* md = reinterpret_cast<InternedMetadata*> GRPC_MDELEM_DATA(gmd);
uint32_t hash = md->hash(); uint32_t hash = md->hash();
if (md->Unref(FWD_DEBUG_ARGS)) { if (GPR_UNLIKELY(md->Unref(FWD_DEBUG_ARGS))) {
/* once the refcount hits zero, some other thread can come along and /* once the refcount hits zero, some other thread can come along and
free md at any time: it's unsafe from this point on to access it */ free md at any time: it's unsafe from this point on to access it */
note_disposed_interned_metadata(hash); note_disposed_interned_metadata(hash);
@ -475,7 +475,7 @@ void grpc_mdelem_do_unref(grpc_mdelem gmd DEBUG_ARGS) {
} }
case GRPC_MDELEM_STORAGE_ALLOCATED: { case GRPC_MDELEM_STORAGE_ALLOCATED: {
auto* md = reinterpret_cast<AllocatedMetadata*> GRPC_MDELEM_DATA(gmd); auto* md = reinterpret_cast<AllocatedMetadata*> GRPC_MDELEM_DATA(gmd);
if (md->Unref(FWD_DEBUG_ARGS)) { if (GPR_UNLIKELY(md->Unref(FWD_DEBUG_ARGS))) {
grpc_core::Delete(md); grpc_core::Delete(md);
} }
break; break;

@ -98,7 +98,7 @@ inline void grpc_stream_unref(grpc_stream_refcount* refcount,
#else #else
inline void grpc_stream_unref(grpc_stream_refcount* refcount) { inline void grpc_stream_unref(grpc_stream_refcount* refcount) {
#endif #endif
if (refcount->refs.Unref()) { if (GPR_UNLIKELY(refcount->refs.Unref())) {
grpc_stream_destroy(refcount); grpc_stream_destroy(refcount);
} }
} }

Loading…
Cancel
Save