79 };
80
81 /*
82 * ShenandoahGCPhaseTiming tracks Shenandoah specific timing information
83 * of a GC phase
84 */
85 class ShenandoahTimingsTracker : public StackObj {
86 private:
87 static ShenandoahPhaseTimings::Phase _current_phase;
88
89 ShenandoahPhaseTimings* const _timings;
90 const ShenandoahPhaseTimings::Phase _phase;
91 const bool _should_aggregate;
92 ShenandoahPhaseTimings::Phase _parent_phase;
93 double _start;
94
95 public:
96 ShenandoahTimingsTracker(ShenandoahPhaseTimings::Phase phase, bool should_aggregate = false);
97 ~ShenandoahTimingsTracker();
98
99 static ShenandoahPhaseTimings::Phase current_phase() { return _current_phase; }
100
101 static bool is_current_phase_valid();
102 };
103
104 /*
105 * ShenandoahPausePhase tracks a STW pause and emits Shenandoah timing and
106 * a corresponding JFR event
107 */
108 class ShenandoahPausePhase : public ShenandoahTimingsTracker {
109 private:
110 GCTraceTimeWrapper<LogLevel::Info, LOG_TAGS(gc)> _tracer;
111 ConcurrentGCTimer* const _timer;
112
113 public:
114 ShenandoahPausePhase(const char* title, ShenandoahPhaseTimings::Phase phase, bool log_heap_usage = false);
115 ~ShenandoahPausePhase();
116 };
117
118 /*
119 * ShenandoahConcurrentPhase tracks a concurrent GC phase and emits Shenandoah timing and
174
175 Thread* const thr = Thread::current();
176 // Shenandoah GC specific safepoints are scheduled by control thread.
177 // So if we are enter here from control thread, then we are definitely not
178 // at Shenandoah safepoint, but at something else.
179 if (thr == ShenandoahHeap::heap()->control_thread()) return false;
180
181 // This is not VM thread, cannot see what VM thread is doing,
182 // so pretend this is a proper Shenandoah safepoint
183 if (!thr->is_VM_thread()) return true;
184
185 // Otherwise check we are at proper operation type
186 VM_Operation* vm_op = VMThread::vm_operation();
187 if (vm_op == nullptr) return false;
188
189 VM_Operation::VMOp_Type type = vm_op->type();
190 return type == VM_Operation::VMOp_ShenandoahInitMark ||
191 type == VM_Operation::VMOp_ShenandoahFinalMarkStartEvac ||
192 type == VM_Operation::VMOp_ShenandoahInitUpdateRefs ||
193 type == VM_Operation::VMOp_ShenandoahFinalUpdateRefs ||
194 type == VM_Operation::VMOp_ShenandoahFinalVerify ||
195 type == VM_Operation::VMOp_ShenandoahFullGC ||
196 type == VM_Operation::VMOp_ShenandoahDegeneratedGC;
197 }
198 };
199
200 class ShenandoahWorkerSession : public StackObj {
201 protected:
202 ShenandoahWorkerSession(uint worker_id);
203 public:
204 static inline uint worker_id() {
205 return WorkerThread::worker_id();
206 }
207 };
208
209 class ShenandoahConcurrentWorkerSession : public ShenandoahWorkerSession {
210 private:
211 EventGCPhaseConcurrent _event;
212
213 public:
214 ShenandoahConcurrentWorkerSession(uint worker_id) : ShenandoahWorkerSession(worker_id) { }
|
79 };
80
81 /*
82 * ShenandoahGCPhaseTiming tracks Shenandoah specific timing information
83 * of a GC phase
84 */
85 class ShenandoahTimingsTracker : public StackObj {
86 private:
87 static ShenandoahPhaseTimings::Phase _current_phase;
88
89 ShenandoahPhaseTimings* const _timings;
90 const ShenandoahPhaseTimings::Phase _phase;
91 const bool _should_aggregate;
92 ShenandoahPhaseTimings::Phase _parent_phase;
93 double _start;
94
95 public:
96 ShenandoahTimingsTracker(ShenandoahPhaseTimings::Phase phase, bool should_aggregate = false);
97 ~ShenandoahTimingsTracker();
98
99 static ShenandoahPhaseTimings::Phase current_phase() {
100 assert(is_current_phase_valid(), "Current phase is not valid");
101 return _current_phase;
102 }
103
104 static bool is_current_phase_valid();
105 };
106
107 /*
108 * ShenandoahPausePhase tracks a STW pause and emits Shenandoah timing and
109 * a corresponding JFR event
110 */
111 class ShenandoahPausePhase : public ShenandoahTimingsTracker {
112 private:
113 GCTraceTimeWrapper<LogLevel::Info, LOG_TAGS(gc)> _tracer;
114 ConcurrentGCTimer* const _timer;
115
116 public:
117 ShenandoahPausePhase(const char* title, ShenandoahPhaseTimings::Phase phase, bool log_heap_usage = false);
118 ~ShenandoahPausePhase();
119 };
120
121 /*
122 * ShenandoahConcurrentPhase tracks a concurrent GC phase and emits Shenandoah timing and
177
178 Thread* const thr = Thread::current();
179 // Shenandoah GC specific safepoints are scheduled by control thread.
180 // So if we are enter here from control thread, then we are definitely not
181 // at Shenandoah safepoint, but at something else.
182 if (thr == ShenandoahHeap::heap()->control_thread()) return false;
183
184 // This is not VM thread, cannot see what VM thread is doing,
185 // so pretend this is a proper Shenandoah safepoint
186 if (!thr->is_VM_thread()) return true;
187
188 // Otherwise check we are at proper operation type
189 VM_Operation* vm_op = VMThread::vm_operation();
190 if (vm_op == nullptr) return false;
191
192 VM_Operation::VMOp_Type type = vm_op->type();
193 return type == VM_Operation::VMOp_ShenandoahInitMark ||
194 type == VM_Operation::VMOp_ShenandoahFinalMarkStartEvac ||
195 type == VM_Operation::VMOp_ShenandoahInitUpdateRefs ||
196 type == VM_Operation::VMOp_ShenandoahFinalUpdateRefs ||
197 type == VM_Operation::VMOp_ShenandoahFinalRoots ||
198 type == VM_Operation::VMOp_ShenandoahFullGC ||
199 type == VM_Operation::VMOp_ShenandoahDegeneratedGC;
200 }
201 };
202
203 class ShenandoahWorkerSession : public StackObj {
204 protected:
205 ShenandoahWorkerSession(uint worker_id);
206 public:
207 static inline uint worker_id() {
208 return WorkerThread::worker_id();
209 }
210 };
211
212 class ShenandoahConcurrentWorkerSession : public ShenandoahWorkerSession {
213 private:
214 EventGCPhaseConcurrent _event;
215
216 public:
217 ShenandoahConcurrentWorkerSession(uint worker_id) : ShenandoahWorkerSession(worker_id) { }
|