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