84 |
84 |
85 // Set if one bucket is out of balance due to hash algorithm deficiency |
85 // Set if one bucket is out of balance due to hash algorithm deficiency |
86 static bool _needs_rehashing; |
86 static bool _needs_rehashing; |
87 |
87 |
88 // For statistics |
88 // For statistics |
89 static int symbols_removed; |
89 static int _symbols_removed; |
90 static int symbols_counted; |
90 static int _symbols_counted; |
91 |
91 |
92 Symbol* allocate_symbol(const u1* name, int len, bool c_heap, TRAPS); // Assumes no characters larger than 0x7F |
92 Symbol* allocate_symbol(const u1* name, int len, bool c_heap, TRAPS); // Assumes no characters larger than 0x7F |
93 |
93 |
94 // Adding elements |
94 // Adding elements |
95 Symbol* basic_add(int index, u1* name, int len, unsigned int hashValue, |
95 Symbol* basic_add(int index, u1* name, int len, unsigned int hashValue, |
119 // Arena for permanent symbols (null class loader) that are never unloaded |
119 // Arena for permanent symbols (null class loader) that are never unloaded |
120 static Arena* _arena; |
120 static Arena* _arena; |
121 static Arena* arena() { return _arena; } // called for statistics |
121 static Arena* arena() { return _arena; } // called for statistics |
122 |
122 |
123 static void initialize_symbols(int arena_alloc_size = 0); |
123 static void initialize_symbols(int arena_alloc_size = 0); |
|
124 |
|
125 static volatile int _parallel_claimed_idx; |
|
126 |
|
127 // Release any dead symbols |
|
128 static void buckets_unlink(int start_idx, int end_idx, int* processed, int* removed, size_t* memory_total); |
124 public: |
129 public: |
125 enum { |
130 enum { |
126 symbol_alloc_batch_size = 8, |
131 symbol_alloc_batch_size = 8, |
127 // Pick initial size based on java -version size measurements |
132 // Pick initial size based on java -version size measurements |
128 symbol_alloc_arena_size = 360*K |
133 symbol_alloc_arena_size = 360*K |
175 constantPoolHandle cp, int names_count, |
180 constantPoolHandle cp, int names_count, |
176 const char** names, int* lengths, int* cp_indices, |
181 const char** names, int* lengths, int* cp_indices, |
177 unsigned int* hashValues, TRAPS); |
182 unsigned int* hashValues, TRAPS); |
178 |
183 |
179 // Release any dead symbols |
184 // Release any dead symbols |
180 static void unlink(); |
185 static void unlink() { |
|
186 int processed = 0; |
|
187 int removed = 0; |
|
188 unlink(&processed, &removed); |
|
189 } |
|
190 static void unlink(int* processed, int* removed); |
|
191 // Release any dead symbols, possibly parallel version |
|
192 static void possibly_parallel_unlink(int* processed, int* removed); |
181 |
193 |
182 // iterate over symbols |
194 // iterate over symbols |
183 static void symbols_do(SymbolClosure *cl); |
195 static void symbols_do(SymbolClosure *cl); |
184 |
196 |
185 // Symbol creation |
197 // Symbol creation |
233 } |
245 } |
234 |
246 |
235 // Rehash the symbol table if it gets out of balance |
247 // Rehash the symbol table if it gets out of balance |
236 static void rehash_table(); |
248 static void rehash_table(); |
237 static bool needs_rehashing() { return _needs_rehashing; } |
249 static bool needs_rehashing() { return _needs_rehashing; } |
|
250 // Parallel chunked scanning |
|
251 static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; } |
|
252 static int parallel_claimed_index() { return _parallel_claimed_idx; } |
238 }; |
253 }; |
239 |
254 |
240 class StringTable : public Hashtable<oop, mtSymbol> { |
255 class StringTable : public Hashtable<oop, mtSymbol> { |
241 friend class VMStructs; |
256 friend class VMStructs; |
242 |
257 |
256 |
271 |
257 oop lookup(int index, jchar* chars, int length, unsigned int hashValue); |
272 oop lookup(int index, jchar* chars, int length, unsigned int hashValue); |
258 |
273 |
259 // Apply the give oop closure to the entries to the buckets |
274 // Apply the give oop closure to the entries to the buckets |
260 // in the range [start_idx, end_idx). |
275 // in the range [start_idx, end_idx). |
261 static void buckets_do(OopClosure* f, int start_idx, int end_idx); |
276 static void buckets_oops_do(OopClosure* f, int start_idx, int end_idx); |
|
277 // Unlink or apply the give oop closure to the entries to the buckets |
|
278 // in the range [start_idx, end_idx). |
|
279 static void buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed); |
262 |
280 |
263 StringTable() : Hashtable<oop, mtSymbol>((int)StringTableSize, |
281 StringTable() : Hashtable<oop, mtSymbol>((int)StringTableSize, |
264 sizeof (HashtableEntry<oop, mtSymbol>)) {} |
282 sizeof (HashtableEntry<oop, mtSymbol>)) {} |
265 |
283 |
266 StringTable(HashtableBucket<mtSymbol>* t, int number_of_entries) |
284 StringTable(HashtableBucket<mtSymbol>* t, int number_of_entries) |
278 _the_table = new StringTable(); |
296 _the_table = new StringTable(); |
279 } |
297 } |
280 |
298 |
281 // GC support |
299 // GC support |
282 // Delete pointers to otherwise-unreachable objects. |
300 // Delete pointers to otherwise-unreachable objects. |
283 static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f); |
301 static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f) { |
|
302 int processed = 0; |
|
303 int removed = 0; |
|
304 unlink_or_oops_do(cl, f, &processed, &removed); |
|
305 } |
284 static void unlink(BoolObjectClosure* cl) { |
306 static void unlink(BoolObjectClosure* cl) { |
285 unlink_or_oops_do(cl, NULL); |
307 int processed = 0; |
286 } |
308 int removed = 0; |
287 |
309 unlink_or_oops_do(cl, NULL, &processed, &removed); |
|
310 } |
|
311 static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed); |
|
312 static void unlink(BoolObjectClosure* cl, int* processed, int* removed) { |
|
313 unlink_or_oops_do(cl, NULL, processed, removed); |
|
314 } |
288 // Serially invoke "f->do_oop" on the locations of all oops in the table. |
315 // Serially invoke "f->do_oop" on the locations of all oops in the table. |
289 static void oops_do(OopClosure* f); |
316 static void oops_do(OopClosure* f); |
290 |
317 |
291 // Possibly parallel version of the above |
318 // Possibly parallel versions of the above |
|
319 static void possibly_parallel_unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed); |
|
320 static void possibly_parallel_unlink(BoolObjectClosure* cl, int* processed, int* removed) { |
|
321 possibly_parallel_unlink_or_oops_do(cl, NULL, processed, removed); |
|
322 } |
292 static void possibly_parallel_oops_do(OopClosure* f); |
323 static void possibly_parallel_oops_do(OopClosure* f); |
293 |
324 |
294 // Hashing algorithm, used as the hash value used by the |
325 // Hashing algorithm, used as the hash value used by the |
295 // StringTable for bucket selection and comparison (stored in the |
326 // StringTable for bucket selection and comparison (stored in the |
296 // HashtableEntry structures). This is used in the String.intern() method. |
327 // HashtableEntry structures). This is used in the String.intern() method. |
347 static void rehash_table(); |
378 static void rehash_table(); |
348 static bool needs_rehashing() { return _needs_rehashing; } |
379 static bool needs_rehashing() { return _needs_rehashing; } |
349 |
380 |
350 // Parallel chunked scanning |
381 // Parallel chunked scanning |
351 static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; } |
382 static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; } |
|
383 static int parallel_claimed_index() { return _parallel_claimed_idx; } |
352 }; |
384 }; |
353 #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP |
385 #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP |