changeset 5887:3a09ec20ba0d

8240124: Better VM Interning Reviewed-by: bae, yan
author vkempik
date Wed, 23 Sep 2020 17:23:54 +0300
parents be18a085ddb0
children b878345a2866
files src/share/vm/classfile/altHashing.cpp src/share/vm/classfile/altHashing.hpp src/share/vm/classfile/symbolTable.cpp src/share/vm/utilities/hashtable.cpp
diffstat 4 files changed, 244 insertions(+), 216 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/classfile/altHashing.cpp	Tue Sep 22 13:09:39 2020 +0300
+++ b/src/share/vm/classfile/altHashing.cpp	Wed Sep 23 17:23:54 2020 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020, 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
@@ -22,12 +22,29 @@
  *
  */
 
+/*
+ * halfsiphash code adapted from reference implementation
+ * (https://github.com/veorq/SipHash/blob/master/halfsiphash.c)
+ * which is distributed with the following copyright:
+ *
+ * SipHash reference C implementation
+ *
+ * Copyright (c) 2016 Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * You should have received a copy of the CC0 Public Domain Dedication along
+ * with this software. If not, see
+ * <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
 #include "precompiled.hpp"
 #include "classfile/altHashing.hpp"
-#include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "oops/markOop.hpp"
-#include "runtime/thread.hpp"
+#include "runtime/os.hpp"
 
 // Get the hash code of the classes mirror if it exists, otherwise just
 // return a random number, which is one of the possible hash code used for
@@ -39,266 +56,284 @@
 }
 
 // Seed value used for each alternative hash calculated.
-jint AltHashing::compute_seed() {
-  jlong nanos = os::javaTimeNanos();
-  jlong now = os::javaTimeMillis();
-  jint SEED_MATERIAL[8] = {
-            (jint) object_hash(SystemDictionary::String_klass()),
-            (jint) object_hash(SystemDictionary::System_klass()),
-            (jint) os::random(),  // current thread isn't a java thread
-            (jint) (((julong)nanos) >> 32),
-            (jint) nanos,
-            (jint) (((julong)now) >> 32),
-            (jint) now,
-            (jint) (os::javaTimeNanos() >> 2)
+uint64_t AltHashing::compute_seed() {
+  uint64_t nanos = os::javaTimeNanos();
+  uint64_t now = os::javaTimeMillis();
+  uint32_t SEED_MATERIAL[8] = {
+            (uint32_t) object_hash(SystemDictionary::String_klass()),
+            (uint32_t) object_hash(SystemDictionary::System_klass()),
+            (uint32_t) os::random(),  // current thread isn't a java thread
+            (uint32_t) (((uint64_t)nanos) >> 32),
+            (uint32_t) nanos,
+            (uint32_t) (((uint64_t)now) >> 32),
+            (uint32_t) now,
+            (uint32_t) (os::javaTimeNanos() >> 2)
   };
 
-  return murmur3_32(SEED_MATERIAL, 8);
+  return halfsiphash_64(SEED_MATERIAL, 8);
+}
+
+// utility function copied from java/lang/Integer
+static uint32_t Integer_rotateLeft(uint32_t i, int distance) {
+  return (i << distance) | (i >> (32 - distance));
 }
 
+static void halfsiphash_rounds(uint32_t v[4], int rounds) {
+  while (rounds-- > 0) {
+    v[0] += v[1];
+    v[1] = Integer_rotateLeft(v[1], 5);
+    v[1] ^= v[0];
+    v[0] = Integer_rotateLeft(v[0], 16);
+    v[2] += v[3];
+    v[3] = Integer_rotateLeft(v[3], 8);
+    v[3] ^= v[2];
+    v[0] += v[3];
+    v[3] = Integer_rotateLeft(v[3], 7);
+    v[3] ^= v[0];
+    v[2] += v[1];
+    v[1] = Integer_rotateLeft(v[1], 13);
+    v[1] ^= v[2];
+    v[2] = Integer_rotateLeft(v[2], 16);
+  }
+ }
 
-// Murmur3 hashing for Symbol
-jint AltHashing::murmur3_32(jint seed, const jbyte* data, int len) {
-  jint h1 = seed;
+static void halfsiphash_adddata(uint32_t v[4], uint32_t newdata, int rounds) {
+  v[3] ^= newdata;
+  halfsiphash_rounds(v, rounds);
+  v[0] ^= newdata;
+}
+
+static void halfsiphash_init32(uint32_t v[4], uint64_t seed) {
+  v[0] = seed & 0xffffffff;
+  v[1] = seed >> 32;
+  v[2] = 0x6c796765 ^ v[0];
+  v[3] = 0x74656462 ^ v[1];
+}
+
+static void halfsiphash_init64(uint32_t v[4], uint64_t seed) {
+  halfsiphash_init32(v, seed);
+  v[1] ^= 0xee;
+}
+
+static uint64_t halfsiphash_finish64(uint32_t v[4], int rounds) {
+  uint64_t rv;
+  v[2] ^= 0xee;
+  halfsiphash_rounds(v, rounds);
+  rv = v[1] ^ v[3];
+  v[1] ^= 0xdd;
+  halfsiphash_rounds(v, rounds);
+  rv |= (uint64_t)(v[1] ^ v[3]) << 32;
+  return rv;
+}
+
+// HalfSipHash-2-4 (64-bit output) for Symbols
+uint64_t AltHashing::halfsiphash_64(uint64_t seed, const int8_t* data, int len) {
+  uint32_t v[4];
+  uint32_t newdata;
+  int off = 0;
   int count = len;
-  int offset = 0;
 
+  halfsiphash_init64(v, seed);
   // body
   while (count >= 4) {
-    jint k1 = (data[offset] & 0x0FF)
-        | (data[offset + 1] & 0x0FF) << 8
-        | (data[offset + 2] & 0x0FF) << 16
-        | data[offset + 3] << 24;
+    // Avoid sign extension with 0x0ff
+    newdata = (data[off] & 0x0FF)
+        | (data[off + 1] & 0x0FF) << 8
+        | (data[off + 2] & 0x0FF) << 16
+        | data[off + 3] << 24;
 
     count -= 4;
-    offset += 4;
+    off += 4;
 
-    k1 *= 0xcc9e2d51;
-    k1 = Integer_rotateLeft(k1, 15);
-    k1 *= 0x1b873593;
-
-    h1 ^= k1;
-    h1 = Integer_rotateLeft(h1, 13);
-    h1 = h1 * 5 + 0xe6546b64;
+    halfsiphash_adddata(v, newdata, 2);
   }
 
   // tail
+  newdata = ((uint32_t)len) << 24; // (Byte.SIZE / Byte.SIZE);
 
   if (count > 0) {
-    jint k1 = 0;
-
     switch (count) {
       case 3:
-        k1 ^= (data[offset + 2] & 0xff) << 16;
+        newdata |= (data[off + 2] & 0x0ff) << 16;
       // fall through
       case 2:
-        k1 ^= (data[offset + 1] & 0xff) << 8;
+        newdata |= (data[off + 1] & 0x0ff) << 8;
       // fall through
       case 1:
-        k1 ^= (data[offset] & 0xff);
+        newdata |= (data[off] & 0x0ff);
       // fall through
-      default:
-        k1 *= 0xcc9e2d51;
-        k1 = Integer_rotateLeft(k1, 15);
-        k1 *= 0x1b873593;
-        h1 ^= k1;
     }
   }
 
-  // finalization
-  h1 ^= len;
+  halfsiphash_adddata(v, newdata, 2);
 
-  // finalization mix force all bits of a hash block to avalanche
-  h1 ^= ((unsigned int)h1) >> 16;
-  h1 *= 0x85ebca6b;
-  h1 ^= ((unsigned int)h1) >> 13;
-  h1 *= 0xc2b2ae35;
-  h1 ^= ((unsigned int)h1) >> 16;
-
-  return h1;
+  // finalization
+  return halfsiphash_finish64(v, 4);
 }
 
-// Murmur3 hashing for Strings
-jint AltHashing::murmur3_32(jint seed, const jchar* data, int len) {
-  jint h1 = seed;
-
+// HalfSipHash-2-4 (64-bit output) for Strings
+uint64_t AltHashing::halfsiphash_64(uint64_t seed, const uint16_t* data, int len) {
+  uint32_t v[4];
+  uint32_t newdata;
   int off = 0;
   int count = len;
 
+  halfsiphash_init64(v, seed);
+
   // body
   while (count >= 2) {
-    jchar d1 = data[off++] & 0xFFFF;
-    jchar d2 = data[off++];
-    jint k1 = (d1 | d2 << 16);
+    uint16_t d1 = data[off++] & 0x0FFFF;
+    uint16_t d2 = data[off++];
+    newdata = (d1 | d2 << 16);
 
     count -= 2;
 
-    k1 *= 0xcc9e2d51;
-    k1 = Integer_rotateLeft(k1, 15);
-    k1 *= 0x1b873593;
-
-    h1 ^= k1;
-    h1 = Integer_rotateLeft(h1, 13);
-    h1 = h1 * 5 + 0xe6546b64;
+    halfsiphash_adddata(v, newdata, 2);
   }
 
   // tail
-
+  newdata = ((uint32_t)len * 2) << 24; // (Character.SIZE / Byte.SIZE);
   if (count > 0) {
-    int k1 = data[off];
-
-    k1 *= 0xcc9e2d51;
-    k1 = Integer_rotateLeft(k1, 15);
-    k1 *= 0x1b873593;
-    h1 ^= k1;
+    newdata |= (uint32_t)data[off];
   }
+  halfsiphash_adddata(v, newdata, 2);
 
   // finalization
-  h1 ^= len * 2; // (Character.SIZE / Byte.SIZE);
-
-  // finalization mix force all bits of a hash block to avalanche
-  h1 ^= ((unsigned int)h1) >> 16;
-  h1 *= 0x85ebca6b;
-  h1 ^= ((unsigned int)h1) >> 13;
-  h1 *= 0xc2b2ae35;
-  h1 ^= ((unsigned int)h1) >> 16;
-
-  return h1;
+  return halfsiphash_finish64(v, 4);
 }
 
-// Hash used for the seed.
-jint AltHashing::murmur3_32(jint seed, const int* data, int len) {
-  jint h1 = seed;
+// HalfSipHash-2-4 (64-bit output) for integers (used to create seed)
+uint64_t AltHashing::halfsiphash_64(uint64_t seed, const uint32_t* data, int len) {
+  uint32_t v[4];
 
   int off = 0;
   int end = len;
 
+  halfsiphash_init64(v, seed);
+
   // body
   while (off < end) {
-    jint k1 = data[off++];
-
-    k1 *= 0xcc9e2d51;
-    k1 = Integer_rotateLeft(k1, 15);
-    k1 *= 0x1b873593;
-
-    h1 ^= k1;
-    h1 = Integer_rotateLeft(h1, 13);
-    h1 = h1 * 5 + 0xe6546b64;
+    halfsiphash_adddata(v, (uint32_t)data[off++], 2);
   }
 
   // tail (always empty, as body is always 32-bit chunks)
 
   // finalization
-
-  h1 ^= len * 4; // (Integer.SIZE / Byte.SIZE);
-
-  // finalization mix force all bits of a hash block to avalanche
-  h1 ^= ((juint)h1) >> 16;
-  h1 *= 0x85ebca6b;
-  h1 ^= ((juint)h1) >> 13;
-  h1 *= 0xc2b2ae35;
-  h1 ^= ((juint)h1) >> 16;
-
-  return h1;
+  halfsiphash_adddata(v, ((uint32_t)len * 4) << 24, 2); // (Integer.SIZE / Byte.SIZE);
+  return halfsiphash_finish64(v, 4);
 }
 
-jint AltHashing::murmur3_32(const int* data, int len) {
-  return murmur3_32(0, data, len);
+// HalfSipHash-2-4 (64-bit output) for integers (used to create seed)
+uint64_t AltHashing::halfsiphash_64(const uint32_t* data, int len) {
+  return halfsiphash_64((uint64_t)0, data, len);
 }
 
 #ifndef PRODUCT
-// Overloaded versions for internal test.
-jint AltHashing::murmur3_32(const jbyte* data, int len) {
-  return murmur3_32(0, data, len);
-}
+  void AltHashing::testHalfsiphash_64_ByteArray() {
+    // printf("testHalfsiphash_64_CharArray\n");
+    const int factor = 4;
 
-jint AltHashing::murmur3_32(const jchar* data, int len) {
-  return murmur3_32(0, data, len);
-}
+    int8_t vector[256];
+    int8_t hashes[factor * 256];
+
+    for (int i = 0; i < 256; i++) {
+      vector[i] = (int8_t) i;
+    }
 
-// Internal test for alternate hashing.  Translated from JDK version
-// test/sun/misc/Hashing.java
-static const jbyte ONE_BYTE[] = { (jbyte) 0x80};
-static const jbyte TWO_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81};
-static const jchar ONE_CHAR[] = { (jchar) 0x8180};
-static const jbyte THREE_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82};
-static const jbyte FOUR_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, (jbyte) 0x83};
-static const jchar TWO_CHAR[] = { (jchar) 0x8180, (jchar) 0x8382};
-static const jint ONE_INT[] = { 0x83828180};
-static const jbyte SIX_BYTE[] = { (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82, (jbyte) 0x83, (jbyte) 0x84, (jbyte) 0x85};
-static const jchar THREE_CHAR[] = { (jchar) 0x8180, (jchar) 0x8382, (jchar) 0x8584};
-static const jbyte EIGHT_BYTE[] = {
-  (jbyte) 0x80, (jbyte) 0x81, (jbyte) 0x82,
-  (jbyte) 0x83, (jbyte) 0x84, (jbyte) 0x85,
-  (jbyte) 0x86, (jbyte) 0x87};
-static const jchar FOUR_CHAR[] = {
-  (jchar) 0x8180, (jchar) 0x8382,
-  (jchar) 0x8584, (jchar) 0x8786};
+    // Hash subranges {}, {0}, {0,1}, {0,1,2}, ..., {0,...,255}
+    for (int i = 0; i < 256; i++) {
+      uint64_t hash = AltHashing::halfsiphash_64(256 - i, vector, i);
+      hashes[i * factor] = (int8_t) hash;
+      hashes[i * factor + 1] = (int8_t)(hash >> 8);
+      hashes[i * factor + 2] = (int8_t)(hash >> 16);
+      hashes[i * factor + 3] = (int8_t)(hash >> 24);
+    }
+
+    // hash to get const result.
+    uint64_t final_hash = AltHashing::halfsiphash_64(0, hashes, factor*256);
 
-static const jint TWO_INT[] = { 0x83828180, 0x87868584};
+    // Value found using reference implementation for the hashes array.
+    // halfsiphash((const uint8_t*)hashes, factor*256, (const uint8_t *)&k,
+    //             (uint8_t*)&reference, 8);
 
-static const juint MURMUR3_32_X86_CHECK_VALUE = 0xB0F57EE3;
+    static const uint64_t HALFSIPHASH_64_BYTE_CHECK_VALUE = 0x15a7911e30917ee8;
 
-void AltHashing::testMurmur3_32_ByteArray() {
-  // printf("testMurmur3_32_ByteArray\n");
-
-  jbyte* vector = new jbyte[256];
-  jbyte* hashes = new jbyte[4 * 256];
-
-  for (int i = 0; i < 256; i++) {
-    vector[i] = (jbyte) i;
+    assert (HALFSIPHASH_64_BYTE_CHECK_VALUE == final_hash,
+      err_msg(
+          "Calculated hash result not as expected. Expected " UINT64_FORMAT " got " UINT64_FORMAT,
+          HALFSIPHASH_64_BYTE_CHECK_VALUE,
+          final_hash));
   }
 
-  // Hash subranges {}, {0}, {0,1}, {0,1,2}, ..., {0,...,255}
-  for (int i = 0; i < 256; i++) {
-    jint hash = murmur3_32(256 - i, vector, i);
-    hashes[i * 4] = (jbyte) hash;
-    hashes[i * 4 + 1] = (jbyte) (((juint)hash) >> 8);
-    hashes[i * 4 + 2] = (jbyte) (((juint)hash) >> 16);
-    hashes[i * 4 + 3] = (jbyte) (((juint)hash) >> 24);
+  void AltHashing::testHalfsiphash_64_CharArray() {
+    // printf("testHalfsiphash_64_CharArray\n");
+    const int factor = 2;
+
+    uint16_t vector[256];
+    uint16_t hashes[factor * 256];
+
+    for (int i = 0; i < 256; i++) {
+      vector[i] = (uint16_t) i;
+    }
+
+    // Hash subranges {}, {0}, {0,1}, {0,1,2}, ..., {0,...,255}
+    for (int i = 0; i < 256; i++) {
+      uint64_t hash = AltHashing::halfsiphash_64(256 - i, vector, i);
+      hashes[i * factor] = (uint16_t) hash;
+      hashes[i * factor + 1] = (uint16_t)(hash >> 16);
+    }
+
+    // hash to get const result.
+    uint64_t final_hash = AltHashing::halfsiphash_64(0, hashes, factor*256);
+
+    // Value found using reference implementation for the hashes array.
+    // halfsiphash((const uint8_t*)hashes, 2*factor*256, (const uint8_t *)&k,
+    //             (uint8_t*)&reference, 8);
+    static const uint64_t HALFSIPHASH_64_CHAR_CHECK_VALUE = 0xf392d8a6a9e24103;
+
+    assert(HALFSIPHASH_64_CHAR_CHECK_VALUE == final_hash,
+      err_msg(
+          "Calculated hash result not as expected. Expected " UINT64_FORMAT " got " UINT64_FORMAT,
+          HALFSIPHASH_64_CHAR_CHECK_VALUE,
+          final_hash));
   }
 
-  // hash to get const result.
-  juint final_hash = murmur3_32(hashes, 4*256);
-
-  assert (MURMUR3_32_X86_CHECK_VALUE == final_hash,
-    err_msg(
-        "Calculated hash result not as expected. Expected %08X got %08X\n",
-        MURMUR3_32_X86_CHECK_VALUE,
-        final_hash));
-}
+  // Test against sample hashes published with the reference implementation:
+  // https://github.com/veorq/SipHash
+  void AltHashing::testHalfsiphash_64_FromReference() {
+    // printf("testHalfsiphash_64_FromReference\n");
 
-void AltHashing::testEquivalentHashes() {
-  jint jbytes, jchars, ints;
-
-  // printf("testEquivalentHashes\n");
-
-  jbytes = murmur3_32(TWO_BYTE, 2);
-  jchars = murmur3_32(ONE_CHAR, 1);
-  assert (jbytes == jchars,
-    err_msg("Hashes did not match. b:%08x != c:%08x\n", jbytes, jchars));
+    const uint64_t seed = 0x0706050403020100;
+    const uint64_t results[16] = {
+              0xc83cb8b9591f8d21, 0xa12ee55b178ae7d5,
+              0x8c85e4bc20e8feed, 0x99c7f5ae9f1fc77b,
+              0xb5f37b5fd2aa3673, 0xdba7ee6f0a2bf51b,
+              0xf1a63fae45107470, 0xb516001efb5f922d,
+              0x6c6211d8469d7028, 0xdc7642ec407ad686,
+              0x4caec8671cc8385b, 0x5ab1dc27adf3301e,
+              0x3e3ea94bc0a8eaa9, 0xe150f598795a4402,
+              0x1d5ff142f992a4a1, 0x60e426bf902876d6
+    };
+    uint32_t vector[16];
 
-  jbytes = murmur3_32(FOUR_BYTE, 4);
-  jchars = murmur3_32(TWO_CHAR, 2);
-  ints = murmur3_32(ONE_INT, 1);
-  assert ((jbytes == jchars) && (jbytes == ints),
-    err_msg("Hashes did not match. b:%08x != c:%08x != i:%08x\n", jbytes, jchars, ints));
-
-  jbytes = murmur3_32(SIX_BYTE, 6);
-  jchars = murmur3_32(THREE_CHAR, 3);
-  assert (jbytes == jchars,
-    err_msg("Hashes did not match. b:%08x != c:%08x\n", jbytes, jchars));
+    for (int i = 0; i < 16; i++)
+      vector[i] = 0x03020100 + i * 0x04040404;
 
-  jbytes = murmur3_32(EIGHT_BYTE, 8);
-  jchars = murmur3_32(FOUR_CHAR, 4);
-  ints = murmur3_32(TWO_INT, 2);
-  assert ((jbytes == jchars) && (jbytes == ints),
-    err_msg("Hashes did not match. b:%08x != c:%08x != i:%08x\n", jbytes, jchars, ints));
-}
+    for (int i = 0; i < 16; i++) {
+      uint64_t hash = AltHashing::halfsiphash_64(seed, vector, i);
+      assert(results[i] == hash,
+        err_msg(
+            "Calculated hash result not as expected. Round %d: "
+            "Expected " UINT64_FORMAT_X " got " UINT64_FORMAT_X "\n",
+            i,
+            results[i],
+            hash));
+    }
+  }
 
-// Returns true if the alternate hashcode is correct
 void AltHashing::test_alt_hash() {
-  testMurmur3_32_ByteArray();
-  testEquivalentHashes();
+  testHalfsiphash_64_ByteArray();
+  testHalfsiphash_64_CharArray();
+  testHalfsiphash_64_FromReference();
 }
 #endif // PRODUCT
--- a/src/share/vm/classfile/altHashing.hpp	Tue Sep 22 13:09:39 2020 +0300
+++ b/src/share/vm/classfile/altHashing.hpp	Wed Sep 23 17:23:54 2020 +0300
@@ -26,37 +26,30 @@
 #define SHARE_VM_CLASSFILE_ALTHASHING_HPP
 
 #include "prims/jni.h"
-#include "classfile/symbolTable.hpp"
+#include "memory/allocation.hpp"
 
 /**
- * Hashing utilities.
- *
- * Implementation of Murmur3 hashing.
- * This code was translated from src/share/classes/sun/misc/Hashing.java
- * code in the JDK.
+ * Implementation of alternate more secure hashing.
  */
 
 class AltHashing : AllStatic {
 
-  // utility function copied from java/lang/Integer
-  static jint Integer_rotateLeft(jint i, int distance) {
-    return (i << distance) | (((juint)i) >> (32-distance));
-  }
-  static jint murmur3_32(const int* data, int len);
-  static jint murmur3_32(jint seed, const int* data, int len);
+  // For the seed computation
+  static uint64_t halfsiphash_64(const uint32_t* data, int len);
+  static uint64_t halfsiphash_64(uint64_t seed, const uint32_t* data, int len);
+ #ifndef PRODUCT
+   // Hashing functions used for internal testing
+  static void testHalfsiphash_64_ByteArray();
+  static void testHalfsiphash_64_CharArray();
+  static void testHalfsiphash_64_FromReference();
+ #endif // PRODUCT
+ public:
+  static uint64_t compute_seed();
 
-#ifndef PRODUCT
-  // Hashing functions used for internal testing
-  static jint murmur3_32(const jbyte* data, int len);
-  static jint murmur3_32(const jchar* data, int len);
-  static void testMurmur3_32_ByteArray();
-  static void testEquivalentHashes();
-#endif // PRODUCT
-
- public:
-  static jint compute_seed();
-  static jint murmur3_32(jint seed, const jbyte* data, int len);
-  static jint murmur3_32(jint seed, const jchar* data, int len);
+  // For Symbols
+  static uint64_t halfsiphash_64(uint64_t seed, const int8_t* data, int len);
+  // For Strings
+  static uint64_t halfsiphash_64(uint64_t seed, const uint16_t* data, int len);
   NOT_PRODUCT(static void test_alt_hash();)
 };
 #endif // SHARE_VM_CLASSFILE_ALTHASHING_HPP
