--- old/src/share/vm/classfile/symbolTable.cpp 2020-05-20 17:59:29.708155879 +0200 +++ new/src/share/vm/classfile/symbolTable.cpp 2020-05-20 17:59:29.560154420 +0200 @@ -721,7 +721,7 @@ // considered dead. The SATB part of G1 needs to get notified about this // potential resurrection, otherwise the marking might not find the object. #if INCLUDE_ALL_GCS - if ((UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) && string != NULL) { + if ((UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) && string != NULL) { G1SATBCardTableModRefBS::enqueue(string); } #endif @@ -925,6 +925,28 @@ buckets_oops_do(f, start_idx, end_idx); } } + +void StringTable::possibly_parallel_oops_do_shenandoah(OopClosure* f) { + const int limit = the_table()->table_size(); + + // ClaimChunkSize is too small for processing a String table during the pause + // efficiently: the atomic add costs dominate on many reasonable string tables. + // Recast the chunk size to give each GC worker about 10 chunks. + assert(UseShenandoahGC, "Only for Shenandoah"); + const int chunk_size = MAX2<int>(ClaimChunkSize, limit / (ParallelGCThreads * 10)); + + for (;;) { + // Grab next set of buckets to scan + int start_idx = Atomic::add(chunk_size, &_parallel_claimed_idx) - chunk_size; + if (start_idx >= limit) { + // End of table + break; + } + + int end_idx = MIN2(limit, start_idx + chunk_size); + buckets_oops_do(f, start_idx, end_idx); + } +} // This verification is part of Universe::verify() and needs to be quick. // See StringTable::verify_and_compare() below for exhaustive verification.