Home | History | Annotate | Download | only in nio
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
      4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      5  *
      6  * This code is free software; you can redistribute it and/or modify it
      7  * under the terms of the GNU General Public License version 2 only, as
      8  * published by the Free Software Foundation.  Oracle designates this
      9  * particular file as subject to the "Classpath" exception as provided
     10  * by Oracle in the LICENSE file that accompanied this code.
     11  *
     12  * This code is distributed in the hope that it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15  * version 2 for more details (a copy is included in the LICENSE file that
     16  * accompanied this code).
     17  *
     18  * You should have received a copy of the GNU General Public License version
     19  * 2 along with this work; if not, write to the Free Software Foundation,
     20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     21  *
     22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     23  * or visit www.oracle.com if you need additional information or have any
     24  * questions.
     25  */
     26 
     27 package java.nio;
     28 
     29 import java.security.AccessController;
     30 
     31 import sun.misc.Unsafe;
     32 import sun.misc.VM;
     33 
     34 /**
     35  * Access to bits, native and otherwise.
     36  */
     37 
     38 class Bits {                            // package-private
     39 
     40     private Bits() {
     41     }
     42 
     43 
     44     // -- Swapping --
     45 
     46     static short swap(short x) {
     47         return Short.reverseBytes(x);
     48     }
     49 
     50     static char swap(char x) {
     51         return Character.reverseBytes(x);
     52     }
     53 
     54     static int swap(int x) {
     55         return Integer.reverseBytes(x);
     56     }
     57 
     58     static long swap(long x) {
     59         return Long.reverseBytes(x);
     60     }
     61 
     62 
     63     // -- get/put char --
     64 
     65     static private char makeChar(byte b1, byte b0) {
     66         return (char) ((b1 << 8) | (b0 & 0xff));
     67     }
     68 
     69     static char getCharL(ByteBuffer bb, int bi) {
     70         return makeChar(bb._get(bi + 1),
     71                 bb._get(bi));
     72     }
     73 
     74     static char getCharL(long a) {
     75         return makeChar(_get(a + 1),
     76                 _get(a));
     77     }
     78 
     79     static char getCharB(ByteBuffer bb, int bi) {
     80         return makeChar(bb._get(bi),
     81                 bb._get(bi + 1));
     82     }
     83 
     84     static char getCharB(long a) {
     85         return makeChar(_get(a),
     86                 _get(a + 1));
     87     }
     88 
     89     static char getChar(ByteBuffer bb, int bi, boolean bigEndian) {
     90         return bigEndian ? getCharB(bb, bi) : getCharL(bb, bi);
     91     }
     92 
     93     static char getChar(long a, boolean bigEndian) {
     94         return bigEndian ? getCharB(a) : getCharL(a);
     95     }
     96 
     97     private static byte char1(char x) {
     98         return (byte) (x >> 8);
     99     }
    100 
    101     private static byte char0(char x) {
    102         return (byte) (x);
    103     }
    104 
    105     static void putCharL(ByteBuffer bb, int bi, char x) {
    106         bb._put(bi, char0(x));
    107         bb._put(bi + 1, char1(x));
    108     }
    109 
    110     static void putCharL(long a, char x) {
    111         _put(a, char0(x));
    112         _put(a + 1, char1(x));
    113     }
    114 
    115     static void putCharB(ByteBuffer bb, int bi, char x) {
    116         bb._put(bi, char1(x));
    117         bb._put(bi + 1, char0(x));
    118     }
    119 
    120     static void putCharB(long a, char x) {
    121         _put(a, char1(x));
    122         _put(a + 1, char0(x));
    123     }
    124 
    125     static void putChar(ByteBuffer bb, int bi, char x, boolean bigEndian) {
    126         if (bigEndian)
    127             putCharB(bb, bi, x);
    128         else
    129             putCharL(bb, bi, x);
    130     }
    131 
    132     static void putChar(long a, char x, boolean bigEndian) {
    133         if (bigEndian)
    134             putCharB(a, x);
    135         else
    136             putCharL(a, x);
    137     }
    138 
    139 
    140     // -- get/put short --
    141 
    142     static private short makeShort(byte b1, byte b0) {
    143         return (short) ((b1 << 8) | (b0 & 0xff));
    144     }
    145 
    146     static short getShortL(ByteBuffer bb, int bi) {
    147         return makeShort(bb._get(bi + 1),
    148                 bb._get(bi));
    149     }
    150 
    151     static short getShortL(long a) {
    152         return makeShort(_get(a + 1),
    153                 _get(a));
    154     }
    155 
    156     static short getShortB(ByteBuffer bb, int bi) {
    157         return makeShort(bb._get(bi),
    158                 bb._get(bi + 1));
    159     }
    160 
    161     static short getShortB(long a) {
    162         return makeShort(_get(a),
    163                 _get(a + 1));
    164     }
    165 
    166     static short getShort(ByteBuffer bb, int bi, boolean bigEndian) {
    167         return bigEndian ? getShortB(bb, bi) : getShortL(bb, bi);
    168     }
    169 
    170     static short getShort(long a, boolean bigEndian) {
    171         return bigEndian ? getShortB(a) : getShortL(a);
    172     }
    173 
    174     private static byte short1(short x) {
    175         return (byte) (x >> 8);
    176     }
    177 
    178     private static byte short0(short x) {
    179         return (byte) (x);
    180     }
    181 
    182     static void putShortL(ByteBuffer bb, int bi, short x) {
    183         bb._put(bi, short0(x));
    184         bb._put(bi + 1, short1(x));
    185     }
    186 
    187     static void putShortL(long a, short x) {
    188         _put(a, short0(x));
    189         _put(a + 1, short1(x));
    190     }
    191 
    192     static void putShortB(ByteBuffer bb, int bi, short x) {
    193         bb._put(bi, short1(x));
    194         bb._put(bi + 1, short0(x));
    195     }
    196 
    197     static void putShortB(long a, short x) {
    198         _put(a, short1(x));
    199         _put(a + 1, short0(x));
    200     }
    201 
    202     static void putShort(ByteBuffer bb, int bi, short x, boolean bigEndian) {
    203         if (bigEndian)
    204             putShortB(bb, bi, x);
    205         else
    206             putShortL(bb, bi, x);
    207     }
    208 
    209     static void putShort(long a, short x, boolean bigEndian) {
    210         if (bigEndian)
    211             putShortB(a, x);
    212         else
    213             putShortL(a, x);
    214     }
    215 
    216 
    217     // -- get/put int --
    218 
    219     static private int makeInt(byte b3, byte b2, byte b1, byte b0) {
    220         return (((b3) << 24) |
    221                 ((b2 & 0xff) << 16) |
    222                 ((b1 & 0xff) << 8) |
    223                 ((b0 & 0xff)));
    224     }
    225 
    226     static int getIntL(ByteBuffer bb, int bi) {
    227         return makeInt(bb._get(bi + 3),
    228                 bb._get(bi + 2),
    229                 bb._get(bi + 1),
    230                 bb._get(bi));
    231     }
    232 
    233     static int getIntL(long a) {
    234         return makeInt(_get(a + 3),
    235                 _get(a + 2),
    236                 _get(a + 1),
    237                 _get(a));
    238     }
    239 
    240     static int getIntB(ByteBuffer bb, int bi) {
    241         return makeInt(bb._get(bi),
    242                 bb._get(bi + 1),
    243                 bb._get(bi + 2),
    244                 bb._get(bi + 3));
    245     }
    246 
    247     static int getIntB(long a) {
    248         return makeInt(_get(a),
    249                 _get(a + 1),
    250                 _get(a + 2),
    251                 _get(a + 3));
    252     }
    253 
    254     static int getInt(ByteBuffer bb, int bi, boolean bigEndian) {
    255         return bigEndian ? getIntB(bb, bi) : getIntL(bb, bi);
    256     }
    257 
    258     static int getInt(long a, boolean bigEndian) {
    259         return bigEndian ? getIntB(a) : getIntL(a);
    260     }
    261 
    262     private static byte int3(int x) {
    263         return (byte) (x >> 24);
    264     }
    265 
    266     private static byte int2(int x) {
    267         return (byte) (x >> 16);
    268     }
    269 
    270     private static byte int1(int x) {
    271         return (byte) (x >> 8);
    272     }
    273 
    274     private static byte int0(int x) {
    275         return (byte) (x);
    276     }
    277 
    278     static void putIntL(ByteBuffer bb, int bi, int x) {
    279         bb._put(bi + 3, int3(x));
    280         bb._put(bi + 2, int2(x));
    281         bb._put(bi + 1, int1(x));
    282         bb._put(bi, int0(x));
    283     }
    284 
    285     static void putIntL(long a, int x) {
    286         _put(a + 3, int3(x));
    287         _put(a + 2, int2(x));
    288         _put(a + 1, int1(x));
    289         _put(a, int0(x));
    290     }
    291 
    292     static void putIntB(ByteBuffer bb, int bi, int x) {
    293         bb._put(bi, int3(x));
    294         bb._put(bi + 1, int2(x));
    295         bb._put(bi + 2, int1(x));
    296         bb._put(bi + 3, int0(x));
    297     }
    298 
    299     static void putIntB(long a, int x) {
    300         _put(a, int3(x));
    301         _put(a + 1, int2(x));
    302         _put(a + 2, int1(x));
    303         _put(a + 3, int0(x));
    304     }
    305 
    306     static void putInt(ByteBuffer bb, int bi, int x, boolean bigEndian) {
    307         if (bigEndian)
    308             putIntB(bb, bi, x);
    309         else
    310             putIntL(bb, bi, x);
    311     }
    312 
    313     static void putInt(long a, int x, boolean bigEndian) {
    314         if (bigEndian)
    315             putIntB(a, x);
    316         else
    317             putIntL(a, x);
    318     }
    319 
    320 
    321     // -- get/put long --
    322 
    323     static private long makeLong(byte b7, byte b6, byte b5, byte b4,
    324                                  byte b3, byte b2, byte b1, byte b0) {
    325         return ((((long) b7) << 56) |
    326                 (((long) b6 & 0xff) << 48) |
    327                 (((long) b5 & 0xff) << 40) |
    328                 (((long) b4 & 0xff) << 32) |
    329                 (((long) b3 & 0xff) << 24) |
    330                 (((long) b2 & 0xff) << 16) |
    331                 (((long) b1 & 0xff) << 8) |
    332                 (((long) b0 & 0xff)));
    333     }
    334 
    335     static long getLongL(ByteBuffer bb, int bi) {
    336         return makeLong(bb._get(bi + 7),
    337                 bb._get(bi + 6),
    338                 bb._get(bi + 5),
    339                 bb._get(bi + 4),
    340                 bb._get(bi + 3),
    341                 bb._get(bi + 2),
    342                 bb._get(bi + 1),
    343                 bb._get(bi));
    344     }
    345 
    346     static long getLongL(long a) {
    347         return makeLong(_get(a + 7),
    348                 _get(a + 6),
    349                 _get(a + 5),
    350                 _get(a + 4),
    351                 _get(a + 3),
    352                 _get(a + 2),
    353                 _get(a + 1),
    354                 _get(a));
    355     }
    356 
    357     static long getLongB(ByteBuffer bb, int bi) {
    358         return makeLong(bb._get(bi),
    359                 bb._get(bi + 1),
    360                 bb._get(bi + 2),
    361                 bb._get(bi + 3),
    362                 bb._get(bi + 4),
    363                 bb._get(bi + 5),
    364                 bb._get(bi + 6),
    365                 bb._get(bi + 7));
    366     }
    367 
    368     static long getLongB(long a) {
    369         return makeLong(_get(a),
    370                 _get(a + 1),
    371                 _get(a + 2),
    372                 _get(a + 3),
    373                 _get(a + 4),
    374                 _get(a + 5),
    375                 _get(a + 6),
    376                 _get(a + 7));
    377     }
    378 
    379     static long getLong(ByteBuffer bb, int bi, boolean bigEndian) {
    380         return bigEndian ? getLongB(bb, bi) : getLongL(bb, bi);
    381     }
    382 
    383     static long getLong(long a, boolean bigEndian) {
    384         return bigEndian ? getLongB(a) : getLongL(a);
    385     }
    386 
    387     private static byte long7(long x) {
    388         return (byte) (x >> 56);
    389     }
    390 
    391     private static byte long6(long x) {
    392         return (byte) (x >> 48);
    393     }
    394 
    395     private static byte long5(long x) {
    396         return (byte) (x >> 40);
    397     }
    398 
    399     private static byte long4(long x) {
    400         return (byte) (x >> 32);
    401     }
    402 
    403     private static byte long3(long x) {
    404         return (byte) (x >> 24);
    405     }
    406 
    407     private static byte long2(long x) {
    408         return (byte) (x >> 16);
    409     }
    410 
    411     private static byte long1(long x) {
    412         return (byte) (x >> 8);
    413     }
    414 
    415     private static byte long0(long x) {
    416         return (byte) (x);
    417     }
    418 
    419     static void putLongL(ByteBuffer bb, int bi, long x) {
    420         bb._put(bi + 7, long7(x));
    421         bb._put(bi + 6, long6(x));
    422         bb._put(bi + 5, long5(x));
    423         bb._put(bi + 4, long4(x));
    424         bb._put(bi + 3, long3(x));
    425         bb._put(bi + 2, long2(x));
    426         bb._put(bi + 1, long1(x));
    427         bb._put(bi, long0(x));
    428     }
    429 
    430     static void putLongL(long a, long x) {
    431         _put(a + 7, long7(x));
    432         _put(a + 6, long6(x));
    433         _put(a + 5, long5(x));
    434         _put(a + 4, long4(x));
    435         _put(a + 3, long3(x));
    436         _put(a + 2, long2(x));
    437         _put(a + 1, long1(x));
    438         _put(a, long0(x));
    439     }
    440 
    441     static void putLongB(ByteBuffer bb, int bi, long x) {
    442         bb._put(bi, long7(x));
    443         bb._put(bi + 1, long6(x));
    444         bb._put(bi + 2, long5(x));
    445         bb._put(bi + 3, long4(x));
    446         bb._put(bi + 4, long3(x));
    447         bb._put(bi + 5, long2(x));
    448         bb._put(bi + 6, long1(x));
    449         bb._put(bi + 7, long0(x));
    450     }
    451 
    452     static void putLongB(long a, long x) {
    453         _put(a, long7(x));
    454         _put(a + 1, long6(x));
    455         _put(a + 2, long5(x));
    456         _put(a + 3, long4(x));
    457         _put(a + 4, long3(x));
    458         _put(a + 5, long2(x));
    459         _put(a + 6, long1(x));
    460         _put(a + 7, long0(x));
    461     }
    462 
    463     static void putLong(ByteBuffer bb, int bi, long x, boolean bigEndian) {
    464         if (bigEndian)
    465             putLongB(bb, bi, x);
    466         else
    467             putLongL(bb, bi, x);
    468     }
    469 
    470     static void putLong(long a, long x, boolean bigEndian) {
    471         if (bigEndian)
    472             putLongB(a, x);
    473         else
    474             putLongL(a, x);
    475     }
    476 
    477 
    478     // -- get/put float --
    479 
    480     static float getFloatL(ByteBuffer bb, int bi) {
    481         return Float.intBitsToFloat(getIntL(bb, bi));
    482     }
    483 
    484     static float getFloatL(long a) {
    485         return Float.intBitsToFloat(getIntL(a));
    486     }
    487 
    488     static float getFloatB(ByteBuffer bb, int bi) {
    489         return Float.intBitsToFloat(getIntB(bb, bi));
    490     }
    491 
    492     static float getFloatB(long a) {
    493         return Float.intBitsToFloat(getIntB(a));
    494     }
    495 
    496     static float getFloat(ByteBuffer bb, int bi, boolean bigEndian) {
    497         return bigEndian ? getFloatB(bb, bi) : getFloatL(bb, bi);
    498     }
    499 
    500     static float getFloat(long a, boolean bigEndian) {
    501         return bigEndian ? getFloatB(a) : getFloatL(a);
    502     }
    503 
    504     static void putFloatL(ByteBuffer bb, int bi, float x) {
    505         putIntL(bb, bi, Float.floatToRawIntBits(x));
    506     }
    507 
    508     static void putFloatL(long a, float x) {
    509         putIntL(a, Float.floatToRawIntBits(x));
    510     }
    511 
    512     static void putFloatB(ByteBuffer bb, int bi, float x) {
    513         putIntB(bb, bi, Float.floatToRawIntBits(x));
    514     }
    515 
    516     static void putFloatB(long a, float x) {
    517         putIntB(a, Float.floatToRawIntBits(x));
    518     }
    519 
    520     static void putFloat(ByteBuffer bb, int bi, float x, boolean bigEndian) {
    521         if (bigEndian)
    522             putFloatB(bb, bi, x);
    523         else
    524             putFloatL(bb, bi, x);
    525     }
    526 
    527     static void putFloat(long a, float x, boolean bigEndian) {
    528         if (bigEndian)
    529             putFloatB(a, x);
    530         else
    531             putFloatL(a, x);
    532     }
    533 
    534 
    535     // -- get/put double --
    536 
    537     static double getDoubleL(ByteBuffer bb, int bi) {
    538         return Double.longBitsToDouble(getLongL(bb, bi));
    539     }
    540 
    541     static double getDoubleL(long a) {
    542         return Double.longBitsToDouble(getLongL(a));
    543     }
    544 
    545     static double getDoubleB(ByteBuffer bb, int bi) {
    546         return Double.longBitsToDouble(getLongB(bb, bi));
    547     }
    548 
    549     static double getDoubleB(long a) {
    550         return Double.longBitsToDouble(getLongB(a));
    551     }
    552 
    553     static double getDouble(ByteBuffer bb, int bi, boolean bigEndian) {
    554         return bigEndian ? getDoubleB(bb, bi) : getDoubleL(bb, bi);
    555     }
    556 
    557     static double getDouble(long a, boolean bigEndian) {
    558         return bigEndian ? getDoubleB(a) : getDoubleL(a);
    559     }
    560 
    561     static void putDoubleL(ByteBuffer bb, int bi, double x) {
    562         putLongL(bb, bi, Double.doubleToRawLongBits(x));
    563     }
    564 
    565     static void putDoubleL(long a, double x) {
    566         putLongL(a, Double.doubleToRawLongBits(x));
    567     }
    568 
    569     static void putDoubleB(ByteBuffer bb, int bi, double x) {
    570         putLongB(bb, bi, Double.doubleToRawLongBits(x));
    571     }
    572 
    573     static void putDoubleB(long a, double x) {
    574         putLongB(a, Double.doubleToRawLongBits(x));
    575     }
    576 
    577     static void putDouble(ByteBuffer bb, int bi, double x, boolean bigEndian) {
    578         if (bigEndian)
    579             putDoubleB(bb, bi, x);
    580         else
    581             putDoubleL(bb, bi, x);
    582     }
    583 
    584     static void putDouble(long a, double x, boolean bigEndian) {
    585         if (bigEndian)
    586             putDoubleB(a, x);
    587         else
    588             putDoubleL(a, x);
    589     }
    590 
    591 
    592     // -- Unsafe access --
    593 
    594     private static final Unsafe unsafe = Unsafe.getUnsafe();
    595 
    596     private static byte _get(long a) {
    597         return unsafe.getByte(a);
    598     }
    599 
    600     private static void _put(long a, byte b) {
    601         unsafe.putByte(a, b);
    602     }
    603 
    604     static Unsafe unsafe() {
    605         return unsafe;
    606     }
    607 
    608 
    609     // -- Processor and memory-system properties --
    610 
    611     /* ----- BEGIN android -----
    612     private static final ByteOrder byteOrder;*/
    613     private static final ByteOrder byteOrder = ByteOrder.LITTLE_ENDIAN;
    614     // ----- END android -----
    615 
    616     static ByteOrder byteOrder() {
    617         // Android changed : android is always little endian.
    618         return byteOrder;
    619 
    620         /* ----- BEGIN android -----
    621         if (byteOrder == null)
    622             throw new Error("Unknown byte order");
    623         if (byteOrder == null) {
    624             long a = unsafe.allocateMemory(8);
    625             try {
    626                 unsafe.putLong(a, 0x0102030405060708L);
    627                 byte b = unsafe.getByte(a);
    628                 switch (b) {
    629                     case 0x01: byteOrder = ByteOrder.BIG_ENDIAN;     break;
    630                     case 0x08: byteOrder = ByteOrder.LITTLE_ENDIAN;  break;
    631                     default: throw new Error("Unknown byte order");
    632                 }
    633             } finally {
    634                 unsafe.freeMemory(a);
    635             }
    636         }
    637         return byteOrder;
    638         */
    639     }
    640 
    641     /* ----- BEGIN android -----
    642     static {
    643         long a = unsafe.allocateMemory(8);
    644         try {
    645             unsafe.putLong(a, 0x0102030405060708L);
    646             byte b = unsafe.getByte(a);
    647             switch (b) {
    648             case 0x01: byteOrder = ByteOrder.BIG_ENDIAN;     break;
    649             case 0x08: byteOrder = ByteOrder.LITTLE_ENDIAN;  break;
    650             default:
    651                 assert false;
    652                 byteOrder = null;
    653             }
    654         } finally {
    655             unsafe.freeMemory(a);
    656         }
    657     }
    658     ----- END android ----- */
    659 
    660 
    661     private static int pageSize = -1;
    662 
    663     static int pageSize() {
    664         if (pageSize == -1)
    665             pageSize = unsafe().pageSize();
    666         return pageSize;
    667     }
    668 
    669     static int pageCount(long size) {
    670         return (int) (size + (long) pageSize() - 1L) / pageSize();
    671     }
    672 
    673     private static boolean unaligned;
    674     private static boolean unalignedKnown = false;
    675 
    676     static boolean unaligned() {
    677         if (unalignedKnown)
    678             return unaligned;
    679         String arch = AccessController.doPrivileged(
    680                 new sun.security.action.GetPropertyAction("os.arch"));
    681         unaligned = arch.equals("i386") || arch.equals("x86")
    682                 || arch.equals("amd64") || arch.equals("x86_64");
    683         unalignedKnown = true;
    684         return unaligned;
    685     }
    686 
    687 
    688     // -- Direct memory management --
    689 
    690     // A user-settable upper limit on the maximum amount of allocatable
    691     // direct buffer memory.  This value may be changed during VM
    692     // initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
    693     private static volatile long maxMemory = VM.maxDirectMemory();
    694     private static volatile long reservedMemory;
    695     private static volatile long totalCapacity;
    696     private static volatile long count;
    697     private static boolean memoryLimitSet = false;
    698 
    699     // These methods should be called whenever direct memory is allocated or
    700     // freed.  They allow the user to control the amount of direct memory
    701     // which a process may access.  All sizes are specified in bytes.
    702     static void reserveMemory(long size, int cap) {
    703         synchronized (Bits.class) {
    704             if (!memoryLimitSet && VM.isBooted()) {
    705                 maxMemory = VM.maxDirectMemory();
    706                 memoryLimitSet = true;
    707             }
    708             // -XX:MaxDirectMemorySize limits the total capacity rather than the
    709             // actual memory usage, which will differ when buffers are page
    710             // aligned.
    711             if (cap <= maxMemory - totalCapacity) {
    712                 reservedMemory += size;
    713                 totalCapacity += cap;
    714                 count++;
    715                 return;
    716             }
    717         }
    718 
    719         System.gc();
    720         try {
    721             Thread.sleep(100);
    722         } catch (InterruptedException x) {
    723             // Restore interrupt status
    724             Thread.currentThread().interrupt();
    725         }
    726         synchronized (Bits.class) {
    727             if (totalCapacity + cap > maxMemory)
    728                 throw new OutOfMemoryError("Direct buffer memory");
    729             reservedMemory += size;
    730             totalCapacity += cap;
    731             count++;
    732         }
    733 
    734     }
    735 
    736     static synchronized void unreserveMemory(long size, int cap) {
    737         if (reservedMemory > 0) {
    738             reservedMemory -= size;
    739             totalCapacity -= cap;
    740             count--;
    741             assert (reservedMemory > -1);
    742         }
    743     }
    744 
    745     // -- Monitoring of direct buffer usage --
    746 
    747     /* ----- BEGIN android -----
    748     static {
    749         // setup access to this package in SharedSecrets
    750         sun.misc.SharedSecrets.setJavaNioAccess(
    751             new sun.misc.JavaNioAccess() {
    752                 @Override
    753                 public sun.misc.JavaNioAccess.BufferPool getDirectBufferPool() {
    754                     return new sun.misc.JavaNioAccess.BufferPool() {
    755                         @Override
    756                         public String getName() {
    757                             return "direct";
    758                         }
    759                         @Override
    760                         public long getCount() {
    761                             return Bits.count;
    762                         }
    763                         @Override
    764                         public long getTotalCapacity() {
    765                             return Bits.totalCapacity;
    766                         }
    767                         @Override
    768                         public long getMemoryUsed() {
    769                             return Bits.reservedMemory;
    770                         }
    771                     };
    772                 }
    773                 @Override
    774                 public ByteBuffer newDirectByteBuffer(long addr, int cap, Object ob) {
    775                     return new DirectByteBuffer(addr, cap, ob);
    776                 }
    777                 @Override
    778                 public void truncate(Buffer buf) {
    779                     buf.truncate();
    780                 }
    781         });
    782     }
    783     ----- END android ----- */
    784 
    785     // -- Bulk get/put acceleration --
    786 
    787     // These numbers represent the point at which we have empirically
    788     // determined that the average cost of a JNI call exceeds the expense
    789     // of an element by element copy.  These numbers may change over time.
    790     static final int JNI_COPY_TO_ARRAY_THRESHOLD = 6;
    791     static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6;
    792 
    793     // This number limits the number of bytes to copy per call to Unsafe's
    794     // copyMemory method. A limit is imposed to allow for safepoint polling
    795     // during a large copy
    796     static final long UNSAFE_COPY_THRESHOLD = 1024L * 1024L;
    797 
    798     // These methods do no bounds checking.  Verification that the copy will not
    799     // result in memory corruption should be done prior to invocation.
    800     // All positions and lengths are specified in bytes.
    801 
    802     /**
    803      * Copy from given source array to destination address.
    804      *
    805      * @param src           source array
    806      * @param srcBaseOffset offset of first element of storage in source array
    807      * @param srcPos        offset within source array of the first element to read
    808      * @param dstAddr       destination address
    809      * @param length        number of bytes to copy
    810      */
    811     static void copyFromArray(Object src, long srcBaseOffset, long srcPos,
    812                               long dstAddr, long length) {
    813         long offset = srcBaseOffset + srcPos;
    814         while (length > 0) {
    815             long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
    816             unsafe.copyMemoryFromPrimitiveArray(src, offset, dstAddr, size);
    817             length -= size;
    818             offset += size;
    819             dstAddr += size;
    820         }
    821     }
    822 
    823     /**
    824      * Copy from source address into given destination array.
    825      *
    826      * @param srcAddr       source address
    827      * @param dst           destination array
    828      * @param dstBaseOffset offset of first element of storage in destination array
    829      * @param dstPos        offset within destination array of the first element to write
    830      * @param length        number of bytes to copy
    831      */
    832     static void copyToArray(long srcAddr, Object dst, long dstBaseOffset, long dstPos,
    833                             long length) {
    834         long offset = dstBaseOffset + dstPos;
    835         while (length > 0) {
    836             long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
    837             unsafe.copyMemoryToPrimitiveArray(srcAddr, dst, offset, size);
    838             length -= size;
    839             srcAddr += size;
    840             offset += size;
    841         }
    842     }
    843 
    844     static void copyFromCharArray(Object src, long srcPos, long dstAddr,
    845                                   long length) {
    846         copyFromShortArray(src, srcPos, dstAddr, length);
    847     }
    848 
    849     static void copyToCharArray(long srcAddr, Object dst, long dstPos,
    850                                 long length) {
    851         copyToShortArray(srcAddr, dst, dstPos, length);
    852     }
    853 
    854     static native void copyFromShortArray(Object src, long srcPos, long dstAddr,
    855                                           long length);
    856 
    857     static native void copyToShortArray(long srcAddr, Object dst, long dstPos,
    858                                         long length);
    859 
    860     static native void copyFromIntArray(Object src, long srcPos, long dstAddr,
    861                                         long length);
    862 
    863     static native void copyToIntArray(long srcAddr, Object dst, long dstPos,
    864                                       long length);
    865 
    866     static native void copyFromLongArray(Object src, long srcPos, long dstAddr,
    867                                          long length);
    868 
    869     static native void copyToLongArray(long srcAddr, Object dst, long dstPos,
    870                                        long length);
    871 
    872 }
    873