Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consolidate declarations of MAX_ARRAY_SIZE in one place #1506

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions src/java.base/share/classes/java/io/InputStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -301,14 +301,6 @@ public int read(byte b[], int off, int len) throws IOException {
return i;
}

/**
* 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_BUFFER_SIZE = Integer.MAX_VALUE - 8;

/**
* Reads all remaining bytes from the input stream. This method blocks until
* all remaining bytes have been read and end of stream is detected, or an
Expand Down Expand Up @@ -413,7 +405,7 @@ public byte[] readNBytes(int len) throws IOException {
}

if (nread > 0) {
if (MAX_BUFFER_SIZE - total < nread) {
if (Arrays.MAX_ARRAY_SIZE - total < nread) {
throw new OutOfMemoryError("Required array size too large");
}
if (nread < buf.length) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,20 +230,12 @@ private void ensureCapacityInternal(int minimumCapacity) {
}
}

/**
* The maximum size of array to allocate (unless necessary).
* 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;

/**
* Returns a capacity at least as large as the given minimum capacity.
* Returns the current capacity increased by the current length + 2 if
* that suffices.
* Will not return a capacity greater than
* {@code (MAX_ARRAY_SIZE >> coder)} unless the given minimum capacity
* {@code (Arrays.MAX_ARRAY_SIZE >> coder)} unless the given minimum capacity
* is greater than that.
*
* @param minCapacity the desired minimum capacity
Expand Down
16 changes: 4 additions & 12 deletions src/java.base/share/classes/java/util/ArrayDeque.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,6 @@ public class ArrayDeque<E> extends AbstractCollection<E>
*/
transient int tail;

/**
* 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 of this deque by at least the given amount.
*
Expand All @@ -144,7 +136,7 @@ private void grow(int needed) {
// Double capacity if small; else grow by 50%
int jump = (oldCapacity < 64) ? (oldCapacity + 2) : (oldCapacity >> 1);
if (jump < needed
|| (newCapacity = (oldCapacity + jump)) - MAX_ARRAY_SIZE > 0)
|| (newCapacity = (oldCapacity + jump)) - Arrays.MAX_ARRAY_SIZE > 0)
newCapacity = newCapacity(needed, jump);
final Object[] es = elements = Arrays.copyOf(elements, newCapacity);
// Exceptionally, here tail == head needs to be disambiguated
Expand All @@ -162,16 +154,16 @@ private void grow(int needed) {
/** Capacity calculation for edge conditions, especially overflow. */
private int newCapacity(int needed, int jump) {
final int oldCapacity = elements.length, minCapacity;
if ((minCapacity = oldCapacity + needed) - MAX_ARRAY_SIZE > 0) {
if ((minCapacity = oldCapacity + needed) - Arrays.MAX_ARRAY_SIZE > 0) {
if (minCapacity < 0)
throw new IllegalStateException("Sorry, deque too big");
return Integer.MAX_VALUE;
}
if (needed > jump)
return minCapacity;
return (oldCapacity + jump - MAX_ARRAY_SIZE < 0)
return (oldCapacity + jump - Arrays.MAX_ARRAY_SIZE < 0)
? oldCapacity + jump
: MAX_ARRAY_SIZE;
: Arrays.MAX_ARRAY_SIZE;
}

/**
Expand Down
9 changes: 9 additions & 0 deletions src/java.base/share/classes/java/util/Arrays.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ public class Arrays {
// Suppresses default constructor, ensuring non-instantiability.
private Arrays() {}


/**
* 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
*/
public static final int MAX_ARRAY_SIZE = ArraysSupport.MAX_ARRAY_LENGTH;

/*
* Sorting methods. Note that all public "sort" methods take the
* same form: performing argument checks if necessary, and then
Expand Down
2 changes: 1 addition & 1 deletion src/java.base/share/classes/java/util/BitSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -1186,7 +1186,7 @@ private void readObject(ObjectInputStream s)
public String toString() {
checkInvariants();

final int MAX_INITIAL_CAPACITY = Integer.MAX_VALUE - 8;
final int MAX_INITIAL_CAPACITY = Arrays.MAX_ARRAY_SIZE;
int numBits = (wordsInUse > 128) ?
cardinality() : wordsInUse * BITS_PER_WORD;
// Avoid overflow in the case of a humongous numBits
Expand Down
22 changes: 7 additions & 15 deletions src/java.base/share/classes/java/util/Hashtable.java
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ public Hashtable(int initialCapacity, float loadFactor) {
initialCapacity = 1;
this.loadFactor = loadFactor;
table = new Entry<?,?>[initialCapacity];
threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
threshold = (int)Math.min(initialCapacity * loadFactor, Arrays.MAX_ARRAY_SIZE + 1);
}

/**
Expand Down Expand Up @@ -388,14 +388,6 @@ public synchronized V get(Object key) {
return null;
}

/**
* 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 of and internally reorganizes this
* hashtable, in order to accommodate and access its entries more
Expand All @@ -410,16 +402,16 @@ protected void rehash() {

// overflow-conscious code
int newCapacity = (oldCapacity << 1) + 1;
if (newCapacity - MAX_ARRAY_SIZE > 0) {
if (oldCapacity == MAX_ARRAY_SIZE)
if (newCapacity - Arrays.MAX_ARRAY_SIZE > 0) {
if (oldCapacity == Arrays.MAX_ARRAY_SIZE)
// Keep running with MAX_ARRAY_SIZE buckets
return;
newCapacity = MAX_ARRAY_SIZE;
newCapacity = Arrays.MAX_ARRAY_SIZE;
}
Entry<?,?>[] newMap = new Entry<?,?>[newCapacity];

modCount++;
threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
threshold = (int)Math.min(newCapacity * loadFactor, Arrays.MAX_ARRAY_SIZE + 1);
table = newMap;

for (int i = oldCapacity ; i-- > 0 ;) {
Expand Down Expand Up @@ -1248,7 +1240,7 @@ void writeHashtable(java.io.ObjectOutputStream s)
*/
final void defaultWriteHashtable(java.io.ObjectOutputStream s, int length,
float loadFactor) throws IOException {
this.threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1);
this.threshold = (int)Math.min(length * loadFactor, Arrays.MAX_ARRAY_SIZE + 1);
this.loadFactor = loadFactor;
s.defaultWriteObject();
}
Expand Down Expand Up @@ -1304,7 +1296,7 @@ void readHashtable(java.io.ObjectInputStream s)
// what we're actually creating.
SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Map.Entry[].class, length);
table = new Entry<?,?>[length];
threshold = (int)Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1);
threshold = (int)Math.min(length * loadFactor, Arrays.MAX_ARRAY_SIZE + 1);
count = 0;

