@@ -1479,19 +1479,20 @@ class ShenandoahParallelHeapRegionTask : public WorkerTask {
14791479private:
14801480 ShenandoahHeap* const _heap;
14811481 ShenandoahHeapRegionClosure* const _blk;
1482+ size_t const _stride;
14821483
14831484 shenandoah_padding (0 );
14841485 volatile size_t _index;
14851486 shenandoah_padding (1 );
14861487
14871488public:
1488- ShenandoahParallelHeapRegionTask (ShenandoahHeapRegionClosure* blk) :
1489+ ShenandoahParallelHeapRegionTask (ShenandoahHeapRegionClosure* blk, size_t stride ) :
14891490 WorkerTask (" Shenandoah Parallel Region Operation" ),
1490- _heap (ShenandoahHeap::heap()), _blk(blk), _index(0 ) {}
1491+ _heap (ShenandoahHeap::heap()), _blk(blk), _stride(stride), _index(0 ) {}
14911492
14921493 void work (uint worker_id) {
14931494 ShenandoahParallelWorkerSession worker_session (worker_id);
1494- size_t stride = ShenandoahParallelRegionStride ;
1495+ size_t stride = _stride ;
14951496
14961497 size_t max = _heap->num_regions ();
14971498 while (Atomic::load (&_index) < max) {
@@ -1510,8 +1511,20 @@ class ShenandoahParallelHeapRegionTask : public WorkerTask {
15101511
15111512void ShenandoahHeap::parallel_heap_region_iterate (ShenandoahHeapRegionClosure* blk) const {
15121513 assert (blk->is_thread_safe (), " Only thread-safe closures here" );
1513- if (num_regions () > ShenandoahParallelRegionStride) {
1514- ShenandoahParallelHeapRegionTask task (blk);
1514+ const uint active_workers = workers ()->active_workers ();
1515+ const size_t n_regions = num_regions ();
1516+ size_t stride = ShenandoahParallelRegionStride;
1517+ if (stride == 0 && active_workers > 1 ) {
1518+ // Automatically derive the stride to balance the work between threads
1519+ // evenly. Do not try to split work if below the reasonable threshold.
1520+ constexpr size_t threshold = 4096 ;
1521+ stride = n_regions <= threshold ?
1522+ threshold :
1523+ (n_regions + active_workers - 1 ) / active_workers;
1524+ }
1525+
1526+ if (n_regions > stride && active_workers > 1 ) {
1527+ ShenandoahParallelHeapRegionTask task (blk, stride);
15151528 workers ()->run_task (&task);
15161529 } else {
15171530 heap_region_iterate (blk);
0 commit comments