From e00f24961adbd1ed0e2189cf5ca9dc16632faa7c Mon Sep 17 00:00:00 2001 From: Carl Mastrangelo Date: Thu, 15 Feb 2018 18:03:15 -0800 Subject: [PATCH] Get memory address from Unsafe for OpenSSL Motivation: Profiling tcnative SSL code showed a non trivial percentage (1%) of time spent in JNI code for InstaceOf. This turned out to be from `Buffer.address` which makes a JNI call, which safely checks on each call that The ByteBuffer is direct. Modification: Prefer using the address field of the pojo rather than looking it up with JNI. This is the same approach taken by the `OpenSsl` class. Result: Less JNI overhead --- .../ssl/ReferenceCountedOpenSslEngine.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java index 42ac7f6196..c0eb141a5f 100644 --- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java +++ b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java @@ -424,7 +424,7 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc final int sslWrote; if (src.isDirect()) { - sslWrote = SSL.writeToSSL(ssl, Buffer.address(src) + pos, len); + sslWrote = SSL.writeToSSL(ssl, bufferAddress(src) + pos, len); if (sslWrote > 0) { src.position(pos + sslWrote); } @@ -455,7 +455,7 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc private ByteBuf writeEncryptedData(final ByteBuffer src, int len) { final int pos = src.position(); if (src.isDirect()) { - SSL.bioSetByteBuffer(networkBIO, Buffer.address(src) + pos, len, false); + SSL.bioSetByteBuffer(networkBIO, bufferAddress(src) + pos, len, false); } else { final ByteBuf buf = alloc.directBuffer(len); try { @@ -483,7 +483,7 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc final int sslRead; final int pos = dst.position(); if (dst.isDirect()) { - sslRead = SSL.readFromSSL(ssl, Buffer.address(dst) + pos, dst.limit() - pos); + sslRead = SSL.readFromSSL(ssl, bufferAddress(dst) + pos, dst.limit() - pos); if (sslRead > 0) { dst.position(pos + sslRead); } @@ -597,7 +597,7 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc try { // Setup the BIO buffer so that we directly write the encryption results into dst. if (dst.isDirect()) { - SSL.bioSetByteBuffer(networkBIO, Buffer.address(dst) + dst.position(), dst.remaining(), + SSL.bioSetByteBuffer(networkBIO, bufferAddress(dst) + dst.position(), dst.remaining(), true); } else { bioReadCopyBuf = alloc.directBuffer(dst.remaining()); @@ -1802,6 +1802,14 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc return applicationProtocol; } + private static long bufferAddress(ByteBuffer b) { + assert b.isDirect(); + if (PlatformDependent.hasUnsafe()) { + return PlatformDependent.directBufferAddress(b); + } + return Buffer.address(b); + } + private final class OpenSslSession implements SSLSession { private final OpenSslSessionContext sessionContext;