From 8ce7e73e78dd4d46f823cae356f0e976e7152327 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Thu, 18 Aug 2016 20:47:33 +0200 Subject: [PATCH] Prevent extra peformance hit by fillInStackTrace() when create a new annotated connect exception. Motivation: To make it easier to debug connect exceptions we create new exceptions which also contain the remote address. For this we basically created a new instance and call setStackTrace(...). When doing this we pay an extra penality because it calls fillInStackTrace() when calling the super constructor. Modifications: Create special sub-classes of Exceptions that override the fillInStackTrace() method and so eliminate the overhead. Result: Less overhead when "annotate" connect exceptions. --- .../io/netty/channel/AbstractChannel.java | 63 +++++++++++++++---- 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/transport/src/main/java/io/netty/channel/AbstractChannel.java b/transport/src/main/java/io/netty/channel/AbstractChannel.java index 4055677dba..879b4c6441 100644 --- a/transport/src/main/java/io/netty/channel/AbstractChannel.java +++ b/transport/src/main/java/io/netty/channel/AbstractChannel.java @@ -939,17 +939,13 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha */ protected final Throwable annotateConnectException(Throwable cause, SocketAddress remoteAddress) { if (cause instanceof ConnectException) { - Throwable newT = new ConnectException(cause.getMessage() + ": " + remoteAddress); - newT.setStackTrace(cause.getStackTrace()); - cause = newT; - } else if (cause instanceof NoRouteToHostException) { - Throwable newT = new NoRouteToHostException(cause.getMessage() + ": " + remoteAddress); - newT.setStackTrace(cause.getStackTrace()); - cause = newT; - } else if (cause instanceof SocketException) { - Throwable newT = new SocketException(cause.getMessage() + ": " + remoteAddress); - newT.setStackTrace(cause.getStackTrace()); - cause = newT; + return new AnnotatedConnectException((ConnectException) cause, remoteAddress); + } + if (cause instanceof NoRouteToHostException) { + return new AnnotatedNoRouteToHostException((NoRouteToHostException) cause, remoteAddress); + } + if (cause instanceof SocketException) { + return new AnnotatedSocketException((SocketException) cause, remoteAddress); } return cause; @@ -1062,4 +1058,49 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha return super.trySuccess(); } } + + private static final class AnnotatedConnectException extends ConnectException { + + private static final long serialVersionUID = 3901958112696433556L; + + AnnotatedConnectException(ConnectException exception, SocketAddress remoteAddress) { + super(exception.getMessage() + ": " + remoteAddress); + setStackTrace(exception.getStackTrace()); + } + + @Override + public Throwable fillInStackTrace() { + return this; + } + } + + private static final class AnnotatedNoRouteToHostException extends NoRouteToHostException { + + private static final long serialVersionUID = -6801433937592080623L; + + AnnotatedNoRouteToHostException(NoRouteToHostException exception, SocketAddress remoteAddress) { + super(exception.getMessage() + ": " + remoteAddress); + setStackTrace(exception.getStackTrace()); + } + + @Override + public Throwable fillInStackTrace() { + return this; + } + } + + private static final class AnnotatedSocketException extends SocketException { + + private static final long serialVersionUID = 3896743275010454039L; + + AnnotatedSocketException(SocketException exception, SocketAddress remoteAddress) { + super(exception.getMessage() + ": " + remoteAddress); + setStackTrace(exception.getStackTrace()); + } + + @Override + public Throwable fillInStackTrace() { + return this; + } + } }