--- a/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template Mon Mar 21 11:21:08 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template Thu Mar 24 11:21:18 2016 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -269,7 +269,7 @@
//
final $type$[] hb; // Non-null only for heap buffers
final int offset;
- boolean isReadOnly; // Valid only for heap buffers
+ boolean isReadOnly;
// Creates a new buffer with the given mark, position, limit, capacity,
// backing array, and array offset
@@ -530,6 +530,10 @@
* it will be read-only if, and only if, this buffer is read-only. </p>
*
* @return The new $type$ buffer
+#if[byte]
+ *
+ * @see #alignedSlice(int)
+#end[byte]
*/
public abstract $Type$Buffer slice();
@@ -1611,6 +1615,143 @@
return this;
}
+ /**
+ * Returns the memory address, pointing to the byte at the given index,
+ * modulus the given unit size.
+ *
+ * <p> A return value greater than zero indicates the address of the byte at
+ * the index is misaligned for the unit size, and the value's quantity
+ * indicates how much the index should be rounded up or down to locate a
+ * byte at an aligned address. Otherwise, a value of {@code 0} indicates
+ * that the address of the byte at the index is aligned for the unit size.
+ *
+ * @apiNote
+ * This method may be utilized to determine if unit size bytes from an
+ * index can be accessed atomically, if supported by the native platform.
+ *
+ * @implNote
+ * This implementation throws {@code UnsupportedOperationException} for
+ * non-direct buffers when the given unit size is greater then {@code 8}.
+ *
+ * @param index
+ * The index to query for alignment offset, must be non-negative, no
+ * upper bounds check is performed
+ *
+ * @param unitSize
+ * The unit size in bytes, must be a power of {@code 2}
+ *
+ * @return The indexed byte's memory address modulus the unit size
+ *
+ * @throws IllegalArgumentException
+ * If the index is negative or the unit size is not a power of
+ * {@code 2}
+ *
+ * @throws UnsupportedOperationException
+ * If the native platform does not guarantee stable alignment offset
+ * values for the given unit size when managing the memory regions
+ * of buffers of the same kind as this buffer (direct or
+ * non-direct). For example, if garbage collection would result
+ * in the moving of a memory region covered by a non-direct buffer
+ * from one location to another and both locations have different
+ * alignment characteristics.
+ *
+ * @see #alignedSlice(int)
+ * @since 9
+ */
+ public final int alignmentOffset(int index, int unitSize) {
+ if (index < 0)
+ throw new IllegalArgumentException("Index less than zero: " + index);
+ if (unitSize < 1 || (unitSize & (unitSize - 1)) != 0)
+ throw new IllegalArgumentException("Unit size not a power of two: " + unitSize);
+ if (unitSize > 8 && !isDirect())
+ throw new UnsupportedOperationException("Unit size unsupported for non-direct buffers: " + unitSize);
+
+ return (int) ((address + index) % unitSize);
+ }
+
+ /**
+ * Creates a new byte buffer whose content is a shared and aligned
+ * subsequence of this buffer's content.
+ *
+ * <p> The content of the new buffer will start at this buffer's current
+ * position rounded up to the index of the nearest aligned byte for the
+ * given unit size, and end at this buffer's limit rounded down to the index
+ * of the nearest aligned byte for the given unit size.
+ * If rounding results in out-of-bound values then the new buffer's capacity
+ * and limit will be zero. If rounding is within bounds the following
+ * expressions will be true for a new buffer {@code nb} and unit size
+ * {@code unitSize}:
+ * <pre>{@code
+ * nb.alignmentOffset(0, unitSize) == 0
+ * nb.alignmentOffset(nb.limit(), unitSize) == 0
+ * }</pre>
+ *
+ * <p> Changes to this buffer's content will be visible in the new
+ * buffer, and vice versa; the two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's position will be zero, its capacity and its limit
+ * will be the number of bytes remaining in this buffer or fewer subject to
+ * alignment, its mark will be undefined, and its byte order will be
+ * {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN}.
+ *
+ * The new buffer will be direct if, and only if, this buffer is direct, and
+ * it will be read-only if, and only if, this buffer is read-only. </p>
+ *
+ * @apiNote
+ * This method may be utilized to create a new buffer where unit size bytes
+ * from index, that is a multiple of the unit size, may be accessed
+ * atomically, if supported by the native platform.
+ *
+ * @implNote
+ * This implementation throws {@code UnsupportedOperationException} for
+ * non-direct buffers when the given unit size is greater then {@code 8}.
+ *
+ * @param unitSize
+ * The unit size in bytes, must be a power of {@code 2}
+ *
+ * @return The new byte buffer
+ *
+ * @throws IllegalArgumentException
+ * If the unit size not a power of {@code 2}
+ *
+ * @throws UnsupportedOperationException
+ * If the native platform does not guarantee stable aligned slices
+ * for the given unit size when managing the memory regions
+ * of buffers of the same kind as this buffer (direct or
+ * non-direct). For example, if garbage collection would result
+ * in the moving of a memory region covered by a non-direct buffer
+ * from one location to another and both locations have different
+ * alignment characteristics.
+ *
+ * @see #alignmentOffset(int, int)
+ * @see #slice()
+ * @since 9
+ */
+ public final ByteBuffer alignedSlice(int unitSize) {
+ int pos = position();
+ int lim = limit();
+
+ int pos_mod = alignmentOffset(pos, unitSize);
+ int lim_mod = alignmentOffset(lim, unitSize);
+
+ // Round up the position to align with unit size
+ int aligned_pos = (pos_mod > 0)
+ ? pos + (unitSize - pos_mod)
+ : pos;
+
+ // Round down the limit to align with unit size
+ int aligned_lim = lim - lim_mod;
+
+ if (aligned_pos > lim || aligned_lim < pos) {
+ aligned_pos = aligned_lim = pos;
+ }
+
+ return slice(aligned_pos, aligned_lim);
+ }
+
+ abstract ByteBuffer slice(int pos, int lim);
+
// Unchecked accessors, for use by ByteBufferAs-X-Buffer classes
//
abstract byte _get(int i); // package-private