// Read the number of elements and then all the key/value objects
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -513,12 +513,6 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
*/
private static final int DEFAULT_CAPACITY = 16;

/**
* The largest possible (non-power of two) array size.
* Needed by toArray and related methods.
*/
static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

/**
* The default concurrency level for this table. Unused but
* defined for compatibility with previous versions of this class.
Expand Down Expand Up @@ -4455,17 +4449,17 @@ abstract static class CollectionView<K,V,E>

public final Object[] toArray() {
long sz = map.mappingCount();
if (sz > MAX_ARRAY_SIZE)
if (sz > Arrays.MAX_ARRAY_SIZE)
throw new OutOfMemoryError(OOME_MSG);
int n = (int)sz;
Object[] r = new Object[n];
int i = 0;
for (E e : this) {
if (i == n) {
if (n >= MAX_ARRAY_SIZE)
if (n >= Arrays.MAX_ARRAY_SIZE)
throw new OutOfMemoryError(OOME_MSG);
if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
n = MAX_ARRAY_SIZE;
if (n >= Arrays.MAX_ARRAY_SIZE - (Arrays.MAX_ARRAY_SIZE >>> 1) - 1)
n = Arrays.MAX_ARRAY_SIZE;
else
n += (n >>> 1) + 1;
r = Arrays.copyOf(r, n);
Expand All @@ -4478,7 +4472,7 @@ public final Object[] toArray() {
@SuppressWarnings("unchecked")
public final <T> T[] toArray(T[] a) {
long sz = map.mappingCount();
if (sz > MAX_ARRAY_SIZE)
if (sz > Arrays.MAX_ARRAY_SIZE)
throw new OutOfMemoryError(OOME_MSG);
int m = (int)sz;
T[] r = (a.length >= m) ? a :
Expand All @@ -4488,10 +4482,10 @@ public final <T> T[] toArray(T[] a) {
int i = 0;
for (E e : this) {
if (i == n) {
if (n >= MAX_ARRAY_SIZE)
if (n >= Arrays.MAX_ARRAY_SIZE)
throw new OutOfMemoryError(OOME_MSG);
if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
n = MAX_ARRAY_SIZE;
if (n >= Arrays.MAX_ARRAY_SIZE - (Arrays.MAX_ARRAY_SIZE >>> 1) - 1)
n = Arrays.MAX_ARRAY_SIZE;
else
n += (n >>> 1) + 1;
r = Arrays.copyOf(r, n);
Expand Down
6 changes: 2 additions & 4 deletions src/java.base/share/classes/java/util/jar/JarFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@

package java.util.jar;

import java.util.Arrays;
import jdk.internal.access.SharedSecrets;
import jdk.internal.access.JavaUtilZipFileAccess;
import sun.security.action.GetPropertyAction;
import sun.security.util.ManifestEntryVerifier;
import sun.security.util.SignatureFileVerifier;

import java.io.ByteArrayInputStream;
import java.io.EOFException;
Expand Down Expand Up @@ -152,8 +152,6 @@ public class JarFile extends ZipFile {
private static final boolean MULTI_RELEASE_ENABLED;
private static final boolean MULTI_RELEASE_FORCED;
private static final ThreadLocal<Boolean> isInitializing = new ThreadLocal<>();
// The maximum size of array to allocate. Some VMs reserve some header words in an array.
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

private SoftReference<Manifest> manRef;
private JarEntry manEntry;
Expand Down Expand Up @@ -796,7 +794,7 @@ private void initializeVerifier() {
private byte[] getBytes(ZipEntry ze) throws IOException {
try (InputStream is = super.getInputStream(ze)) {
long uncompressedSize = ze.getSize();
if (uncompressedSize > MAX_ARRAY_SIZE) {
if (uncompressedSize > Arrays.MAX_ARRAY_SIZE) {
throw new OutOfMemoryError("Required array size too large");
}
int len = (int)uncompressedSize;
Expand Down
4 changes: 2 additions & 2 deletions src/java.base/share/classes/java/util/regex/Pattern.java
Original file line number Diff line number Diff line change
Expand Up @@ -1355,8 +1355,8 @@ public static String quote(String s) {
return "\\Q" + s + "\\E";

int lenHint = s.length();
lenHint = (lenHint < Integer.MAX_VALUE - 8 - lenHint) ?
(lenHint << 1) : (Integer.MAX_VALUE - 8);
lenHint = (lenHint < Arrays.MAX_ARRAY_SIZE - lenHint) ?
(lenHint << 1) : Arrays.MAX_ARRAY_SIZE;

StringBuilder sb = new StringBuilder(lenHint);
sb.append("\\Q");
Expand Down
3 changes: 1 addition & 2 deletions src/java.base/share/classes/java/util/stream/Nodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Deque;
import java.util.List;
import java.util.Objects;
import java.util.Spliterator;
import java.util.Spliterators;
Expand Down Expand Up @@ -58,7 +57,7 @@ private Nodes() {
/**
* The maximum size of an array that can be allocated.
*/
static final long MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
static final long MAX_ARRAY_SIZE = Arrays.MAX_ARRAY_SIZE;

