jdk/src/share/classes/java/util/Hashtable.java
changeset 5466 f130bb07764b
parent 715 f16baef3a20e
child 5506 202f599c92aa
--- a/jdk/src/share/classes/java/util/Hashtable.java	Fri May 07 16:11:13 2010 +0100
+++ b/jdk/src/share/classes/java/util/Hashtable.java	Sun May 09 00:59:30 2010 -0700
@@ -365,6 +365,14 @@
     }
 
     /**
+     * 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 and internally reorganizes this
      * hashtable, in order to accommodate and access its entries more
      * efficiently.  This method is called automatically when the
@@ -375,7 +383,14 @@
         int oldCapacity = table.length;
         Entry[] oldMap = table;
 
-        int newCapacity = oldCapacity * 2 + 1;
+        // overflow-conscious code
+        int newCapacity = (oldCapacity << 1) + 1;
+        if (newCapacity - MAX_ARRAY_SIZE > 0) {
+            if (oldCapacity == MAX_ARRAY_SIZE)
+                // Keep running with MAX_ARRAY_SIZE buckets
+                return;
+            newCapacity = MAX_ARRAY_SIZE;
+        }
         Entry[] newMap = new Entry[newCapacity];
 
         modCount++;