Mercurial > hg > openjdk > icedtea > jdk7 > jdk
changeset 5448:a73386183d31
7180240: Disable alternative string hashing by default
Summary: Disables by default the alternative hashing approach used by Hashtable, HashMap, WeakHashMap, ConcurrentHashMap for String keys introduced in 7122677
Reviewed-by: smarks
author | mduigou |
---|---|
date | Thu, 28 Jun 2012 11:41:26 -0700 |
parents | 83f8283e4791 |
children | aa0ad405f70b 9ca4ae899116 |
files | src/share/classes/java/util/HashMap.java src/share/classes/java/util/Hashtable.java src/share/classes/java/util/WeakHashMap.java src/share/classes/java/util/concurrent/ConcurrentHashMap.java |
diffstat | 4 files changed, 78 insertions(+), 68 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/java/util/HashMap.java Wed Jun 27 21:10:26 2012 +0100 +++ b/src/share/classes/java/util/HashMap.java Thu Jun 28 11:41:26 2012 -0700 @@ -176,17 +176,16 @@ transient int modCount; /** - * The default threshold of capacity above which alternate hashing is used. - * Alternative hashing reduces the incidence of collisions due to weak hash - * code calculation. + * The default threshold of map capacity above which alternative hashing is + * used for String keys. Alternative hashing reduces the incidence of + * collisions due to weak hash code calculation for String keys. * <p/> * This value may be overridden by defining the system property - * {@code java.util.althashing.threshold}. A property value of {@code 1} + * {@code jdk.map.althashing.threshold}. A property value of {@code 1} * forces alternative hashing to be used at all times whereas - * {@code 2147483648 } ({@code Integer.MAX_VALUE}) value ensures that - * alternative hashing is never used. + * {@code -1} value ensures that alternative hashing is never used. */ - static final int ALTERNATE_HASHING_THRESHOLD_DEFAULT = 512; + static final int ALTERNATIVE_HASHING_THRESHOLD_DEFAULT = Integer.MAX_VALUE; /** * holds values which can't be initialized until after VM is booted. @@ -195,20 +194,19 @@ // Unsafe mechanics /** - * + * Unsafe utilities */ static final sun.misc.Unsafe UNSAFE; /** - * Offset of "final" hashmask field we must set in - * readObject() method. + * Offset of "final" hashSeed field we must set in readObject() method. */ static final long HASHSEED_OFFSET; /** - * Table capacity above which to switch to use alternate hashing. + * Table capacity above which to switch to use alternative hashing. */ - static final int ALTERNATE_HASHING_THRESHOLD; + static final int ALTERNATIVE_HASHING_THRESHOLD; static { String altThreshold = java.security.AccessController.doPrivileged( @@ -219,20 +217,20 @@ try { threshold = (null != altThreshold) ? Integer.parseInt(altThreshold) - : ALTERNATE_HASHING_THRESHOLD_DEFAULT; + : ALTERNATIVE_HASHING_THRESHOLD_DEFAULT; // disable alternative hashing if -1 - if(threshold == -1) { + if (threshold == -1) { threshold = Integer.MAX_VALUE; } - if(threshold < 0) { + if (threshold < 0) { throw new IllegalArgumentException("value must be positive integer."); } } catch(IllegalArgumentException failed) { throw new Error("Illegal value for 'jdk.map.althashing.threshold'", failed); } - ALTERNATE_HASHING_THRESHOLD = threshold; + ALTERNATIVE_HASHING_THRESHOLD = threshold; try { UNSAFE = sun.misc.Unsafe.getUnsafe(); @@ -245,8 +243,8 @@ } /** - * If {@code true} then perform alternate hashing to reduce the incidence of - * collisions due to weak hash code calculation. + * If {@code true} then perform alternative hashing of String keys to reduce + * the incidence of collisions due to weak hash code calculation. */ transient boolean useAltHashing; @@ -284,7 +282,7 @@ threshold = (int)Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1); table = new Entry[capacity]; useAltHashing = sun.misc.VM.isBooted() && - (capacity >= Holder.ALTERNATE_HASHING_THRESHOLD); + (capacity >= Holder.ALTERNATIVE_HASHING_THRESHOLD); init(); } @@ -561,7 +559,7 @@ Entry[] newTable = new Entry[newCapacity]; boolean oldAltHashing = useAltHashing; useAltHashing |= sun.misc.VM.isBooted() && - (newCapacity >= Holder.ALTERNATE_HASHING_THRESHOLD); + (newCapacity >= Holder.ALTERNATIVE_HASHING_THRESHOLD); boolean rehash = oldAltHashing ^ useAltHashing; transfer(newTable, rehash); table = newTable; @@ -576,7 +574,7 @@ for (Entry<K,V> e : table) { while(null != e) { Entry<K,V> next = e.next; - if(rehash) { + if (rehash) { e.hash = null == e.key ? 0 : hash(e.key); } int i = indexFor(e.hash, newCapacity); @@ -1147,7 +1145,7 @@ table = new Entry[capacity]; threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1); useAltHashing = sun.misc.VM.isBooted() && - (capacity >= Holder.ALTERNATE_HASHING_THRESHOLD); + (capacity >= Holder.ALTERNATIVE_HASHING_THRESHOLD); init(); // Give subclass a chance to do its thing.
--- a/src/share/classes/java/util/Hashtable.java Wed Jun 27 21:10:26 2012 +0100 +++ b/src/share/classes/java/util/Hashtable.java Thu Jun 28 11:41:26 2012 -0700 @@ -164,17 +164,16 @@ private static final long serialVersionUID = 1421746759512286392L; /** - * The default threshold of capacity above which alternate hashing is used. - * Alternative hashing reduces the incidence of collisions due to weak hash - * code calculation. + * The default threshold of map capacity above which alternative hashing is + * used for String keys. Alternative hashing reduces the incidence of + * collisions due to weak hash code calculation for String keys. * <p/> * This value may be overridden by defining the system property - * {@code java.util.althashing.threshold}. A property value of {@code 1} + * {@code jdk.map.althashing.threshold}. A property value of {@code 1} * forces alternative hashing to be used at all times whereas - * {@code -1 } value ensures that - * alternative hashing is never used. + * {@code -1} value ensures that alternative hashing is never used. */ - static final int ALTERNATE_HASHING_THRESHOLD_DEFAULT = 512; + static final int ALTERNATIVE_HASHING_THRESHOLD_DEFAULT = 512; /** * holds values which can't be initialized until after VM is booted. @@ -182,9 +181,9 @@ private static class Holder { /** - * Table capacity above which to switch to use alternate hashing. + * Table capacity above which to switch to use alternative hashing. */ - static final int ALTERNATE_HASHING_THRESHOLD; + static final int ALTERNATIVE_HASHING_THRESHOLD; static { String altThreshold = java.security.AccessController.doPrivileged( @@ -195,32 +194,39 @@ try { threshold = (null != altThreshold) ? Integer.parseInt(altThreshold) - : ALTERNATE_HASHING_THRESHOLD_DEFAULT; + : ALTERNATIVE_HASHING_THRESHOLD_DEFAULT; // disable alternative hashing if -1 - if(threshold == -1) { + if (threshold == -1) { threshold = Integer.MAX_VALUE; } - if(threshold < 0) { + if (threshold < 0) { throw new IllegalArgumentException("value must be positive integer."); } } catch(IllegalArgumentException failed) { throw new Error("Illegal value for 'jdk.map.althashing.threshold'", failed); } - ALTERNATE_HASHING_THRESHOLD = threshold; + ALTERNATIVE_HASHING_THRESHOLD = threshold; } } /** - * If {@code true} then perform alternate hashing to reduce the incidence of - * collisions due to weak hash code calculation. + * If {@code true} then perform alternative hashing of String keys to reduce + * the incidence of collisions due to weak hash code calculation. */ transient boolean useAltHashing; // Unsafe mechanics + /** + * Unsafe utilities + */ private static final sun.misc.Unsafe UNSAFE; + + /** + * Offset of "final" hashSeed field we must set in readObject() method. + */ private static final long HASHSEED_OFFSET; static { @@ -279,7 +285,7 @@ table = new Entry[initialCapacity]; threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1); useAltHashing = sun.misc.VM.isBooted() && - (initialCapacity >= Holder.ALTERNATE_HASHING_THRESHOLD); + (initialCapacity >= Holder.ALTERNATIVE_HASHING_THRESHOLD); } /** @@ -493,7 +499,7 @@ threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1); boolean currentAltHashing = useAltHashing; useAltHashing = sun.misc.VM.isBooted() && - (newCapacity >= Holder.ALTERNATE_HASHING_THRESHOLD); + (newCapacity >= Holder.ALTERNATIVE_HASHING_THRESHOLD); boolean rehash = currentAltHashing ^ useAltHashing; table = newMap; @@ -503,7 +509,7 @@ Entry<K,V> e = old; old = old.next; - if(rehash) { + if (rehash) { e.hash = hash(e.key); } int index = (e.hash & 0x7FFFFFFF) % newCapacity; @@ -1015,7 +1021,7 @@ threshold = (int) Math.min(length * loadFactor, MAX_ARRAY_SIZE + 1); count = 0; useAltHashing = sun.misc.VM.isBooted() && - (length >= Holder.ALTERNATE_HASHING_THRESHOLD); + (length >= Holder.ALTERNATIVE_HASHING_THRESHOLD); // Read the number of elements and then all the key/value objects for (; elements > 0; elements--) {
--- a/src/share/classes/java/util/WeakHashMap.java Wed Jun 27 21:10:26 2012 +0100 +++ b/src/share/classes/java/util/WeakHashMap.java Thu Jun 28 11:41:26 2012 -0700 @@ -185,17 +185,16 @@ int modCount; /** - * The default threshold of capacity above which alternate hashing is - * used. Alternative hashing reduces the incidence of collisions due to - * weak hash code calculation. - * <p/> - * This value may be overridden by defining the system property - * {@code java.util.althashing.threshold} to an integer value. A property - * value of {@code 1} forces alternative hashing to be used at all times - * whereas {@code 2147483648 } ({@code Integer.MAX_VALUE}) value ensures - * that alternative hashing is never used. - */ - static final int ALTERNATE_HASHING_THRESHOLD_DEFAULT = 512; + * The default threshold of map capacity above which alternative hashing is + * used for String keys. Alternative hashing reduces the incidence of + * collisions due to weak hash code calculation for String keys. + * <p/> + * This value may be overridden by defining the system property + * {@code jdk.map.althashing.threshold}. A property value of {@code 1} + * forces alternative hashing to be used at all times whereas + * {@code -1} value ensures that alternative hashing is never used. + */ + static final int ALTERNATIVE_HASHING_THRESHOLD_DEFAULT = Integer.MAX_VALUE; /** * holds values which can't be initialized until after VM is booted. @@ -203,9 +202,9 @@ private static class Holder { /** - * Table capacity above which to switch to use alternate hashing. + * Table capacity above which to switch to use alternative hashing. */ - static final int ALTERNATE_HASHING_THRESHOLD; + static final int ALTERNATIVE_HASHING_THRESHOLD; static { String altThreshold = java.security.AccessController.doPrivileged( @@ -216,20 +215,20 @@ try { threshold = (null != altThreshold) ? Integer.parseInt(altThreshold) - : ALTERNATE_HASHING_THRESHOLD_DEFAULT; + : ALTERNATIVE_HASHING_THRESHOLD_DEFAULT; // disable alternative hashing if -1 - if(threshold == -1) { + if (threshold == -1) { threshold = Integer.MAX_VALUE; } - if(threshold < 0) { + if (threshold < 0) { throw new IllegalArgumentException("value must be positive integer."); } } catch(IllegalArgumentException failed) { throw new Error("Illegal value for 'jdk.map.althashing.threshold'", failed); } - ALTERNATE_HASHING_THRESHOLD = threshold; + ALTERNATIVE_HASHING_THRESHOLD = threshold; } } @@ -276,7 +275,7 @@ this.loadFactor = loadFactor; threshold = (int)(capacity * loadFactor); useAltHashing = sun.misc.VM.isBooted() && - (capacity >= Holder.ALTERNATE_HASHING_THRESHOLD); + (capacity >= Holder.ALTERNATIVE_HASHING_THRESHOLD); } /** @@ -560,7 +559,7 @@ Entry<K,V>[] newTable = newTable(newCapacity); boolean oldAltHashing = useAltHashing; useAltHashing |= sun.misc.VM.isBooted() && - (newCapacity >= Holder.ALTERNATE_HASHING_THRESHOLD); + (newCapacity >= Holder.ALTERNATIVE_HASHING_THRESHOLD); boolean rehash = oldAltHashing ^ useAltHashing; transfer(oldTable, newTable, rehash); table = newTable; @@ -592,7 +591,7 @@ e.value = null; // " " size--; } else { - if(rehash) { + if (rehash) { e.hash = hash(key); } int i = indexFor(e.hash, dest.length);
--- a/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Wed Jun 27 21:10:26 2012 +0100 +++ b/src/share/classes/java/util/concurrent/ConcurrentHashMap.java Thu Jun 28 11:41:26 2012 -0700 @@ -183,11 +183,18 @@ private static class Holder { /** - * Enable alternate hashing? + * Enable alternative hashing of String keys? + * + * <p>Unlike the other hash map implementations we do not implement a + * threshold for regulating whether alternative hashing is used for + * String keys. Alternative hashing is either enabled for all instances + * or disabled for all instances. */ - static final boolean ALTERNATE_HASHING; + static final boolean ALTERNATIVE_HASHING; static { + // Use the "threshold" system property even though our threshold + // behaviour is "ON" or "OFF". String altThreshold = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction( "jdk.map.althashing.threshold")); @@ -196,20 +203,20 @@ try { threshold = (null != altThreshold) ? Integer.parseInt(altThreshold) - : 1; + : Integer.MAX_VALUE; // disable alternative hashing if -1 - if(threshold == -1) { + if (threshold == -1) { threshold = Integer.MAX_VALUE; } - if(threshold < 0) { + if (threshold < 0) { throw new IllegalArgumentException("value must be positive integer."); } } catch(IllegalArgumentException failed) { throw new Error("Illegal value for 'jdk.map.althashing.threshold'", failed); } - ALTERNATE_HASHING = threshold <= MAXIMUM_CAPACITY; + ALTERNATIVE_HASHING = threshold <= MAXIMUM_CAPACITY; } } @@ -220,7 +227,7 @@ private transient final int hashSeed = randomHashSeed(this); private static int randomHashSeed(ConcurrentHashMap instance) { - if (sun.misc.VM.isBooted() && Holder.ALTERNATE_HASHING) { + if (sun.misc.VM.isBooted() && Holder.ALTERNATIVE_HASHING) { return sun.misc.Hashing.randomHashSeed(instance); }