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