This commit is contained in:
Harold Seigel 2017-04-27 14:15:30 +00:00
commit dbbc52769a
5 changed files with 122 additions and 2 deletions

View File

@ -571,3 +571,4 @@ b01c519b715ef6f785d0631adee0a6537cf6c12e jdk-9+162
0af429be8bbaeaaf0cb838e9af28c953dda6a9c8 jdk-9+164
c92c6416ca03b1464d5ed99cf6201e52b5ba0a70 jdk-9+165
560d7aa083a24b6a56443feb8de0f40435d33aa9 jdk-9+166
48809c513ed5ebb4d4dbf2f454afcce2780db6db jdk-10+2

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.memory;
public class AltHashing {
public static long murmur3_32(long seed, byte[] data) {
long h1 = seed;
int len = data.length;
int count = len;
int offset = 0;
// body
while (count >= 4) {
long k1 = (data[offset] & 0x0FF)
| (data[offset + 1] & 0x0FF) << 8
| (data[offset + 2] & 0x0FF) << 16
| data[offset + 3] << 24;
count -= 4;
offset += 4;
k1 *= 0xcc9e2d51;
k1 = Integer.rotateLeft((int)k1, 15);
k1 *= 0x1b873593;
k1 &= 0xFFFFFFFFL;
h1 ^= k1;
h1 = Integer.rotateLeft((int)h1, 13);
h1 = h1 * 5 + 0xe6546b64;
h1 &= 0xFFFFFFFFL;
}
//tail
if (count > 0) {
long k1 = 0;
switch (count) {
case 3:
k1 ^= (data[offset + 2] & 0xff) << 16;
// fall through
case 2:
k1 ^= (data[offset + 1] & 0xff) << 8;
// fall through
case 1:
k1 ^= (data[offset] & 0xff);
// fall through
default:
k1 *= 0xcc9e2d51;
k1 = Integer.rotateLeft((int)k1, 15);
k1 *= 0x1b873593;
k1 &= 0xFFFFFFFFL;
h1 ^= k1;
h1 &= 0xFFFFFFFFL;
}
}
// finalization
h1 ^= len;
// finalization mix force all bits of a hash block to avalanche
h1 ^= h1 >> 16;
h1 *= 0x85ebca6b;
h1 &= 0xFFFFFFFFL;
h1 ^= h1 >> 13;
h1 *= 0xc2b2ae35;
h1 &= 0xFFFFFFFFL;
h1 ^= h1 >> 16;
return h1 & 0xFFFFFFFFL;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2017, 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
@ -45,11 +45,14 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
Type type = db.lookupType("SymbolTable");
theTableField = type.getAddressField("_the_table");
sharedTableField = type.getAddressField("_shared_table");
type = db.lookupType("RehashableSymbolHashtable");
seedField = type.getCIntegerField("_seed");
}
// Fields
private static AddressField theTableField;
private static AddressField sharedTableField;
private static CIntegerField seedField;
private CompactHashTable sharedTable;
@ -62,6 +65,17 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
return table;
}
public static long getSeed() {
return (long) seedField.getValue();
}
public static boolean useAlternateHashcode() {
if (getSeed() != 0) {
return true;
}
return false;
}
public SymbolTable(Address addr) {
super(addr);
}
@ -86,11 +100,17 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
public Symbol probe(byte[] name) {
long hashValue = hashSymbol(name);
// shared table does not use alternate hashing algorithm,
// it always uses the same original hash code.
Symbol s = sharedTable.probe(name, hashValue);
if (s != null) {
return s;
}
if (useAlternateHashcode()) {
hashValue = AltHashing.murmur3_32(getSeed(), name);
}
for (HashtableEntry e = (HashtableEntry) bucket(hashToIndex(hashValue)); e != null; e = (HashtableEntry) e.next()) {
if (e.hash() == hashValue) {
Symbol sym = Symbol.create(e.literalValue());

View File

@ -199,6 +199,7 @@ typedef Hashtable<InstanceKlass*, mtClass> KlassHashtable;
typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
typedef RehashableHashtable<Symbol*, mtSymbol> RehashableSymbolHashtable;
//--------------------------------------------------------------------------------
// VM_STRUCTS
@ -584,6 +585,7 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
\
static_field(SymbolTable, _the_table, SymbolTable*) \
static_field(SymbolTable, _shared_table, SymbolCompactHashTable) \
static_field(RehashableSymbolHashtable, _seed, juint) \
\
/***************/ \
/* StringTable */ \
@ -1602,6 +1604,8 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
\
declare_toplevel_type(BasicHashtable<mtInternal>) \
declare_type(IntptrHashtable, BasicHashtable<mtInternal>) \
declare_toplevel_type(BasicHashtable<mtSymbol>) \
declare_type(RehashableSymbolHashtable, BasicHashtable<mtSymbol>) \
declare_type(SymbolTable, SymbolHashtable) \
declare_type(StringTable, StringHashtable) \
declare_type(LoaderConstraintTable, KlassHashtable) \

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, 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
@ -294,6 +294,7 @@ protected:
};
template <class T, MEMFLAGS F> class RehashableHashtable : public Hashtable<T, F> {
friend class VMStructs;
protected:
enum {