http://git-wip-us.apache.org/repos/asf/ignite/blob/a87decdc/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java b/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java index 2867b0a..1f7a53c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java @@ -18,15 +18,67 @@ package org.apache.ignite.internal.util; import java.lang.reflect.Field; +import java.nio.ByteOrder; import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import sun.misc.Unsafe; /** - * Provides handle on Unsafe class from SUN which cannot be instantiated directly. + * <p>Wrapper for {@link sun.misc.Unsafe} class.</p> + * + * <p> + * The following statements for memory access operations are true: + * <ul> + * <li>All {@code putXxx(long addr, xxx val)}, {@code getXxx(long addr)}, {@code putXxx(byte[] arr, long off, xxx val)}, + * {@code getXxx(byte[] arr, long off)} and corresponding methods with {@code LE} suffix are alignment aware + * and can be safely used with unaligned pointers.</li> + * <li>All {@code putXxxField(Object obj, long fieldOff, xxx val)} and {@code getXxxField(Object obj, long fieldOff)} + * methods are not alignment aware and can't be safely used with unaligned pointers. This methods can be safely used + * for object field values access because all object fields addresses are aligned.</li> + * <li>All {@code putXxxLE(...)} and {@code getXxxLE(...)} methods assumes that byte order is fixed as little-endian + * while native byte order is big-endian. So it is client code responsibility to check native byte order before + * invoking of this methods.</li> + * </ul> + * </p> */ -public class GridUnsafe { +public abstract class GridUnsafe { + /** Unsafe. */ + private static final Unsafe UNSAFE = unsafe(); + + /** Unaligned flag. */ + private static final boolean UNALIGNED = unaligned(); + + /** Big endian. */ + public static final boolean BIG_ENDIAN = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; + + /** Address size. */ + public static final int ADDR_SIZE = UNSAFE.addressSize(); + + /** */ + public static final long BYTE_ARR_OFF = UNSAFE.arrayBaseOffset(byte[].class); + + /** */ + public static final long SHORT_ARR_OFF = UNSAFE.arrayBaseOffset(short[].class); + + /** */ + public static final long INT_ARR_OFF = UNSAFE.arrayBaseOffset(int[].class); + + /** */ + public static final long LONG_ARR_OFF = UNSAFE.arrayBaseOffset(long[].class); + + /** */ + public static final long FLOAT_ARR_OFF = UNSAFE.arrayBaseOffset(float[].class); + + /** */ + public static final long DOUBLE_ARR_OFF = UNSAFE.arrayBaseOffset(double[].class); + + /** */ + public static final long CHAR_ARR_OFF = UNSAFE.arrayBaseOffset(char[].class); + + /** */ + public static final long BOOLEAN_ARR_OFF = UNSAFE.arrayBaseOffset(boolean[].class); + /** * Ensure singleton. */ @@ -35,9 +87,1130 @@ public class GridUnsafe { } /** + * Gets boolean value from object field. + * + * @param obj Object. + * @param fieldOff Field offset. + * @return Boolean value from object field. + */ + public static boolean getBooleanField(Object obj, long fieldOff) { + return UNSAFE.getBoolean(obj, fieldOff); + } + + /** + * Stores boolean value into object field. + * + * @param obj Object. + * @param fieldOff Field offset. + * @param val Value. + */ + public static void putBooleanField(Object obj, long fieldOff, boolean val) { + UNSAFE.putBoolean(obj, fieldOff, val); + } + + /** + * Gets byte value from object field. + * + * @param obj Object. + * @param fieldOff Field offset. + * @return Byte value from object field. + */ + public static byte getByteField(Object obj, long fieldOff) { + return UNSAFE.getByte(obj, fieldOff); + } + + /** + * Stores byte value into object field. + * + * @param obj Object. + * @param fieldOff Field offset. + * @param val Value. + */ + public static void putByteField(Object obj, long fieldOff, byte val) { + UNSAFE.putByte(obj, fieldOff, val); + } + + /** + * Gets short value from object field. + * + * @param obj Object. + * @param fieldOff Field offset. + * @return Short value from object field. + */ + public static short getShortField(Object obj, long fieldOff) { + return UNSAFE.getShort(obj, fieldOff); + } + + /** + * Stores short value into object field. + * + * @param obj Object. + * @param fieldOff Field offset. + * @param val Value. + */ + public static void putShortField(Object obj, long fieldOff, short val) { + UNSAFE.putShort(obj, fieldOff, val); + } + + /** + * Gets char value from object field. + * + * @param obj Object. + * @param fieldOff Field offset. + * @return Char value from object field. + */ + public static char getCharField(Object obj, long fieldOff) { + return UNSAFE.getChar(obj, fieldOff); + } + + /** + * Stores char value into object field. + * + * @param obj Object. + * @param fieldOff Field offset. + * @param val Value. + */ + public static void putCharField(Object obj, long fieldOff, char val) { + UNSAFE.putChar(obj, fieldOff, val); + } + + /** + * Gets integer value from object field. + * + * @param obj Object. + * @param fieldOff Field offset. + * @return Integer value from object field. + */ + public static int getIntField(Object obj, long fieldOff) { + return UNSAFE.getInt(obj, fieldOff); + } + + /** + * Stores integer value into object field. + * + * @param obj Object. + * @param fieldOff Field offset. + * @param val Value. + */ + public static void putIntField(Object obj, long fieldOff, int val) { + UNSAFE.putInt(obj, fieldOff, val); + } + + /** + * Gets long value from object field. + * + * @param obj Object. + * @param fieldOff Field offset. + * @return Long value from object field. + */ + public static long getLongField(Object obj, long fieldOff) { + return UNSAFE.getLong(obj, fieldOff); + } + + /** + * Stores long value into object field. + * + * @param obj Object. + * @param fieldOff Field offset. + * @param val Value. + */ + public static void putLongField(Object obj, long fieldOff, long val) { + UNSAFE.putLong(obj, fieldOff, val); + } + + /** + * Gets float value from object field. + * + * @param obj Object. + * @param fieldOff Field offset. + * @return Float value from object field. + */ + public static float getFloatField(Object obj, long fieldOff) { + return UNSAFE.getFloat(obj, fieldOff); + } + + /** + * Stores float value into object field. + * + * @param obj Object. + * @param fieldOff Field offset. + * @param val Value. + */ + public static void putFloatField(Object obj, long fieldOff, float val) { + UNSAFE.putFloat(obj, fieldOff, val); + } + + /** + * Gets double value from object field. + * + * @param obj Object. + * @param fieldOff Field offset. + * @return Double value from object field. + */ + public static double getDoubleField(Object obj, long fieldOff) { + return UNSAFE.getDouble(obj, fieldOff); + } + + /** + * Stores double value into object field. + * + * @param obj Object. + * @param fieldOff Field offset. + * @param val Value. + */ + public static void putDoubleField(Object obj, long fieldOff, double val) { + UNSAFE.putDouble(obj, fieldOff, val); + } + + /** + * Gets reference from object field. + * + * @param obj Object. + * @param fieldOff Field offset. + * @return Reference from object field. + */ + public static Object getObjectField(Object obj, long fieldOff) { + return UNSAFE.getObject(obj, fieldOff); + } + + /** + * Stores reference value into object field. + * + * @param obj Object. + * @param fieldOff Field offset. + * @param val Value. + */ + public static void putObjectField(Object obj, long fieldOff, Object val) { + UNSAFE.putObject(obj, fieldOff, val); + } + + /** + * Gets boolean value from byte array. + * + * @param arr Byte array. + * @param off Offset. + * @return Boolean value from byte array. + */ + public static boolean getBoolean(byte[] arr, long off) { + return UNSAFE.getBoolean(arr, off); + } + + /** + * Stores boolean value into byte array. + * + * @param arr Byte array. + * @param off Offset. + * @param val Value. + */ + public static void putBoolean(byte[] arr, long off, boolean val) { + UNSAFE.putBoolean(arr, off, val); + } + + /** + * Gets byte value from byte array. + * + * @param arr Byte array. + * @param off Offset. + * @return Byte value from byte array. + */ + public static byte getByte(byte[] arr, long off) { + return UNSAFE.getByte(arr, off); + } + + /** + * Stores byte value into byte array. + * + * @param arr Byte array. + * @param off Offset. + * @param val Value. + */ + public static void putByte(byte[] arr, long off, byte val) { + UNSAFE.putByte(arr, off, val); + } + + /** + * Gets short value from byte array. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @return Short value from byte array. + */ + public static short getShort(byte[] arr, long off) { + return UNALIGNED ? UNSAFE.getShort(arr, off) : getShortByByte(arr, off, BIG_ENDIAN); + } + + /** + * Stores short value into byte array. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @param val Value. + */ + public static void putShort(byte[] arr, long off, short val) { + if (UNALIGNED) + UNSAFE.putShort(arr, off, val); + else + putShortByByte(arr, off, val, BIG_ENDIAN); + } + + /** + * Gets char value from byte array. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @return Char value from byte array. + */ + public static char getChar(byte[] arr, long off) { + return UNALIGNED ? UNSAFE.getChar(arr, off) : getCharByByte(arr, off, BIG_ENDIAN); + } + + /** + * Stores char value into byte array. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @param val Value. + */ + public static void putChar(byte[] arr, long off, char val) { + if (UNALIGNED) + UNSAFE.putChar(arr, off, val); + else + putCharByByte(arr, off, val, BIG_ENDIAN); + } + + /** + * Gets integer value from byte array. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @return Integer value from byte array. + */ + public static int getInt(byte[] arr, long off) { + return UNALIGNED ? UNSAFE.getInt(arr, off) : getIntByByte(arr, off, BIG_ENDIAN); + } + + /** + * Stores integer value into byte array. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @param val Value. + */ + public static void putInt(byte[] arr, long off, int val) { + if (UNALIGNED) + UNSAFE.putInt(arr, off, val); + else + putIntByByte(arr, off, val, BIG_ENDIAN); + } + + /** + * Gets long value from byte array. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @return Long value from byte array. + */ + public static long getLong(byte[] arr, long off) { + return UNALIGNED ? UNSAFE.getLong(arr, off) : getLongByByte(arr, off, BIG_ENDIAN); + } + + /** + * Stores long value into byte array. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @param val Value. + */ + public static void putLong(byte[] arr, long off, long val) { + if (UNALIGNED) + UNSAFE.putLong(arr, off, val); + else + putLongByByte(arr, off, val, BIG_ENDIAN); + } + + /** + * Gets float value from byte array. Alignment aware. + * + * @param arr Object. + * @param off Offset. + * @return Float value from byte array. + */ + public static float getFloat(byte[] arr, long off) { + return UNALIGNED ? UNSAFE.getFloat(arr, off) : Float.intBitsToFloat(getIntByByte(arr, off, BIG_ENDIAN)); + } + + /** + * Stores float value into byte array. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @param val Value. + */ + public static void putFloat(byte[] arr, long off, float val) { + if (UNALIGNED) + UNSAFE.putFloat(arr, off, val); + else + putIntByByte(arr, off, Float.floatToIntBits(val), BIG_ENDIAN); + } + + /** + * Gets double value from byte array. Alignment aware. + * + * @param arr byte array. + * @param off Offset. + * @return Double value from byte array. Alignment aware. + */ + public static double getDouble(byte[] arr, long off) { + return UNALIGNED ? UNSAFE.getDouble(arr, off) : Double.longBitsToDouble(getLongByByte(arr, off, BIG_ENDIAN)); + } + + /** + * Stores double value into byte array. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @param val Value. + */ + public static void putDouble(byte[] arr, long off, double val) { + if (UNALIGNED) + UNSAFE.putDouble(arr, off, val); + else + putLongByByte(arr, off, Double.doubleToLongBits(val), BIG_ENDIAN); + } + + /** + * Gets short value from byte array assuming that value stored in little-endian byte order and native byte order + * is big-endian. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @return Short value from byte array. + */ + public static short getShortLE(byte[] arr, long off) { + return UNALIGNED ? Short.reverseBytes(UNSAFE.getShort(arr, off)) : getShortByByte(arr, off, false); + } + + /** + * Stores short value into byte array assuming that value should be stored in little-endian byte order and native + * byte order is big-endian. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @param val Value. + */ + public static void putShortLE(byte[] arr, long off, short val) { + if (UNALIGNED) + UNSAFE.putShort(arr, off, Short.reverseBytes(val)); + else + putShortByByte(arr, off, val, false); + } + + /** + * Gets char value from byte array assuming that value stored in little-endian byte order and native byte order + * is big-endian. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @return Char value from byte array. + */ + public static char getCharLE(byte[] arr, long off) { + return UNALIGNED ? Character.reverseBytes(UNSAFE.getChar(arr, off)) : getCharByByte(arr, off, false); + } + + /** + * Stores char value into byte array assuming that value should be stored in little-endian byte order and native + * byte order is big-endian. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @param val Value. + */ + public static void putCharLE(byte[] arr, long off, char val) { + if (UNALIGNED) + UNSAFE.putChar(arr, off, Character.reverseBytes(val)); + else + putCharByByte(arr, off, val, false); + } + + /** + * Gets integer value from byte array assuming that value stored in little-endian byte order and native byte order + * is big-endian. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @return Integer value from byte array. + */ + public static int getIntLE(byte[] arr, long off) { + return UNALIGNED ? Integer.reverseBytes(UNSAFE.getInt(arr, off)) : getIntByByte(arr, off, false); + } + + /** + * Stores integer value into byte array assuming that value should be stored in little-endian byte order and + * native byte order is big-endian. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @param val Value. + */ + public static void putIntLE(byte[] arr, long off, int val) { + if (UNALIGNED) + UNSAFE.putInt(arr, off, Integer.reverseBytes(val)); + else + putIntByByte(arr, off, val, false); + } + + /** + * Gets long value from byte array assuming that value stored in little-endian byte order and native byte order + * is big-endian. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @return Long value from byte array. + */ + public static long getLongLE(byte[] arr, long off) { + return UNALIGNED ? Long.reverseBytes(UNSAFE.getLong(arr, off)) : getLongByByte(arr, off, false); + } + + /** + * Stores long value into byte array assuming that value should be stored in little-endian byte order and native + * byte order is big-endian. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @param val Value. + */ + public static void putLongLE(byte[] arr, long off, long val) { + if (UNALIGNED) + UNSAFE.putLong(arr, off, Long.reverseBytes(val)); + else + putLongByByte(arr, off, val, false); + } + + /** + * Gets float value from byte array assuming that value stored in little-endian byte order and native byte order + * is big-endian. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @return Float value from byte array. + */ + public static float getFloatLE(byte[] arr, long off) { + return Float.intBitsToFloat( + UNALIGNED ? Integer.reverseBytes(UNSAFE.getInt(arr, off)) : getIntByByte(arr, off, false) + ); + } + + /** + * Stores float value into byte array assuming that value should be stored in little-endian byte order and native + * byte order is big-endian. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @param val Value. + */ + public static void putFloatLE(byte[] arr, long off, float val) { + int intVal = Float.floatToIntBits(val); + + if (UNALIGNED) + UNSAFE.putInt(arr, off, Integer.reverseBytes(intVal)); + else + putIntByByte(arr, off, intVal, false); + } + + /** + * Gets double value from byte array assuming that value stored in little-endian byte order and native byte order + * is big-endian. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @return Double value from byte array. + */ + public static double getDoubleLE(byte[] arr, long off) { + return Double.longBitsToDouble( + UNALIGNED ? Long.reverseBytes(UNSAFE.getLong(arr, off)) : getLongByByte(arr, off, false) + ); + } + + /** + * Stores double value into byte array assuming that value should be stored in little-endian byte order and + * native byte order is big-endian. Alignment aware. + * + * @param arr Byte array. + * @param off Offset. + * @param val Value. + */ + public static void putDoubleLE(byte[] arr, long off, double val) { + long longVal = Double.doubleToLongBits(val); + + if (UNALIGNED) + UNSAFE.putLong(arr, off, Long.reverseBytes(longVal)); + else + putLongByByte(arr, off, longVal, false); + } + + /** + * Gets byte value from given address. + * + * @param addr Address. + * @return Byte value from given address. + */ + public static byte getByte(long addr) { + return UNSAFE.getByte(addr); + } + + /** + * Stores given byte value. + * + * @param addr Address. + * @param val Value. + */ + public static void putByte(long addr, byte val) { + UNSAFE.putByte(addr, val); + } + + /** + * Gets short value from given address. Alignment aware. + * + * @param addr Address. + * @return Short value from given address. + */ + public static short getShort(long addr) { + return UNALIGNED ? UNSAFE.getShort(addr) : getShortByByte(addr, BIG_ENDIAN); + } + + /** + * Stores given short value. Alignment aware. + * + * @param addr Address. + * @param val Value. + */ + public static void putShort(long addr, short val) { + if (UNALIGNED) + UNSAFE.putShort(addr, val); + else + putShortByByte(addr, val, BIG_ENDIAN); + } + + /** + * Gets char value from given address. Alignment aware. + * + * @param addr Address. + * @return Char value from given address. + */ + public static char getChar(long addr) { + return UNALIGNED ? UNSAFE.getChar(addr) : getCharByByte(addr, BIG_ENDIAN); + } + + /** + * Stores given char value. Alignment aware. + * + * @param addr Address. + * @param val Value. + */ + public static void putChar(long addr, char val) { + if (UNALIGNED) + UNSAFE.putChar(addr, val); + else + putCharByByte(addr, val, BIG_ENDIAN); + } + + /** + * Gets integer value from given address. Alignment aware. + * + * @param addr Address. + * @return Integer value from given address. + */ + public static int getInt(long addr) { + return UNALIGNED ? UNSAFE.getInt(addr) : getIntByByte(addr, BIG_ENDIAN); + } + + /** + * Stores given integer value. Alignment aware. + * + * @param addr Address. + * @param val Value. + */ + public static void putInt(long addr, int val) { + if (UNALIGNED) + UNSAFE.putInt(addr, val); + else + putIntByByte(addr, val, BIG_ENDIAN); + } + + /** + * Gets long value from given address. Alignment aware. + * + * @param addr Address. + * @return Long value from given address. + */ + public static long getLong(long addr) { + return UNALIGNED ? UNSAFE.getLong(addr) : getLongByByte(addr, BIG_ENDIAN); + } + + /** + * Stores given integer value. Alignment aware. + * + * @param addr Address. + * @param val Value. + */ + public static void putLong(long addr, long val) { + if (UNALIGNED) + UNSAFE.putLong(addr, val); + else + putLongByByte(addr, val, BIG_ENDIAN); + } + + /** + * Gets float value from given address. Alignment aware. + * + * @param addr Address. + * @return Float value from given address. + */ + public static float getFloat(long addr) { + return UNALIGNED ? UNSAFE.getFloat(addr) : Float.intBitsToFloat(getIntByByte(addr, BIG_ENDIAN)); + } + + /** + * Stores given float value. Alignment aware. + * + * @param addr Address. + * @param val Value. + */ + public static void putFloat(long addr, float val) { + if (UNALIGNED) + UNSAFE.putFloat(addr, val); + else + putIntByByte(addr, Float.floatToIntBits(val), BIG_ENDIAN); + } + + /** + * Gets double value from given address. Alignment aware. + * + * @param addr Address. + * @return Double value from given address. + */ + public static double getDouble(long addr) { + return UNALIGNED ? UNSAFE.getDouble(addr) : Double.longBitsToDouble(getLongByByte(addr, BIG_ENDIAN)); + } + + /** + * Stores given double value. Alignment aware. + * + * @param addr Address. + * @param val Value. + */ + public static void putDouble(long addr, double val) { + if (UNALIGNED) + UNSAFE.putDouble(addr, val); + else + putLongByByte(addr, Double.doubleToLongBits(val), BIG_ENDIAN); + } + + /** + * Gets short value from given address assuming that value stored in little-endian byte order and native byte order + * is big-endian. Alignment aware. + * + * @param addr Address. + * @return Short value from given address. + */ + public static short getShortLE(long addr) { + return UNALIGNED ? Short.reverseBytes(UNSAFE.getShort(addr)) : getShortByByte(addr, false); + } + + /** + * Stores given short value assuming that value should be stored in little-endian byte order and native byte + * order is big-endian. Alignment aware. + * + * @param addr Address. + * @param val Value. + */ + public static void putShortLE(long addr, short val) { + if (UNALIGNED) + UNSAFE.putShort(addr, Short.reverseBytes(val)); + else + putShortByByte(addr, val, false); + } + + /** + * Gets char value from given address assuming that value stored in little-endian byte order and native byte order + * is big-endian. Alignment aware. + * + * @param addr Address. + * @return Char value from given address. + */ + public static char getCharLE(long addr) { + return UNALIGNED ? Character.reverseBytes(UNSAFE.getChar(addr)) : getCharByByte(addr, false); + } + + /** + * Stores given char value assuming that value should be stored in little-endian byte order and native byte order + * is big-endian. Alignment aware. + * + * @param addr Address. + * @param val Value. + */ + public static void putCharLE(long addr, char val) { + if (UNALIGNED) + UNSAFE.putChar(addr, Character.reverseBytes(val)); + else + putCharByByte(addr, val, false); + } + + /** + * Gets integer value from given address assuming that value stored in little-endian byte order + * and native byte order is big-endian. Alignment aware. + * + * @param addr Address. + * @return Integer value from given address. + */ + public static int getIntLE(long addr) { + return UNALIGNED ? Integer.reverseBytes(UNSAFE.getInt(addr)) : getIntByByte(addr, false); + } + + /** + * Stores given integer value assuming that value should be stored in little-endian byte order + * and native byte order is big-endian. Alignment aware. + * + * @param addr Address. + * @param val Value. + */ + public static void putIntLE(long addr, int val) { + if (UNALIGNED) + UNSAFE.putInt(addr, Integer.reverseBytes(val)); + else + putIntByByte(addr, val, false); + } + + /** + * Gets long value from given address assuming that value stored in little-endian byte order + * and native byte order is big-endian. Alignment aware. + * + * @param addr Address. + * @return Long value from given address. + */ + public static long getLongLE(long addr) { + return UNALIGNED ? Long.reverseBytes(UNSAFE.getLong(addr)) : getLongByByte(addr, false); + } + + /** + * Stores given integer value assuming that value should be stored in little-endian byte order + * and native byte order is big-endian. Alignment aware. + * + * @param addr Address. + * @param val Value. + */ + public static void putLongLE(long addr, long val) { + if (UNALIGNED) + UNSAFE.putLong(addr, Long.reverseBytes(val)); + else + putLongByByte(addr, val, false); + } + + /** + * Gets float value from given address assuming that value stored in little-endian byte order + * and native byte order is big-endian. Alignment aware. + * + * @param addr Address. + * @return Float value from given address. + */ + public static float getFloatLE(long addr) { + return Float.intBitsToFloat(UNALIGNED ? Integer.reverseBytes(UNSAFE.getInt(addr)) : getIntByByte(addr, false)); + } + + /** + * Stores given float value assuming that value should be stored in little-endian byte order + * and native byte order is big-endian. Alignment aware. + * + * @param addr Address. + * @param val Value. + */ + public static void putFloatLE(long addr, float val) { + int intVal = Float.floatToIntBits(val); + + if (UNALIGNED) + UNSAFE.putInt(addr, Integer.reverseBytes(intVal)); + else + putIntByByte(addr, intVal, false); + } + + /** + * Gets double value from given address assuming that value stored in little-endian byte order + * and native byte order is big-endian. Alignment aware. + * + * @param addr Address. + * @return Double value from given address. + */ + public static double getDoubleLE(long addr) { + return Double.longBitsToDouble( + UNALIGNED ? Long.reverseBytes(UNSAFE.getLong(addr)) : getLongByByte(addr, false) + ); + } + + /** + * Stores given double value assuming that value should be stored in little-endian byte order + * and native byte order is big-endian. Alignment aware. + * + * @param addr Address. + * @param val Value. + */ + public static void putDoubleLE(long addr, double val) { + long longVal = Double.doubleToLongBits(val); + + if (UNALIGNED) + UNSAFE.putLong(addr, Long.reverseBytes(longVal)); + else + putLongByByte(addr, longVal, false); + } + + /** + * Returns static field offset. + * + * @param field Field. + * @return Static field offset. + */ + public static long staticFieldOffset(Field field) { + return UNSAFE.staticFieldOffset(field); + } + + /** + * Returns object field offset. + * + * @param field Field. + * @return Object field offset. + */ + public static long objectFieldOffset(Field field) { + return UNSAFE.objectFieldOffset(field); + } + + /** + * Returns static field base. + * + * @param field Field. + * @return Static field base. + */ + public static Object staticFieldBase(Field field) { + return UNSAFE.staticFieldBase(field); + } + + /** + * Allocates memory. + * + * @param size Size. + * @return address. + */ + public static long allocateMemory(long size) { + return UNSAFE.allocateMemory(size); + } + + /** + * Reallocates memory. + * + * @param addr Address. + * @param len Length. + * @return address. + */ + public static long reallocateMemory(long addr, long len) { + return UNSAFE.reallocateMemory(addr, len); + } + + /** + * Fills memory with given value. + * + * @param addr Address. + * @param len Length. + * @param val Value. + */ + public static void setMemory(long addr, long len, byte val) { + UNSAFE.setMemory(addr, len, val); + } + + /** + * Copies memory. + * + * @param src Source. + * @param dst Dst. + * @param len Length. + */ + public static void copyMemory(long src, long dst, long len) { + UNSAFE.copyMemory(src, dst, len); + } + + /** + * Sets all bytes in a given block of memory to a copy of another block. + * + * @param srcBase Source base. + * @param srcOff Source offset. + * @param dstBase Dst base. + * @param dstOff Dst offset. + * @param len Length. + */ + public static void copyMemory(Object srcBase, long srcOff, Object dstBase, long dstOff, long len) { + UNSAFE.copyMemory(srcBase, srcOff, dstBase, dstOff, len); + } + + /** + * Frees memory. + * + * @param addr Address. + */ + public static void freeMemory(long addr) { + UNSAFE.freeMemory(addr); + } + + /** + * Returns the offset of the first element in the storage allocation of a given array class. + * + * @param cls Class. + * @return the offset of the first element in the storage allocation of a given array class. + */ + public static int arrayBaseOffset(Class cls) { + return UNSAFE.arrayBaseOffset(cls); + } + + /** + * Allocates instance of given class. + * + * @param cls Class. + * @return Allocated instance. + */ + public static Object allocateInstance(Class cls) throws InstantiationException { + return UNSAFE.allocateInstance(cls); + } + + /** + * Acquires monitor lock. + * + * @param obj Object. + */ + public static void monitorEnter(Object obj) { + UNSAFE.monitorEnter(obj); + } + + /** + * Releases monitor lock. + * + * @param obj Object. + */ + public static void monitorExit(Object obj) { + UNSAFE.monitorExit(obj); + } + + /** + * Integer CAS. + * + * @param obj Object. + * @param off Offset. + * @param exp Expected. + * @param upd Upd. + * @return {@code True} if operation completed successfully, {@code false} - otherwise. + */ + public static boolean compareAndSwapInt(Object obj, long off, int exp, int upd) { + return UNSAFE.compareAndSwapInt(obj, off, exp, upd); + } + + /** + * Long CAS. + * + * @param obj Object. + * @param off Offset. + * @param exp Expected. + * @param upd Upd. + * @return {@code True} if operation completed successfully, {@code false} - otherwise. + */ + public static boolean compareAndSwapLong(Object obj, long off, long exp, long upd) { + return UNSAFE.compareAndSwapLong(obj, off, exp, upd); + } + + /** + * Gets byte value with volatile semantic. + * + * @param obj Object. + * @param off Offset. + * @return Byte value. + */ + public static byte getByteVolatile(Object obj, long off) { + return UNSAFE.getByteVolatile(obj, off); + } + + /** + * Stores byte value with volatile semantic. + * + * @param obj Object. + * @param off Offset. + * @param val Value. + */ + public static void putByteVolatile(Object obj, long off, byte val) { + UNSAFE.putByteVolatile(obj, off, val); + } + + /** + * Gets integer value with volatile semantic. + * + * @param obj Object. + * @param off Offset. + * @return Integer value. + */ + public static int getIntVolatile(Object obj, long off) { + return UNSAFE.getIntVolatile(obj, off); + } + + /** + * Stores integer value with volatile semantic. + * + * @param obj Object. + * @param off Offset. + * @param val Value. + */ + public static void putIntVolatile(Object obj, long off, int val) { + UNSAFE.putIntVolatile(obj, off, val); + } + + /** + * Gets long value with volatile semantic. + * + * @param obj Object. + * @param off Offset. + * @return Long value. + */ + public static long getLongVolatile(Object obj, long off) { + return UNSAFE.getLongVolatile(obj, off); + } + + /** + * Stores long value with volatile semantic. + * + * @param obj Object. + * @param off Offset. + * @param val Value. + */ + public static void putLongVolatile(Object obj, long off, long val) { + UNSAFE.putLongVolatile(obj, off, val); + } + + /** + * Stores reference value with volatile semantic. + * + * @param obj Object. + * @param off Offset. + * @param val Value. + */ + public static void putObjectVolatile(Object obj, long off, Object val) { + UNSAFE.putObjectVolatile(obj, off, val); + } + + /** + * Returns unaligned flag. + */ + private static boolean unaligned() { + String arch = System.getProperty("os.arch"); + + return arch.equals("i386") || arch.equals("x86") || arch.equals("amd64") || arch.equals("x86_64"); + } + + /** * @return Instance of Unsafe class. */ - public static Unsafe unsafe() { + private static Unsafe unsafe() { try { return Unsafe.getUnsafe(); } @@ -59,4 +1232,308 @@ public class GridUnsafe { } } } + + /** + * @param obj Object. + * @param off Offset. + * @param bigEndian Order of value bytes in memory. If {@code true} - big-endian, otherwise little-endian. + */ + private static short getShortByByte(Object obj, long off, boolean bigEndian) { + if (bigEndian) + return (short)(UNSAFE.getByte(obj, off) << 8 | (UNSAFE.getByte(obj, off + 1) & 0xff)); + else + return (short)(UNSAFE.getByte(obj, off + 1) << 8 | (UNSAFE.getByte(obj, off) & 0xff)); + } + + /** + * @param obj Object. + * @param off Offset. + * @param val Value. + * @param bigEndian Order of value bytes in memory. If {@code true} - big-endian, otherwise little-endian. + */ + private static void putShortByByte(Object obj, long off, short val, boolean bigEndian) { + if (bigEndian) { + UNSAFE.putByte(obj, off, (byte)(val >> 8)); + UNSAFE.putByte(obj, off + 1, (byte)val); + } + else { + UNSAFE.putByte(obj, off + 1, (byte)(val >> 8)); + UNSAFE.putByte(obj, off, (byte)val); + } + } + + /** + * @param obj Object. + * @param off Offset. + * @param bigEndian Order of value bytes in memory. If {@code true} - big-endian, otherwise little-endian. + */ + private static char getCharByByte(Object obj, long off, boolean bigEndian) { + if (bigEndian) + return (char)(UNSAFE.getByte(obj, off) << 8 | (UNSAFE.getByte(obj, off + 1) & 0xff)); + else + return (char)(UNSAFE.getByte(obj, off + 1) << 8 | (UNSAFE.getByte(obj, off) & 0xff)); + } + + /** + * @param obj Object. + * @param addr Address. + * @param val Value. + * @param bigEndian Order of value bytes in memory. If {@code true} - big-endian, otherwise little-endian. + */ + private static void putCharByByte(Object obj, long addr, char val, boolean bigEndian) { + if (bigEndian) { + UNSAFE.putByte(obj, addr, (byte)(val >> 8)); + UNSAFE.putByte(obj, addr + 1, (byte)val); + } + else { + UNSAFE.putByte(obj, addr + 1, (byte)(val >> 8)); + UNSAFE.putByte(obj, addr, (byte)val); + } + } + + /** + * @param obj Object. + * @param addr Address. + * @param bigEndian Order of value bytes in memory. If {@code true} - big-endian, otherwise little-endian. + */ + private static int getIntByByte(Object obj, long addr, boolean bigEndian) { + if (bigEndian) { + return (((int)UNSAFE.getByte(obj, addr)) << 24) | + (((int)UNSAFE.getByte(obj, addr + 1) & 0xff) << 16) | + (((int)UNSAFE.getByte(obj, addr + 2) & 0xff) << 8) | + (((int)UNSAFE.getByte(obj, addr + 3) & 0xff)); + } + else { + return (((int)UNSAFE.getByte(obj, addr + 3)) << 24) | + (((int)UNSAFE.getByte(obj, addr + 2) & 0xff) << 16) | + (((int)UNSAFE.getByte(obj, addr + 1) & 0xff) << 8) | + (((int)UNSAFE.getByte(obj, addr) & 0xff)); + } + } + + /** + * @param obj Object. + * @param addr Address. + * @param val Value. + * @param bigEndian Order of value bytes in memory. If {@code true} - big-endian, otherwise little-endian. + */ + private static void putIntByByte(Object obj, long addr, int val, boolean bigEndian) { + if (bigEndian) { + UNSAFE.putByte(obj, addr, (byte)(val >> 24)); + UNSAFE.putByte(obj, addr + 1, (byte)(val >> 16)); + UNSAFE.putByte(obj, addr + 2, (byte)(val >> 8)); + UNSAFE.putByte(obj, addr + 3, (byte)(val)); + } + else { + UNSAFE.putByte(obj, addr + 3, (byte)(val >> 24)); + UNSAFE.putByte(obj, addr + 2, (byte)(val >> 16)); + UNSAFE.putByte(obj, addr + 1, (byte)(val >> 8)); + UNSAFE.putByte(obj, addr, (byte)(val)); + } + } + + /** + * @param obj Object. + * @param addr Address. + * @param bigEndian Order of value bytes in memory. If {@code true} - big-endian, otherwise little-endian. + */ + private static long getLongByByte(Object obj, long addr, boolean bigEndian) { + if (bigEndian) { + return (((long)UNSAFE.getByte(obj, addr)) << 56) | + (((long)UNSAFE.getByte(obj, addr + 1) & 0xff) << 48) | + (((long)UNSAFE.getByte(obj, addr + 2) & 0xff) << 40) | + (((long)UNSAFE.getByte(obj, addr + 3) & 0xff) << 32) | + (((long)UNSAFE.getByte(obj, addr + 4) & 0xff) << 24) | + (((long)UNSAFE.getByte(obj, addr + 5) & 0xff) << 16) | + (((long)UNSAFE.getByte(obj, addr + 6) & 0xff) << 8) | + (((long)UNSAFE.getByte(obj, addr + 7) & 0xff)); + } + else { + return (((long)UNSAFE.getByte(obj, addr + 7)) << 56) | + (((long)UNSAFE.getByte(obj, addr + 6) & 0xff) << 48) | + (((long)UNSAFE.getByte(obj, addr + 5) & 0xff) << 40) | + (((long)UNSAFE.getByte(obj, addr + 4) & 0xff) << 32) | + (((long)UNSAFE.getByte(obj, addr + 3) & 0xff) << 24) | + (((long)UNSAFE.getByte(obj, addr + 2) & 0xff) << 16) | + (((long)UNSAFE.getByte(obj, addr + 1) & 0xff) << 8) | + (((long)UNSAFE.getByte(obj, addr) & 0xff)); + } + } + + /** + * @param obj Object. + * @param addr Address. + * @param val Value. + * @param bigEndian Order of value bytes in memory. If {@code true} - big-endian, otherwise little-endian. + */ + private static void putLongByByte(Object obj, long addr, long val, boolean bigEndian) { + if (bigEndian) { + UNSAFE.putByte(obj, addr, (byte)(val >> 56)); + UNSAFE.putByte(obj, addr + 1, (byte)(val >> 48)); + UNSAFE.putByte(obj, addr + 2, (byte)(val >> 40)); + UNSAFE.putByte(obj, addr + 3, (byte)(val >> 32)); + UNSAFE.putByte(obj, addr + 4, (byte)(val >> 24)); + UNSAFE.putByte(obj, addr + 5, (byte)(val >> 16)); + UNSAFE.putByte(obj, addr + 6, (byte)(val >> 8)); + UNSAFE.putByte(obj, addr + 7, (byte)(val)); + } + else { + UNSAFE.putByte(obj, addr + 7, (byte)(val >> 56)); + UNSAFE.putByte(obj, addr + 6, (byte)(val >> 48)); + UNSAFE.putByte(obj, addr + 5, (byte)(val >> 40)); + UNSAFE.putByte(obj, addr + 4, (byte)(val >> 32)); + UNSAFE.putByte(obj, addr + 3, (byte)(val >> 24)); + UNSAFE.putByte(obj, addr + 2, (byte)(val >> 16)); + UNSAFE.putByte(obj, addr + 1, (byte)(val >> 8)); + UNSAFE.putByte(obj, addr, (byte)(val)); + } + } + + /** + * @param addr Address. + * @param bigEndian Order of value bytes in memory. If {@code true} - big-endian, otherwise little-endian. + */ + private static short getShortByByte(long addr, boolean bigEndian) { + if (bigEndian) + return (short)(UNSAFE.getByte(addr) << 8 | (UNSAFE.getByte(addr + 1) & 0xff)); + else + return (short)(UNSAFE.getByte(addr + 1) << 8 | (UNSAFE.getByte(addr) & 0xff)); + } + + /** + * @param addr Address. + * @param val Value. + * @param bigEndian Order of value bytes in memory. If {@code true} - big-endian, otherwise little-endian. + */ + private static void putShortByByte(long addr, short val, boolean bigEndian) { + if (bigEndian) { + UNSAFE.putByte(addr, (byte)(val >> 8)); + UNSAFE.putByte(addr + 1, (byte)val); + } + else { + UNSAFE.putByte(addr + 1, (byte)(val >> 8)); + UNSAFE.putByte(addr, (byte)val); + } + } + + /** + * @param addr Address. + * @param bigEndian Order of value bytes in memory. If {@code true} - big-endian, otherwise little-endian. + */ + private static char getCharByByte(long addr, boolean bigEndian) { + if (bigEndian) + return (char)(UNSAFE.getByte(addr) << 8 | (UNSAFE.getByte(addr + 1) & 0xff)); + else + return (char)(UNSAFE.getByte(addr + 1) << 8 | (UNSAFE.getByte(addr) & 0xff)); + } + + /** + * @param addr Address. + * @param val Value. + * @param bigEndian Order of value bytes in memory. If {@code true} - big-endian, otherwise little-endian. + */ + private static void putCharByByte(long addr, char val, boolean bigEndian) { + if (bigEndian) { + UNSAFE.putByte(addr, (byte)(val >> 8)); + UNSAFE.putByte(addr + 1, (byte)val); + } + else { + UNSAFE.putByte(addr + 1, (byte)(val >> 8)); + UNSAFE.putByte(addr, (byte)val); + } + } + + /** + * @param addr Address. + * @param bigEndian Order of value bytes in memory. If {@code true} - big-endian, otherwise little-endian. + */ + private static int getIntByByte(long addr, boolean bigEndian) { + if (bigEndian) { + return (((int)UNSAFE.getByte(addr)) << 24) | + (((int)UNSAFE.getByte(addr + 1) & 0xff) << 16) | + (((int)UNSAFE.getByte(addr + 2) & 0xff) << 8) | + (((int)UNSAFE.getByte(addr + 3) & 0xff)); + } + else { + return (((int)UNSAFE.getByte(addr + 3)) << 24) | + (((int)UNSAFE.getByte(addr + 2) & 0xff) << 16) | + (((int)UNSAFE.getByte(addr + 1) & 0xff) << 8) | + (((int)UNSAFE.getByte(addr) & 0xff)); + } + } + + /** + * @param addr Address. + * @param val Value. + * @param bigEndian Order of value bytes in memory. If {@code true} - big-endian, otherwise little-endian. + */ + private static void putIntByByte(long addr, int val, boolean bigEndian) { + if (bigEndian) { + UNSAFE.putByte(addr, (byte)(val >> 24)); + UNSAFE.putByte(addr + 1, (byte)(val >> 16)); + UNSAFE.putByte(addr + 2, (byte)(val >> 8)); + UNSAFE.putByte(addr + 3, (byte)(val)); + } + else { + UNSAFE.putByte(addr + 3, (byte)(val >> 24)); + UNSAFE.putByte(addr + 2, (byte)(val >> 16)); + UNSAFE.putByte(addr + 1, (byte)(val >> 8)); + UNSAFE.putByte(addr, (byte)(val)); + } + } + + /** + * @param addr Address. + * @param bigEndian Order of value bytes in memory. If {@code true} - big-endian, otherwise little-endian. + */ + private static long getLongByByte(long addr, boolean bigEndian) { + if (bigEndian) { + return (((long)UNSAFE.getByte(addr)) << 56) | + (((long)UNSAFE.getByte(addr + 1) & 0xff) << 48) | + (((long)UNSAFE.getByte(addr + 2) & 0xff) << 40) | + (((long)UNSAFE.getByte(addr + 3) & 0xff) << 32) | + (((long)UNSAFE.getByte(addr + 4) & 0xff) << 24) | + (((long)UNSAFE.getByte(addr + 5) & 0xff) << 16) | + (((long)UNSAFE.getByte(addr + 6) & 0xff) << 8) | + (((long)UNSAFE.getByte(addr + 7) & 0xff)); + } + else { + return (((long)UNSAFE.getByte(addr + 7)) << 56) | + (((long)UNSAFE.getByte(addr + 6) & 0xff) << 48) | + (((long)UNSAFE.getByte(addr + 5) & 0xff) << 40) | + (((long)UNSAFE.getByte(addr + 4) & 0xff) << 32) | + (((long)UNSAFE.getByte(addr + 3) & 0xff) << 24) | + (((long)UNSAFE.getByte(addr + 2) & 0xff) << 16) | + (((long)UNSAFE.getByte(addr + 1) & 0xff) << 8) | + (((long)UNSAFE.getByte(addr) & 0xff)); + } + } + + /** + * @param addr Address. + * @param val Value. + * @param bigEndian Order of value bytes in memory. If {@code true} - big-endian, otherwise little-endian. + */ + private static void putLongByByte(long addr, long val, boolean bigEndian) { + if (bigEndian) { + UNSAFE.putByte(addr, (byte)(val >> 56)); + UNSAFE.putByte(addr + 1, (byte)(val >> 48)); + UNSAFE.putByte(addr + 2, (byte)(val >> 40)); + UNSAFE.putByte(addr + 3, (byte)(val >> 32)); + UNSAFE.putByte(addr + 4, (byte)(val >> 24)); + UNSAFE.putByte(addr + 5, (byte)(val >> 16)); + UNSAFE.putByte(addr + 6, (byte)(val >> 8)); + UNSAFE.putByte(addr + 7, (byte)(val)); + } + else { + UNSAFE.putByte(addr + 7, (byte)(val >> 56)); + UNSAFE.putByte(addr + 6, (byte)(val >> 48)); + UNSAFE.putByte(addr + 5, (byte)(val >> 40)); + UNSAFE.putByte(addr + 4, (byte)(val >> 32)); + UNSAFE.putByte(addr + 3, (byte)(val >> 24)); + UNSAFE.putByte(addr + 2, (byte)(val >> 16)); + UNSAFE.putByte(addr + 1, (byte)(val >> 8)); + UNSAFE.putByte(addr, (byte)(val)); + } + } } \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/a87decdc/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java index 6c0b8e6..a6b28fd 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java @@ -243,21 +243,19 @@ import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_BUILD_VER; import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_CACHE; import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_JVM_PID; import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_MACS; +import static org.apache.ignite.internal.util.GridUnsafe.objectFieldOffset; +import static org.apache.ignite.internal.util.GridUnsafe.putObjectVolatile; +import static org.apache.ignite.internal.util.GridUnsafe.staticFieldBase; +import static org.apache.ignite.internal.util.GridUnsafe.staticFieldOffset; /** * Collection of utility methods used throughout the system. */ @SuppressWarnings({"UnusedReturnValue", "UnnecessaryFullyQualifiedName"}) public abstract class IgniteUtils { - /** Unsafe. */ - private static final Unsafe UNSAFE = GridUnsafe.unsafe(); - /** {@code True} if {@code unsafe} should be used for array copy. */ private static final boolean UNSAFE_BYTE_ARR_CP = unsafeByteArrayCopyAvailable(); - /** Offset. */ - private static final int BYTE_ARRAY_DATA_OFFSET = UNSAFE.arrayBaseOffset(byte[].class); - /** Sun-specific JDK constructor factory for objects that don't have empty constructor. */ private static final Method CTOR_FACTORY; @@ -526,7 +524,7 @@ public abstract class IgniteUtils { } // UNIX name detection. - if (osLow.contains("olaris")) + if (osLow.contains("olaris") || osLow.contains("sunos")) solaris = true; else if (osLow.contains("inux")) linux = true; @@ -669,9 +667,8 @@ public abstract class IgniteUtils { // We use unsafe operations to update static fields on interface because // they are treated as static final and cannot be updated via standard reflection. - UNSAFE.putObjectVolatile(UNSAFE.staticFieldBase(f1), UNSAFE.staticFieldOffset(f1), gridEvents()); - UNSAFE.putObjectVolatile(UNSAFE.staticFieldBase(f2), UNSAFE.staticFieldOffset(f2), - gridEvents(EVT_NODE_METRICS_UPDATED)); + putObjectVolatile(staticFieldBase(f1), staticFieldOffset(f1), gridEvents()); + putObjectVolatile(staticFieldBase(f2), staticFieldOffset(f2), gridEvents(EVT_NODE_METRICS_UPDATED)); assert EVTS_ALL != null; assert EVTS_ALL.length == GRID_EVTS.length; @@ -7692,7 +7689,7 @@ public abstract class IgniteUtils { */ public static long fieldOffset(Class<?> cls, String fieldName) { try { - return UNSAFE.objectFieldOffset(cls.getDeclaredField(fieldName)); + return objectFieldOffset(cls.getDeclaredField(fieldName)); } catch (NoSuchFieldException e) { throw new IllegalStateException(e); @@ -8304,7 +8301,7 @@ public abstract class IgniteUtils { @SuppressWarnings("TypeParameterExtendsFinalClass") private static boolean unsafeByteArrayCopyAvailable() { try { - Class<? extends Unsafe> unsafeCls = UNSAFE.getClass(); + Class<? extends Unsafe> unsafeCls = Unsafe.class; unsafeCls.getMethod("copyMemory", Object.class, long.class, Object.class, long.class, long.class); @@ -8327,7 +8324,7 @@ public abstract class IgniteUtils { assert resBuf.length >= resOff + len; if (UNSAFE_BYTE_ARR_CP) - UNSAFE.copyMemory(src, BYTE_ARRAY_DATA_OFFSET + off, resBuf, BYTE_ARRAY_DATA_OFFSET + resOff, len); + GridUnsafe.copyMemory(src, GridUnsafe.BYTE_ARR_OFF + off, resBuf, GridUnsafe.BYTE_ARR_OFF + resOff, len); else System.arraycopy(src, off, resBuf, resOff, len); @@ -8860,18 +8857,18 @@ public abstract class IgniteUtils { * @return Offset. */ public static long writeGridUuid(byte[] arr, long off, @Nullable IgniteUuid uid) { - UNSAFE.putBoolean(arr, off++, uid != null); + GridUnsafe.putBoolean(arr, off++, uid != null); if (uid != null) { - UNSAFE.putLong(arr, off, uid.globalId().getMostSignificantBits()); + GridUnsafe.putLong(arr, off, uid.globalId().getMostSignificantBits()); off += 8; - UNSAFE.putLong(arr, off, uid.globalId().getLeastSignificantBits()); + GridUnsafe.putLong(arr, off, uid.globalId().getLeastSignificantBits()); off += 8; - UNSAFE.putLong(arr, off, uid.localId()); + GridUnsafe.putLong(arr, off, uid.localId()); off += 8; } @@ -8885,18 +8882,18 @@ public abstract class IgniteUtils { * @return UUID. */ @Nullable public static IgniteUuid readGridUuid(byte[] arr, long off) { - if (UNSAFE.getBoolean(arr, off++)) { - long most = UNSAFE.getLong(arr, off); + if (GridUnsafe.getBoolean(arr, off++)) { + long most = GridUnsafe.getLong(arr, off); off += 8; - long least = UNSAFE.getLong(arr, off); + long least = GridUnsafe.getLong(arr, off); off += 8; UUID globalId = new UUID(most, least); - long locId = UNSAFE.getLong(arr, off); + long locId = GridUnsafe.getLong(arr, off); return new IgniteUuid(globalId, locId); } @@ -8909,18 +8906,18 @@ public abstract class IgniteUtils { * @return UUID. */ @Nullable public static IgniteUuid readGridUuid(long ptr) { - if (UNSAFE.getBoolean(null, ptr++)) { - long most = UNSAFE.getLong(ptr); + if (GridUnsafe.getBoolean(null, ptr++)) { + long most = GridUnsafe.getLong(ptr); ptr += 8; - long least = UNSAFE.getLong(ptr); + long least = GridUnsafe.getLong(ptr); ptr += 8; UUID globalId = new UUID(most, least); - long locId = UNSAFE.getLong(ptr); + long locId = GridUnsafe.getLong(ptr); return new IgniteUuid(globalId, locId); } @@ -8937,43 +8934,43 @@ public abstract class IgniteUtils { public static long writeVersion(byte[] arr, long off, GridCacheVersion ver) { boolean verEx = ver instanceof GridCacheVersionEx; - UNSAFE.putBoolean(arr, off++, verEx); + GridUnsafe.putBoolean(arr, off++, verEx); if (verEx) { GridCacheVersion drVer = ver.conflictVersion(); assert drVer != null; - UNSAFE.putInt(arr, off, drVer.topologyVersion()); + GridUnsafe.putInt(arr, off, drVer.topologyVersion()); off += 4; - UNSAFE.putInt(arr, off, drVer.nodeOrderAndDrIdRaw()); + GridUnsafe.putInt(arr, off, drVer.nodeOrderAndDrIdRaw()); off += 4; - UNSAFE.putLong(arr, off, drVer.globalTime()); + GridUnsafe.putLong(arr, off, drVer.globalTime()); off += 8; - UNSAFE.putLong(arr, off, drVer.order()); + GridUnsafe.putLong(arr, off, drVer.order()); off += 8; } - UNSAFE.putInt(arr, off, ver.topologyVersion()); + GridUnsafe.putInt(arr, off, ver.topologyVersion()); off += 4; - UNSAFE.putInt(arr, off, ver.nodeOrderAndDrIdRaw()); + GridUnsafe.putInt(arr, off, ver.nodeOrderAndDrIdRaw()); off += 4; - UNSAFE.putLong(arr, off, ver.globalTime()); + GridUnsafe.putLong(arr, off, ver.globalTime()); off += 8; - UNSAFE.putLong(arr, off, ver.order()); + GridUnsafe.putLong(arr, off, ver.order()); off += 8; @@ -8986,18 +8983,18 @@ public abstract class IgniteUtils { * @return Version. */ public static GridCacheVersion readVersion(long ptr, boolean verEx) { - GridCacheVersion ver = new GridCacheVersion(UNSAFE.getInt(ptr), - UNSAFE.getInt(ptr + 4), - UNSAFE.getLong(ptr + 8), - UNSAFE.getLong(ptr + 16)); + GridCacheVersion ver = new GridCacheVersion(GridUnsafe.getInt(ptr), + GridUnsafe.getInt(ptr + 4), + GridUnsafe.getLong(ptr + 8), + GridUnsafe.getLong(ptr + 16)); if (verEx) { ptr += 24; - ver = new GridCacheVersionEx(UNSAFE.getInt(ptr), - UNSAFE.getInt(ptr + 4), - UNSAFE.getLong(ptr + 8), - UNSAFE.getLong(ptr + 16), + ver = new GridCacheVersionEx(GridUnsafe.getInt(ptr), + GridUnsafe.getInt(ptr + 4), + GridUnsafe.getLong(ptr + 8), + GridUnsafe.getLong(ptr + 16), ver); } @@ -9011,38 +9008,38 @@ public abstract class IgniteUtils { * @return Version. */ public static GridCacheVersion readVersion(byte[] arr, long off, boolean verEx) { - int topVer = UNSAFE.getInt(arr, off); + int topVer = GridUnsafe.getInt(arr, off); off += 4; - int nodeOrderDrId = UNSAFE.getInt(arr, off); + int nodeOrderDrId = GridUnsafe.getInt(arr, off); off += 4; - long globalTime = UNSAFE.getLong(arr, off); + long globalTime = GridUnsafe.getLong(arr, off); off += 8; - long order = UNSAFE.getLong(arr, off); + long order = GridUnsafe.getLong(arr, off); off += 8; GridCacheVersion ver = new GridCacheVersion(topVer, nodeOrderDrId, globalTime, order); if (verEx) { - topVer = UNSAFE.getInt(arr, off); + topVer = GridUnsafe.getInt(arr, off); off += 4; - nodeOrderDrId = UNSAFE.getInt(arr, off); + nodeOrderDrId = GridUnsafe.getInt(arr, off); off += 4; - globalTime = UNSAFE.getLong(arr, off); + globalTime = GridUnsafe.getLong(arr, off); off += 8; - order = UNSAFE.getLong(arr, off); + order = GridUnsafe.getLong(arr, off); ver = new GridCacheVersionEx(topVer, nodeOrderDrId, globalTime, order, ver); } @@ -9058,7 +9055,7 @@ public abstract class IgniteUtils { public static byte[] copyMemory(long ptr, int size) { byte[] res = new byte[size]; - UNSAFE.copyMemory(null, ptr, res, BYTE_ARRAY_DATA_OFFSET, size); + GridUnsafe.copyMemory(null, ptr, res, GridUnsafe.BYTE_ARR_OFF, size); return res; } http://git-wip-us.apache.org/repos/asf/ignite/blob/a87decdc/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java b/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java index 00fa2c3..2f57e59 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataInput.java @@ -26,41 +26,24 @@ import org.apache.ignite.internal.util.tostring.GridToStringExclude; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.SB; import org.apache.ignite.internal.util.typedef.internal.U; -import sun.misc.Unsafe; import static org.apache.ignite.IgniteSystemProperties.IGNITE_MARSHAL_BUFFERS_RECHECK; +import static org.apache.ignite.internal.util.GridUnsafe.BIG_ENDIAN; +import static org.apache.ignite.internal.util.GridUnsafe.BYTE_ARR_OFF; +import static org.apache.ignite.internal.util.GridUnsafe.CHAR_ARR_OFF; +import static org.apache.ignite.internal.util.GridUnsafe.DOUBLE_ARR_OFF; +import static org.apache.ignite.internal.util.GridUnsafe.FLOAT_ARR_OFF; +import static org.apache.ignite.internal.util.GridUnsafe.INT_ARR_OFF; +import static org.apache.ignite.internal.util.GridUnsafe.LONG_ARR_OFF; +import static org.apache.ignite.internal.util.GridUnsafe.SHORT_ARR_OFF; /** * Data input based on {@code Unsafe} operations. */ public class GridUnsafeDataInput extends InputStream implements GridDataInput { - /** Unsafe. */ - private static final Unsafe UNSAFE = GridUnsafe.unsafe(); - /** */ private static final Long CHECK_FREQ = Long.getLong(IGNITE_MARSHAL_BUFFERS_RECHECK, 10000); - /** */ - private static final long byteArrOff = UNSAFE.arrayBaseOffset(byte[].class); - - /** */ - private static final long shortArrOff = UNSAFE.arrayBaseOffset(short[].class); - - /** */ - private static final long intArrOff = UNSAFE.arrayBaseOffset(int[].class); - - /** */ - private static final long longArrOff = UNSAFE.arrayBaseOffset(long[].class); - - /** */ - private static final long floatArrOff = UNSAFE.arrayBaseOffset(float[].class); - - /** */ - private static final long doubleArrOff = UNSAFE.arrayBaseOffset(double[].class); - - /** */ - private static final long charArrOff = UNSAFE.arrayBaseOffset(char[].class); - /** Maximum data block length. */ private static final int MAX_BLOCK_SIZE = 1024; @@ -152,7 +135,7 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput { if (maxOff < halfSize) { byte[] newInBuf = new byte[halfSize]; // Shrink. - UNSAFE.copyMemory(inBuf, byteArrOff, newInBuf, byteArrOff, off); + GridUnsafe.copyMemory(inBuf, BYTE_ARR_OFF, newInBuf, BYTE_ARR_OFF, off); buf = inBuf = newInBuf; } @@ -208,7 +191,7 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput { byte[] arr = new byte[arrSize]; - UNSAFE.copyMemory(buf, byteArrOff + offset(arrSize), arr, byteArrOff, arrSize); + GridUnsafe.copyMemory(buf, BYTE_ARR_OFF + offset(arrSize), arr, BYTE_ARR_OFF, arrSize); return arr; } @@ -223,7 +206,17 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput { short[] arr = new short[arrSize]; - UNSAFE.copyMemory(buf, byteArrOff + offset(bytesToCp), arr, shortArrOff, bytesToCp); + long off = BYTE_ARR_OFF + offset(bytesToCp); + + if (BIG_ENDIAN) { + for (int i = 0; i < arr.length; i++) { + arr[i] = GridUnsafe.getShortLE(buf, off); + + off += 2; + } + } + else + GridUnsafe.copyMemory(buf, off, arr, SHORT_ARR_OFF, bytesToCp); return arr; } @@ -238,7 +231,17 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput { int[] arr = new int[arrSize]; - UNSAFE.copyMemory(buf, byteArrOff + offset(bytesToCp), arr, intArrOff, bytesToCp); + long off = BYTE_ARR_OFF + offset(bytesToCp); + + if (BIG_ENDIAN) { + for (int i = 0; i < arr.length; i++) { + arr[i] = GridUnsafe.getIntLE(buf, off); + + off += 4; + } + } + else + GridUnsafe.copyMemory(buf, off, arr, INT_ARR_OFF, bytesToCp); return arr; } @@ -253,7 +256,17 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput { double[] arr = new double[arrSize]; - UNSAFE.copyMemory(buf, byteArrOff + offset(bytesToCp), arr, doubleArrOff, bytesToCp); + long off = BYTE_ARR_OFF + offset(bytesToCp); + + if (BIG_ENDIAN) { + for (int i = 0; i < arr.length; i++) { + arr[i] = GridUnsafe.getDoubleLE(buf, off); + + off += 8; + } + } + else + GridUnsafe.copyMemory(buf, off, arr, DOUBLE_ARR_OFF, bytesToCp); return arr; } @@ -280,7 +293,17 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput { char[] arr = new char[arrSize]; - UNSAFE.copyMemory(buf, byteArrOff + offset(bytesToCp), arr, charArrOff, bytesToCp); + long off = BYTE_ARR_OFF + offset(bytesToCp); + + if (BIG_ENDIAN) { + for (int i = 0; i < arr.length; i++) { + arr[i] = GridUnsafe.getCharLE(buf, off); + + off += 2; + } + } + else + GridUnsafe.copyMemory(buf, off, arr, CHAR_ARR_OFF, bytesToCp); return arr; } @@ -295,7 +318,17 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput { long[] arr = new long[arrSize]; - UNSAFE.copyMemory(buf, byteArrOff + offset(bytesToCp), arr, longArrOff, bytesToCp); + long off = BYTE_ARR_OFF + offset(bytesToCp); + + if (BIG_ENDIAN) { + for (int i = 0; i < arr.length; i++) { + arr[i] = GridUnsafe.getLongLE(buf, off); + + off += 8; + } + } + else + GridUnsafe.copyMemory(buf, off, arr, LONG_ARR_OFF, bytesToCp); return arr; } @@ -310,7 +343,17 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput { float[] arr = new float[arrSize]; - UNSAFE.copyMemory(buf, byteArrOff + offset(bytesToCp), arr, floatArrOff, bytesToCp); + long off = BYTE_ARR_OFF + offset(bytesToCp); + + if (BIG_ENDIAN) { + for (int i = 0; i < arr.length; i++) { + arr[i] = GridUnsafe.getFloatLE(buf, off); + + off += 4; + } + } + else + GridUnsafe.copyMemory(buf, off, arr, FLOAT_ARR_OFF, bytesToCp); return arr; } @@ -321,14 +364,14 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput { fromStream(len); - UNSAFE.copyMemory(buf, byteArrOff + offset(len), b, byteArrOff, len); + GridUnsafe.copyMemory(buf, BYTE_ARR_OFF + offset(len), b, BYTE_ARR_OFF, len); } /** {@inheritDoc} */ @Override public void readFully(byte[] b, int off, int len) throws IOException { fromStream(len); - UNSAFE.copyMemory(buf, byteArrOff + offset(len), b, byteArrOff + off, len); + GridUnsafe.copyMemory(buf, BYTE_ARR_OFF + offset(len), b, BYTE_ARR_OFF + off, len); } /** {@inheritDoc} */ @@ -345,14 +388,14 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput { @Override public boolean readBoolean() throws IOException { fromStream(1); - return UNSAFE.getBoolean(buf, byteArrOff + offset(1)); + return GridUnsafe.getBoolean(buf, BYTE_ARR_OFF + offset(1)); } /** {@inheritDoc} */ @Override public byte readByte() throws IOException { fromStream(1); - return UNSAFE.getByte(buf, byteArrOff + offset(1)); + return GridUnsafe.getByte(buf, BYTE_ARR_OFF + offset(1)); } /** {@inheritDoc} */ @@ -364,7 +407,9 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput { @Override public short readShort() throws IOException { fromStream(2); - return UNSAFE.getShort(buf, byteArrOff + offset(2)); + long off = BYTE_ARR_OFF + offset(2); + + return BIG_ENDIAN ? GridUnsafe.getShortLE(buf, off) : GridUnsafe.getShort(buf, off); } /** {@inheritDoc} */ @@ -376,7 +421,9 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput { @Override public char readChar() throws IOException { fromStream(2); - char v = UNSAFE.getChar(buf, byteArrOff + off); + long off = BYTE_ARR_OFF + this.off; + + char v = BIG_ENDIAN ? GridUnsafe.getCharLE(buf, off) : GridUnsafe.getChar(buf, off); offset(2); @@ -387,28 +434,32 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput { @Override public int readInt() throws IOException { fromStream(4); - return UNSAFE.getInt(buf, byteArrOff + offset(4)); + long off = BYTE_ARR_OFF + offset(4); + + return BIG_ENDIAN ? GridUnsafe.getIntLE(buf, off) : GridUnsafe.getInt(buf, off); } /** {@inheritDoc} */ @Override public long readLong() throws IOException { fromStream(8); - return UNSAFE.getLong(buf, byteArrOff + offset(8)); + long off = BYTE_ARR_OFF + offset(8); + + return BIG_ENDIAN ? GridUnsafe.getLongLE(buf, off) : GridUnsafe.getLong(buf, off); } /** {@inheritDoc} */ @Override public float readFloat() throws IOException { - fromStream(4); + int v = readInt(); - return UNSAFE.getFloat(buf, byteArrOff + offset(4)); + return Float.intBitsToFloat(v); } /** {@inheritDoc} */ @Override public double readDouble() throws IOException { - fromStream(8); + long v = readLong(); - return UNSAFE.getDouble(buf, byteArrOff + offset(8)); + return Double.longBitsToDouble(v); } /** {@inheritDoc} */ @@ -437,7 +488,7 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput { else { int toRead = Math.min(len, max - this.off); - UNSAFE.copyMemory(buf, byteArrOff + offset(toRead), b, byteArrOff + off, toRead); + GridUnsafe.copyMemory(buf, BYTE_ARR_OFF + offset(toRead), b, BYTE_ARR_OFF + off, toRead); return toRead; } @@ -501,7 +552,7 @@ public class GridUnsafeDataInput extends InputStream implements GridDataInput { else { // shift and refill buffer manually if (avail > 0) - UNSAFE.copyMemory(utfBuf, byteArrOff + pos, utfBuf, byteArrOff, avail); + GridUnsafe.copyMemory(utfBuf, BYTE_ARR_OFF + pos, utfBuf, BYTE_ARR_OFF, avail); pos = 0; end = (int)Math.min(MAX_BLOCK_SIZE, utfLen); http://git-wip-us.apache.org/repos/asf/ignite/blob/a87decdc/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataOutput.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataOutput.java b/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataOutput.java index b7c82a6..c0fe0d3 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataOutput.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/io/GridUnsafeDataOutput.java @@ -22,41 +22,24 @@ import java.io.OutputStream; import org.apache.ignite.internal.util.GridUnsafe; import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; -import sun.misc.Unsafe; import static org.apache.ignite.IgniteSystemProperties.IGNITE_MARSHAL_BUFFERS_RECHECK; +import static org.apache.ignite.internal.util.GridUnsafe.BIG_ENDIAN; +import static org.apache.ignite.internal.util.GridUnsafe.BYTE_ARR_OFF; +import static org.apache.ignite.internal.util.GridUnsafe.CHAR_ARR_OFF; +import static org.apache.ignite.internal.util.GridUnsafe.DOUBLE_ARR_OFF; +import static org.apache.ignite.internal.util.GridUnsafe.FLOAT_ARR_OFF; +import static org.apache.ignite.internal.util.GridUnsafe.INT_ARR_OFF; +import static org.apache.ignite.internal.util.GridUnsafe.LONG_ARR_OFF; +import static org.apache.ignite.internal.util.GridUnsafe.SHORT_ARR_OFF; /** * Data output based on {@code Unsafe} operations. */ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput { - /** Unsafe. */ - private static final Unsafe UNSAFE = GridUnsafe.unsafe(); - /** */ private static final Long CHECK_FREQ = Long.getLong(IGNITE_MARSHAL_BUFFERS_RECHECK, 10000); - /** */ - private static final long byteArrOff = UNSAFE.arrayBaseOffset(byte[].class); - - /** */ - private static final long shortArrOff = UNSAFE.arrayBaseOffset(short[].class); - - /** */ - private static final long intArrOff = UNSAFE.arrayBaseOffset(int[].class); - - /** */ - private static final long longArrOff = UNSAFE.arrayBaseOffset(long[].class); - - /** */ - private static final long floatArrOff = UNSAFE.arrayBaseOffset(float[].class); - - /** */ - private static final long doubleArrOff = UNSAFE.arrayBaseOffset(double[].class); - - /** */ - private static final long charArrOff = UNSAFE.arrayBaseOffset(char[].class); - /** Length of char buffer (for writing strings). */ private static final int CHAR_BUF_SIZE = 256; @@ -114,7 +97,7 @@ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput @Override public byte[] array() { byte[] bytes0 = new byte[off]; - UNSAFE.copyMemory(bytes, byteArrOff, bytes0, byteArrOff, off); + GridUnsafe.copyMemory(bytes, BYTE_ARR_OFF, bytes0, BYTE_ARR_OFF, off); return bytes0; } @@ -147,7 +130,7 @@ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput if (size > bytes.length) { byte[] newBytes = new byte[size << 1]; // Grow. - UNSAFE.copyMemory(bytes, byteArrOff, newBytes, byteArrOff, off); + GridUnsafe.copyMemory(bytes, BYTE_ARR_OFF, newBytes, BYTE_ARR_OFF, off); bytes = newBytes; } @@ -157,7 +140,7 @@ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput if (maxOff < halfSize) { byte[] newBytes = new byte[halfSize]; // Shrink. - UNSAFE.copyMemory(bytes, byteArrOff, newBytes, byteArrOff, off); + GridUnsafe.copyMemory(bytes, BYTE_ARR_OFF, newBytes, BYTE_ARR_OFF, off); bytes = newBytes; } @@ -182,7 +165,7 @@ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput @Override public void write(byte[] b) throws IOException { requestFreeSize(b.length); - UNSAFE.copyMemory(b, byteArrOff, bytes, byteArrOff + off, b.length); + GridUnsafe.copyMemory(b, BYTE_ARR_OFF, bytes, BYTE_ARR_OFF + off, b.length); onWrite(b.length); } @@ -191,7 +174,7 @@ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput @Override public void write(byte[] b, int off, int len) throws IOException { requestFreeSize(len); - UNSAFE.copyMemory(b, byteArrOff + off, bytes, byteArrOff + this.off, len); + GridUnsafe.copyMemory(b, BYTE_ARR_OFF + off, bytes, BYTE_ARR_OFF + this.off, len); onWrite(len); } @@ -204,7 +187,17 @@ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput requestFreeSize(bytesToCp); - UNSAFE.copyMemory(arr, doubleArrOff, bytes, byteArrOff + off, bytesToCp); + if (BIG_ENDIAN) { + long off = BYTE_ARR_OFF + this.off; + + for (double val : arr) { + GridUnsafe.putDoubleLE(bytes, off, val); + + off += 8; + } + } + else + GridUnsafe.copyMemory(arr, DOUBLE_ARR_OFF, bytes, BYTE_ARR_OFF + off, bytesToCp); onWrite(bytesToCp); } @@ -226,7 +219,17 @@ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput requestFreeSize(bytesToCp); - UNSAFE.copyMemory(arr, charArrOff, bytes, byteArrOff + off, bytesToCp); + if (BIG_ENDIAN) { + long off = BYTE_ARR_OFF + this.off; + + for (char val : arr) { + GridUnsafe.putCharLE(bytes, off, val); + + off += 2; + } + } + else + GridUnsafe.copyMemory(arr, CHAR_ARR_OFF, bytes, BYTE_ARR_OFF + off, bytesToCp); onWrite(bytesToCp); } @@ -239,7 +242,17 @@ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput requestFreeSize(bytesToCp); - UNSAFE.copyMemory(arr, longArrOff, bytes, byteArrOff + off, bytesToCp); + if (BIG_ENDIAN) { + long off = BYTE_ARR_OFF + this.off; + + for (long val : arr) { + GridUnsafe.putLongLE(bytes, off, val); + + off += 8; + } + } + else + GridUnsafe.copyMemory(arr, LONG_ARR_OFF, bytes, BYTE_ARR_OFF + off, bytesToCp); onWrite(bytesToCp); } @@ -252,7 +265,17 @@ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput requestFreeSize(bytesToCp); - UNSAFE.copyMemory(arr, floatArrOff, bytes, byteArrOff + off, bytesToCp); + if (BIG_ENDIAN) { + long off = BYTE_ARR_OFF + this.off; + + for (float val : arr) { + GridUnsafe.putFloatLE(bytes, off, val); + + off += 4; + } + } + else + GridUnsafe.copyMemory(arr, FLOAT_ARR_OFF, bytes, BYTE_ARR_OFF + off, bytesToCp); onWrite(bytesToCp); } @@ -270,7 +293,7 @@ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput requestFreeSize(arr.length); - UNSAFE.copyMemory(arr, byteArrOff, bytes, byteArrOff + off, arr.length); + GridUnsafe.copyMemory(arr, BYTE_ARR_OFF, bytes, BYTE_ARR_OFF + off, arr.length); onWrite(arr.length); } @@ -283,7 +306,17 @@ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput requestFreeSize(bytesToCp); - UNSAFE.copyMemory(arr, shortArrOff, bytes, byteArrOff + off, bytesToCp); + if (BIG_ENDIAN) { + long off = BYTE_ARR_OFF + this.off; + + for (short val : arr) { + GridUnsafe.putShortLE(bytes, off, val); + + off += 2; + } + } + else + GridUnsafe.copyMemory(arr, SHORT_ARR_OFF, bytes, BYTE_ARR_OFF + off, bytesToCp); onWrite(bytesToCp); } @@ -296,7 +329,17 @@ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput requestFreeSize(bytesToCp); - UNSAFE.copyMemory(arr, intArrOff, bytes, byteArrOff + off, bytesToCp); + if (BIG_ENDIAN) { + long off = BYTE_ARR_OFF + this.off; + + for (int val : arr) { + GridUnsafe.putIntLE(bytes, off, val); + + off += 4; + } + } + else + GridUnsafe.copyMemory(arr, INT_ARR_OFF, bytes, BYTE_ARR_OFF + off, bytesToCp); onWrite(bytesToCp); } @@ -310,7 +353,7 @@ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput @Override public void writeBoolean(boolean v) throws IOException { requestFreeSize(1); - UNSAFE.putBoolean(bytes, byteArrOff + off, v); + GridUnsafe.putBoolean(bytes, BYTE_ARR_OFF + off, v); onWrite(1); } @@ -319,7 +362,7 @@ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput @Override public void writeByte(int v) throws IOException { requestFreeSize(1); - UNSAFE.putByte(bytes, byteArrOff + off, (byte)v); + GridUnsafe.putByte(bytes, BYTE_ARR_OFF + off, (byte)v); onWrite(1); } @@ -328,7 +371,14 @@ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput @Override public void writeShort(int v) throws IOException { requestFreeSize(2); - UNSAFE.putShort(bytes, byteArrOff + off, (short)v); + short val = (short)v; + + long off = BYTE_ARR_OFF + this.off; + + if (BIG_ENDIAN) + GridUnsafe.putShortLE(bytes, off, val); + else + GridUnsafe.putShort(bytes, off, val); onWrite(2); } @@ -337,7 +387,14 @@ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput @Override public void writeChar(int v) throws IOException { requestFreeSize(2); - UNSAFE.putChar(bytes, byteArrOff + off, (char)v); + char val = (char)v; + + long off = BYTE_ARR_OFF + this.off; + + if (BIG_ENDIAN) + GridUnsafe.putCharLE(bytes, off, val); + else + GridUnsafe.putChar(bytes, off, val); onWrite(2); } @@ -346,7 +403,12 @@ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput @Override public void writeInt(int v) throws IOException { requestFreeSize(4); - UNSAFE.putInt(bytes, byteArrOff + off, v); + long off = BYTE_ARR_OFF + this.off; + + if (BIG_ENDIAN) + GridUnsafe.putIntLE(bytes, off, v); + else + GridUnsafe.putInt(bytes, off, v); onWrite(4); } @@ -355,27 +417,28 @@ public class GridUnsafeDataOutput extends OutputStream implements GridDataOutput @Override public void writeLong(long v) throws IOException { requestFreeSize(8); - UNSAFE.putLong(bytes, byteArrOff + off, v); + long off = BYTE_ARR_OFF + this.off; + + if (BIG_ENDIAN) + GridUnsafe.putLongLE(bytes, off, v); + else + GridUnsafe.putLong(bytes, off, v); onWrite(8); } /** {@inheritDoc} */ @Override public void writeFloat(float v) throws IOException { - requestFreeSize(4); + int val = Float.floatToIntBits(v); - UNSAFE.putFloat(bytes, byteArrOff + off, v); - - onWrite(4); + writeInt(val); } /** {@inheritDoc} */ @Override public void writeDouble(double v) throws IOException { - requestFreeSize(8); - - UNSAFE.putDouble(bytes, byteArrOff + off, v); + long val = Double.doubleToLongBits(v); - onWrite(8); + writeLong(val); } /** {@inheritDoc} */
