src/hotspot/share/gc/g1/g1CollectionSet.cpp
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 54843 25c329958c70
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
    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   FREE_C_HEAP_ARRAY(uint, _collection_set_regions);
    76     FREE_C_HEAP_ARRAY(uint, _collection_set_regions);
       
    77   }
       
    78   free_optional_regions();
    76   free_optional_regions();
    79   clear_candidates();
    77   clear_candidates();
    80 }
    78 }
    81 
    79 
    82 void G1CollectionSet::init_region_lengths(uint eden_cset_region_length,
    80 void G1CollectionSet::init_region_lengths(uint eden_cset_region_length,
   106 void G1CollectionSet::clear_candidates() {
   104 void G1CollectionSet::clear_candidates() {
   107   delete _candidates;
   105   delete _candidates;
   108   _candidates = NULL;
   106   _candidates = NULL;
   109 }
   107 }
   110 
   108 
   111 void G1CollectionSet::set_recorded_rs_lengths(size_t rs_lengths) {
   109 void G1CollectionSet::set_recorded_rs_length(size_t rs_length) {
   112   _recorded_rs_lengths = rs_lengths;
   110   _recorded_rs_length = rs_length;
   113 }
   111 }
   114 
   112 
   115 // Add the heap region at the head of the non-incremental collection set
   113 // Add the heap region at the head of the non-incremental collection set
   116 void G1CollectionSet::add_old_region(HeapRegion* hr) {
   114 void G1CollectionSet::add_old_region(HeapRegion* hr) {
   117   assert_at_safepoint_on_vm_thread();
   115   assert_at_safepoint_on_vm_thread();
   125 
   123 
   126   _collection_set_regions[_collection_set_cur_length++] = hr->hrm_index();
   124   _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.");
   125   assert(_collection_set_cur_length <= _collection_set_max_length, "Collection set now larger than maximum size.");
   128 
   126 
   129   _bytes_used_before += hr->used();
   127   _bytes_used_before += hr->used();
   130   _recorded_rs_lengths += hr->rem_set()->occupied();
   128   _recorded_rs_length += hr->rem_set()->occupied();
   131   _old_region_length++;
   129   _old_region_length++;
   132 
   130 
   133   _g1h->old_set_remove(hr);
   131   _g1h->old_set_remove(hr);
   134 }
   132 }
   135 
   133 
   146   assert(_collection_set_cur_length == 0, "Collection set must be empty before starting a new collection set.");
   144   assert(_collection_set_cur_length == 0, "Collection set must be empty before starting a new collection set.");
   147   assert(_inc_build_state == Inactive, "Precondition");
   145   assert(_inc_build_state == Inactive, "Precondition");
   148 
   146 
   149   _inc_bytes_used_before = 0;
   147   _inc_bytes_used_before = 0;
   150 
   148 
   151   _inc_recorded_rs_lengths = 0;
   149   _inc_recorded_rs_length = 0;
   152   _inc_recorded_rs_lengths_diffs = 0;
   150   _inc_recorded_rs_length_diff = 0;
   153   _inc_predicted_elapsed_time_ms = 0.0;
   151   _inc_predicted_elapsed_time_ms = 0.0;
   154   _inc_predicted_elapsed_time_ms_diffs = 0.0;
   152   _inc_predicted_elapsed_time_ms_diff = 0.0;
   155 
   153 
   156   update_incremental_marker();
   154   update_incremental_marker();
   157 }
   155 }
   158 
   156 
   159 void G1CollectionSet::finalize_incremental_building() {
   157 void G1CollectionSet::finalize_incremental_building() {
   160   assert(_inc_build_state == Active, "Precondition");
   158   assert(_inc_build_state == Active, "Precondition");
   161   assert(SafepointSynchronize::is_at_safepoint(), "should be at a safepoint");
   159   assert(SafepointSynchronize::is_at_safepoint(), "should be at a safepoint");
   162 
   160 
   163   // The two "main" fields, _inc_recorded_rs_lengths and
   161   // The two "main" fields, _inc_recorded_rs_length and
   164   // _inc_predicted_elapsed_time_ms, are updated by the thread
   162   // _inc_predicted_elapsed_time_ms, are updated by the thread
   165   // that adds a new region to the CSet. Further updates by the
   163   // that adds a new region to the CSet. Further updates by the
   166   // concurrent refinement thread that samples the young RSet lengths
   164   // concurrent refinement thread that samples the young RSet lengths
   167   // are accumulated in the *_diffs fields. Here we add the diffs to
   165   // are accumulated in the *_diff fields. Here we add the diffs to
   168   // the "main" fields.
   166   // the "main" fields.
   169 
   167 
   170   if (_inc_recorded_rs_lengths_diffs >= 0) {
   168   if (_inc_recorded_rs_length_diff >= 0) {
   171     _inc_recorded_rs_lengths += _inc_recorded_rs_lengths_diffs;
   169     _inc_recorded_rs_length += _inc_recorded_rs_length_diff;
   172   } else {
   170   } else {
   173     // This is defensive. The diff should in theory be always positive
   171     // This is defensive. The diff should in theory be always positive
   174     // as RSets can only grow between GCs. However, given that we
   172     // as RSets can only grow between GCs. However, given that we
   175     // sample their size concurrently with other threads updating them
   173     // sample their size concurrently with other threads updating them
   176     // it's possible that we might get the wrong size back, which
   174     // it's possible that we might get the wrong size back, which
   177     // could make the calculations somewhat inaccurate.
   175     // could make the calculations somewhat inaccurate.
   178     size_t diffs = (size_t) (-_inc_recorded_rs_lengths_diffs);
   176     size_t diffs = (size_t) (-_inc_recorded_rs_length_diff);
   179     if (_inc_recorded_rs_lengths >= diffs) {
   177     if (_inc_recorded_rs_length >= diffs) {
   180       _inc_recorded_rs_lengths -= diffs;
   178       _inc_recorded_rs_length -= diffs;
   181     } else {
   179     } else {
   182       _inc_recorded_rs_lengths = 0;
   180       _inc_recorded_rs_length = 0;
   183     }
   181     }
   184   }
   182   }
   185   _inc_predicted_elapsed_time_ms += _inc_predicted_elapsed_time_ms_diffs;
   183   _inc_predicted_elapsed_time_ms += _inc_predicted_elapsed_time_ms_diff;
   186 
   184 
   187   _inc_recorded_rs_lengths_diffs = 0;
   185   _inc_recorded_rs_length_diff = 0;
   188   _inc_predicted_elapsed_time_ms_diffs = 0.0;
   186   _inc_predicted_elapsed_time_ms_diff = 0.0;
   189 }
   187 }
   190 
   188 
   191 void G1CollectionSet::clear() {
   189 void G1CollectionSet::clear() {
   192   assert_at_safepoint_on_vm_thread();
   190   assert_at_safepoint_on_vm_thread();
   193   _collection_set_cur_length = 0;
   191   _collection_set_cur_length = 0;
   215     bool result = cl->do_heap_region(r);
   213     bool result = cl->do_heap_region(r);
   216     guarantee(!result, "Must not cancel iteration");
   214     guarantee(!result, "Must not cancel iteration");
   217   }
   215   }
   218 }
   216 }
   219 
   217 
   220 void G1CollectionSet::iterate_incremental_part_from(HeapRegionClosure* cl, uint worker_id, uint total_workers) const {
   218 void G1CollectionSet::iterate_incremental_part_from(HeapRegionClosure* cl,
       
   219                                                     HeapRegionClaimer* hr_claimer,
       
   220                                                     uint worker_id,
       
   221                                                     uint total_workers) const {
   221   assert_at_safepoint();
   222   assert_at_safepoint();
   222 
   223 
   223   size_t len = _collection_set_cur_length - _inc_part_start;
   224   size_t len = increment_length();
   224   if (len == 0) {
   225   if (len == 0) {
   225     return;
   226     return;
   226   }
   227   }
   227 
   228 
   228   size_t start_pos = (worker_id * len) / total_workers;
   229   size_t start_pos = (worker_id * len) / total_workers;
   229   size_t cur_pos = start_pos;
   230   size_t cur_pos = start_pos;
   230 
   231 
   231   do {
   232   do {
   232     HeapRegion* r = _g1h->region_at(_collection_set_regions[cur_pos + _inc_part_start]);
   233     uint region_idx = _collection_set_regions[cur_pos + _inc_part_start];
   233     bool result = cl->do_heap_region(r);
   234     if (hr_claimer == NULL || hr_claimer->claim_region(region_idx)) {
   234     guarantee(!result, "Must not cancel iteration");
   235       HeapRegion* r = _g1h->region_at(region_idx);
       
   236       bool result = cl->do_heap_region(r);
       
   237       guarantee(!result, "Must not cancel iteration");
       
   238     }
   235 
   239 
   236     cur_pos++;
   240     cur_pos++;
   237     if (cur_pos == len) {
   241     if (cur_pos == len) {
   238       cur_pos = 0;
   242       cur_pos = 0;
   239     }
   243     }
   244                                                      size_t new_rs_length) {
   248                                                      size_t new_rs_length) {
   245   // Update the CSet information that is dependent on the new RS length
   249   // Update the CSet information that is dependent on the new RS length
   246   assert(hr->is_young(), "Precondition");
   250   assert(hr->is_young(), "Precondition");
   247   assert(!SafepointSynchronize::is_at_safepoint(), "should not be at a safepoint");
   251   assert(!SafepointSynchronize::is_at_safepoint(), "should not be at a safepoint");
   248 
   252 
   249   // We could have updated _inc_recorded_rs_lengths and
   253   // We could have updated _inc_recorded_rs_length and
   250   // _inc_predicted_elapsed_time_ms directly but we'd need to do
   254   // _inc_predicted_elapsed_time_ms directly but we'd need to do
   251   // that atomically, as this code is executed by a concurrent
   255   // that atomically, as this code is executed by a concurrent
   252   // refinement thread, potentially concurrently with a mutator thread
   256   // refinement thread, potentially concurrently with a mutator thread
   253   // allocating a new region and also updating the same fields. To
   257   // allocating a new region and also updating the same fields. To
   254   // avoid the atomic operations we accumulate these updates on two
   258   // avoid the atomic operations we accumulate these updates on two
   255   // separate fields (*_diffs) and we'll just add them to the "main"
   259   // separate fields (*_diff) and we'll just add them to the "main"
   256   // fields at the start of a GC.
   260   // fields at the start of a GC.
   257 
   261 
   258   ssize_t old_rs_length = (ssize_t) hr->recorded_rs_length();
   262   ssize_t old_rs_length = (ssize_t) hr->recorded_rs_length();
   259   ssize_t rs_lengths_diff = (ssize_t) new_rs_length - old_rs_length;
   263   ssize_t rs_length_diff = (ssize_t) new_rs_length - old_rs_length;
   260   _inc_recorded_rs_lengths_diffs += rs_lengths_diff;
   264   _inc_recorded_rs_length_diff += rs_length_diff;
   261 
   265 
   262   double old_elapsed_time_ms = hr->predicted_elapsed_time_ms();
   266   double old_elapsed_time_ms = hr->predicted_elapsed_time_ms();
   263   double new_region_elapsed_time_ms = predict_region_elapsed_time_ms(hr);
   267   double new_region_elapsed_time_ms = predict_region_elapsed_time_ms(hr);
   264   double elapsed_ms_diff = new_region_elapsed_time_ms - old_elapsed_time_ms;
   268   double elapsed_ms_diff = new_region_elapsed_time_ms - old_elapsed_time_ms;
   265   _inc_predicted_elapsed_time_ms_diffs += elapsed_ms_diff;
   269   _inc_predicted_elapsed_time_ms_diff += elapsed_ms_diff;
   266 
   270 
   267   hr->set_recorded_rs_length(new_rs_length);
   271   hr->set_recorded_rs_length(new_rs_length);
   268   hr->set_predicted_elapsed_time_ms(new_region_elapsed_time_ms);
   272   hr->set_predicted_elapsed_time_ms(new_region_elapsed_time_ms);
   269 }
   273 }
   270 
   274 
   271 void G1CollectionSet::add_young_region_common(HeapRegion* hr) {
   275 void G1CollectionSet::add_young_region_common(HeapRegion* hr) {
   272   assert(hr->is_young(), "invariant");
   276   assert(hr->is_young(), "invariant");
   273   assert(_inc_build_state == Active, "Precondition");
   277   assert(_inc_build_state == Active, "Precondition");
   274 
   278 
   275   size_t collection_set_length = _collection_set_cur_length;
   279   size_t collection_set_length = _collection_set_cur_length;
   276   assert(collection_set_length <= INT_MAX, "Collection set is too large with %d entries", (int)collection_set_length);
   280   // We use UINT_MAX as "invalid" marker in verification.
   277   hr->set_young_index_in_cset((int)collection_set_length);
   281   assert(collection_set_length < (UINT_MAX - 1),
       
   282          "Collection set is too large with " SIZE_FORMAT " entries", collection_set_length);
       
   283   hr->set_young_index_in_cset((uint)collection_set_length + 1);
   278 
   284 
   279   _collection_set_regions[collection_set_length] = hr->hrm_index();
   285   _collection_set_regions[collection_set_length] = hr->hrm_index();
   280   // Concurrent readers must observe the store of the value in the array before an
   286   // Concurrent readers must observe the store of the value in the array before an
   281   // update to the length field.
   287   // update to the length field.
   282   OrderAccess::storestore();
   288   OrderAccess::storestore();
   308     // the incremental collection set, or it is updated by the
   314     // the incremental collection set, or it is updated by the
   309     // rset sampling code
   315     // rset sampling code
   310     hr->set_recorded_rs_length(rs_length);
   316     hr->set_recorded_rs_length(rs_length);
   311     hr->set_predicted_elapsed_time_ms(region_elapsed_time_ms);
   317     hr->set_predicted_elapsed_time_ms(region_elapsed_time_ms);
   312 
   318 
   313     _inc_recorded_rs_lengths += rs_length;
   319     _inc_recorded_rs_length += rs_length;
   314     _inc_predicted_elapsed_time_ms += region_elapsed_time_ms;
   320     _inc_predicted_elapsed_time_ms += region_elapsed_time_ms;
   315     _inc_bytes_used_before += hr->used();
   321     _inc_bytes_used_before += hr->used();
   316   }
   322   }
   317 
   323 
   318   assert(!hr->in_collection_set(), "invariant");
   324   assert(!hr->in_collection_set(), "invariant");
   401   finalize_incremental_building();
   407   finalize_incremental_building();
   402 
   408 
   403   guarantee(target_pause_time_ms > 0.0,
   409   guarantee(target_pause_time_ms > 0.0,
   404             "target_pause_time_ms = %1.6lf should be positive", target_pause_time_ms);
   410             "target_pause_time_ms = %1.6lf should be positive", target_pause_time_ms);
   405 
   411 
   406   size_t pending_cards = _policy->pending_cards();
   412   size_t pending_cards = _policy->pending_cards_at_gc_start();
   407   double base_time_ms = _policy->predict_base_elapsed_time_ms(pending_cards);
   413   double base_time_ms = _policy->predict_base_elapsed_time_ms(pending_cards);
   408   double time_remaining_ms = MAX2(target_pause_time_ms - base_time_ms, 0.0);
   414   double time_remaining_ms = MAX2(target_pause_time_ms - base_time_ms, 0.0);
   409 
   415 
   410   log_trace(gc, ergo, cset)("Start choosing CSet. pending cards: " SIZE_FORMAT " predicted base time: %1.2fms remaining time: %1.2fms target pause time: %1.2fms",
   416   log_trace(gc, ergo, cset)("Start choosing CSet. pending cards: " SIZE_FORMAT " predicted base time: %1.2fms remaining time: %1.2fms target pause time: %1.2fms",
   411                             pending_cards, base_time_ms, time_remaining_ms, target_pause_time_ms);
   417                             pending_cards, base_time_ms, time_remaining_ms, target_pause_time_ms);
   429   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",
   430                             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);
   431 
   437 
   432   // The number of recorded young regions is the incremental
   438   // The number of recorded young regions is the incremental
   433   // collection set's current size
   439   // collection set's current size
   434   set_recorded_rs_lengths(_inc_recorded_rs_lengths);
   440   set_recorded_rs_length(_inc_recorded_rs_length);
   435 
   441 
   436   double young_end_time_sec = os::elapsedTime();
   442   double young_end_time_sec = os::elapsedTime();
   437   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);
   438 
   444 
   439   return time_remaining_ms;
   445   return time_remaining_ms;
   517   move_candidates_to_collection_set(num_selected_regions);
   523   move_candidates_to_collection_set(num_selected_regions);
   518 
   524 
   519   _num_optional_regions -= num_selected_regions;
   525   _num_optional_regions -= num_selected_regions;
   520 
   526 
   521   stop_incremental_building();
   527   stop_incremental_building();
       
   528 
       
   529   _g1h->verify_region_attr_remset_update();
       
   530 
   522   return num_selected_regions > 0;
   531   return num_selected_regions > 0;
   523 }
   532 }
   524 
   533 
   525 void G1CollectionSet::abandon_optional_collection_set(G1ParScanThreadStateSet* pss) {
   534 void G1CollectionSet::abandon_optional_collection_set(G1ParScanThreadStateSet* pss) {
   526   for (uint i = 0; i < _num_optional_regions; i++) {
   535   for (uint i = 0; i < _num_optional_regions; i++) {
   527     HeapRegion* r = candidates()->at(candidates()->cur_idx() + i);
   536     HeapRegion* r = candidates()->at(candidates()->cur_idx() + i);
   528     pss->record_unused_optional_region(r);
   537     pss->record_unused_optional_region(r);
       
   538     // Clear collection set marker and make sure that the remembered set information
       
   539     // is correct as we still need it later.
   529     _g1h->clear_region_attr(r);
   540     _g1h->clear_region_attr(r);
       
   541     _g1h->register_region_with_region_attr(r);
   530     r->clear_index_in_opt_cset();
   542     r->clear_index_in_opt_cset();
   531   }
   543   }
   532   free_optional_regions();
   544   free_optional_regions();
       
   545 
       
   546   _g1h->verify_region_attr_remset_update();
   533 }
   547 }
   534 
   548 
   535 #ifdef ASSERT
   549 #ifdef ASSERT
   536 class G1VerifyYoungCSetIndicesClosure : public HeapRegionClosure {
   550 class G1VerifyYoungCSetIndicesClosure : public HeapRegionClosure {
   537 private:
   551 private:
   538   size_t _young_length;
   552   size_t _young_length;
   539   int* _heap_region_indices;
   553   uint* _heap_region_indices;
   540 public:
   554 public:
   541   G1VerifyYoungCSetIndicesClosure(size_t young_length) : HeapRegionClosure(), _young_length(young_length) {
   555   G1VerifyYoungCSetIndicesClosure(size_t young_length) : HeapRegionClosure(), _young_length(young_length) {
   542     _heap_region_indices = NEW_C_HEAP_ARRAY(int, young_length, mtGC);
   556     _heap_region_indices = NEW_C_HEAP_ARRAY(uint, young_length + 1, mtGC);
   543     for (size_t i = 0; i < young_length; i++) {
   557     for (size_t i = 0; i < young_length + 1; i++) {
   544       _heap_region_indices[i] = -1;
   558       _heap_region_indices[i] = UINT_MAX;
   545     }
   559     }
   546   }
   560   }
   547   ~G1VerifyYoungCSetIndicesClosure() {
   561   ~G1VerifyYoungCSetIndicesClosure() {
   548     FREE_C_HEAP_ARRAY(int, _heap_region_indices);
   562     FREE_C_HEAP_ARRAY(int, _heap_region_indices);
   549   }
   563   }
   550 
   564 
   551   virtual bool do_heap_region(HeapRegion* r) {
   565   virtual bool do_heap_region(HeapRegion* r) {
   552     const int idx = r->young_index_in_cset();
   566     const uint idx = r->young_index_in_cset();
   553 
   567 
   554     assert(idx > -1, "Young index must be set for all regions in the incremental collection set but is not for region %u.", r->hrm_index());
   568     assert(idx > 0, "Young index must be set for all regions in the incremental collection set but is not for region %u.", r->hrm_index());
   555     assert((size_t)idx < _young_length, "Young cset index too large for region %u", r->hrm_index());
   569     assert(idx <= _young_length, "Young cset index %u too large for region %u", idx, r->hrm_index());
   556 
   570 
   557     assert(_heap_region_indices[idx] == -1,
   571     assert(_heap_region_indices[idx] == UINT_MAX,
   558            "Index %d used by multiple regions, first use by region %u, second by region %u",
   572            "Index %d used by multiple regions, first use by region %u, second by region %u",
   559            idx, _heap_region_indices[idx], r->hrm_index());
   573            idx, _heap_region_indices[idx], r->hrm_index());
   560 
   574 
   561     _heap_region_indices[idx] = r->hrm_index();
   575     _heap_region_indices[idx] = r->hrm_index();
   562 
   576