You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2016/02/04 11:09:30 UTC
[27/50] [abbrv] ignite git commit: ignite-2080 Data alignment issues
with Unsafe
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} */