8223593: Refactor code for reallocating storage

Reviewed-by: prappo, plevart, rriggs, smarks
This commit is contained in:
Ivan Gerasimov 2019-05-21 18:40:29 -07:00
parent 54d0b2a8d6
commit 218204b1a3
11 changed files with 129 additions and 247 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 2019, 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
@ -29,6 +29,8 @@ import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Objects;
import jdk.internal.util.ArraysSupport;
/**
* This class implements an output stream in which the data is
* written into a byte array. The buffer automatically grows as data
@ -84,48 +86,20 @@ public class ByteArrayOutputStream extends OutputStream {
* at least the number of elements specified by the minimum
* capacity argument.
*
* @param minCapacity the desired minimum capacity
* @throws OutOfMemoryError if {@code minCapacity < 0}. This is
* interpreted as a request for the unsatisfiably large capacity
* @param minCapacity the desired minimum capacity.
* @throws OutOfMemoryError if {@code minCapacity < 0} and
* {@code minCapacity - buf.length > 0}. This is interpreted as a
* request for the unsatisfiably large capacity.
* {@code (long) Integer.MAX_VALUE + (minCapacity - Integer.MAX_VALUE)}.
*/
private void ensureCapacity(int minCapacity) {
// overflow-conscious code
if (minCapacity - buf.length > 0)
grow(minCapacity);
}
/**
* The maximum size of array to allocate.
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = buf.length;
int newCapacity = oldCapacity << 1;
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
buf = Arrays.copyOf(buf, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
int minGrowth = minCapacity - oldCapacity;
if (minGrowth > 0) {
buf = Arrays.copyOf(buf, ArraysSupport.newLength(oldCapacity,
minGrowth, oldCapacity /* preferred growth */));
}
}
/**