< prev index next >
src/java.base/share/classes/java/lang/AbstractStringBuilder.java
Print this page
rev 13764 : [mq]: 8149330-Friendly-realloc-in-StringBuilder
@@ -143,29 +143,35 @@
expandCapacity(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;
+
+ /**
* This implements the expansion semantics of ensureCapacity with no
* size check or synchronization.
*/
private void expandCapacity(int minimumCapacity) {
int newCapacity = (value.length >> coder) * 2 + 2;
if (newCapacity - minimumCapacity < 0) {
newCapacity = minimumCapacity;
}
- if (newCapacity < 0) {
- if (minimumCapacity < 0) {// overflow
- throw new OutOfMemoryError();
- }
- newCapacity = Integer.MAX_VALUE;
- }
- if (coder != LATIN1 && newCapacity > StringUTF16.MAX_LENGTH) {
- if (minimumCapacity >= StringUTF16.MAX_LENGTH) {
+
+ final int SAFE_BOUND = (MAX_ARRAY_SIZE >> coder);
+ if (((SAFE_BOUND - newCapacity) | newCapacity) < 0) {
+ final int UNSAFE_BOUND = (Integer.MAX_VALUE >> coder);
+ if (UNSAFE_BOUND - minimumCapacity < 0) { // overflow
throw new OutOfMemoryError();
}
- newCapacity = StringUTF16.MAX_LENGTH;
+ newCapacity = (minimumCapacity > SAFE_BOUND)
+ ? minimumCapacity : SAFE_BOUND;
}
this.value = Arrays.copyOf(value, newCapacity << coder);
}
/**
< prev index next >