35 #include "gc/g1/g1GCPhaseTimes.hpp" |
35 #include "gc/g1/g1GCPhaseTimes.hpp" |
36 #include "gc/g1/g1Policy.hpp" |
36 #include "gc/g1/g1Policy.hpp" |
37 #include "gc/g1/g1YoungGenSizer.hpp" |
37 #include "gc/g1/g1YoungGenSizer.hpp" |
38 #include "gc/g1/heapRegion.inline.hpp" |
38 #include "gc/g1/heapRegion.inline.hpp" |
39 #include "gc/g1/heapRegionRemSet.hpp" |
39 #include "gc/g1/heapRegionRemSet.hpp" |
|
40 #include "gc/g1/youngList.hpp" |
40 #include "gc/shared/gcPolicyCounters.hpp" |
41 #include "gc/shared/gcPolicyCounters.hpp" |
|
42 #include "logging/logStream.hpp" |
41 #include "runtime/arguments.hpp" |
43 #include "runtime/arguments.hpp" |
42 #include "runtime/java.hpp" |
44 #include "runtime/java.hpp" |
43 #include "runtime/mutexLocker.hpp" |
45 #include "runtime/mutexLocker.hpp" |
44 #include "utilities/debug.hpp" |
46 #include "utilities/debug.hpp" |
45 #include "utilities/growableArray.hpp" |
47 #include "utilities/growableArray.hpp" |
193 YoungTargetLengths result; |
195 YoungTargetLengths result; |
194 |
196 |
195 // Calculate the absolute and desired min bounds first. |
197 // Calculate the absolute and desired min bounds first. |
196 |
198 |
197 // This is how many young regions we already have (currently: the survivors). |
199 // This is how many young regions we already have (currently: the survivors). |
198 const uint base_min_length = _g1->young_list()->survivor_length(); |
200 const uint base_min_length = _g1->survivor_regions_count(); |
199 uint desired_min_length = calculate_young_list_desired_min_length(base_min_length); |
201 uint desired_min_length = calculate_young_list_desired_min_length(base_min_length); |
200 // This is the absolute minimum young length. Ensure that we |
202 // This is the absolute minimum young length. Ensure that we |
201 // will at least have one eden region available for allocation. |
203 // will at least have one eden region available for allocation. |
202 uint absolute_min_length = base_min_length + MAX2(_g1->young_list()->eden_length(), (uint)1); |
204 uint absolute_min_length = base_min_length + MAX2(_g1->eden_regions_count(), (uint)1); |
203 // If we shrank the young list target it should not shrink below the current size. |
205 // If we shrank the young list target it should not shrink below the current size. |
204 desired_min_length = MAX2(desired_min_length, absolute_min_length); |
206 desired_min_length = MAX2(desired_min_length, absolute_min_length); |
205 // Calculate the absolute and desired max bounds. |
207 // Calculate the absolute and desired max bounds. |
206 |
208 |
207 uint desired_max_length = calculate_young_list_desired_max_length(); |
209 uint desired_max_length = calculate_young_list_desired_max_length(); |
358 return base_min_length + min_young_length; |
360 return base_min_length + min_young_length; |
359 } |
361 } |
360 |
362 |
361 double G1DefaultPolicy::predict_survivor_regions_evac_time() const { |
363 double G1DefaultPolicy::predict_survivor_regions_evac_time() const { |
362 double survivor_regions_evac_time = 0.0; |
364 double survivor_regions_evac_time = 0.0; |
363 const GrowableArray<HeapRegion*>* survivor_regions = _g1->young_list()->survivor_regions(); |
365 const GrowableArray<HeapRegion*>* survivor_regions = _g1->survivor()->regions(); |
364 |
366 |
365 for (GrowableArrayIterator<HeapRegion*> it = survivor_regions->begin(); |
367 for (GrowableArrayIterator<HeapRegion*> it = survivor_regions->begin(); |
366 it != survivor_regions->end(); |
368 it != survivor_regions->end(); |
367 ++it) { |
369 ++it) { |
368 survivor_regions_evac_time += predict_region_elapsed_time_ms(*it, collector_state()->gcs_are_young()); |
370 survivor_regions_evac_time += predict_region_elapsed_time_ms(*it, collector_state()->gcs_are_young()); |
392 } |
394 } |
393 } |
395 } |
394 |
396 |
395 #ifndef PRODUCT |
397 #ifndef PRODUCT |
396 bool G1DefaultPolicy::verify_young_ages() { |
398 bool G1DefaultPolicy::verify_young_ages() { |
397 HeapRegion* head = _g1->young_list()->first_region(); |
399 return verify_young_ages(_collection_set->inc_head(), _short_lived_surv_rate_group); |
398 return |
|
399 verify_young_ages(head, _short_lived_surv_rate_group); |
|
400 // also call verify_young_ages on any additional surv rate groups |
|
401 } |
400 } |
402 |
401 |
403 bool G1DefaultPolicy::verify_young_ages(HeapRegion* head, SurvRateGroup *surv_rate_group) { |
402 bool G1DefaultPolicy::verify_young_ages(HeapRegion* head, SurvRateGroup *surv_rate_group) { |
404 guarantee( surv_rate_group != NULL, "pre-condition" ); |
403 guarantee( surv_rate_group != NULL, "pre-condition" ); |
405 |
404 |
406 const char* name = surv_rate_group->name(); |
405 const char* name = surv_rate_group->name(); |
407 bool ret = true; |
406 bool ret = true; |
408 int prev_age = -1; |
|
409 |
407 |
410 for (HeapRegion* curr = head; |
408 for (HeapRegion* curr = head; |
411 curr != NULL; |
409 curr != NULL; |
412 curr = curr->get_next_young_region()) { |
410 curr = curr->next_in_collection_set()) { |
413 SurvRateGroup* group = curr->surv_rate_group(); |
411 SurvRateGroup* group = curr->surv_rate_group(); |
414 if (group == NULL && !curr->is_survivor()) { |
412 if (group == NULL && !curr->is_survivor()) { |
415 log_error(gc, verify)("## %s: encountered NULL surv_rate_group", name); |
413 log_error(gc, verify)("## %s: encountered NULL surv_rate_group", name); |
416 ret = false; |
414 ret = false; |
417 } |
415 } |
418 |
416 |
419 if (surv_rate_group == group) { |
417 if (surv_rate_group == group) { |
420 int age = curr->age_in_surv_rate_group(); |
418 if (curr->age_in_surv_rate_group() < 0) { |
421 |
|
422 if (age < 0) { |
|
423 log_error(gc, verify)("## %s: encountered negative age", name); |
419 log_error(gc, verify)("## %s: encountered negative age", name); |
424 ret = false; |
420 ret = false; |
425 } |
421 } |
426 |
422 } |
427 if (age <= prev_age) { |
423 } |
428 log_error(gc, verify)("## %s: region ages are not strictly increasing (%d, %d)", name, age, prev_age); |
424 |
429 ret = false; |
425 if (!ret) { |
430 } |
426 LogStreamHandle(Error, gc, verify) log; |
431 prev_age = age; |
427 _collection_set->print(head, &log); |
432 } |
|
433 } |
428 } |
434 |
429 |
435 return ret; |
430 return ret; |
436 } |
431 } |
437 #endif // PRODUCT |
432 #endif // PRODUCT |
910 // add this call for any other surv rate groups |
905 // add this call for any other surv rate groups |
911 #endif // PRODUCT |
906 #endif // PRODUCT |
912 } |
907 } |
913 |
908 |
914 bool G1DefaultPolicy::should_allocate_mutator_region() const { |
909 bool G1DefaultPolicy::should_allocate_mutator_region() const { |
915 uint young_list_length = _g1->young_list()->length(); |
910 uint young_list_length = _g1->young_regions_count(); |
916 uint young_list_target_length = _young_list_target_length; |
911 uint young_list_target_length = _young_list_target_length; |
917 return young_list_length < young_list_target_length; |
912 return young_list_length < young_list_target_length; |
918 } |
913 } |
919 |
914 |
920 bool G1DefaultPolicy::can_expand_young_list() const { |
915 bool G1DefaultPolicy::can_expand_young_list() const { |
921 uint young_list_length = _g1->young_list()->length(); |
916 uint young_list_length = _g1->young_regions_count(); |
922 uint young_list_max_length = _young_list_max_length; |
917 uint young_list_max_length = _young_list_max_length; |
923 return young_list_length < young_list_max_length; |
918 return young_list_length < young_list_max_length; |
924 } |
919 } |
925 |
920 |
926 bool G1DefaultPolicy::adaptive_young_list_length() const { |
921 bool G1DefaultPolicy::adaptive_young_list_length() const { |
1158 result += 1; |
1153 result += 1; |
1159 } |
1154 } |
1160 return (uint) result; |
1155 return (uint) result; |
1161 } |
1156 } |
1162 |
1157 |
1163 void G1DefaultPolicy::finalize_collection_set(double target_pause_time_ms) { |
1158 void G1DefaultPolicy::finalize_collection_set(double target_pause_time_ms, G1SurvivorRegions* survivor) { |
1164 double time_remaining_ms = _collection_set->finalize_young_part(target_pause_time_ms); |
1159 double time_remaining_ms = _collection_set->finalize_young_part(target_pause_time_ms, survivor); |
1165 _collection_set->finalize_old_part(time_remaining_ms); |
1160 _collection_set->finalize_old_part(time_remaining_ms); |
1166 } |
1161 } |
|
1162 |
|
1163 void G1DefaultPolicy::transfer_survivors_to_cset(const G1SurvivorRegions* survivors) { |
|
1164 |
|
1165 // Add survivor regions to SurvRateGroup. |
|
1166 note_start_adding_survivor_regions(); |
|
1167 finished_recalculating_age_indexes(true /* is_survivors */); |
|
1168 |
|
1169 HeapRegion* last = NULL; |
|
1170 for (GrowableArrayIterator<HeapRegion*> it = survivors->regions()->begin(); |
|
1171 it != survivors->regions()->end(); |
|
1172 ++it) { |
|
1173 HeapRegion* curr = *it; |
|
1174 set_region_survivor(curr); |
|
1175 |
|
1176 // The region is a non-empty survivor so let's add it to |
|
1177 // the incremental collection set for the next evacuation |
|
1178 // pause. |
|
1179 _collection_set->add_survivor_regions(curr); |
|
1180 |
|
1181 last = curr; |
|
1182 } |
|
1183 note_stop_adding_survivor_regions(); |
|
1184 |
|
1185 // Don't clear the survivor list handles until the start of |
|
1186 // the next evacuation pause - we need it in order to re-tag |
|
1187 // the survivor regions from this evacuation pause as 'young' |
|
1188 // at the start of the next. |
|
1189 |
|
1190 finished_recalculating_age_indexes(false /* is_survivors */); |
|
1191 } |