Correctly handle byte shifting if system does not support unaligned access.
Motivation: We had a bug in our implemention which double "reversed" bytes on systems which not support unaligned access. Modifications: - Correctly only reverse bytes if needed. - Share code between unsafe implementations. Result: No more data-corruption on sytems without unaligned access.
This commit is contained in:
parent
27c68647df
commit
f30a51b905
@ -23,15 +23,11 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.GatheringByteChannel;
|
||||
import java.nio.channels.ScatteringByteChannel;
|
||||
|
||||
final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
|
||||
|
||||
private static final boolean NATIVE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
|
||||
|
||||
private static final Recycler<PooledUnsafeDirectByteBuf> RECYCLER = new Recycler<PooledUnsafeDirectByteBuf>() {
|
||||
@Override
|
||||
protected PooledUnsafeDirectByteBuf newObject(Handle<PooledUnsafeDirectByteBuf> handle) {
|
||||
@ -80,33 +76,27 @@ final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
|
||||
|
||||
@Override
|
||||
protected byte _getByte(int index) {
|
||||
return PlatformDependent.getByte(addr(index));
|
||||
return UnsafeByteBufUtil.getByte(addr(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected short _getShort(int index) {
|
||||
short v = PlatformDependent.getShort(addr(index));
|
||||
return NATIVE_ORDER? v : Short.reverseBytes(v);
|
||||
return UnsafeByteBufUtil.getShort(addr(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int _getUnsignedMedium(int index) {
|
||||
long addr = addr(index);
|
||||
return (PlatformDependent.getByte(addr) & 0xff) << 16 |
|
||||
(PlatformDependent.getByte(addr + 1) & 0xff) << 8 |
|
||||
PlatformDependent.getByte(addr + 2) & 0xff;
|
||||
return UnsafeByteBufUtil.getUnsignedMedium(addr(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int _getInt(int index) {
|
||||
int v = PlatformDependent.getInt(addr(index));
|
||||
return NATIVE_ORDER? v : Integer.reverseBytes(v);
|
||||
return UnsafeByteBufUtil.getInt(addr(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long _getLong(int index) {
|
||||
long v = PlatformDependent.getLong(addr(index));
|
||||
return NATIVE_ORDER? v : Long.reverseBytes(v);
|
||||
return UnsafeByteBufUtil.getLong(addr(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -220,30 +210,27 @@ final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
|
||||
|
||||
@Override
|
||||
protected void _setByte(int index, int value) {
|
||||
PlatformDependent.putByte(addr(index), (byte) value);
|
||||
UnsafeByteBufUtil.setByte(addr(index), (byte) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setShort(int index, int value) {
|
||||
PlatformDependent.putShort(addr(index), NATIVE_ORDER ? (short) value : Short.reverseBytes((short) value));
|
||||
UnsafeByteBufUtil.setShort(addr(index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setMedium(int index, int value) {
|
||||
long addr = addr(index);
|
||||
PlatformDependent.putByte(addr, (byte) (value >>> 16));
|
||||
PlatformDependent.putByte(addr + 1, (byte) (value >>> 8));
|
||||
PlatformDependent.putByte(addr + 2, (byte) value);
|
||||
UnsafeByteBufUtil.setMedium(addr(index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setInt(int index, int value) {
|
||||
PlatformDependent.putInt(addr(index), NATIVE_ORDER ? value : Integer.reverseBytes(value));
|
||||
UnsafeByteBufUtil.setInt(addr(index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setLong(int index, long value) {
|
||||
PlatformDependent.putLong(addr(index), NATIVE_ORDER ? value : Long.reverseBytes(value));
|
||||
UnsafeByteBufUtil.setLong(addr(index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -393,6 +380,10 @@ final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
|
||||
|
||||
@Override
|
||||
protected SwappedByteBuf newSwappedByteBuf() {
|
||||
return new UnsafeDirectSwappedByteBuf(this);
|
||||
if (PlatformDependent.isUnaligned()) {
|
||||
// Only use if unaligned access is supported otherwise there is no gain.
|
||||
return new UnsafeDirectSwappedByteBuf(this);
|
||||
}
|
||||
return super.newSwappedByteBuf();
|
||||
}
|
||||
}
|
||||
|
@ -19,15 +19,12 @@ package io.netty.buffer;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Read-only ByteBuf which wraps a read-only direct ByteBuffer and use unsafe for best performance.
|
||||
*/
|
||||
final class ReadOnlyUnsafeDirectByteBuf extends ReadOnlyByteBufferBuf {
|
||||
private static final boolean NATIVE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
|
||||
private final long memoryAddress;
|
||||
|
||||
ReadOnlyUnsafeDirectByteBuf(ByteBufAllocator allocator, ByteBuffer buffer) {
|
||||
@ -37,33 +34,27 @@ final class ReadOnlyUnsafeDirectByteBuf extends ReadOnlyByteBufferBuf {
|
||||
|
||||
@Override
|
||||
protected byte _getByte(int index) {
|
||||
return PlatformDependent.getByte(addr(index));
|
||||
return UnsafeByteBufUtil.getByte(addr(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected short _getShort(int index) {
|
||||
short v = PlatformDependent.getShort(addr(index));
|
||||
return NATIVE_ORDER? v : Short.reverseBytes(v);
|
||||
return UnsafeByteBufUtil.getShort(addr(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int _getUnsignedMedium(int index) {
|
||||
long addr = addr(index);
|
||||
return (PlatformDependent.getByte(addr) & 0xff) << 16 |
|
||||
(PlatformDependent.getByte(addr + 1) & 0xff) << 8 |
|
||||
PlatformDependent.getByte(addr + 2) & 0xff;
|
||||
return UnsafeByteBufUtil.getUnsignedMedium(addr(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int _getInt(int index) {
|
||||
int v = PlatformDependent.getInt(addr(index));
|
||||
return NATIVE_ORDER? v : Integer.reverseBytes(v);
|
||||
return UnsafeByteBufUtil.getInt(addr(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long _getLong(int index) {
|
||||
long v = PlatformDependent.getLong(addr(index));
|
||||
return NATIVE_ORDER? v : Long.reverseBytes(v);
|
||||
return UnsafeByteBufUtil.getLong(addr(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -33,8 +33,6 @@ import java.nio.channels.ScatteringByteChannel;
|
||||
*/
|
||||
public class UnpooledUnsafeDirectByteBuf extends AbstractReferenceCountedByteBuf {
|
||||
|
||||
private static final boolean NATIVE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
|
||||
|
||||
private final ByteBufAllocator alloc;
|
||||
|
||||
private long memoryAddress;
|
||||
@ -217,33 +215,27 @@ public class UnpooledUnsafeDirectByteBuf extends AbstractReferenceCountedByteBuf
|
||||
|
||||
@Override
|
||||
protected byte _getByte(int index) {
|
||||
return PlatformDependent.getByte(addr(index));
|
||||
return UnsafeByteBufUtil.getByte(addr(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected short _getShort(int index) {
|
||||
short v = PlatformDependent.getShort(addr(index));
|
||||
return NATIVE_ORDER? v : Short.reverseBytes(v);
|
||||
return UnsafeByteBufUtil.getShort(addr(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int _getUnsignedMedium(int index) {
|
||||
long addr = addr(index);
|
||||
return (PlatformDependent.getByte(addr) & 0xff) << 16 |
|
||||
(PlatformDependent.getByte(addr + 1) & 0xff) << 8 |
|
||||
PlatformDependent.getByte(addr + 2) & 0xff;
|
||||
return UnsafeByteBufUtil.getUnsignedMedium(addr(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int _getInt(int index) {
|
||||
int v = PlatformDependent.getInt(addr(index));
|
||||
return NATIVE_ORDER? v : Integer.reverseBytes(v);
|
||||
return UnsafeByteBufUtil.getInt(addr(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long _getLong(int index) {
|
||||
long v = PlatformDependent.getLong(addr(index));
|
||||
return NATIVE_ORDER? v : Long.reverseBytes(v);
|
||||
return UnsafeByteBufUtil.getLong(addr(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -319,30 +311,27 @@ public class UnpooledUnsafeDirectByteBuf extends AbstractReferenceCountedByteBuf
|
||||
|
||||
@Override
|
||||
protected void _setByte(int index, int value) {
|
||||
PlatformDependent.putByte(addr(index), (byte) value);
|
||||
UnsafeByteBufUtil.setByte(addr(index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setShort(int index, int value) {
|
||||
PlatformDependent.putShort(addr(index), NATIVE_ORDER ? (short) value : Short.reverseBytes((short) value));
|
||||
UnsafeByteBufUtil.setShort(addr(index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setMedium(int index, int value) {
|
||||
long addr = addr(index);
|
||||
PlatformDependent.putByte(addr, (byte) (value >>> 16));
|
||||
PlatformDependent.putByte(addr + 1, (byte) (value >>> 8));
|
||||
PlatformDependent.putByte(addr + 2, (byte) value);
|
||||
UnsafeByteBufUtil.setMedium(addr(index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setInt(int index, int value) {
|
||||
PlatformDependent.putInt(addr(index), NATIVE_ORDER ? value : Integer.reverseBytes(value));
|
||||
UnsafeByteBufUtil.setInt(addr(index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _setLong(int index, long value) {
|
||||
PlatformDependent.putLong(addr(index), NATIVE_ORDER ? value : Long.reverseBytes(value));
|
||||
UnsafeByteBufUtil.setLong(addr(index), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -529,6 +518,10 @@ public class UnpooledUnsafeDirectByteBuf extends AbstractReferenceCountedByteBuf
|
||||
|
||||
@Override
|
||||
protected SwappedByteBuf newSwappedByteBuf() {
|
||||
return new UnsafeDirectSwappedByteBuf(this);
|
||||
if (PlatformDependent.isUnaligned()) {
|
||||
// Only use if unaligned access is supported otherwise there is no gain.
|
||||
return new UnsafeDirectSwappedByteBuf(this);
|
||||
}
|
||||
return super.newSwappedByteBuf();
|
||||
}
|
||||
}
|
||||
|
138
buffer/src/main/java/io/netty/buffer/UnsafeByteBufUtil.java
Normal file
138
buffer/src/main/java/io/netty/buffer/UnsafeByteBufUtil.java
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* All operations get and set as {@link ByteOrder#BIG_ENDIAN}.
|
||||
*/
|
||||
final class UnsafeByteBufUtil {
|
||||
|
||||
private static final boolean NATIVE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
|
||||
private static final boolean UNALIGNED = PlatformDependent.isUnaligned();
|
||||
|
||||
static byte getByte(long address) {
|
||||
return PlatformDependent.getByte(address);
|
||||
}
|
||||
|
||||
static short getShort(long address) {
|
||||
if (UNALIGNED) {
|
||||
short v = PlatformDependent.getShort(address);
|
||||
return 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) {
|
||||
return (PlatformDependent.getByte(address) & 0xff) |
|
||||
(PlatformDependent.getShort(address + 1) & 0xffff) << 8;
|
||||
}
|
||||
return (Short.reverseBytes(PlatformDependent.getShort(address)) & 0xffff) << 8 |
|
||||
PlatformDependent.getByte(address + 2) & 0xff;
|
||||
}
|
||||
return (PlatformDependent.getByte(address) & 0xff) << 16 |
|
||||
(PlatformDependent.getByte(address + 1) & 0xff) << 8 |
|
||||
PlatformDependent.getByte(address + 2) & 0xff;
|
||||
}
|
||||
|
||||
static int getInt(long address) {
|
||||
if (UNALIGNED) {
|
||||
int v = PlatformDependent.getInt(address);
|
||||
return NATIVE_ORDER ? v : Integer.reverseBytes(v);
|
||||
}
|
||||
return PlatformDependent.getByte(address) << 24 |
|
||||
(PlatformDependent.getByte(address + 1) & 0xff) << 16 |
|
||||
(PlatformDependent.getByte(address + 2) & 0xff) << 8 |
|
||||
PlatformDependent.getByte(address + 3) & 0xff;
|
||||
}
|
||||
|
||||
static long getLong(long address) {
|
||||
if (UNALIGNED) {
|
||||
long v = PlatformDependent.getLong(address);
|
||||
return NATIVE_ORDER ? v : Long.reverseBytes(v);
|
||||
}
|
||||
return (long) PlatformDependent.getByte(address) << 56 |
|
||||
((long) PlatformDependent.getByte(address + 1) & 0xff) << 48 |
|
||||
((long) PlatformDependent.getByte(address + 2) & 0xff) << 40 |
|
||||
((long) PlatformDependent.getByte(address + 3) & 0xff) << 32 |
|
||||
((long) PlatformDependent.getByte(address + 4) & 0xff) << 24 |
|
||||
((long) PlatformDependent.getByte(address + 5) & 0xff) << 16 |
|
||||
((long) PlatformDependent.getByte(address + 6) & 0xff) << 8 |
|
||||
(long) PlatformDependent.getByte(address + 7) & 0xff;
|
||||
}
|
||||
|
||||
static void setByte(long address, int value) {
|
||||
PlatformDependent.putByte(address, (byte) value);
|
||||
}
|
||||
|
||||
static void setShort(long address, int value) {
|
||||
if (UNALIGNED) {
|
||||
PlatformDependent.putShort(address, NATIVE_ORDER ? (short) value : Short.reverseBytes((short) value));
|
||||
} else {
|
||||
PlatformDependent.putByte(address, (byte) (value >>> 8));
|
||||
PlatformDependent.putByte(address + 1, (byte) value);
|
||||
}
|
||||
}
|
||||
|
||||
static void setMedium(long address, int value) {
|
||||
if (UNALIGNED) {
|
||||
if (NATIVE_ORDER) {
|
||||
PlatformDependent.putByte(address, (byte) value);
|
||||
PlatformDependent.putShort(address + 1, (short) (value >>> 8));
|
||||
} else {
|
||||
PlatformDependent.putShort(address, Short.reverseBytes((short) (value >>> 8)));
|
||||
PlatformDependent.putByte(address + 2, (byte) value);
|
||||
}
|
||||
} else {
|
||||
PlatformDependent.putByte(address, (byte) (value >>> 16));
|
||||
PlatformDependent.putByte(address + 1, (byte) (value >>> 8));
|
||||
PlatformDependent.putByte(address + 2, (byte) value);
|
||||
}
|
||||
}
|
||||
|
||||
static void setInt(long address, int value) {
|
||||
if (UNALIGNED) {
|
||||
PlatformDependent.putInt(address, NATIVE_ORDER ? value : Integer.reverseBytes(value));
|
||||
} else {
|
||||
PlatformDependent.putByte(address, (byte) (value >>> 24));
|
||||
PlatformDependent.putByte(address + 1, (byte) (value >>> 16));
|
||||
PlatformDependent.putByte(address + 2, (byte) (value >>> 8));
|
||||
PlatformDependent.putByte(address + 3, (byte) value);
|
||||
}
|
||||
}
|
||||
|
||||
static void setLong(long address, long value) {
|
||||
if (UNALIGNED) {
|
||||
PlatformDependent.putLong(address, NATIVE_ORDER ? value : Long.reverseBytes(value));
|
||||
} else {
|
||||
PlatformDependent.putByte(address, (byte) (value >>> 56));
|
||||
PlatformDependent.putByte(address + 1, (byte) (value >>> 48));
|
||||
PlatformDependent.putByte(address + 2, (byte) (value >>> 40));
|
||||
PlatformDependent.putByte(address + 3, (byte) (value >>> 32));
|
||||
PlatformDependent.putByte(address + 4, (byte) (value >>> 24));
|
||||
PlatformDependent.putByte(address + 5, (byte) (value >>> 16));
|
||||
PlatformDependent.putByte(address + 6, (byte) (value >>> 8));
|
||||
PlatformDependent.putByte(address + 7, (byte) value);
|
||||
}
|
||||
}
|
||||
|
||||
private UnsafeByteBufUtil() { }
|
||||
}
|
@ -30,6 +30,7 @@ final class UnsafeDirectSwappedByteBuf extends SwappedByteBuf {
|
||||
|
||||
UnsafeDirectSwappedByteBuf(AbstractByteBuf buf) {
|
||||
super(buf);
|
||||
assert PlatformDependent.isUnaligned();
|
||||
wrapped = buf;
|
||||
nativeByteOrder = NATIVE_ORDER == (order() == ByteOrder.BIG_ENDIAN);
|
||||
}
|
||||
|
@ -151,6 +151,15 @@ public final class PlatformDependent {
|
||||
return HAS_UNSAFE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code true} if and only if the platform supports unaligned access.
|
||||
*
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Segmentation_fault#Bus_error">Wikipedia on segfault</a>
|
||||
*/
|
||||
public static boolean isUnaligned() {
|
||||
return PlatformDependent0.isUnaligned();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the platform has reliable low-level direct buffer access API and a user has not specified
|
||||
* {@code -Dio.netty.noPreferDirect} option.
|
||||
|
@ -23,7 +23,6 @@ import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
||||
@ -39,7 +38,6 @@ final class PlatformDependent0 {
|
||||
|
||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(PlatformDependent0.class);
|
||||
static final Unsafe UNSAFE;
|
||||
private static final boolean BIG_ENDIAN = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
|
||||
private static final long ADDRESS_FIELD_OFFSET;
|
||||
private static final long ARRAY_BASE_OFFSET;
|
||||
|
||||
@ -49,11 +47,6 @@ final class PlatformDependent0 {
|
||||
*/
|
||||
private static final long UNSAFE_COPY_THRESHOLD = 1024L * 1024L;
|
||||
|
||||
/**
|
||||
* {@code true} if and only if the platform supports unaligned access.
|
||||
*
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Segmentation_fault#Bus_error">Wikipedia on segfault</a>
|
||||
*/
|
||||
private static final boolean UNALIGNED;
|
||||
|
||||
static {
|
||||
@ -138,6 +131,10 @@ final class PlatformDependent0 {
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isUnaligned() {
|
||||
return UNALIGNED;
|
||||
}
|
||||
|
||||
static boolean hasUnsafe() {
|
||||
return UNSAFE != null;
|
||||
}
|
||||
@ -190,53 +187,15 @@ final class PlatformDependent0 {
|
||||
}
|
||||
|
||||
static short getShort(long address) {
|
||||
if (UNALIGNED) {
|
||||
return UNSAFE.getShort(address);
|
||||
} else if (BIG_ENDIAN) {
|
||||
return (short) (getByte(address) << 8 | getByte(address + 1) & 0xff);
|
||||
} else {
|
||||
return (short) (getByte(address + 1) << 8 | getByte(address) & 0xff);
|
||||
}
|
||||
return UNSAFE.getShort(address);
|
||||
}
|
||||
|
||||
static int getInt(long address) {
|
||||
if (UNALIGNED) {
|
||||
return UNSAFE.getInt(address);
|
||||
} else if (BIG_ENDIAN) {
|
||||
return getByte(address) << 24 |
|
||||
(getByte(address + 1) & 0xff) << 16 |
|
||||
(getByte(address + 2) & 0xff) << 8 |
|
||||
getByte(address + 3) & 0xff;
|
||||
} else {
|
||||
return getByte(address + 3) << 24 |
|
||||
(getByte(address + 2) & 0xff) << 16 |
|
||||
(getByte(address + 1) & 0xff) << 8 |
|
||||
getByte(address) & 0xff;
|
||||
}
|
||||
return UNSAFE.getInt(address);
|
||||
}
|
||||
|
||||
static long getLong(long address) {
|
||||
if (UNALIGNED) {
|
||||
return UNSAFE.getLong(address);
|
||||
} else if (BIG_ENDIAN) {
|
||||
return (long) getByte(address) << 56 |
|
||||
((long) getByte(address + 1) & 0xff) << 48 |
|
||||
((long) getByte(address + 2) & 0xff) << 40 |
|
||||
((long) getByte(address + 3) & 0xff) << 32 |
|
||||
((long) getByte(address + 4) & 0xff) << 24 |
|
||||
((long) getByte(address + 5) & 0xff) << 16 |
|
||||
((long) getByte(address + 6) & 0xff) << 8 |
|
||||
(long) getByte(address + 7) & 0xff;
|
||||
} else {
|
||||
return (long) getByte(address + 7) << 56 |
|
||||
((long) getByte(address + 6) & 0xff) << 48 |
|
||||
((long) getByte(address + 5) & 0xff) << 40 |
|
||||
((long) getByte(address + 4) & 0xff) << 32 |
|
||||
((long) getByte(address + 3) & 0xff) << 24 |
|
||||
((long) getByte(address + 2) & 0xff) << 16 |
|
||||
((long) getByte(address + 1) & 0xff) << 8 |
|
||||
(long) getByte(address) & 0xff;
|
||||
}
|
||||
return UNSAFE.getLong(address);
|
||||
}
|
||||
|
||||
static void putOrderedObject(Object object, long address, Object value) {
|
||||
@ -248,55 +207,15 @@ final class PlatformDependent0 {
|
||||
}
|
||||
|
||||
static void putShort(long address, short value) {
|
||||
if (UNALIGNED) {
|
||||
UNSAFE.putShort(address, value);
|
||||
} else if (BIG_ENDIAN) {
|
||||
putByte(address, (byte) (value >>> 8));
|
||||
putByte(address + 1, (byte) value);
|
||||
} else {
|
||||
putByte(address + 1, (byte) (value >>> 8));
|
||||
putByte(address, (byte) value);
|
||||
}
|
||||
UNSAFE.putShort(address, value);
|
||||
}
|
||||
|
||||
static void putInt(long address, int value) {
|
||||
if (UNALIGNED) {
|
||||
UNSAFE.putInt(address, value);
|
||||
} else if (BIG_ENDIAN) {
|
||||
putByte(address, (byte) (value >>> 24));
|
||||
putByte(address + 1, (byte) (value >>> 16));
|
||||
putByte(address + 2, (byte) (value >>> 8));
|
||||
putByte(address + 3, (byte) value);
|
||||
} else {
|
||||
putByte(address + 3, (byte) (value >>> 24));
|
||||
putByte(address + 2, (byte) (value >>> 16));
|
||||
putByte(address + 1, (byte) (value >>> 8));
|
||||
putByte(address, (byte) value);
|
||||
}
|
||||
UNSAFE.putInt(address, value);
|
||||
}
|
||||
|
||||
static void putLong(long address, long value) {
|
||||
if (UNALIGNED) {
|
||||
UNSAFE.putLong(address, value);
|
||||
} else if (BIG_ENDIAN) {
|
||||
putByte(address, (byte) (value >>> 56));
|
||||
putByte(address + 1, (byte) (value >>> 48));
|
||||
putByte(address + 2, (byte) (value >>> 40));
|
||||
putByte(address + 3, (byte) (value >>> 32));
|
||||
putByte(address + 4, (byte) (value >>> 24));
|
||||
putByte(address + 5, (byte) (value >>> 16));
|
||||
putByte(address + 6, (byte) (value >>> 8));
|
||||
putByte(address + 7, (byte) value);
|
||||
} else {
|
||||
putByte(address + 7, (byte) (value >>> 56));
|
||||
putByte(address + 6, (byte) (value >>> 48));
|
||||
putByte(address + 5, (byte) (value >>> 40));
|
||||
putByte(address + 4, (byte) (value >>> 32));
|
||||
putByte(address + 3, (byte) (value >>> 24));
|
||||
putByte(address + 2, (byte) (value >>> 16));
|
||||
putByte(address + 1, (byte) (value >>> 8));
|
||||
putByte(address, (byte) value);
|
||||
}
|
||||
UNSAFE.putLong(address, value);
|
||||
}
|
||||
|
||||
static void copyMemory(long srcAddr, long dstAddr, long length) {
|
||||
|
Loading…
Reference in New Issue
Block a user