Skip to content

Commit 8bd5645

Browse files
author
Sangheon Kim
committed
8346568: G1: Other time can be negative
Reviewed-by: tschatzl, iwalulya
1 parent 2ec61f0 commit 8bd5645

File tree

4 files changed

+48
-32
lines changed

4 files changed

+48
-32
lines changed

src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ void G1GCPhaseTimes::reset() {
193193
_cur_region_register_time = 0.0;
194194
_cur_verify_before_time_ms = 0.0;
195195
_cur_verify_after_time_ms = 0.0;
196+
_cur_prepare_concurrent_task_time_ms = 0.0;
196197

197198
for (int i = 0; i < GCParPhasesSentinel; i++) {
198199
if (_gc_par_phases[i] != nullptr) {
@@ -407,10 +408,7 @@ void G1GCPhaseTimes::trace_count(const char* name, size_t value) const {
407408
}
408409

409410
double G1GCPhaseTimes::print_pre_evacuate_collection_set() const {
410-
const double pre_concurrent_start_ms = average_time_ms(ResetMarkingState) +
411-
average_time_ms(NoteStartOfMark);
412-
413-
const double sum_ms = pre_concurrent_start_ms +
411+
const double sum_ms = _cur_prepare_concurrent_task_time_ms +
414412
_cur_pre_evacuate_prepare_time_ms +
415413
_recorded_young_cset_choice_time_ms +
416414
_recorded_non_young_cset_choice_time_ms +
@@ -419,9 +417,12 @@ double G1GCPhaseTimes::print_pre_evacuate_collection_set() const {
419417

420418
info_time("Pre Evacuate Collection Set", sum_ms);
421419

422-
if (pre_concurrent_start_ms > 0.0) {
423-
debug_phase(_gc_par_phases[ResetMarkingState]);
424-
debug_phase(_gc_par_phases[NoteStartOfMark]);
420+
// Concurrent tasks of ResetMarkingState and NoteStartOfMark are triggered during
421+
// young collection. However, their execution time are not included in _gc_pause_time_ms.
422+
if (_cur_prepare_concurrent_task_time_ms > 0.0) {
423+
debug_time("Prepare Concurrent Start", _cur_prepare_concurrent_task_time_ms);
424+
debug_phase(_gc_par_phases[ResetMarkingState], 1);
425+
debug_phase(_gc_par_phases[NoteStartOfMark], 1);
425426
}
426427

427428
debug_time("Pre Evacuate Prepare", _cur_pre_evacuate_prepare_time_ms);
@@ -545,6 +546,11 @@ void G1GCPhaseTimes::print_other(double accounted_ms) const {
545546
info_time("Other", _gc_pause_time_ms - accounted_ms);
546547
}
547548

549+
// Root-region-scan-wait, verify-before and verify-after are part of young GC,
550+
// but these are not measured by G1Policy. i.e. these are not included in
551+
// G1Policy::record_young_collection_start() and record_young_collection_end().
552+
// In addition, these are not included in G1GCPhaseTimes::_gc_pause_time_ms.
553+
// See G1YoungCollector::collect().
548554
void G1GCPhaseTimes::print(bool evacuation_failed) {
549555
if (_root_region_scan_wait_time_ms > 0.0) {
550556
debug_time("Root Region Scan Waiting", _root_region_scan_wait_time_ms);
@@ -559,15 +565,13 @@ void G1GCPhaseTimes::print(bool evacuation_failed) {
559565

560566
double accounted_ms = 0.0;
561567

562-
accounted_ms += _root_region_scan_wait_time_ms;
563-
accounted_ms += _cur_verify_before_time_ms;
564-
565568
accounted_ms += print_pre_evacuate_collection_set();
566569
accounted_ms += print_evacuate_initial_collection_set();
567570
accounted_ms += print_evacuate_optional_collection_set();
568571
accounted_ms += print_post_evacuate_collection_set(evacuation_failed);
569572

570-
accounted_ms += _cur_verify_after_time_ms;
573+
assert(_gc_pause_time_ms >= accounted_ms, "GC pause time(%.3lfms) cannot be "
574+
"smaller than the sum of each phase(%.3lfms).", _gc_pause_time_ms, accounted_ms);
571575

572576
print_other(accounted_ms);
573577

src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -177,12 +177,12 @@ class G1GCPhaseTimes : public CHeapObj<mtGC> {
177177

178178
double _cur_merge_heap_roots_time_ms;
179179
double _cur_optional_merge_heap_roots_time_ms;
180+
// Included in above merge and optional-merge time.
181+
double _cur_distribute_log_buffers_time_ms;
180182

181183
double _cur_prepare_merge_heap_roots_time_ms;
182184
double _cur_optional_prepare_merge_heap_roots_time_ms;
183185

184-
double _cur_distribute_log_buffers_time_ms;
185-
186186
double _cur_pre_evacuate_prepare_time_ms;
187187

188188
double _cur_post_evacuate_cleanup_1_time_ms;
@@ -192,6 +192,7 @@ class G1GCPhaseTimes : public CHeapObj<mtGC> {
192192
double _cur_ref_proc_time_ms;
193193

194194
double _cur_collection_start_sec;
195+
// Not included in _gc_pause_time_ms
195196
double _root_region_scan_wait_time_ms;
196197

197198
double _external_accounted_time_ms;
@@ -211,9 +212,13 @@ class G1GCPhaseTimes : public CHeapObj<mtGC> {
211212

212213
double _cur_region_register_time;
213214

215+
// Not included in _gc_pause_time_ms
214216
double _cur_verify_before_time_ms;
215217
double _cur_verify_after_time_ms;
216218

219+
// Time spent to trigger concurrent tasks of ResetMarkingState and NoteStartOfMark.
220+
double _cur_prepare_concurrent_task_time_ms;
221+
217222
ReferenceProcessorPhaseTimes _ref_phase_times;
218223
WeakProcessorTimes _weak_phase_times;
219224

@@ -318,6 +323,10 @@ class G1GCPhaseTimes : public CHeapObj<mtGC> {
318323
_cur_ref_proc_time_ms = ms;
319324
}
320325

326+
void record_prepare_concurrent_task_time_ms(double ms) {
327+
_cur_prepare_concurrent_task_time_ms = ms;
328+
}
329+
321330
void record_root_region_scan_wait_time(double time_ms) {
322331
_root_region_scan_wait_time_ms = time_ms;
323332
}
@@ -389,8 +398,11 @@ class G1GCPhaseTimes : public CHeapObj<mtGC> {
389398
double cur_collection_par_time_ms() {
390399
return _cur_collection_initial_evac_time_ms +
391400
_cur_optional_evac_time_ms +
401+
_cur_prepare_merge_heap_roots_time_ms +
392402
_cur_merge_heap_roots_time_ms +
393-
_cur_optional_merge_heap_roots_time_ms;
403+
_cur_optional_prepare_merge_heap_roots_time_ms +
404+
_cur_optional_merge_heap_roots_time_ms +
405+
_cur_collection_nmethod_list_cleanup_time_ms;
394406
}
395407

396408
double cur_expand_heap_time_ms() {

src/hotspot/share/gc/g1/g1RemSet.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,6 +1445,7 @@ void G1RemSet::print_merge_heap_roots_stats() {
14451445

14461446
void G1RemSet::merge_heap_roots(bool initial_evacuation) {
14471447
G1CollectedHeap* g1h = G1CollectedHeap::heap();
1448+
G1GCPhaseTimes* pt = g1h->phase_times();
14481449

14491450
{
14501451
Ticks start = Ticks::now();
@@ -1453,9 +1454,9 @@ void G1RemSet::merge_heap_roots(bool initial_evacuation) {
14531454

14541455
Tickspan total = Ticks::now() - start;
14551456
if (initial_evacuation) {
1456-
g1h->phase_times()->record_prepare_merge_heap_roots_time(total.seconds() * 1000.0);
1457+
pt->record_prepare_merge_heap_roots_time(total.seconds() * 1000.0);
14571458
} else {
1458-
g1h->phase_times()->record_or_add_optional_prepare_merge_heap_roots_time(total.seconds() * 1000.0);
1459+
pt->record_or_add_optional_prepare_merge_heap_roots_time(total.seconds() * 1000.0);
14591460
}
14601461
}
14611462

@@ -1465,6 +1466,8 @@ void G1RemSet::merge_heap_roots(bool initial_evacuation) {
14651466
uint const num_workers = initial_evacuation ? workers->active_workers() :
14661467
MIN2(workers->active_workers(), (uint)increment_length);
14671468

1469+
Ticks start = Ticks::now();
1470+
14681471
{
14691472
G1MergeHeapRootsTask cl(_scan_state, num_workers, initial_evacuation);
14701473
log_debug(gc, ergo)("Running %s using %u workers for %zu regions",
@@ -1483,6 +1486,12 @@ void G1RemSet::merge_heap_roots(bool initial_evacuation) {
14831486
}
14841487

14851488
print_merge_heap_roots_stats();
1489+
1490+
if (initial_evacuation) {
1491+
pt->record_merge_heap_roots_time((Ticks::now() - start).seconds() * 1000.0);
1492+
} else {
1493+
pt->record_or_add_optional_merge_heap_roots_time((Ticks::now() - start).seconds() * 1000.0);
1494+
}
14861495
}
14871496

14881497
void G1RemSet::complete_evac_phase(bool has_more_than_one_evacuation_phase) {

src/hotspot/share/gc/g1/g1YoungCollector.cpp

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,9 @@ void G1YoungCollector::pre_evacuate_collection_set(G1EvacInfo* evacuation_info)
486486
calculate_collection_set(evacuation_info, policy()->max_pause_time_ms());
487487

488488
if (collector_state()->in_concurrent_start_gc()) {
489+
Ticks start = Ticks::now();
489490
concurrent_mark()->pre_concurrent_start(_gc_cause);
491+
phase_times()->record_prepare_concurrent_task_time_ms((Ticks::now() - start).seconds() * 1000.0);
490492
}
491493

492494
// Please see comment in g1CollectedHeap.hpp and
@@ -743,11 +745,7 @@ void G1YoungCollector::evacuate_initial_collection_set(G1ParScanThreadStateSet*
743745
bool has_optional_evacuation_work) {
744746
G1GCPhaseTimes* p = phase_times();
745747

746-
{
747-
Ticks start = Ticks::now();
748-
rem_set()->merge_heap_roots(true /* initial_evacuation */);
749-
p->record_merge_heap_roots_time((Ticks::now() - start).seconds() * 1000.0);
750-
}
748+
rem_set()->merge_heap_roots(true /* initial_evacuation */);
751749

752750
Tickspan task_time;
753751
const uint num_workers = workers()->active_workers();
@@ -812,6 +810,7 @@ void G1YoungCollector::evacuate_next_optional_regions(G1ParScanThreadStateSet* p
812810
Tickspan total_processing = Ticks::now() - start_processing;
813811

814812
G1GCPhaseTimes* p = phase_times();
813+
p->record_or_add_optional_evac_time(task_time.seconds() * 1000.0);
815814
p->record_or_add_nmethod_list_cleanup_time((total_processing - task_time).seconds() * 1000.0);
816815
}
817816

@@ -830,17 +829,9 @@ void G1YoungCollector::evacuate_optional_collection_set(G1ParScanThreadStateSet*
830829
break;
831830
}
832831

833-
{
834-
Ticks start = Ticks::now();
835-
rem_set()->merge_heap_roots(false /* initial_evacuation */);
836-
phase_times()->record_or_add_optional_merge_heap_roots_time((Ticks::now() - start).seconds() * 1000.0);
837-
}
832+
rem_set()->merge_heap_roots(false /* initial_evacuation */);
838833

839-
{
840-
Ticks start = Ticks::now();
841-
evacuate_next_optional_regions(per_thread_states);
842-
phase_times()->record_or_add_optional_evac_time((Ticks::now() - start).seconds() * 1000.0);
843-
}
834+
evacuate_next_optional_regions(per_thread_states);
844835

845836
rem_set()->complete_evac_phase(true /* has_more_than_one_evacuation_phase */);
846837
}

0 commit comments

Comments
 (0)