159 for (ret = 1; ((size_t)1 << ret) < value; ++ret); 160 return ret; 161 } 162 163 void SymbolTable::create_table () { 164 size_t start_size_log_2 = ceil_log2(SymbolTableSize); 165 _current_size = ((size_t)1) << start_size_log_2; 166 log_trace(symboltable)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")", 167 _current_size, start_size_log_2); 168 _local_table = new SymbolTableHash(start_size_log_2, END_SIZE, REHASH_LEN); 169 170 // Initialize the arena for global symbols, size passed in depends on CDS. 171 if (symbol_alloc_arena_size == 0) { 172 _arena = new (mtSymbol) Arena(mtSymbol); 173 } else { 174 _arena = new (mtSymbol) Arena(mtSymbol, symbol_alloc_arena_size); 175 } 176 } 177 178 void SymbolTable::delete_symbol(Symbol* sym) { 179 if (sym->is_permanent()) { 180 MutexLocker ml(SymbolArena_lock, Mutex::_no_safepoint_check_flag); // Protect arena 181 // Deleting permanent symbol should not occur very often (insert race condition), 182 // so log it. 183 log_trace_symboltable_helper(sym, "Freeing permanent symbol"); 184 if (!arena()->Afree(sym, sym->size())) { 185 log_trace_symboltable_helper(sym, "Leaked permanent symbol"); 186 } 187 } else { 188 delete sym; 189 } 190 } 191 192 void SymbolTable::reset_has_items_to_clean() { Atomic::store(&_has_items_to_clean, false); } 193 void SymbolTable::mark_has_items_to_clean() { Atomic::store(&_has_items_to_clean, true); } 194 bool SymbolTable::has_items_to_clean() { return Atomic::load(&_has_items_to_clean); } 195 196 void SymbolTable::item_added() { 197 Atomic::inc(&_items_count); 198 } 204 205 double SymbolTable::get_load_factor() { 206 return (double)_items_count/_current_size; 207 } 208 209 size_t SymbolTable::table_size() { 210 return ((size_t)1) << _local_table->get_size_log2(Thread::current()); 211 } 212 213 void SymbolTable::trigger_cleanup() { 214 MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag); 215 _has_work = true; 216 Service_lock->notify_all(); 217 } 218 219 Symbol* SymbolTable::allocate_symbol(const char* name, int len, bool c_heap) { 220 assert (len <= Symbol::max_length(), "should be checked by caller"); 221 222 Symbol* sym; 223 if (Arguments::is_dumping_archive()) { 224 c_heap = false; 225 } 226 if (c_heap) { 227 // refcount starts as 1 228 sym = new (len) Symbol((const u1*)name, len, 1); 229 assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted"); 230 } else { 231 // Allocate to global arena 232 MutexLocker ml(SymbolArena_lock, Mutex::_no_safepoint_check_flag); // Protect arena 233 sym = new (len, arena()) Symbol((const u1*)name, len, PERM_REFCOUNT); 234 } 235 return sym; 236 } 237 238 class SymbolsDo : StackObj { 239 SymbolClosure *_cl; 240 public: 241 SymbolsDo(SymbolClosure *cl) : _cl(cl) {} 242 bool operator()(Symbol** value) { 243 assert(value != NULL, "expected valid value"); 244 assert(*value != NULL, "value should point to a symbol"); 245 _cl->do_symbol(value); 246 return true; 247 }; 248 }; 249 | 159 for (ret = 1; ((size_t)1 << ret) < value; ++ret); 160 return ret; 161 } 162 163 void SymbolTable::create_table () { 164 size_t start_size_log_2 = ceil_log2(SymbolTableSize); 165 _current_size = ((size_t)1) << start_size_log_2; 166 log_trace(symboltable)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")", 167 _current_size, start_size_log_2); 168 _local_table = new SymbolTableHash(start_size_log_2, END_SIZE, REHASH_LEN); 169 170 // Initialize the arena for global symbols, size passed in depends on CDS. 171 if (symbol_alloc_arena_size == 0) { 172 _arena = new (mtSymbol) Arena(mtSymbol); 173 } else { 174 _arena = new (mtSymbol) Arena(mtSymbol, symbol_alloc_arena_size); 175 } 176 } 177 178 void SymbolTable::delete_symbol(Symbol* sym) { 179 if (Arguments::is_dumping_archive()) { 180 // Do not delete symbols as we may be in the middle of preparing the 181 // symbols for dumping. 182 return; 183 } 184 if (sym->is_permanent()) { 185 MutexLocker ml(SymbolArena_lock, Mutex::_no_safepoint_check_flag); // Protect arena 186 // Deleting permanent symbol should not occur very often (insert race condition), 187 // so log it. 188 log_trace_symboltable_helper(sym, "Freeing permanent symbol"); 189 if (!arena()->Afree(sym, sym->size())) { 190 log_trace_symboltable_helper(sym, "Leaked permanent symbol"); 191 } 192 } else { 193 delete sym; 194 } 195 } 196 197 void SymbolTable::reset_has_items_to_clean() { Atomic::store(&_has_items_to_clean, false); } 198 void SymbolTable::mark_has_items_to_clean() { Atomic::store(&_has_items_to_clean, true); } 199 bool SymbolTable::has_items_to_clean() { return Atomic::load(&_has_items_to_clean); } 200 201 void SymbolTable::item_added() { 202 Atomic::inc(&_items_count); 203 } 209 210 double SymbolTable::get_load_factor() { 211 return (double)_items_count/_current_size; 212 } 213 214 size_t SymbolTable::table_size() { 215 return ((size_t)1) << _local_table->get_size_log2(Thread::current()); 216 } 217 218 void SymbolTable::trigger_cleanup() { 219 MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag); 220 _has_work = true; 221 Service_lock->notify_all(); 222 } 223 224 Symbol* SymbolTable::allocate_symbol(const char* name, int len, bool c_heap) { 225 assert (len <= Symbol::max_length(), "should be checked by caller"); 226 227 Symbol* sym; 228 if (Arguments::is_dumping_archive()) { 229 // Need to make all symbols permanent -- or else some symbols may be GC'ed 230 // during the archive dumping code that's executed outside of a safepoint. 231 c_heap = false; 232 } 233 if (c_heap) { 234 // refcount starts as 1 235 sym = new (len) Symbol((const u1*)name, len, 1); 236 assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted"); 237 } else if (DumpSharedSpaces) { 238 // See comments inside Symbol::operator new(size_t, int) 239 sym = new (len) Symbol((const u1*)name, len, PERM_REFCOUNT); 240 assert(sym != NULL, "new should call vm_exit_out_of_memory if failed to allocate symbol during DumpSharedSpaces"); 241 } else { 242 // Allocate to global arena 243 MutexLocker ml(SymbolArena_lock, Mutex::_no_safepoint_check_flag); // Protect arena 244 sym = new (len, arena()) Symbol((const u1*)name, len, PERM_REFCOUNT); 245 } 246 return sym; 247 } 248 249 class SymbolsDo : StackObj { 250 SymbolClosure *_cl; 251 public: 252 SymbolsDo(SymbolClosure *cl) : _cl(cl) {} 253 bool operator()(Symbol** value) { 254 assert(value != NULL, "expected valid value"); 255 assert(*value != NULL, "value should point to a symbol"); 256 _cl->do_symbol(value); 257 return true; 258 }; 259 }; 260 |