KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > nio > Bits


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
8 package java.nio;
9
10 import java.security.AccessController JavaDoc;
11 import java.security.PrivilegedAction JavaDoc;
12 import sun.misc.Unsafe;
13 import sun.misc.VM;
14
15 /**
16  * Access to bits, native and otherwise.
17  */

18
19 class Bits { // package-private
20

21     private Bits() { }
22
23
24     // -- Swapping --
25

26     static short swap(short x) {
27     return (short)((x << 8) |
28                ((x >> 8) & 0xff));
29     }
30
31     static char swap(char x) {
32     return (char)((x << 8) |
33               ((x >> 8) & 0xff));
34     }
35
36     static int swap(int x) {
37     return (int)((swap((short)x) << 16) |
38              (swap((short)(x >> 16)) & 0xffff));
39     }
40
41     static long swap(long x) {
42     return (long)(((long)swap((int)(x)) << 32) |
43               ((long)swap((int)(x >> 32)) & 0xffffffffL));
44     }
45
46
47     // -- get/put char --
48

49     static private char makeChar(byte b1, byte b0) {
50     return (char)((b1 << 8) | (b0 & 0xff));
51     }
52
53     static char getCharL(ByteBuffer JavaDoc bb, int bi) {
54     return makeChar(bb._get(bi + 1),
55             bb._get(bi + 0));
56     }
57
58     static char getCharL(long a) {
59     return makeChar(_get(a + 1),
60             _get(a + 0));
61     }
62
63     static char getCharB(ByteBuffer JavaDoc bb, int bi) {
64     return makeChar(bb._get(bi + 0),
65             bb._get(bi + 1));
66     }
67
68     static char getCharB(long a) {
69     return makeChar(_get(a + 0),
70             _get(a + 1));
71     }
72
73     static char getChar(ByteBuffer JavaDoc bb, int bi, boolean bigEndian) {
74     return (bigEndian ? getCharB(bb, bi) : getCharL(bb, bi));
75     }
76
77     static char getChar(long a, boolean bigEndian) {
78     return (bigEndian ? getCharB(a) : getCharL(a));
79     }
80
81     private static byte char1(char x) { return (byte)(x >> 8); }
82     private static byte char0(char x) { return (byte)(x >> 0); }
83
84     static void putCharL(ByteBuffer JavaDoc bb, int bi, char x) {
85     bb._put(bi + 0, char0(x));
86     bb._put(bi + 1, char1(x));
87     }
88
89     static void putCharL(long a, char x) {
90     _put(a + 0, char0(x));
91     _put(a + 1, char1(x));
92     }
93
94     static void putCharB(ByteBuffer JavaDoc bb, int bi, char x) {
95     bb._put(bi + 0, char1(x));
96     bb._put(bi + 1, char0(x));
97     }
98
99     static void putCharB(long a, char x) {
100     _put(a + 0, char1(x));
101     _put(a + 1, char0(x));
102     }
103
104     static void putChar(ByteBuffer JavaDoc bb, int bi, char x, boolean bigEndian) {
105     if (bigEndian)
106         putCharB(bb, bi, x);
107     else
108         putCharL(bb, bi, x);
109     }
110
111     static void putChar(long a, char x, boolean bigEndian) {
112     if (bigEndian)
113         putCharB(a, x);
114     else
115         putCharL(a, x);
116     }
117
118
119     // -- get/put short --
120

121     static private short makeShort(byte b1, byte b0) {
122     return (short)((b1 << 8) | (b0 & 0xff));
123     }
124
125     static short getShortL(ByteBuffer JavaDoc bb, int bi) {
126     return makeShort(bb._get(bi + 1),
127              bb._get(bi + 0));
128     }
129
130     static short getShortL(long a) {
131     return makeShort(_get(a + 1),
132              _get(a));
133     }
134
135     static short getShortB(ByteBuffer JavaDoc bb, int bi) {
136     return makeShort(bb._get(bi + 0),
137              bb._get(bi + 1));
138     }
139
140     static short getShortB(long a) {
141     return makeShort(_get(a),
142              _get(a + 1));
143     }
144
145     static short getShort(ByteBuffer JavaDoc bb, int bi, boolean bigEndian) {
146     return (bigEndian ? getShortB(bb, bi) : getShortL(bb, bi));
147     }
148
149     static short getShort(long a, boolean bigEndian) {
150     return (bigEndian ? getShortB(a) : getShortL(a));
151     }
152
153     private static byte short1(short x) { return (byte)(x >> 8); }
154     private static byte short0(short x) { return (byte)(x >> 0); }
155
156     static void putShortL(ByteBuffer JavaDoc bb, int bi, short x) {
157     bb._put(bi + 0, short0(x));
158     bb._put(bi + 1, short1(x));
159     }
160
161     static void putShortL(long a, short x) {
162     _put(a, short0(x));
163     _put(a + 1, short1(x));
164     }
165
166     static void putShortB(ByteBuffer JavaDoc bb, int bi, short x) {
167     bb._put(bi + 0, short1(x));
168     bb._put(bi + 1, short0(x));
169     }
170
171     static void putShortB(long a, short x) {
172     _put(a, short1(x));
173     _put(a + 1, short0(x));
174     }
175
176     static void putShort(ByteBuffer JavaDoc bb, int bi, short x, boolean bigEndian) {
177     if (bigEndian)
178         putShortB(bb, bi, x);
179     else
180         putShortL(bb, bi, x);
181     }
182
183     static void putShort(long a, short x, boolean bigEndian) {
184     if (bigEndian)
185         putShortB(a, x);
186     else
187         putShortL(a, x);
188     }
189
190
191     // -- get/put int --
192

193     static private int makeInt(byte b3, byte b2, byte b1, byte b0) {
194     return (int)((((b3 & 0xff) << 24) |
195               ((b2 & 0xff) << 16) |
196               ((b1 & 0xff) << 8) |
197               ((b0 & 0xff) << 0)));
198     }
199
200     static int getIntL(ByteBuffer JavaDoc bb, int bi) {
201     return makeInt(bb._get(bi + 3),
202                bb._get(bi + 2),
203                bb._get(bi + 1),
204                bb._get(bi + 0));
205     }
206
207     static int getIntL(long a) {
208     return makeInt(_get(a + 3),
209                _get(a + 2),
210                _get(a + 1),
211                _get(a + 0));
212     }
213
214     static int getIntB(ByteBuffer JavaDoc bb, int bi) {
215     return makeInt(bb._get(bi + 0),
216                bb._get(bi + 1),
217                bb._get(bi + 2),
218                bb._get(bi + 3));
219     }
220
221     static int getIntB(long a) {
222     return makeInt(_get(a + 0),
223                _get(a + 1),
224                _get(a + 2),
225                _get(a + 3));
226     }
227
228     static int getInt(ByteBuffer JavaDoc bb, int bi, boolean bigEndian) {
229     return (bigEndian ? getIntB(bb, bi) : getIntL(bb, bi));
230     }
231
232     static int getInt(long a, boolean bigEndian) {
233     return (bigEndian ? getIntB(a) : getIntL(a));
234     }
235
236     private static byte int3(int x) { return (byte)(x >> 24); }
237     private static byte int2(int x) { return (byte)(x >> 16); }
238     private static byte int1(int x) { return (byte)(x >> 8); }
239     private static byte int0(int x) { return (byte)(x >> 0); }
240
241     static void putIntL(ByteBuffer JavaDoc bb, int bi, int x) {
242     bb._put(bi + 3, int3(x));
243     bb._put(bi + 2, int2(x));
244     bb._put(bi + 1, int1(x));
245     bb._put(bi + 0, int0(x));
246     }
247
248     static void putIntL(long a, int x) {
249     _put(a + 3, int3(x));
250     _put(a + 2, int2(x));
251     _put(a + 1, int1(x));
252     _put(a + 0, int0(x));
253     }
254
255     static void putIntB(ByteBuffer JavaDoc bb, int bi, int x) {
256     bb._put(bi + 0, int3(x));
257     bb._put(bi + 1, int2(x));
258     bb._put(bi + 2, int1(x));
259     bb._put(bi + 3, int0(x));
260     }
261
262     static void putIntB(long a, int x) {
263     _put(a + 0, int3(x));
264     _put(a + 1, int2(x));
265     _put(a + 2, int1(x));
266     _put(a + 3, int0(x));
267     }
268
269     static void putInt(ByteBuffer JavaDoc bb, int bi, int x, boolean bigEndian) {
270     if (bigEndian)
271         putIntB(bb, bi, x);
272     else
273         putIntL(bb, bi, x);
274     }
275
276     static void putInt(long a, int x, boolean bigEndian) {
277     if (bigEndian)
278         putIntB(a, x);
279     else
280         putIntL(a, x);
281     }
282
283
284     // -- get/put long --
285

286     static private long makeLong(byte b7, byte b6, byte b5, byte b4,
287                  byte b3, byte b2, byte b1, byte b0)
288     {
289     return ((((long)b7 & 0xff) << 56) |
290         (((long)b6 & 0xff) << 48) |
291         (((long)b5 & 0xff) << 40) |
292         (((long)b4 & 0xff) << 32) |
293         (((long)b3 & 0xff) << 24) |
294         (((long)b2 & 0xff) << 16) |
295         (((long)b1 & 0xff) << 8) |
296         (((long)b0 & 0xff) << 0));
297     }
298
299     static long getLongL(ByteBuffer JavaDoc bb, int bi) {
300     return makeLong(bb._get(bi + 7),
301             bb._get(bi + 6),
302             bb._get(bi + 5),
303             bb._get(bi + 4),
304             bb._get(bi + 3),
305             bb._get(bi + 2),
306             bb._get(bi + 1),
307             bb._get(bi + 0));
308     }
309
310     static long getLongL(long a) {
311     return makeLong(_get(a + 7),
312             _get(a + 6),
313             _get(a + 5),
314             _get(a + 4),
315             _get(a + 3),
316             _get(a + 2),
317             _get(a + 1),
318             _get(a + 0));
319     }
320
321     static long getLongB(ByteBuffer JavaDoc bb, int bi) {
322     return makeLong(bb._get(bi + 0),
323             bb._get(bi + 1),
324             bb._get(bi + 2),
325             bb._get(bi + 3),
326             bb._get(bi + 4),
327             bb._get(bi + 5),
328             bb._get(bi + 6),
329             bb._get(bi + 7));
330     }
331
332     static long getLongB(long a) {
333     return makeLong(_get(a + 0),
334             _get(a + 1),
335             _get(a + 2),
336             _get(a + 3),
337             _get(a + 4),
338             _get(a + 5),
339             _get(a + 6),
340             _get(a + 7));
341     }
342
343     static long getLong(ByteBuffer JavaDoc bb, int bi, boolean bigEndian) {
344     return (bigEndian ? getLongB(bb, bi) : getLongL(bb, bi));
345     }
346
347     static long getLong(long a, boolean bigEndian) {
348     return (bigEndian ? getLongB(a) : getLongL(a));
349     }
350
351     private static byte long7(long x) { return (byte)(x >> 56); }
352     private static byte long6(long x) { return (byte)(x >> 48); }
353     private static byte long5(long x) { return (byte)(x >> 40); }
354     private static byte long4(long x) { return (byte)(x >> 32); }
355     private static byte long3(long x) { return (byte)(x >> 24); }
356     private static byte long2(long x) { return (byte)(x >> 16); }
357     private static byte long1(long x) { return (byte)(x >> 8); }
358     private static byte long0(long x) { return (byte)(x >> 0); }
359
360     static void putLongL(ByteBuffer JavaDoc bb, int bi, long x) {
361     bb._put(bi + 7, long7(x));
362     bb._put(bi + 6, long6(x));
363     bb._put(bi + 5, long5(x));
364     bb._put(bi + 4, long4(x));
365     bb._put(bi + 3, long3(x));
366     bb._put(bi + 2, long2(x));
367     bb._put(bi + 1, long1(x));
368     bb._put(bi + 0, long0(x));
369     }
370
371     static void putLongL(long a, long x) {
372     _put(a + 7, long7(x));
373     _put(a + 6, long6(x));
374     _put(a + 5, long5(x));
375     _put(a + 4, long4(x));
376     _put(a + 3, long3(x));
377     _put(a + 2, long2(x));
378     _put(a + 1, long1(x));
379     _put(a + 0, long0(x));
380     }
381
382     static void putLongB(ByteBuffer JavaDoc bb, int bi, long x) {
383     bb._put(bi + 0, long7(x));
384     bb._put(bi + 1, long6(x));
385     bb._put(bi + 2, long5(x));
386     bb._put(bi + 3, long4(x));
387     bb._put(bi + 4, long3(x));
388     bb._put(bi + 5, long2(x));
389     bb._put(bi + 6, long1(x));
390     bb._put(bi + 7, long0(x));
391     }
392
393     static void putLongB(long a, long x) {
394     _put(a + 0, long7(x));
395     _put(a + 1, long6(x));
396     _put(a + 2, long5(x));
397     _put(a + 3, long4(x));
398     _put(a + 4, long3(x));
399     _put(a + 5, long2(x));
400     _put(a + 6, long1(x));
401     _put(a + 7, long0(x));
402     }
403
404     static void putLong(ByteBuffer JavaDoc bb, int bi, long x, boolean bigEndian) {
405     if (bigEndian)
406         putLongB(bb, bi, x);
407     else
408         putLongL(bb, bi, x);
409     }
410
411     static void putLong(long a, long x, boolean bigEndian) {
412     if (bigEndian)
413         putLongB(a, x);
414     else
415         putLongL(a, x);
416     }
417
418
419     // -- get/put float --
420

421     static float getFloatL(ByteBuffer JavaDoc bb, int bi) {
422     return Float.intBitsToFloat(getIntL(bb, bi));
423     }
424
425     static float getFloatL(long a) {
426     return Float.intBitsToFloat(getIntL(a));
427     }
428
429     static float getFloatB(ByteBuffer JavaDoc bb, int bi) {
430     return Float.intBitsToFloat(getIntB(bb, bi));
431     }
432
433     static float getFloatB(long a) {
434     return Float.intBitsToFloat(getIntB(a));
435     }
436
437     static float getFloat(ByteBuffer JavaDoc bb, int bi, boolean bigEndian) {
438     return (bigEndian ? getFloatB(bb, bi) : getFloatL(bb, bi));
439     }
440
441     static float getFloat(long a, boolean bigEndian) {
442     return (bigEndian ? getFloatB(a) : getFloatL(a));
443     }
444
445     static void putFloatL(ByteBuffer JavaDoc bb, int bi, float x) {
446     putIntL(bb, bi, Float.floatToRawIntBits(x));
447     }
448
449     static void putFloatL(long a, float x) {
450     putIntL(a, Float.floatToRawIntBits(x));
451     }
452
453     static void putFloatB(ByteBuffer JavaDoc bb, int bi, float x) {
454     putIntB(bb, bi, Float.floatToRawIntBits(x));
455     }
456
457     static void putFloatB(long a, float x) {
458     putIntB(a, Float.floatToRawIntBits(x));
459     }
460
461     static void putFloat(ByteBuffer JavaDoc bb, int bi, float x, boolean bigEndian) {
462     if (bigEndian)
463         putFloatB(bb, bi, x);
464     else
465         putFloatL(bb, bi, x);
466     }
467
468     static void putFloat(long a, float x, boolean bigEndian) {
469     if (bigEndian)
470         putFloatB(a, x);
471     else
472         putFloatL(a, x);
473     }
474
475
476     // -- get/put double --
477

478     static double getDoubleL(ByteBuffer JavaDoc bb, int bi) {
479     return Double.longBitsToDouble(getLongL(bb, bi));
480     }
481
482     static double getDoubleL(long a) {
483     return Double.longBitsToDouble(getLongL(a));
484     }
485
486     static double getDoubleB(ByteBuffer JavaDoc bb, int bi) {
487     return Double.longBitsToDouble(getLongB(bb, bi));
488     }
489
490     static double getDoubleB(long a) {
491     return Double.longBitsToDouble(getLongB(a));
492     }
493
494     static double getDouble(ByteBuffer JavaDoc bb, int bi, boolean bigEndian) {
495     return (bigEndian ? getDoubleB(bb, bi) : getDoubleL(bb, bi));
496     }
497
498     static double getDouble(long a, boolean bigEndian) {
499     return (bigEndian ? getDoubleB(a) : getDoubleL(a));
500     }
501
502     static void putDoubleL(ByteBuffer JavaDoc bb, int bi, double x) {
503     putLongL(bb, bi, Double.doubleToRawLongBits(x));
504     }
505
506     static void putDoubleL(long a, double x) {
507     putLongL(a, Double.doubleToRawLongBits(x));
508     }
509
510     static void putDoubleB(ByteBuffer JavaDoc bb, int bi, double x) {
511     putLongB(bb, bi, Double.doubleToRawLongBits(x));
512     }
513
514     static void putDoubleB(long a, double x) {
515     putLongB(a, Double.doubleToRawLongBits(x));
516     }
517
518     static void putDouble(ByteBuffer JavaDoc bb, int bi, double x, boolean bigEndian) {
519     if (bigEndian)
520         putDoubleB(bb, bi, x);
521     else
522         putDoubleL(bb, bi, x);
523     }
524
525     static void putDouble(long a, double x, boolean bigEndian) {
526     if (bigEndian)
527         putDoubleB(a, x);
528     else
529         putDoubleL(a, x);
530     }
531
532
533     // -- Unsafe access --
534

535     private static final Unsafe unsafe = Unsafe.getUnsafe();
536
537     private static byte _get(long a) {
538     return unsafe.getByte(a);
539     }
540
541     private static void _put(long a, byte b) {
542     unsafe.putByte(a, b);
543     }
544
545     static Unsafe unsafe() {
546     return unsafe;
547     }
548
549
550     // -- Processor and memory-system properties --
551

552     private static ByteOrder JavaDoc byteOrder = null;
553
554     static ByteOrder JavaDoc byteOrder() {
555     if (byteOrder != null)
556         return byteOrder;
557     long a = unsafe.allocateMemory(8);
558     try {
559         unsafe.putLong(a, 0x0102030405060708L);
560         byte b = unsafe.getByte(a);
561         switch (b) {
562         case 0x01: byteOrder = ByteOrder.BIG_ENDIAN; break;
563         case 0x08: byteOrder = ByteOrder.LITTLE_ENDIAN; break;
564         default:
565         throw new Error JavaDoc("Unknown byte order");
566         }
567     } finally {
568         unsafe.freeMemory(a);
569     }
570     return byteOrder;
571     }
572
573
574     private static int pageSize = -1;
575
576     static int pageSize() {
577     if (pageSize == -1)
578         pageSize = unsafe().pageSize();
579     return pageSize;
580     }
581
582
583     private static boolean unaligned;
584     private static boolean unalignedKnown = false;
585
586     static boolean unaligned() {
587     if (unalignedKnown)
588         return unaligned;
589         PrivilegedAction JavaDoc pa
590         = new sun.security.action.GetPropertyAction("os.arch");
591         String JavaDoc arch = (String JavaDoc)AccessController.doPrivileged(pa);
592     unaligned = arch.equals("i386") || arch.equals("x86");
593     unalignedKnown = true;
594     return unaligned;
595     }
596
597
598     // -- Direct memory management --
599

600     // A user-settable upper limit on the maximum amount of allocatable
601
// direct buffer memory. This value may be changed during VM
602
// initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
603
private static volatile long maxMemory = VM.maxDirectMemory();
604     private static volatile long reservedMemory = 0;
605     private static boolean memoryLimitSet = false;
606
607     // These methods should be called whenever direct memory is allocated or
608
// freed. They allow the user to control the amount of direct memory
609
// which a process may access. All sizes are specified in bytes.
610
static void reserveMemory(long size) {
611
612     synchronized (Bits JavaDoc.class) {
613         if (!memoryLimitSet && VM.isBooted()) {
614         maxMemory = VM.maxDirectMemory();
615         memoryLimitSet = true;
616         }
617         if (size <= maxMemory - reservedMemory) {
618         reservedMemory += size;
619         return;
620         }
621     }
622
623     System.gc();
624     try {
625         Thread.sleep(100);
626     } catch (InterruptedException JavaDoc x) {
627         // Restore interrupt status
628
Thread.currentThread().interrupt();
629     }
630     synchronized (Bits JavaDoc.class) {
631         if (reservedMemory + size > maxMemory)
632         throw new OutOfMemoryError JavaDoc("Direct buffer memory");
633         reservedMemory += size;
634     }
635
636     }
637
638     static synchronized void unreserveMemory(long size) {
639     if (reservedMemory > 0) {
640         reservedMemory -= size;
641         assert (reservedMemory > -1);
642     }
643     }
644
645
646     // -- Bulk get/put acceleration --
647

648     // These numbers represent the point at which we have empirically
649
// determined that the average cost of a JNI call exceeds the expense
650
// of an element by element copy. These numbers may change over time.
651
static final int JNI_COPY_TO_ARRAY_THRESHOLD = 6;
652     static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6;
653
654     // These methods do no bounds checking. Verification that the copy will not
655
// result in memory corruption should be done prior to invocation.
656
// All positions and lengths are specified in bytes.
657

658     static native void copyFromByteArray(Object JavaDoc src, long srcPos, long dstAddr,
659                      long length);
660     static native void copyToByteArray(long srcAddr, Object JavaDoc dst, long dstPos,
661                        long length);
662
663     static void copyFromCharArray(Object JavaDoc src, long srcPos, long dstAddr,
664                   long length)
665     {
666     copyFromShortArray(src, srcPos, dstAddr, length);
667     }
668
669     static void copyToCharArray(long srcAddr, Object JavaDoc dst, long dstPos,
670                 long length)
671     {
672     copyToShortArray(srcAddr, dst, dstPos, length);
673     }
674
675     static native void copyFromShortArray(Object JavaDoc src, long srcPos, long dstAddr,
676                       long length);
677     static native void copyToShortArray(long srcAddr, Object JavaDoc dst, long dstPos,
678                     long length);
679
680     static native void copyFromIntArray(Object JavaDoc src, long srcPos, long dstAddr,
681                     long length);
682     static native void copyToIntArray(long srcAddr, Object JavaDoc dst, long dstPos,
683                     long length);
684
685     static native void copyFromLongArray(Object JavaDoc src, long srcPos, long dstAddr,
686                      long length);
687     static native void copyToLongArray(long srcAddr, Object JavaDoc dst, long dstPos,
688                        long length);
689
690 }
691
Popular Tags