Skip to content

Commit 32eb529

Browse files
William Kempershipilev
authored andcommitted
8324553: Shenandoah: Move periodic tasks closer to their collaborators
Reviewed-by: kdnilsen, shade
1 parent c702dca commit 32eb529

8 files changed

+140
-93
lines changed

src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp

Lines changed: 5 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -50,31 +50,12 @@ ShenandoahControlThread::ShenandoahControlThread() :
5050
ConcurrentGCThread(),
5151
_alloc_failure_waiters_lock(Mutex::safepoint-2, "ShenandoahAllocFailureGC_lock", true),
5252
_gc_waiters_lock(Mutex::safepoint-2, "ShenandoahRequestedGC_lock", true),
53-
_periodic_task(this),
5453
_requested_gc_cause(GCCause::_no_cause_specified),
5554
_degen_point(ShenandoahGC::_degenerated_outside_cycle),
5655
_allocs_seen(0) {
5756
set_name("Shenandoah Control Thread");
5857
reset_gc_id();
5958
create_and_start();
60-
_periodic_task.enroll();
61-
if (ShenandoahPacing) {
62-
_periodic_pacer_notify_task.enroll();
63-
}
64-
}
65-
66-
ShenandoahControlThread::~ShenandoahControlThread() {
67-
// This is here so that super is called.
68-
}
69-
70-
void ShenandoahPeriodicTask::task() {
71-
_thread->handle_force_counters_update();
72-
_thread->handle_counters_update();
73-
}
74-
75-
void ShenandoahPeriodicPacerNotify::task() {
76-
assert(ShenandoahPacing, "Should not be here otherwise");
77-
ShenandoahHeap::heap()->pacer()->notify_waiters();
7859
}
7960

