--- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp Thu Oct 17 20:27:44 2019 +0100
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp Thu Oct 17 20:53:35 2019 +0100
@@ -145,7 +145,7 @@
STATIC_ASSERT(sizeof(LP64_ONLY(jint) NOT_LP64(jshort)) <= (sizeof(size_t)/2));
const size_t max_yellow_zone = LP64_ONLY(max_jint) NOT_LP64(max_jshort);
const size_t max_green_zone = max_yellow_zone / 2;
-const size_t max_red_zone = INT_MAX; // For dcqs.set_max_completed_buffers.
+const size_t max_red_zone = INT_MAX; // For dcqs.set_max_cards.
STATIC_ASSERT(max_yellow_zone <= max_red_zone);
// Range check assertions for green zone values.
@@ -198,19 +198,19 @@
static Thresholds calc_thresholds(size_t green_zone,
size_t yellow_zone,
- uint worker_i) {
+ uint worker_id) {
double yellow_size = yellow_zone - green_zone;
double step = yellow_size / G1ConcurrentRefine::max_num_threads();
- if (worker_i == 0) {
+ if (worker_id == 0) {
// Potentially activate worker 0 more aggressively, to keep
// available buffers near green_zone value. When yellow_size is
// large we don't want to allow a full step to accumulate before
// doing any processing, as that might lead to significantly more
- // than green_zone buffers to be processed by update_rs.
+ // than green_zone buffers to be processed during scanning.
step = MIN2(step, ParallelGCThreads / 2.0);
}
- size_t activate_offset = static_cast<size_t>(ceil(step * (worker_i + 1)));
- size_t deactivate_offset = static_cast<size_t>(floor(step * worker_i));
+ size_t activate_offset = static_cast<size_t>(ceil(step * (worker_id + 1)));
+ size_t deactivate_offset = static_cast<size_t>(floor(step * worker_id));
return Thresholds(green_zone + activate_offset,
green_zone + deactivate_offset);
}
@@ -232,8 +232,12 @@
return _thread_control.initialize(this, max_num_threads());
}
+static size_t buffers_to_cards(size_t value) {
+ return value * G1UpdateBufferSize;
+}
+
static size_t calc_min_yellow_zone_size() {
- size_t step = G1ConcRefinementThresholdStep;
+ size_t step = buffers_to_cards(G1ConcRefinementThresholdStep);
uint n_workers = G1ConcurrentRefine::max_num_threads();
if ((max_yellow_zone / step) < n_workers) {
return max_yellow_zone;
@@ -247,11 +251,12 @@
if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) {
green = ParallelGCThreads;
}
+ green = buffers_to_cards(green);
return MIN2(green, max_green_zone);
}
static size_t calc_init_yellow_zone(size_t green, size_t min_size) {
- size_t config = G1ConcRefinementYellowZone;
+ size_t config = buffers_to_cards(G1ConcRefinementYellowZone);
size_t size = 0;
if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) {
size = green * 2;
@@ -266,7 +271,7 @@
static size_t calc_init_red_zone(size_t green, size_t yellow) {
size_t size = yellow - green;
if (!FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) {
- size_t config = G1ConcRefinementRedZone;
+ size_t config = buffers_to_cards(G1ConcRefinementRedZone);
if (yellow < config) {
size = MAX2(size, config - yellow);
}
@@ -322,18 +327,18 @@
}
static size_t calc_new_green_zone(size_t green,
- double update_rs_time,
- size_t update_rs_processed_buffers,
+ double logged_cards_scan_time,
+ size_t processed_logged_cards,
double goal_ms) {
// Adjust green zone based on whether we're meeting the time goal.
// Limit to max_green_zone.
const double inc_k = 1.1, dec_k = 0.9;
- if (update_rs_time > goal_ms) {
+ if (logged_cards_scan_time > goal_ms) {
if (green > 0) {
green = static_cast<size_t>(green * dec_k);
}
- } else if (update_rs_time < goal_ms &&
- update_rs_processed_buffers > green) {
+ } else if (logged_cards_scan_time < goal_ms &&
+ processed_logged_cards > green) {
green = static_cast<size_t>(MAX2(green * inc_k, green + 1.0));
green = MIN2(green, max_green_zone);
}
@@ -350,20 +355,20 @@
return MIN2(yellow + (yellow - green), max_red_zone);
}
-void G1ConcurrentRefine::update_zones(double update_rs_time,
- size_t update_rs_processed_buffers,
+void G1ConcurrentRefine::update_zones(double logged_cards_scan_time,
+ size_t processed_logged_cards,
double goal_ms) {
log_trace( CTRL_TAGS )("Updating Refinement Zones: "
- "update_rs time: %.3fms, "
- "update_rs buffers: " SIZE_FORMAT ", "
- "update_rs goal time: %.3fms",
- update_rs_time,
- update_rs_processed_buffers,
+ "logged cards scan time: %.3fms, "
+ "processed cards: " SIZE_FORMAT ", "
+ "goal time: %.3fms",
+ logged_cards_scan_time,
+ processed_logged_cards,
goal_ms);
_green_zone = calc_new_green_zone(_green_zone,
- update_rs_time,
- update_rs_processed_buffers,
+ logged_cards_scan_time,
+ processed_logged_cards,
goal_ms);
_yellow_zone = calc_new_yellow_zone(_green_zone, _min_yellow_zone_size);
_red_zone = calc_new_red_zone(_green_zone, _yellow_zone);
@@ -376,37 +381,53 @@
_green_zone, _yellow_zone, _red_zone);
}
-void G1ConcurrentRefine::adjust(double update_rs_time,
- size_t update_rs_processed_buffers,
+void G1ConcurrentRefine::adjust(double logged_cards_scan_time,
+ size_t processed_logged_cards,
double goal_ms) {
G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
if (G1UseAdaptiveConcRefinement) {
- update_zones(update_rs_time, update_rs_processed_buffers, goal_ms);
+ update_zones(logged_cards_scan_time, processed_logged_cards, goal_ms);
// Change the barrier params
if (max_num_threads() == 0) {
// Disable dcqs notification when there are no threads to notify.
- dcqs.set_process_completed_buffers_threshold(G1DirtyCardQueueSet::ProcessCompletedBuffersThresholdNever);
+ dcqs.set_process_cards_threshold(G1DirtyCardQueueSet::ProcessCardsThresholdNever);
} else {
// Worker 0 is the primary; wakeup is via dcqs notification.
STATIC_ASSERT(max_yellow_zone <= INT_MAX);
size_t activate = activation_threshold(0);
- dcqs.set_process_completed_buffers_threshold(activate);
+ dcqs.set_process_cards_threshold(activate);
}
- dcqs.set_max_completed_buffers(red_zone());
+ dcqs.set_max_cards(red_zone());
}
- size_t curr_queue_size = dcqs.completed_buffers_num();
- if ((dcqs.max_completed_buffers() > 0) &&
+ size_t curr_queue_size = dcqs.num_cards();
+ if ((dcqs.max_cards() > 0) &&
(curr_queue_size >= yellow_zone())) {
- dcqs.set_completed_buffers_padding(curr_queue_size);
+ dcqs.set_max_cards_padding(curr_queue_size);
} else {
- dcqs.set_completed_buffers_padding(0);
+ dcqs.set_max_cards_padding(0);
}
dcqs.notify_if_necessary();
}
+G1ConcurrentRefine::RefinementStats G1ConcurrentRefine::total_refinement_stats() const {
+ struct CollectData : public ThreadClosure {
+ Tickspan _total_time;
+ size_t _total_cards;
+ CollectData() : _total_time(), _total_cards(0) {}
+ virtual void do_thread(Thread* t) {
+ G1ConcurrentRefineThread* crt = static_cast<G1ConcurrentRefineThread*>(t);
+ _total_time += crt->total_refinement_time();
+ _total_cards += crt->total_refined_cards();
+ }
+ } collector;
+ // Cast away const so we can call non-modifying closure on threads.
+ const_cast<G1ConcurrentRefine*>(this)->threads_do(&collector);
+ return RefinementStats(collector._total_time, collector._total_cards);
+}
+
size_t G1ConcurrentRefine::activation_threshold(uint worker_id) const {
Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, worker_id);
return activation_level(thresholds);
@@ -427,21 +448,23 @@
}
}
-bool G1ConcurrentRefine::do_refinement_step(uint worker_id) {
+bool G1ConcurrentRefine::do_refinement_step(uint worker_id,
+ size_t* total_refined_cards) {
G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
- size_t curr_buffer_num = dcqs.completed_buffers_num();
- // If the number of the buffers falls down into the yellow zone,
+ size_t curr_cards = dcqs.num_cards();
+ // If the number of the cards falls down into the yellow zone,
// that means that the transition period after the evacuation pause has ended.
// Since the value written to the DCQS is the same for all threads, there is no
// need to synchronize.
- if (dcqs.completed_buffers_padding() > 0 && curr_buffer_num <= yellow_zone()) {
- dcqs.set_completed_buffers_padding(0);
+ if (dcqs.max_cards_padding() > 0 && curr_cards <= yellow_zone()) {
+ dcqs.set_max_cards_padding(0);
}
- maybe_activate_more_threads(worker_id, curr_buffer_num);
+ maybe_activate_more_threads(worker_id, curr_cards);
// Process the next buffer, if there are enough left.
return dcqs.refine_completed_buffer_concurrently(worker_id + worker_id_offset(),
- deactivation_threshold(worker_id));
+ deactivation_threshold(worker_id),
+ total_refined_cards);
}