--- old/src/share/vm/classfile/symbolTable.cpp 2020-05-19 11:21:23.590525147 +0200 +++ new/src/share/vm/classfile/symbolTable.cpp 2020-05-19 11:21:23.510525171 +0200 @@ -926,6 +926,28 @@ } } +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 = 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. void StringTable::verify() { --- old/src/share/vm/classfile/symbolTable.hpp 2020-05-19 11:21:24.090525000 +0200 +++ new/src/share/vm/classfile/symbolTable.hpp 2020-05-19 11:21:24.006525025 +0200 @@ -328,6 +328,7 @@ possibly_parallel_unlink_or_oops_do(cl, NULL, processed, removed); } static void possibly_parallel_oops_do(OopClosure* f); + static void possibly_parallel_oops_do_shenandoah(OopClosure* f); // Hashing algorithm, used as the hash value used by the // StringTable for bucket selection and comparison (stored in the --- old/src/share/vm/gc_implementation/shenandoah/shenandoahRootProcessor.cpp 2020-05-19 11:21:24.586524855 +0200 +++ new/src/share/vm/gc_implementation/shenandoah/shenandoahRootProcessor.cpp 2020-05-19 11:21:24.502524880 +0200 @@ -103,7 +103,7 @@ void ShenandoahStringTableRoots::oops_do(OopClosure* oops, uint worker_id) { ShenandoahWorkerTimingsTracker timer(_phase, ShenandoahPhaseTimings::StringTableRoots, worker_id); - StringTable::possibly_parallel_oops_do(oops); + StringTable::possibly_parallel_oops_do_shenandoah(oops); } ShenandoahThreadRoots::ShenandoahThreadRoots(ShenandoahPhaseTimings::Phase phase) :