117 static size_t ceil_log2(size_t value) {
118 size_t ret;
119 for (ret = 1; ((size_t)1 << ret) < value; ++ret);
120 return ret;
121 }
122
123 SymbolTable::SymbolTable() :
124 _symbols_removed(0), _symbols_counted(0), _local_table(NULL),
125 _current_size(0), _has_work(0), _needs_rehashing(false),
126 _items_count(0), _uncleaned_items_count(0) {
127
128 size_t start_size_log_2 = ceil_log2(SymbolTableSize);
129 _current_size = ((size_t)1) << start_size_log_2;
130 log_trace(symboltable)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")",
131 _current_size, start_size_log_2);
132 _local_table = new SymbolTableHash(start_size_log_2, END_SIZE, REHASH_LEN);
133 }
134
135 void SymbolTable::delete_symbol(Symbol* sym) {
136 if (sym->refcount() == PERM_REFCOUNT) {
137 MutexLocker ml(SymbolTable_lock); // Protect arena
138 // Deleting permanent symbol should not occur very often (insert race condition),
139 // so log it.
140 log_trace_symboltable_helper(sym, "Freeing permanent symbol");
141 if (!arena()->Afree(sym, sym->size())) {
142 log_trace_symboltable_helper(sym, "Leaked permanent symbol");
143 }
144 } else {
145 delete sym;
146 }
147 }
148
149 void SymbolTable::item_added() {
150 Atomic::inc(&(SymbolTable::the_table()->_items_count));
151 }
152
153 void SymbolTable::set_item_clean_count(size_t ncl) {
154 Atomic::store(ncl, &(SymbolTable::the_table()->_uncleaned_items_count));
155 log_trace(symboltable)("Set uncleaned items:" SIZE_FORMAT, SymbolTable::the_table()->_uncleaned_items_count);
156 }
157
180
181 void SymbolTable::trigger_concurrent_work() {
182 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
183 SymbolTable::the_table()->_has_work = true;
184 Service_lock->notify_all();
185 }
186
187 Symbol* SymbolTable::allocate_symbol(const char* name, int len, bool c_heap, TRAPS) {
188 assert (len <= Symbol::max_length(), "should be checked by caller");
189
190 Symbol* sym;
191 if (DumpSharedSpaces) {
192 c_heap = false;
193 }
194 if (c_heap) {
195 // refcount starts as 1
196 sym = new (len, THREAD) Symbol((const u1*)name, len, 1);
197 assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
198 } else {
199 // Allocate to global arena
200 MutexLocker ml(SymbolTable_lock); // Protect arena
201 sym = new (len, arena(), THREAD) Symbol((const u1*)name, len, PERM_REFCOUNT);
202 }
203 return sym;
204 }
205
206 void SymbolTable::initialize_symbols(int arena_alloc_size) {
207 // Initialize the arena for global symbols, size passed in depends on CDS.
208 if (arena_alloc_size == 0) {
209 _arena = new (mtSymbol) Arena(mtSymbol);
210 } else {
211 _arena = new (mtSymbol) Arena(mtSymbol, arena_alloc_size);
212 }
213 }
214
215 class SymbolsDo : StackObj {
216 SymbolClosure *_cl;
217 public:
218 SymbolsDo(SymbolClosure *cl) : _cl(cl) {}
219 bool operator()(Symbol** value) {
220 assert(value != NULL, "expected valid value");
|
117 static size_t ceil_log2(size_t value) {
118 size_t ret;
119 for (ret = 1; ((size_t)1 << ret) < value; ++ret);
120 return ret;
121 }
122
123 SymbolTable::SymbolTable() :
124 _symbols_removed(0), _symbols_counted(0), _local_table(NULL),
125 _current_size(0), _has_work(0), _needs_rehashing(false),
126 _items_count(0), _uncleaned_items_count(0) {
127
128 size_t start_size_log_2 = ceil_log2(SymbolTableSize);
129 _current_size = ((size_t)1) << start_size_log_2;
130 log_trace(symboltable)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")",
131 _current_size, start_size_log_2);
132 _local_table = new SymbolTableHash(start_size_log_2, END_SIZE, REHASH_LEN);
133 }
134
135 void SymbolTable::delete_symbol(Symbol* sym) {
136 if (sym->refcount() == PERM_REFCOUNT) {
137 MutexLockerEx ml(SymbolArena_lock, Mutex::_no_safepoint_check_flag); // Protect arena
138 // Deleting permanent symbol should not occur very often (insert race condition),
139 // so log it.
140 log_trace_symboltable_helper(sym, "Freeing permanent symbol");
141 if (!arena()->Afree(sym, sym->size())) {
142 log_trace_symboltable_helper(sym, "Leaked permanent symbol");
143 }
144 } else {
145 delete sym;
146 }
147 }
148
149 void SymbolTable::item_added() {
150 Atomic::inc(&(SymbolTable::the_table()->_items_count));
151 }
152
153 void SymbolTable::set_item_clean_count(size_t ncl) {
154 Atomic::store(ncl, &(SymbolTable::the_table()->_uncleaned_items_count));
155 log_trace(symboltable)("Set uncleaned items:" SIZE_FORMAT, SymbolTable::the_table()->_uncleaned_items_count);
156 }
157
180
181 void SymbolTable::trigger_concurrent_work() {
182 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
183 SymbolTable::the_table()->_has_work = true;
184 Service_lock->notify_all();
185 }
186
187 Symbol* SymbolTable::allocate_symbol(const char* name, int len, bool c_heap, TRAPS) {
188 assert (len <= Symbol::max_length(), "should be checked by caller");
189
190 Symbol* sym;
191 if (DumpSharedSpaces) {
192 c_heap = false;
193 }
194 if (c_heap) {
195 // refcount starts as 1
196 sym = new (len, THREAD) Symbol((const u1*)name, len, 1);
197 assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
198 } else {
199 // Allocate to global arena
200 MutexLockerEx ml(SymbolArena_lock, Mutex::_no_safepoint_check_flag); // Protect arena
201 sym = new (len, arena(), THREAD) Symbol((const u1*)name, len, PERM_REFCOUNT);
202 }
203 return sym;
204 }
205
206 void SymbolTable::initialize_symbols(int arena_alloc_size) {
207 // Initialize the arena for global symbols, size passed in depends on CDS.
208 if (arena_alloc_size == 0) {
209 _arena = new (mtSymbol) Arena(mtSymbol);
210 } else {
211 _arena = new (mtSymbol) Arena(mtSymbol, arena_alloc_size);
212 }
213 }
214
215 class SymbolsDo : StackObj {
216 SymbolClosure *_cl;
217 public:
218 SymbolsDo(SymbolClosure *cl) : _cl(cl) {}
219 bool operator()(Symbol** value) {
220 assert(value != NULL, "expected valid value");
|