--- a/src/share/vm/classfile/symbolTable.cpp	Tue Sep 22 13:09:39 2020 +0300
+++ b/src/share/vm/classfile/symbolTable.cpp	Wed Sep 23 17:23:54 2020 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, 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
@@ -216,7 +216,7 @@
 // Pick hashing algorithm.
 unsigned int SymbolTable::hash_symbol(const char* s, int len) {
   return use_alternate_hashcode() ?
-           AltHashing::murmur3_32(seed(), (const jbyte*)s, len) :
+           AltHashing::halfsiphash_64(seed(), (const int8_t*)s, len) :
            java_lang_String::to_hash(s, len);
 }
 
@@ -656,7 +656,7 @@
 
 // Pick hashing algorithm
 unsigned int StringTable::hash_string(const jchar* s, int len) {
-  return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :
+  return use_alternate_hashcode() ? AltHashing::halfsiphash_64(seed(), s, len) :
                                     java_lang_String::to_hash(s, len);
 }
 
--- a/src/share/vm/utilities/hashtable.cpp	Tue Sep 22 13:09:39 2020 +0300
+++ b/src/share/vm/utilities/hashtable.cpp	Wed Sep 23 17:23:54 2020 +0300
@@ -97,7 +97,7 @@
 template <class T, MEMFLAGS F> unsigned int Hashtable<T, F>::new_hash(Symbol* sym) {
   ResourceMark rm;
   // Use alternate hashing algorithm on this symbol.
-  return AltHashing::murmur3_32(seed(), (const jbyte*)sym->as_C_string(), sym->utf8_length());
+  return AltHashing::halfsiphash_64(seed(), (const int8_t*)sym->as_C_string(), sym->utf8_length());
 }
 
 template <class T, MEMFLAGS F> unsigned int Hashtable<T, F>::new_hash(oop string) {
@@ -105,7 +105,7 @@
   int length;
   jchar* chars = java_lang_String::as_unicode_string(string, length);
   // Use alternate hashing algorithm on the string
-  return AltHashing::murmur3_32(seed(), chars, length);
+  return AltHashing::halfsiphash_64(seed(), chars, length);
 }
 
 // Create a new table and using alternate hash code, populate the new table