On Tue, 13 Jan 2026 08:18:58 GMT, Alan Bateman <[email protected]> wrote:
> it would be useful to hear more on how this might be used
As an example, imagine a subclass which wants to add a fast `writeLong` method.
With `ensureCapacity` available, this is as simple as:
public class LongStream extends ByteArrayOutputStream {
private static final VarHandle LONG =
MethodHandles.byteArrayViewVarHandle(long[].class, BIG_ENDIAN);
public void writeLong(long value) {
ensureCapacity(count + 8);
LONG.set(buf, count, value);
count += 8;
}
}
Without access to `ensureCapacity`, having access only to the buffer and the
count, the same class must copy the `ensureCapacity` logic, which means that it
must also copy the `ArraysSupport.newLength` logic:
public class LongStream2 extends ByteArrayOutputStream {
private static final VarHandle LONG =
MethodHandles.byteArrayViewVarHandle(long[].class, BIG_ENDIAN);
public void writeLong(long value) {
ensureCapacity(count + 8);
LONG.set(buf, count, value);
count += 8;
}
// **************** copied from ByteArrayOutputStream ****************
private void ensureCapacity(int minCapacity) {
// overflow-conscious code
int oldCapacity = buf.length;
int minGrowth = minCapacity - oldCapacity;
if (minGrowth > 0) {
buf = Arrays.copyOf(buf, /*ArraysSupport.*/newLength(oldCapacity,
minGrowth, oldCapacity /* preferred growth */));
}
}
// ******************** copied from ArraysSupport ********************
private static final int SOFT_MAX_ARRAY_LENGTH = Integer.MAX_VALUE - 8;
private static int newLength(int oldLength, int minGrowth, int prefGrowth) {
// preconditions not checked because of inlining
// assert oldLength >= 0
// assert minGrowth > 0
int prefLength = oldLength + Math.max(minGrowth, prefGrowth); // might
overflow
if (0 < prefLength && prefLength <= SOFT_MAX_ARRAY_LENGTH) {
return prefLength;
} else {
// put code cold in a separate method
return hugeLength(oldLength, minGrowth);
}
}
private static int hugeLength(int oldLength, int minGrowth) {
int minLength = oldLength + minGrowth;
if (minLength < 0) { // overflow
throw new OutOfMemoryError(
"Required array length " + oldLength + " + " + minGrowth + " is
too large");
} else if (minLength <= SOFT_MAX_ARRAY_LENGTH) {
return SOFT_MAX_ARRAY_LENGTH;
} else {
return minLength;
}
}
}
-------------
PR Comment: https://git.openjdk.org/jdk/pull/29180#issuecomment-3743690145