mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-20 07:15:31 +00:00
8149469: ByteBuffer API and implementation enhancements for VarHandles
Reviewed-by: chegar, alanb
This commit is contained in:
parent
2954d94462
commit
4485394e3d
@ -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
|
||||
@ -25,9 +25,10 @@
|
||||
|
||||
package java.nio;
|
||||
|
||||
import java.util.Spliterator;
|
||||
import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
|
||||
import java.util.Spliterator;
|
||||
|
||||
/**
|
||||
* A container for data of a specific primitive type.
|
||||
*
|
||||
@ -188,7 +189,15 @@ public abstract class Buffer {
|
||||
private int limit;
|
||||
private int capacity;
|
||||
|
||||
// Used only by direct buffers
|
||||
// Used by heap byte buffers or direct buffers with Unsafe access
|
||||
// For heap byte buffers this field will be the address relative to the
|
||||
// array base address and offset into that array. The address might
|
||||
// not align on a word boundary for slices, nor align at a long word
|
||||
// (8 byte) boundary for byte[] allocations on 32-bit systems.
|
||||
// For direct buffers it is the start address of the memory region. The
|
||||
// address might not align on a word boundary for slices, nor when created
|
||||
// using JNI, see NewDirectByteBuffer(void*, long).
|
||||
// Should ideally be declared final
|
||||
// NOTE: hoisted here for speed in JNI GetDirectBufferAddress
|
||||
long address;
|
||||
|
||||
|
||||
@ -140,6 +140,7 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
att = null;
|
||||
#else[rw]
|
||||
super(cap);
|
||||
this.isReadOnly = true;
|
||||
#end[rw]
|
||||
}
|
||||
|
||||
@ -180,6 +181,7 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
att = null;
|
||||
#else[rw]
|
||||
super(cap, addr, fd, unmapper);
|
||||
this.isReadOnly = true;
|
||||
#end[rw]
|
||||
}
|
||||
|
||||
@ -200,6 +202,7 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
att = db;
|
||||
#else[rw]
|
||||
super(db, mark, pos, lim, cap, off);
|
||||
this.isReadOnly = true;
|
||||
#end[rw]
|
||||
}
|
||||
|
||||
@ -213,6 +216,15 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
return new Direct$Type$Buffer$RW$$BO$(this, -1, 0, rem, rem, off);
|
||||
}
|
||||
|
||||
#if[byte]
|
||||
public $Type$Buffer slice(int pos, int lim) {
|
||||
assert (pos >= 0);
|
||||
assert (pos <= lim);
|
||||
int rem = lim - pos;
|
||||
return new Direct$Type$Buffer$RW$$BO$(this, -1, 0, rem, rem, pos);
|
||||
}
|
||||
#end[byte]
|
||||
|
||||
public $Type$Buffer duplicate() {
|
||||
return new Direct$Type$Buffer$RW$$BO$(this,
|
||||
this.markValue(),
|
||||
|
||||
@ -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
|
||||
@ -74,6 +74,9 @@ class Heap$Type$Buffer$RW$
|
||||
super(cap, lim);
|
||||
this.isReadOnly = true;
|
||||
#end[rw]
|
||||
#if[byte]
|
||||
this.address = arrayBaseOffset;
|
||||
#end[byte]
|
||||
}
|
||||
|
||||
Heap$Type$Buffer$RW$($type$[] buf, int off, int len) { // package-private
|
||||
@ -87,6 +90,9 @@ class Heap$Type$Buffer$RW$
|
||||
super(buf, off, len);
|
||||
this.isReadOnly = true;
|
||||
#end[rw]
|
||||
#if[byte]
|
||||
this.address = arrayBaseOffset;
|
||||
#end[byte]
|
||||
}
|
||||
|
||||
protected Heap$Type$Buffer$RW$($type$[] buf,
|
||||
@ -103,6 +109,9 @@ class Heap$Type$Buffer$RW$
|
||||
super(buf, mark, pos, lim, cap, off);
|
||||
this.isReadOnly = true;
|
||||
#end[rw]
|
||||
#if[byte]
|
||||
this.address = arrayBaseOffset + off;
|
||||
#end[byte]
|
||||
}
|
||||
|
||||
public $Type$Buffer slice() {
|
||||
@ -114,6 +123,20 @@ class Heap$Type$Buffer$RW$
|
||||
this.position() + offset);
|
||||
}
|
||||
|
||||
#if[byte]
|
||||
$Type$Buffer slice(int pos, int lim) {
|
||||
assert (pos >= 0);
|
||||
assert (pos <= lim);
|
||||
int rem = lim - pos;
|
||||
return new Heap$Type$Buffer$RW$(hb,
|
||||
-1,
|
||||
0,
|
||||
rem,
|
||||
rem,
|
||||
pos + offset);
|
||||
}
|
||||
#end[byte]
|
||||
|
||||
public $Type$Buffer duplicate() {
|
||||
return new Heap$Type$Buffer$RW$(hb,
|
||||
this.markValue(),
|
||||
@ -144,7 +167,7 @@ class Heap$Type$Buffer$RW$
|
||||
|
||||
#if[byte]
|
||||
private long byteOffset(long i) {
|
||||
return arrayBaseOffset + i + offset;
|
||||
return address + i;
|
||||
}
|
||||
#end[byte]
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, 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
|
||||
@ -39,6 +39,7 @@ class StringCharBuffer // package-private
|
||||
if ((start < 0) || (start > n) || (end < start) || (end > n))
|
||||
throw new IndexOutOfBoundsException();
|
||||
str = s;
|
||||
this.isReadOnly = true;
|
||||
}
|
||||
|
||||
public CharBuffer slice() {
|
||||
@ -58,6 +59,7 @@ class StringCharBuffer // package-private
|
||||
int offset) {
|
||||
super(mark, pos, limit, cap, null, offset);
|
||||
str = s;
|
||||
this.isReadOnly = true;
|
||||
}
|
||||
|
||||
public CharBuffer duplicate() {
|
||||
|
||||
@ -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 @@ public abstract class $Type$Buffer
|
||||
//
|
||||
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 @@ public abstract class $Type$Buffer
|
||||
* 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 @@ public abstract class $Type$Buffer
|
||||
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
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, 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
|
||||
@ -336,6 +336,103 @@ public class Basic$Type$
|
||||
|
||||
}
|
||||
|
||||
private static void testAlign(final ByteBuffer b, boolean direct) {
|
||||
// index out-of bounds
|
||||
tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(-1, (short) 1));
|
||||
|
||||
// unit size values
|
||||
tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(0, (short) 0));
|
||||
for (int us = 1; us < 65; us++) {
|
||||
int _us = us;
|
||||
if ((us & (us - 1)) != 0) {
|
||||
// unit size not a power of two
|
||||
tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(0, _us));
|
||||
} else {
|
||||
if (direct || us <= 8) {
|
||||
b.alignmentOffset(0, us);
|
||||
} else {
|
||||
// unit size > 8 with non-direct buffer
|
||||
tryCatch(b, UnsupportedOperationException.class, () -> b.alignmentOffset(0, _us));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Probe for long misalignment at index zero for a newly created buffer
|
||||
ByteBuffer empty = direct ? ByteBuffer.allocateDirect(0) : ByteBuffer.allocate(0);
|
||||
int longMisalignmentAtZero = empty.alignmentOffset(0, 8);
|
||||
|
||||
if (direct) {
|
||||
// Freshly created direct byte buffers should be aligned at index 0
|
||||
// for ref and primitive values (see Unsafe.allocateMemory)
|
||||
if (longMisalignmentAtZero != 0)
|
||||
fail("Direct byte buffer misalligned at index 0 for ref and primitive values " + longMisalignmentAtZero);
|
||||
} else {
|
||||
// For heap byte buffers misalignment may occur on 32-bit systems
|
||||
// where Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 == 4 and not 0
|
||||
// Note the GC will preserve alignment of the base address of the
|
||||
// array
|
||||
if (jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 != longMisalignmentAtZero)
|
||||
fail("Heap byte buffer misalligned at index 0 for ref and primitive values " + longMisalignmentAtZero);
|
||||
}
|
||||
|
||||
// Ensure test buffer is correctly aligned at index 0
|
||||
if (b.alignmentOffset(0, 8) != longMisalignmentAtZero)
|
||||
fail("Test input buffer not correctly aligned at index 0", b);
|
||||
|
||||
// Test misalignment values
|
||||
for (int us : new int[]{1, 2, 4, 8}) {
|
||||
for (int i = 0; i < us * 2; i++) {
|
||||
int am = b.alignmentOffset(i, us);
|
||||
int expectedAm = (longMisalignmentAtZero + i) % us;
|
||||
|
||||
if (am != expectedAm)
|
||||
fail(String.format("b.alignmentOffset(%d, %d) == %d incorrect, expected %d", i, us, am, expectedAm));
|
||||
}
|
||||
}
|
||||
|
||||
// Created aligned slice to test against
|
||||
int ap = 8 - longMisalignmentAtZero;
|
||||
int al = b.limit() - b.alignmentOffset(b.limit(), 8);
|
||||
ByteBuffer ab = b.position(ap).limit(al).
|
||||
slice();
|
||||
if (ab.limit() == 0)
|
||||
fail("Test input buffer not sufficiently sized to cover an aligned region for all values", b);
|
||||
if (ab.alignmentOffset(0, 8) != 0)
|
||||
fail("Aligned test input buffer not correctly aligned at index 0", ab);
|
||||
|
||||
for (int us : new int[]{1, 2, 4, 8}) {
|
||||
for (int p = 1; p < 16; p++) {
|
||||
int l = ab.limit() - p;
|
||||
|
||||
ByteBuffer as = ab.slice().position(p).limit(l).
|
||||
alignedSlice(us);
|
||||
|
||||
ck(as, 0, as.position());
|
||||
ck(as, as.capacity(), as.limit());
|
||||
if (b.isDirect() != as.isDirect())
|
||||
fail("Lost direction", as);
|
||||
if (b.isReadOnly() != as.isReadOnly())
|
||||
fail("Lost read-only", as);
|
||||
|
||||
if (as.alignmentOffset(0, us) != 0)
|
||||
fail("Buffer not correctly aligned at index 0", as);
|
||||
|
||||
if (as.alignmentOffset(as.limit(), us) != 0)
|
||||
fail("Buffer not correctly aligned at limit", as);
|
||||
|
||||
int p_mod = ab.alignmentOffset(p, us);
|
||||
int l_mod = ab.alignmentOffset(l, us);
|
||||
// Round up position
|
||||
p = (p_mod > 0) ? p + (us - p_mod) : p;
|
||||
// Round down limit
|
||||
l = l - l_mod;
|
||||
|
||||
int ec = l - p;
|
||||
if (as.limit() != ec)
|
||||
fail("Buffer capacity incorrect, expected: " + ec, as);
|
||||
}
|
||||
}
|
||||
}
|
||||
#end[byte]
|
||||
|
||||
private static void fail(String problem,
|
||||
@ -854,6 +951,11 @@ public class Basic$Type$
|
||||
|
||||
relPut(b); // Required by testViews
|
||||
|
||||
#if[byte]
|
||||
// Test alignment
|
||||
|
||||
testAlign(b, direct);
|
||||
#end[byte]
|
||||
}
|
||||
|
||||
#if[char]
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
* @bug 4413135 4414911 4416536 4416562 4418782 4471053 4472779 4490253 4523725
|
||||
* 4526177 4463011 4660660 4661219 4663521 4782970 4804304 4938424 6231529
|
||||
* 6221101 6234263 6535542 6591971 6593946 6795561 7190219 7199551 8065556
|
||||
* 8149469
|
||||
* @author Mark Reinhold
|
||||
*/
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, 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
|
||||
@ -336,6 +336,103 @@ public class BasicByte
|
||||
|
||||
}
|
||||
|
||||
private static void testAlign(final ByteBuffer b, boolean direct) {
|
||||
// index out-of bounds
|
||||
tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(-1, (short) 1));
|
||||
|
||||
// unit size values
|
||||
tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(0, (short) 0));
|
||||
for (int us = 1; us < 65; us++) {
|
||||
int _us = us;
|
||||
if ((us & (us - 1)) != 0) {
|
||||
// unit size not a power of two
|
||||
tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(0, _us));
|
||||
} else {
|
||||
if (direct || us <= 8) {
|
||||
b.alignmentOffset(0, us);
|
||||
} else {
|
||||
// unit size > 8 with non-direct buffer
|
||||
tryCatch(b, UnsupportedOperationException.class, () -> b.alignmentOffset(0, _us));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Probe for long misalignment at index zero for a newly created buffer
|
||||
ByteBuffer empty = direct ? ByteBuffer.allocateDirect(0) : ByteBuffer.allocate(0);
|
||||
int longMisalignmentAtZero = empty.alignmentOffset(0, 8);
|
||||
|
||||
if (direct) {
|
||||
// Freshly created direct byte buffers should be aligned at index 0
|
||||
// for ref and primitive values (see Unsafe.allocateMemory)
|
||||
if (longMisalignmentAtZero != 0)
|
||||
fail("Direct byte buffer misalligned at index 0 for ref and primitive values " + longMisalignmentAtZero);
|
||||
} else {
|
||||
// For heap byte buffers misalignment may occur on 32-bit systems
|
||||
// where Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 == 4 and not 0
|
||||
// Note the GC will preserve alignment of the base address of the
|
||||
// array
|
||||
if (jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 != longMisalignmentAtZero)
|
||||
fail("Heap byte buffer misalligned at index 0 for ref and primitive values " + longMisalignmentAtZero);
|
||||
}
|
||||
|
||||
// Ensure test buffer is correctly aligned at index 0
|
||||
if (b.alignmentOffset(0, 8) != longMisalignmentAtZero)
|
||||
fail("Test input buffer not correctly aligned at index 0", b);
|
||||
|
||||
// Test misalignment values
|
||||
for (int us : new int[]{1, 2, 4, 8}) {
|
||||
for (int i = 0; i < us * 2; i++) {
|
||||
int am = b.alignmentOffset(i, us);
|
||||
int expectedAm = (longMisalignmentAtZero + i) % us;
|
||||
|
||||
if (am != expectedAm)
|
||||
fail(String.format("b.alignmentOffset(%d, %d) == %d incorrect, expected %d", i, us, am, expectedAm));
|
||||
}
|
||||
}
|
||||
|
||||
// Created aligned slice to test against
|
||||
int ap = 8 - longMisalignmentAtZero;
|
||||
int al = b.limit() - b.alignmentOffset(b.limit(), 8);
|
||||
ByteBuffer ab = b.position(ap).limit(al).
|
||||
slice();
|
||||
if (ab.limit() == 0)
|
||||
fail("Test input buffer not sufficiently sized to cover an aligned region for all values", b);
|
||||
if (ab.alignmentOffset(0, 8) != 0)
|
||||
fail("Aligned test input buffer not correctly aligned at index 0", ab);
|
||||
|
||||
for (int us : new int[]{1, 2, 4, 8}) {
|
||||
for (int p = 1; p < 16; p++) {
|
||||
int l = ab.limit() - p;
|
||||
|
||||
ByteBuffer as = ab.slice().position(p).limit(l).
|
||||
alignedSlice(us);
|
||||
|
||||
ck(as, 0, as.position());
|
||||
ck(as, as.capacity(), as.limit());
|
||||
if (b.isDirect() != as.isDirect())
|
||||
fail("Lost direction", as);
|
||||
if (b.isReadOnly() != as.isReadOnly())
|
||||
fail("Lost read-only", as);
|
||||
|
||||
if (as.alignmentOffset(0, us) != 0)
|
||||
fail("Buffer not correctly aligned at index 0", as);
|
||||
|
||||
if (as.alignmentOffset(as.limit(), us) != 0)
|
||||
fail("Buffer not correctly aligned at limit", as);
|
||||
|
||||
int p_mod = ab.alignmentOffset(p, us);
|
||||
int l_mod = ab.alignmentOffset(l, us);
|
||||
// Round up position
|
||||
p = (p_mod > 0) ? p + (us - p_mod) : p;
|
||||
// Round down limit
|
||||
l = l - l_mod;
|
||||
|
||||
int ec = l - p;
|
||||
if (as.limit() != ec)
|
||||
fail("Buffer capacity incorrect, expected: " + ec, as);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void fail(String problem,
|
||||
@ -854,6 +951,11 @@ public class BasicByte
|
||||
|
||||
relPut(b); // Required by testViews
|
||||
|
||||
|
||||
// Test alignment
|
||||
|
||||
testAlign(b, direct);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, 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
|
||||
@ -317,6 +317,103 @@ public class BasicChar
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -854,6 +951,11 @@ public class BasicChar
|
||||
|
||||
relPut(b); // Required by testViews
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, 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
|
||||
@ -317,6 +317,103 @@ public class BasicDouble
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -854,6 +951,11 @@ public class BasicDouble
|
||||
|
||||
relPut(b); // Required by testViews
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, 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
|
||||
@ -317,6 +317,103 @@ public class BasicFloat
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -854,6 +951,11 @@ public class BasicFloat
|
||||
|
||||
relPut(b); // Required by testViews
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, 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
|
||||
@ -317,6 +317,103 @@ public class BasicInt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -854,6 +951,11 @@ public class BasicInt
|
||||
|
||||
relPut(b); // Required by testViews
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, 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
|
||||
@ -317,6 +317,103 @@ public class BasicLong
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -854,6 +951,11 @@ public class BasicLong
|
||||
|
||||
relPut(b); // Required by testViews
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, 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
|
||||
@ -317,6 +317,103 @@ public class BasicShort
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -854,6 +951,11 @@ public class BasicShort
|
||||
|
||||
relPut(b); // Required by testViews
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user