src/share/vm/classfile/symbolTable.cpp
Print this page
rev 4735 : 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.
Reviewed-by:
*** 596,605 ****
--- 596,607 ----
// --------------------------------------------------------------------------
StringTable* StringTable::_the_table = NULL;
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) :
java_lang_String::hash_code(s, len);
}
*** 782,791 ****
--- 784,830 ----
entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p);
}
}
}
+ 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<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());
+
+ // 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<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p);
+ }
+ }
+ }
+ }
+
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();