--- a/jdk/src/share/classes/java/util/WeakHashMap.java Tue Jun 04 09:45:14 2013 +0200
+++ b/jdk/src/share/classes/java/util/WeakHashMap.java Tue Jun 04 10:04:28 2013 +0100
@@ -187,11 +187,37 @@
*/
int modCount;
+ private static class Holder {
+ static final boolean USE_HASHSEED;
+
+ static {
+ String hashSeedProp = java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction(
+ "jdk.map.useRandomSeed"));
+ boolean localBool = (null != hashSeedProp)
+ ? Boolean.parseBoolean(hashSeedProp) : false;
+ USE_HASHSEED = localBool;
+ }
+ }
+
/**
* A randomizing value associated with this instance that is applied to
* hash code of keys to make hash collisions harder to find.
+ *
+ * Non-final so it can be set lazily, but be sure not to set more than once.
*/
- transient final int hashSeed = sun.misc.Hashing.randomHashSeed(this);
+ transient int hashSeed;
+
+ /**
+ * Initialize the hashing mask value.
+ */
+ final void initHashSeed() {
+ if (sun.misc.VM.isBooted() && Holder.USE_HASHSEED) {
+ // Do not set hashSeed more than once!
+ // assert hashSeed == 0;
+ hashSeed = sun.misc.Hashing.randomHashSeed(this);
+ }
+ }
@SuppressWarnings("unchecked")
private Entry<K,V>[] newTable(int n) {
@@ -223,6 +249,7 @@
table = newTable(capacity);
this.loadFactor = loadFactor;
threshold = (int)(capacity * loadFactor);
+ initHashSeed();
}
/**
@@ -298,10 +325,7 @@
* in lower bits.
*/
final int hash(Object k) {
- if (k instanceof String) {
- return ((String) k).hash32();
- }
- int h = hashSeed ^ k.hashCode();
+ int h = hashSeed ^ k.hashCode();
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded