1 /*
   2  * Copyright (c) 2000, 2019, 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 jdk.internal.HotSpotIntrinsicCandidate;
  29 import jdk.internal.access.JavaNioAccess;
  30 import jdk.internal.access.SharedSecrets;
  31 import jdk.internal.misc.Unsafe;
  32 
  33 import java.util.Spliterator;
  34 
  35 /**
  36  * A container for data of a specific primitive type.
  37  *
  38  * <p> A buffer is a linear, finite sequence of elements of a specific
  39  * primitive type.  Aside from its content, the essential properties of a
  40  * buffer are its capacity, limit, and position: </p>
  41  *
  42  * <blockquote>
  43  *
  44  *   <p> A buffer's <i>capacity</i> is the number of elements it contains.  The
  45  *   capacity of a buffer is never negative and never changes.  </p>
  46  *
  47  *   <p> A buffer's <i>limit</i> is the index of the first element that should
  48  *   not be read or written.  A buffer's limit is never negative and is never
  49  *   greater than its capacity.  </p>
  50  *
  51  *   <p> A buffer's <i>position</i> is the index of the next element to be
  52  *   read or written.  A buffer's position is never negative and is never
  53  *   greater than its limit.  </p>
  54  *
  55  * </blockquote>
  56  *
  57  * <p> There is one subclass of this class for each non-boolean primitive type.
  58  *
  59  *
  60  * <h2> Transferring data </h2>
  61  *
  62  * <p> Each subclass of this class defines two categories of <i>get</i> and
  63  * <i>put</i> operations: </p>
  64  *
  65  * <blockquote>
  66  *
  67  *   <p> <i>Relative</i> operations read or write one or more elements starting
  68  *   at the current position and then increment the position by the number of
  69  *   elements transferred.  If the requested transfer exceeds the limit then a
  70  *   relative <i>get</i> operation throws a {@link BufferUnderflowException}
  71  *   and a relative <i>put</i> operation throws a {@link
  72  *   BufferOverflowException}; in either case, no data is transferred.  </p>
  73  *
  74  *   <p> <i>Absolute</i> operations take an explicit element index and do not
  75  *   affect the position.  Absolute <i>get</i> and <i>put</i> operations throw
  76  *   an {@link IndexOutOfBoundsException} if the index argument exceeds the
  77  *   limit.  </p>
  78  *
  79  * </blockquote>
  80  *
  81  * <p> Data may also, of course, be transferred in to or out of a buffer by the
  82  * I/O operations of an appropriate channel, which are always relative to the
  83  * current position.
  84  *
  85  *
  86  * <h2> Marking and resetting </h2>
  87  *
  88  * <p> A buffer's <i>mark</i> is the index to which its position will be reset
  89  * when the {@link #reset reset} method is invoked.  The mark is not always
  90  * defined, but when it is defined it is never negative and is never greater
  91  * than the position.  If the mark is defined then it is discarded when the
  92  * position or the limit is adjusted to a value smaller than the mark.  If the
  93  * mark is not defined then invoking the {@link #reset reset} method causes an
  94  * {@link InvalidMarkException} to be thrown.
  95  *
  96  *
  97  * <h2> Invariants </h2>
  98  *
  99  * <p> The following invariant holds for the mark, position, limit, and
 100  * capacity values:
 101  *
 102  * <blockquote>
 103  *     {@code 0} {@code <=}
 104  *     <i>mark</i> {@code <=}
 105  *     <i>position</i> {@code <=}
 106  *     <i>limit</i> {@code <=}
 107  *     <i>capacity</i>
 108  * </blockquote>
 109  *
 110  * <p> A newly-created buffer always has a position of zero and a mark that is
 111  * undefined.  The initial limit may be zero, or it may be some other value
 112  * that depends upon the type of the buffer and the manner in which it is
 113  * constructed.  Each element of a newly-allocated buffer is initialized
 114  * to zero.
 115  *
 116  *
 117  * <h2> Additional operations </h2>
 118  *
 119  * <p> In addition to methods for accessing the position, limit, and capacity
 120  * values and for marking and resetting, this class also defines the following
 121  * operations upon buffers:
 122  *
 123  * <ul>
 124  *
 125  *   <li><p> {@link #clear} makes a buffer ready for a new sequence of
 126  *   channel-read or relative <i>put</i> operations: It sets the limit to the
 127  *   capacity and the position to zero.  </p></li>
 128  *
 129  *   <li><p> {@link #flip} makes a buffer ready for a new sequence of
 130  *   channel-write or relative <i>get</i> operations: It sets the limit to the
 131  *   current position and then sets the position to zero.  </p></li>
 132  *
 133  *   <li><p> {@link #rewind} makes a buffer ready for re-reading the data that
 134  *   it already contains: It leaves the limit unchanged and sets the position
 135  *   to zero.  </p></li>
 136  *
 137  *   <li><p> The {@link #slice} and {@link #slice(int,int) slice(index,length)}
 138  *   methods create a subsequence of a buffer: They leave the limit and the
 139  *   position unchanged. </p></li>
 140  *
 141  *   <li><p> {@link #duplicate} creates a shallow copy of a buffer: It leaves
 142  *   the limit and the position unchanged. </p></li>
 143  *
 144  * </ul>
 145  *
 146  *
 147  * <h2> Read-only buffers </h2>
 148  *
 149  * <p> Every buffer is readable, but not every buffer is writable.  The
 150  * mutation methods of each buffer class are specified as <i>optional
 151  * operations</i> that will throw a {@link ReadOnlyBufferException} when
 152  * invoked upon a read-only buffer.  A read-only buffer does not allow its
 153  * content to be changed, but its mark, position, and limit values are mutable.
 154  * Whether or not a buffer is read-only may be determined by invoking its
 155  * {@link #isReadOnly isReadOnly} method.
 156  *
 157  *
 158  * <h2> Thread safety </h2>
 159  *
 160  * <p> Buffers are not safe for use by multiple concurrent threads.  If a
 161  * buffer is to be used by more than one thread then access to the buffer
 162  * should be controlled by appropriate synchronization.
 163  *
 164  *
 165  * <h2> Invocation chaining </h2>
 166  *
 167  * <p> Methods in this class that do not otherwise have a value to return are
 168  * specified to return the buffer upon which they are invoked.  This allows
 169  * method invocations to be chained; for example, the sequence of statements
 170  *
 171  * <blockquote><pre>
 172  * b.flip();
 173  * b.position(23);
 174  * b.limit(42);</pre></blockquote>
 175  *
 176  * can be replaced by the single, more compact statement
 177  *
 178  * <blockquote><pre>
 179  * b.flip().position(23).limit(42);</pre></blockquote>
 180  *
 181  *
 182  * @author Mark Reinhold
 183  * @author JSR-51 Expert Group
 184  * @since 1.4
 185  */
 186 
 187 public abstract class Buffer {
 188     // Cached unsafe-access object
 189     static final Unsafe UNSAFE = Unsafe.getUnsafe();
 190 
 191     /**
 192      * The characteristics of Spliterators that traverse and split elements
 193      * maintained in Buffers.
 194      */
 195     static final int SPLITERATOR_CHARACTERISTICS =
 196         Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
 197 
 198     // Invariants: mark <= position <= limit <= capacity
 199     private int mark = -1;
 200     private int position = 0;
 201     private int limit;
 202     private int capacity;
 203 
 204     // Used by heap byte buffers or direct buffers with Unsafe access
 205     // For heap byte buffers this field will be the address relative to the
 206     // array base address and offset into that array. The address might
 207     // not align on a word boundary for slices, nor align at a long word
 208     // (8 byte) boundary for byte[] allocations on 32-bit systems.
 209     // For direct buffers it is the start address of the memory region. The
 210     // address might not align on a word boundary for slices, nor when created
 211     // using JNI, see NewDirectByteBuffer(void*, long).
 212     // Should ideally be declared final
 213     // NOTE: hoisted here for speed in JNI GetDirectBufferAddress
 214     long address;
 215 
 216     // Creates a new buffer with the given mark, position, limit, and capacity,
 217     // after checking invariants.
 218     //
 219     Buffer(int mark, int pos, int lim, int cap) {       // package-private
 220         if (cap < 0)
 221             throw createCapacityException(cap);
 222         this.capacity = cap;
 223         limit(lim);
 224         position(pos);
 225         if (mark >= 0) {
 226             if (mark > pos)
 227                 throw new IllegalArgumentException("mark > position: ("
 228                                                    + mark + " > " + pos + ")");
 229             this.mark = mark;
 230         }
 231     }
 232 
 233     /**
 234      * Returns an {@code IllegalArgumentException} indicating that the source
 235      * and target are the same {@code Buffer}.  Intended for use in
 236      * {@code put(src)} when the parameter is the {@code Buffer} on which the
 237      * method is being invoked.
 238      *
 239      * @return  IllegalArgumentException
 240      *          With a message indicating equal source and target buffers
 241      */
 242     static IllegalArgumentException createSameBufferException() {
 243         return new IllegalArgumentException("The source buffer is this buffer");
 244     }
 245 
 246     /**
 247      * Verify that the capacity is nonnegative.
 248      *
 249      * @param  capacity
 250      *         The new buffer's capacity, in $type$s
 251      *
 252      * @throws  IllegalArgumentException
 253      *          If the {@code capacity} is a negative integer
 254      */
 255     static IllegalArgumentException createCapacityException(int capacity) {
 256         assert capacity < 0 : "capacity expected to be negative";
 257         return new IllegalArgumentException("capacity < 0: ("
 258             + capacity + " < 0)");
 259     }
 260 
 261     /**
 262      * Returns this buffer's capacity.
 263      *
 264      * @return  The capacity of this buffer
 265      */
 266     public final int capacity() {
 267         return capacity;
 268     }
 269 
 270     /**
 271      * Returns this buffer's position.
 272      *
 273      * @return  The position of this buffer
 274      */
 275     public final int position() {
 276         return position;
 277     }
 278 
 279     /**
 280      * Sets this buffer's position.  If the mark is defined and larger than the
 281      * new position then it is discarded.
 282      *
 283      * @param  newPosition
 284      *         The new position value; must be non-negative
 285      *         and no larger than the current limit
 286      *
 287      * @return  This buffer
 288      *
 289      * @throws  IllegalArgumentException
 290      *          If the preconditions on {@code newPosition} do not hold
 291      */
 292     public Buffer position(int newPosition) {
 293         if (newPosition > limit | newPosition < 0)
 294             throw createPositionException(newPosition);
 295         position = newPosition;
 296         if (mark > position) mark = -1;
 297         return this;
 298     }
 299 
 300     /**
 301      * Verify that {@code 0 < newPosition <= limit}
 302      *
 303      * @param newPosition
 304      *        The new position value
 305      *
 306      * @throws IllegalArgumentException
 307      *         If the specified position is out of bounds.
 308      */
 309     private IllegalArgumentException createPositionException(int newPosition) {
 310         String msg = null;
 311 
 312         if (newPosition > limit) {
 313             msg = "newPosition > limit: (" + newPosition + " > " + limit + ")";
 314         } else { // assume negative
 315             assert newPosition < 0 : "newPosition expected to be negative";
 316             msg = "newPosition < 0: (" + newPosition + " < 0)";
 317         }
 318 
 319         return new IllegalArgumentException(msg);
 320     }
 321 
 322     /**
 323      * Returns this buffer's limit.
 324      *
 325      * @return  The limit of this buffer
 326      */
 327     public final int limit() {
 328         return limit;
 329     }
 330 
 331     /**
 332      * Sets this buffer's limit.  If the position is larger than the new limit
 333      * then it is set to the new limit.  If the mark is defined and larger than
 334      * the new limit then it is discarded.
 335      *
 336      * @param  newLimit
 337      *         The new limit value; must be non-negative
 338      *         and no larger than this buffer's capacity
 339      *
 340      * @return  This buffer
 341      *
 342      * @throws  IllegalArgumentException
 343      *          If the preconditions on {@code newLimit} do not hold
 344      */
 345     public Buffer limit(int newLimit) {
 346         if (newLimit > capacity | newLimit < 0)
 347             throw createLimitException(newLimit);
 348         limit = newLimit;
 349         if (position > limit) position = limit;
 350         if (mark > limit) mark = -1;
 351         return this;
 352     }
 353 
 354     /**
 355      * Verify that {@code 0 < newLimit <= capacity}
 356      *
 357      * @param newLimit
 358      *        The new limit value
 359      *
 360      * @throws IllegalArgumentException
 361      *         If the specified limit is out of bounds.
 362      */
 363     private IllegalArgumentException createLimitException(int newLimit) {
 364         String msg = null;
 365 
 366         if (newLimit > capacity) {
 367             msg = "newLimit > capacity: (" + newLimit + " > " + capacity + ")";
 368         } else { // assume negative
 369             assert newLimit < 0 : "newLimit expected to be negative";
 370             msg = "newLimit < 0: (" + newLimit + " < 0)";
 371         }
 372 
 373         return new IllegalArgumentException(msg);
 374     }
 375 
 376     /**
 377      * Sets this buffer's mark at its position.
 378      *
 379      * @return  This buffer
 380      */
 381     public Buffer mark() {
 382         mark = position;
 383         return this;
 384     }
 385 
 386     /**
 387      * Resets this buffer's position to the previously-marked position.
 388      *
 389      * <p> Invoking this method neither changes nor discards the mark's
 390      * value. </p>
 391      *
 392      * @return  This buffer
 393      *
 394      * @throws  InvalidMarkException
 395      *          If the mark has not been set
 396      */
 397     public Buffer reset() {
 398         int m = mark;
 399         if (m < 0)
 400             throw new InvalidMarkException();
 401         position = m;
 402         return this;
 403     }
 404 
 405     /**
 406      * Clears this buffer.  The position is set to zero, the limit is set to
 407      * the capacity, and the mark is discarded.
 408      *
 409      * <p> Invoke this method before using a sequence of channel-read or
 410      * <i>put</i> operations to fill this buffer.  For example:
 411      *
 412      * <blockquote><pre>
 413      * buf.clear();     // Prepare buffer for reading
 414      * in.read(buf);    // Read data</pre></blockquote>
 415      *
 416      * <p> This method does not actually erase the data in the buffer, but it
 417      * is named as if it did because it will most often be used in situations
 418      * in which that might as well be the case. </p>
 419      *
 420      * @return  This buffer
 421      */
 422     public Buffer clear() {
 423         position = 0;
 424         limit = capacity;
 425         mark = -1;
 426         return this;
 427     }
 428 
 429     /**
 430      * Flips this buffer.  The limit is set to the current position and then
 431      * the position is set to zero.  If the mark is defined then it is
 432      * discarded.
 433      *
 434      * <p> After a sequence of channel-read or <i>put</i> operations, invoke
 435      * this method to prepare for a sequence of channel-write or relative
 436      * <i>get</i> operations.  For example:
 437      *
 438      * <blockquote><pre>
 439      * buf.put(magic);    // Prepend header
 440      * in.read(buf);      // Read data into rest of buffer
 441      * buf.flip();        // Flip buffer
 442      * out.write(buf);    // Write header + data to channel</pre></blockquote>
 443      *
 444      * <p> This method is often used in conjunction with the {@link
 445      * java.nio.ByteBuffer#compact compact} method when transferring data from
 446      * one place to another.  </p>
 447      *
 448      * @return  This buffer
 449      */
 450     public Buffer flip() {
 451         limit = position;
 452         position = 0;
 453         mark = -1;
 454         return this;
 455     }
 456 
 457     /**
 458      * Rewinds this buffer.  The position is set to zero and the mark is
 459      * discarded.
 460      *
 461      * <p> Invoke this method before a sequence of channel-write or <i>get</i>
 462      * operations, assuming that the limit has already been set
 463      * appropriately.  For example:
 464      *
 465      * <blockquote><pre>
 466      * out.write(buf);    // Write remaining data
 467      * buf.rewind();      // Rewind buffer
 468      * buf.get(array);    // Copy data into array</pre></blockquote>
 469      *
 470      * @return  This buffer
 471      */
 472     public Buffer rewind() {
 473         position = 0;
 474         mark = -1;
 475         return this;
 476     }
 477 
 478     /**
 479      * Returns the number of elements between the current position and the
 480      * limit.
 481      *
 482      * @return  The number of elements remaining in this buffer
 483      */
 484     public final int remaining() {
 485         return limit - position;
 486     }
 487 
 488     /**
 489      * Tells whether there are any elements between the current position and
 490      * the limit.
 491      *
 492      * @return  {@code true} if, and only if, there is at least one element
 493      *          remaining in this buffer
 494      */
 495     public final boolean hasRemaining() {
 496         return position < limit;
 497     }
 498 
 499     /**
 500      * Tells whether or not this buffer is read-only.
 501      *
 502      * @return  {@code true} if, and only if, this buffer is read-only
 503      */
 504     public abstract boolean isReadOnly();
 505 
 506     /**
 507      * Tells whether or not this buffer is backed by an accessible
 508      * array.
 509      *
 510      * <p> If this method returns {@code true} then the {@link #array() array}
 511      * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
 512      * </p>
 513      *
 514      * @return  {@code true} if, and only if, this buffer
 515      *          is backed by an array and is not read-only
 516      *
 517      * @since 1.6
 518      */
 519     public abstract boolean hasArray();
 520 
 521     /**
 522      * Returns the array that backs this
 523      * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
 524      *
 525      * <p> This method is intended to allow array-backed buffers to be
 526      * passed to native code more efficiently. Concrete subclasses
 527      * provide more strongly-typed return values for this method.
 528      *
 529      * <p> Modifications to this buffer's content will cause the returned
 530      * array's content to be modified, and vice versa.
 531      *
 532      * <p> Invoke the {@link #hasArray hasArray} method before invoking this
 533      * method in order to ensure that this buffer has an accessible backing
 534      * array.  </p>
 535      *
 536      * @return  The array that backs this buffer
 537      *
 538      * @throws  ReadOnlyBufferException
 539      *          If this buffer is backed by an array but is read-only
 540      *
 541      * @throws  UnsupportedOperationException
 542      *          If this buffer is not backed by an accessible array
 543      *
 544      * @since 1.6
 545      */
 546     public abstract Object array();
 547 
 548     /**
 549      * Returns the offset within this buffer's backing array of the first
 550      * element of the buffer&nbsp;&nbsp;<i>(optional operation)</i>.
 551      *
 552      * <p> If this buffer is backed by an array then buffer position <i>p</i>
 553      * corresponds to array index <i>p</i>&nbsp;+&nbsp;{@code arrayOffset()}.
 554      *
 555      * <p> Invoke the {@link #hasArray hasArray} method before invoking this
 556      * method in order to ensure that this buffer has an accessible backing
 557      * array.  </p>
 558      *
 559      * @return  The offset within this buffer's array
 560      *          of the first element of the buffer
 561      *
 562      * @throws  ReadOnlyBufferException
 563      *          If this buffer is backed by an array but is read-only
 564      *
 565      * @throws  UnsupportedOperationException
 566      *          If this buffer is not backed by an accessible array
 567      *
 568      * @since 1.6
 569      */
 570     public abstract int arrayOffset();
 571 
 572     /**
 573      * Tells whether or not this buffer is
 574      * <a href="ByteBuffer.html#direct"><i>direct</i></a>.
 575      *
 576      * @return  {@code true} if, and only if, this buffer is direct
 577      *
 578      * @since 1.6
 579      */
 580     public abstract boolean isDirect();
 581 
 582     /**
 583      * Creates a new buffer whose content is a shared subsequence of
 584      * this buffer's content.
 585      *
 586      * <p> The content of the new buffer will start at this buffer's current
 587      * position.  Changes to this buffer's content will be visible in the new
 588      * buffer, and vice versa; the two buffers' position, limit, and mark
 589      * values will be independent.
 590      *
 591      * <p> The new buffer's position will be zero, its capacity and its limit
 592      * will be the number of elements remaining in this buffer, its mark will be
 593      * undefined. The new buffer will be direct if, and only if, this buffer is
 594      * direct, and it will be read-only if, and only if, this buffer is
 595      * read-only.  </p>
 596      *
 597      * @return  The new buffer
 598      *
 599      * @since 9
 600      */
 601     public abstract Buffer slice();
 602 
 603     /**
 604      * Creates a new buffer whose content is a shared subsequence of
 605      * this buffer's content.
 606      *
 607      * <p> The content of the new buffer will start at position {@code index}
 608      * in this buffer, and will contain {@code length} elements. Changes to
 609      * this buffer's content will be visible in the new buffer, and vice versa;
 610      * the two buffers' position, limit, and mark values will be independent.
 611      *
 612      * <p> The new buffer's position will be zero, its capacity and its limit
 613      * will be {@code length}, its mark will be undefined. The new buffer will
 614      * be direct if, and only if, this buffer is direct, and it will be
 615      * read-only if, and only if, this buffer is read-only.  </p>
 616      *
 617      * @param   index
 618      *          The position in this buffer at which the content of the new
 619      *          buffer will start; must be non-negative and no larger than
 620      *          {@link #limit() limit()}
 621      *
 622      * @param   length
 623      *          The number of elements the new buffer will contain; must be
 624      *          non-negative and no larger than {@code limit() - index}
 625      *
 626      * @return  The new buffer
 627      *
 628      * @throws  IndexOutOfBoundsException
 629      *          If {@code index} is negative or greater than {@code limit()},
 630      *          {@code length} is negative, or {@code length > limit() - index}
 631      *
 632      * @since 13
 633      */
 634     public abstract Buffer slice(int index, int length);
 635 
 636     /**
 637      * Creates a new buffer that shares this buffer's content.
 638      *
 639      * <p> The content of the new buffer will be that of this buffer.  Changes
 640      * to this buffer's content will be visible in the new buffer, and vice
 641      * versa; the two buffers' position, limit, and mark values will be
 642      * independent.
 643      *
 644      * <p> The new buffer's capacity, limit, position and mark values will be
 645      * identical to those of this buffer. The new buffer will be direct if, and
 646      * only if, this buffer is direct, and it will be read-only if, and only if,
 647      * this buffer is read-only.  </p>
 648      *
 649      * @return  The new buffer
 650      *
 651      * @since 9
 652      */
 653     public abstract Buffer duplicate();
 654 
 655 
 656     // -- Package-private methods for bounds checking, etc. --
 657 
 658     /**
 659      *
 660      * @return the base reference, paired with the address
 661      * field, which in combination can be used for unsafe access into a heap
 662      * buffer or direct byte buffer (and views of).
 663      */
 664     abstract Object base();
 665 
 666     /**
 667      * Checks the current position against the limit, throwing a {@link
 668      * BufferUnderflowException} if it is not smaller than the limit, and then
 669      * increments the position.
 670      *
 671      * @return  The current position value, before it is incremented
 672      */
 673     final int nextGetIndex() {                          // package-private
 674         if (position >= limit)
 675             throw new BufferUnderflowException();
 676         return position++;
 677     }
 678 
 679     final int nextGetIndex(int nb) {                    // package-private
 680         if (limit - position < nb)
 681             throw new BufferUnderflowException();
 682         int p = position;
 683         position += nb;
 684         return p;
 685     }
 686 
 687     /**
 688      * Checks the current position against the limit, throwing a {@link
 689      * BufferOverflowException} if it is not smaller than the limit, and then
 690      * increments the position.
 691      *
 692      * @return  The current position value, before it is incremented
 693      */
 694     final int nextPutIndex() {                          // package-private
 695         if (position >= limit)
 696             throw new BufferOverflowException();
 697         return position++;
 698     }
 699 
 700     final int nextPutIndex(int nb) {                    // package-private
 701         if (limit - position < nb)
 702             throw new BufferOverflowException();
 703         int p = position;
 704         position += nb;
 705         return p;
 706     }
 707 
 708     /**
 709      * Checks the given index against the limit, throwing an {@link
 710      * IndexOutOfBoundsException} if it is not smaller than the limit
 711      * or is smaller than zero.
 712      */
 713     @HotSpotIntrinsicCandidate
 714     final int checkIndex(int i) {                       // package-private
 715         if ((i < 0) || (i >= limit))
 716             throw new IndexOutOfBoundsException();
 717         return i;
 718     }
 719 
 720     final int checkIndex(int i, int nb) {               // package-private
 721         if ((i < 0) || (nb > limit - i))
 722             throw new IndexOutOfBoundsException();
 723         return i;
 724     }
 725 
 726     final int markValue() {                             // package-private
 727         return mark;
 728     }
 729 
 730     final void discardMark() {                          // package-private
 731         mark = -1;
 732     }
 733 
 734     static {
 735         // setup access to this package in SharedSecrets
 736         SharedSecrets.setJavaNioAccess(
 737             new JavaNioAccess() {
 738                 @Override
 739                 public JavaNioAccess.BufferPool getDirectBufferPool() {
 740                     return Bits.BUFFER_POOL;
 741                 }
 742             });
 743     }
 744 
 745 }