// IllegalArgumentException messages
static final String BAD_SIZE = "Stream size exceeds max array size";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;

/**
* A simple Unsynced ByteArrayOutputStream
Expand All @@ -33,7 +34,7 @@ public class UnsyncByteArrayOutputStream extends OutputStream {

// Maximum array size. Using same value as ArrayList in OpenJDK.
// Integer.MAX_VALUE doesn't work on some VMs, as some header values are reserved
private static final int VM_ARRAY_INDEX_MAX_VALUE = Integer.MAX_VALUE - 8;
private static final int VM_ARRAY_INDEX_MAX_VALUE = Arrays.MAX_ARRAY_SIZE;
private static final int INITIAL_SIZE = 8192;

private byte[] buf;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import jdk.internal.vm.annotation.ForceInline;
import sun.security.action.GetPropertyAction;

import java.io.FileDescriptor;
import java.lang.invoke.VarHandle;
import java.lang.ref.Cleaner;
import java.nio.ByteBuffer;
Expand Down Expand Up @@ -435,7 +434,7 @@ private int checkArraySize(String typeName, int elemSize) {
throw new UnsupportedOperationException(String.format("Segment size is not a multiple of %d. Size: %d", elemSize, length));
}
long arraySize = length / elemSize;
if (arraySize > (Integer.MAX_VALUE - 8)) { //conservative check
if (arraySize > (Arrays.MAX_ARRAY_SIZE)) { //conservative check
throw new UnsupportedOperationException(String.format("Segment is too large to wrap as %s. Size: %d", typeName, length));
}
return (int)arraySize;
Expand Down
7 changes: 3 additions & 4 deletions src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/JFC.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
public final class JFC {
private static final int BUFFER_SIZE = 8192;
private static final int MAXIMUM_FILE_SIZE = 1024 * 1024;
private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
private static volatile List<KnownConfiguration> knownConfigurations;

/**
Expand Down Expand Up @@ -188,12 +187,12 @@ private static byte[] read(InputStream source, int initialSize) throws IOExcepti
break;

// one more byte was read; need to allocate a larger buffer
if (capacity <= MAX_BUFFER_SIZE - capacity) {
if (capacity <= Arrays.MAX_ARRAY_SIZE - capacity) {
capacity = Math.max(capacity << 1, BUFFER_SIZE);
} else {
if (capacity == MAX_BUFFER_SIZE)
if (capacity == Arrays.MAX_ARRAY_SIZE)
throw new OutOfMemoryError("Required array size too large");
capacity = MAX_BUFFER_SIZE;
capacity = Arrays.MAX_ARRAY_SIZE;
}
buf = Arrays.copyOf(buf, capacity);
buf[nread++] = (byte)n;
Expand Down