diff --git a/src/java.base/share/classes/java/nio/X-Buffer.java.template b/src/java.base/share/classes/java/nio/X-Buffer.java.template index 2a249bca2b9..4c550d1fb0c 100644 --- a/src/java.base/share/classes/java/nio/X-Buffer.java.template +++ b/src/java.base/share/classes/java/nio/X-Buffer.java.template @@ -1871,19 +1871,20 @@ public abstract class $Type$Buffer * Returns the memory address, pointing to the byte at the given index, * modulo the given unit size. * - *
The return value is non-negative, with {@code 0} indicating that the - * address of the byte at the index is aligned for the unit size, and a - * positive value that the address is misaligned for the unit size. If the - * address of the byte at the index is misaligned, the return value + *
The return value is non-negative in the range of {@code 0} + * (inclusive) up to {@code unitSize} (exclusive), with zero indicating + * that the address of the byte at the index is aligned for the unit size, + * and a positive value that the address is misaligned for the unit size. + * If the address of the byte at the index is misaligned, the return value * represents how much the index should be adjusted to locate a byte at an * aligned address. Specifically, the index should either be decremented by - * the return value, or incremented by the unit size minus the return value. - * Therefore given + * the return value if the latter is not greater than {@code index}, or be + * incremented by the unit size minus the return value. Therefore given *
* int value = alignmentOffset(index, unitSize)
* then the identities
* + * alignmentOffset(index - value, unitSize) == 0, value ≤ index * and *- * alignmentOffset(index - value, unitSize) == 0
* alignmentOffset(index + (unitSize - value), unitSize) == 0
diff --git a/test/jdk/java/nio/Buffer/Basic-X.java.template b/test/jdk/java/nio/Buffer/Basic-X.java.template
index 057a1842130..0879a61c61c 100644
--- a/test/jdk/java/nio/Buffer/Basic-X.java.template
+++ b/test/jdk/java/nio/Buffer/Basic-X.java.template
@@ -39,6 +39,7 @@ import java.nio.*;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.Random;
#end[byte]
@@ -492,6 +493,38 @@ public class Basic$Type$
} catch (IOException e) {
throw new UncheckedIOException(e);
}
+
+ // alignment identities
+ final int maxPow2 = 12;
+ ByteBuffer bb = ByteBuffer.allocateDirect(1 << maxPow2); // cap 4096
+
+ Random rnd = new Random();
+ long seed = rnd.nextLong();
+ rnd = new Random(seed);
+
+ for (int i = 0; i < 100; i++) {
+ // 1 == 2^0 <= unitSize == 2^k <= bb.capacity()/2
+ int unitSize = 1 << rnd.nextInt(maxPow2);
+ // 0 <= index < 2*unitSize
+ int index = rnd.nextInt(unitSize << 1);
+ int value = bb.alignmentOffset(index, unitSize);
+ try {
+ if (value < 0 || value >= unitSize) {
+ throw new RuntimeException(value + " < 0 || " +
+ value + " >= " + unitSize);
+ }
+ if (value <= index &&
+ bb.alignmentOffset(index - value, unitSize) != 0)
+ throw new RuntimeException("Identity 1");
+ if (bb.alignmentOffset(index + (unitSize - value),
+ unitSize) != 0)
+ throw new RuntimeException("Identity 2");
+ } catch (RuntimeException re) {
+ System.err.format("seed %d, index %d, unitSize %d, value %d%n",
+ seed, index, unitSize, value);
+ throw re;
+ }
+ }
}
private static MappedByteBuffer[] mappedBuffers() throws IOException {
diff --git a/test/jdk/java/nio/Buffer/Basic.java b/test/jdk/java/nio/Buffer/Basic.java
index f3875a97ddb..90d5ec943ab 100644
--- a/test/jdk/java/nio/Buffer/Basic.java
+++ b/test/jdk/java/nio/Buffer/Basic.java
@@ -26,7 +26,7 @@
* @bug 4413135 4414911 4416536 4416562 4418782 4471053 4472779 4490253 4523725
* 4526177 4463011 4660660 4661219 4663521 4782970 4804304 4938424 5029431
* 5071718 6231529 6221101 6234263 6535542 6591971 6593946 6795561 7190219
- * 7199551 8065556 8149469 8230665
+ * 7199551 8065556 8149469 8230665 8237514
* @modules java.base/java.nio:open
* java.base/jdk.internal.misc
* @author Mark Reinhold
diff --git a/test/jdk/java/nio/Buffer/BasicByte.java b/test/jdk/java/nio/Buffer/BasicByte.java
index c510ee78d0d..f4790e72483 100644
--- a/test/jdk/java/nio/Buffer/BasicByte.java
+++ b/test/jdk/java/nio/Buffer/BasicByte.java
@@ -39,6 +39,7 @@ import java.nio.*;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.Random;
@@ -492,6 +493,38 @@ public class BasicByte
} catch (IOException e) {
throw new UncheckedIOException(e);
}
+
+ // alignment identities
+ final int maxPow2 = 12;
+ ByteBuffer bb = ByteBuffer.allocateDirect(1 << maxPow2); // cap 4096
+
+ Random rnd = new Random();
+ long seed = rnd.nextLong();
+ rnd = new Random(seed);
+
+ for (int i = 0; i < 100; i++) {
+ // 1 == 2^0 <= unitSize == 2^k <= bb.capacity()/2
+ int unitSize = 1 << rnd.nextInt(maxPow2);
+ // 0 <= index < 2*unitSize
+ int index = rnd.nextInt(unitSize << 1);
+ int value = bb.alignmentOffset(index, unitSize);
+ try {
+ if (value < 0 || value >= unitSize) {
+ throw new RuntimeException(value + " < 0 || " +
+ value + " >= " + unitSize);
+ }
+ if (value <= index &&
+ bb.alignmentOffset(index - value, unitSize) != 0)
+ throw new RuntimeException("Identity 1");
+ if (bb.alignmentOffset(index + (unitSize - value),
+ unitSize) != 0)
+ throw new RuntimeException("Identity 2");
+ } catch (RuntimeException re) {
+ System.err.format("seed %d, index %d, unitSize %d, value %d%n",
+ seed, index, unitSize, value);
+ throw re;
+ }
+ }
}
private static MappedByteBuffer[] mappedBuffers() throws IOException {