Remove caching for String.hashcode

String hashcode is no longer used in HashMap and it is only used if it is directly called and it doesn't have a predictable performance. I don't see much value in keeping it around any longer.

PiperOrigin-RevId: 339796010
Change-Id: I51c45621bea02c48a5b5df316d11a7113643c048
diff --git a/user/super/com/google/gwt/emul/java/lang/String.java b/user/super/com/google/gwt/emul/java/lang/String.java
index 45ddd0e..3aba0d3 100644
--- a/user/super/com/google/gwt/emul/java/lang/String.java
+++ b/user/super/com/google/gwt/emul/java/lang/String.java
@@ -29,8 +29,8 @@
 import java.util.Locale;
 import java.util.StringJoiner;
 import javaemul.internal.ArrayHelper;
+import javaemul.internal.Coercions;
 import javaemul.internal.EmulatedCharset;
-import javaemul.internal.HashCodes;
 import javaemul.internal.JsUtils;
 import javaemul.internal.NativeRegExp;
 import javaemul.internal.annotations.DoNotInline;
@@ -454,7 +454,12 @@
 
   @Override
   public int hashCode() {
-    return HashCodes.getStringHashCode(this);
+    int h = 0;
+    for (int i = 0; i < length(); i++) {
+      // Following is the common hash function '(31 * h + x)' as '(x << 5) - x' equal to '31 * x'.
+      h = Coercions.ensureInt((h << 5) - h + charAt(i));
+    }
+    return h;
   }
 
   public int indexOf(int codePoint) {
diff --git a/user/super/com/google/gwt/emul/javaemul/internal/HashCodes.java b/user/super/com/google/gwt/emul/javaemul/internal/HashCodes.java
index 0a50eac..fa7cb68 100644
--- a/user/super/com/google/gwt/emul/javaemul/internal/HashCodes.java
+++ b/user/super/com/google/gwt/emul/javaemul/internal/HashCodes.java
@@ -22,7 +22,7 @@
   public static int getIdentityHashCode(Object o) {
     switch (JsUtils.typeOf(o)) {
       case "string":
-        return getStringHashCode(JsUtils.uncheckedCast(o));
+        return JsUtils.<String>uncheckedCast(o).hashCode();
       case "number":
         return Double.hashCode(JsUtils.unsafeCastToDouble(o));
       case "boolean":
@@ -35,8 +35,4 @@
   public static int getObjectIdentityHashCode(Object o) {
     return ObjectHashing.getHashCode(o);
   }
-
-  public static int getStringHashCode(String s) {
-    return StringHashCache.getHashCode(s);
-  }
 }
diff --git a/user/super/com/google/gwt/emul/javaemul/internal/JsUtils.java b/user/super/com/google/gwt/emul/javaemul/internal/JsUtils.java
index fa2dca9..efd46f1 100644
--- a/user/super/com/google/gwt/emul/javaemul/internal/JsUtils.java
+++ b/user/super/com/google/gwt/emul/javaemul/internal/JsUtils.java
@@ -55,9 +55,5 @@
   public static native <T> T getProperty(Object map, String key) /*-{
     return map[key];
   }-*/;
-
-  public static native void setProperty(Object map, String key, Object value) /*-{
-    map[key] = value;
-  }-*/;
 }
 
diff --git a/user/super/com/google/gwt/emul/javaemul/internal/StringHashCache.java b/user/super/com/google/gwt/emul/javaemul/internal/StringHashCache.java
deleted file mode 100644
index c803422..0000000
--- a/user/super/com/google/gwt/emul/javaemul/internal/StringHashCache.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package javaemul.internal;
-
-import static javaemul.internal.Coercions.ensureInt;
-
-/**
- * Hashcode caching for strings.
- */
-class StringHashCache {
-  /**
-   * The "old" cache; it will be dumped when front is full.
-   */
-  private static Object back = new Object();
-  /**
-   * Tracks the number of entries in front.
-   */
-  private static int count = 0;
-  /**
-   * The "new" cache; it will become back when it becomes full.
-   */
-  private static Object front = new Object();
-  /**
-   * Pulled this number out of thin air.
-   */
-  private static final int MAX_CACHE = 256;
-
-  public static int getHashCode(String str) {
-    // Accesses must to be prefixed with ':' to prevent conflict with built-in
-    // JavaScript properties.
-    String key = ":" + str;
-
-    // Check the front store.
-    Double result = JsUtils.getProperty(front, key);
-    if (result != null) {
-      return result.intValue();
-    }
-    // Check the back store.
-    result = JsUtils.getProperty(back, key);
-    int hashCode = result == null ? compute(str) : result.intValue();
-    // Increment can trigger the swap/flush; call after checking back but
-    // before writing to front.
-    increment();
-    JsUtils.setProperty(front, key, (double) hashCode);
-
-    return hashCode;
-  }
-
-  private static int compute(String str) {
-    int hashCode = 0;
-    int n = str.length();
-    int nBatch = n - 4;
-    int i = 0;
-
-    // Process batches of 4 characters at a time and add them to the hash coercing to 32 bits
-    while (i < nBatch) {
-      hashCode = str.charAt(i + 3)
-          + 31 * (str.charAt(i + 2)
-          + 31 * (str.charAt(i + 1)
-          + 31 * (str.charAt(i)
-          + 31 * hashCode)));
-
-      hashCode = ensureInt(hashCode); // make sure we don't overflow
-      i += 4;
-    }
-
-    // Now process the leftovers
-    while (i < n) {
-      hashCode = hashCode * 31 + str.charAt(i++);
-    }
-    hashCode = ensureInt(hashCode); // make sure we don't overflow
-
-    return hashCode;
-  }
-
-  private static void increment() {
-    if (count == MAX_CACHE) {
-      back = front;
-      front = new Object();
-      count = 0;
-    }
-    ++count;
-  }
-}