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