diff -r 97e3f3f77254 -r c44b88bb9b5e jdk/src/share/classes/java/lang/String.java --- a/jdk/src/share/classes/java/lang/String.java Thu May 17 10:06:19 2012 -0700 +++ b/jdk/src/share/classes/java/lang/String.java Wed May 30 22:18:37 2012 -0700 @@ -25,7 +25,6 @@ package java.lang; -import java.io.ObjectStreamClass; import java.io.ObjectStreamField; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; @@ -3021,4 +3020,100 @@ */ public native String intern(); + /** + * Seed value used for each alternative hash calculated. + */ + private static final int HASHING_SEED; + + static { + long nanos = System.nanoTime(); + long now = System.currentTimeMillis(); + int SEED_MATERIAL[] = { + System.identityHashCode(String.class), + System.identityHashCode(System.class), + (int) (nanos >>> 32), + (int) nanos, + (int) (now >>> 32), + (int) now, + (int) (System.nanoTime() >>> 2) + }; + + // Use murmur3 to scramble the seeding material. + // Inline implementation to avoid loading classes + int h1 = 0; + + // body + for(int k1 : SEED_MATERIAL) { + k1 *= 0xcc9e2d51; + k1 = (k1 << 15) | (k1 >>> 17); + k1 *= 0x1b873593; + + h1 ^= k1; + h1 = (h1 << 13) | (h1 >>> 19); + h1 = h1 * 5 + 0xe6546b64; + } + + // tail (always empty, as body is always 32-bit chunks) + + // finalization + + h1 ^= SEED_MATERIAL.length * 4; + + // finalization mix force all bits of a hash block to avalanche + h1 ^= h1 >>> 16; + h1 *= 0x85ebca6b; + h1 ^= h1 >>> 13; + h1 *= 0xc2b2ae35; + h1 ^= h1 >>> 16; + + HASHING_SEED = h1; + } + + /** + * Cached value of the hashing algorithm result + */ + private transient int hash32 = 0; + + /** + * Return a 32-bit hash code value for this object. + *

+ * The general contract of {@code hash32} is: + *

+ *

+ * The hash value will never be zero. + * + * @return a hash code value for this object. + * @see java.lang.Object#equals(java.lang.Object) + */ + public int hash32() { + int h = hash32; + if (0 == h) { + // harmless data race on hash32 here. + h = sun.misc.Hashing.murmur3_32(HASHING_SEED, value, 0, value.length); + + // ensure result is not zero to avoid recalcing + h = (0 != h) ? h : 1; + + hash32 = h; + } + + return h; + } + }