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