@@ -669,6 +669,7 @@ void ShenandoahRegionPartitions::assert_bounds() {
669669ShenandoahFreeSet::ShenandoahFreeSet (ShenandoahHeap* heap, size_t max_regions) :
670670 _heap(heap),
671671 _partitions(max_regions, this ),
672+ _trash_regions(NEW_C_HEAP_ARRAY(ShenandoahHeapRegion*, max_regions, mtGC)),
672673 _alloc_bias_weight(0 )
673674{
674675 clear_internal ();
@@ -1217,7 +1218,7 @@ HeapWord* ShenandoahFreeSet::allocate_contiguous(ShenandoahAllocRequest& req) {
12171218 return _heap->get_region (beg)->bottom ();
12181219}
12191220
1220- void ShenandoahFreeSet::try_recycle_trashed (ShenandoahHeapRegion * r) {
1221+ void ShenandoahFreeSet::try_recycle_trashed (ShenandoahHeapRegion* r) {
12211222 if (r->is_trash ()) {
12221223 r->recycle ();
12231224 }
@@ -1226,13 +1227,24 @@ void ShenandoahFreeSet::try_recycle_trashed(ShenandoahHeapRegion *r) {
12261227void ShenandoahFreeSet::recycle_trash () {
12271228 // lock is not reentrable, check we don't have it
12281229 shenandoah_assert_not_heaplocked ();
1230+ size_t count = 0 ;
12291231 for (size_t i = 0 ; i < _heap->num_regions (); i++) {
12301232 ShenandoahHeapRegion* r = _heap->get_region (i);
12311233 if (r->is_trash ()) {
1232- ShenandoahHeapLocker locker (_heap->lock ());
1233- try_recycle_trashed (r);
1234+ _trash_regions[count++] = r;
1235+ }
1236+ }
1237+
1238+ // Relinquish the lock after this much time passed.
1239+ static constexpr jlong deadline_ns = 30000 ; // 30 us
1240+ size_t idx = 0 ;
1241+ while (idx < count) {
1242+ os::naked_yield (); // Yield to allow allocators to take the lock
1243+ ShenandoahHeapLocker locker (_heap->lock ());
1244+ const jlong deadline = os::javaTimeNanos () + deadline_ns;
1245+ while (idx < count && os::javaTimeNanos () < deadline) {
1246+ try_recycle_trashed (_trash_regions[idx++]);
12341247 }
1235- SpinPause (); // allow allocators to take the lock
12361248 }
12371249}
12381250
0 commit comments