1 /*
   2  * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.nio;
  27 
  28 import java.util.concurrent.atomic.AtomicLong;
  29 import java.util.concurrent.locks.ReentrantLock;
  30 
  31 import jdk.internal.misc.*;
  32 import jdk.internal.ref.CleanerFactory;
  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     private static 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     private static 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     private static 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     private static 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     private static final ByteOrder byteOrder
 568         = unsafe.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
 569 
 570     static ByteOrder byteOrder() {
 571         return byteOrder;
 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     static int pageCount(long size) {
 583         return (int)(size + (long)pageSize() - 1L) / pageSize();
 584     }
 585 
 586     private static boolean unaligned = unsafe.unalignedAccess();
 587 
 588     static boolean unaligned() {
 589         return unaligned;
 590     }
 591 
 592 
 593     // -- Direct memory management --
 594 
 595     // A user-settable upper limit on the maximum amount of allocatable
 596     // direct buffer memory.  This value may be changed during VM
 597     // initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
 598     private static volatile long maxMemory = VM.maxDirectMemory();
 599     private static final AtomicLong reservedMemory = new AtomicLong();
 600     private static final AtomicLong totalCapacity = new AtomicLong();
 601     private static final AtomicLong count = new AtomicLong();
 602     private static volatile boolean memoryLimitSet;
 603 
 604     // max. number of sleeps during try-reserving with exponentially
 605     // increasing delay before throwing OutOfMemoryError:
 606     // 1, 2, 4, 8, 16, 32, 64, 128, 256 (total 511 ms ~ 0.5 s)
 607     // which means that OOME will be thrown after 0.5 s of trying
 608     private static final int MAX_SLEEPS = 9;
 609 
 610     private static final ReentrantLock reservationQueue = new ReentrantLock(true);
 611 
 612     // These methods should be called whenever direct memory is allocated or
 613     // freed.  They allow the user to control the amount of direct memory
 614     // which a process may access.  All sizes are specified in bytes.
 615     static void reserveMemory(long size, int cap) {
 616 
 617         if (!memoryLimitSet && VM.isBooted()) {
 618             maxMemory = VM.maxDirectMemory();
 619             memoryLimitSet = true;
 620         }
 621 
 622         // optimist!
 623         if (tryReserveMemory(size, cap)) {
 624             return;
 625         }
 626 
 627         // reservation threads that don't succeed at first must queue so that
 628         // some of them don't starve while others succeed.
 629         reservationQueue.lock();
 630         try {
 631             JavaLangRefAccess jlra = SharedSecrets.getJavaLangRefAccess();
 632 
 633             // retry reservation while helping the Cleaner thread process enqueued
 634             // Cleanable(s) which includes the ones that free direct buffer memory
 635             // until the queue drains out
 636             do {
 637                 if (tryReserveMemory(size, cap)) {
 638                     return;
 639                 }
 640             } while (jlra.cleanNextPendingCleanable(CleanerFactory.cleaner()));
 641 
 642             // trigger GC's Reference discovery
 643             System.gc();
 644             // make sure all newly discovered Reference(s) are enqueued
 645             jlra.enqueuePendingReferences();
 646 
 647             // retry reservation while helping the Cleaner thread process enqueued
 648             // Cleanable(s) which includes the ones that free direct buffer memory
 649             // until the queue drains out
 650             do {
 651                 if (tryReserveMemory(size, cap)) {
 652                     return;
 653                 }
 654             } while (jlra.cleanNextPendingCleanable(CleanerFactory.cleaner()));
 655 
 656             // no luck
 657             throw new OutOfMemoryError("Direct buffer memory");
 658         } finally {
 659             reservationQueue.unlock();
 660         }
 661     }
 662 
 663     private static boolean tryReserveMemory(long size, int cap) {
 664 
 665         // -XX:MaxDirectMemorySize limits the total capacity rather than the
 666         // actual memory usage, which will differ when buffers are page
 667         // aligned.
 668         long totalCap;
 669         while (cap <= maxMemory - (totalCap = totalCapacity.get())) {
 670             if (totalCapacity.compareAndSet(totalCap, totalCap + cap)) {
 671                 reservedMemory.addAndGet(size);
 672                 count.incrementAndGet();
 673                 return true;
 674             }
 675         }
 676 
 677         return false;
 678     }
 679 
 680 
 681     static void unreserveMemory(long size, int cap) {
 682         long cnt = count.decrementAndGet();
 683         long reservedMem = reservedMemory.addAndGet(-size);
 684         long totalCap = totalCapacity.addAndGet(-cap);
 685         assert cnt >= 0 && reservedMem >= 0 && totalCap >= 0;
 686     }
 687 
 688     // -- Monitoring of direct buffer usage --
 689 
 690     static {
 691         // setup access to this package in SharedSecrets
 692         SharedSecrets.setJavaNioAccess(
 693             new JavaNioAccess() {
 694                 @Override
 695                 public JavaNioAccess.BufferPool getDirectBufferPool() {
 696                     return new JavaNioAccess.BufferPool() {
 697                         @Override
 698                         public String getName() {
 699                             return "direct";
 700                         }
 701                         @Override
 702                         public long getCount() {
 703                             return Bits.count.get();
 704                         }
 705                         @Override
 706                         public long getTotalCapacity() {
 707                             return Bits.totalCapacity.get();
 708                         }
 709                         @Override
 710                         public long getMemoryUsed() {
 711                             return Bits.reservedMemory.get();
 712                         }
 713                     };
 714                 }
 715                 @Override
 716                 public ByteBuffer newDirectByteBuffer(long addr, int cap, Object ob) {
 717                     return new DirectByteBuffer(addr, cap, ob);
 718                 }
 719                 @Override
 720                 public void truncate(Buffer buf) {
 721                     buf.truncate();
 722                 }
 723         });
 724     }
 725 
 726     // -- Bulk get/put acceleration --
 727 
 728     // These numbers represent the point at which we have empirically
 729     // determined that the average cost of a JNI call exceeds the expense
 730     // of an element by element copy.  These numbers may change over time.
 731     static final int JNI_COPY_TO_ARRAY_THRESHOLD   = 6;
 732     static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6;
 733 
 734     // This number limits the number of bytes to copy per call to Unsafe's
 735     // copyMemory method. A limit is imposed to allow for safepoint polling
 736     // during a large copy
 737     static final long UNSAFE_COPY_THRESHOLD = 1024L * 1024L;
 738 
 739     // These methods do no bounds checking.  Verification that the copy will not
 740     // result in memory corruption should be done prior to invocation.
 741     // All positions and lengths are specified in bytes.
 742 
 743     /**
 744      * Copy from given source array to destination address.
 745      *
 746      * @param   src
 747      *          source array
 748      * @param   srcBaseOffset
 749      *          offset of first element of storage in source array
 750      * @param   srcPos
 751      *          offset within source array of the first element to read
 752      * @param   dstAddr
 753      *          destination address
 754      * @param   length
 755      *          number of bytes to copy
 756      */
 757     static void copyFromArray(Object src, long srcBaseOffset, long srcPos,
 758                               long dstAddr, long length)
 759     {
 760         long offset = srcBaseOffset + srcPos;
 761         while (length > 0) {
 762             long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
 763             unsafe.copyMemory(src, offset, null, dstAddr, size);
 764             length -= size;
 765             offset += size;
 766             dstAddr += size;
 767         }
 768     }
 769 
 770     /**
 771      * Copy from source address into given destination array.
 772      *
 773      * @param   srcAddr
 774      *          source address
 775      * @param   dst
 776      *          destination array
 777      * @param   dstBaseOffset
 778      *          offset of first element of storage in destination array
 779      * @param   dstPos
 780      *          offset within destination array of the first element to write
 781      * @param   length
 782      *          number of bytes to copy
 783      */
 784     static void copyToArray(long srcAddr, Object dst, long dstBaseOffset, long dstPos,
 785                             long length)
 786     {
 787         long offset = dstBaseOffset + dstPos;
 788         while (length > 0) {
 789             long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
 790             unsafe.copyMemory(null, srcAddr, dst, offset, size);
 791             length -= size;
 792             srcAddr += size;
 793             offset += size;
 794         }
 795     }
 796 
 797     /**
 798      * Copy and unconditionally byte swap 16 bit elements from a heap array to off-heap memory
 799      *
 800      * @param src
 801      *        the source array, must be a 16-bit primitive array type
 802      * @param srcPos
 803      *        byte offset within source array of the first element to read
 804      * @param dstAddr
 805      *        destination address
 806      * @param length
 807      *        number of bytes to copy
 808      */
 809     static void copyFromCharArray(Object src, long srcPos, long dstAddr, long length) {
 810         unsafe.copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 2);
 811     }
 812 
 813     /**
 814      * Copy and unconditionally byte swap 16 bit elements from off-heap memory to a heap array
 815      *
 816      * @param srcAddr
 817      *        source address
 818      * @param dst
 819      *        destination array, must be a 16-bit primitive array type
 820      * @param dstPos
 821      *        byte offset within the destination array of the first element to write
 822      * @param length
 823      *        number of bytes to copy
 824      */
 825     static void copyToCharArray(long srcAddr, Object dst, long dstPos, long length) {
 826         unsafe.copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 2);
 827     }
 828 
 829     /**
 830      * Copy and unconditionally byte swap 16 bit elements from a heap array to off-heap memory
 831      *
 832      * @param src
 833      *        the source array, must be a 16-bit primitive array type
 834      * @param srcPos
 835      *        byte offset within source array of the first element to read
 836      * @param dstAddr
 837      *        destination address
 838      * @param length
 839      *        number of bytes to copy
 840      */
 841     static void copyFromShortArray(Object src, long srcPos, long dstAddr, long length) {
 842         unsafe.copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 2);
 843     }
 844 
 845     /**
 846      * Copy and unconditionally byte swap 16 bit elements from off-heap memory to a heap array
 847      *
 848      * @param srcAddr
 849      *        source address
 850      * @param dst
 851      *        destination array, must be a 16-bit primitive array type
 852      * @param dstPos
 853      *        byte offset within the destination array of the first element to write
 854      * @param length
 855      *        number of bytes to copy
 856      */
 857     static void copyToShortArray(long srcAddr, Object dst, long dstPos, long length) {
 858         unsafe.copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 2);
 859     }
 860 
 861     /**
 862      * Copy and unconditionally byte swap 32 bit elements from a heap array to off-heap memory
 863      *
 864      * @param src
 865      *        the source array, must be a 32-bit primitive array type
 866      * @param srcPos
 867      *        byte offset within source array of the first element to read
 868      * @param dstAddr
 869      *        destination address
 870      * @param length
 871      *        number of bytes to copy
 872      */
 873     static void copyFromIntArray(Object src, long srcPos, long dstAddr, long length) {
 874         unsafe.copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 4);
 875     }
 876 
 877     /**
 878      * Copy and unconditionally byte swap 32 bit elements from off-heap memory to a heap array
 879      *
 880      * @param srcAddr
 881      *        source address
 882      * @param dst
 883      *        destination array, must be a 32-bit primitive array type
 884      * @param dstPos
 885      *        byte offset within the destination array of the first element to write
 886      * @param length
 887      *        number of bytes to copy
 888      */
 889     static void copyToIntArray(long srcAddr, Object dst, long dstPos, long length) {
 890         unsafe.copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 4);
 891     }
 892 
 893     /**
 894      * Copy and unconditionally byte swap 64 bit elements from a heap array to off-heap memory
 895      *
 896      * @param src
 897      *        the source array, must be a 64-bit primitive array type
 898      * @param srcPos
 899      *        byte offset within source array of the first element to read
 900      * @param dstAddr
 901      *        destination address
 902      * @param length
 903      *        number of bytes to copy
 904      */
 905     static void copyFromLongArray(Object src, long srcPos, long dstAddr, long length) {
 906         unsafe.copySwapMemory(src, unsafe.arrayBaseOffset(src.getClass()) + srcPos, null, dstAddr, length, 8);
 907     }
 908 
 909     /**
 910      * Copy and unconditionally byte swap 64 bit elements from off-heap memory to a heap array
 911      *
 912      * @param srcAddr
 913      *        source address
 914      * @param dst
 915      *        destination array, must be a 64-bit primitive array type
 916      * @param dstPos
 917      *        byte offset within the destination array of the first element to write
 918      * @param length
 919      *        number of bytes to copy
 920      */
 921     static void copyToLongArray(long srcAddr, Object dst, long dstPos, long length) {
 922         unsafe.copySwapMemory(null, srcAddr, dst, unsafe.arrayBaseOffset(dst.getClass()) + dstPos, length, 8);
 923     }
 924 }