src/hotspot/share/gc/g1/g1CollectionSet.cpp
changeset 57663 bf8e76d86d05
parent 55510 3e31a8beaae4
child 57802 854e828d6b5b
equal deleted inserted replaced
57662:f81dbe27a7b1 57663:bf8e76d86d05
    59   _collection_set_regions(NULL),
    59   _collection_set_regions(NULL),
    60   _collection_set_cur_length(0),
    60   _collection_set_cur_length(0),
    61   _collection_set_max_length(0),
    61   _collection_set_max_length(0),
    62   _num_optional_regions(0),
    62   _num_optional_regions(0),
    63   _bytes_used_before(0),
    63   _bytes_used_before(0),
    64   _recorded_rs_lengths(0),
    64   _recorded_rs_length(0),
    65   _inc_build_state(Inactive),
    65   _inc_build_state(Inactive),
    66   _inc_part_start(0),
    66   _inc_part_start(0),
    67   _inc_bytes_used_before(0),
    67   _inc_bytes_used_before(0),
    68   _inc_recorded_rs_lengths(0),
    68   _inc_recorded_rs_length(0),
    69   _inc_recorded_rs_lengths_diffs(0),
    69   _inc_recorded_rs_length_diff(0),
    70   _inc_predicted_elapsed_time_ms(0.0),
    70   _inc_predicted_elapsed_time_ms(0.0),
    71   _inc_predicted_elapsed_time_ms_diffs(0.0) {
    71   _inc_predicted_elapsed_time_ms_diff(0.0) {
    72 }
    72 }
    73 
    73 
    74 G1CollectionSet::~G1CollectionSet() {
    74 G1CollectionSet::~G1CollectionSet() {
    75   if (_collection_set_regions != NULL) {
    75   if (_collection_set_regions != NULL) {
    76     FREE_C_HEAP_ARRAY(uint, _collection_set_regions);
    76     FREE_C_HEAP_ARRAY(uint, _collection_set_regions);
   106 void G1CollectionSet::clear_candidates() {
   106 void G1CollectionSet::clear_candidates() {
   107   delete _candidates;
   107   delete _candidates;
   108   _candidates = NULL;
   108   _candidates = NULL;
   109 }
   109 }
   110 
   110 
   111 void G1CollectionSet::set_recorded_rs_lengths(size_t rs_lengths) {
   111 void G1CollectionSet::set_recorded_rs_length(size_t rs_length) {
   112   _recorded_rs_lengths = rs_lengths;
   112   _recorded_rs_length = rs_length;
   113 }
   113 }
   114 
   114 
   115 // Add the heap region at the head of the non-incremental collection set
   115 // Add the heap region at the head of the non-incremental collection set
   116 void G1CollectionSet::add_old_region(HeapRegion* hr) {
   116 void G1CollectionSet::add_old_region(HeapRegion* hr) {
   117   assert_at_safepoint_on_vm_thread();
   117   assert_at_safepoint_on_vm_thread();
   125 
   125 
   126   _collection_set_regions[_collection_set_cur_length++] = hr->hrm_index();
   126   _collection_set_regions[_collection_set_cur_length++] = hr->hrm_index();
   127   assert(_collection_set_cur_length <= _collection_set_max_length, "Collection set now larger than maximum size.");
   127   assert(_collection_set_cur_length <= _collection_set_max_length, "Collection set now larger than maximum size.");
   128 
   128 
   129   _bytes_used_before += hr->used();
   129   _bytes_used_before += hr->used();
   130   _recorded_rs_lengths += hr->rem_set()->occupied();
   130   _recorded_rs_length += hr->rem_set()->occupied();
   131   _old_region_length++;
   131   _old_region_length++;
   132 
   132 
   133   _g1h->old_set_remove(hr);
   133   _g1h->old_set_remove(hr);
   134 }
   134 }
   135 
   135 
   146   assert(_collection_set_cur_length == 0, "Collection set must be empty before starting a new collection set.");
   146   assert(_collection_set_cur_length == 0, "Collection set must be empty before starting a new collection set.");
   147   assert(_inc_build_state == Inactive, "Precondition");
   147   assert(_inc_build_state == Inactive, "Precondition");
   148 
   148 
   149   _inc_bytes_used_before = 0;
   149   _inc_bytes_used_before = 0;
   150 
   150 
   151   _inc_recorded_rs_lengths = 0;
   151   _inc_recorded_rs_length = 0;
   152   _inc_recorded_rs_lengths_diffs = 0;
   152   _inc_recorded_rs_length_diff = 0;
   153   _inc_predicted_elapsed_time_ms = 0.0;
   153   _inc_predicted_elapsed_time_ms = 0.0;
   154   _inc_predicted_elapsed_time_ms_diffs = 0.0;
   154   _inc_predicted_elapsed_time_ms_diff = 0.0;
   155 
   155 
   156   update_incremental_marker();
   156   update_incremental_marker();
   157 }
   157 }
   158 
   158 
   159 void G1CollectionSet::finalize_incremental_building() {
   159 void G1CollectionSet::finalize_incremental_building() {
   160   assert(_inc_build_state == Active, "Precondition");
   160   assert(_inc_build_state == Active, "Precondition");
   161   assert(SafepointSynchronize::is_at_safepoint(), "should be at a safepoint");
   161   assert(SafepointSynchronize::is_at_safepoint(), "should be at a safepoint");
   162 
   162 
   163   // The two "main" fields, _inc_recorded_rs_lengths and
   163   // The two "main" fields, _inc_recorded_rs_length and
   164   // _inc_predicted_elapsed_time_ms, are updated by the thread
   164   // _inc_predicted_elapsed_time_ms, are updated by the thread
   165   // that adds a new region to the CSet. Further updates by the
   165   // that adds a new region to the CSet. Further updates by the
   166   // concurrent refinement thread that samples the young RSet lengths
   166   // concurrent refinement thread that samples the young RSet lengths
   167   // are accumulated in the *_diffs fields. Here we add the diffs to
   167   // are accumulated in the *_diff fields. Here we add the diffs to
   168   // the "main" fields.
   168   // the "main" fields.
   169 
   169 
   170   if (_inc_recorded_rs_lengths_diffs >= 0) {
   170   if (_inc_recorded_rs_length_diff >= 0) {
   171     _inc_recorded_rs_lengths += _inc_recorded_rs_lengths_diffs;
   171     _inc_recorded_rs_length += _inc_recorded_rs_length_diff;
   172   } else {
   172   } else {
   173     // This is defensive. The diff should in theory be always positive
   173     // This is defensive. The diff should in theory be always positive
   174     // as RSets can only grow between GCs. However, given that we
   174     // as RSets can only grow between GCs. However, given that we
   175     // sample their size concurrently with other threads updating them
   175     // sample their size concurrently with other threads updating them
   176     // it's possible that we might get the wrong size back, which
   176     // it's possible that we might get the wrong size back, which
   177     // could make the calculations somewhat inaccurate.
   177     // could make the calculations somewhat inaccurate.
   178     size_t diffs = (size_t) (-_inc_recorded_rs_lengths_diffs);
   178     size_t diffs = (size_t) (-_inc_recorded_rs_length_diff);
   179     if (_inc_recorded_rs_lengths >= diffs) {
   179     if (_inc_recorded_rs_length >= diffs) {
   180       _inc_recorded_rs_lengths -= diffs;
   180       _inc_recorded_rs_length -= diffs;
   181     } else {
   181     } else {
   182       _inc_recorded_rs_lengths = 0;
   182       _inc_recorded_rs_length = 0;
   183     }
   183     }
   184   }
   184   }
   185   _inc_predicted_elapsed_time_ms += _inc_predicted_elapsed_time_ms_diffs;
   185   _inc_predicted_elapsed_time_ms += _inc_predicted_elapsed_time_ms_diff;
   186 
   186 
   187   _inc_recorded_rs_lengths_diffs = 0;
   187   _inc_recorded_rs_length_diff = 0;
   188   _inc_predicted_elapsed_time_ms_diffs = 0.0;
   188   _inc_predicted_elapsed_time_ms_diff = 0.0;
   189 }
   189 }
   190 
   190 
   191 void G1CollectionSet::clear() {
   191 void G1CollectionSet::clear() {
   192   assert_at_safepoint_on_vm_thread();
   192   assert_at_safepoint_on_vm_thread();
   193   _collection_set_cur_length = 0;
   193   _collection_set_cur_length = 0;
   250                                                      size_t new_rs_length) {
   250                                                      size_t new_rs_length) {
   251   // Update the CSet information that is dependent on the new RS length
   251   // Update the CSet information that is dependent on the new RS length
   252   assert(hr->is_young(), "Precondition");
   252   assert(hr->is_young(), "Precondition");
   253   assert(!SafepointSynchronize::is_at_safepoint(), "should not be at a safepoint");
   253   assert(!SafepointSynchronize::is_at_safepoint(), "should not be at a safepoint");
   254 
   254 
   255   // We could have updated _inc_recorded_rs_lengths and
   255   // We could have updated _inc_recorded_rs_length and
   256   // _inc_predicted_elapsed_time_ms directly but we'd need to do
   256   // _inc_predicted_elapsed_time_ms directly but we'd need to do
   257   // that atomically, as this code is executed by a concurrent
   257   // that atomically, as this code is executed by a concurrent
   258   // refinement thread, potentially concurrently with a mutator thread
   258   // refinement thread, potentially concurrently with a mutator thread
   259   // allocating a new region and also updating the same fields. To
   259   // allocating a new region and also updating the same fields. To
   260   // avoid the atomic operations we accumulate these updates on two
   260   // avoid the atomic operations we accumulate these updates on two
   261   // separate fields (*_diffs) and we'll just add them to the "main"
   261   // separate fields (*_diff) and we'll just add them to the "main"
   262   // fields at the start of a GC.
   262   // fields at the start of a GC.
   263 
   263 
   264   ssize_t old_rs_length = (ssize_t) hr->recorded_rs_length();
   264   ssize_t old_rs_length = (ssize_t) hr->recorded_rs_length();
   265   ssize_t rs_lengths_diff = (ssize_t) new_rs_length - old_rs_length;
   265   ssize_t rs_length_diff = (ssize_t) new_rs_length - old_rs_length;
   266   _inc_recorded_rs_lengths_diffs += rs_lengths_diff;
   266   _inc_recorded_rs_length_diff += rs_length_diff;
   267 
   267 
   268   double old_elapsed_time_ms = hr->predicted_elapsed_time_ms();
   268   double old_elapsed_time_ms = hr->predicted_elapsed_time_ms();
   269   double new_region_elapsed_time_ms = predict_region_elapsed_time_ms(hr);
   269   double new_region_elapsed_time_ms = predict_region_elapsed_time_ms(hr);
   270   double elapsed_ms_diff = new_region_elapsed_time_ms - old_elapsed_time_ms;
   270   double elapsed_ms_diff = new_region_elapsed_time_ms - old_elapsed_time_ms;
   271   _inc_predicted_elapsed_time_ms_diffs += elapsed_ms_diff;
   271   _inc_predicted_elapsed_time_ms_diff += elapsed_ms_diff;
   272 
   272 
   273   hr->set_recorded_rs_length(new_rs_length);
   273   hr->set_recorded_rs_length(new_rs_length);
   274   hr->set_predicted_elapsed_time_ms(new_region_elapsed_time_ms);
   274   hr->set_predicted_elapsed_time_ms(new_region_elapsed_time_ms);
   275 }
   275 }
   276 
   276 
   314     // the incremental collection set, or it is updated by the
   314     // the incremental collection set, or it is updated by the
   315     // rset sampling code
   315     // rset sampling code
   316     hr->set_recorded_rs_length(rs_length);
   316     hr->set_recorded_rs_length(rs_length);
   317     hr->set_predicted_elapsed_time_ms(region_elapsed_time_ms);
   317     hr->set_predicted_elapsed_time_ms(region_elapsed_time_ms);
   318 
   318 
   319     _inc_recorded_rs_lengths += rs_length;
   319     _inc_recorded_rs_length += rs_length;
   320     _inc_predicted_elapsed_time_ms += region_elapsed_time_ms;
   320     _inc_predicted_elapsed_time_ms += region_elapsed_time_ms;
   321     _inc_bytes_used_before += hr->used();
   321     _inc_bytes_used_before += hr->used();
   322   }
   322   }
   323 
   323 
   324   assert(!hr->in_collection_set(), "invariant");
   324   assert(!hr->in_collection_set(), "invariant");
   435   log_trace(gc, ergo, cset)("Add young regions to CSet. eden: %u regions, survivors: %u regions, predicted young region time: %1.2fms, target pause time: %1.2fms",
   435   log_trace(gc, ergo, cset)("Add young regions to CSet. eden: %u regions, survivors: %u regions, predicted young region time: %1.2fms, target pause time: %1.2fms",
   436                             eden_region_length, survivor_region_length, _inc_predicted_elapsed_time_ms, target_pause_time_ms);
   436                             eden_region_length, survivor_region_length, _inc_predicted_elapsed_time_ms, target_pause_time_ms);
   437 
   437 
   438   // The number of recorded young regions is the incremental
   438   // The number of recorded young regions is the incremental
   439   // collection set's current size
   439   // collection set's current size
   440   set_recorded_rs_lengths(_inc_recorded_rs_lengths);
   440   set_recorded_rs_length(_inc_recorded_rs_length);
   441 
   441 
   442   double young_end_time_sec = os::elapsedTime();
   442   double young_end_time_sec = os::elapsedTime();
   443   phase_times()->record_young_cset_choice_time_ms((young_end_time_sec - young_start_time_sec) * 1000.0);
   443   phase_times()->record_young_cset_choice_time_ms((young_end_time_sec - young_start_time_sec) * 1000.0);
   444 
   444 
   445   return time_remaining_ms;
   445   return time_remaining_ms;