src/share/vm/classfile/stringTable.cpp

Print this page




  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/javaClasses.hpp"
  28 #include "classfile/stringTable.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "gc_interface/collectedHeap.inline.hpp"
  31 #include "memory/allocation.inline.hpp"
  32 #include "memory/filemap.hpp"
  33 #include "memory/gcLocker.inline.hpp"
  34 #include "oops/oop.inline.hpp"
  35 #include "oops/oop.inline2.hpp"
  36 #include "runtime/atomic.inline.hpp"
  37 #include "runtime/mutexLocker.hpp"
  38 #include "utilities/hashtable.inline.hpp"
  39 #if INCLUDE_ALL_GCS

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


 140 
 141   oop test = lookup(index, name, len, hashValue); // calls lookup(u1*, int)
 142   if (test != NULL) {
 143     // Entry already added
 144     return test;
 145   }
 146 
 147   HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string());
 148   add_entry(index, entry);
 149   return string();
 150 }
 151 
 152 
 153 oop StringTable::lookup(Symbol* symbol) {
 154   ResourceMark rm;
 155   int length;
 156   jchar* chars = symbol->as_unicode(length);
 157   return lookup(chars, length);
 158 }
 159 











 160 
 161 oop StringTable::lookup(jchar* name, int len) {
 162   unsigned int hash = hash_string(name, len);
 163   int index = the_table()->hash_to_index(hash);
 164   return the_table()->lookup(index, name, len, hash);




 165 }
 166 
 167 
 168 oop StringTable::intern(Handle string_or_null, jchar* name,
 169                         int len, TRAPS) {
 170   unsigned int hashValue = hash_string(name, len);
 171   int index = the_table()->hash_to_index(hashValue);
 172   oop found_string = the_table()->lookup(index, name, len, hashValue);
 173 
 174   // Found
 175   if (found_string != NULL) return found_string;



 176 
 177   debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
 178   assert(!Universe::heap()->is_in_reserved(name),
 179          "proposed name of symbol must be stable");
 180 
 181   Handle string;
 182   // try to reuse the string if possible
 183   if (!string_or_null.is_null()) {
 184     string = string_or_null;
 185   } else {
 186     string = java_lang_String::create_from_unicode(name, len, CHECK_NULL);
 187   }
 188 
 189 #if INCLUDE_ALL_GCS
 190   if (G1StringDedup::is_enabled()) {
 191     // Deduplicate the string before it is interned. Note that we should never
 192     // deduplicate a string after it has been interned. Doing so will counteract
 193     // compiler optimizations done on e.g. interned string literals.
 194     G1StringDedup::deduplicate(string());
 195   }
 196 #endif
 197 
 198   // Grab the StringTable_lock before getting the_table() because it could
 199   // change at safepoint.


 200   MutexLocker ml(StringTable_lock, THREAD);
 201 
 202   // Otherwise, add to symbol to table
 203   return the_table()->basic_add(index, string, name, len,
 204                                 hashValue, CHECK_NULL);





 205 }
 206 
 207 oop StringTable::intern(Symbol* symbol, TRAPS) {
 208   if (symbol == NULL) return NULL;
 209   ResourceMark rm(THREAD);
 210   int length;
 211   jchar* chars = symbol->as_unicode(length);
 212   Handle string;
 213   oop result = intern(string, chars, length, CHECK_NULL);
 214   return result;
 215 }
 216 
 217 
 218 oop StringTable::intern(oop string, TRAPS)
 219 {
 220   if (string == NULL) return NULL;
 221   ResourceMark rm(THREAD);
 222   int length;
 223   Handle h_string (THREAD, string);
 224   jchar* chars = java_lang_String::as_unicode_string(string, length, CHECK_NULL);




  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/javaClasses.hpp"
  28 #include "classfile/stringTable.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "gc_interface/collectedHeap.inline.hpp"
  31 #include "memory/allocation.inline.hpp"
  32 #include "memory/filemap.hpp"
  33 #include "memory/gcLocker.inline.hpp"
  34 #include "oops/oop.inline.hpp"
  35 #include "oops/oop.inline2.hpp"
  36 #include "runtime/atomic.inline.hpp"
  37 #include "runtime/mutexLocker.hpp"
  38 #include "utilities/hashtable.inline.hpp"
  39 #if INCLUDE_ALL_GCS
  40 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
  41 #include "gc_implementation/g1/g1StringDedup.hpp"
  42 #endif
  43 
  44 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
  45 
  46 // the number of buckets a thread claims
  47 const int ClaimChunkSize = 32;
  48 
  49 #ifdef ASSERT
  50 class StableMemoryChecker : public StackObj {
  51   enum { _bufsize = wordSize*4 };
  52 
  53   address _region;
  54   jint    _size;
  55   u1      _save_buf[_bufsize];
  56 
  57   int sample(u1* save_buf) {
  58     if (_size <= _bufsize) {
  59       memcpy(save_buf, _region, _size);
  60       return _size;


 141 
 142   oop test = lookup(index, name, len, hashValue); // calls lookup(u1*, int)
 143   if (test != NULL) {
 144     // Entry already added
 145     return test;
 146   }
 147 
 148   HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string());
 149   add_entry(index, entry);
 150   return string();
 151 }
 152 
 153 
 154 oop StringTable::lookup(Symbol* symbol) {
 155   ResourceMark rm;
 156   int length;
 157   jchar* chars = symbol->as_unicode(length);
 158   return lookup(chars, length);
 159 }
 160 
 161 // Tell the GC that this string was looked up in the StringTable.
 162 static void ensure_string_alive(oop string) {
 163   // A lookup in the StringTable could return an object that was previously
 164   // considered dead. The SATB part of G1 needs to get notified about this
 165   // potential resurrection, otherwise the marking might not find the object.
 166 #if INCLUDE_ALL_GCS
 167   if (UseG1GC && string != NULL) {
 168     G1SATBCardTableModRefBS::enqueue(string);
 169   }
 170 #endif
 171 }
 172 
 173 oop StringTable::lookup(jchar* name, int len) {
 174   unsigned int hash = hash_string(name, len);
 175   int index = the_table()->hash_to_index(hash);
 176   oop string = the_table()->lookup(index, name, len, hash);
 177 
 178   ensure_string_alive(string);
 179 
 180   return string;
 181 }
 182 
 183 
 184 oop StringTable::intern(Handle string_or_null, jchar* name,
 185                         int len, TRAPS) {
 186   unsigned int hashValue = hash_string(name, len);
 187   int index = the_table()->hash_to_index(hashValue);
 188   oop found_string = the_table()->lookup(index, name, len, hashValue);
 189 
 190   // Found
 191   if (found_string != NULL) {
 192     ensure_string_alive(found_string);
 193     return found_string;
 194   }
 195 
 196   debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
 197   assert(!Universe::heap()->is_in_reserved(name),
 198          "proposed name of symbol must be stable");
 199 
 200   Handle string;
 201   // try to reuse the string if possible
 202   if (!string_or_null.is_null()) {
 203     string = string_or_null;
 204   } else {
 205     string = java_lang_String::create_from_unicode(name, len, CHECK_NULL);
 206   }
 207 
 208 #if INCLUDE_ALL_GCS
 209   if (G1StringDedup::is_enabled()) {
 210     // Deduplicate the string before it is interned. Note that we should never
 211     // deduplicate a string after it has been interned. Doing so will counteract
 212     // compiler optimizations done on e.g. interned string literals.
 213     G1StringDedup::deduplicate(string());
 214   }
 215 #endif
 216 
 217   // Grab the StringTable_lock before getting the_table() because it could
 218   // change at safepoint.
 219   oop added_or_found;
 220   {
 221     MutexLocker ml(StringTable_lock, THREAD);

 222     // Otherwise, add to symbol to table
 223     added_or_found = the_table()->basic_add(index, string, name, len,
 224                                   hashValue, CHECK_NULL);
 225   }
 226 
 227   ensure_string_alive(added_or_found);
 228 
 229   return added_or_found;
 230 }
 231 
 232 oop StringTable::intern(Symbol* symbol, TRAPS) {
 233   if (symbol == NULL) return NULL;
 234   ResourceMark rm(THREAD);
 235   int length;
 236   jchar* chars = symbol->as_unicode(length);
 237   Handle string;
 238   oop result = intern(string, chars, length, CHECK_NULL);
 239   return result;
 240 }
 241 
 242 
 243 oop StringTable::intern(oop string, TRAPS)
 244 {
 245   if (string == NULL) return NULL;
 246   ResourceMark rm(THREAD);
 247   int length;
 248   Handle h_string (THREAD, string);
 249   jchar* chars = java_lang_String::as_unicode_string(string, length, CHECK_NULL);