Add *UnsafeHeapByteBuf for improve performance on systems with sun.misc.Unsafe
Motivation: sun.misc.Unsafe allows us to handle heap ByteBuf in a more efficient matter. We should use special ByteBuf implementation when sun.misc.Unsafe can be used to increase performance. Modifications: - Add PooledUnsafeHeapByteBuf and UnpooledUnsafeHeapByteBuf that are used when sun.misc.Unsafe is ready to use. - Add UnsafeHeapSwappedByteBuf Result: Better performance when using heap buffers and sun.misc.Unsafe is ready to use.
This commit is contained in:
parent
f30a51b905
commit
7d4c077492
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright 2015 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you under the Apache License,
|
||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package io.netty.buffer;
|
||||
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
/**
|
||||
* Special {@link SwappedByteBuf} for {@link ByteBuf}s that is using unsafe.
|
||||
*/
|
||||
abstract class AbstractUnsafeSwappedByteBuf extends SwappedByteBuf {
|
||||
private final boolean nativeByteOrder;
|
||||
private final AbstractByteBuf wrapped;
|
||||
|
||||
AbstractUnsafeSwappedByteBuf(AbstractByteBuf buf) {
|
||||
super(buf);
|
||||
assert PlatformDependent.isUnaligned();
|
||||
wrapped = buf;
|
||||
nativeByteOrder = UnsafeByteBufUtil.BIG_ENDIAN_NATIVE_ORDER == (order() == ByteOrder.BIG_ENDIAN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final long getLong(int index) {
|
||||
wrapped.checkIndex(index, 8);
|
||||
long v = _getLong(wrapped, index);
|
||||
return nativeByteOrder ? v : Long.reverseBytes(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final float getFloat(int index) {
|
||||
return Float.intBitsToFloat(getInt(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final double getDouble(int index) {
|
||||
return Double.longBitsToDouble(getLong(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final char getChar(int index) {
|
||||
return (char) getShort(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final long getUnsignedInt(int index) {
|
||||
return getInt(index) & 0xFFFFFFFFL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getInt(int index) {
|
||||
wrapped.checkIndex0(index, 4);
|
||||
int v = _getInt(wrapped, index);
|
||||
return nativeByteOrder ? v : Integer.reverseBytes(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getUnsignedShort(int index) {
|
||||
return getShort(index) & 0xFFFF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final short getShort(int index) {
|
||||
wrapped.checkIndex0(index, 2);
|
||||
short v = _getShort(wrapped, index);
|
||||
return nativeByteOrder ? v : Short.reverseBytes(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ByteBuf setShort(int index, int value) {
|
||||
wrapped.checkIndex0(index, 2);
|
||||
_setShort(wrapped, index, nativeByteOrder ? (short) value : Short.reverseBytes((short) value));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ByteBuf setInt(int index, int value) {
|
||||
wrapped.checkIndex0(index, 4);
|
||||
_setInt(wrapped, index, nativeByteOrder ? value : Integer.reverseBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ByteBuf setLong(int index, long value) {
|
||||
wrapped.checkIndex(index, 8);
|
||||
_setLong(wrapped, index, nativeByteOrder ? value : Long.reverseBytes(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ByteBuf setChar(int index, int value) {
|
||||
setShort(index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ByteBuf setFloat(int index, float value) {
|
||||
setInt(index, Float.floatToRawIntBits(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ByteBuf setDouble(int index, double value) {
|
||||
setLong(index, Double.doubleToRawLongBits(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ByteBuf writeShort(int value) {
|
||||
wrapped.ensureWritable(2);
|
||||
_setShort(wrapped, wrapped.writerIndex, nativeByteOrder ? (short) value : Short.reverseBytes((short) value));
|
||||
wrapped.writerIndex += 2;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ByteBuf writeInt(int value) {
|
||||
wrapped.ensureWritable(4);
|
||||
_setInt(wrapped, wrapped.writerIndex, nativeByteOrder ? value : Integer.reverseBytes(value));
|
||||
wrapped.writerIndex += 4;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ByteBuf writeLong(long value) {
|
||||
wrapped.ensureWritable(8);
|
||||
_setLong(wrapped, wrapped.writerIndex, nativeByteOrder ? value : Long.reverseBytes(value));
|
||||
wrapped.writerIndex += 8;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ByteBuf writeChar(int value) {
|
||||
writeShort(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ByteBuf writeFloat(float value) {
|
||||
writeInt(Float.floatToRawIntBits(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ByteBuf writeDouble(double value) {
|
||||
writeLong(Double.doubleToRawLongBits(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
protected abstract short _getShort(AbstractByteBuf wrapped, int index);
|
||||
protected abstract int _getInt(AbstractByteBuf wrapped, int index);
|
||||
protected abstract long _getLong(AbstractByteBuf wrapped, int index);
|
||||
protected abstract void _setShort(AbstractByteBuf wrapped, int index, short value);
|
||||
protected abstract void _setInt(AbstractByteBuf wrapped, int index, int value);
|
||||
protected abstract void _setLong(AbstractByteBuf wrapped, int index, long value);
|
||||
}
|
@ -26,6 +26,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
abstract class PoolArena<T> implements PoolArenaMetric {
|
||||
static final boolean HAS_UNSAFE = PlatformDependent.hasUnsafe();
|
||||
|
||||
enum SizeClass {
|
||||
Tiny,
|
||||
@ -614,7 +615,8 @@ abstract class PoolArena<T> implements PoolArenaMetric {
|
||||
|
||||
@Override
|
||||
protected PooledByteBuf<byte[]> newByteBuf(int maxCapacity) {
|
||||
return PooledHeapByteBuf.newInstance(maxCapacity);
|
||||
return HAS_UNSAFE ? PooledUnsafeHeapByteBuf.newUnsafeInstance(maxCapacity)
|
||||
: PooledHeapByteBuf.newInstance(maxCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -629,8 +631,6 @@ abstract class PoolArena<T> implements PoolArenaMetric {
|
||||
|
||||
static final class DirectArena extends PoolArena<ByteBuffer> {
|
||||
|
||||
private static final boolean HAS_UNSAFE = PlatformDependent.hasUnsafe();
|
||||
|
||||
DirectArena(PooledByteBufAllocator parent, int pageSize, int maxOrder, int pageShifts, int chunkSize) {
|
||||
super(parent, pageSize, maxOrder, pageShifts, chunkSize);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.GatheringByteChannel;
|
||||
import java.nio.channels.ScatteringByteChannel;
|
||||
|
||||
final class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
|
||||
class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
|
||||
|
||||
private static final Recycler<PooledHeapByteBuf> RECYCLER = new Recycler<PooledHeapByteBuf>() {
|
||||
@Override
|
||||
@ -40,12 +40,12 @@ final class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
|
||||
return buf;
|
||||
}
|
||||
|
||||
private PooledHeapByteBuf(Recycler.Handle<PooledHeapByteBuf> recyclerHandle, int maxCapacity) {
|
||||
PooledHeapByteBuf(Recycler.Handle<? extends PooledHeapByteBuf> recyclerHandle, int maxCapacity) {
|
||||
super(recyclerHandle, maxCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirect() {
|
||||
public final boolean isDirect() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ final class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
|
||||
public final ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) {
|
||||
checkDstIndex(index, length, dstIndex, dst.capacity());
|
||||
if (dst.hasMemoryAddress()) {
|
||||
PlatformDependent.copyMemory(memory, idx(index), dst.memoryAddress() + dstIndex, length);
|
||||
@ -104,28 +104,28 @@ final class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
|
||||
public final ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) {
|
||||
checkDstIndex(index, length, dstIndex, dst.length);
|
||||
System.arraycopy(memory, idx(index), dst, dstIndex, length);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf getBytes(int index, ByteBuffer dst) {
|
||||
public final ByteBuf getBytes(int index, ByteBuffer dst) {
|
||||
checkIndex(index);
|
||||
dst.put(memory, idx(index), Math.min(capacity() - index, dst.remaining()));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
|
||||
public final ByteBuf getBytes(int index, OutputStream out, int length) throws IOException {
|
||||
checkIndex(index, length);
|
||||
out.write(memory, idx(index), length);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
|
||||
public final int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
|
||||
return getBytes(index, out, length, false);
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ final class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readBytes(GatheringByteChannel out, int length) throws IOException {
|
||||
public final int readBytes(GatheringByteChannel out, int length) throws IOException {
|
||||
checkReadableBytes(length);
|
||||
int readBytes = getBytes(readerIndex, out, length, true);
|
||||
readerIndex += readBytes;
|
||||
@ -192,7 +192,7 @@ final class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
|
||||
public final ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) {
|
||||
checkSrcIndex(index, length, srcIndex, src.capacity());
|
||||
if (src.hasMemoryAddress()) {
|
||||
PlatformDependent.copyMemory(src.memoryAddress() + srcIndex, memory, idx(index), length);
|
||||
@ -205,14 +205,14 @@ final class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
|
||||
public final ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) {
|
||||
checkSrcIndex(index, length, srcIndex, src.length);
|
||||
System.arraycopy(src, srcIndex, memory, idx(index), length);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setBytes(int index, ByteBuffer src) {
|
||||
public final ByteBuf setBytes(int index, ByteBuffer src) {
|
||||
int length = src.remaining();
|
||||
checkIndex(index, length);
|
||||
src.get(memory, idx(index), length);
|
||||
@ -220,13 +220,13 @@ final class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setBytes(int index, InputStream in, int length) throws IOException {
|
||||
public final int setBytes(int index, InputStream in, int length) throws IOException {
|
||||
checkIndex(index, length);
|
||||
return in.read(memory, idx(index), length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
|
||||
public final int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
|
||||
checkIndex(index, length);
|
||||
index = idx(index);
|
||||
try {
|
||||
@ -237,7 +237,7 @@ final class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf copy(int index, int length) {
|
||||
public final ByteBuf copy(int index, int length) {
|
||||
checkIndex(index, length);
|
||||
ByteBuf copy = alloc().heapBuffer(length, maxCapacity());
|
||||
copy.writeBytes(memory, idx(index), length);
|
||||
@ -245,17 +245,17 @@ final class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nioBufferCount() {
|
||||
public final int nioBufferCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer[] nioBuffers(int index, int length) {
|
||||
public final ByteBuffer[] nioBuffers(int index, int length) {
|
||||
return new ByteBuffer[] { nioBuffer(index, length) };
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer nioBuffer(int index, int length) {
|
||||
public final ByteBuffer nioBuffer(int index, int length) {
|
||||
checkIndex(index, length);
|
||||
index = idx(index);
|
||||
ByteBuffer buf = ByteBuffer.wrap(memory, index, length);
|
||||
@ -263,40 +263,40 @@ final class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer internalNioBuffer(int index, int length) {
|
||||
public final ByteBuffer internalNioBuffer(int index, int length) {
|
||||
checkIndex(index, length);
|
||||
index = idx(index);
|
||||
return (ByteBuffer) internalNioBuffer().clear().position(index).limit(index + length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasArray() {
|
||||
public final boolean hasArray() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] array() {
|
||||
public final byte[] array() {
|
||||
ensureAccessible();
|
||||
return memory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int arrayOffset() {
|
||||
public final int arrayOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMemoryAddress() {
|
||||
public final boolean hasMemoryAddress() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long memoryAddress() {
|
||||
public final long memoryAddress() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ByteBuffer newInternalNioBuffer(byte[] memory) {
|
||||
protected final ByteBuffer newInternalNioBuffer(byte[] memory) {
|
||||
return ByteBuffer.wrap(memory);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2015 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file tothe License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package io.netty.buffer;
|
||||
|
||||
import io.netty.util.Recycler;
|
||||
import io.netty.util.Recycler.Handle;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
|
||||
final class PooledUnsafeHeapByteBuf extends PooledHeapByteBuf {
|
||||
|
||||
private static final Recycler<PooledUnsafeHeapByteBuf> RECYCLER = new Recycler<PooledUnsafeHeapByteBuf>() {
|
||||
@Override
|
||||
protected PooledUnsafeHeapByteBuf newObject(Handle<PooledUnsafeHeapByteBuf> handle) {
|
||||
return new PooledUnsafeHeapByteBuf(handle, 0);
|
||||
}
|
||||
};
|
||||
|
||||
static PooledUnsafeHeapByteBuf newUnsafeInstance(int maxCapacity) {
|
||||
PooledUnsafeHeapByteBuf buf = RECYCLER.get();
|
||||
buf.reuse(maxCapacity);
|
||||
return buf;
|
||||
}
|
||||
|
||||
private PooledUnsafeHeapByteBuf(Handle<PooledUnsafeHeapByteBuf> recyclerHandle, int maxCapacity) {
|
||||
super(recyclerHandle, maxCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte _getByte(int index) {
|
||||
return UnsafeByteBufUtil.getByte(memory, idx(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected short _getShort(int index) {
|
||||
return UnsafeByteBufUtil.getShort(memory, idx(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int _getUnsignedMedium(int index) {
|
||||
return UnsafeByteBufUtil.getUnsignedMedium(memory, idx(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int _getInt(int index) {
|
||||
return UnsafeByteBufUtil.getInt(memory, idx(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long _getLong(int index) {
|
||||
return UnsafeByteBufUtil.getLong(memory, idx(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setByte(int index, int value) {
|
||||
UnsafeByteBufUtil.setByte(memory, idx(index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setShort(int index, int value) {
|
||||
UnsafeByteBufUtil.setShort(memory, idx(index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setMedium(int index, int value) {
|
||||
UnsafeByteBufUtil.setMedium(memory, idx(index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setInt(int index, int value) {
|
||||
UnsafeByteBufUtil.setInt(memory, idx(index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setLong(int index, long value) {
|
||||
UnsafeByteBufUtil.setLong(memory, idx(index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SwappedByteBuf newSwappedByteBuf() {
|
||||
if (PlatformDependent.isUnaligned()) {
|
||||
// Only use if unaligned access is supported otherwise there is no gain.
|
||||
return new UnsafeHeapSwappedByteBuf(this);
|
||||
}
|
||||
return super.newSwappedByteBuf();
|
||||
}
|
||||
}
|
@ -40,7 +40,8 @@ public final class UnpooledByteBufAllocator extends AbstractByteBufAllocator {
|
||||
|
||||
@Override
|
||||
protected ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity) {
|
||||
return new UnpooledHeapByteBuf(this, initialCapacity, maxCapacity);
|
||||
return PlatformDependent.hasUnsafe() ? new UnpooledUnsafeHeapByteBuf(this, initialCapacity, maxCapacity)
|
||||
: new UnpooledHeapByteBuf(this, initialCapacity, maxCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,7 +32,7 @@ import java.nio.channels.ScatteringByteChannel;
|
||||
public class UnpooledHeapByteBuf extends AbstractReferenceCountedByteBuf {
|
||||
|
||||
private final ByteBufAllocator alloc;
|
||||
private byte[] array;
|
||||
byte[] array;
|
||||
private ByteBuffer tmpNioBuf;
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2015 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you under the Apache License,
|
||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package io.netty.buffer;
|
||||
|
||||
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
|
||||
final class UnpooledUnsafeHeapByteBuf extends UnpooledHeapByteBuf {
|
||||
|
||||
/**
|
||||
* Creates a new heap buffer with a newly allocated byte array.
|
||||
*
|
||||
* @param initialCapacity the initial capacity of the underlying byte array
|
||||
* @param maxCapacity the max capacity of the underlying byte array
|
||||
*/
|
||||
UnpooledUnsafeHeapByteBuf(ByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
|
||||
super(alloc, initialCapacity, maxCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getByte(int index) {
|
||||
checkIndex(index);
|
||||
return _getByte(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte _getByte(int index) {
|
||||
return UnsafeByteBufUtil.getByte(array, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getShort(int index) {
|
||||
checkIndex(index, 2);
|
||||
return _getShort(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected short _getShort(int index) {
|
||||
return UnsafeByteBufUtil.getShort(array, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUnsignedMedium(int index) {
|
||||
checkIndex(index, 3);
|
||||
return _getUnsignedMedium(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int _getUnsignedMedium(int index) {
|
||||
return UnsafeByteBufUtil.getUnsignedMedium(array, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(int index) {
|
||||
checkIndex(index, 4);
|
||||
return _getInt(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int _getInt(int index) {
|
||||
return UnsafeByteBufUtil.getInt(array, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(int index) {
|
||||
checkIndex(index, 8);
|
||||
return _getLong(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long _getLong(int index) {
|
||||
return UnsafeByteBufUtil.getLong(array, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setByte(int index, int value) {
|
||||
checkIndex(index);
|
||||
_setByte(index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setByte(int index, int value) {
|
||||
UnsafeByteBufUtil.setByte(array, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setShort(int index, int value) {
|
||||
checkIndex(index, 2);
|
||||
_setShort(index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setShort(int index, int value) {
|
||||
UnsafeByteBufUtil.setShort(array, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setMedium(int index, int value) {
|
||||
checkIndex(index, 3);
|
||||
_setMedium(index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setMedium(int index, int value) {
|
||||
UnsafeByteBufUtil.setMedium(array, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setInt(int index, int value) {
|
||||
checkIndex(index, 4);
|
||||
_setInt(index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setInt(int index, int value) {
|
||||
UnsafeByteBufUtil.setInt(array, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setLong(int index, long value) {
|
||||
checkIndex(index, 8);
|
||||
_setLong(index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setLong(int index, long value) {
|
||||
UnsafeByteBufUtil.setLong(array, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SwappedByteBuf newSwappedByteBuf() {
|
||||
if (PlatformDependent.isUnaligned()) {
|
||||
// Only use if unaligned access is supported otherwise there is no gain.
|
||||
return new UnsafeHeapSwappedByteBuf(this);
|
||||
}
|
||||
return super.newSwappedByteBuf();
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@ import java.nio.ByteOrder;
|
||||
*/
|
||||
final class UnsafeByteBufUtil {
|
||||
|
||||
private static final boolean NATIVE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
|
||||
static final boolean BIG_ENDIAN_NATIVE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
|
||||
private static final boolean UNALIGNED = PlatformDependent.isUnaligned();
|
||||
|
||||
static byte getByte(long address) {
|
||||
@ -34,14 +34,14 @@ final class UnsafeByteBufUtil {
|
||||
static short getShort(long address) {
|
||||
if (UNALIGNED) {
|
||||
short v = PlatformDependent.getShort(address);
|
||||
return NATIVE_ORDER ? v : Short.reverseBytes(v);
|
||||
return BIG_ENDIAN_NATIVE_ORDER ? v : Short.reverseBytes(v);
|
||||
}
|
||||
return (short) (PlatformDependent.getByte(address) << 8 | PlatformDependent.getByte(address + 1) & 0xff);
|
||||
}
|
||||
|
||||
static int getUnsignedMedium(long address) {
|
||||
if (UNALIGNED) {
|
||||
if (NATIVE_ORDER) {
|
||||
if (BIG_ENDIAN_NATIVE_ORDER) {
|
||||
return (PlatformDependent.getByte(address) & 0xff) |
|
||||
(PlatformDependent.getShort(address + 1) & 0xffff) << 8;
|
||||
}
|
||||
@ -56,7 +56,7 @@ final class UnsafeByteBufUtil {
|
||||
static int getInt(long address) {
|
||||
if (UNALIGNED) {
|
||||
int v = PlatformDependent.getInt(address);
|
||||
return NATIVE_ORDER ? v : Integer.reverseBytes(v);
|
||||
return BIG_ENDIAN_NATIVE_ORDER ? v : Integer.reverseBytes(v);
|
||||
}
|
||||
return PlatformDependent.getByte(address) << 24 |
|
||||
(PlatformDependent.getByte(address + 1) & 0xff) << 16 |
|
||||
@ -67,7 +67,7 @@ final class UnsafeByteBufUtil {
|
||||
static long getLong(long address) {
|
||||
if (UNALIGNED) {
|
||||
long v = PlatformDependent.getLong(address);
|
||||
return NATIVE_ORDER ? v : Long.reverseBytes(v);
|
||||
return BIG_ENDIAN_NATIVE_ORDER ? v : Long.reverseBytes(v);
|
||||
}
|
||||
return (long) PlatformDependent.getByte(address) << 56 |
|
||||
((long) PlatformDependent.getByte(address + 1) & 0xff) << 48 |
|
||||
@ -85,7 +85,8 @@ final class UnsafeByteBufUtil {
|
||||
|
||||
static void setShort(long address, int value) {
|
||||
if (UNALIGNED) {
|
||||
PlatformDependent.putShort(address, NATIVE_ORDER ? (short) value : Short.reverseBytes((short) value));
|
||||
PlatformDependent.putShort(
|
||||
address, BIG_ENDIAN_NATIVE_ORDER ? (short) value : Short.reverseBytes((short) value));
|
||||
} else {
|
||||
PlatformDependent.putByte(address, (byte) (value >>> 8));
|
||||
PlatformDependent.putByte(address + 1, (byte) value);
|
||||
@ -94,7 +95,7 @@ final class UnsafeByteBufUtil {
|
||||
|
||||
static void setMedium(long address, int value) {
|
||||
if (UNALIGNED) {
|
||||
if (NATIVE_ORDER) {
|
||||
if (BIG_ENDIAN_NATIVE_ORDER) {
|
||||
PlatformDependent.putByte(address, (byte) value);
|
||||
PlatformDependent.putShort(address + 1, (short) (value >>> 8));
|
||||
} else {
|
||||
@ -110,7 +111,7 @@ final class UnsafeByteBufUtil {
|
||||
|
||||
static void setInt(long address, int value) {
|
||||
if (UNALIGNED) {
|
||||
PlatformDependent.putInt(address, NATIVE_ORDER ? value : Integer.reverseBytes(value));
|
||||
PlatformDependent.putInt(address, BIG_ENDIAN_NATIVE_ORDER ? value : Integer.reverseBytes(value));
|
||||
} else {
|
||||
PlatformDependent.putByte(address, (byte) (value >>> 24));
|
||||
PlatformDependent.putByte(address + 1, (byte) (value >>> 16));
|
||||
@ -121,7 +122,7 @@ final class UnsafeByteBufUtil {
|
||||
|
||||
static void setLong(long address, long value) {
|
||||
if (UNALIGNED) {
|
||||
PlatformDependent.putLong(address, NATIVE_ORDER ? value : Long.reverseBytes(value));
|
||||
PlatformDependent.putLong(address, BIG_ENDIAN_NATIVE_ORDER ? value : Long.reverseBytes(value));
|
||||
} else {
|
||||
PlatformDependent.putByte(address, (byte) (value >>> 56));
|
||||
PlatformDependent.putByte(address + 1, (byte) (value >>> 48));
|
||||
@ -134,5 +135,113 @@ final class UnsafeByteBufUtil {
|
||||
}
|
||||
}
|
||||
|
||||
static byte getByte(byte[] array, int index) {
|
||||
return PlatformDependent.getByte(array, index);
|
||||
}
|
||||
|
||||
static short getShort(byte[] array, int index) {
|
||||
if (UNALIGNED) {
|
||||
short v = PlatformDependent.getShort(array, index);
|
||||
return BIG_ENDIAN_NATIVE_ORDER ? v : Short.reverseBytes(v);
|
||||
}
|
||||
return (short) (PlatformDependent.getByte(index) << 8 | PlatformDependent.getByte(index + 1) & 0xff);
|
||||
}
|
||||
|
||||
static int getUnsignedMedium(byte[] array, int index) {
|
||||
if (UNALIGNED) {
|
||||
if (BIG_ENDIAN_NATIVE_ORDER) {
|
||||
return (PlatformDependent.getByte(array, index) & 0xff) |
|
||||
(PlatformDependent.getShort(array, index + 1) & 0xffff) << 8;
|
||||
}
|
||||
return (Short.reverseBytes(PlatformDependent.getShort(array, index)) & 0xffff) << 8 |
|
||||
PlatformDependent.getByte(array, index + 2) & 0xff;
|
||||
}
|
||||
return (PlatformDependent.getByte(array, index) & 0xff) << 16 |
|
||||
(PlatformDependent.getByte(array, index + 1) & 0xff) << 8 |
|
||||
PlatformDependent.getByte(array, index + 2) & 0xff;
|
||||
}
|
||||
|
||||
static int getInt(byte[] array, int index) {
|
||||
if (UNALIGNED) {
|
||||
int v = PlatformDependent.getInt(array, index);
|
||||
return BIG_ENDIAN_NATIVE_ORDER ? v : Integer.reverseBytes(v);
|
||||
}
|
||||
return PlatformDependent.getByte(array, index) << 24 |
|
||||
(PlatformDependent.getByte(array, index + 1) & 0xff) << 16 |
|
||||
(PlatformDependent.getByte(array, index + 2) & 0xff) << 8 |
|
||||
PlatformDependent.getByte(array, index + 3) & 0xff;
|
||||
}
|
||||
|
||||
static long getLong(byte[] array, int index) {
|
||||
if (UNALIGNED) {
|
||||
long v = PlatformDependent.getLong(array, index);
|
||||
return BIG_ENDIAN_NATIVE_ORDER ? v : Long.reverseBytes(v);
|
||||
}
|
||||
return (long) PlatformDependent.getByte(array, index) << 56 |
|
||||
((long) PlatformDependent.getByte(array, index + 1) & 0xff) << 48 |
|
||||
((long) PlatformDependent.getByte(array, index + 2) & 0xff) << 40 |
|
||||
((long) PlatformDependent.getByte(array, index + 3) & 0xff) << 32 |
|
||||
((long) PlatformDependent.getByte(array, index + 4) & 0xff) << 24 |
|
||||
((long) PlatformDependent.getByte(array, index + 5) & 0xff) << 16 |
|
||||
((long) PlatformDependent.getByte(array, index + 6) & 0xff) << 8 |
|
||||
(long) PlatformDependent.getByte(array, index + 7) & 0xff;
|
||||
}
|
||||
|
||||
static void setByte(byte[] array, int index, int value) {
|
||||
PlatformDependent.putByte(array, index, (byte) value);
|
||||
}
|
||||
|
||||
static void setShort(byte[] array, int index, int value) {
|
||||
if (UNALIGNED) {
|
||||
PlatformDependent.putShort(
|
||||
array, index, BIG_ENDIAN_NATIVE_ORDER ? (short) value : Short.reverseBytes((short) value));
|
||||
} else {
|
||||
PlatformDependent.putByte(array, index, (byte) (value >>> 8));
|
||||
PlatformDependent.putByte(array, index + 1, (byte) value);
|
||||
}
|
||||
}
|
||||
|
||||
static void setMedium(byte[] array, int index, int value) {
|
||||
if (UNALIGNED) {
|
||||
if (BIG_ENDIAN_NATIVE_ORDER) {
|
||||
PlatformDependent.putByte(array, index, (byte) value);
|
||||
PlatformDependent.putShort(array, index + 1, (short) (value >>> 8));
|
||||
} else {
|
||||
PlatformDependent.putShort(array, index, Short.reverseBytes((short) (value >>> 8)));
|
||||
PlatformDependent.putByte(array, index + 2, (byte) value);
|
||||
}
|
||||
} else {
|
||||
PlatformDependent.putByte(array, index, (byte) (value >>> 16));
|
||||
PlatformDependent.putByte(array, index + 1, (byte) (value >>> 8));
|
||||
PlatformDependent.putByte(array, index + 2, (byte) value);
|
||||
}
|
||||
}
|
||||
|
||||
static void setInt(byte[] array, int index, int value) {
|
||||
if (UNALIGNED) {
|
||||
PlatformDependent.putInt(array, index, BIG_ENDIAN_NATIVE_ORDER ? value : Integer.reverseBytes(value));
|
||||
} else {
|
||||
PlatformDependent.putByte(array, index, (byte) (value >>> 24));
|
||||
PlatformDependent.putByte(array, index + 1, (byte) (value >>> 16));
|
||||
PlatformDependent.putByte(array, index + 2, (byte) (value >>> 8));
|
||||
PlatformDependent.putByte(array, index + 3, (byte) value);
|
||||
}
|
||||
}
|
||||
|
||||
static void setLong(byte[] array, int index, long value) {
|
||||
if (UNALIGNED) {
|
||||
PlatformDependent.putLong(array, index, BIG_ENDIAN_NATIVE_ORDER ? value : Long.reverseBytes(value));
|
||||
} else {
|
||||
PlatformDependent.putByte(array, index, (byte) (value >>> 56));
|
||||
PlatformDependent.putByte(array, index + 1, (byte) (value >>> 48));
|
||||
PlatformDependent.putByte(array, index + 2, (byte) (value >>> 40));
|
||||
PlatformDependent.putByte(array, index + 3, (byte) (value >>> 32));
|
||||
PlatformDependent.putByte(array, index + 4, (byte) (value >>> 24));
|
||||
PlatformDependent.putByte(array, index + 5, (byte) (value >>> 16));
|
||||
PlatformDependent.putByte(array, index + 6, (byte) (value >>> 8));
|
||||
PlatformDependent.putByte(array, index + 7, (byte) value);
|
||||
}
|
||||
}
|
||||
|
||||
private UnsafeByteBufUtil() { }
|
||||
}
|
||||
|
@ -18,24 +18,16 @@ package io.netty.buffer;
|
||||
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
/**
|
||||
* Special {@link SwappedByteBuf} for {@link ByteBuf}s that are backed by a {@code memoryAddress}.
|
||||
*/
|
||||
final class UnsafeDirectSwappedByteBuf extends SwappedByteBuf {
|
||||
private static final boolean NATIVE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
|
||||
private final boolean nativeByteOrder;
|
||||
private final AbstractByteBuf wrapped;
|
||||
final class UnsafeDirectSwappedByteBuf extends AbstractUnsafeSwappedByteBuf {
|
||||
|
||||
UnsafeDirectSwappedByteBuf(AbstractByteBuf buf) {
|
||||
super(buf);
|
||||
assert PlatformDependent.isUnaligned();
|
||||
wrapped = buf;
|
||||
nativeByteOrder = NATIVE_ORDER == (order() == ByteOrder.BIG_ENDIAN);
|
||||
}
|
||||
|
||||
private long addr(int index) {
|
||||
private static long addr(AbstractByteBuf wrapped, int index) {
|
||||
// We need to call wrapped.memoryAddress() everytime and NOT cache it as it may change if the buffer expand.
|
||||
// See:
|
||||
// - https://github.com/netty/netty/issues/2587
|
||||
@ -44,144 +36,32 @@ final class UnsafeDirectSwappedByteBuf extends SwappedByteBuf {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(int index) {
|
||||
wrapped.checkIndex(index, 8);
|
||||
long v = PlatformDependent.getLong(addr(index));
|
||||
return nativeByteOrder? v : Long.reverseBytes(v);
|
||||
protected long _getLong(AbstractByteBuf wrapped, int index) {
|
||||
return PlatformDependent.getLong(addr(wrapped, index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFloat(int index) {
|
||||
return Float.intBitsToFloat(getInt(index));
|
||||
protected int _getInt(AbstractByteBuf wrapped, int index) {
|
||||
return PlatformDependent.getInt(addr(wrapped, index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble(int index) {
|
||||
return Double.longBitsToDouble(getLong(index));
|
||||
protected short _getShort(AbstractByteBuf wrapped, int index) {
|
||||
return PlatformDependent.getShort(addr(wrapped, index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public char getChar(int index) {
|
||||
return (char) getShort(index);
|
||||
protected void _setShort(AbstractByteBuf wrapped, int index, short value) {
|
||||
PlatformDependent.putShort(addr(wrapped, index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getUnsignedInt(int index) {
|
||||
return getInt(index) & 0xFFFFFFFFL;
|
||||
protected void _setInt(AbstractByteBuf wrapped, int index, int value) {
|
||||
PlatformDependent.putInt(addr(wrapped, index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(int index) {
|
||||
wrapped.checkIndex(index, 4);
|
||||
int v = PlatformDependent.getInt(addr(index));
|
||||
return nativeByteOrder? v : Integer.reverseBytes(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUnsignedShort(int index) {
|
||||
return getShort(index) & 0xFFFF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getShort(int index) {
|
||||
wrapped.checkIndex(index, 2);
|
||||
short v = PlatformDependent.getShort(addr(index));
|
||||
return nativeByteOrder? v : Short.reverseBytes(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setShort(int index, int value) {
|
||||
wrapped.checkIndex(index, 2);
|
||||
_setShort(index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setInt(int index, int value) {
|
||||
wrapped.checkIndex(index, 4);
|
||||
_setInt(index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setLong(int index, long value) {
|
||||
wrapped.checkIndex(index, 8);
|
||||
_setLong(index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setChar(int index, int value) {
|
||||
setShort(index, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setFloat(int index, float value) {
|
||||
setInt(index, Float.floatToRawIntBits(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf setDouble(int index, double value) {
|
||||
setLong(index, Double.doubleToRawLongBits(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf writeShort(int value) {
|
||||
wrapped.ensureAccessible();
|
||||
wrapped.ensureWritable(2);
|
||||
_setShort(wrapped.writerIndex, value);
|
||||
wrapped.writerIndex += 2;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf writeInt(int value) {
|
||||
wrapped.ensureAccessible();
|
||||
wrapped.ensureWritable(4);
|
||||
_setInt(wrapped.writerIndex, value);
|
||||
wrapped.writerIndex += 4;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf writeLong(long value) {
|
||||
wrapped.ensureAccessible();
|
||||
wrapped.ensureWritable(8);
|
||||
_setLong(wrapped.writerIndex, value);
|
||||
wrapped.writerIndex += 8;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf writeChar(int value) {
|
||||
writeShort(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf writeFloat(float value) {
|
||||
writeInt(Float.floatToRawIntBits(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuf writeDouble(double value) {
|
||||
writeLong(Double.doubleToRawLongBits(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
private void _setShort(int index, int value) {
|
||||
PlatformDependent.putShort(addr(index), nativeByteOrder ? (short) value : Short.reverseBytes((short) value));
|
||||
}
|
||||
|
||||
private void _setInt(int index, int value) {
|
||||
PlatformDependent.putInt(addr(index), nativeByteOrder ? value : Integer.reverseBytes(value));
|
||||
}
|
||||
|
||||
private void _setLong(int index, long value) {
|
||||
PlatformDependent.putLong(addr(index), nativeByteOrder ? value : Long.reverseBytes(value));
|
||||
protected void _setLong(AbstractByteBuf wrapped, int index, long value) {
|
||||
PlatformDependent.putLong(addr(wrapped, index), value);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2014 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you under the Apache License,
|
||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package io.netty.buffer;
|
||||
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
|
||||
/**
|
||||
* Special {@link SwappedByteBuf} for {@link ByteBuf}s that use unsafe to access the byte array.
|
||||
*/
|
||||
final class UnsafeHeapSwappedByteBuf extends AbstractUnsafeSwappedByteBuf {
|
||||
|
||||
UnsafeHeapSwappedByteBuf(AbstractByteBuf buf) {
|
||||
super(buf);
|
||||
}
|
||||
|
||||
private static int idx(ByteBuf wrapped, int index) {
|
||||
return wrapped.arrayOffset() + index;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long _getLong(AbstractByteBuf wrapped, int index) {
|
||||
return PlatformDependent.getLong(wrapped.array(), idx(wrapped, index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int _getInt(AbstractByteBuf wrapped, int index) {
|
||||
return PlatformDependent.getInt(wrapped.array(), idx(wrapped, index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected short _getShort(AbstractByteBuf wrapped, int index) {
|
||||
return PlatformDependent.getShort(wrapped.array(), idx(wrapped, index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setShort(AbstractByteBuf wrapped, int index, short value) {
|
||||
PlatformDependent.putShort(wrapped.array(), idx(wrapped, index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setInt(AbstractByteBuf wrapped, int index, int value) {
|
||||
PlatformDependent.putInt(wrapped.array(), idx(wrapped, index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setLong(AbstractByteBuf wrapped, int index, long value) {
|
||||
PlatformDependent.putLong(wrapped.array(), idx(wrapped, index), value);
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ import java.lang.reflect.Method;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@ -77,7 +78,7 @@ public final class PlatformDependent {
|
||||
HAS_UNSAFE && !SystemPropertyUtil.getBoolean("io.netty.noPreferDirect", false);
|
||||
private static final long MAX_DIRECT_MEMORY = maxDirectMemory0();
|
||||
|
||||
private static final long ARRAY_BASE_OFFSET = PlatformDependent0.arrayBaseOffset();
|
||||
private static final long BYTE_ARRAY_BASE_OFFSET = PlatformDependent0.byteArrayBaseOffset();
|
||||
|
||||
private static final boolean HAS_JAVASSIST = hasJavassist0();
|
||||
|
||||
@ -86,6 +87,7 @@ public final class PlatformDependent {
|
||||
private static final int BIT_MODE = bitMode0();
|
||||
|
||||
private static final int ADDRESS_SIZE = addressSize0();
|
||||
private static final boolean NATIVE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
|
||||
|
||||
static {
|
||||
if (logger.isDebugEnabled()) {
|
||||
@ -343,6 +345,22 @@ public final class PlatformDependent {
|
||||
return PlatformDependent0.getLong(address);
|
||||
}
|
||||
|
||||
public static byte getByte(byte[] data, int index) {
|
||||
return PlatformDependent0.getByte(data, index);
|
||||
}
|
||||
|
||||
public static short getShort(byte[] data, int index) {
|
||||
return PlatformDependent0.getShort(data, index);
|
||||
}
|
||||
|
||||
public static int getInt(byte[] data, int index) {
|
||||
return PlatformDependent0.getInt(data, index);
|
||||
}
|
||||
|
||||
public static long getLong(byte[] data, int index) {
|
||||
return PlatformDependent0.getLong(data, index);
|
||||
}
|
||||
|
||||
public static void putOrderedObject(Object object, long address, Object value) {
|
||||
PlatformDependent0.putOrderedObject(object, address, value);
|
||||
}
|
||||
@ -363,16 +381,32 @@ public final class PlatformDependent {
|
||||
PlatformDependent0.putLong(address, value);
|
||||
}
|
||||
|
||||
public static void putByte(byte[] data, int index, byte value) {
|
||||
PlatformDependent0.putByte(data, index, value);
|
||||
}
|
||||
|
||||
public static void putShort(byte[] data, int index, short value) {
|
||||
PlatformDependent0.putShort(data, index, value);
|
||||
}
|
||||
|
||||
public static void putInt(byte[] data, int index, int value) {
|
||||
PlatformDependent0.putInt(data, index, value);
|
||||
}
|
||||
|
||||
public static void putLong(byte[] data, int index, long value) {
|
||||
PlatformDependent0.putLong(data, index, value);
|
||||
}
|
||||
|
||||
public static void copyMemory(long srcAddr, long dstAddr, long length) {
|
||||
PlatformDependent0.copyMemory(srcAddr, dstAddr, length);
|
||||
}
|
||||
|
||||
public static void copyMemory(byte[] src, int srcIndex, long dstAddr, long length) {
|
||||
PlatformDependent0.copyMemory(src, ARRAY_BASE_OFFSET + srcIndex, null, dstAddr, length);
|
||||
PlatformDependent0.copyMemory(src, BYTE_ARRAY_BASE_OFFSET + srcIndex, null, dstAddr, length);
|
||||
}
|
||||
|
||||
public static void copyMemory(long srcAddr, byte[] dst, int dstIndex, long length) {
|
||||
PlatformDependent0.copyMemory(null, srcAddr, dst, ARRAY_BASE_OFFSET + dstIndex, length);
|
||||
PlatformDependent0.copyMemory(null, srcAddr, dst, BYTE_ARRAY_BASE_OFFSET + dstIndex, length);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -39,7 +39,7 @@ final class PlatformDependent0 {
|
||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(PlatformDependent0.class);
|
||||
static final Unsafe UNSAFE;
|
||||
private static final long ADDRESS_FIELD_OFFSET;
|
||||
private static final long ARRAY_BASE_OFFSET;
|
||||
private static final long BYTE_ARRAY_BASE_OFFSET;
|
||||
|
||||
/**
|
||||
* Limits the number of bytes to copy per {@link Unsafe#copyMemory(long, long, long)} to allow safepoint polling
|
||||
@ -108,11 +108,11 @@ final class PlatformDependent0 {
|
||||
|
||||
if (unsafe == null) {
|
||||
ADDRESS_FIELD_OFFSET = -1;
|
||||
ARRAY_BASE_OFFSET = -1;
|
||||
BYTE_ARRAY_BASE_OFFSET = -1;
|
||||
UNALIGNED = false;
|
||||
} else {
|
||||
ADDRESS_FIELD_OFFSET = objectFieldOffset(addressField);
|
||||
ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset(byte[].class);
|
||||
BYTE_ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset(byte[].class);
|
||||
boolean unaligned;
|
||||
try {
|
||||
Class<?> bitsClass = Class.forName("java.nio.Bits", false, ClassLoader.getSystemClassLoader());
|
||||
@ -158,8 +158,8 @@ final class PlatformDependent0 {
|
||||
return getLong(buffer, ADDRESS_FIELD_OFFSET);
|
||||
}
|
||||
|
||||
static long arrayBaseOffset() {
|
||||
return ARRAY_BASE_OFFSET;
|
||||
static long byteArrayBaseOffset() {
|
||||
return BYTE_ARRAY_BASE_OFFSET;
|
||||
}
|
||||
|
||||
static Object getObject(Object object, long fieldOffset) {
|
||||
@ -198,6 +198,22 @@ final class PlatformDependent0 {
|
||||
return UNSAFE.getLong(address);
|
||||
}
|
||||
|
||||
static byte getByte(byte[] data, int index) {
|
||||
return UNSAFE.getByte(data, BYTE_ARRAY_BASE_OFFSET + index);
|
||||
}
|
||||
|
||||
static short getShort(byte[] data, int index) {
|
||||
return UNSAFE.getShort(data, BYTE_ARRAY_BASE_OFFSET + index);
|
||||
}
|
||||
|
||||
static int getInt(byte[] data, int index) {
|
||||
return UNSAFE.getInt(data, BYTE_ARRAY_BASE_OFFSET + index);
|
||||
}
|
||||
|
||||
static long getLong(byte[] data, int index) {
|
||||
return UNSAFE.getLong(data, BYTE_ARRAY_BASE_OFFSET + index);
|
||||
}
|
||||
|
||||
static void putOrderedObject(Object object, long address, Object value) {
|
||||
UNSAFE.putOrderedObject(object, address, value);
|
||||
}
|
||||
@ -218,6 +234,22 @@ final class PlatformDependent0 {
|
||||
UNSAFE.putLong(address, value);
|
||||
}
|
||||
|
||||
static void putByte(byte[] data, int index, byte value) {
|
||||
UNSAFE.putByte(data, BYTE_ARRAY_BASE_OFFSET + index, value);
|
||||
}
|
||||
|
||||
static void putShort(byte[] data, int index, short value) {
|
||||
UNSAFE.putShort(data, BYTE_ARRAY_BASE_OFFSET + index, value);
|
||||
}
|
||||
|
||||
static void putInt(byte[] data, int index, int value) {
|
||||
UNSAFE.putInt(data, BYTE_ARRAY_BASE_OFFSET + index, value);
|
||||
}
|
||||
|
||||
static void putLong(byte[] data, int index, long value) {
|
||||
UNSAFE.putLong(data, BYTE_ARRAY_BASE_OFFSET + index, value);
|
||||
}
|
||||
|
||||
static void copyMemory(long srcAddr, long dstAddr, long length) {
|
||||
//UNSAFE.copyMemory(srcAddr, dstAddr, length);
|
||||
while (length > 0) {
|
||||
@ -249,8 +281,8 @@ final class PlatformDependent0 {
|
||||
if (len1 == 0) {
|
||||
return true;
|
||||
}
|
||||
final long baseOffset1 = ARRAY_BASE_OFFSET + startPos1;
|
||||
final long baseOffset2 = ARRAY_BASE_OFFSET + startPos2;
|
||||
final long baseOffset1 = BYTE_ARRAY_BASE_OFFSET + startPos1;
|
||||
final long baseOffset2 = BYTE_ARRAY_BASE_OFFSET + startPos2;
|
||||
int remainingBytes = len1 & 7;
|
||||
for (int i = len1 - 8; i >= remainingBytes; i -= 8) {
|
||||
if (UNSAFE.getLong(bytes1, baseOffset1 + i) != UNSAFE.getLong(bytes2, baseOffset2 + i)) {
|
||||
|
Loading…
Reference in New Issue
Block a user