35
35
#include " gc/shenandoah/shenandoahPacer.inline.hpp"
36
36
#include " gc/shenandoah/shenandoahUtils.hpp"
37
37
#include " gc/shenandoah/heuristics/shenandoahHeuristics.hpp"
38
+ #include " gc/shenandoah/mode/shenandoahMode.hpp"
39
+ #include " logging/log.hpp"
38
40
#include " memory/metaspaceUtils.hpp"
39
41
#include " memory/metaspaceStats.hpp"
40
- #include " memory/resourceArea.hpp"
41
- #include " runtime/atomic.hpp"
42
42
43
43
ShenandoahControlThread::ShenandoahControlThread () :
44
- ConcurrentGCThread(),
45
- _alloc_failure_waiters_lock(Mutex::safepoint-2 , " ShenandoahAllocFailureGC_lock" , true ),
46
- _gc_waiters_lock(Mutex::safepoint-2 , " ShenandoahRequestedGC_lock" , true ),
44
+ ShenandoahController(),
47
45
_requested_gc_cause(GCCause::_no_cause_specified),
48
- _degen_point(ShenandoahGC::_degenerated_outside_cycle),
49
- _allocs_seen(0 ) {
46
+ _degen_point(ShenandoahGC::_degenerated_outside_cycle) {
50
47
set_name (" Shenandoah Control Thread" );
51
- reset_gc_id ();
52
48
create_and_start ();
53
49
}
54
50
55
51
void ShenandoahControlThread::run_service () {
56
- ShenandoahHeap* heap = ShenandoahHeap::heap ();
52
+ ShenandoahHeap* const heap = ShenandoahHeap::heap ();
57
53
58
54
const GCMode default_mode = concurrent_normal;
59
55
const GCCause::Cause default_cause = GCCause::_shenandoah_concurrent_gc;
@@ -77,7 +73,7 @@ void ShenandoahControlThread::run_service() {
77
73
const GCCause::Cause requested_gc_cause = _requested_gc_cause;
78
74
79
75
// This control loop iteration has seen this much allocation.
80
- const size_t allocs_seen = Atomic::xchg (&_allocs_seen, ( size_t ) 0 , memory_order_relaxed );
76
+ const size_t allocs_seen = reset_allocs_seen ( );
81
77
82
78
// Check if we have seen a new target for soft max heap size.
83
79
const bool soft_max_changed = heap->check_soft_max_changed ();
@@ -106,7 +102,6 @@ void ShenandoahControlThread::run_service() {
106
102
policy->record_alloc_failure_to_full ();
107
103
mode = stw_full;
108
104
}
109
-
110
105
} else if (is_gc_requested) {
111
106
cause = requested_gc_cause;
112
107
log_info (gc)(" Trigger: GC request (%s)" , GCCause::to_string (cause));
@@ -239,7 +234,7 @@ void ShenandoahControlThread::run_service() {
239
234
heap->pacer ()->setup_for_idle ();
240
235
}
241
236
} else {
242
- // Allow allocators to know we have seen this much regions
237
+ // Report to pacer that we have seen this many words allocated
243
238
if (ShenandoahPacing && (allocs_seen > 0 )) {
244
239
heap->pacer ()->report_alloc (allocs_seen);
245
240
}
@@ -407,88 +402,8 @@ void ShenandoahControlThread::handle_requested_gc(GCCause::Cause cause) {
407
402
}
408
403
}
409
404
410
- void ShenandoahControlThread::handle_alloc_failure (ShenandoahAllocRequest& req, bool block) {
411
- ShenandoahHeap* heap = ShenandoahHeap::heap ();
412
-
413
- assert (current ()->is_Java_thread (), " expect Java thread here" );
414
-
415
- if (try_set_alloc_failure_gc ()) {
416
- // Only report the first allocation failure
417
- log_info (gc)(" Failed to allocate %s, " SIZE_FORMAT " %s" ,
418
- req.type_string (),
419
- byte_size_in_proper_unit (req.size () * HeapWordSize), proper_unit_for_byte_size (req.size () * HeapWordSize));
420
-
421
- // Now that alloc failure GC is scheduled, we can abort everything else
422
- heap->cancel_gc (GCCause::_allocation_failure);
423
- }
424
-
425
-
426
- if (block) {
427
- MonitorLocker ml (&_alloc_failure_waiters_lock);
428
- while (is_alloc_failure_gc ()) {
429
- ml.wait ();
430
- }
431
- }
432
- }
433
-
434
- void ShenandoahControlThread::handle_alloc_failure_evac (size_t words) {
435
- ShenandoahHeap* heap = ShenandoahHeap::heap ();
436
-
437
- if (try_set_alloc_failure_gc ()) {
438
- // Only report the first allocation failure
439
- log_info (gc)(" Failed to allocate " SIZE_FORMAT " %s for evacuation" ,
440
- byte_size_in_proper_unit (words * HeapWordSize), proper_unit_for_byte_size (words * HeapWordSize));
441
- }
442
-
443
- // Forcefully report allocation failure
444
- heap->cancel_gc (GCCause::_shenandoah_allocation_failure_evac);
445
- }
446
-
447
- void ShenandoahControlThread::notify_alloc_failure_waiters () {
448
- _alloc_failure_gc.unset ();
449
- MonitorLocker ml (&_alloc_failure_waiters_lock);
450
- ml.notify_all ();
451
- }
452
-
453
- bool ShenandoahControlThread::try_set_alloc_failure_gc () {
454
- return _alloc_failure_gc.try_set ();
455
- }
456
-
457
- bool ShenandoahControlThread::is_alloc_failure_gc () {
458
- return _alloc_failure_gc.is_set ();
459
- }
460
-
461
405
void ShenandoahControlThread::notify_gc_waiters () {
462
406
_gc_requested.unset ();
463
407
MonitorLocker ml (&_gc_waiters_lock);
464
408
ml.notify_all ();
465
409
}
466
-
467
- void ShenandoahControlThread::pacing_notify_alloc (size_t words) {
468
- assert (ShenandoahPacing, " should only call when pacing is enabled" );
469
- Atomic::add (&_allocs_seen, words, memory_order_relaxed);
470
- }
471
-
472
- void ShenandoahControlThread::reset_gc_id () {
473
- Atomic::store (&_gc_id, (size_t )0 );
474
- }
475
-
476
- void ShenandoahControlThread::update_gc_id () {
477
- Atomic::inc (&_gc_id);
478
- }
479
-
480
- size_t ShenandoahControlThread::get_gc_id () {
481
- return Atomic::load (&_gc_id);
482
- }
483
-
484
- void ShenandoahControlThread::start () {
485
- create_and_start ();
486
- }
487
-
488
- void ShenandoahControlThread::prepare_for_graceful_shutdown () {
489
- _graceful_shutdown.set ();
490
- }
491
-
492
- bool ShenandoahControlThread::in_graceful_shutdown () {
493
- return _graceful_shutdown.is_set ();
494
- }
0 commit comments