mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8223593: Refactor code for reallocating storage
Reviewed-by: prappo, plevart, rriggs, smarks
This commit is contained in:
parent
54d0b2a8d6
commit
218204b1a3
11 changed files with 129 additions and 247 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1994, 2016, 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
|
||||
|
@ -26,6 +26,7 @@
|
|||
package java.io;
|
||||
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
|
||||
/**
|
||||
* A <code>BufferedInputStream</code> adds
|
||||
|
@ -53,14 +54,6 @@ class BufferedInputStream extends FilterInputStream {
|
|||
|
||||
private static int DEFAULT_BUFFER_SIZE = 8192;
|
||||
|
||||
/**
|
||||
* 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 int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
|
||||
|
||||
/**
|
||||
* As this class is used early during bootstrap, it's motivated to use
|
||||
* Unsafe.compareAndSetObject instead of AtomicReferenceFieldUpdater
|
||||
|
@ -220,7 +213,7 @@ class BufferedInputStream extends FilterInputStream {
|
|||
byte[] buffer = getBufIfOpen();
|
||||
if (markpos < 0)
|
||||
pos = 0; /* no mark: throw away the buffer */
|
||||
else if (pos >= buffer.length) /* no room left in buffer */
|
||||
else if (pos >= buffer.length) { /* no room left in buffer */
|
||||
if (markpos > 0) { /* can throw away early part of the buffer */
|
||||
int sz = pos - markpos;
|
||||
System.arraycopy(buffer, markpos, buffer, 0, sz);
|
||||
|
@ -229,11 +222,10 @@ class BufferedInputStream extends FilterInputStream {
|
|||
} else if (buffer.length >= marklimit) {
|
||||
markpos = -1; /* buffer got too big, invalidate mark */
|
||||
pos = 0; /* drop buffer contents */
|
||||
} else if (buffer.length >= MAX_BUFFER_SIZE) {
|
||||
throw new OutOfMemoryError("Required array size too large");
|
||||
} else { /* grow buffer */
|
||||
int nsz = (pos <= MAX_BUFFER_SIZE - pos) ?
|
||||
pos * 2 : MAX_BUFFER_SIZE;
|
||||
int nsz = ArraysSupport.newLength(pos,
|
||||
1, /* minimum growth */
|
||||
pos /* preferred growth */);
|
||||
if (nsz > marklimit)
|
||||
nsz = marklimit;
|
||||
byte[] nbuf = new byte[nsz];
|
||||
|
@ -248,6 +240,7 @@ class BufferedInputStream extends FilterInputStream {
|
|||
}
|
||||
buffer = nbuf;
|
||||
}
|
||||
}
|
||||
count = pos;
|
||||
int n = getInIfOpen().read(buffer, pos, buffer.length - pos);
|
||||
if (n > 0)
|
||||
|
|
|
@ -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 */));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,6 +35,7 @@ import java.util.stream.IntStream;
|
|||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
|
||||
import static java.lang.String.LATIN1;
|
||||
import static java.lang.String.UTF16;
|
||||
|
@ -42,14 +43,6 @@ import static java.lang.String.checkOffset;
|
|||
|
||||
final class StringLatin1 {
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
public static char charAt(byte[] value, int index) {
|
||||
if (index < 0 || index >= value.length) {
|
||||
throw new StringIndexOutOfBoundsException(index);
|
||||
|
@ -353,15 +346,7 @@ final class StringLatin1 {
|
|||
i += targLen;
|
||||
while ((j = indexOf(value, valLen, targ, targLen, i)) > 0) {
|
||||
if (++p == pos.length) {
|
||||
int cap = p + (p >> 1);
|
||||
// overflow-conscious code
|
||||
if (cap - MAX_ARRAY_SIZE > 0) {
|
||||
if (p == MAX_ARRAY_SIZE) {
|
||||
throw new OutOfMemoryError();
|
||||
}
|
||||
cap = MAX_ARRAY_SIZE;
|
||||
}
|
||||
pos = Arrays.copyOf(pos, cap);
|
||||
pos = Arrays.copyOf(pos, ArraysSupport.newLength(p, 1, p >> 1));
|
||||
}
|
||||
pos[p] = j;
|
||||
i = j + targLen;
|
||||
|
|
|
@ -33,6 +33,7 @@ import java.util.function.IntConsumer;
|
|||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
import jdk.internal.vm.annotation.ForceInline;
|
||||
import jdk.internal.vm.annotation.DontInline;
|
||||
|
||||
|
@ -649,15 +650,7 @@ final class StringUTF16 {
|
|||
: indexOf(value, valLen, targ, targLen, i))) > 0)
|
||||
{
|
||||
if (++p == pos.length) {
|
||||
int cap = p + (p >> 1);
|
||||
// overflow-conscious code
|
||||
if (cap - MAX_ARRAY_SIZE > 0) {
|
||||
if (p == MAX_ARRAY_SIZE) {
|
||||
throw new OutOfMemoryError();
|
||||
}
|
||||
cap = MAX_ARRAY_SIZE;
|
||||
}
|
||||
pos = Arrays.copyOf(pos, cap);
|
||||
pos = Arrays.copyOf(pos, ArraysSupport.newLength(p, 1, p >> 1));
|
||||
}
|
||||
pos[p] = j;
|
||||
i = j + targLen;
|
||||
|
@ -1554,15 +1547,6 @@ final class StringUTF16 {
|
|||
|
||||
static final int MAX_LENGTH = Integer.MAX_VALUE >> 1;
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
// Used by trusted callers. Assumes all necessary bounds checks have
|
||||
// been done by the caller.
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ import java.util.function.BiPredicate;
|
|||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
import sun.nio.ch.FileChannelImpl;
|
||||
import sun.nio.fs.AbstractFileSystemProvider;
|
||||
|
||||
|
@ -3196,14 +3197,6 @@ public final class Files {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
private static final jdk.internal.access.JavaLangAccess JLA =
|
||||
jdk.internal.access.SharedSecrets.getJavaLangAccess();
|
||||
|
||||
|
@ -3240,13 +3233,10 @@ public final class Files {
|
|||
break;
|
||||
|
||||
// one more byte was read; need to allocate a larger buffer
|
||||
if (capacity <= MAX_BUFFER_SIZE - capacity) {
|
||||
capacity = Math.max(capacity << 1, BUFFER_SIZE);
|
||||
} else {
|
||||
if (capacity == MAX_BUFFER_SIZE)
|
||||
throw new OutOfMemoryError("Required array size too large");
|
||||
capacity = MAX_BUFFER_SIZE;
|
||||
}
|
||||
capacity = Math.max(ArraysSupport.newLength(capacity,
|
||||
1, /* minimum growth */
|
||||
capacity /* preferred growth */),
|
||||
BUFFER_SIZE);
|
||||
buf = Arrays.copyOf(buf, capacity);
|
||||
buf[nread++] = (byte)n;
|
||||
}
|
||||
|
@ -3283,7 +3273,7 @@ public final class Files {
|
|||
if (sbc instanceof FileChannelImpl)
|
||||
((FileChannelImpl) sbc).setUninterruptible();
|
||||
long size = sbc.size();
|
||||
if (size > (long) MAX_BUFFER_SIZE)
|
||||
if (size > (long) Integer.MAX_VALUE)
|
||||
throw new OutOfMemoryError("Required array size too large");
|
||||
return read(in, (int)size);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
|
@ -25,6 +25,8 @@
|
|||
|
||||
package java.util;
|
||||
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
|
||||
/**
|
||||
* This class provides a skeletal implementation of the {@code Collection}
|
||||
* interface, to minimize the effort required to implement this interface. <p>
|
||||
|
@ -203,14 +205,6 @@ public abstract class AbstractCollection<E> implements Collection<E> {
|
|||
return it.hasNext() ? finishToArray(r, it) : r;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Reallocates the array being used within toArray when the iterator
|
||||
* returned more elements than expected, and finishes filling it from
|
||||
|
@ -223,29 +217,19 @@ public abstract class AbstractCollection<E> implements Collection<E> {
|
|||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
|
||||
int i = r.length;
|
||||
int len = r.length;
|
||||
int i = len;
|
||||
while (it.hasNext()) {
|
||||
int cap = r.length;
|
||||
if (i == cap) {
|
||||
int newCap = cap + (cap >> 1) + 1;
|
||||
// overflow-conscious code
|
||||
if (newCap - MAX_ARRAY_SIZE > 0)
|
||||
newCap = hugeCapacity(cap + 1);
|
||||
r = Arrays.copyOf(r, newCap);
|
||||
if (i == len) {
|
||||
len = ArraysSupport.newLength(len,
|
||||
1, /* minimum growth */
|
||||
(len >> 1) + 1 /* preferred growth */);
|
||||
r = Arrays.copyOf(r, len);
|
||||
}
|
||||
r[i++] = (T)it.next();
|
||||
}
|
||||
// trim if overallocated
|
||||
return (i == r.length) ? r : Arrays.copyOf(r, i);
|
||||
}
|
||||
|
||||
private static int hugeCapacity(int minCapacity) {
|
||||
if (minCapacity < 0) // overflow
|
||||
throw new OutOfMemoryError
|
||||
("Required array size too large");
|
||||
return (minCapacity > MAX_ARRAY_SIZE) ?
|
||||
Integer.MAX_VALUE :
|
||||
MAX_ARRAY_SIZE;
|
||||
return (i == len) ? r : Arrays.copyOf(r, i);
|
||||
}
|
||||
|
||||
// Modification Operations
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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,7 @@ import java.util.function.Consumer;
|
|||
import java.util.function.Predicate;
|
||||
import java.util.function.UnaryOperator;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
|
||||
/**
|
||||
* Resizable-array implementation of the {@code List} interface. Implements
|
||||
|
@ -218,14 +219,6 @@ public class ArrayList<E> extends AbstractList<E>
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Increases the capacity to ensure that it can hold at least the
|
||||
* number of elements specified by the minimum capacity argument.
|
||||
|
@ -234,47 +227,21 @@ public class ArrayList<E> extends AbstractList<E>
|
|||
* @throws OutOfMemoryError if minCapacity is less than zero
|
||||
*/
|
||||
private Object[] grow(int minCapacity) {
|
||||
return elementData = Arrays.copyOf(elementData,
|
||||
newCapacity(minCapacity));
|
||||
int oldCapacity = elementData.length;
|
||||
if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
|
||||
int newCapacity = ArraysSupport.newLength(oldCapacity,
|
||||
minCapacity - oldCapacity, /* minimum growth */
|
||||
oldCapacity >> 1 /* preferred growth */);
|
||||
return elementData = Arrays.copyOf(elementData, newCapacity);
|
||||
} else {
|
||||
return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
|
||||
}
|
||||
}
|
||||
|
||||
private Object[] grow() {
|
||||
return grow(size + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a capacity at least as large as the given minimum capacity.
|
||||
* Returns the current capacity increased by 50% if that suffices.
|
||||
* Will not return a capacity greater than MAX_ARRAY_SIZE unless
|
||||
* the given minimum capacity is greater than MAX_ARRAY_SIZE.
|
||||
*
|
||||
* @param minCapacity the desired minimum capacity
|
||||
* @throws OutOfMemoryError if minCapacity is less than zero
|
||||
*/
|
||||
private int newCapacity(int minCapacity) {
|
||||
// overflow-conscious code
|
||||
int oldCapacity = elementData.length;
|
||||
int newCapacity = oldCapacity + (oldCapacity >> 1);
|
||||
if (newCapacity - minCapacity <= 0) {
|
||||
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
|
||||
return Math.max(DEFAULT_CAPACITY, minCapacity);
|
||||
if (minCapacity < 0) // overflow
|
||||
throw new OutOfMemoryError();
|
||||
return minCapacity;
|
||||
}
|
||||
return (newCapacity - MAX_ARRAY_SIZE <= 0)
|
||||
? newCapacity
|
||||
: hugeCapacity(minCapacity);
|
||||
}
|
||||
|
||||
private static int hugeCapacity(int minCapacity) {
|
||||
if (minCapacity < 0) // overflow
|
||||
throw new OutOfMemoryError();
|
||||
return (minCapacity > MAX_ARRAY_SIZE)
|
||||
? Integer.MAX_VALUE
|
||||
: MAX_ARRAY_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of elements in this list.
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 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
|
||||
|
@ -28,6 +28,7 @@ package java.util;
|
|||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
|
||||
/**
|
||||
* An unbounded priority {@linkplain Queue queue} based on a priority heap.
|
||||
|
@ -281,14 +282,6 @@ public class PriorityQueue<E> extends AbstractQueue<E>
|
|||
heapify();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 the array.
|
||||
*
|
||||
|
@ -297,23 +290,13 @@ public class PriorityQueue<E> extends AbstractQueue<E>
|
|||
private void grow(int minCapacity) {
|
||||
int oldCapacity = queue.length;
|
||||
// Double size if small; else grow by 50%
|
||||
int newCapacity = oldCapacity + ((oldCapacity < 64) ?
|
||||
(oldCapacity + 2) :
|
||||
(oldCapacity >> 1));
|
||||
// overflow-conscious code
|
||||
if (newCapacity - MAX_ARRAY_SIZE > 0)
|
||||
newCapacity = hugeCapacity(minCapacity);
|
||||
int newCapacity = ArraysSupport.newLength(oldCapacity,
|
||||
minCapacity - oldCapacity, /* minimum growth */
|
||||
oldCapacity < 64 ? oldCapacity + 2 : oldCapacity >> 1
|
||||
/* preferred growth */);
|
||||
queue = Arrays.copyOf(queue, 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified element into this priority queue.
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
@ -32,6 +32,8 @@ import java.util.function.Consumer;
|
|||
import java.util.function.Predicate;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
|
||||
/**
|
||||
* The {@code Vector} class implements a growable array of
|
||||
* objects. Like an array, it contains components that can be
|
||||
|
@ -241,14 +243,6 @@ public class Vector<E>
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Increases the capacity to ensure that it can hold at least the
|
||||
* number of elements specified by the minimum capacity argument.
|
||||
|
@ -257,45 +251,18 @@ public class Vector<E>
|
|||
* @throws OutOfMemoryError if minCapacity is less than zero
|
||||
*/
|
||||
private Object[] grow(int minCapacity) {
|
||||
return elementData = Arrays.copyOf(elementData,
|
||||
newCapacity(minCapacity));
|
||||
int oldCapacity = elementData.length;
|
||||
int newCapacity = ArraysSupport.newLength(oldCapacity,
|
||||
minCapacity - oldCapacity, /* minimum growth */
|
||||
capacityIncrement > 0 ? capacityIncrement : oldCapacity
|
||||
/* preferred growth */);
|
||||
return elementData = Arrays.copyOf(elementData, newCapacity);
|
||||
}
|
||||
|
||||
private Object[] grow() {
|
||||
return grow(elementCount + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a capacity at least as large as the given minimum capacity.
|
||||
* Will not return a capacity greater than MAX_ARRAY_SIZE unless
|
||||
* the given minimum capacity is greater than MAX_ARRAY_SIZE.
|
||||
*
|
||||
* @param minCapacity the desired minimum capacity
|
||||
* @throws OutOfMemoryError if minCapacity is less than zero
|
||||
*/
|
||||
private int newCapacity(int minCapacity) {
|
||||
// overflow-conscious code
|
||||
int oldCapacity = elementData.length;
|
||||
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
|
||||
capacityIncrement : oldCapacity);
|
||||
if (newCapacity - minCapacity <= 0) {
|
||||
if (minCapacity < 0) // overflow
|
||||
throw new OutOfMemoryError();
|
||||
return minCapacity;
|
||||
}
|
||||
return (newCapacity - MAX_ARRAY_SIZE <= 0)
|
||||
? newCapacity
|
||||
: hugeCapacity(minCapacity);
|
||||
}
|
||||
|
||||
private static int hugeCapacity(int minCapacity) {
|
||||
if (minCapacity < 0) // overflow
|
||||
throw new OutOfMemoryError();
|
||||
return (minCapacity > MAX_ARRAY_SIZE) ?
|
||||
Integer.MAX_VALUE :
|
||||
MAX_ARRAY_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the size of this vector. If the new size is greater than the
|
||||
* current size, new {@code null} items are added to the end of
|
||||
|
|
|
@ -43,6 +43,7 @@ import java.util.function.Predicate;
|
|||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
|
||||
/**
|
||||
* A compiled representation of a regular expression.
|
||||
|
@ -2315,13 +2316,15 @@ loop: for(int x=0, offset=0; x<nCodePoints; x++, offset+=len) {
|
|||
}
|
||||
}
|
||||
|
||||
private void append(int ch, int len) {
|
||||
if (len >= buffer.length) {
|
||||
int[] tmp = new int[len+len];
|
||||
System.arraycopy(buffer, 0, tmp, 0, len);
|
||||
buffer = tmp;
|
||||
private void append(int ch, int index) {
|
||||
int len = buffer.length;
|
||||
if (index - len >= 0) {
|
||||
len = ArraysSupport.newLength(len,
|
||||
1 + index - len, /* minimum growth */
|
||||
len /* preferred growth */);
|
||||
buffer = Arrays.copyOf(buffer, len);
|
||||
}
|
||||
buffer[len] = ch;
|
||||
buffer[index] = ch;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue