1. /*
  2. * @(#)Bits.java 1.18 04/05/24
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.nio;
  8. import java.security.AccessController;
  9. import java.security.PrivilegedAction;
  10. import sun.misc.Unsafe;
  11. import sun.misc.VM;
  12. /**
  13. * Access to bits, native and otherwise.
  14. */
  15. class Bits { // package-private
  16. private Bits() { }
  17. // -- Swapping --
  18. static short swap(short x) {
  19. return (short)((x << 8) |
  20. ((x >> 8) & 0xff));
  21. }
  22. static char swap(char x) {
  23. return (char)((x << 8) |
  24. ((x >> 8) & 0xff));
  25. }
  26. static int swap(int x) {
  27. return (int)((swap((short)x) << 16) |
  28. (swap((short)(x >> 16)) & 0xffff));
  29. }
  30. static long swap(long x) {
  31. return (long)(((long)swap((int)(x)) << 32) |
  32. ((long)swap((int)(x >> 32)) & 0xffffffffL));
  33. }
  34. // -- get/put char --
  35. static private char makeChar(byte b1, byte b0) {
  36. return (char)((b1 << 8) | (b0 & 0xff));
  37. }
  38. static char getCharL(ByteBuffer bb, int bi) {
  39. return makeChar(bb._get(bi + 1),
  40. bb._get(bi + 0));
  41. }
  42. static char getCharL(long a) {
  43. return makeChar(_get(a + 1),
  44. _get(a + 0));
  45. }
  46. static char getCharB(ByteBuffer bb, int bi) {
  47. return makeChar(bb._get(bi + 0),
  48. bb._get(bi + 1));
  49. }
  50. static char getCharB(long a) {
  51. return makeChar(_get(a + 0),
  52. _get(a + 1));
  53. }
  54. static char getChar(ByteBuffer bb, int bi, boolean bigEndian) {
  55. return (bigEndian ? getCharB(bb, bi) : getCharL(bb, bi));
  56. }
  57. static char getChar(long a, boolean bigEndian) {
  58. return (bigEndian ? getCharB(a) : getCharL(a));
  59. }
  60. private static byte char1(char x) { return (byte)(x >> 8); }
  61. private static byte char0(char x) { return (byte)(x >> 0); }
  62. static void putCharL(ByteBuffer bb, int bi, char x) {
  63. bb._put(bi + 0, char0(x));
  64. bb._put(bi + 1, char1(x));
  65. }
  66. static void putCharL(long a, char x) {
  67. _put(a + 0, char0(x));
  68. _put(a + 1, char1(x));
  69. }
  70. static void putCharB(ByteBuffer bb, int bi, char x) {
  71. bb._put(bi + 0, char1(x));
  72. bb._put(bi + 1, char0(x));
  73. }
  74. static void putCharB(long a, char x) {
  75. _put(a + 0, char1(x));
  76. _put(a + 1, char0(x));
  77. }
  78. static void putChar(ByteBuffer bb, int bi, char x, boolean bigEndian) {
  79. if (bigEndian)
  80. putCharB(bb, bi, x);
  81. else
  82. putCharL(bb, bi, x);
  83. }
  84. static void putChar(long a, char x, boolean bigEndian) {
  85. if (bigEndian)
  86. putCharB(a, x);
  87. else
  88. putCharL(a, x);
  89. }
  90. // -- get/put short --
  91. static private short makeShort(byte b1, byte b0) {
  92. return (short)((b1 << 8) | (b0 & 0xff));
  93. }
  94. static short getShortL(ByteBuffer bb, int bi) {
  95. return makeShort(bb._get(bi + 1),
  96. bb._get(bi + 0));
  97. }
  98. static short getShortL(long a) {
  99. return makeShort(_get(a + 1),
  100. _get(a));
  101. }
  102. static short getShortB(ByteBuffer bb, int bi) {
  103. return makeShort(bb._get(bi + 0),
  104. bb._get(bi + 1));
  105. }
  106. static short getShortB(long a) {
  107. return makeShort(_get(a),
  108. _get(a + 1));
  109. }
  110. static short getShort(ByteBuffer bb, int bi, boolean bigEndian) {
  111. return (bigEndian ? getShortB(bb, bi) : getShortL(bb, bi));
  112. }
  113. static short getShort(long a, boolean bigEndian) {
  114. return (bigEndian ? getShortB(a) : getShortL(a));
  115. }
  116. private static byte short1(short x) { return (byte)(x >> 8); }
  117. private static byte short0(short x) { return (byte)(x >> 0); }
  118. static void putShortL(ByteBuffer bb, int bi, short x) {
  119. bb._put(bi + 0, short0(x));
  120. bb._put(bi + 1, short1(x));
  121. }
  122. static void putShortL(long a, short x) {
  123. _put(a, short0(x));
  124. _put(a + 1, short1(x));
  125. }
  126. static void putShortB(ByteBuffer bb, int bi, short x) {
  127. bb._put(bi + 0, short1(x));
  128. bb._put(bi + 1, short0(x));
  129. }
  130. static void putShortB(long a, short x) {
  131. _put(a, short1(x));
  132. _put(a + 1, short0(x));
  133. }
  134. static void putShort(ByteBuffer bb, int bi, short x, boolean bigEndian) {
  135. if (bigEndian)
  136. putShortB(bb, bi, x);
  137. else
  138. putShortL(bb, bi, x);
  139. }
  140. static void putShort(long a, short x, boolean bigEndian) {
  141. if (bigEndian)
  142. putShortB(a, x);
  143. else
  144. putShortL(a, x);
  145. }
  146. // -- get/put int --
  147. static private int makeInt(byte b3, byte b2, byte b1, byte b0) {
  148. return (int)((((b3 & 0xff) << 24) |
  149. ((b2 & 0xff) << 16) |
  150. ((b1 & 0xff) << 8) |
  151. ((b0 & 0xff) << 0)));
  152. }
  153. static int getIntL(ByteBuffer bb, int bi) {
  154. return makeInt(bb._get(bi + 3),
  155. bb._get(bi + 2),
  156. bb._get(bi + 1),
  157. bb._get(bi + 0));
  158. }
  159. static int getIntL(long a) {
  160. return makeInt(_get(a + 3),
  161. _get(a + 2),
  162. _get(a + 1),
  163. _get(a + 0));
  164. }
  165. static int getIntB(ByteBuffer bb, int bi) {
  166. return makeInt(bb._get(bi + 0),
  167. bb._get(bi + 1),
  168. bb._get(bi + 2),
  169. bb._get(bi + 3));
  170. }
  171. static int getIntB(long a) {
  172. return makeInt(_get(a + 0),
  173. _get(a + 1),
  174. _get(a + 2),
  175. _get(a + 3));
  176. }
  177. static int getInt(ByteBuffer bb, int bi, boolean bigEndian) {
  178. return (bigEndian ? getIntB(bb, bi) : getIntL(bb, bi));
  179. }
  180. static int getInt(long a, boolean bigEndian) {
  181. return (bigEndian ? getIntB(a) : getIntL(a));
  182. }
  183. private static byte int3(int x) { return (byte)(x >> 24); }
  184. private static byte int2(int x) { return (byte)(x >> 16); }
  185. private static byte int1(int x) { return (byte)(x >> 8); }
  186. private static byte int0(int x) { return (byte)(x >> 0); }
  187. static void putIntL(ByteBuffer bb, int bi, int x) {
  188. bb._put(bi + 3, int3(x));
  189. bb._put(bi + 2, int2(x));
  190. bb._put(bi + 1, int1(x));
  191. bb._put(bi + 0, int0(x));
  192. }
  193. static void putIntL(long a, int x) {
  194. _put(a + 3, int3(x));
  195. _put(a + 2, int2(x));
  196. _put(a + 1, int1(x));
  197. _put(a + 0, int0(x));
  198. }
  199. static void putIntB(ByteBuffer bb, int bi, int x) {
  200. bb._put(bi + 0, int3(x));
  201. bb._put(bi + 1, int2(x));
  202. bb._put(bi + 2, int1(x));
  203. bb._put(bi + 3, int0(x));
  204. }
  205. static void putIntB(long a, int x) {
  206. _put(a + 0, int3(x));
  207. _put(a + 1, int2(x));
  208. _put(a + 2, int1(x));
  209. _put(a + 3, int0(x));
  210. }
  211. static void putInt(ByteBuffer bb, int bi, int x, boolean bigEndian) {
  212. if (bigEndian)
  213. putIntB(bb, bi, x);
  214. else
  215. putIntL(bb, bi, x);
  216. }
  217. static void putInt(long a, int x, boolean bigEndian) {
  218. if (bigEndian)
  219. putIntB(a, x);
  220. else
  221. putIntL(a, x);
  222. }
  223. // -- get/put long --
  224. static private long makeLong(byte b7, byte b6, byte b5, byte b4,
  225. byte b3, byte b2, byte b1, byte b0)
  226. {
  227. return ((((long)b7 & 0xff) << 56) |
  228. (((long)b6 & 0xff) << 48) |
  229. (((long)b5 & 0xff) << 40) |
  230. (((long)b4 & 0xff) << 32) |
  231. (((long)b3 & 0xff) << 24) |
  232. (((long)b2 & 0xff) << 16) |
  233. (((long)b1 & 0xff) << 8) |
  234. (((long)b0 & 0xff) << 0));
  235. }
  236. static long getLongL(ByteBuffer bb, int bi) {
  237. return makeLong(bb._get(bi + 7),
  238. bb._get(bi + 6),
  239. bb._get(bi + 5),
  240. bb._get(bi + 4),
  241. bb._get(bi + 3),
  242. bb._get(bi + 2),
  243. bb._get(bi + 1),
  244. bb._get(bi + 0));
  245. }
  246. static long getLongL(long a) {
  247. return makeLong(_get(a + 7),
  248. _get(a + 6),
  249. _get(a + 5),
  250. _get(a + 4),
  251. _get(a + 3),
  252. _get(a + 2),
  253. _get(a + 1),
  254. _get(a + 0));
  255. }
  256. static long getLongB(ByteBuffer bb, int bi) {
  257. return makeLong(bb._get(bi + 0),
  258. bb._get(bi + 1),
  259. bb._get(bi + 2),
  260. bb._get(bi + 3),
  261. bb._get(bi + 4),
  262. bb._get(bi + 5),
  263. bb._get(bi + 6),
  264. bb._get(bi + 7));
  265. }
  266. static long getLongB(long a) {
  267. return makeLong(_get(a + 0),
  268. _get(a + 1),
  269. _get(a + 2),
  270. _get(a + 3),
  271. _get(a + 4),
  272. _get(a + 5),
  273. _get(a + 6),
  274. _get(a + 7));
  275. }
  276. static long getLong(ByteBuffer bb, int bi, boolean bigEndian) {
  277. return (bigEndian ? getLongB(bb, bi) : getLongL(bb, bi));
  278. }
  279. static long getLong(long a, boolean bigEndian) {
  280. return (bigEndian ? getLongB(a) : getLongL(a));
  281. }
  282. private static byte long7(long x) { return (byte)(x >> 56); }
  283. private static byte long6(long x) { return (byte)(x >> 48); }
  284. private static byte long5(long x) { return (byte)(x >> 40); }
  285. private static byte long4(long x) { return (byte)(x >> 32); }
  286. private static byte long3(long x) { return (byte)(x >> 24); }
  287. private static byte long2(long x) { return (byte)(x >> 16); }
  288. private static byte long1(long x) { return (byte)(x >> 8); }
  289. private static byte long0(long x) { return (byte)(x >> 0); }
  290. static void putLongL(ByteBuffer bb, int bi, long x) {
  291. bb._put(bi + 7, long7(x));
  292. bb._put(bi + 6, long6(x));
  293. bb._put(bi + 5, long5(x));
  294. bb._put(bi + 4, long4(x));
  295. bb._put(bi + 3, long3(x));
  296. bb._put(bi + 2, long2(x));
  297. bb._put(bi + 1, long1(x));
  298. bb._put(bi + 0, long0(x));
  299. }
  300. static void putLongL(long a, long x) {
  301. _put(a + 7, long7(x));
  302. _put(a + 6, long6(x));
  303. _put(a + 5, long5(x));
  304. _put(a + 4, long4(x));
  305. _put(a + 3, long3(x));
  306. _put(a + 2, long2(x));
  307. _put(a + 1, long1(x));
  308. _put(a + 0, long0(x));
  309. }
  310. static void putLongB(ByteBuffer bb, int bi, long x) {
  311. bb._put(bi + 0, long7(x));
  312. bb._put(bi + 1, long6(x));
  313. bb._put(bi + 2, long5(x));
  314. bb._put(bi + 3, long4(x));
  315. bb._put(bi + 4, long3(x));
  316. bb._put(bi + 5, long2(x));
  317. bb._put(bi + 6, long1(x));
  318. bb._put(bi + 7, long0(x));
  319. }
  320. static void putLongB(long a, long x) {
  321. _put(a + 0, long7(x));
  322. _put(a + 1, long6(x));
  323. _put(a + 2, long5(x));
  324. _put(a + 3, long4(x));
  325. _put(a + 4, long3(x));
  326. _put(a + 5, long2(x));
  327. _put(a + 6, long1(x));
  328. _put(a + 7, long0(x));
  329. }
  330. static void putLong(ByteBuffer bb, int bi, long x, boolean bigEndian) {
  331. if (bigEndian)
  332. putLongB(bb, bi, x);
  333. else
  334. putLongL(bb, bi, x);
  335. }
  336. static void putLong(long a, long x, boolean bigEndian) {
  337. if (bigEndian)
  338. putLongB(a, x);
  339. else
  340. putLongL(a, x);
  341. }
  342. // -- get/put float --
  343. static float getFloatL(ByteBuffer bb, int bi) {
  344. return Float.intBitsToFloat(getIntL(bb, bi));
  345. }
  346. static float getFloatL(long a) {
  347. return Float.intBitsToFloat(getIntL(a));
  348. }
  349. static float getFloatB(ByteBuffer bb, int bi) {
  350. return Float.intBitsToFloat(getIntB(bb, bi));
  351. }
  352. static float getFloatB(long a) {
  353. return Float.intBitsToFloat(getIntB(a));
  354. }
  355. static float getFloat(ByteBuffer bb, int bi, boolean bigEndian) {
  356. return (bigEndian ? getFloatB(bb, bi) : getFloatL(bb, bi));
  357. }
  358. static float getFloat(long a, boolean bigEndian) {
  359. return (bigEndian ? getFloatB(a) : getFloatL(a));
  360. }
  361. static void putFloatL(ByteBuffer bb, int bi, float x) {
  362. putIntL(bb, bi, Float.floatToRawIntBits(x));
  363. }
  364. static void putFloatL(long a, float x) {
  365. putIntL(a, Float.floatToRawIntBits(x));
  366. }
  367. static void putFloatB(ByteBuffer bb, int bi, float x) {
  368. putIntB(bb, bi, Float.floatToRawIntBits(x));
  369. }
  370. static void putFloatB(long a, float x) {
  371. putIntB(a, Float.floatToRawIntBits(x));
  372. }
  373. static void putFloat(ByteBuffer bb, int bi, float x, boolean bigEndian) {
  374. if (bigEndian)
  375. putFloatB(bb, bi, x);
  376. else
  377. putFloatL(bb, bi, x);
  378. }
  379. static void putFloat(long a, float x, boolean bigEndian) {
  380. if (bigEndian)
  381. putFloatB(a, x);
  382. else
  383. putFloatL(a, x);
  384. }
  385. // -- get/put double --
  386. static double getDoubleL(ByteBuffer bb, int bi) {
  387. return Double.longBitsToDouble(getLongL(bb, bi));
  388. }
  389. static double getDoubleL(long a) {
  390. return Double.longBitsToDouble(getLongL(a));
  391. }
  392. static double getDoubleB(ByteBuffer bb, int bi) {
  393. return Double.longBitsToDouble(getLongB(bb, bi));
  394. }
  395. static double getDoubleB(long a) {
  396. return Double.longBitsToDouble(getLongB(a));
  397. }
  398. static double getDouble(ByteBuffer bb, int bi, boolean bigEndian) {
  399. return (bigEndian ? getDoubleB(bb, bi) : getDoubleL(bb, bi));
  400. }
  401. static double getDouble(long a, boolean bigEndian) {
  402. return (bigEndian ? getDoubleB(a) : getDoubleL(a));
  403. }
  404. static void putDoubleL(ByteBuffer bb, int bi, double x) {
  405. putLongL(bb, bi, Double.doubleToRawLongBits(x));
  406. }
  407. static void putDoubleL(long a, double x) {
  408. putLongL(a, Double.doubleToRawLongBits(x));
  409. }
  410. static void putDoubleB(ByteBuffer bb, int bi, double x) {
  411. putLongB(bb, bi, Double.doubleToRawLongBits(x));
  412. }
  413. static void putDoubleB(long a, double x) {
  414. putLongB(a, Double.doubleToRawLongBits(x));
  415. }
  416. static void putDouble(ByteBuffer bb, int bi, double x, boolean bigEndian) {
  417. if (bigEndian)
  418. putDoubleB(bb, bi, x);
  419. else
  420. putDoubleL(bb, bi, x);
  421. }
  422. static void putDouble(long a, double x, boolean bigEndian) {
  423. if (bigEndian)
  424. putDoubleB(a, x);
  425. else
  426. putDoubleL(a, x);
  427. }
  428. // -- Unsafe access --
  429. private static final Unsafe unsafe = Unsafe.getUnsafe();
  430. private static byte _get(long a) {
  431. return unsafe.getByte(a);
  432. }
  433. private static void _put(long a, byte b) {
  434. unsafe.putByte(a, b);
  435. }
  436. static Unsafe unsafe() {
  437. return unsafe;
  438. }
  439. // -- Processor and memory-system properties --
  440. private static ByteOrder byteOrder = null;
  441. static ByteOrder byteOrder() {
  442. if (byteOrder != null)
  443. return byteOrder;
  444. long a = unsafe.allocateMemory(8);
  445. try {
  446. unsafe.putLong(a, 0x0102030405060708L);
  447. byte b = unsafe.getByte(a);
  448. switch (b) {
  449. case 0x01: byteOrder = ByteOrder.BIG_ENDIAN; break;
  450. case 0x08: byteOrder = ByteOrder.LITTLE_ENDIAN; break;
  451. default:
  452. throw new Error("Unknown byte order");
  453. }
  454. } finally {
  455. unsafe.freeMemory(a);
  456. }
  457. return byteOrder;
  458. }
  459. private static int pageSize = -1;
  460. static int pageSize() {
  461. if (pageSize == -1)
  462. pageSize = unsafe().pageSize();
  463. return pageSize;
  464. }
  465. private static boolean unaligned;
  466. private static boolean unalignedKnown = false;
  467. static boolean unaligned() {
  468. if (unalignedKnown)
  469. return unaligned;
  470. PrivilegedAction pa
  471. = new sun.security.action.GetPropertyAction("os.arch");
  472. String arch = (String)AccessController.doPrivileged(pa);
  473. unaligned = arch.equals("i386") || arch.equals("x86");
  474. unalignedKnown = true;
  475. return unaligned;
  476. }
  477. // -- Direct memory management --
  478. // A user-settable upper limit on the maximum amount of allocatable
  479. // direct buffer memory. This value may be changed during VM
  480. // initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
  481. private static volatile long maxMemory = VM.maxDirectMemory();
  482. private static volatile long reservedMemory = 0;
  483. private static boolean memoryLimitSet = false;
  484. // These methods should be called whenever direct memory is allocated or
  485. // freed. They allow the user to control the amount of direct memory
  486. // which a process may access. All sizes are specified in bytes.
  487. static void reserveMemory(long size) {
  488. synchronized (Bits.class) {
  489. if (!memoryLimitSet && VM.isBooted()) {
  490. maxMemory = VM.maxDirectMemory();
  491. memoryLimitSet = true;
  492. }
  493. if (size <= maxMemory - reservedMemory) {
  494. reservedMemory += size;
  495. return;
  496. }
  497. }
  498. System.gc();
  499. try {
  500. Thread.sleep(100);
  501. } catch (InterruptedException x) {
  502. // Restore interrupt status
  503. Thread.currentThread().interrupt();
  504. }
  505. synchronized (Bits.class) {
  506. if (reservedMemory + size > maxMemory)
  507. throw new OutOfMemoryError("Direct buffer memory");
  508. reservedMemory += size;
  509. }
  510. }
  511. static synchronized void unreserveMemory(long size) {
  512. if (reservedMemory > 0) {
  513. reservedMemory -= size;
  514. assert (reservedMemory > -1);
  515. }
  516. }
  517. // -- Bulk get/put acceleration --
  518. // These numbers represent the point at which we have empirically
  519. // determined that the average cost of a JNI call exceeds the expense
  520. // of an element by element copy. These numbers may change over time.
  521. static final int JNI_COPY_TO_ARRAY_THRESHOLD = 6;
  522. static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6;
  523. // These methods do no bounds checking. Verification that the copy will not
  524. // result in memory corruption should be done prior to invocation.
  525. // All positions and lengths are specified in bytes.
  526. static native void copyFromByteArray(Object src, long srcPos, long dstAddr,
  527. long length);
  528. static native void copyToByteArray(long srcAddr, Object dst, long dstPos,
  529. long length);
  530. static void copyFromCharArray(Object src, long srcPos, long dstAddr,
  531. long length)
  532. {
  533. copyFromShortArray(src, srcPos, dstAddr, length);
  534. }
  535. static void copyToCharArray(long srcAddr, Object dst, long dstPos,
  536. long length)
  537. {
  538. copyToShortArray(srcAddr, dst, dstPos, length);
  539. }
  540. static native void copyFromShortArray(Object src, long srcPos, long dstAddr,
  541. long length);
  542. static native void copyToShortArray(long srcAddr, Object dst, long dstPos,
  543. long length);
  544. static native void copyFromIntArray(Object src, long srcPos, long dstAddr,
  545. long length);
  546. static native void copyToIntArray(long srcAddr, Object dst, long dstPos,
  547. long length);
  548. static native void copyFromLongArray(Object src, long srcPos, long dstAddr,
  549. long length);
  550. static native void copyToLongArray(long srcAddr, Object dst, long dstPos,
  551. long length);
  552. }