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) 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