Wed, 04 Jul 2012 15:55:45 -0400
7181200: JVM new hashing code breaks SA in product mode
Summary: Made new_hash() overloaded rather than a virtual function so SA code doesn't need to be changed.
Reviewed-by: kvn, acorn, dholmes, fparain
1.1 --- a/src/share/vm/classfile/symbolTable.cpp Tue Jul 03 17:35:00 2012 -0700 1.2 +++ b/src/share/vm/classfile/symbolTable.cpp Wed Jul 04 15:55:45 2012 -0400 1.3 @@ -43,7 +43,6 @@ 1.4 // Static arena for symbols that are not deallocated 1.5 Arena* SymbolTable::_arena = NULL; 1.6 bool SymbolTable::_needs_rehashing = false; 1.7 -jint SymbolTable::_seed = 0; 1.8 1.9 Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS) { 1.10 assert (len <= Symbol::max_length(), "should be checked by caller"); 1.11 @@ -130,12 +129,6 @@ 1.12 } 1.13 } 1.14 1.15 -unsigned int SymbolTable::new_hash(Symbol* sym) { 1.16 - ResourceMark rm; 1.17 - // Use alternate hashing algorithm on this symbol. 1.18 - return AltHashing::murmur3_32(seed(), (const jbyte*)sym->as_C_string(), sym->utf8_length()); 1.19 -} 1.20 - 1.21 // Create a new table and using alternate hash code, populate the new table 1.22 // with the existing strings. Set flag to use the alternate hash code afterwards. 1.23 void SymbolTable::rehash_table() { 1.24 @@ -145,10 +138,6 @@ 1.25 // Create a new symbol table 1.26 SymbolTable* new_table = new SymbolTable(); 1.27 1.28 - // Initialize the global seed for hashing. 1.29 - _seed = AltHashing::compute_seed(); 1.30 - assert(seed() != 0, "shouldn't be zero"); 1.31 - 1.32 the_table()->move_to(new_table); 1.33 1.34 // Delete the table and buckets (entries are reused in new table). 1.35 @@ -620,7 +609,6 @@ 1.36 StringTable* StringTable::_the_table = NULL; 1.37 1.38 bool StringTable::_needs_rehashing = false; 1.39 -jint StringTable::_seed = 0; 1.40 1.41 // Pick hashing algorithm 1.42 unsigned int StringTable::hash_string(const jchar* s, int len) { 1.43 @@ -837,14 +825,6 @@ 1.44 } 1.45 1.46 1.47 -unsigned int StringTable::new_hash(oop string) { 1.48 - ResourceMark rm; 1.49 - int length; 1.50 - jchar* chars = java_lang_String::as_unicode_string(string, length); 1.51 - // Use alternate hashing algorithm on the string 1.52 - return AltHashing::murmur3_32(seed(), chars, length); 1.53 -} 1.54 - 1.55 // Create a new table and using alternate hash code, populate the new table 1.56 // with the existing strings. Set flag to use the alternate hash code afterwards. 1.57 void StringTable::rehash_table() { 1.58 @@ -853,10 +833,6 @@ 1.59 if (DumpSharedSpaces) return; 1.60 StringTable* new_table = new StringTable(); 1.61 1.62 - // Initialize new global seed for hashing. 1.63 - _seed = AltHashing::compute_seed(); 1.64 - assert(seed() != 0, "shouldn't be zero"); 1.65 - 1.66 // Rehash the table 1.67 the_table()->move_to(new_table); 1.68
2.1 --- a/src/share/vm/classfile/symbolTable.hpp Tue Jul 03 17:35:00 2012 -0700 2.2 +++ b/src/share/vm/classfile/symbolTable.hpp Wed Jul 04 15:55:45 2012 -0400 2.3 @@ -81,7 +81,6 @@ 2.4 2.5 // Set if one bucket is out of balance due to hash algorithm deficiency 2.6 static bool _needs_rehashing; 2.7 - static jint _seed; 2.8 2.9 // For statistics 2.10 static int symbols_removed; 2.11 @@ -124,11 +123,6 @@ 2.12 static Arena* arena() { return _arena; } // called for statistics 2.13 2.14 static void initialize_symbols(int arena_alloc_size = 0); 2.15 - 2.16 - static bool use_alternate_hashcode() { return _seed != 0; } 2.17 - static jint seed() { return _seed; } 2.18 - 2.19 - unsigned int new_hash(Symbol* sym); 2.20 public: 2.21 enum { 2.22 symbol_alloc_batch_size = 8, 2.23 @@ -247,7 +241,6 @@ 2.24 2.25 // Set if one bucket is out of balance due to hash algorithm deficiency 2.26 static bool _needs_rehashing; 2.27 - static jint _seed; 2.28 2.29 static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS); 2.30 oop basic_add(int index, Handle string_or_null, jchar* name, int len, 2.31 @@ -261,11 +254,6 @@ 2.32 StringTable(HashtableBucket<mtSymbol>* t, int number_of_entries) 2.33 : Hashtable<oop, mtSymbol>((int)StringTableSize, sizeof (HashtableEntry<oop, mtSymbol>), t, 2.34 number_of_entries) {} 2.35 - 2.36 - static bool use_alternate_hashcode() { return _seed != 0; } 2.37 - static jint seed() { return _seed; } 2.38 - 2.39 - unsigned int new_hash(oop s); 2.40 public: 2.41 // The string table 2.42 static StringTable* the_table() { return _the_table; }
3.1 --- a/src/share/vm/utilities/hashtable.cpp Tue Jul 03 17:35:00 2012 -0700 3.2 +++ b/src/share/vm/utilities/hashtable.cpp Wed Jul 04 15:55:45 2012 -0400 3.3 @@ -23,6 +23,8 @@ 3.4 */ 3.5 3.6 #include "precompiled.hpp" 3.7 +#include "classfile/altHashing.hpp" 3.8 +#include "classfile/javaClasses.hpp" 3.9 #include "memory/allocation.inline.hpp" 3.10 #include "memory/filemap.hpp" 3.11 #include "memory/resourceArea.hpp" 3.12 @@ -90,12 +92,33 @@ 3.13 return false; 3.14 } 3.15 3.16 +template <class T, MEMFLAGS F> jint Hashtable<T, F>::_seed = 0; 3.17 + 3.18 +template <class T, MEMFLAGS F> unsigned int Hashtable<T, F>::new_hash(Symbol* sym) { 3.19 + ResourceMark rm; 3.20 + // Use alternate hashing algorithm on this symbol. 3.21 + return AltHashing::murmur3_32(seed(), (const jbyte*)sym->as_C_string(), sym->utf8_length()); 3.22 +} 3.23 + 3.24 +template <class T, MEMFLAGS F> unsigned int Hashtable<T, F>::new_hash(oop string) { 3.25 + ResourceMark rm; 3.26 + int length; 3.27 + jchar* chars = java_lang_String::as_unicode_string(string, length); 3.28 + // Use alternate hashing algorithm on the string 3.29 + return AltHashing::murmur3_32(seed(), chars, length); 3.30 +} 3.31 + 3.32 // Create a new table and using alternate hash code, populate the new table 3.33 // with the existing elements. This can be used to change the hash code 3.34 // and could in the future change the size of the table. 3.35 3.36 template <class T, MEMFLAGS F> void Hashtable<T, F>::move_to(Hashtable<T, F>* new_table) { 3.37 - int saved_entry_count = BasicHashtable<F>::number_of_entries(); 3.38 + 3.39 + // Initialize the global seed for hashing. 3.40 + _seed = AltHashing::compute_seed(); 3.41 + assert(seed() != 0, "shouldn't be zero"); 3.42 + 3.43 + int saved_entry_count = this->number_of_entries(); 3.44 3.45 // Iterate through the table and create a new entry for the new table 3.46 for (int i = 0; i < new_table->table_size(); ++i) {
4.1 --- a/src/share/vm/utilities/hashtable.hpp Tue Jul 03 17:35:00 2012 -0700 4.2 +++ b/src/share/vm/utilities/hashtable.hpp Wed Jul 04 15:55:45 2012 -0400 4.3 @@ -278,7 +278,14 @@ 4.4 4.5 // Function to move these elements into the new table. 4.6 void move_to(Hashtable<T, F>* new_table); 4.7 - virtual unsigned int new_hash(T) { ShouldNotReachHere(); return 0; } // should be overridden 4.8 + static bool use_alternate_hashcode() { return _seed != 0; } 4.9 + static jint seed() { return _seed; } 4.10 + 4.11 + private: 4.12 + static jint _seed; 4.13 + 4.14 + unsigned int new_hash(Symbol* s); 4.15 + unsigned int new_hash(oop string); 4.16 }; 4.17 4.18