@@ -467,36 +467,59 @@ void G1YoungCollector::set_young_collection_default_active_worker_threads(){
467
467
log_info (gc,task)(" Using %u workers of %u for evacuation" , active_workers, workers ()->max_workers ());
468
468
}
469
469
470
- void G1YoungCollector::flush_dirty_card_queues () {
470
+ void G1YoungCollector::retire_tlabs () {
471
+ Ticks start = Ticks::now ();
472
+ _g1h->retire_tlabs ();
473
+ double retire_time = (Ticks::now () - start).seconds () * MILLIUNITS;
474
+ phase_times ()->record_prepare_tlab_time_ms (retire_time);
475
+ }
476
+
477
+ void G1YoungCollector::concatenate_dirty_card_logs_and_stats () {
471
478
Ticks start = Ticks::now ();
472
479
G1DirtyCardQueueSet& qset = G1BarrierSet::dirty_card_queue_set ();
473
480
size_t old_cards = qset.num_cards ();
474
- qset.concatenate_logs ();
475
- size_t added_cards = qset.num_cards () - old_cards;
476
- Tickspan concat_time = Ticks::now () - start;
477
- policy ()->record_concatenate_dirty_card_logs (concat_time, added_cards);
481
+ qset.concatenate_logs_and_stats ();
482
+ size_t pending_cards = qset.num_cards ();
483
+ size_t thread_buffer_cards = pending_cards - old_cards;
484
+ policy ()->record_concurrent_refinement_stats (pending_cards, thread_buffer_cards);
485
+ double concat_time = (Ticks::now () - start).seconds () * MILLIUNITS;
486
+ phase_times ()->record_concatenate_dirty_card_logs_time_ms (concat_time);
487
+ }
488
+
489
+ #ifdef ASSERT
490
+ void G1YoungCollector::verify_empty_dirty_card_logs () const {
491
+ struct Verifier : public ThreadClosure {
492
+ size_t _buffer_size;
493
+ Verifier () : _buffer_size(G1BarrierSet::dirty_card_queue_set().buffer_size()) {}
494
+ void do_thread (Thread* t) override {
495
+ G1DirtyCardQueue& queue = G1ThreadLocalData::dirty_card_queue (t);
496
+ assert ((queue.buffer () == nullptr ) || (queue.index () == _buffer_size),
497
+ " non-empty dirty card queue for thread" );
498
+ }
499
+ } verifier;
500
+ Threads::threads_do (&verifier);
478
501
}
502
+ #endif // ASSERT
503
+
504
+ void G1YoungCollector::pre_evacuate_collection_set (G1EvacInfo* evacuation_info) {
505
+ // Flush early, so later phases don't need to account for per-thread stuff.
506
+ // Flushes deferred card marks, so must precede concatenating logs.
507
+ retire_tlabs ();
508
+
509
+ // Flush early, so later phases don't need to account for per-thread stuff.
510
+ concatenate_dirty_card_logs_and_stats ();
511
+
512
+ calculate_collection_set (evacuation_info, policy ()->max_pause_time_ms ());
479
513
480
- void G1YoungCollector::pre_evacuate_collection_set (G1EvacInfo* evacuation_info, G1ParScanThreadStateSet* per_thread_states) {
481
514
// Please see comment in g1CollectedHeap.hpp and
482
515
// G1CollectedHeap::ref_processing_init() to see how
483
516
// reference processing currently works in G1.
484
517
ref_processor_stw ()->start_discovery (false /* always_clear */ );
485
518
486
- _evac_failure_regions.pre_collection (_g1h->max_reserved_regions ());
519
+ _evac_failure_regions.pre_collection (_g1h->max_reserved_regions ());
487
520
488
521
_g1h->gc_prologue (false );
489
522
490
- {
491
- Ticks start = Ticks::now ();
492
- _g1h->retire_tlabs ();
493
- phase_times ()->record_prepare_tlab_time_ms ((Ticks::now () - start).seconds () * 1000.0 );
494
- }
495
-
496
- // Flush dirty card queues to qset, so later phases don't need to account
497
- // for partially filled per-thread queues and such.
498
- flush_dirty_card_queues ();
499
-
500
523
hot_card_cache ()->reset_hot_cache_claimed_index ();
501
524
502
525
// Initialize the GC alloc regions.
@@ -519,7 +542,7 @@ void G1YoungCollector::pre_evacuate_collection_set(G1EvacInfo* evacuation_info,
519
542
}
520
543
521
544
assert (_g1h->verifier ()->check_region_attr_table (), " Inconsistency in the region attributes table." );
522
- per_thread_states-> preserved_marks_set ()-> assert_empty ();
545
+ verify_empty_dirty_card_logs ();
523
546
524
547
#if COMPILER2_OR_JVMCI
525
548
DerivedPointerTable::clear ();
@@ -1013,19 +1036,6 @@ bool G1YoungCollector::evacuation_failed() const {
1013
1036
return _evac_failure_regions.evacuation_failed ();
1014
1037
}
1015
1038
1016
- class G1PreservedMarksSet : public PreservedMarksSet {
1017
- public:
1018
-
1019
- G1PreservedMarksSet (uint num_workers) : PreservedMarksSet(true /* in_c_heap */ ) {
1020
- init (num_workers);
1021
- }
1022
-
1023
- virtual ~G1PreservedMarksSet () {
1024
- assert_empty ();
1025
- reclaim ();
1026
- }
1027
- };
1028
-
1029
1039
G1YoungCollector::G1YoungCollector (GCCause::Cause gc_cause) :
1030
1040
_g1h(G1CollectedHeap::heap()),
1031
1041
_gc_cause(gc_cause),
@@ -1073,20 +1083,14 @@ void G1YoungCollector::collect() {
1073
1083
// other trivial setup above).
1074
1084
policy ()->record_young_collection_start ();
1075
1085
1076
- calculate_collection_set (jtm.evacuation_info (), policy ()-> max_pause_time_ms ());
1086
+ pre_evacuate_collection_set (jtm.evacuation_info ());
1077
1087
1078
- G1RedirtyCardsQueueSet rdcqs (G1BarrierSet::dirty_card_queue_set ().allocator ());
1079
- G1PreservedMarksSet preserved_marks_set (workers ()->active_workers ());
1080
1088
G1ParScanThreadStateSet per_thread_states (_g1h,
1081
- &rdcqs,
1082
- &preserved_marks_set,
1083
1089
workers ()->active_workers (),
1084
1090
collection_set ()->young_region_length (),
1085
1091
collection_set ()->optional_region_length (),
1086
1092
&_evac_failure_regions);
1087
1093
1088
- pre_evacuate_collection_set (jtm.evacuation_info (), &per_thread_states);
1089
-
1090
1094
bool may_do_optional_evacuation = collection_set ()->optional_region_length () != 0 ;
1091
1095
// Actually do the work...
1092
1096
evacuate_initial_collection_set (&per_thread_states, may_do_optional_evacuation);
1 commit comments
openjdk-notifier[bot] commentedon Nov 25, 2022
Review
Issues