From 49952a6302c10628155d8344f57473ceb355c9be Mon Sep 17 00:00:00 2001
From: Francesco Nigro <nigro.fra@gmail.com>
Date: Tue, 16 Jan 2024 13:48:59 +0100
Subject: [PATCH] Short-circuit ByteBuf::release

Motivation:

ReferenceCountUtil::safeRelease can both hit interface virtual calls and requires checking for an interface type (ReferenceCounted)

Modifications:

Perform a class check to save both.

Result:

Faster buffers release
---
 .../io/netty/channel/ChannelOutboundBuffer.java  | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java b/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java
index 7008ef558ccc..27119e8fbf47 100644
--- a/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java
+++ b/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java
@@ -15,6 +15,7 @@
  */
 package io.netty.channel;
 
+import io.netty.buffer.AbstractReferenceCountedByteBuf;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufHolder;
 import io.netty.buffer.Unpooled;
@@ -275,9 +276,20 @@ public boolean remove() {
 
         removeEntry(e);
 
+        // only release message, notify and decrement if it was not canceled before.
         if (!e.cancelled) {
-            // only release message, notify and decrement if it was not canceled before.
-            ReferenceCountUtil.safeRelease(msg);
+            // this save both checking against the ReferenceCounted interface
+            // and makes better use of virtual calls vs interface ones
+            if (msg instanceof AbstractReferenceCountedByteBuf) {
+                try {
+                    // release now as it is flushed.
+                    ((AbstractReferenceCountedByteBuf) msg).release();
+                } catch (Throwable t) {
+                    logger.warn("Failed to release a ByteBuf: {}", msg, t);
+                }
+            } else {
+                ReferenceCountUtil.safeRelease(msg);
+            }
             safeSuccess(promise);
             decrementPendingOutboundBytes(size, false, true);
         }