8061
void ShenandoahControlThread::run_service() {
@@ -195,7 +176,7 @@ void ShenandoahControlThread::run_service() {
195176

196177
// If GC was requested, we are sampling the counters even without actual triggers
197178
// from allocation machinery. This captures GC phases more accurately.
198-
set_forced_counters_update(true);
179+
heap->set_forced_counters_update(true);
199180

200181
// If GC was requested, we better dump freeset data for performance debugging
201182
{
@@ -236,16 +217,16 @@ void ShenandoahControlThread::run_service() {
236217
// Notify Universe about new heap usage. This has implications for
237218
// global soft refs policy, and we better report it every time heap
238219
// usage goes down.
239-
Universe::heap()->update_capacity_and_used_at_gc();
220+
heap->update_capacity_and_used_at_gc();
240221

241222
// Signal that we have completed a visit to all live objects.
242-
Universe::heap()->record_whole_heap_examined_timestamp();
223+
heap->record_whole_heap_examined_timestamp();
243224
}
244225

245226
// Disable forced counters update, and update counters one more time
246227
// to capture the state at the end of GC session.
247-
handle_force_counters_update();
248-
set_forced_counters_update(false);
228+
heap->handle_force_counters_update();
229+
heap->set_forced_counters_update(false);
249230

250231
// Retract forceful part of soft refs policy
251232
heap->soft_ref_policy()->set_should_clear_all_soft_refs(false);
@@ -573,28 +554,8 @@ void ShenandoahControlThread::notify_gc_waiters() {
573554
ml.notify_all();
574555
}
575556

576-
void ShenandoahControlThread::handle_counters_update() {
577-
if (_do_counters_update.is_set()) {
578-
_do_counters_update.unset();
579-
ShenandoahHeap::heap()->monitoring_support()->update_counters();
580-
}
581-
}
582-
583-
void ShenandoahControlThread::handle_force_counters_update() {
584-
if (_force_counters_update.is_set()) {
585-
_do_counters_update.unset(); // reset these too, we do update now!
586-
ShenandoahHeap::heap()->monitoring_support()->update_counters();
587-
}
588-
}
589-
590557
void ShenandoahControlThread::notify_heap_changed() {
591558
// This is called from allocation path, and thus should be fast.
592-
593-
// Update monitoring counters when we took a new region. This amortizes the
594-
// update costs on slow path.
595-
if (_do_counters_update.is_unset()) {
596-
_do_counters_update.set();
597-
}
598559
// Notify that something had changed.
599560
if (_heap_changed.is_unset()) {
600561
_heap_changed.set();
@@ -606,10 +567,6 @@ void ShenandoahControlThread::pacing_notify_alloc(size_t words) {
606567
Atomic::add(&_allocs_seen, words, memory_order_relaxed);
607568
}
608569

609-
void ShenandoahControlThread::set_forced_counters_update(bool value) {
610-
_force_counters_update.set_cond(value);
611-
}
612-
613570
void ShenandoahControlThread::reset_gc_id() {
614571
Atomic::store(&_gc_id, (size_t)0);
615572
}

src/hotspot/share/gc/shenandoah/shenandoahControlThread.hpp

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -31,28 +31,8 @@
3131
#include "gc/shenandoah/shenandoahHeap.hpp"
3232
#include "gc/shenandoah/shenandoahPadding.hpp"
3333
#include "gc/shenandoah/shenandoahSharedVariables.hpp"
34-
#include "runtime/task.hpp"
3534
#include "utilities/ostream.hpp"
3635

37-
// Periodic task is useful for doing asynchronous things that do not require (heap) locks,
38-
// or synchronization with other parts of collector. These could run even when ShenandoahConcurrentThread
39-
// is busy driving the GC cycle.
40-
class ShenandoahPeriodicTask : public PeriodicTask {
41-
private:
42-
ShenandoahControlThread* _thread;
43-
public:
44-
ShenandoahPeriodicTask(ShenandoahControlThread* thread) :
45-
PeriodicTask(100), _thread(thread) {}
46-
virtual void task();
47-
};
48-
49-
// Periodic task to notify blocked paced waiters.
50-
class ShenandoahPeriodicPacerNotify : public PeriodicTask {
51-
public:
52-
ShenandoahPeriodicPacerNotify() : PeriodicTask(PeriodicTask::min_interval) {}
53-
virtual void task();
54-
};
55-
5636
class ShenandoahControlThread: public ConcurrentGCThread {
5737
friend class VMStructs;
5838

@@ -69,8 +49,6 @@ class ShenandoahControlThread: public ConcurrentGCThread {
6949
// to make complete explicit cycle for for demanding customers.
7050
Monitor _alloc_failure_waiters_lock;
7151
Monitor _gc_waiters_lock;
72-
ShenandoahPeriodicTask _periodic_task;
73-
ShenandoahPeriodicPacerNotify _periodic_pacer_notify_task;
7452

7553
public:
7654
void run_service();
@@ -81,8 +59,6 @@ class ShenandoahControlThread: public ConcurrentGCThread {
8159
ShenandoahSharedFlag _alloc_failure_gc;
8260
ShenandoahSharedFlag _graceful_shutdown;
8361
ShenandoahSharedFlag _heap_changed;
84-
ShenandoahSharedFlag _do_counters_update;
85-
ShenandoahSharedFlag _force_counters_update;
8662
GCCause::Cause _requested_gc_cause;
8763
ShenandoahGC::ShenandoahDegenPoint _degen_point;
8864

@@ -119,7 +95,6 @@ class ShenandoahControlThread: public ConcurrentGCThread {
11995
public:
12096
// Constructor
12197
ShenandoahControlThread();
122-
~ShenandoahControlThread();
12398

12499
// Handle allocation failure from a mutator allocation.
125100
// Optionally blocks while collector is handling the failure. If the GC
@@ -132,10 +107,6 @@ class ShenandoahControlThread: public ConcurrentGCThread {
132107

133108
void request_gc(GCCause::Cause cause);
134109

135-
void handle_counters_update();
136-
void handle_force_counters_update();
137-
void set_forced_counters_update(bool value);
138-
139110
void notify_heap_changed();
140111

141112
void pacing_notify_alloc(size_t words);

src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,6 @@ jint ShenandoahHeap::initialize() {
432432
if (ShenandoahPacing) {
433433
_pacer = new ShenandoahPacer(this);
434434
_pacer->setup_for_idle();
435-
} else {
436-
_pacer = nullptr;
437435
}
438436

439437
_control_thread = new ShenandoahControlThread();
@@ -782,10 +780,25 @@ void ShenandoahHeap::op_uncommit(double shrink_before, size_t shrink_until) {
782780
}
783781

784782
if (count > 0) {
785-
control_thread()->notify_heap_changed();
783+
notify_heap_changed();
786784
}
787785
}
788786

787+
void ShenandoahHeap::notify_heap_changed() {
788+
// Update monitoring counters when we took a new region. This amortizes the
789+
// update costs on slow path.
790+
monitoring_support()->notify_heap_changed();
791+
control_thread()->notify_heap_changed();
792+
}
793+
794+
void ShenandoahHeap::set_forced_counters_update(bool value) {
795+
monitoring_support()->set_forced_counters_update(value);
796+
}
797+
798+
void ShenandoahHeap::handle_force_counters_update() {
799+
monitoring_support()->handle_force_counters_update();
800+
}
801+
789802
HeapWord* ShenandoahHeap::allocate_from_gclab_slow(Thread* thread, size_t size) {
790803
// New object should fit the GCLAB size
791804
size_t min_size = MAX2(size, PLAB::min_size());
@@ -915,7 +928,7 @@ HeapWord* ShenandoahHeap::allocate_memory(ShenandoahAllocRequest& req) {
915928
}
916929

917930
if (in_new_region) {
918-
control_thread()->notify_heap_changed();
931+
notify_heap_changed();
919932
}
920933

921934
if (result != nullptr) {

src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,15 @@ class ShenandoahHeap : public CollectedHeap, public ShenandoahSpaceInfo {
207207

208208
void set_soft_max_capacity(size_t v);
209209

210+
// ---------- Periodic Tasks
211+
//
212+
private:
213+
void notify_heap_changed();
214+
215+
public:
216+
void set_forced_counters_update(bool value);
217+
void handle_force_counters_update();
218+
210219
// ---------- Workers handling
211220
//
212221
private:

src/hotspot/share/gc/shenandoah/shenandoahMonitoringSupport.cpp

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class ShenandoahYoungGenerationCounters : public GenerationCounters {
3737
ShenandoahYoungGenerationCounters() :
3838
GenerationCounters("Young", 0, 0, 0, (size_t)0, (size_t)0) {};
3939

40-
virtual void update_all() {
40+
void update_all() override {
4141
// no update
4242
}
4343
};
@@ -46,19 +46,20 @@ class ShenandoahGenerationCounters : public GenerationCounters {
4646
private:
4747
ShenandoahHeap* _heap;
4848
public:
49-
ShenandoahGenerationCounters(ShenandoahHeap* heap) :
49+
explicit ShenandoahGenerationCounters(ShenandoahHeap* heap) :
5050
GenerationCounters("Heap", 1, 1, heap->initial_capacity(), heap->max_capacity(), heap->capacity()),
5151
_heap(heap)
5252
{};
5353

54-
virtual void update_all() {
54+
void update_all() override {
5555
_current_size->set_value(_heap->capacity());
5656
}
5757
};
5858

5959
ShenandoahMonitoringSupport::ShenandoahMonitoringSupport(ShenandoahHeap* heap) :
6060
_partial_counters(nullptr),
61-
_full_counters(nullptr)
61+
_full_counters(nullptr),
62+
_counters_update_task(this)
6263
{
6364
// Collection counters do not fit Shenandoah very well.
6465
// We record partial cycles as "young", and full cycles (including full STW GC) as "old".
@@ -71,6 +72,8 @@ ShenandoahMonitoringSupport::ShenandoahMonitoringSupport(ShenandoahHeap* heap) :
7172
_space_counters = new HSpaceCounters(_heap_counters->name_space(), "Heap", 0, heap->max_capacity(), heap->initial_capacity());
7273

7374
_heap_region_counters = new ShenandoahHeapRegionCounters();
75+
76+
_counters_update_task.enroll();
7477
}
7578

7679
CollectorCounters* ShenandoahMonitoringSupport::stw_collection_counters() {
@@ -103,3 +106,44 @@ void ShenandoahMonitoringSupport::update_counters() {
103106
MetaspaceCounters::update_performance_counters();
104107
}
105108
}
109+
110+
void ShenandoahMonitoringSupport::notify_heap_changed() {
111+
_counters_update_task.notify_heap_changed();
112+
}
113+
114+
void ShenandoahMonitoringSupport::set_forced_counters_update(bool value) {
115+
_counters_update_task.set_forced_counters_update(value);
116+
}
117+
118+
void ShenandoahMonitoringSupport::handle_force_counters_update() {
119+
_counters_update_task.handle_force_counters_update();
120+
}
121+
122+
void ShenandoahPeriodicCountersUpdateTask::task() {
123+
handle_force_counters_update();
124+
handle_counters_update();
125+
}
126+
127+
void ShenandoahPeriodicCountersUpdateTask::handle_counters_update() {
128+
if (_do_counters_update.is_set()) {
129+
_do_counters_update.unset();
130+
_monitoring_support->update_counters();
131+
}
132+
}
133+
134+
void ShenandoahPeriodicCountersUpdateTask::handle_force_counters_update() {
135+
if (_force_counters_update.is_set()) {
136+
_do_counters_update.unset(); // reset these too, we do update now!
137+
_monitoring_support->update_counters();
138+
}
139+
}
140+
141+
void ShenandoahPeriodicCountersUpdateTask::notify_heap_changed() {
142+
if (_do_counters_update.is_unset()) {
143+
_do_counters_update.set();
144+
}
145+
}
146+
147+
void ShenandoahPeriodicCountersUpdateTask::set_forced_counters_update(bool value) {
148+
_force_counters_update.set_cond(value);
149+
}

src/hotspot/share/gc/shenandoah/shenandoahMonitoringSupport.hpp

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,35 @@
2525
#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHMONITORINGSUPPORT_HPP
2626
#define SHARE_GC_SHENANDOAH_SHENANDOAHMONITORINGSUPPORT_HPP
2727

28+
#include "gc/shenandoah/shenandoahSharedVariables.hpp"
2829
#include "memory/allocation.hpp"
30+
#include "runtime/task.hpp"
2931

3032
class GenerationCounters;
3133
class HSpaceCounters;
3234
class ShenandoahHeap;
3335
class CollectorCounters;
3436
class ShenandoahHeapRegionCounters;
37+
class ShenandoahMonitoringSupport;
38+
39+
class ShenandoahPeriodicCountersUpdateTask : public PeriodicTask {
40+
private:
41+
ShenandoahSharedFlag _do_counters_update;
42+
ShenandoahSharedFlag _force_counters_update;
43+
ShenandoahMonitoringSupport* const _monitoring_support;
44+
45+
public:
46+
explicit ShenandoahPeriodicCountersUpdateTask(ShenandoahMonitoringSupport* monitoring_support) :
47+
PeriodicTask(100),
48+
_monitoring_support(monitoring_support) { }
49+
50+
void task() override;
51+
52+
void handle_counters_update();
53+
void handle_force_counters_update();
54+
void set_forced_counters_update(bool value);
55+
void notify_heap_changed();
56+
};
3557

3658
class ShenandoahMonitoringSupport : public CHeapObj<mtGC> {
3759
private:
@@ -44,14 +66,20 @@ class ShenandoahMonitoringSupport : public CHeapObj<mtGC> {
4466
HSpaceCounters* _space_counters;
4567

4668
ShenandoahHeapRegionCounters* _heap_region_counters;
69+
ShenandoahPeriodicCountersUpdateTask _counters_update_task;
4770

4871
public:
49-
ShenandoahMonitoringSupport(ShenandoahHeap* heap);
50-
CollectorCounters* stw_collection_counters();
51-
CollectorCounters* full_stw_collection_counters();
52-
CollectorCounters* concurrent_collection_counters();
53-
CollectorCounters* partial_collection_counters();
54-
void update_counters();
72+
explicit ShenandoahMonitoringSupport(ShenandoahHeap* heap);
73+
CollectorCounters* stw_collection_counters();
74+
CollectorCounters* full_stw_collection_counters();
75+
CollectorCounters* concurrent_collection_counters();
76+
CollectorCounters* partial_collection_counters();
77+
78+
void notify_heap_changed();
79+
void set_forced_counters_update(bool value);
80+
void handle_force_counters_update();
81+
82+
void update_counters();
5583
};
5684

5785
#endif // SHARE_GC_SHENANDOAH_SHENANDOAHMONITORINGSUPPORT_HPP

src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,3 +338,8 @@ void ShenandoahPacer::print_cycle_on(outputStream* out) {
338338
}
339339
out->cr();
340340
}
341+
342+
void ShenandoahPeriodicPacerNotifyTask::task() {
343+
assert(ShenandoahPacing, "Should not be here otherwise");
344+
_pacer->notify_waiters();
345+
}

0 commit comments

Comments
 (0)