< prev index next >
src/java.base/share/classes/jdk/internal/util/ArraysSupport.java
Print this page
rev 54772 : [mq]: 8223593-Refactor-code-for-reallocating-storage
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -26,11 +26,13 @@
import jdk.internal.HotSpotIntrinsicCandidate;
import jdk.internal.misc.Unsafe;
/**
- * Utility methods to find a mismatch between two primitive arrays.
+ * Utility methods to work with arrays.
+ * This includes a set of methods to find a mismatch between two primitive arrays
+ * and a method to calculate the new size of an array to be reallocated
*
* <p>Array equality and lexicographical comparison can be built on top of
* array mismatch functionality.
*
* <p>The mismatch method implementation, {@link #vectorizedMismatch}, leverages
@@ -569,6 +571,52 @@
}
}
return -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;
+
+ /**
+ * Calculates new size of an array to be reallocated.
+ *
+ * The result will be at least {@code oldCapacity + growAtLeastBy}.
+ * The result can be greater (normally, up to
+ * {@code oldCapacity + preferredGrowBy}).
+ * This function will not return values greater than
+ * {@link #MAX_ARRAY_SIZE} unless necessary.
+ *
+ * @param oldCapacity current size of the array
+ * @param growAtLeastBy minimum required growth of the array size
+ * @param preferredGrowBy preferred growth of the array size
+ * @return the new size of the array
+ * @throws OutOfMemoryError if increasing {@code oldCapacity) by
+ * {@code growAtLeastBy} overflows.
+ */
+ public static int newCapacity(int oldCapacity,
+ int growAtLeastBy,
+ int preferredGrowBy) {
+ assert oldCapacity >= 0;
+ assert growAtLeastBy > 0;
+
+ int newCapacity = oldCapacity + preferredGrowBy;
+ if (preferredGrowBy < growAtLeastBy) {
+ newCapacity = oldCapacity + growAtLeastBy;
+ }
+ return (newCapacity - MAX_ARRAY_SIZE > 0)
+ ? hugeCapacity(oldCapacity + growAtLeastBy) : newCapacity;
+ }
+
+ 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;
+ }
}
< prev index next >