--- old/src/share/vm/classfile/symbolTable.cpp 2013-05-24 14:55:44.647055530 -0700 +++ new/src/share/vm/classfile/symbolTable.cpp 2013-05-24 14:55:44.437909787 -0700 @@ -598,6 +598,8 @@ bool StringTable::_needs_rehashing = false; +volatile uint StringTable::_par_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) : @@ -784,6 +786,43 @@ } } +void StringTable::possibly_parallel_oops_do(OopClosure* f, uint worker_id) { + const uint ClaimChunkSize = 20; + const uint limit = the_table()->table_size(); + + for (;;) { + // Grab next set of buckets to scan + uint start_idx = (uint) Atomic::add((jint)ClaimChunkSize, + (volatile jint*)&_par_claimed_idx) - ClaimChunkSize; + if (start_idx >= limit) { + // End of table + break; + } + + uint end_idx = MIN2(limit, start_idx + ClaimChunkSize); + //gclog_or_tty->print_cr("[%u] Claimed [%d, %d)", worker_id, start_idx, end_idx); + + for (uint i = start_idx; i < end_idx; i += 1) { + HashtableEntry** p = the_table()->bucket_addr(i); + HashtableEntry* entry = the_table()->bucket(i); + + while (entry != NULL) { + f->do_oop((oop*)entry->literal_addr()); + + // Did the closure remove the literal from the table? + if (entry->literal() == NULL) { + assert(!entry->is_shared(), "immutable hashtable entry?"); + *p = entry->next(); + the_table()->free_entry(entry); + } else { + p = entry->next_addr(); + } + entry = (HashtableEntry*)HashtableEntry::make_ptr(*p); + } + } + } +} + void StringTable::verify() { for (int i = 0; i < the_table()->table_size(); ++i) { HashtableEntry* p = the_table()->bucket(i);