You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2016/02/03 07:10:07 UTC

[3/8] 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} */