src/hotspot/share/classfile/stringTable.cpp
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 54942 2523496f5107
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
    28 #include "classfile/javaClasses.inline.hpp"
    28 #include "classfile/javaClasses.inline.hpp"
    29 #include "classfile/stringTable.hpp"
    29 #include "classfile/stringTable.hpp"
    30 #include "classfile/systemDictionary.hpp"
    30 #include "classfile/systemDictionary.hpp"
    31 #include "gc/shared/collectedHeap.hpp"
    31 #include "gc/shared/collectedHeap.hpp"
    32 #include "gc/shared/oopStorage.inline.hpp"
    32 #include "gc/shared/oopStorage.inline.hpp"
       
    33 #include "gc/shared/oopStorageSet.hpp"
    33 #include "logging/log.hpp"
    34 #include "logging/log.hpp"
    34 #include "logging/logStream.hpp"
    35 #include "logging/logStream.hpp"
    35 #include "memory/allocation.inline.hpp"
    36 #include "memory/allocation.inline.hpp"
    36 #include "memory/filemap.hpp"
    37 #include "memory/filemap.hpp"
    37 #include "memory/heapShared.inline.hpp"
    38 #include "memory/heapShared.inline.hpp"
    56 
    57 
    57 // We prefer short chains of avg 2
    58 // We prefer short chains of avg 2
    58 const double PREF_AVG_LIST_LEN = 2.0;
    59 const double PREF_AVG_LIST_LEN = 2.0;
    59 // 2^24 is max size
    60 // 2^24 is max size
    60 const size_t END_SIZE = 24;
    61 const size_t END_SIZE = 24;
    61 // If a chain gets to 32 something might be wrong
    62 // If a chain gets to 100 something might be wrong
    62 const size_t REHASH_LEN = 32;
    63 const size_t REHASH_LEN = 100;
    63 // If we have as many dead items as 50% of the number of bucket
    64 // If we have as many dead items as 50% of the number of bucket
    64 const double CLEAN_DEAD_HIGH_WATER_MARK = 0.5;
    65 const double CLEAN_DEAD_HIGH_WATER_MARK = 0.5;
    65 
    66 
    66 #if INCLUDE_CDS_JAVA_HEAP
    67 #if INCLUDE_CDS_JAVA_HEAP
    67 inline oop read_string_from_compact_hashtable(address base_address, u4 offset) {
    68 inline oop read_string_from_compact_hashtable(address base_address, u4 offset) {
    77 > _shared_table;
    78 > _shared_table;
    78 #endif
    79 #endif
    79 
    80 
    80 // --------------------------------------------------------------------------
    81 // --------------------------------------------------------------------------
    81 
    82 
    82 typedef ConcurrentHashTable<WeakHandle<vm_string_table_data>,
    83 typedef ConcurrentHashTable<StringTableConfig, mtSymbol> StringTableHash;
    83                             StringTableConfig, mtSymbol> StringTableHash;
       
    84 static StringTableHash* _local_table = NULL;
    84 static StringTableHash* _local_table = NULL;
    85 
    85 
    86 volatile bool StringTable::_has_work = false;
    86 volatile bool StringTable::_has_work = false;
    87 volatile bool StringTable::_needs_rehashing = false;
    87 volatile bool StringTable::_needs_rehashing = false;
    88 
    88 
    89 volatile size_t StringTable::_uncleaned_items_count = 0;
    89 volatile size_t StringTable::_uncleaned_items_count = 0;
    90 OopStorage* StringTable::_weak_handles = NULL;
       
    91 
    90 
    92 static size_t _current_size = 0;
    91 static size_t _current_size = 0;
    93 static volatile size_t _items_count = 0;
    92 static volatile size_t _items_count = 0;
    94 
    93 
    95 volatile bool _alt_hash = false;
    94 volatile bool _alt_hash = false;
    99   return  useAlt ?
    98   return  useAlt ?
   100     AltHashing::murmur3_32(murmur_seed, s, len) :
    99     AltHashing::murmur3_32(murmur_seed, s, len) :
   101     java_lang_String::hash_code(s, len);
   100     java_lang_String::hash_code(s, len);
   102 }
   101 }
   103 
   102 
   104 class StringTableConfig : public StringTableHash::BaseConfig {
   103 class StringTableConfig : public StackObj {
   105  private:
   104  private:
   106  public:
   105  public:
   107   static uintx get_hash(WeakHandle<vm_string_table_data> const& value,
   106   typedef WeakHandle<vm_string_table_data> Value;
   108                         bool* is_dead) {
   107 
       
   108   static uintx get_hash(Value const& value, bool* is_dead) {
   109     EXCEPTION_MARK;
   109     EXCEPTION_MARK;
   110     oop val_oop = value.peek();
   110     oop val_oop = value.peek();
   111     if (val_oop == NULL) {
   111     if (val_oop == NULL) {
   112       *is_dead = true;
   112       *is_dead = true;
   113       return 0;
   113       return 0;
   122     }
   122     }
   123     vm_exit_out_of_memory(length, OOM_MALLOC_ERROR, "get hash from oop");
   123     vm_exit_out_of_memory(length, OOM_MALLOC_ERROR, "get hash from oop");
   124     return 0;
   124     return 0;
   125   }
   125   }
   126   // We use default allocation/deallocation but counted
   126   // We use default allocation/deallocation but counted
   127   static void* allocate_node(size_t size,
   127   static void* allocate_node(size_t size, Value const& value) {
   128                              WeakHandle<vm_string_table_data> const& value) {
       
   129     StringTable::item_added();
   128     StringTable::item_added();
   130     return StringTableHash::BaseConfig::allocate_node(size, value);
   129     return AllocateHeap(size, mtSymbol);
   131   }
   130   }
   132   static void free_node(void* memory,
   131   static void free_node(void* memory, Value const& value) {
   133                         WeakHandle<vm_string_table_data> const& value) {
       
   134     value.release();
   132     value.release();
   135     StringTableHash::BaseConfig::free_node(memory, value);
   133     FreeHeap(memory);
   136     StringTable::item_removed();
   134     StringTable::item_removed();
   137   }
   135   }
   138 };
   136 };
   139 
   137 
   140 class StringTableLookupJchar : StackObj {
   138 class StringTableLookupJchar : StackObj {
   206   for (ret = 1; ((size_t)1 << ret) < val; ++ret);
   204   for (ret = 1; ((size_t)1 << ret) < val; ++ret);
   207   return ret;
   205   return ret;
   208 }
   206 }
   209 
   207 
   210 void StringTable::create_table() {
   208 void StringTable::create_table() {
   211   _weak_handles = new OopStorage("StringTable weak",
       
   212                                  StringTableWeakAlloc_lock,
       
   213                                  StringTableWeakActive_lock);
       
   214   size_t start_size_log_2 = ceil_log2(StringTableSize);
   209   size_t start_size_log_2 = ceil_log2(StringTableSize);
   215   _current_size = ((size_t)1) << start_size_log_2;
   210   _current_size = ((size_t)1) << start_size_log_2;
   216   log_trace(stringtable)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")",
   211   log_trace(stringtable)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")",
   217                          _current_size, start_size_log_2);
   212                          _current_size, start_size_log_2);
   218   _local_table = new StringTableHash(start_size_log_2, END_SIZE, REHASH_LEN);
   213   _local_table = new StringTableHash(start_size_log_2, END_SIZE, REHASH_LEN);
   342   }
   337   }
   343   found_string = do_lookup(name, len, hash);
   338   found_string = do_lookup(name, len, hash);
   344   if (found_string != NULL) {
   339   if (found_string != NULL) {
   345     return found_string;
   340     return found_string;
   346   }
   341   }
   347   return do_intern(string_or_null_h, name, len, hash, CHECK_NULL);
   342   return do_intern(string_or_null_h, name, len, hash, THREAD);
   348 }
   343 }
   349 
   344 
   350 oop StringTable::do_intern(Handle string_or_null_h, const jchar* name,
   345 oop StringTable::do_intern(Handle string_or_null_h, const jchar* name,
   351                            int len, uintx hash, TRAPS) {
   346                            int len, uintx hash, TRAPS) {
   352   HandleMark hm(THREAD);  // cleanup strings created
   347   HandleMark hm(THREAD);  // cleanup strings created
   388   } while(true);
   383   } while(true);
   389 }
   384 }
   390 
   385 
   391 void StringTable::oops_do(OopClosure* f) {
   386 void StringTable::oops_do(OopClosure* f) {
   392   assert(f != NULL, "No closure");
   387   assert(f != NULL, "No closure");
   393   _weak_handles->oops_do(f);
   388   OopStorageSet::string_table_weak()->oops_do(f);
   394 }
   389 }
   395 
   390 
   396 // Concurrent work
   391 // Concurrent work
   397 void StringTable::grow(JavaThread* jt) {
   392 void StringTable::grow(JavaThread* jt) {
   398   StringTableHash::GrowTask gt(_local_table);
   393   StringTableHash::GrowTask gt(_local_table);
   494 bool StringTable::do_rehash() {
   489 bool StringTable::do_rehash() {
   495   if (!_local_table->is_safepoint_safe()) {
   490   if (!_local_table->is_safepoint_safe()) {
   496     return false;
   491     return false;
   497   }
   492   }
   498 
   493 
   499   // We use max size
   494   // We use current size, not max size.
   500   StringTableHash* new_table = new StringTableHash(END_SIZE, END_SIZE, REHASH_LEN);
   495   size_t new_size = _local_table->get_size_log2(Thread::current());
       
   496   StringTableHash* new_table = new StringTableHash(new_size, END_SIZE, REHASH_LEN);
   501   // Use alt hash from now on
   497   // Use alt hash from now on
   502   _alt_hash = true;
   498   _alt_hash = true;
   503   if (!_local_table->try_move_nodes_to(Thread::current(), new_table)) {
   499   if (!_local_table->try_move_nodes_to(Thread::current(), new_table)) {
   504     _alt_hash = false;
   500     _alt_hash = false;
   505     delete new_table;
   501     delete new_table;