8221723: Avoid storing zero to String.hash
authorredestad
Tue, 02 Apr 2019 11:24:40 +0200
changeset 54378 7c576e4d0afa
parent 54377 35794e8db61b
child 54379 40a7e2fc9beb
8221723: Avoid storing zero to String.hash Reviewed-by: shade, prappo, jiangli
src/java.base/share/classes/java/lang/String.java
test/micro/org/openjdk/bench/java/lang/StringHashCode.java
--- a/src/java.base/share/classes/java/lang/String.java	Tue Apr 02 10:04:35 2019 +0200
+++ b/src/java.base/share/classes/java/lang/String.java	Tue Apr 02 11:24:40 2019 +0200
@@ -1510,8 +1510,14 @@
     public int hashCode() {
         int h = hash;
         if (h == 0 && value.length > 0) {
-            hash = h = isLatin1() ? StringLatin1.hashCode(value)
-                                  : StringUTF16.hashCode(value);
+            h = isLatin1() ? StringLatin1.hashCode(value)
+                           : StringUTF16.hashCode(value);
+            // Avoid issuing a store if the calculated value is also zero:
+            // in addition to a minor performance benefit, this allows storing
+            // Strings with zero hash code in read-only memory.
+            if (h != 0) {
+                hash = h;
+            }
         }
         return h;
     }
--- a/test/micro/org/openjdk/bench/java/lang/StringHashCode.java	Tue Apr 02 10:04:35 2019 +0200
+++ b/test/micro/org/openjdk/bench/java/lang/StringHashCode.java	Tue Apr 02 11:24:40 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,11 +42,13 @@
 
     private String hashcode;
     private String hashcode0;
+    private String empty;
 
     @Setup
     public void setup() {
         hashcode = "abcdefghijkl";
         hashcode0 = new String(new char[]{72, 90, 100, 89, 105, 2, 72, 90, 100, 89, 105, 2});
+        empty = new String();
     }
 
     /**
@@ -66,4 +68,13 @@
     public int notCached() {
         return hashcode0.hashCode();
     }
+
+    /**
+     * Benchmark testing String.hashCode() with the empty string. Since the
+     * empty String has hashCode = 0, this value is always recalculated.
+     */
+    @Benchmark
+    public int empty() {
+        return empty.hashCode();
+    }
 }