Commits

Anonymous committed e2f2209

Fix the HashMap performance regression.

Go back to the original cheap (and inline) secondary hash.
LinkedHashMap is a subclass of HashMap, so that has to change too.

Bug: 8290590
Change-Id: I7959a8ce8b8fc96e7f1d2c8a2a13fe83ef4c0dd5

Comments (0)

Files changed (2)

luni/src/main/java/java/util/HashMap.java

             return e == null ? null : e.value;
         }
 
-        int hash = Collections.secondaryHash(key);
+        // Doug Lea's supplemental secondaryHash function (inlined).
+        // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
+        int hash = key.hashCode();
+        hash ^= (hash >>> 20) ^ (hash >>> 12);
+        hash ^= (hash >>> 7) ^ (hash >>> 4);
+
         HashMapEntry<K, V>[] tab = table;
         for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
                 e != null; e = e.next) {
             return entryForNullKey != null;
         }
 
-        int hash = Collections.secondaryHash(key);
+        // Doug Lea's supplemental secondaryHash function (inlined).
+        // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
+        int hash = key.hashCode();
+        hash ^= (hash >>> 20) ^ (hash >>> 12);
+        hash ^= (hash >>> 7) ^ (hash >>> 4);
+
         HashMapEntry<K, V>[] tab = table;
         for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
                 e != null; e = e.next) {
         return false;
     }
 
+    // Doug Lea's supplemental secondaryHash function (non-inlined).
+    // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
+    static int secondaryHash(Object key) {
+        int hash = key.hashCode();
+        hash ^= (hash >>> 20) ^ (hash >>> 12);
+        hash ^= (hash >>> 7) ^ (hash >>> 4);
+        return hash;
+    }
+
     /**
      * Returns whether this map contains the specified value.
      *
             return putValueForNullKey(value);
         }
 
-        int hash = Collections.secondaryHash(key);
+        int hash = secondaryHash(key);
         HashMapEntry<K, V>[] tab = table;
         int index = hash & (tab.length - 1);
         for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
             return;
         }
 
-        int hash = Collections.secondaryHash(key);
+        int hash = secondaryHash(key);
         HashMapEntry<K, V>[] tab = table;
         int index = hash & (tab.length - 1);
         HashMapEntry<K, V> first = tab[index];
         if (key == null) {
             return removeNullKey();
         }
-        int hash = Collections.secondaryHash(key);
+        int hash = secondaryHash(key);
         HashMapEntry<K, V>[] tab = table;
         int index = hash & (tab.length - 1);
         for (HashMapEntry<K, V> e = tab[index], prev = null;
             return e != null && Objects.equal(value, e.value);
         }
 
-        int hash = Collections.secondaryHash(key);
+        int hash = secondaryHash(key);
         HashMapEntry<K, V>[] tab = table;
         int index = hash & (tab.length - 1);
         for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
             return true;
         }
 
-        int hash = Collections.secondaryHash(key);
+        int hash = secondaryHash(key);
         HashMapEntry<K, V>[] tab = table;
         int index = hash & (tab.length - 1);
         for (HashMapEntry<K, V> e = tab[index], prev = null;

luni/src/main/java/java/util/LinkedHashMap.java

             return e.value;
         }
 
-        int hash = Collections.secondaryHash(key);
+        // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590).
+        int hash = secondaryHash(key);
         HashMapEntry<K, V>[] tab = table;
         for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
                 e != null; e = e.next) {