diff --git a/buffer/src/main/java/io/netty/buffer/PooledUnsafeDirectByteBuf.java b/buffer/src/main/java/io/netty/buffer/PooledUnsafeDirectByteBuf.java index 2d3ce43640..242a653a3d 100644 --- a/buffer/src/main/java/io/netty/buffer/PooledUnsafeDirectByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/PooledUnsafeDirectByteBuf.java @@ -371,4 +371,19 @@ final class PooledUnsafeDirectByteBuf extends PooledByteBuf { } return super.newSwappedByteBuf(); } + + @Override + public ByteBuf setZero(int index, int length) { + UnsafeByteBufUtil.setZero(this, addr(index), index, length); + return this; + } + + @Override + public ByteBuf writeZero(int length) { + ensureWritable(length); + int wIndex = writerIndex; + setZero(wIndex, length); + writerIndex = wIndex + length; + return this; + } } diff --git a/buffer/src/main/java/io/netty/buffer/PooledUnsafeHeapByteBuf.java b/buffer/src/main/java/io/netty/buffer/PooledUnsafeHeapByteBuf.java index f1fad7c9e4..d06e02f0bc 100644 --- a/buffer/src/main/java/io/netty/buffer/PooledUnsafeHeapByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/PooledUnsafeHeapByteBuf.java @@ -128,6 +128,34 @@ final class PooledUnsafeHeapByteBuf extends PooledHeapByteBuf { UnsafeByteBufUtil.setLongLE(memory, idx(index), value); } + @Override + public ByteBuf setZero(int index, int length) { + if (PlatformDependent.javaVersion() >= 7) { + // Only do on java7+ as the needed Unsafe call was only added there. + _setZero(index, length); + return this; + } + return super.setZero(index, length); + } + + @Override + public ByteBuf writeZero(int length) { + if (PlatformDependent.javaVersion() >= 7) { + // Only do on java7+ as the needed Unsafe call was only added there. + ensureWritable(length); + int wIndex = writerIndex; + _setZero(wIndex, length); + writerIndex = wIndex + length; + return this; + } + return super.writeZero(length); + } + + private void _setZero(int index, int length) { + checkIndex(index, length); + UnsafeByteBufUtil.setZero(memory, idx(index), length); + } + @Override @Deprecated protected SwappedByteBuf newSwappedByteBuf() { diff --git a/buffer/src/main/java/io/netty/buffer/UnpooledUnsafeDirectByteBuf.java b/buffer/src/main/java/io/netty/buffer/UnpooledUnsafeDirectByteBuf.java index 9b55445d24..2ed83ad6f7 100644 --- a/buffer/src/main/java/io/netty/buffer/UnpooledUnsafeDirectByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/UnpooledUnsafeDirectByteBuf.java @@ -503,4 +503,19 @@ public class UnpooledUnsafeDirectByteBuf extends AbstractReferenceCountedByteBuf } return super.newSwappedByteBuf(); } + + @Override + public ByteBuf setZero(int index, int length) { + UnsafeByteBufUtil.setZero(this, addr(index), index, length); + return this; + } + + @Override + public ByteBuf writeZero(int length) { + ensureWritable(length); + int wIndex = writerIndex; + setZero(wIndex, length); + writerIndex = wIndex + length; + return this; + } } diff --git a/buffer/src/main/java/io/netty/buffer/UnpooledUnsafeHeapByteBuf.java b/buffer/src/main/java/io/netty/buffer/UnpooledUnsafeHeapByteBuf.java index 1f687d0596..d911c1fc25 100644 --- a/buffer/src/main/java/io/netty/buffer/UnpooledUnsafeHeapByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/UnpooledUnsafeHeapByteBuf.java @@ -236,6 +236,34 @@ final class UnpooledUnsafeHeapByteBuf extends UnpooledHeapByteBuf { UnsafeByteBufUtil.setLongLE(array, index, value); } + @Override + public ByteBuf setZero(int index, int length) { + if (PlatformDependent.javaVersion() >= 7) { + // Only do on java7+ as the needed Unsafe call was only added there. + _setZero(index, length); + return this; + } + return super.setZero(index, length); + } + + @Override + public ByteBuf writeZero(int length) { + if (PlatformDependent.javaVersion() >= 7) { + // Only do on java7+ as the needed Unsafe call was only added there. + ensureWritable(length); + int wIndex = writerIndex; + _setZero(wIndex, length); + writerIndex = wIndex + length; + return this; + } + return super.writeZero(length); + } + + private void _setZero(int index, int length) { + checkIndex(index, length); + UnsafeByteBufUtil.setZero(array, index, length); + } + @Override @Deprecated protected SwappedByteBuf newSwappedByteBuf() { diff --git a/buffer/src/main/java/io/netty/buffer/UnsafeByteBufUtil.java b/buffer/src/main/java/io/netty/buffer/UnsafeByteBufUtil.java index fd2f886f7c..74d72d5083 100644 --- a/buffer/src/main/java/io/netty/buffer/UnsafeByteBufUtil.java +++ b/buffer/src/main/java/io/netty/buffer/UnsafeByteBufUtil.java @@ -33,6 +33,7 @@ import static io.netty.util.internal.PlatformDependent.BIG_ENDIAN_NATIVE_ORDER; */ final class UnsafeByteBufUtil { private static final boolean UNALIGNED = PlatformDependent.isUnaligned(); + private static final byte ZERO = 0; static byte getByte(long address) { return PlatformDependent.getByte(address); @@ -451,6 +452,13 @@ final class UnsafeByteBufUtil { } } + static void setZero(byte[] array, int index, int length) { + if (length == 0) { + return; + } + PlatformDependent.setMemory(array, index, length, ZERO); + } + static ByteBuf copy(AbstractByteBuf buf, long addr, int index, int length) { buf.checkIndex(index, length); ByteBuf copy = buf.alloc().directBuffer(length, buf.maxCapacity()); @@ -602,5 +610,14 @@ final class UnsafeByteBufUtil { } } + static void setZero(AbstractByteBuf buf, long addr, int index, int length) { + if (length == 0) { + return; + } + + buf.checkIndex(index, length); + PlatformDependent.setMemory(addr, length, ZERO); + } + private UnsafeByteBufUtil() { } } diff --git a/common/src/main/java/io/netty/util/internal/PlatformDependent.java b/common/src/main/java/io/netty/util/internal/PlatformDependent.java index 6c8b59e1d7..98a4b69dc4 100644 --- a/common/src/main/java/io/netty/util/internal/PlatformDependent.java +++ b/common/src/main/java/io/netty/util/internal/PlatformDependent.java @@ -496,6 +496,14 @@ public final class PlatformDependent { PlatformDependent0.copyMemory(null, srcAddr, dst, BYTE_ARRAY_BASE_OFFSET + dstIndex, length); } + public static void setMemory(byte[] dst, int dstIndex, long bytes, byte value) { + PlatformDependent0.setMemory(dst, BYTE_ARRAY_BASE_OFFSET + dstIndex, bytes, value); + } + + public static void setMemory(long address, long bytes, byte value) { + PlatformDependent0.setMemory(address, bytes, value); + } + /** * Compare two {@code byte} arrays for equality. For performance reasons no bounds checking on the * parameters is performed. diff --git a/common/src/main/java/io/netty/util/internal/PlatformDependent0.java b/common/src/main/java/io/netty/util/internal/PlatformDependent0.java index 6964f30f01..50885273c9 100644 --- a/common/src/main/java/io/netty/util/internal/PlatformDependent0.java +++ b/common/src/main/java/io/netty/util/internal/PlatformDependent0.java @@ -322,6 +322,14 @@ final class PlatformDependent0 { } } + static void setMemory(long address, long bytes, byte value) { + UNSAFE.setMemory(address, bytes, value); + } + + static void setMemory(Object o, long offset, long bytes, byte value) { + UNSAFE.setMemory(o, offset, bytes, value); + } + static boolean equals(byte[] bytes1, int startPos1, byte[] bytes2, int startPos2, int length) { if (length == 0) { return true;