--- old/src/share/classes/java/lang/String.java 2012-05-24 12:15:18.000000000 -0700 +++ new/src/share/classes/java/lang/String.java 2012-05-24 12:15:18.000000000 -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; @@ -3073,5 +3072,65 @@ * guaranteed to be from a pool of unique strings. */ 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), + System.identityHashCode(Thread.currentThread()), + (int) (nanos >>> 32), + (int) nanos, + (int) (now >>> 32), + (int) now, + (int) (System.nanoTime() >> 2) + }; + + int h = 0; + for(int each : SEED_MATERIAL) { + h ^= each; + } + + // Spread bits to regularize both segment and index locations, + // using variant of single-word Wang/Jenkins hash. + h += (h << 15) ^ 0xffffcd7d; + h ^= (h >>> 10); + h += (h << 3); + h ^= (h >>> 6); + h += (h << 2) + (h << 14); + + HASHING_SEED = h ^ (h >>> 16); + } + + /** + * Cached value of the alternative hashing algorithm result + */ + private transient int hash32 = 0; + + /** + * Calculates a 32-bit hash value for this string. + * + * @return a 32-bit hash value for this string. + */ + int hash32() { + int h = hash32; + if (0 == h) { + // harmless data race on hash32 here. + h = sun.misc.Hashing.murmur3_32(HASHING_SEED, value, offset, count); + + // ensure result is not zero to avoid recalcing + h = (0 != h) ? h : 1; + + hash32 = h; + } + + return h; + } }