1 /*
   2  * Copyright (c) 2000, 2015, 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 import jdk.internal.ref.CleanerFactory;
  36 import jdk.internal.ref.CleanerImpl;
  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     // max. number of sleeps during try-reserving with exponentially
 609     // increasing delay before throwing OutOfMemoryError:
 610     // 1, 2, 4, 8, 16, 32, 64, 128, 256 (total 511 ms ~ 0.5 s)
 611     // which means that OOME will be thrown after 0.5 s of trying
 612     private static final int MAX_SLEEPS = 9;
 613 
 614     // These methods should be called whenever direct memory is allocated or
 615     // freed.  They allow the user to control the amount of direct memory
 616     // which a process may access.  All sizes are specified in bytes.
 617     static void reserveMemory(long size, int cap) {
 618 
 619         if (!memoryLimitSet && VM.isBooted()) {
 620             maxMemory = VM.maxDirectMemory();
 621             memoryLimitSet = true;
 622         }
 623 
 624         // optimist!
 625         if (tryReserveMemory(size, cap)) {
 626             return;
 627         }
 628 
 629         final JavaLangRefAccess jlra = SharedSecrets.getJavaLangRefAccess();
 630 
 631         // retry while helping enqueue pending Reference objects
 632         // which includes executing pending Cleaner(s) which includes
 633         // Cleaner(s) that free direct buffer memory
 634         while (jlra.tryHandlePendingReference() | // use non-short-circuit or
 635                CleanerImpl.getCleanerImpl(CleanerFactory.cleaner()).drainQueue()) {
 636             if (tryReserveMemory(size, cap)) {
 637                 return;
 638             }
 639         }
 640 
 641         // trigger VM's Reference processing
 642         System.gc();
 643 
 644         // a retry loop with exponential back-off delays
 645         // (this gives VM some time to do it's job)
 646         boolean interrupted = false;
 647         try {
 648             long sleepTime = 1;
 649             int sleeps = 0;
 650             while (true) {
 651                 if (tryReserveMemory(size, cap)) {
 652                     return;
 653                 }
 654                 if (sleeps >= MAX_SLEEPS) {
 655                     break;
 656                 }
 657                 if (!jlra.tryHandlePendingReference() & // use non-short-circuit and
 658                     !CleanerImpl.getCleanerImpl(CleanerFactory.cleaner()).drainQueue()) {
 659                     try {
 660                         Thread.sleep(sleepTime);
 661                         sleepTime <<= 1;
 662                         sleeps++;
 663                     } catch (InterruptedException e) {
 664                         interrupted = true;
 665                     }
 666                 }
 667             }
 668 
 669             // no luck
 670             throw new OutOfMemoryError("Direct buffer memory");
 671 
 672         } finally {
 673             if (interrupted) {
 674                 // don't swallow interrupts
 675                 Thread.currentThread().interrupt();
 676             }
 677         }
 678     }
 679 
 680     private static boolean tryReserveMemory(long size, int cap) {
 681 
 682         // -XX:MaxDirectMemorySize limits the total capacity rather than the
 683         // actual memory usage, which will differ when buffers are page
 684         // aligned.
 685         long totalCap;
 686         while (cap <= maxMemory - (totalCap = totalCapacity.get())) {
 687             if (totalCapacity.compareAndSet(totalCap, totalCap + cap)) {
 688                 reservedMemory.addAndGet(size);
 689                 count.incrementAndGet();
 690                 return true;
 691             }
 692         }
 693 
 694         return false;
 695     }
 696 
 697 
 698     static void unreserveMemory(long size, int cap) {
 699         long cnt = count.decrementAndGet();
 700         long reservedMem = reservedMemory.addAndGet(-size);
 701         long totalCap = totalCapacity.addAndGet(-cap);
 702         assert cnt >= 0 && reservedMem >= 0 && totalCap >= 0;
 703     }
 704 
 705     // -- Monitoring of direct buffer usage --
 706 
 707     static {
 708         // setup access to this package in SharedSecrets
 709         SharedSecrets.setJavaNioAccess(
 710             new JavaNioAccess() {
 711                 @Override
 712                 public JavaNioAccess.BufferPool getDirectBufferPool() {
 713                     return new JavaNioAccess.BufferPool() {
 714                         @Override
 715                         public String getName() {
 716                             return "direct";
 717                         }
 718                         @Override
 719                         public long getCount() {
 720                             return Bits.count.get();
 721                         }
 722                         @Override
 723                         public long getTotalCapacity() {
 724                             return Bits.totalCapacity.get();
 725                         }
 726                         @Override
 727                         public long getMemoryUsed() {
 728                             return Bits.reservedMemory.get();
 729                         }
 730                     };
 731                 }
 732                 @Override
 733                 public ByteBuffer newDirectByteBuffer(long addr, int cap, Object ob) {
 734                     return new DirectByteBuffer(addr, cap, ob);
 735                 }
 736                 @Override
 737                 public void truncate(Buffer buf) {
 738                     buf.truncate();
 739                 }
 740         });
 741     }
 742 
 743     // -- Bulk get/put acceleration --
 744 
 745     // These numbers represent the point at which we have empirically
 746     // determined that the average cost of a JNI call exceeds the expense
 747     // of an element by element copy.  These numbers may change over time.
 748     static final int JNI_COPY_TO_ARRAY_THRESHOLD   = 6;
 749     static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6;
 750 
 751     // This number limits the number of bytes to copy per call to Unsafe's
 752     // copyMemory method. A limit is imposed to allow for safepoint polling
 753     // during a large copy
 754     static final long UNSAFE_COPY_THRESHOLD = 1024L * 1024L;
 755 
 756     // These methods do no bounds checking.  Verification that the copy will not
 757     // result in memory corruption should be done prior to invocation.
 758     // All positions and lengths are specified in bytes.
 759 
 760     /**
 761      * Copy from given source array to destination address.
 762      *
 763      * @param   src
 764      *          source array
 765      * @param   srcBaseOffset
 766      *          offset of first element of storage in source array
 767      * @param   srcPos
 768      *          offset within source array of the first element to read
 769      * @param   dstAddr
 770      *          destination address
 771      * @param   length
 772      *          number of bytes to copy
 773      */
 774     static void copyFromArray(Object src, long srcBaseOffset, long srcPos,
 775                               long dstAddr, long length)
 776     {
 777         long offset = srcBaseOffset + srcPos;
 778         while (length > 0) {
 779             long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
 780             unsafe.copyMemory(src, offset, null, dstAddr, size);
 781             length -= size;
 782             offset += size;
 783             dstAddr += size;
 784         }
 785     }
 786 
 787     /**
 788      * Copy from source address into given destination array.
 789      *
 790      * @param   srcAddr
 791      *          source address
 792      * @param   dst
 793      *          destination array
 794      * @param   dstBaseOffset
 795      *          offset of first element of storage in destination array
 796      * @param   dstPos
 797      *          offset within destination array of the first element to write
 798      * @param   length
 799      *          number of bytes to copy
 800      */
 801     static void copyToArray(long srcAddr, Object dst, long dstBaseOffset, long dstPos,
 802                             long length)
 803     {
 804         long offset = dstBaseOffset + dstPos;
 805         while (length > 0) {
 806             long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
 807             unsafe.copyMemory(null, srcAddr, dst, offset, size);
 808             length -= size;
 809             srcAddr += size;
 810             offset += size;
 811         }
 812     }
 813 
 814     static void copyFromCharArray(Object src, long srcPos, long dstAddr,
 815                                   long length)
 816     {
 817         copyFromShortArray(src, srcPos, dstAddr, length);
 818     }
 819 
 820     static void copyToCharArray(long srcAddr, Object dst, long dstPos,
 821                                 long length)
 822     {
 823         copyToShortArray(srcAddr, dst, dstPos, length);
 824     }
 825 
 826     static native void copyFromShortArray(Object src, long srcPos, long dstAddr,
 827                                           long length);
 828     static native void copyToShortArray(long srcAddr, Object dst, long dstPos,
 829                                         long length);
 830 
 831     static native void copyFromIntArray(Object src, long srcPos, long dstAddr,
 832                                         long length);
 833     static native void copyToIntArray(long srcAddr, Object dst, long dstPos,
 834                                       long length);
 835 
 836     static native void copyFromLongArray(Object src, long srcPos, long dstAddr,
 837                                          long length);
 838     static native void copyToLongArray(long srcAddr, Object dst, long dstPos,
 839                                        long length);
 840 
 841 }