1.1 --- a/src/share/vm/classfile/symbolTable.cpp Fri Jun 22 15:39:16 2012 -0700 1.2 +++ b/src/share/vm/classfile/symbolTable.cpp Mon Jun 25 21:33:35 2012 -0400 1.3 @@ -46,11 +46,8 @@ 1.4 jint SymbolTable::_seed = 0; 1.5 1.6 Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS) { 1.7 - // Don't allow symbols to be created which cannot fit in a Symbol*. 1.8 - if (len > Symbol::max_length()) { 1.9 - THROW_MSG_0(vmSymbols::java_lang_InternalError(), 1.10 - "name is too long to represent"); 1.11 - } 1.12 + assert (len <= Symbol::max_length(), "should be checked by caller"); 1.13 + 1.14 Symbol* sym; 1.15 // Allocate symbols in the C heap when dumping shared spaces in case there 1.16 // are temporary symbols we can remove. 1.17 @@ -95,9 +92,14 @@ 1.18 int total = 0; 1.19 size_t memory_total = 0; 1.20 for (int i = 0; i < the_table()->table_size(); ++i) { 1.21 - for (HashtableEntry<Symbol*>** p = the_table()->bucket_addr(i); *p != NULL; ) { 1.22 - HashtableEntry<Symbol*>* entry = *p; 1.23 - if (entry->is_shared()) { 1.24 + HashtableEntry<Symbol*>** p = the_table()->bucket_addr(i); 1.25 + HashtableEntry<Symbol*>* entry = the_table()->bucket(i); 1.26 + while (entry != NULL) { 1.27 + // Shared entries are normally at the end of the bucket and if we run into 1.28 + // a shared entry, then there is nothing more to remove. However, if we 1.29 + // have rehashed the table, then the shared entries are no longer at the 1.30 + // end of the bucket. 1.31 + if (entry->is_shared() && !use_alternate_hashcode()) { 1.32 break; 1.33 } 1.34 Symbol* s = entry->literal(); 1.35 @@ -106,6 +108,7 @@ 1.36 assert(s != NULL, "just checking"); 1.37 // If reference count is zero, remove. 1.38 if (s->refcount() == 0) { 1.39 + assert(!entry->is_shared(), "shared entries should be kept live"); 1.40 delete s; 1.41 removed++; 1.42 *p = entry->next(); 1.43 @@ -113,6 +116,8 @@ 1.44 } else { 1.45 p = entry->next_addr(); 1.46 } 1.47 + // get next entry 1.48 + entry = (HashtableEntry<Symbol*>*)HashtableEntry<Symbol*>::make_ptr(*p); 1.49 } 1.50 } 1.51 symbols_removed += removed; 1.52 @@ -135,7 +140,8 @@ 1.53 // with the existing strings. Set flag to use the alternate hash code afterwards. 1.54 void SymbolTable::rehash_table() { 1.55 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 1.56 - assert(!DumpSharedSpaces, "this should never happen with -Xshare:dump"); 1.57 + // This should never happen with -Xshare:dump but it might in testing mode. 1.58 + if (DumpSharedSpaces) return; 1.59 // Create a new symbol table 1.60 SymbolTable* new_table = new SymbolTable(); 1.61 1.62 @@ -176,12 +182,11 @@ 1.63 return NULL; 1.64 } 1.65 1.66 -// Pick hashing algorithm, but return value already given if not using a new 1.67 -// hash algorithm. 1.68 -unsigned int SymbolTable::hash_symbol(const char* s, int len, unsigned int hashValue) { 1.69 +// Pick hashing algorithm. 1.70 +unsigned int SymbolTable::hash_symbol(const char* s, int len) { 1.71 return use_alternate_hashcode() ? 1.72 AltHashing::murmur3_32(seed(), (const jbyte*)s, len) : 1.73 - (hashValue != 0 ? hashValue : java_lang_String::to_hash(s, len)); 1.74 + java_lang_String::to_hash(s, len); 1.75 } 1.76 1.77 1.78 @@ -201,6 +206,9 @@ 1.79 // Found 1.80 if (s != NULL) return s; 1.81 1.82 + // Grab SymbolTable_lock first. 1.83 + MutexLocker ml(SymbolTable_lock, THREAD); 1.84 + 1.85 // Otherwise, add to symbol to table 1.86 return the_table()->basic_add(index, (u1*)name, len, hashValue, true, CHECK_NULL); 1.87 } 1.88 @@ -238,6 +246,9 @@ 1.89 // We can't include the code in No_Safepoint_Verifier because of the 1.90 // ResourceMark. 1.91 1.92 + // Grab SymbolTable_lock first. 1.93 + MutexLocker ml(SymbolTable_lock, THREAD); 1.94 + 1.95 return the_table()->basic_add(index, (u1*)buffer, len, hashValue, true, CHECK_NULL); 1.96 } 1.97 1.98 @@ -306,6 +317,9 @@ 1.99 int names_count, 1.100 const char** names, int* lengths, int* cp_indices, 1.101 unsigned int* hashValues, TRAPS) { 1.102 + // Grab SymbolTable_lock first. 1.103 + MutexLocker ml(SymbolTable_lock, THREAD); 1.104 + 1.105 SymbolTable* table = the_table(); 1.106 bool added = table->basic_add(class_loader, cp, names_count, names, lengths, 1.107 cp_indices, hashValues, CHECK); 1.108 @@ -326,22 +340,39 @@ 1.109 if (result != NULL) { 1.110 return result; 1.111 } 1.112 + // Grab SymbolTable_lock first. 1.113 + MutexLocker ml(SymbolTable_lock, THREAD); 1.114 + 1.115 SymbolTable* table = the_table(); 1.116 int index = table->hash_to_index(hash); 1.117 return table->basic_add(index, (u1*)name, (int)strlen(name), hash, false, THREAD); 1.118 } 1.119 1.120 -Symbol* SymbolTable::basic_add(int index, u1 *name, int len, 1.121 +Symbol* SymbolTable::basic_add(int index_arg, u1 *name, int len, 1.122 unsigned int hashValue_arg, bool c_heap, TRAPS) { 1.123 assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), 1.124 "proposed name of symbol must be stable"); 1.125 1.126 - // Grab SymbolTable_lock first. 1.127 - MutexLocker ml(SymbolTable_lock, THREAD); 1.128 + // Don't allow symbols to be created which cannot fit in a Symbol*. 1.129 + if (len > Symbol::max_length()) { 1.130 + THROW_MSG_0(vmSymbols::java_lang_InternalError(), 1.131 + "name is too long to represent"); 1.132 + } 1.133 + 1.134 + // Cannot hit a safepoint in this function because the "this" pointer can move. 1.135 + No_Safepoint_Verifier nsv; 1.136 1.137 // Check if the symbol table has been rehashed, if so, need to recalculate 1.138 - // the hash value. 1.139 - unsigned int hashValue = hash_symbol((const char*)name, len, hashValue_arg); 1.140 + // the hash value and index. 1.141 + unsigned int hashValue; 1.142 + int index; 1.143 + if (use_alternate_hashcode()) { 1.144 + hashValue = hash_symbol((const char*)name, len); 1.145 + index = hash_to_index(hashValue); 1.146 + } else { 1.147 + hashValue = hashValue_arg; 1.148 + index = index_arg; 1.149 + } 1.150 1.151 // Since look-up was done lock-free, we need to check if another 1.152 // thread beat us in the race to insert the symbol. 1.153 @@ -377,13 +408,18 @@ 1.154 } 1.155 } 1.156 1.157 - // Hold SymbolTable_lock through the symbol creation 1.158 - MutexLocker ml(SymbolTable_lock, THREAD); 1.159 + // Cannot hit a safepoint in this function because the "this" pointer can move. 1.160 + No_Safepoint_Verifier nsv; 1.161 1.162 for (int i=0; i<names_count; i++) { 1.163 // Check if the symbol table has been rehashed, if so, need to recalculate 1.164 // the hash value. 1.165 - unsigned int hashValue = hash_symbol(names[i], lengths[i], hashValues[i]); 1.166 + unsigned int hashValue; 1.167 + if (use_alternate_hashcode()) { 1.168 + hashValue = hash_symbol(names[i], lengths[i]); 1.169 + } else { 1.170 + hashValue = hashValues[i]; 1.171 + } 1.172 // Since look-up was done lock-free, we need to check if another 1.173 // thread beat us in the race to insert the symbol. 1.174 int index = hash_to_index(hashValue); 1.175 @@ -587,9 +623,9 @@ 1.176 jint StringTable::_seed = 0; 1.177 1.178 // Pick hashing algorithm 1.179 -unsigned int StringTable::hash_string(const jchar* s, int len, unsigned int hashValue) { 1.180 +unsigned int StringTable::hash_string(const jchar* s, int len) { 1.181 return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) : 1.182 - (hashValue != 0 ? hashValue : java_lang_String::to_hash(s, len)); 1.183 + java_lang_String::to_hash(s, len); 1.184 } 1.185 1.186 oop StringTable::lookup(int index, jchar* name, 1.187 @@ -611,29 +647,25 @@ 1.188 } 1.189 1.190 1.191 -oop StringTable::basic_add(int index, Handle string_or_null, jchar* name, 1.192 +oop StringTable::basic_add(int index_arg, Handle string, jchar* name, 1.193 int len, unsigned int hashValue_arg, TRAPS) { 1.194 - debug_only(StableMemoryChecker smc(name, len * sizeof(name[0]))); 1.195 - assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), 1.196 - "proposed name of symbol must be stable"); 1.197 - 1.198 - Handle string; 1.199 - // try to reuse the string if possible 1.200 - if (!string_or_null.is_null() && (!JavaObjectsInPerm || string_or_null()->is_perm())) { 1.201 - string = string_or_null; 1.202 - } else { 1.203 - string = java_lang_String::create_tenured_from_unicode(name, len, CHECK_NULL); 1.204 - } 1.205 - 1.206 - // Allocation must be done before grapping the SymbolTable_lock lock 1.207 - MutexLocker ml(StringTable_lock, THREAD); 1.208 1.209 assert(java_lang_String::equals(string(), name, len), 1.210 "string must be properly initialized"); 1.211 + // Cannot hit a safepoint in this function because the "this" pointer can move. 1.212 + No_Safepoint_Verifier nsv; 1.213 1.214 // Check if the symbol table has been rehashed, if so, need to recalculate 1.215 - // the hash value before second lookup. 1.216 - unsigned int hashValue = hash_string(name, len, hashValue_arg); 1.217 + // the hash value and index before second lookup. 1.218 + unsigned int hashValue; 1.219 + int index; 1.220 + if (use_alternate_hashcode()) { 1.221 + hashValue = hash_string(name, len); 1.222 + index = hash_to_index(hashValue); 1.223 + } else { 1.224 + hashValue = hashValue_arg; 1.225 + index = index_arg; 1.226 + } 1.227 1.228 // Since look-up was done lock-free, we need to check if another 1.229 // thread beat us in the race to insert the symbol. 1.230 @@ -664,13 +696,29 @@ 1.231 int len, TRAPS) { 1.232 unsigned int hashValue = hash_string(name, len); 1.233 int index = the_table()->hash_to_index(hashValue); 1.234 - oop string = the_table()->lookup(index, name, len, hashValue); 1.235 + oop found_string = the_table()->lookup(index, name, len, hashValue); 1.236 1.237 // Found 1.238 - if (string != NULL) return string; 1.239 + if (found_string != NULL) return found_string; 1.240 + 1.241 + debug_only(StableMemoryChecker smc(name, len * sizeof(name[0]))); 1.242 + assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), 1.243 + "proposed name of symbol must be stable"); 1.244 + 1.245 + Handle string; 1.246 + // try to reuse the string if possible 1.247 + if (!string_or_null.is_null() && (!JavaObjectsInPerm || string_or_null()->is_perm())) { 1.248 + string = string_or_null; 1.249 + } else { 1.250 + string = java_lang_String::create_tenured_from_unicode(name, len, CHECK_NULL); 1.251 + } 1.252 + 1.253 + // Grab the StringTable_lock before getting the_table() because it could 1.254 + // change at safepoint. 1.255 + MutexLocker ml(StringTable_lock, THREAD); 1.256 1.257 // Otherwise, add to symbol to table 1.258 - return the_table()->basic_add(index, string_or_null, name, len, 1.259 + return the_table()->basic_add(index, string, name, len, 1.260 hashValue, CHECK_NULL); 1.261 } 1.262 1.263 @@ -713,18 +761,24 @@ 1.264 // entries at a safepoint. 1.265 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 1.266 for (int i = 0; i < the_table()->table_size(); ++i) { 1.267 - for (HashtableEntry<oop>** p = the_table()->bucket_addr(i); *p != NULL; ) { 1.268 - HashtableEntry<oop>* entry = *p; 1.269 - if (entry->is_shared()) { 1.270 + HashtableEntry<oop>** p = the_table()->bucket_addr(i); 1.271 + HashtableEntry<oop>* entry = the_table()->bucket(i); 1.272 + while (entry != NULL) { 1.273 + // Shared entries are normally at the end of the bucket and if we run into 1.274 + // a shared entry, then there is nothing more to remove. However, if we 1.275 + // have rehashed the table, then the shared entries are no longer at the 1.276 + // end of the bucket. 1.277 + if (entry->is_shared() && !use_alternate_hashcode()) { 1.278 break; 1.279 } 1.280 assert(entry->literal() != NULL, "just checking"); 1.281 - if (is_alive->do_object_b(entry->literal())) { 1.282 + if (entry->is_shared() || is_alive->do_object_b(entry->literal())) { 1.283 p = entry->next_addr(); 1.284 } else { 1.285 *p = entry->next(); 1.286 the_table()->free_entry(entry); 1.287 } 1.288 + entry = (HashtableEntry<oop>*)HashtableEntry<oop>::make_ptr(*p); 1.289 } 1.290 } 1.291 } 1.292 @@ -795,7 +849,8 @@ 1.293 // with the existing strings. Set flag to use the alternate hash code afterwards. 1.294 void StringTable::rehash_table() { 1.295 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 1.296 - assert(!DumpSharedSpaces, "this should never happen with -Xshare:dump"); 1.297 + // This should never happen with -Xshare:dump but it might in testing mode. 1.298 + if (DumpSharedSpaces) return; 1.299 StringTable* new_table = new StringTable(); 1.300 1.301 // Initialize new global seed for hashing.