src/hotspot/share/classfile/symbolTable.cpp
changeset 54847 59ea39bb2809
parent 54764 865ec913f916
child 54896 ea619918de95
equal deleted inserted replaced
54846:e4049522b074 54847:59ea39bb2809
   193   MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
   193   MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
   194   SymbolTable::the_table()->_has_work = true;
   194   SymbolTable::the_table()->_has_work = true;
   195   Service_lock->notify_all();
   195   Service_lock->notify_all();
   196 }
   196 }
   197 
   197 
   198 Symbol* SymbolTable::allocate_symbol(const char* name, int len, bool c_heap, TRAPS) {
   198 Symbol* SymbolTable::allocate_symbol(const char* name, int len, bool c_heap) {
   199   assert (len <= Symbol::max_length(), "should be checked by caller");
   199   assert (len <= Symbol::max_length(), "should be checked by caller");
   200 
   200 
   201   Symbol* sym;
   201   Symbol* sym;
   202   if (DumpSharedSpaces) {
   202   if (DumpSharedSpaces) {
   203     c_heap = false;
   203     c_heap = false;
   204   }
   204   }
   205   if (c_heap) {
   205   if (c_heap) {
   206     // refcount starts as 1
   206     // refcount starts as 1
   207     sym = new (len, THREAD) Symbol((const u1*)name, len, 1);
   207     sym = new (len) Symbol((const u1*)name, len, 1);
   208     assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
   208     assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
   209   } else {
   209   } else {
   210     // Allocate to global arena
   210     // Allocate to global arena
   211     MutexLocker ml(SymbolArena_lock, Mutex::_no_safepoint_check_flag); // Protect arena
   211     MutexLocker ml(SymbolArena_lock, Mutex::_no_safepoint_check_flag); // Protect arena
   212     sym = new (len, arena(), THREAD) Symbol((const u1*)name, len, PERM_REFCOUNT);
   212     sym = new (len, arena()) Symbol((const u1*)name, len, PERM_REFCOUNT);
   213   }
   213   }
   214   return sym;
   214   return sym;
   215 }
   215 }
   216 
   216 
   217 void SymbolTable::initialize_symbols(int arena_alloc_size) {
   217 void SymbolTable::initialize_symbols(int arena_alloc_size) {
   315     }
   315     }
   316   }
   316   }
   317   return sym;
   317   return sym;
   318 }
   318 }
   319 
   319 
   320 Symbol* SymbolTable::lookup(const char* name, int len, TRAPS) {
   320 Symbol* SymbolTable::new_symbol(const char* name, int len) {
   321   unsigned int hash = hash_symbol(name, len, SymbolTable::_alt_hash);
   321   unsigned int hash = hash_symbol(name, len, SymbolTable::_alt_hash);
   322   Symbol* sym = SymbolTable::the_table()->lookup_common(name, len, hash);
   322   Symbol* sym = SymbolTable::the_table()->lookup_common(name, len, hash);
   323   if (sym == NULL) {
   323   if (sym == NULL) {
   324     sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, true, CHECK_NULL);
   324     sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, true);
   325   }
   325   }
   326   assert(sym->refcount() != 0, "lookup should have incremented the count");
   326   assert(sym->refcount() != 0, "lookup should have incremented the count");
   327   assert(sym->equals(name, len), "symbol must be properly initialized");
   327   assert(sym->equals(name, len), "symbol must be properly initialized");
   328   return sym;
   328   return sym;
   329 }
   329 }
   330 
   330 
   331 Symbol* SymbolTable::lookup(const Symbol* sym, int begin, int end, TRAPS) {
   331 Symbol* SymbolTable::new_symbol(const Symbol* sym, int begin, int end) {
       
   332   assert(begin <= end && end <= sym->utf8_length(), "just checking");
   332   assert(sym->refcount() != 0, "require a valid symbol");
   333   assert(sym->refcount() != 0, "require a valid symbol");
   333   const char* name = (const char*)sym->base() + begin;
   334   const char* name = (const char*)sym->base() + begin;
   334   int len = end - begin;
   335   int len = end - begin;
   335   unsigned int hash = hash_symbol(name, len, SymbolTable::_alt_hash);
   336   unsigned int hash = hash_symbol(name, len, SymbolTable::_alt_hash);
   336   Symbol* found = SymbolTable::the_table()->lookup_common(name, len, hash);
   337   Symbol* found = SymbolTable::the_table()->lookup_common(name, len, hash);
   337   if (found == NULL) {
   338   if (found == NULL) {
   338     found = SymbolTable::the_table()->do_add_if_needed(name, len, hash, true, THREAD);
   339     found = SymbolTable::the_table()->do_add_if_needed(name, len, hash, true);
   339   }
   340   }
   340   return found;
   341   return found;
   341 }
   342 }
   342 
   343 
   343 class SymbolTableLookup : StackObj {
   344 class SymbolTableLookup : StackObj {
   345   Thread* _thread;
   346   Thread* _thread;
   346   uintx _hash;
   347   uintx _hash;
   347   int _len;
   348   int _len;
   348   const char* _str;
   349   const char* _str;
   349 public:
   350 public:
   350   SymbolTableLookup(Thread* thread, const char* key, int len, uintx hash)
   351   SymbolTableLookup(const char* key, int len, uintx hash)
   351   : _thread(thread), _hash(hash), _len(len), _str(key) {}
   352   : _hash(hash), _len(len), _str(key) {}
   352   uintx get_hash() const {
   353   uintx get_hash() const {
   353     return _hash;
   354     return _hash;
   354   }
   355   }
   355   bool equals(Symbol** value, bool* is_dead) {
   356   bool equals(Symbol** value, bool* is_dead) {
   356     assert(value != NULL, "expected valid value");
   357     assert(value != NULL, "expected valid value");
   386   }
   387   }
   387 };
   388 };
   388 
   389 
   389 Symbol* SymbolTable::do_lookup(const char* name, int len, uintx hash) {
   390 Symbol* SymbolTable::do_lookup(const char* name, int len, uintx hash) {
   390   Thread* thread = Thread::current();
   391   Thread* thread = Thread::current();
   391   SymbolTableLookup lookup(thread, name, len, hash);
   392   SymbolTableLookup lookup(name, len, hash);
   392   SymbolTableGet stg;
   393   SymbolTableGet stg;
   393   bool rehash_warning = false;
   394   bool rehash_warning = false;
   394   _local_table->get(thread, lookup, stg, &rehash_warning);
   395   _local_table->get(thread, lookup, stg, &rehash_warning);
   395   update_needs_rehash(rehash_warning);
   396   update_needs_rehash(rehash_warning);
   396   Symbol* sym = stg.get_res_sym();
   397   Symbol* sym = stg.get_res_sym();
   404 }
   405 }
   405 
   406 
   406 // Suggestion: Push unicode-based lookup all the way into the hashing
   407 // Suggestion: Push unicode-based lookup all the way into the hashing
   407 // and probing logic, so there is no need for convert_to_utf8 until
   408 // and probing logic, so there is no need for convert_to_utf8 until
   408 // an actual new Symbol* is created.
   409 // an actual new Symbol* is created.
   409 Symbol* SymbolTable::lookup_unicode(const jchar* name, int utf16_length, TRAPS) {
   410 Symbol* SymbolTable::new_symbol(const jchar* name, int utf16_length) {
   410   int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);
   411   int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);
   411   char stack_buf[ON_STACK_BUFFER_LENGTH];
   412   char stack_buf[ON_STACK_BUFFER_LENGTH];
   412   if (utf8_length < (int) sizeof(stack_buf)) {
   413   if (utf8_length < (int) sizeof(stack_buf)) {
   413     char* chars = stack_buf;
   414     char* chars = stack_buf;
   414     UNICODE::convert_to_utf8(name, utf16_length, chars);
   415     UNICODE::convert_to_utf8(name, utf16_length, chars);
   415     return lookup(chars, utf8_length, THREAD);
   416     return new_symbol(chars, utf8_length);
   416   } else {
   417   } else {
   417     ResourceMark rm(THREAD);
   418     ResourceMark rm;
   418     char* chars = NEW_RESOURCE_ARRAY(char, utf8_length + 1);
   419     char* chars = NEW_RESOURCE_ARRAY(char, utf8_length + 1);
   419     UNICODE::convert_to_utf8(name, utf16_length, chars);
   420     UNICODE::convert_to_utf8(name, utf16_length, chars);
   420     return lookup(chars, utf8_length, THREAD);
   421     return new_symbol(chars, utf8_length);
   421   }
   422   }
   422 }
   423 }
   423 
   424 
   424 Symbol* SymbolTable::lookup_only_unicode(const jchar* name, int utf16_length,
   425 Symbol* SymbolTable::lookup_only_unicode(const jchar* name, int utf16_length,
   425                                            unsigned int& hash) {
   426                                          unsigned int& hash) {
   426   int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);
   427   int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);
   427   char stack_buf[ON_STACK_BUFFER_LENGTH];
   428   char stack_buf[ON_STACK_BUFFER_LENGTH];
   428   if (utf8_length < (int) sizeof(stack_buf)) {
   429   if (utf8_length < (int) sizeof(stack_buf)) {
   429     char* chars = stack_buf;
   430     char* chars = stack_buf;
   430     UNICODE::convert_to_utf8(name, utf16_length, chars);
   431     UNICODE::convert_to_utf8(name, utf16_length, chars);
   437   }
   438   }
   438 }
   439 }
   439 
   440 
   440 void SymbolTable::new_symbols(ClassLoaderData* loader_data, const constantPoolHandle& cp,
   441 void SymbolTable::new_symbols(ClassLoaderData* loader_data, const constantPoolHandle& cp,
   441                               int names_count, const char** names, int* lengths,
   442                               int names_count, const char** names, int* lengths,
   442                               int* cp_indices, unsigned int* hashValues, TRAPS) {
   443                               int* cp_indices, unsigned int* hashValues) {
   443   bool c_heap = !loader_data->is_the_null_class_loader_data();
   444   bool c_heap = !loader_data->is_the_null_class_loader_data();
   444   for (int i = 0; i < names_count; i++) {
   445   for (int i = 0; i < names_count; i++) {
   445     const char *name = names[i];
   446     const char *name = names[i];
   446     int len = lengths[i];
   447     int len = lengths[i];
   447     unsigned int hash = hashValues[i];
   448     unsigned int hash = hashValues[i];
   448     assert(SymbolTable::the_table()->lookup_shared(name, len, hash) == NULL, "must have checked already");
   449     assert(SymbolTable::the_table()->lookup_shared(name, len, hash) == NULL, "must have checked already");
   449     Symbol* sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, c_heap, CHECK);
   450     Symbol* sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, c_heap);
   450     assert(sym->refcount() != 0, "lookup should have incremented the count");
   451     assert(sym->refcount() != 0, "lookup should have incremented the count");
   451     cp->symbol_at_put(cp_indices[i], sym);
   452     cp->symbol_at_put(cp_indices[i], sym);
   452   }
   453   }
   453 }
   454 }
   454 
   455 
   455 Symbol* SymbolTable::do_add_if_needed(const char* name, int len, uintx hash, bool heap, TRAPS) {
   456 Symbol* SymbolTable::do_add_if_needed(const char* name, int len, uintx hash, bool heap) {
   456   SymbolTableLookup lookup(THREAD, name, len, hash);
   457   SymbolTableLookup lookup(name, len, hash);
   457   SymbolTableGet stg;
   458   SymbolTableGet stg;
   458   bool clean_hint = false;
   459   bool clean_hint = false;
   459   bool rehash_warning = false;
   460   bool rehash_warning = false;
   460   Symbol* sym = NULL;
   461   Symbol* sym = NULL;
       
   462   Thread* THREAD = Thread::current();
   461 
   463 
   462   do {
   464   do {
   463     if (_local_table->get(THREAD, lookup, stg, &rehash_warning)) {
   465     if (_local_table->get(THREAD, lookup, stg, &rehash_warning)) {
   464       sym = stg.get_res_sym();
   466       sym = stg.get_res_sym();
   465       break;
   467       break;
   466     }
   468     }
   467     sym = SymbolTable::the_table()->allocate_symbol(name, len, heap, THREAD);
   469     sym = SymbolTable::the_table()->allocate_symbol(name, len, heap);
   468     if (_local_table->insert(THREAD, lookup, sym, &rehash_warning, &clean_hint)) {
   470     if (_local_table->insert(THREAD, lookup, sym, &rehash_warning, &clean_hint)) {
   469       break;
   471       break;
   470     }
   472     }
   471   } while(true);
   473   } while(true);
   472 
   474 
   479 
   481 
   480   assert((sym == NULL) || sym->refcount() != 0, "found dead symbol");
   482   assert((sym == NULL) || sym->refcount() != 0, "found dead symbol");
   481   return sym;
   483   return sym;
   482 }
   484 }
   483 
   485 
   484 Symbol* SymbolTable::new_permanent_symbol(const char* name, TRAPS) {
   486 Symbol* SymbolTable::new_permanent_symbol(const char* name) {
   485   unsigned int hash = 0;
   487   unsigned int hash = 0;
   486   int len = (int)strlen(name);
   488   int len = (int)strlen(name);
   487   Symbol* sym = SymbolTable::lookup_only(name, len, hash);
   489   Symbol* sym = SymbolTable::lookup_only(name, len, hash);
   488   if (sym == NULL) {
   490   if (sym == NULL) {
   489     sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, false, CHECK_NULL);
   491     sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, false);
   490   }
   492   }
   491   if (!sym->is_permanent()) {
   493   if (!sym->is_permanent()) {
   492     sym->make_permanent();
   494     sym->make_permanent();
   493     log_trace_symboltable_helper(sym, "Asked for a permanent symbol, but got a regular one");
   495     log_trace_symboltable_helper(sym, "Asked for a permanent symbol, but got a regular one");
   494   }
   496   }