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 
  30 import jdk.internal.misc.JavaNioAccess;
  31 import jdk.internal.misc.JavaLangRefAccess;
  32 import jdk.internal.misc.SharedSecrets;
  33 import jdk.internal.misc.Unsafe;
  34 import jdk.internal.misc.VM;
  35 
  36 /**
  37  * Access to bits, native and otherwise.
  38  */
  39 
  40 class Bits {                            // package-private
  41 
  42     private Bits() { }
  43 
  44 
  45     // -- Swapping --
  46 
  47     static short swap(short x) {
  48         return Short.reverseBytes(x);
  49     }
  50 
  51     static char swap(char x) {
  52         return Character.reverseBytes(x);
  53     }
  54 
  55     static int swap(int x) {
  56         return Integer.reverseBytes(x);
  57     }
  58 
  59     static long swap(long x) {
  60         return Long.reverseBytes(x);
  61     }
  62 
  63 
  64     // -- get/put char --
  65 
  66     private static char makeChar(byte b1, byte b0) {
  67         return (char)((b1 << 8) | (b0 & 0xff));
  68     }
  69 
  70     static char getCharL(ByteBuffer bb, int bi) {
  71         return makeChar(bb._get(bi + 1),
  72                         bb._get(bi    ));
  73     }
  74 
  75     static char getCharL(long a) {
  76         return makeChar(_get(a + 1),
  77                         _get(a    ));
  78     }
  79 
  80     static char getCharB(ByteBuffer bb, int bi) {
  81         return makeChar(bb._get(bi    ),
  82                         bb._get(bi + 1));
  83     }
  84 
  85     static char getCharB(long a) {
  86         return makeChar(_get(a    ),
  87                         _get(a + 1));
  88     }
  89 
  90     static char getChar(ByteBuffer bb, int bi, boolean bigEndian) {
  91         return bigEndian ? getCharB(bb, bi) : getCharL(bb, bi);
  92     }
  93 
  94     static char getChar(long a, boolean bigEndian) {
  95         return bigEndian ? getCharB(a) : getCharL(a);
  96     }
  97 
  98     private static byte char1(char x) { return (byte)(x >> 8); }
  99     private static byte char0(char x) { return (byte)(x     ); }
 100 
 101     static void putCharL(ByteBuffer bb, int bi, char x) {
 102         bb._put(bi    , char0(x));
 103         bb._put(bi + 1, char1(x));
 104     }
 105 
 106     static void putCharL(long a, char x) {
 107         _put(a    , char0(x));
 108         _put(a + 1, char1(x));
 109     }
 110 
 111     static void putCharB(ByteBuffer bb, int bi, char x) {
 112         bb._put(bi    , char1(x));
 113         bb._put(bi + 1, char0(x));
 114     }
 115 
 116     static void putCharB(long a, char x) {
 117         _put(a    , char1(x));
 118         _put(a + 1, char0(x));
 119     }
 120 
 121     static void putChar(ByteBuffer bb, int bi, char x, boolean bigEndian) {
 122         if (bigEndian)
 123             putCharB(bb, bi, x);
 124         else
 125             putCharL(bb, bi, x);
 126     }
 127 
 128     static void putChar(long a, char x, boolean bigEndian) {
 129         if (bigEndian)
 130             putCharB(a, x);
 131         else
 132             putCharL(a, x);
 133     }
 134 
 135 
 136     // -- get/put short --
 137 
 138     private static short makeShort(byte b1, byte b0) {
 139         return (short)((b1 << 8) | (b0 & 0xff));
 140     }
 141 
 142     static short getShortL(ByteBuffer bb, int bi) {
 143         return makeShort(bb._get(bi + 1),
 144                          bb._get(bi    ));
 145     }
 146 
 147     static short getShortL(long a) {
 148         return makeShort(_get(a + 1),
 149                          _get(a    ));
 150     }
 151 
 152     static short getShortB(ByteBuffer bb, int bi) {
 153         return makeShort(bb._get(bi    ),
 154                          bb._get(bi + 1));
 155     }
 156 
 157     static short getShortB(long a) {
 158         return makeShort(_get(a    ),
 159                          _get(a + 1));
 160     }
 161 
 162     static short getShort(ByteBuffer bb, int bi, boolean bigEndian) {
 163         return bigEndian ? getShortB(bb, bi) : getShortL(bb, bi);
 164     }
 165 
 166     static short getShort(long a, boolean bigEndian) {
 167         return bigEndian ? getShortB(a) : getShortL(a);
 168     }
 169 
 170     private static byte short1(short x) { return (byte)(x >> 8); }
 171     private static byte short0(short x) { return (byte)(x     ); }
 172 
 173     static void putShortL(ByteBuffer bb, int bi, short x) {
 174         bb._put(bi    , short0(x));
 175         bb._put(bi + 1, short1(x));
 176     }
 177 
 178     static void putShortL(long a, short x) {
 179         _put(a    , short0(x));
 180         _put(a + 1, short1(x));
 181     }
 182 
 183     static void putShortB(ByteBuffer bb, int bi, short x) {
 184         bb._put(bi    , short1(x));
 185         bb._put(bi + 1, short0(x));
 186     }
 187 
 188     static void putShortB(long a, short x) {
 189         _put(a    , short1(x));
 190         _put(a + 1, short0(x));
 191     }
 192 
 193     static void putShort(ByteBuffer bb, int bi, short x, boolean bigEndian) {
 194         if (bigEndian)
 195             putShortB(bb, bi, x);
 196         else
 197             putShortL(bb, bi, x);
 198     }
 199 
 200     static void putShort(long a, short x, boolean bigEndian) {
 201         if (bigEndian)
 202             putShortB(a, x);
 203         else
 204             putShortL(a, x);
 205     }
 206 
 207 
 208     // -- get/put int --
 209 
 210     private static int makeInt(byte b3, byte b2, byte b1, byte b0) {
 211         return (((b3       ) << 24) |
 212                 ((b2 & 0xff) << 16) |
 213                 ((b1 & 0xff) <<  8) |
 214                 ((b0 & 0xff)      ));
 215     }
 216 
 217     static int getIntL(ByteBuffer bb, int bi) {
 218         return makeInt(bb._get(bi + 3),
 219                        bb._get(bi + 2),
 220                        bb._get(bi + 1),
 221                        bb._get(bi    ));
 222     }
 223 
 224     static int getIntL(long a) {
 225         return makeInt(_get(a + 3),
 226                        _get(a + 2),
 227                        _get(a + 1),
 228                        _get(a    ));
 229     }
 230 
 231     static int getIntB(ByteBuffer bb, int bi) {
 232         return makeInt(bb._get(bi    ),
 233                        bb._get(bi + 1),
 234                        bb._get(bi + 2),
 235                        bb._get(bi + 3));
 236     }
 237 
 238     static int getIntB(long a) {
 239         return makeInt(_get(a    ),
 240                        _get(a + 1),
 241                        _get(a + 2),
 242                        _get(a + 3));
 243     }
 244 
 245     static int getInt(ByteBuffer bb, int bi, boolean bigEndian) {
 246         return bigEndian ? getIntB(bb, bi) : getIntL(bb, bi) ;
 247     }
 248 
 249     static int getInt(long a, boolean bigEndian) {
 250         return bigEndian ? getIntB(a) : getIntL(a) ;
 251     }
 252 
 253     private static byte int3(int x) { return (byte)(x >> 24); }
 254     private static byte int2(int x) { return (byte)(x >> 16); }
 255     private static byte int1(int x) { return (byte)(x >>  8); }
 256     private static byte int0(int x) { return (byte)(x      ); }
 257 
 258     static void putIntL(ByteBuffer bb, int bi, int x) {
 259         bb._put(bi + 3, int3(x));
 260         bb._put(bi + 2, int2(x));
 261         bb._put(bi + 1, int1(x));
 262         bb._put(bi    , int0(x));
 263     }
 264 
 265     static void putIntL(long a, int x) {
 266         _put(a + 3, int3(x));
 267         _put(a + 2, int2(x));
 268         _put(a + 1, int1(x));
 269         _put(a    , int0(x));
 270     }
 271 
 272     static void putIntB(ByteBuffer bb, int bi, int x) {
 273         bb._put(bi    , int3(x));
 274         bb._put(bi + 1, int2(x));
 275         bb._put(bi + 2, int1(x));
 276         bb._put(bi + 3, int0(x));
 277     }
 278 
 279     static void putIntB(long a, int x) {
 280         _put(a    , int3(x));
 281         _put(a + 1, int2(x));
 282         _put(a + 2, int1(x));
 283         _put(a + 3, int0(x));
 284     }
 285 
 286     static void putInt(ByteBuffer bb, int bi, int x, boolean bigEndian) {
 287         if (bigEndian)
 288             putIntB(bb, bi, x);
 289         else
 290             putIntL(bb, bi, x);
 291     }
 292 
 293     static void putInt(long a, int x, boolean bigEndian) {
 294         if (bigEndian)
 295             putIntB(a, x);
 296         else
 297             putIntL(a, x);
 298     }
 299 
 300 
 301     // -- get/put long --
 302 
 303     private static long makeLong(byte b7, byte b6, byte b5, byte b4,
 304                                  byte b3, byte b2, byte b1, byte b0)
 305     {
 306         return ((((long)b7       ) << 56) |
 307                 (((long)b6 & 0xff) << 48) |
 308                 (((long)b5 & 0xff) << 40) |
 309                 (((long)b4 & 0xff) << 32) |
 310                 (((long)b3 & 0xff) << 24) |
 311                 (((long)b2 & 0xff) << 16) |
 312                 (((long)b1 & 0xff) <<  8) |
 313                 (((long)b0 & 0xff)      ));
 314     }
 315 
 316     static long getLongL(ByteBuffer bb, int bi) {
 317         return makeLong(bb._get(bi + 7),
 318                         bb._get(bi + 6),
 319                         bb._get(bi + 5),
 320                         bb._get(bi + 4),
 321                         bb._get(bi + 3),
 322                         bb._get(bi + 2),
 323                         bb._get(bi + 1),
 324                         bb._get(bi    ));
 325     }
 326 
 327     static long getLongL(long a) {
 328         return makeLong(_get(a + 7),
 329                         _get(a + 6),
 330                         _get(a + 5),
 331                         _get(a + 4),
 332                         _get(a + 3),
 333                         _get(a + 2),
 334                         _get(a + 1),
 335                         _get(a    ));
 336     }
 337 
 338     static long getLongB(ByteBuffer bb, int bi) {
 339         return makeLong(bb._get(bi    ),
 340                         bb._get(bi + 1),
 341                         bb._get(bi + 2),
 342                         bb._get(bi + 3),
 343                         bb._get(bi + 4),
 344                         bb._get(bi + 5),
 345                         bb._get(bi + 6),
 346                         bb._get(bi + 7));
 347     }
 348 
 349     static long getLongB(long a) {
 350         return makeLong(_get(a    ),
 351                         _get(a + 1),
 352                         _get(a + 2),
 353                         _get(a + 3),
 354                         _get(a + 4),
 355                         _get(a + 5),
 356                         _get(a + 6),
 357                         _get(a + 7));
 358     }
 359 
 360     static long getLong(ByteBuffer bb, int bi, boolean bigEndian) {
 361         return bigEndian ? getLongB(bb, bi) : getLongL(bb, bi);
 362     }
 363 
 364     static long getLong(long a, boolean bigEndian) {
 365         return bigEndian ? getLongB(a) : getLongL(a);
 366     }
 367 
 368     private static byte long7(long x) { return (byte)(x >> 56); }
 369     private static byte long6(long x) { return (byte)(x >> 48); }
 370     private static byte long5(long x) { return (byte)(x >> 40); }
 371     private static byte long4(long x) { return (byte)(x >> 32); }
 372     private static byte long3(long x) { return (byte)(x >> 24); }
 373     private static byte long2(long x) { return (byte)(x >> 16); }
 374     private static byte long1(long x) { return (byte)(x >>  8); }
 375     private static byte long0(long x) { return (byte)(x      ); }
 376 
 377     static void putLongL(ByteBuffer bb, int bi, long x) {
 378         bb._put(bi + 7, long7(x));
 379         bb._put(bi + 6, long6(x));
 380         bb._put(bi + 5, long5(x));
 381         bb._put(bi + 4, long4(x));
 382         bb._put(bi + 3, long3(x));
 383         bb._put(bi + 2, long2(x));
 384         bb._put(bi + 1, long1(x));
 385         bb._put(bi    , long0(x));
 386     }
 387 
 388     static void putLongL(long a, long x) {
 389         _put(a + 7, long7(x));
 390         _put(a + 6, long6(x));
 391         _put(a + 5, long5(x));
 392         _put(a + 4, long4(x));
 393         _put(a + 3, long3(x));
 394         _put(a + 2, long2(x));
 395         _put(a + 1, long1(x));
 396         _put(a    , long0(x));
 397     }
 398 
 399     static void putLongB(ByteBuffer bb, int bi, long x) {
 400         bb._put(bi    , long7(x));
 401         bb._put(bi + 1, long6(x));
 402         bb._put(bi + 2, long5(x));
 403         bb._put(bi + 3, long4(x));
 404         bb._put(bi + 4, long3(x));
 405         bb._put(bi + 5, long2(x));
 406         bb._put(bi + 6, long1(x));
 407         bb._put(bi + 7, long0(x));
 408     }
 409 
 410     static void putLongB(long a, long x) {
 411         _put(a    , long7(x));
 412         _put(a + 1, long6(x));
 413         _put(a + 2, long5(x));
 414         _put(a + 3, long4(x));
 415         _put(a + 4, long3(x));
 416         _put(a + 5, long2(x));
 417         _put(a + 6, long1(x));
 418         _put(a + 7, long0(x));
 419     }
 420 
 421     static void putLong(ByteBuffer bb, int bi, long x, boolean bigEndian) {
 422         if (bigEndian)
 423             putLongB(bb, bi, x);
 424         else
 425             putLongL(bb, bi, x);
 426     }
 427 
 428     static void putLong(long a, long x, boolean bigEndian) {
 429         if (bigEndian)
 430             putLongB(a, x);
 431         else
 432             putLongL(a, x);
 433     }
 434 
 435 
 436     // -- get/put float --
 437 
 438     static float getFloatL(ByteBuffer bb, int bi) {
 439         return Float.intBitsToFloat(getIntL(bb, bi));
 440     }
 441 
 442     static float getFloatL(long a) {
 443         return Float.intBitsToFloat(getIntL(a));
 444     }
 445 
 446     static float getFloatB(ByteBuffer bb, int bi) {
 447         return Float.intBitsToFloat(getIntB(bb, bi));
 448     }
 449 
 450     static float getFloatB(long a) {
 451         return Float.intBitsToFloat(getIntB(a));
 452     }
 453 
 454     static float getFloat(ByteBuffer bb, int bi, boolean bigEndian) {
 455         return bigEndian ? getFloatB(bb, bi) : getFloatL(bb, bi);
 456     }
 457 
 458     static float getFloat(long a, boolean bigEndian) {
 459         return bigEndian ? getFloatB(a) : getFloatL(a);
 460     }
 461 
 462     static void putFloatL(ByteBuffer bb, int bi, float x) {
 463         putIntL(bb, bi, Float.floatToRawIntBits(x));
 464     }
 465 
 466     static void putFloatL(long a, float x) {
 467         putIntL(a, Float.floatToRawIntBits(x));
 468     }
 469 
 470     static void putFloatB(ByteBuffer bb, int bi, float x) {
 471         putIntB(bb, bi, Float.floatToRawIntBits(x));
 472     }
 473 
 474     static void putFloatB(long a, float x) {
 475         putIntB(a, Float.floatToRawIntBits(x));
 476     }
 477 
 478     static void putFloat(ByteBuffer bb, int bi, float x, boolean bigEndian) {
 479         if (bigEndian)
 480             putFloatB(bb, bi, x);
 481         else
 482             putFloatL(bb, bi, x);
 483     }
 484 
 485     static void putFloat(long a, float x, boolean bigEndian) {
 486         if (bigEndian)
 487             putFloatB(a, x);
 488         else
 489             putFloatL(a, x);
 490     }
 491 
 492 
 493     // -- get/put double --
 494 
 495     static double getDoubleL(ByteBuffer bb, int bi) {
 496         return Double.longBitsToDouble(getLongL(bb, bi));
 497     }
 498 
 499     static double getDoubleL(long a) {
 500         return Double.longBitsToDouble(getLongL(a));
 501     }
 502 
 503     static double getDoubleB(ByteBuffer bb, int bi) {
 504         return Double.longBitsToDouble(getLongB(bb, bi));
 505     }
 506 
 507     static double getDoubleB(long a) {
 508         return Double.longBitsToDouble(getLongB(a));
 509     }
 510 
 511     static double getDouble(ByteBuffer bb, int bi, boolean bigEndian) {
 512         return bigEndian ? getDoubleB(bb, bi) : getDoubleL(bb, bi);
 513     }
 514 
 515     static double getDouble(long a, boolean bigEndian) {
 516         return bigEndian ? getDoubleB(a) : getDoubleL(a);
 517     }
 518 
 519     static void putDoubleL(ByteBuffer bb, int bi, double x) {
 520         putLongL(bb, bi, Double.doubleToRawLongBits(x));
 521     }
 522 
 523     static void putDoubleL(long a, double x) {
 524         putLongL(a, Double.doubleToRawLongBits(x));
 525     }
 526 
 527     static void putDoubleB(ByteBuffer bb, int bi, double x) {
 528         putLongB(bb, bi, Double.doubleToRawLongBits(x));
 529     }
 530 
 531     static void putDoubleB(long a, double x) {
 532         putLongB(a, Double.doubleToRawLongBits(x));
 533     }
 534 
 535     static void putDouble(ByteBuffer bb, int bi, double x, boolean bigEndian) {
 536         if (bigEndian)
 537             putDoubleB(bb, bi, x);
 538         else
 539             putDoubleL(bb, bi, x);
 540     }
 541 
 542     static void putDouble(long a, double x, boolean bigEndian) {
 543         if (bigEndian)
 544             putDoubleB(a, x);
 545         else
 546             putDoubleL(a, x);
 547     }
 548 
 549 
 550     // -- Unsafe access --
 551 
 552     private static final Unsafe unsafe = Unsafe.getUnsafe();
 553 
 554     private static byte _get(long a) {
 555         return unsafe.getByte(a);
 556     }
 557 
 558     private static void _put(long a, byte b) {
 559         unsafe.putByte(a, b);
 560     }
 561 
 562     static Unsafe unsafe() {
 563         return unsafe;
 564     }
 565 
 566 
 567     // -- Processor and memory-system properties --
 568 
 569     private static final ByteOrder byteOrder
 570         = unsafe.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
 571 
 572     static ByteOrder byteOrder() {
 573         return byteOrder;
 574     }
 575 
 576     private static int pageSize = -1;
 577 
 578     static int pageSize() {
 579         if (pageSize == -1)
 580             pageSize = unsafe().pageSize();
 581         return pageSize;
 582     }
 583 
 584     static int pageCount(long size) {
 585         return (int)(size + (long)pageSize() - 1L) / pageSize();
 586     }
 587 
 588     private static boolean unaligned = unsafe.unalignedAccess();
 589 
 590     static boolean unaligned() {
 591         return unaligned;
 592     }
 593 
 594 
 595     // -- Direct memory management --
 596 
 597     // A user-settable upper limit on the maximum amount of allocatable
 598     // direct buffer memory.  This value may be changed during VM
 599     // initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
 600     private static volatile long maxMemory = VM.maxDirectMemory();
 601     private static final AtomicLong reservedMemory = new AtomicLong();
 602     private static final AtomicLong totalCapacity = new AtomicLong();
 603     private static final AtomicLong count = new AtomicLong();
 604     private static volatile boolean memoryLimitSet;
 605 
 606     // max. number of sleeps during try-reserving with exponentially
 607     // increasing delay before throwing OutOfMemoryError:
 608     // 1, 2, 4, 8, 16, 32, 64, 128, 256 (total 511 ms ~ 0.5 s)
 609     // which means that OOME will be thrown after 0.5 s of trying
 610     private static final int MAX_SLEEPS = 9;
 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.initLevel() >= 1) {
 618             maxMemory = VM.maxDirectMemory();
 619             memoryLimitSet = true;
 620         }
 621 
 622         // optimist!
 623         if (tryReserveMemory(size, cap)) {
 624             return;
 625         }
 626 
 627         final JavaLangRefAccess jlra = SharedSecrets.getJavaLangRefAccess();
 628 
 629         // retry while helping enqueue pending Reference objects
 630         // which includes executing pending Cleaner(s) which includes
 631         // Cleaner(s) that free direct buffer memory
 632         while (jlra.tryHandlePendingReference()) {
 633             if (tryReserveMemory(size, cap)) {
 634                 return;
 635             }
 636         }
 637 
 638         // trigger VM's Reference processing
 639         System.gc();
 640 
 641         // a retry loop with exponential back-off delays
 642         // (this gives VM some time to do it's job)
 643         boolean interrupted = false;
 644         try {
 645             long sleepTime = 1;
 646             int sleeps = 0;
 647             while (true) {
 648                 if (tryReserveMemory(size, cap)) {
 649                     return;
 650                 }
 651                 if (sleeps >= MAX_SLEEPS) {
 652                     break;
 653                 }
 654                 if (!jlra.tryHandlePendingReference()) {
 655                     try {
 656                         Thread.sleep(sleepTime);
 657                         sleepTime <<= 1;
 658                         sleeps++;
 659                     } catch (InterruptedException e) {
 660                         interrupted = true;
 661                     }
 662                 }
 663             }
 664 
 665             // no luck
 666             throw new OutOfMemoryError("Direct buffer memory");
 667 
 668         } finally {
 669             if (interrupted) {
 670                 // don't swallow interrupts
 671                 Thread.currentThread().interrupt();
 672             }
 673         }
 674     }
 675 
 676     private static boolean tryReserveMemory(long size, int cap) {
 677 
 678         // -XX:MaxDirectMemorySize limits the total capacity rather than the
 679         // actual memory usage, which will differ when buffers are page
 680         // aligned.
 681         long totalCap;
 682         while (cap <= maxMemory - (totalCap = totalCapacity.get())) {
 683             if (totalCapacity.compareAndSet(totalCap, totalCap + cap)) {
 684                 reservedMemory.addAndGet(size);
 685                 count.incrementAndGet();
 686                 return true;
 687             }
 688         }
 689 
 690         return false;
 691     }
 692 
 693 
 694     static void unreserveMemory(long size, int cap) {
 695         long cnt = count.decrementAndGet();
 696         long reservedMem = reservedMemory.addAndGet(-size);
 697         long totalCap = totalCapacity.addAndGet(-cap);
 698         assert cnt >= 0 && reservedMem >= 0 && totalCap >= 0;
 699     }
 700 
 701     // -- Monitoring of direct buffer usage --
 702 
 703     static {
 704         // setup access to this package in SharedSecrets
 705         SharedSecrets.setJavaNioAccess(
 706             new JavaNioAccess() {
 707                 @Override
 708                 public JavaNioAccess.BufferPool getDirectBufferPool() {
 709                     return new JavaNioAccess.BufferPool() {
 710                         @Override
 711                         public String getName() {
 712                             return "direct";
 713                         }
 714                         @Override
 715                         public long getCount() {
 716                             return Bits.count.get();
 717                         }
 718                         @Override
 719                         public long getTotalCapacity() {
 720                             return Bits.totalCapacity.get();
 721                         }
 722                         @Override
 723                         public long getMemoryUsed() {
 724                             return Bits.reservedMemory.get();
 725                         }
 726                     };
 727                 }
 728                 @Override
 729                 public ByteBuffer newDirectByteBuffer(long addr, int cap, Object ob) {
 730                     return new DirectByteBuffer(addr, cap, ob);
 731                 }
 732                 @Override
 733                 public void truncate(Buffer buf) {
 734                     buf.truncate();
 735                 }
 736         });
 737     }
 738 
 739     // These numbers represent the point at which we have empirically
 740     // determined that the average cost of a JNI call exceeds the expense
 741     // of an element by element copy.  These numbers may change over time.
 742     static final int JNI_COPY_TO_ARRAY_THRESHOLD   = 6;
 743     static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6;
 744 }