< prev index next >

src/share/vm/classfile/stringTable.cpp

Print this page




  94 CompactHashtable<oop, char> StringTable::_shared_table;
  95 
  96 // Pick hashing algorithm
  97 template<typename T>
  98 unsigned int StringTable::hash_string(const T* s, int len) {
  99   return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :
 100                                     java_lang_String::hash_code(s, len);
 101 }
 102 
 103 // Explicit instantiation for all supported types.
 104 template unsigned int StringTable::hash_string<jchar>(const jchar* s, int len);
 105 template unsigned int StringTable::hash_string<jbyte>(const jbyte* s, int len);
 106 
 107 oop StringTable::lookup_shared(jchar* name, int len) {
 108   // java_lang_String::hash_code() was used to compute hash values in the shared table. Don't
 109   // use the hash value from StringTable::hash_string() as it might use alternate hashcode.
 110   return _shared_table.lookup((const char*)name,
 111                               java_lang_String::hash_code(name, len), len);
 112 }
 113 













 114 oop StringTable::lookup_in_main_table(int index, jchar* name,
 115                                 int len, unsigned int hash) {
 116   int count = 0;
 117   for (HashtableEntry<oop, mtSymbol>* l = bucket(index); l != NULL; l = l->next()) {
 118     count++;
 119     if (l->hash() == hash) {
 120       if (java_lang_String::equals(l->literal(), name, len)) {
 121         return l->literal();


 122       }
 123     }
 124   }
 125   // If the bucket size is too deep check if this hash code is insufficient.
 126   if (count >= rehash_count && !needs_rehashing()) {
 127     _needs_rehashing = check_rehash_table(count);
 128   }
 129   return NULL;
 130 }
 131 
 132 
 133 oop StringTable::basic_add(int index_arg, Handle string, jchar* name,
 134                            int len, unsigned int hashValue_arg, TRAPS) {
 135 
 136   assert(java_lang_String::equals(string(), name, len),
 137          "string must be properly initialized");
 138   // Cannot hit a safepoint in this function because the "this" pointer can move.
 139   NoSafepointVerifier nsv;
 140 
 141   // Check if the symbol table has been rehashed, if so, need to recalculate


 156   // No need to lookup the shared table from here since the caller (intern()) already did
 157   oop test = lookup_in_main_table(index, name, len, hashValue); // calls lookup(u1*, int)
 158   if (test != NULL) {
 159     // Entry already added
 160     return test;
 161   }
 162 
 163   HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string());
 164   add_entry(index, entry);
 165   return string();
 166 }
 167 
 168 
 169 oop StringTable::lookup(Symbol* symbol) {
 170   ResourceMark rm;
 171   int length;
 172   jchar* chars = symbol->as_unicode(length);
 173   return lookup(chars, length);
 174 }
 175 
 176 // Tell the GC that this string was looked up in the StringTable.
 177 static void ensure_string_alive(oop string) {
 178   // A lookup in the StringTable could return an object that was previously
 179   // considered dead. The SATB part of G1 needs to get notified about this
 180   // potential resurrection, otherwise the marking might not find the object.
 181 #if INCLUDE_ALL_GCS
 182   if (UseG1GC && string != NULL) {
 183     G1SATBCardTableModRefBS::enqueue(string);
 184   }
 185 #endif
 186 }
 187 
 188 oop StringTable::lookup(jchar* name, int len) {
 189   oop string = lookup_shared(name, len);
 190   if (string != NULL) {
 191     return string;
 192   }
 193 
 194   unsigned int hash = hash_string(name, len);
 195   int index = the_table()->hash_to_index(hash);
 196   string = the_table()->lookup_in_main_table(index, name, len, hash);
 197 
 198   ensure_string_alive(string);
 199 
 200   return string;
 201 }
 202 
 203 
 204 oop StringTable::intern(Handle string_or_null, jchar* name,
 205                         int len, TRAPS) {
 206   oop found_string = lookup_shared(name, len);
 207   if (found_string != NULL) {
 208     return found_string;
 209   }
 210 
 211   unsigned int hashValue = hash_string(name, len);
 212   int index = the_table()->hash_to_index(hashValue);
 213   found_string = the_table()->lookup_in_main_table(index, name, len, hashValue);
 214 
 215   // Found
 216   if (found_string != NULL) {
 217     ensure_string_alive(found_string);
 218     return found_string;
 219   }
 220 
 221   debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
 222   assert(!Universe::heap()->is_in_reserved(name),
 223          "proposed name of symbol must be stable");
 224 
 225   Handle string;
 226   // try to reuse the string if possible
 227   if (!string_or_null.is_null()) {
 228     string = string_or_null;
 229   } else {
 230     string = java_lang_String::create_from_unicode(name, len, CHECK_NULL);
 231   }
 232 
 233 #if INCLUDE_ALL_GCS
 234   if (G1StringDedup::is_enabled()) {
 235     // Deduplicate the string before it is interned. Note that we should never
 236     // deduplicate a string after it has been interned. Doing so will counteract
 237     // compiler optimizations done on e.g. interned string literals.
 238     G1StringDedup::deduplicate(string());
 239   }
 240 #endif
 241 
 242   // Grab the StringTable_lock before getting the_table() because it could
 243   // change at safepoint.
 244   oop added_or_found;
 245   {
 246     MutexLocker ml(StringTable_lock, THREAD);
 247     // Otherwise, add to symbol to table
 248     added_or_found = the_table()->basic_add(index, string, name, len,
 249                                   hashValue, CHECK_NULL);
 250   }
 251 
 252   ensure_string_alive(added_or_found);
 253 
 254   return added_or_found;
 255 }
 256 
 257 oop StringTable::intern(Symbol* symbol, TRAPS) {
 258   if (symbol == NULL) return NULL;
 259   ResourceMark rm(THREAD);
 260   int length;
 261   jchar* chars = symbol->as_unicode(length);
 262   Handle string;
 263   oop result = intern(string, chars, length, CHECK_NULL);
 264   return result;
 265 }
 266 
 267 
 268 oop StringTable::intern(oop string, TRAPS)
 269 {
 270   if (string == NULL) return NULL;
 271   ResourceMark rm(THREAD);
 272   int length;




  94 CompactHashtable<oop, char> StringTable::_shared_table;
  95 
  96 // Pick hashing algorithm
  97 template<typename T>
  98 unsigned int StringTable::hash_string(const T* s, int len) {
  99   return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :
 100                                     java_lang_String::hash_code(s, len);
 101 }
 102 
 103 // Explicit instantiation for all supported types.
 104 template unsigned int StringTable::hash_string<jchar>(const jchar* s, int len);
 105 template unsigned int StringTable::hash_string<jbyte>(const jbyte* s, int len);
 106 
 107 oop StringTable::lookup_shared(jchar* name, int len) {
 108   // java_lang_String::hash_code() was used to compute hash values in the shared table. Don't
 109   // use the hash value from StringTable::hash_string() as it might use alternate hashcode.
 110   return _shared_table.lookup((const char*)name,
 111                               java_lang_String::hash_code(name, len), len);
 112 }
 113 
 114 // Tell the GC that this string was looked up in the StringTable.
 115 static void ensure_string_alive(oop string) {
 116   // A lookup in the StringTable could return an object that was previously
 117   // considered dead. The SATB part of G1 needs to get notified about this
 118   // potential resurrection, otherwise the marking might not find the object.
 119 #if INCLUDE_ALL_GCS
 120   assert(string != NULL, "should only be called when string found in table");
 121   if (UseG1GC) {
 122     G1SATBCardTableModRefBS::enqueue(string);
 123   }
 124 #endif
 125 }
 126 
 127 oop StringTable::lookup_in_main_table(int index, jchar* name,
 128                                 int len, unsigned int hash) {
 129   int count = 0;
 130   for (HashtableEntry<oop, mtSymbol>* l = bucket(index); l != NULL; l = l->next()) {
 131     count++;
 132     if (l->hash() == hash) {
 133       if (java_lang_String::equals(l->literal(), name, len)) {
 134         oop result = l->literal();
 135         ensure_string_alive(result);
 136         return result;
 137       }
 138     }
 139   }
 140   // If the bucket size is too deep check if this hash code is insufficient.
 141   if (count >= rehash_count && !needs_rehashing()) {
 142     _needs_rehashing = check_rehash_table(count);
 143   }
 144   return NULL;
 145 }
 146 
 147 
 148 oop StringTable::basic_add(int index_arg, Handle string, jchar* name,
 149                            int len, unsigned int hashValue_arg, TRAPS) {
 150 
 151   assert(java_lang_String::equals(string(), name, len),
 152          "string must be properly initialized");
 153   // Cannot hit a safepoint in this function because the "this" pointer can move.
 154   NoSafepointVerifier nsv;
 155 
 156   // Check if the symbol table has been rehashed, if so, need to recalculate


 171   // No need to lookup the shared table from here since the caller (intern()) already did
 172   oop test = lookup_in_main_table(index, name, len, hashValue); // calls lookup(u1*, int)
 173   if (test != NULL) {
 174     // Entry already added
 175     return test;
 176   }
 177 
 178   HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string());
 179   add_entry(index, entry);
 180   return string();
 181 }
 182 
 183 
 184 oop StringTable::lookup(Symbol* symbol) {
 185   ResourceMark rm;
 186   int length;
 187   jchar* chars = symbol->as_unicode(length);
 188   return lookup(chars, length);
 189 }
 190 












 191 oop StringTable::lookup(jchar* name, int len) {
 192   oop string = lookup_shared(name, len);
 193   if (string != NULL) {
 194     return string;
 195   }
 196 
 197   unsigned int hash = hash_string(name, len);
 198   int index = the_table()->hash_to_index(hash);
 199   string = the_table()->lookup_in_main_table(index, name, len, hash);



 200   return string;
 201 }
 202 
 203 
 204 oop StringTable::intern(Handle string_or_null, jchar* name,
 205                         int len, TRAPS) {
 206   oop found_string = lookup_shared(name, len);
 207   if (found_string != NULL) {
 208     return found_string;
 209   }
 210 
 211   unsigned int hashValue = hash_string(name, len);
 212   int index = the_table()->hash_to_index(hashValue);
 213   found_string = the_table()->lookup_in_main_table(index, name, len, hashValue);
 214 
 215   // Found
 216   if (found_string != NULL) {

 217     return found_string;
 218   }
 219 
 220   debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
 221   assert(!Universe::heap()->is_in_reserved(name),
 222          "proposed name of symbol must be stable");
 223 
 224   Handle string;
 225   // try to reuse the string if possible
 226   if (!string_or_null.is_null()) {
 227     string = string_or_null;
 228   } else {
 229     string = java_lang_String::create_from_unicode(name, len, CHECK_NULL);
 230   }
 231 
 232 #if INCLUDE_ALL_GCS
 233   if (G1StringDedup::is_enabled()) {
 234     // Deduplicate the string before it is interned. Note that we should never
 235     // deduplicate a string after it has been interned. Doing so will counteract
 236     // compiler optimizations done on e.g. interned string literals.
 237     G1StringDedup::deduplicate(string());
 238   }
 239 #endif
 240 
 241   // Grab the StringTable_lock before getting the_table() because it could
 242   // change at safepoint.
 243   oop added_or_found;
 244   {
 245     MutexLocker ml(StringTable_lock, THREAD);
 246     // Otherwise, add to symbol to table
 247     added_or_found = the_table()->basic_add(index, string, name, len,
 248                                   hashValue, CHECK_NULL);
 249   }


 250 
 251   return added_or_found;
 252 }
 253 
 254 oop StringTable::intern(Symbol* symbol, TRAPS) {
 255   if (symbol == NULL) return NULL;
 256   ResourceMark rm(THREAD);
 257   int length;
 258   jchar* chars = symbol->as_unicode(length);
 259   Handle string;
 260   oop result = intern(string, chars, length, CHECK_NULL);
 261   return result;
 262 }
 263 
 264 
 265 oop StringTable::intern(oop string, TRAPS)
 266 {
 267   if (string == NULL) return NULL;
 268   ResourceMark rm(THREAD);
 269   int length;


< prev index next >