< prev index next >

src/share/vm/classfile/stringTable.cpp

Print this page
rev 12906 : [mq]: gc_interface


  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/altHashing.hpp"
  27 #include "classfile/compactHashtable.inline.hpp"
  28 #include "classfile/javaClasses.inline.hpp"
  29 #include "classfile/stringTable.hpp"
  30 #include "classfile/systemDictionary.hpp"
  31 #include "gc/shared/collectedHeap.inline.hpp"
  32 #include "gc/shared/gcLocker.inline.hpp"
  33 #include "memory/allocation.inline.hpp"
  34 #include "memory/filemap.hpp"
  35 #include "memory/resourceArea.hpp"
  36 #include "oops/oop.inline.hpp"

  37 #include "runtime/atomic.hpp"
  38 #include "runtime/mutexLocker.hpp"
  39 #include "utilities/hashtable.inline.hpp"
  40 #include "utilities/macros.hpp"
  41 #if INCLUDE_ALL_GCS

  42 #include "gc/g1/g1CollectedHeap.hpp"
  43 #include "gc/g1/g1SATBCardTableModRefBS.hpp"
  44 #include "gc/g1/g1StringDedup.hpp"
  45 #endif
  46 
  47 // the number of buckets a thread claims
  48 const int ClaimChunkSize = 32;
  49 
  50 #ifdef ASSERT
  51 class StableMemoryChecker : public StackObj {
  52   enum { _bufsize = wordSize*4 };
  53 
  54   address _region;
  55   jint    _size;
  56   u1      _save_buf[_bufsize];
  57 
  58   int sample(u1* save_buf) {
  59     if (_size <= _bufsize) {
  60       memcpy(save_buf, _region, _size);
  61       return _size;
  62     } else {
  63       // copy head and tail


 116   if (chars != NULL) {
 117     return hash_string(chars, length);
 118   } else {
 119     vm_exit_out_of_memory(length, OOM_MALLOC_ERROR, "unable to create Unicode string for verification");
 120     return 0;
 121   }
 122 }
 123 
 124 oop StringTable::lookup_shared(jchar* name, int len, unsigned int hash) {
 125   assert(hash == java_lang_String::hash_code(name, len),
 126          "hash must be computed using java_lang_String::hash_code");
 127   return _shared_table.lookup((const char*)name, hash, len);
 128 }
 129 
 130 oop StringTable::lookup_in_main_table(int index, jchar* name,
 131                                 int len, unsigned int hash) {
 132   int count = 0;
 133   for (HashtableEntry<oop, mtSymbol>* l = bucket(index); l != NULL; l = l->next()) {
 134     count++;
 135     if (l->hash() == hash) {
 136       if (java_lang_String::equals(l->literal(), name, len)) {
 137         return l->literal();








 138       }
 139     }
 140   }
 141   // If the bucket size is too deep check if this hash code is insufficient.
 142   if (count >= rehash_count && !needs_rehashing()) {
 143     _needs_rehashing = check_rehash_table(count);
 144   }
 145   return NULL;
 146 }
 147 
 148 
 149 oop StringTable::basic_add(int index_arg, Handle string, jchar* name,
 150                            int len, unsigned int hashValue_arg, TRAPS) {
 151 
 152   assert(java_lang_String::equals(string(), name, len),
 153          "string must be properly initialized");
 154   // Cannot hit a safepoint in this function because the "this" pointer can move.
 155   NoSafepointVerifier nsv;
 156 
 157   // Check if the symbol table has been rehashed, if so, need to recalculate


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


 761       }
 762     }
 763   }
 764 
 765   _shared_table.set_type(CompactHashtable<oop, char>::_string_table);
 766   _shared_table.serialize(soc);
 767 
 768   if (soc->writing()) {
 769     _shared_table.reset(); // Sanity. Make sure we don't use the shared table at dump time
 770   } else if (_ignore_shared_strings) {
 771     _shared_table.reset();
 772   }
 773 #endif
 774 }
 775 
 776 void StringTable::shared_oops_do(OopClosure* f) {
 777 #if INCLUDE_CDS && defined(_LP64) && !defined(_WINDOWS)
 778   _shared_table.oops_do(f);
 779 #endif
 780 }
 781 


  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/altHashing.hpp"
  27 #include "classfile/compactHashtable.inline.hpp"
  28 #include "classfile/javaClasses.inline.hpp"
  29 #include "classfile/stringTable.hpp"
  30 #include "classfile/systemDictionary.hpp"
  31 #include "gc/shared/collectedHeap.inline.hpp"
  32 #include "gc/shared/gcLocker.inline.hpp"
  33 #include "memory/allocation.inline.hpp"
  34 #include "memory/filemap.hpp"
  35 #include "memory/resourceArea.hpp"
  36 #include "oops/oop.inline.hpp"
  37 #include "runtime/access.inline.hpp"
  38 #include "runtime/atomic.hpp"
  39 #include "runtime/mutexLocker.hpp"
  40 #include "utilities/hashtable.inline.hpp"
  41 #include "utilities/macros.hpp"
  42 #if INCLUDE_ALL_GCS
  43 #include "gc/g1/g1BarrierSet.hpp"
  44 #include "gc/g1/g1CollectedHeap.hpp"

  45 #include "gc/g1/g1StringDedup.hpp"
  46 #endif
  47 
  48 // the number of buckets a thread claims
  49 const int ClaimChunkSize = 32;
  50 
  51 #ifdef ASSERT
  52 class StableMemoryChecker : public StackObj {
  53   enum { _bufsize = wordSize*4 };
  54 
  55   address _region;
  56   jint    _size;
  57   u1      _save_buf[_bufsize];
  58 
  59   int sample(u1* save_buf) {
  60     if (_size <= _bufsize) {
  61       memcpy(save_buf, _region, _size);
  62       return _size;
  63     } else {
  64       // copy head and tail


 117   if (chars != NULL) {
 118     return hash_string(chars, length);
 119   } else {
 120     vm_exit_out_of_memory(length, OOM_MALLOC_ERROR, "unable to create Unicode string for verification");
 121     return 0;
 122   }
 123 }
 124 
 125 oop StringTable::lookup_shared(jchar* name, int len, unsigned int hash) {
 126   assert(hash == java_lang_String::hash_code(name, len),
 127          "hash must be computed using java_lang_String::hash_code");
 128   return _shared_table.lookup((const char*)name, hash, len);
 129 }
 130 
 131 oop StringTable::lookup_in_main_table(int index, jchar* name,
 132                                       int len, unsigned int hash) {
 133   int count = 0;
 134   for (HashtableEntry<oop, mtSymbol>* l = bucket(index); l != NULL; l = l->next()) {
 135     count++;
 136     if (l->hash() == hash) {
 137       oop* string_addr = l->literal_addr();
 138       // The ACCESS_WEAK peeks at the oop without keeping it alive.
 139       // This is *very dangerous* in general but is okay in this specific
 140       // case. The subsequent oop_load keeps the oop alive if it it matched
 141       // the jchar* string.
 142       oop string = RootAccess<GC_ACCESS_ON_PHANTOM | ACCESS_WEAK>::oop_load(string_addr);
 143       typeArrayOop value = HeapAccess<GC_ACCESS_ON_STRONG | ACCESS_WEAK>::oop_load_at(string, java_lang_String::value_offset_in_bytes());
 144       int length = java_lang_String::length(string, value);
 145       if (java_lang_String::equals(value, length, string, name, len)) {
 146         return RootAccess<GC_ACCESS_ON_PHANTOM>::oop_load(string_addr);
 147       }
 148     }
 149   }
 150   // If the bucket size is too deep check if this hash code is insufficient.
 151   if (count >= rehash_count && !needs_rehashing()) {
 152     _needs_rehashing = check_rehash_table(count);
 153   }
 154   return NULL;
 155 }
 156 
 157 
 158 oop StringTable::basic_add(int index_arg, Handle string, jchar* name,
 159                            int len, unsigned int hashValue_arg, TRAPS) {
 160 
 161   assert(java_lang_String::equals(string(), name, len),
 162          "string must be properly initialized");
 163   // Cannot hit a safepoint in this function because the "this" pointer can move.
 164   NoSafepointVerifier nsv;
 165 
 166   // Check if the symbol table has been rehashed, if so, need to recalculate


 181   // No need to lookup the shared table from here since the caller (intern()) already did
 182   oop test = lookup_in_main_table(index, name, len, hashValue); // calls lookup(u1*, int)
 183   if (test != NULL) {
 184     // Entry already added
 185     return test;
 186   }
 187 
 188   HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string());
 189   add_entry(index, entry);
 190   return string();
 191 }
 192 
 193 
 194 oop StringTable::lookup(Symbol* symbol) {
 195   ResourceMark rm;
 196   int length;
 197   jchar* chars = symbol->as_unicode(length);
 198   return lookup(chars, length);
 199 }
 200 












 201 oop StringTable::lookup(jchar* name, int len) {
 202   // shared table always uses java_lang_String::hash_code
 203   unsigned int hash = java_lang_String::hash_code(name, len);
 204   oop string = lookup_shared(name, len, hash);
 205   if (string != NULL) {
 206     return string;
 207   }
 208   if (use_alternate_hashcode()) {
 209     hash = alt_hash_string(name, len);
 210   }
 211   int index = the_table()->hash_to_index(hash);
 212   string = the_table()->lookup_in_main_table(index, name, len, hash);
 213 


 214   return string;
 215 }
 216 
 217 oop StringTable::intern(Handle string_or_null, jchar* name,
 218                         int len, TRAPS) {
 219   // shared table always uses java_lang_String::hash_code
 220   unsigned int hashValue = java_lang_String::hash_code(name, len);
 221   oop found_string = lookup_shared(name, len, hashValue);
 222   if (found_string != NULL) {
 223     return found_string;
 224   }
 225   if (use_alternate_hashcode()) {
 226     hashValue = alt_hash_string(name, len);
 227   }
 228   int index = the_table()->hash_to_index(hashValue);
 229   found_string = the_table()->lookup_in_main_table(index, name, len, hashValue);
 230 
 231   // Found
 232   if (found_string != NULL) {



 233     return found_string;
 234   }
 235 
 236   debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
 237   assert(!Universe::heap()->is_in_reserved(name),
 238          "proposed name of symbol must be stable");
 239 
 240   HandleMark hm(THREAD);  // cleanup strings created
 241   Handle string;
 242   // try to reuse the string if possible
 243   if (!string_or_null.is_null()) {
 244     string = string_or_null;
 245   } else {
 246     string = java_lang_String::create_from_unicode(name, len, CHECK_NULL);
 247   }
 248 
 249 #if INCLUDE_ALL_GCS
 250   if (G1StringDedup::is_enabled()) {
 251     // Deduplicate the string before it is interned. Note that we should never
 252     // deduplicate a string after it has been interned. Doing so will counteract
 253     // compiler optimizations done on e.g. interned string literals.
 254     G1StringDedup::deduplicate(string());
 255   }
 256 #endif
 257 
 258   // Grab the StringTable_lock before getting the_table() because it could
 259   // change at safepoint.
 260   oop added_or_found;
 261   {
 262     MutexLocker ml(StringTable_lock, THREAD);
 263     // Otherwise, add to symbol to table
 264     added_or_found = the_table()->basic_add(index, string, name, len,
 265                                   hashValue, CHECK_NULL);
 266   }
 267 




 268   return added_or_found;
 269 }
 270 
 271 oop StringTable::intern(Symbol* symbol, TRAPS) {
 272   if (symbol == NULL) return NULL;
 273   ResourceMark rm(THREAD);
 274   int length;
 275   jchar* chars = symbol->as_unicode(length);
 276   Handle string;
 277   oop result = intern(string, chars, length, CHECK_NULL);
 278   return result;
 279 }
 280 
 281 
 282 oop StringTable::intern(oop string, TRAPS)
 283 {
 284   if (string == NULL) return NULL;
 285   ResourceMark rm(THREAD);
 286   int length;
 287   Handle h_string (THREAD, string);


 749       }
 750     }
 751   }
 752 
 753   _shared_table.set_type(CompactHashtable<oop, char>::_string_table);
 754   _shared_table.serialize(soc);
 755 
 756   if (soc->writing()) {
 757     _shared_table.reset(); // Sanity. Make sure we don't use the shared table at dump time
 758   } else if (_ignore_shared_strings) {
 759     _shared_table.reset();
 760   }
 761 #endif
 762 }
 763 
 764 void StringTable::shared_oops_do(OopClosure* f) {
 765 #if INCLUDE_CDS && defined(_LP64) && !defined(_WINDOWS)
 766   _shared_table.oops_do(f);
 767 #endif
 768 }

< prev index next >