< prev index next >
src/share/vm/gc/g1/g1CollectorPolicy.cpp
Print this page
rev 9402 : dihop-changes
rev 9404 : [mq]: erik-jmasa-review
*** 37,46 ****
--- 37,47 ----
#include "gc/shared/gcPolicyCounters.hpp"
#include "runtime/arguments.hpp"
#include "runtime/java.hpp"
#include "runtime/mutexLocker.hpp"
#include "utilities/debug.hpp"
+ #include "utilities/pair.hpp"
// Different defaults for different number of GC threads
// They were chosen by running GCOld and SPECjbb on debris with different
// numbers of GC threads and choosing them based on the results
*** 292,304 ****
_collectionSetChooser = new CollectionSetChooser();
}
G1CollectorPolicy::~G1CollectorPolicy() {
- if (_ihop_control != NULL) {
delete _ihop_control;
- }
}
double G1CollectorPolicy::get_new_prediction(TruncatedSeq const* seq) const {
return _predictor.get_new_prediction(seq);
}
--- 293,303 ----
*** 533,561 ****
// constraints (i.e., user-defined minimum bound). Currently, we
// effectively don't set this bound.
return _young_gen_sizer->max_desired_young_length();
}
! void G1CollectorPolicy::update_young_list_max_and_target_length(size_t* unbounded_target_length) {
! update_young_list_max_and_target_length(get_new_prediction(_rs_lengths_seq), unbounded_target_length);
}
! void G1CollectorPolicy::update_young_list_max_and_target_length(size_t rs_lengths, size_t* unbounded_target_length) {
! update_young_list_target_length(rs_lengths, unbounded_target_length);
update_max_gc_locker_expansion();
}
! void G1CollectorPolicy::update_young_list_target_length(size_t rs_lengths, size_t* unbounded_target_length) {
! _young_list_target_length = bounded_young_list_target_length(rs_lengths, unbounded_target_length);
}
! void G1CollectorPolicy::update_young_list_target_length() {
! update_young_list_target_length(get_new_prediction(_rs_lengths_seq));
! }
! uint G1CollectorPolicy::bounded_young_list_target_length(size_t rs_lengths, size_t* unbounded_target_length) const {
! // Calculate the absolute and desired min bounds.
// This is how many young regions we already have (currently: the survivors).
uint base_min_length = recorded_survivor_regions();
uint desired_min_length = calculate_young_list_desired_min_length(base_min_length);
// This is the absolute minimum young length. Ensure that we
--- 532,561 ----
// constraints (i.e., user-defined minimum bound). Currently, we
// effectively don't set this bound.
return _young_gen_sizer->max_desired_young_length();
}
! uint G1CollectorPolicy::update_young_list_max_and_target_length() {
! return update_young_list_max_and_target_length(get_new_prediction(_rs_lengths_seq));
}
! uint G1CollectorPolicy::update_young_list_max_and_target_length(size_t rs_lengths) {
! uint unbounded_target_length = update_young_list_target_length(rs_lengths);
update_max_gc_locker_expansion();
+ return unbounded_target_length;
}
! uint G1CollectorPolicy::update_young_list_target_length(size_t rs_lengths) {
! YoungTargetLengths young_lengths = young_list_target_lengths(rs_lengths);
! _young_list_target_length = young_lengths.first;
! return young_lengths.second;
}
! G1CollectorPolicy::YoungTargetLengths G1CollectorPolicy::young_list_target_lengths(size_t rs_lengths) const {
! YoungTargetLengths result;
! // Calculate the absolute and desired min bounds first.
// This is how many young regions we already have (currently: the survivors).
uint base_min_length = recorded_survivor_regions();
uint desired_min_length = calculate_young_list_desired_min_length(base_min_length);
// This is the absolute minimum young length. Ensure that we
*** 584,596 ****
// The user asked for a fixed young gen so we'll fix the young gen
// whether the next GC is young or mixed.
young_list_target_length = _young_list_fixed_length;
}
! if (unbounded_target_length != NULL) {
! *unbounded_target_length = young_list_target_length;
! }
// We will try our best not to "eat" into the reserve.
uint absolute_max_length = 0;
if (_free_regions_at_end_of_collection > _reserve_regions) {
absolute_max_length = _free_regions_at_end_of_collection - _reserve_regions;
--- 584,594 ----
// The user asked for a fixed young gen so we'll fix the young gen
// whether the next GC is young or mixed.
young_list_target_length = _young_list_fixed_length;
}
! result.second = young_list_target_length;
// We will try our best not to "eat" into the reserve.
uint absolute_max_length = 0;
if (_free_regions_at_end_of_collection > _reserve_regions) {
absolute_max_length = _free_regions_at_end_of_collection - _reserve_regions;
*** 611,621 ****
assert(young_list_target_length > recorded_survivor_regions(),
"we should be able to allocate at least one eden region");
assert(young_list_target_length >= absolute_min_length, "post-condition");
! return young_list_target_length;
}
uint
G1CollectorPolicy::calculate_young_list_target_length(size_t rs_lengths,
uint base_min_length,
--- 609,620 ----
assert(young_list_target_length > recorded_survivor_regions(),
"we should be able to allocate at least one eden region");
assert(young_list_target_length >= absolute_min_length, "post-condition");
! result.first = young_list_target_length;
! return result;
}
uint
G1CollectorPolicy::calculate_young_list_target_length(size_t rs_lengths,
uint base_min_length,
*** 926,936 ****
void G1CollectorPolicy::record_concurrent_mark_cleanup_completed() {
bool should_continue_with_reclaim = next_gc_should_be_mixed("request last young-only gc",
"skip last young-only gc");
collector_state()->set_last_young_gc(should_continue_with_reclaim);
! // We abort the marking phase.
if (!should_continue_with_reclaim) {
abort_time_to_mixed_tracking();
}
collector_state()->set_in_marking_window(false);
}
--- 925,935 ----
void G1CollectorPolicy::record_concurrent_mark_cleanup_completed() {
bool should_continue_with_reclaim = next_gc_should_be_mixed("request last young-only gc",
"skip last young-only gc");
collector_state()->set_last_young_gc(should_continue_with_reclaim);
! // We skip the marking phase.
if (!should_continue_with_reclaim) {
abort_time_to_mixed_tracking();
}
collector_state()->set_in_marking_window(false);
}
*** 1045,1067 ****
record_concurrent_mark_init_end(0.0);
} else {
maybe_start_marking();
}
! double app_time_ms = 1.0;
!
! if (update_stats) {
! _trace_young_gen_time_data.record_end_collection(pause_time_ms, phase_times());
! // this is where we update the allocation rate of the application
! app_time_ms =
! (phase_times()->cur_collection_start_sec() * 1000.0 - _prev_collection_pause_end_ms);
if (app_time_ms < MIN_TIMER_GRANULARITY) {
// This usually happens due to the timer not having the required
// granularity. Some Linuxes are the usual culprits.
// We'll just set it to something (arbitrarily) small.
app_time_ms = 1.0;
}
// We maintain the invariant that all objects allocated by mutator
// threads will be allocated out of eden regions. So, we can use
// the eden region number allocated since the previous GC to
// calculate the application's allocate rate. The only exception
// to that is humongous objects that are allocated separately. But
--- 1044,1063 ----
record_concurrent_mark_init_end(0.0);
} else {
maybe_start_marking();
}
! double app_time_ms = (phase_times()->cur_collection_start_sec() * 1000.0 - _prev_collection_pause_end_ms);
if (app_time_ms < MIN_TIMER_GRANULARITY) {
// This usually happens due to the timer not having the required
// granularity. Some Linuxes are the usual culprits.
// We'll just set it to something (arbitrarily) small.
app_time_ms = 1.0;
}
+
+ if (update_stats) {
+ _trace_young_gen_time_data.record_end_collection(pause_time_ms, phase_times());
// We maintain the invariant that all objects allocated by mutator
// threads will be allocated out of eden regions. So, we can use
// the eden region number allocated since the previous GC to
// calculate the application's allocate rate. The only exception
// to that is humongous objects that are allocated separately. But
*** 1208,1230 ****
_free_regions_at_end_of_collection = _g1->num_free_regions();
// IHOP control wants to know the expected young gen length if it were not
// restrained by the heap reserve. Using the actual length would make the
// prediction too small and the limit the young gen every time we get to the
// predicted target occupancy.
! size_t last_unrestrained_young_length = 0;
! update_young_list_max_and_target_length(&last_unrestrained_young_length);
update_rs_lengths_prediction();
double marking_to_mixed_time = -1.0;
if (!collector_state()->last_gc_was_young() && _initial_mark_to_mixed.has_result()) {
marking_to_mixed_time = _initial_mark_to_mixed.last_marking_time();
assert(marking_to_mixed_time > 0.0,
"Initial mark to mixed time must be larger than zero but is %.3f",
marking_to_mixed_time);
}
! // Only update IHOP information on regular GCs.
! if (update_stats) {
update_ihop_statistics(marking_to_mixed_time,
app_time_ms / 1000.0,
_last_old_allocated_bytes,
last_unrestrained_young_length * HeapRegion::GrainBytes);
}
--- 1204,1226 ----
_free_regions_at_end_of_collection = _g1->num_free_regions();
// IHOP control wants to know the expected young gen length if it were not
// restrained by the heap reserve. Using the actual length would make the
// prediction too small and the limit the young gen every time we get to the
// predicted target occupancy.
! size_t last_unrestrained_young_length = update_young_list_max_and_target_length();
update_rs_lengths_prediction();
+ // Only update IHOP information on regular GCs.
+ if (update_stats) {
double marking_to_mixed_time = -1.0;
if (!collector_state()->last_gc_was_young() && _initial_mark_to_mixed.has_result()) {
marking_to_mixed_time = _initial_mark_to_mixed.last_marking_time();
assert(marking_to_mixed_time > 0.0,
"Initial mark to mixed time must be larger than zero but is %.3f",
marking_to_mixed_time);
}
!
update_ihop_statistics(marking_to_mixed_time,
app_time_ms / 1000.0,
_last_old_allocated_bytes,
last_unrestrained_young_length * HeapRegion::GrainBytes);
}
*** 1269,1279 ****
// To avoid using really small times that may be caused by e.g. back-to-back gcs
// we filter them out.
double const min_valid_time = 1e-6;
if (marking_time > min_valid_time) {
! _ihop_control->update_time_to_mixed(marking_time);
report = true;
}
// As an approximation for the young gc promotion rates during marking we use
// all of them. In many applications there are only a few if any young gcs during
--- 1265,1275 ----
// To avoid using really small times that may be caused by e.g. back-to-back gcs
// we filter them out.
double const min_valid_time = 1e-6;
if (marking_time > min_valid_time) {
! _ihop_control->update_marking_length(marking_time);
report = true;
}
// As an approximation for the young gc promotion rates during marking we use
// all of them. In many applications there are only a few if any young gcs during
< prev index next >