Mercurial > hg > graal-jvmci-8
comparison src/share/vm/classfile/symbolTable.hpp @ 14303:893ce66f7473
8027476: Improve performance of Stringtable unlink
8027455: Improve symbol table scan times during gc pauses
Summary: Parallelize string table and symbol table scan during remark and full GC. Some additional statistics output if the experimental flag G1TraceStringSymbolTableScrubbing is set.
Reviewed-by: mgerdin, coleenp, brutisso
author | tschatzl |
---|---|
date | Mon, 20 Jan 2014 11:47:07 +0100 |
parents | c90e76575b03 |
children | 4ca6dc0799b6 152cf4afc11f |
comparison
equal
deleted
inserted
replaced
14265:3e2b76368121 | 14303:893ce66f7473 |
---|---|
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 |