package com.ximple.eofms.util; //~--- JDK imports ------------------------------------------------------------ import java.nio.ByteOrder; import java.security.AccessController; import java.security.PrivilegedAction; import sun.misc.VM; /** * Bits * User: Ulysses * Date: 2007/6/17 * Time: 上午 01:16:39 */ public class Bits { // -- Unsafe access -- // private static final Unsafe unsafe = Unsafe.getUnsafe(); // -- Processor and memory-system properties -- private static ByteOrder byteOrder = null; private static int pageSize = -1; private static boolean unaligned; private static boolean unalignedKnown = false; // -- Direct memory management -- // A user-settable upper limit on the maximum amount of allocatable // direct buffer memory. This value may be changed during VM // initialization if it is launched with "-XX:MaxDirectMemorySize=". private static volatile long maxMemory = VM.maxDirectMemory(); private static volatile long reservedMemory = 0; private static boolean memoryLimitSet = false; private Bits() { } // -- Swapping -- public static short swap(short x) { return (short) ((x << 8) | ((x >> 8) & 0xff)); } public static char swap(char x) { return (char) ((x << 8) | ((x >> 8) & 0xff)); } public static int swap(int x) { return (int) ((swap((short) x) << 16) | (swap((short) (x >> 16)) & 0xffff)); } public static long swap(long x) { return (long) (((long) swap((int) (x)) << 32) | ((long) swap((int) (x >> 32)) & 0xffffffffL)); } // -- get/put char -- static private char makeChar(byte b1, byte b0) { return (char) ((b1 << 8) | (b0 & 0xff)); } private static byte char1(char x) { return (byte) (x >> 8); } private static byte char0(char x) { return (byte) (x >> 0); } // --get/put short-- public static short makeShort(byte b1, byte b0) { return (short) ((b1 << 8) | (b0 & 0xff)); } private static byte short1(short x) { return (byte) (x >> 8); } public static byte short0(short x) { return (byte) (x >> 0); } // -- get/put int -- public static int makeInt(byte b3, byte b2, byte b1, byte b0) { return (int) ((((b3 & 0xff) << 24) | ((b2 & 0xff) << 16) | ((b1 & 0xff) << 8) | ((b0 & 0xff) << 0))); } public static int makeInt(short hiword, short loword) { return ((hiword & 0xffff) << 16) + (loword & 0xffff); } public static short getHiShort(int qwValue) { return ((short) (qwValue >>> 16)); } public static short getLoShort(int qwValue) { return ((short) (qwValue & 0xFFFF)); } public static byte int3(int x) { return (byte) (x >> 24); } public static byte int2(int x) { return (byte) (x >> 16); } private static byte int1(int x) { return (byte) (x >> 8); } private static byte int0(int x) { return (byte) (x >> 0); } // -- get/put long -- public static long makeLong(byte b7, byte b6, byte b5, byte b4, byte b3, byte b2, byte b1, byte b0) { return ((((long) b7 & 0xff) << 56) | (((long) b6 & 0xff) << 48) | (((long) b5 & 0xff) << 40) | (((long) b4 & 0xff) << 32) | (((long) b3 & 0xff) << 24) | (((long) b2 & 0xff) << 16) | (((long) b1 & 0xff) << 8) | (((long) b0 & 0xff) << 0)); } public static long makeLong(int LoValue, int HiValue) { return (((long) HiValue & 0xFFFFFFFF) << 32) + (((long) LoValue) & 0xFFFFFFFF); } public static int getHiInt(long qwValue) { return ((int) (qwValue >>> 32)); } public static int getLoInt(long qwValue) { return ((int) (qwValue & 0xFFFFFFFF)); } private static byte long7(long x) { return (byte) (x >> 56); } private static byte long6(long x) { return (byte) (x >> 48); } private static byte long5(long x) { return (byte) (x >> 40); } private static byte long4(long x) { return (byte) (x >> 32); } private static byte long3(long x) { return (byte) (x >> 24); } private static byte long2(long x) { return (byte) (x >> 16); } private static byte long1(long x) { return (byte) (x >> 8); } private static byte long0(long x) { return (byte) (x >> 0); } // -- get/put float -- // -- get/put double -- /* private static byte _get(long a) { return unsafe.getByte(a); } private static void _put(long a, byte b) { unsafe.putByte(a, b); } static Unsafe unsafe() { return unsafe; } static ByteOrder byteOrder() { if (byteOrder != null) { return byteOrder; } long a = unsafe.allocateMemory(8); try { unsafe.putLong(a, 0x0102030405060708L); byte b = unsafe.getByte(a); switch (b) { case 0x01 : byteOrder = ByteOrder.BIG_ENDIAN; break; case 0x08 : byteOrder = ByteOrder.LITTLE_ENDIAN; break; default : throw new Error("Unknown byte order"); } } finally { unsafe.freeMemory(a); } return byteOrder; } */ static boolean unaligned() { if (unalignedKnown) { return unaligned; } PrivilegedAction pa = new sun.security.action.GetPropertyAction("os.arch"); String arch = (String) AccessController.doPrivileged(pa); unaligned = arch.equals("i386") || arch.equals("x86"); unalignedKnown = true; return unaligned; } // These methods should be called whenever direct memory is allocated or // freed. They allow the user to control the amount of direct memory // which a process may access. All sizes are specified in bytes. static void reserveMemory(long size) { synchronized (Bits.class) { if (!memoryLimitSet && VM.isBooted()) { maxMemory = VM.maxDirectMemory(); memoryLimitSet = true; } if (size <= maxMemory - reservedMemory) { reservedMemory += size; return; } } System.gc(); try { Thread.sleep(100); } catch (InterruptedException x) { // Restore interrupt status Thread.currentThread().interrupt(); } synchronized (Bits.class) { if (reservedMemory + size > maxMemory) { throw new OutOfMemoryError("Direct buffer memory"); } reservedMemory += size; } } static synchronized void unreserveMemory(long size) { if (reservedMemory > 0) { reservedMemory -= size; assert (reservedMemory > -1); } } }