Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8255151

Add utility methods to check long indexes and ranges

    XMLWordPrintable

    Details

    • Type: CSR
    • Status: Closed
    • Priority: P4
    • Resolution: Approved
    • Fix Version/s: 16
    • Component/s: core-libs
    • Labels:
      None
    • Subcomponent:
    • Compatibility Kind:
      source
    • Compatibility Risk:
      minimal
    • Compatibility Risk Description:
      New methods
    • Interface Kind:
      Java API
    • Scope:
      SE

      Description

      Summary

      Add bounds check methods accepting long values.

      Problem

      Bounds checking is not difficult to write explicitly but it can be easy to make trivial mistakes, such as introducing overflow bugs. It is advantageous to consolidate such checks from a correctness and security/integrity perspective. Further more in certain cases it is an opportunity to optimize, via an intrinsic, certain checks and guide hotspot towards unsigned comparisons.

      Enhancements to the Java platform will enable optimizations of loops over bounds greater than the minimum and maximum range of int values, requiring bounds checking operating on long values.

      In the Foreign Memory Access API (JEP 393), the bounds of a memory segments are expressed as long values. Since bound checks involving longs are not currently optimized, the implementation of the foreign memory access API had to resort to several tricks to gauge whether a memory segment can be considered "small" (e.g. whose size fits in an int value) and then use int operations on small segments, accordingly. While in most cases, these workarounds are hidden inside the API implementation, they add a significant cost in terms of complexity and long term maintenance.

      Solution

      Overload the existing int accepting bounds check methods defined in java.util.Objects with long accepting bounds check methods.

      Specification

      The following static methods are added to java.util.Objects. The specification is identical to that of the existing int accepting bounds check methods of the same method name.

      /**
       * Checks if the {@code index} is within the bounds of the range from
       * {@code 0} (inclusive) to {@code length} (exclusive).
       *
       * <p>The {@code index} is defined to be out of bounds if any of the
       * following inequalities is true:
       * <ul>
       *  <li>{@code index < 0}</li>
       *  <li>{@code index >= length}</li>
       *  <li>{@code length < 0}, which is implied from the former inequalities</li>
       * </ul>
       *
       * @param index the index
       * @param length the upper-bound (exclusive) of the range
       * @return {@code index} if it is within bounds of the range
       * @throws IndexOutOfBoundsException if the {@code index} is out of bounds
       * @since 16
       */
      public static
      long checkIndex(long index, long length)
      
      /**
       * Checks if the sub-range from {@code fromIndex} (inclusive) to
       * {@code toIndex} (exclusive) is within the bounds of range from {@code 0}
       * (inclusive) to {@code length} (exclusive).
       *
       * <p>The sub-range is defined to be out of bounds if any of the following
       * inequalities is true:
       * <ul>
       *  <li>{@code fromIndex < 0}</li>
       *  <li>{@code fromIndex > toIndex}</li>
       *  <li>{@code toIndex > length}</li>
       *  <li>{@code length < 0}, which is implied from the former inequalities</li>
       * </ul>
       *
       * @param fromIndex the lower-bound (inclusive) of the sub-range
       * @param toIndex the upper-bound (exclusive) of the sub-range
       * @param length the upper-bound (exclusive) the range
       * @return {@code fromIndex} if the sub-range within bounds of the range
       * @throws IndexOutOfBoundsException if the sub-range is out of bounds
       * @since 16
       */
      public static
      long checkFromToIndex(long fromIndex, long toIndex, long length)
      
      /**
       * Checks if the sub-range from {@code fromIndex} (inclusive) to
       * {@code fromIndex + size} (exclusive) is within the bounds of range from
       * {@code 0} (inclusive) to {@code length} (exclusive).
       *
       * <p>The sub-range is defined to be out of bounds if any of the following
       * inequalities is true:
       * <ul>
       *  <li>{@code fromIndex < 0}</li>
       *  <li>{@code size < 0}</li>
       *  <li>{@code fromIndex + size > length}, taking into account integer overflow</li>
       *  <li>{@code length < 0}, which is implied from the former inequalities</li>
       * </ul>
       *
       * @param fromIndex the lower-bound (inclusive) of the sub-interval
       * @param size the size of the sub-range
       * @param length the upper-bound (exclusive) of the range
       * @return {@code fromIndex} if the sub-range within bounds of the range
       * @throws IndexOutOfBoundsException if the sub-range is out of bounds
       * @since 16
       */
      public static
      long checkFromIndexSize(long fromIndex, long size, long length)

      The following constructor is added to java.lang.IndexOutOfBoundsException:

      /**
       * Constructs a new {@code IndexOutOfBoundsException} class with an
       * argument indicating the illegal index.
       *
       * <p>The index is included in this exception's detail message.  The
       * exact presentation format of the detail message is unspecified.
       *
       * @param index the illegal index.
       * @since 16
       */
      public IndexOutOfBoundsException(long index)

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              psandoz Paul Sandoz
              Reporter:
              roland Roland Westrelin
              Reviewed By:
              Chris Hegarty, Maurizio Cimadamore
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: