src/share/vm/classfile/symbolTable.cpp

Print this page
rev 4551 : 8015237: Parallelize string table scanning during strong root processing
Summary: Parallelize the scanning of the intern string table by having each GC worker claim a given number of buckets. Changes were also reviewed by Per Liden <per.liden@oracle.com>.
Reviewed-by: tschatzl, stefank, twisti

*** 608,617 **** --- 608,619 ---- // -------------------------------------------------------------------------- StringTable* StringTable::_the_table = NULL; bool StringTable::_needs_rehashing = false; + volatile int StringTable::_parallel_claimed_idx = 0; + // Pick hashing algorithm unsigned int StringTable::hash_string(const jchar* s, int len) { return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) : java_lang_String::to_hash(s, len); }
*** 769,780 **** entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p); } } } ! void StringTable::oops_do(OopClosure* f) { ! for (int i = 0; i < the_table()->table_size(); ++i) { HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i); HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i); while (entry != NULL) { f->do_oop((oop*)entry->literal_addr()); --- 771,792 ---- entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p); } } } ! void StringTable::buckets_do(OopClosure* f, int start_idx, int end_idx) { ! const int limit = the_table()->table_size(); ! ! assert(0 <= start_idx && start_idx <= limit, ! err_msg("start_idx (" INT32_FORMAT ") oob?", start_idx)); ! assert(0 <= end_idx && end_idx <= limit, ! err_msg("end_idx (" INT32_FORMAT ") oob?", end_idx)); ! assert(start_idx <= end_idx, ! err_msg("Ordering: start_idx=" INT32_FORMAT", end_idx=" INT32_FORMAT, ! start_idx, end_idx)); ! ! for (int i = start_idx; i < end_idx; i += 1) { HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i); HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i); while (entry != NULL) { f->do_oop((oop*)entry->literal_addr());
*** 789,798 **** --- 801,831 ---- entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p); } } } + void StringTable::oops_do(OopClosure* f) { + buckets_do(f, 0, the_table()->table_size()); + } + + void StringTable::possibly_parallel_oops_do(OopClosure* f) { + const int ClaimChunkSize = 32; + const int limit = the_table()->table_size(); + + for (;;) { + // Grab next set of buckets to scan + int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize; + if (start_idx >= limit) { + // End of table + break; + } + + int end_idx = MIN2(limit, start_idx + ClaimChunkSize); + buckets_do(f, start_idx, end_idx); + } + } + void StringTable::verify() { for (int i = 0; i < the_table()->table_size(); ++i) { HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i); for ( ; p != NULL; p = p->next()) { oop s = p->literal();