From c6bdc2b7dce0996d61a7be2bde56064b6b631cef Mon Sep 17 00:00:00 2001 From: Nick Hill Date: Sat, 16 Nov 2019 11:26:02 -0800 Subject: [PATCH] Reduce ByteBuffer duplication when resizing pooled direct ByteBufs (#9765) Motivation: Currently when use of Unsafe is disabled and an internal reallocation is performed for a direct PooledByteBuf, a one-off temporary duplicate is made of the source and destination backing nio buffers so that the copy can be done in a threadsafe manner. The need for this can be reduced by sharing the temporary duplicate buffer that is already stored in the corresponding destination PooledByteBuf instance. Modifications: Have PoolArena#memoryCopy(...) take the destination PooledByteBuf instead of the underlying mem reference and offset, and use internalNioBuffer() to obtain/initialize a reusable duplicate of the backing nio buffer. Result: Fewer temporary allocations when resizing direct pooled ByteBufs in the non-Unsafe case --- .../src/main/java/io/netty/buffer/PoolArena.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/buffer/src/main/java/io/netty/buffer/PoolArena.java b/buffer/src/main/java/io/netty/buffer/PoolArena.java index 488d3f1b7a..e1270493c2 100644 --- a/buffer/src/main/java/io/netty/buffer/PoolArena.java +++ b/buffer/src/main/java/io/netty/buffer/PoolArena.java @@ -402,7 +402,7 @@ abstract class PoolArena implements PoolArenaMetric { buf.trimIndicesToCapacity(newCapacity); bytesToCopy = newCapacity; } - memoryCopy(oldMemory, oldOffset, buf.memory, buf.offset, bytesToCopy); + memoryCopy(oldMemory, oldOffset, buf, bytesToCopy); if (freeOldMemory) { free(oldChunk, oldNioBuffer, oldHandle, oldMaxLength, buf.cache); } @@ -566,7 +566,7 @@ abstract class PoolArena implements PoolArenaMetric { protected abstract PoolChunk newChunk(int pageSize, int maxOrder, int pageShifts, int chunkSize); protected abstract PoolChunk newUnpooledChunk(int capacity); protected abstract PooledByteBuf newByteBuf(int maxCapacity); - protected abstract void memoryCopy(T src, int srcOffset, T dst, int dstOffset, int length); + protected abstract void memoryCopy(T src, int srcOffset, PooledByteBuf dst, int length); protected abstract void destroyChunk(PoolChunk chunk); @Override @@ -686,12 +686,12 @@ abstract class PoolArena implements PoolArenaMetric { } @Override - protected void memoryCopy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int length) { + protected void memoryCopy(byte[] src, int srcOffset, PooledByteBuf dst, int length) { if (length == 0) { return; } - System.arraycopy(src, srcOffset, dst, dstOffset, length); + System.arraycopy(src, srcOffset, dst.memory, dst.offset, length); } } @@ -771,7 +771,7 @@ abstract class PoolArena implements PoolArenaMetric { } @Override - protected void memoryCopy(ByteBuffer src, int srcOffset, ByteBuffer dst, int dstOffset, int length) { + protected void memoryCopy(ByteBuffer src, int srcOffset, PooledByteBuf dstBuf, int length) { if (length == 0) { return; } @@ -779,13 +779,13 @@ abstract class PoolArena implements PoolArenaMetric { if (HAS_UNSAFE) { PlatformDependent.copyMemory( PlatformDependent.directBufferAddress(src) + srcOffset, - PlatformDependent.directBufferAddress(dst) + dstOffset, length); + PlatformDependent.directBufferAddress(dstBuf.memory) + dstBuf.offset, length); } else { // We must duplicate the NIO buffers because they may be accessed by other Netty buffers. src = src.duplicate(); - dst = dst.duplicate(); + ByteBuffer dst = dstBuf.internalNioBuffer(); src.position(srcOffset).limit(srcOffset + length); - dst.position(dstOffset); + dst.position(dstBuf.offset); dst.put(src); } }