< prev index next >

src/java.base/share/classes/jdk/internal/util/ArraysSupport.java

Print this page
rev 54801 : [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.  Also included is
+ * 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,51 @@
             }
         }
 
         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
+     */
+    public 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 X = 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 the minimum required size
+     * {@code X} is greater.
+     *
+     * @param oldCapacity       current size of the array (must be non negative)
+     * @param growAtLeastBy     minimum required growth of the array size (must
+                                be positive)
+     * @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 + Math.max(growAtLeastBy, preferredGrowBy);
+        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 >