1.1 --- a/src/share/vm/utilities/hashtable.cpp Tue Sep 23 17:24:34 2014 -0700 1.2 +++ b/src/share/vm/utilities/hashtable.cpp Fri Aug 29 13:08:01 2014 +0200 1.3 @@ -36,21 +36,22 @@ 1.4 #include "utilities/numberSeq.hpp" 1.5 1.6 1.7 -// This is a generic hashtable, designed to be used for the symbol 1.8 -// and string tables. 1.9 -// 1.10 -// It is implemented as an open hash table with a fixed number of buckets. 1.11 -// 1.12 -// %note: 1.13 -// - HashtableEntrys are allocated in blocks to reduce the space overhead. 1.14 +// This hashtable is implemented as an open hash table with a fixed number of buckets. 1.15 1.16 -template <MEMFLAGS F> BasicHashtableEntry<F>* BasicHashtable<F>::new_entry(unsigned int hashValue) { 1.17 - BasicHashtableEntry<F>* entry; 1.18 - 1.19 - if (_free_list) { 1.20 +template <MEMFLAGS F> BasicHashtableEntry<F>* BasicHashtable<F>::new_entry_free_list() { 1.21 + BasicHashtableEntry<F>* entry = NULL; 1.22 + if (_free_list != NULL) { 1.23 entry = _free_list; 1.24 _free_list = _free_list->next(); 1.25 - } else { 1.26 + } 1.27 + return entry; 1.28 +} 1.29 + 1.30 +// HashtableEntrys are allocated in blocks to reduce the space overhead. 1.31 +template <MEMFLAGS F> BasicHashtableEntry<F>* BasicHashtable<F>::new_entry(unsigned int hashValue) { 1.32 + BasicHashtableEntry<F>* entry = new_entry_free_list(); 1.33 + 1.34 + if (entry == NULL) { 1.35 if (_first_free_entry + _entry_size >= _end_block) { 1.36 int block_size = MIN2(512, MAX2((int)_table_size / 2, (int)_number_of_entries)); 1.37 int len = _entry_size * block_size; 1.38 @@ -83,9 +84,9 @@ 1.39 // This is somewhat an arbitrary heuristic but if one bucket gets to 1.40 // rehash_count which is currently 100, there's probably something wrong. 1.41 1.42 -template <MEMFLAGS F> bool BasicHashtable<F>::check_rehash_table(int count) { 1.43 - assert(table_size() != 0, "underflow"); 1.44 - if (count > (((double)number_of_entries()/(double)table_size())*rehash_multiple)) { 1.45 +template <class T, MEMFLAGS F> bool RehashableHashtable<T, F>::check_rehash_table(int count) { 1.46 + assert(this->table_size() != 0, "underflow"); 1.47 + if (count > (((double)this->number_of_entries()/(double)this->table_size())*rehash_multiple)) { 1.48 // Set a flag for the next safepoint, which should be at some guaranteed 1.49 // safepoint interval. 1.50 return true; 1.51 @@ -93,13 +94,13 @@ 1.52 return false; 1.53 } 1.54 1.55 -template <class T, MEMFLAGS F> juint Hashtable<T, F>::_seed = 0; 1.56 +template <class T, MEMFLAGS F> juint RehashableHashtable<T, F>::_seed = 0; 1.57 1.58 // Create a new table and using alternate hash code, populate the new table 1.59 // with the existing elements. This can be used to change the hash code 1.60 // and could in the future change the size of the table. 1.61 1.62 -template <class T, MEMFLAGS F> void Hashtable<T, F>::move_to(Hashtable<T, F>* new_table) { 1.63 +template <class T, MEMFLAGS F> void RehashableHashtable<T, F>::move_to(RehashableHashtable<T, F>* new_table) { 1.64 1.65 // Initialize the global seed for hashing. 1.66 _seed = AltHashing::compute_seed(); 1.67 @@ -109,7 +110,7 @@ 1.68 1.69 // Iterate through the table and create a new entry for the new table 1.70 for (int i = 0; i < new_table->table_size(); ++i) { 1.71 - for (HashtableEntry<T, F>* p = bucket(i); p != NULL; ) { 1.72 + for (HashtableEntry<T, F>* p = this->bucket(i); p != NULL; ) { 1.73 HashtableEntry<T, F>* next = p->next(); 1.74 T string = p->literal(); 1.75 // Use alternate hashing algorithm on the symbol in the first table 1.76 @@ -238,11 +239,11 @@ 1.77 } 1.78 } 1.79 1.80 -template <class T, MEMFLAGS F> int Hashtable<T, F>::literal_size(Symbol *symbol) { 1.81 +template <class T, MEMFLAGS F> int RehashableHashtable<T, F>::literal_size(Symbol *symbol) { 1.82 return symbol->size() * HeapWordSize; 1.83 } 1.84 1.85 -template <class T, MEMFLAGS F> int Hashtable<T, F>::literal_size(oop oop) { 1.86 +template <class T, MEMFLAGS F> int RehashableHashtable<T, F>::literal_size(oop oop) { 1.87 // NOTE: this would over-count if (pre-JDK8) java_lang_Class::has_offset_field() is true, 1.88 // and the String.value array is shared by several Strings. However, starting from JDK8, 1.89 // the String.value array is not shared anymore. 1.90 @@ -255,12 +256,12 @@ 1.91 // Note: if you create a new subclass of Hashtable<MyNewType, F>, you will need to 1.92 // add a new function Hashtable<T, F>::literal_size(MyNewType lit) 1.93 1.94 -template <class T, MEMFLAGS F> void Hashtable<T, F>::dump_table(outputStream* st, const char *table_name) { 1.95 +template <class T, MEMFLAGS F> void RehashableHashtable<T, F>::dump_table(outputStream* st, const char *table_name) { 1.96 NumberSeq summary; 1.97 int literal_bytes = 0; 1.98 for (int i = 0; i < this->table_size(); ++i) { 1.99 int count = 0; 1.100 - for (HashtableEntry<T, F>* e = bucket(i); 1.101 + for (HashtableEntry<T, F>* e = this->bucket(i); 1.102 e != NULL; e = e->next()) { 1.103 count++; 1.104 literal_bytes += literal_size(e->literal()); 1.105 @@ -270,7 +271,7 @@ 1.106 double num_buckets = summary.num(); 1.107 double num_entries = summary.sum(); 1.108 1.109 - int bucket_bytes = (int)num_buckets * sizeof(bucket(0)); 1.110 + int bucket_bytes = (int)num_buckets * sizeof(HashtableBucket<F>); 1.111 int entry_bytes = (int)num_entries * sizeof(HashtableEntry<T, F>); 1.112 int total_bytes = literal_bytes + bucket_bytes + entry_bytes; 1.113 1.114 @@ -353,11 +354,14 @@ 1.115 #endif 1.116 // Explicitly instantiate these types 1.117 template class Hashtable<ConstantPool*, mtClass>; 1.118 +template class RehashableHashtable<Symbol*, mtSymbol>; 1.119 +template class RehashableHashtable<oopDesc*, mtSymbol>; 1.120 template class Hashtable<Symbol*, mtSymbol>; 1.121 template class Hashtable<Klass*, mtClass>; 1.122 template class Hashtable<oop, mtClass>; 1.123 #if defined(SOLARIS) || defined(CHECK_UNHANDLED_OOPS) 1.124 template class Hashtable<oop, mtSymbol>; 1.125 +template class RehashableHashtable<oop, mtSymbol>; 1.126 #endif // SOLARIS || CHECK_UNHANDLED_OOPS 1.127 template class Hashtable<oopDesc*, mtSymbol>; 1.128 template class Hashtable<Symbol*, mtClass>;