< prev index next >

src/hotspot/share/gc/g1/g1CollectionSet.cpp

Print this page
rev 53416 : imported patch 8217330-split-collectionsetchooser
rev 53417 : [mq]: 8217330-leo-review
   1 /*
   2  * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


  27 #include "gc/g1/g1CollectionSet.hpp"
  28 #include "gc/g1/g1CollectorState.hpp"
  29 #include "gc/g1/g1ParScanThreadState.hpp"
  30 #include "gc/g1/g1Policy.hpp"
  31 #include "gc/g1/heapRegion.inline.hpp"
  32 #include "gc/g1/heapRegionRemSet.hpp"
  33 #include "gc/g1/heapRegionSet.hpp"
  34 #include "logging/logStream.hpp"
  35 #include "utilities/debug.hpp"
  36 #include "utilities/globalDefinitions.hpp"
  37 #include "utilities/quickSort.hpp"
  38 
  39 G1CollectorState* G1CollectionSet::collector_state() {
  40   return _g1h->collector_state();
  41 }
  42 
  43 G1GCPhaseTimes* G1CollectionSet::phase_times() {
  44   return _policy->phase_times();
  45 }
  46 
  47 CollectionSetChooser* G1CollectionSet::cset_chooser() {
  48   return _cset_chooser;
  49 }
  50 
  51 double G1CollectionSet::predict_region_elapsed_time_ms(HeapRegion* hr) {
  52   return _policy->predict_region_elapsed_time_ms(hr, collector_state()->in_young_only_phase());
  53 }
  54 
  55 G1CollectionSet::G1CollectionSet(G1CollectedHeap* g1h, G1Policy* policy) :
  56   _g1h(g1h),
  57   _policy(policy),
  58   _cset_chooser(new CollectionSetChooser()),
  59   _eden_region_length(0),
  60   _survivor_region_length(0),
  61   _old_region_length(0),
  62   _collection_set_regions(NULL),
  63   _collection_set_cur_length(0),
  64   _collection_set_max_length(0),
  65   _optional_regions(NULL),
  66   _optional_region_length(0),
  67   _optional_region_max_length(0),
  68   _bytes_used_before(0),
  69   _recorded_rs_lengths(0),
  70   _inc_build_state(Inactive),
  71   _inc_bytes_used_before(0),
  72   _inc_recorded_rs_lengths(0),
  73   _inc_recorded_rs_lengths_diffs(0),
  74   _inc_predicted_elapsed_time_ms(0.0),
  75   _inc_predicted_elapsed_time_ms_diffs(0.0) {
  76 }
  77 
  78 G1CollectionSet::~G1CollectionSet() {
  79   if (_collection_set_regions != NULL) {
  80     FREE_C_HEAP_ARRAY(uint, _collection_set_regions);
  81   }
  82   free_optional_regions();
  83   delete _cset_chooser;
  84 }
  85 
  86 void G1CollectionSet::init_region_lengths(uint eden_cset_region_length,
  87                                           uint survivor_cset_region_length) {
  88   assert_at_safepoint_on_vm_thread();
  89 
  90   _eden_region_length     = eden_cset_region_length;
  91   _survivor_region_length = survivor_cset_region_length;
  92 
  93   assert((size_t) young_region_length() == _collection_set_cur_length,
  94          "Young region length %u should match collection set length " SIZE_FORMAT, young_region_length(), _collection_set_cur_length);
  95 
  96   _old_region_length      = 0;
  97   _optional_region_length = 0;
  98 }
  99 
 100 void G1CollectionSet::initialize(uint max_region_length) {
 101   guarantee(_collection_set_regions == NULL, "Must only initialize once.");
 102   _collection_set_max_length = max_region_length;
 103   _collection_set_regions = NEW_C_HEAP_ARRAY(uint, max_region_length, mtGC);


 422   // Clear the fields that point to the survivor list - they are all young now.
 423   survivors->convert_to_eden();
 424 
 425   _bytes_used_before = _inc_bytes_used_before;
 426   time_remaining_ms = MAX2(time_remaining_ms - _inc_predicted_elapsed_time_ms, 0.0);
 427 
 428   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",
 429                             eden_region_length, survivor_region_length, _inc_predicted_elapsed_time_ms, target_pause_time_ms);
 430 
 431   // The number of recorded young regions is the incremental
 432   // collection set's current size
 433   set_recorded_rs_lengths(_inc_recorded_rs_lengths);
 434 
 435   double young_end_time_sec = os::elapsedTime();
 436   phase_times()->record_young_cset_choice_time_ms((young_end_time_sec - young_start_time_sec) * 1000.0);
 437 
 438   return time_remaining_ms;
 439 }
 440 
 441 void G1CollectionSet::add_as_old(HeapRegion* hr) {
 442   cset_chooser()->pop(); // already have region via peek()
 443   _g1h->old_set_remove(hr);
 444   add_old_region(hr);
 445 }
 446 
 447 void G1CollectionSet::add_as_optional(HeapRegion* hr) {
 448   assert(_optional_regions != NULL, "Must not be called before array is allocated");
 449   cset_chooser()->pop(); // already have region via peek()
 450   _g1h->old_set_remove(hr);
 451   add_optional_region(hr);
 452 }
 453 
 454 bool G1CollectionSet::optional_is_full() {
 455   assert(_optional_region_length <= _optional_region_max_length, "Invariant");
 456   return _optional_region_length == _optional_region_max_length;
 457 }
 458 
 459 void G1CollectionSet::clear_optional_region(const HeapRegion* hr) {
 460   assert(_optional_regions != NULL, "Must not be called before array is allocated");
 461   uint index = hr->index_in_opt_cset();
 462   _optional_regions[index] = NULL;
 463 }
 464 
 465 static int compare_region_idx(const uint a, const uint b) {
 466   if (a > b) {
 467     return 1;
 468   } else if (a == b) {
 469     return 0;
 470   } else {
 471     return -1;
 472   }
 473 }
 474 
 475 void G1CollectionSet::finalize_old_part(double time_remaining_ms) {
 476   double non_young_start_time_sec = os::elapsedTime();
 477   double predicted_old_time_ms = 0.0;
 478   double predicted_optional_time_ms = 0.0;
 479   double optional_threshold_ms = time_remaining_ms * _policy->optional_prediction_fraction();
 480   uint expensive_region_num = 0;
 481 
 482   if (collector_state()->in_mixed_phase()) {
 483     cset_chooser()->verify();
 484     const uint min_old_cset_length = _policy->calc_min_old_cset_length();
 485     const uint max_old_cset_length = MAX2(min_old_cset_length, _policy->calc_max_old_cset_length());
 486     bool check_time_remaining = _policy->adaptive_young_list_length();
 487 
 488     initialize_optional(max_old_cset_length - min_old_cset_length);
 489     log_debug(gc, ergo, cset)("Start adding old regions for mixed gc. min %u regions, max %u regions, "
 490                               "time remaining %1.2fms, optional threshold %1.2fms",
 491                               min_old_cset_length, max_old_cset_length, time_remaining_ms, optional_threshold_ms);
 492 
 493     HeapRegion* hr = cset_chooser()->peek();
 494     while (hr != NULL) {
 495       if (old_region_length() + optional_region_length() >= max_old_cset_length) {
 496         // Added maximum number of old regions to the CSet.
 497         log_debug(gc, ergo, cset)("Finish adding old regions to CSet (old CSet region num reached max). "
 498                                   "old %u regions, optional %u regions",
 499                                   old_region_length(), optional_region_length());
 500         break;
 501       }
 502 
 503       // Stop adding regions if the remaining reclaimable space is
 504       // not above G1HeapWastePercent.
 505       size_t reclaimable_bytes = cset_chooser()->remaining_reclaimable_bytes();
 506       double reclaimable_percent = _policy->reclaimable_bytes_percent(reclaimable_bytes);
 507       double threshold = (double) G1HeapWastePercent;
 508       if (reclaimable_percent <= threshold) {
 509         // We've added enough old regions that the amount of uncollected
 510         // reclaimable space is at or below the waste threshold. Stop
 511         // adding old regions to the CSet.
 512         log_debug(gc, ergo, cset)("Finish adding old regions to CSet (reclaimable percentage not over threshold). "
 513                                   "reclaimable: " SIZE_FORMAT "%s (%1.2f%%) threshold: " UINTX_FORMAT "%%",
 514                                   byte_size_in_proper_unit(reclaimable_bytes), proper_unit_for_byte_size(reclaimable_bytes),
 515                                   reclaimable_percent, G1HeapWastePercent);
 516         break;
 517       }
 518 
 519       double predicted_time_ms = predict_region_elapsed_time_ms(hr);
 520       time_remaining_ms = MAX2(time_remaining_ms - predicted_time_ms, 0.0);
 521       // Add regions to old set until we reach minimum amount
 522       if (old_region_length() < min_old_cset_length) {
 523         predicted_old_time_ms += predicted_time_ms;
 524         add_as_old(hr);
 525         // Record the number of regions added when no time remaining


 534           break;
 535         }
 536         // Keep adding regions to old set until we reach optional threshold
 537         if (time_remaining_ms > optional_threshold_ms) {
 538           predicted_old_time_ms += predicted_time_ms;
 539           add_as_old(hr);
 540         } else if (time_remaining_ms > 0) {
 541           // Keep adding optional regions until time is up
 542           if (!optional_is_full()) {
 543             predicted_optional_time_ms += predicted_time_ms;
 544             add_as_optional(hr);
 545           } else {
 546             log_debug(gc, ergo, cset)("Finish adding old regions to CSet (optional set full).");
 547             break;
 548           }
 549         } else {
 550           log_debug(gc, ergo, cset)("Finish adding old regions to CSet (predicted time is too high).");
 551           break;
 552         }
 553       }
 554       hr = cset_chooser()->peek();
 555     }
 556     if (hr == NULL) {
 557       log_debug(gc, ergo, cset)("Finish adding old regions to CSet (candidate old regions not available)");
 558     }
 559 
 560     cset_chooser()->verify();
 561   }
 562 
 563   stop_incremental_building();
 564 
 565   log_debug(gc, ergo, cset)("Finish choosing CSet regions old: %u, optional: %u, "
 566                             "predicted old time: %1.2fms, predicted optional time: %1.2fms, time remaining: %1.2f",
 567                             old_region_length(), optional_region_length(),
 568                             predicted_old_time_ms, predicted_optional_time_ms, time_remaining_ms);
 569   if (expensive_region_num > 0) {
 570     log_debug(gc, ergo, cset)("CSet contains %u old regions that were added although the predicted time was too high.",
 571                               expensive_region_num);
 572   }
 573 
 574   double non_young_end_time_sec = os::elapsedTime();
 575   phase_times()->record_non_young_cset_choice_time_ms((non_young_end_time_sec - non_young_start_time_sec) * 1000.0);
 576 
 577   QuickSort::sort(_collection_set_regions, _collection_set_cur_length, compare_region_idx, true);
 578 }
 579 
 580 HeapRegion* G1OptionalCSet::region_at(uint index) {


 613 
 614 void G1OptionalCSet::complete_evacuation() {
 615   _evacuation_failed = false;
 616   for (uint i = _current_index; i < _current_limit; i++) {
 617     HeapRegion* hr = region_at(i);
 618     _cset->clear_optional_region(hr);
 619     if (hr->evacuation_failed()){
 620       _evacuation_failed = true;
 621     }
 622   }
 623   _current_index = _current_limit;
 624 }
 625 
 626 bool G1OptionalCSet::evacuation_failed() {
 627   return _evacuation_failed;
 628 }
 629 
 630 G1OptionalCSet::~G1OptionalCSet() {
 631   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 632   while (!is_empty()) {
 633     // We want to return regions not evacuated to the
 634     // chooser in reverse order to maintain the old order.
 635     HeapRegion* hr = _cset->remove_last_optional_region();
 636     assert(hr != NULL, "Should be valid region left");
 637     _pset->record_unused_optional_region(hr);
 638     g1h->old_set_add(hr);
 639     g1h->clear_in_cset(hr);
 640     hr->set_index_in_opt_cset(InvalidCSetIndex);
 641     _cset->cset_chooser()->push(hr);
 642   }
 643   _cset->free_optional_regions();
 644 }
 645 
 646 uint G1OptionalCSet::size() {
 647   return _cset->optional_region_length() - _current_index;
 648 }
 649 
 650 bool G1OptionalCSet::is_empty() {
 651   return size() == 0;
 652 }
 653 
 654 void G1OptionalCSet::prepare_to_evacuate_optional_region(HeapRegion* hr) {
 655   log_trace(gc, cset)("Adding region %u for optional evacuation", hr->hrm_index());
 656   G1CollectedHeap::heap()->clear_in_cset(hr);
 657   _cset->add_old_region(hr);
 658 }
 659 
 660 #ifdef ASSERT
 661 class G1VerifyYoungCSetIndicesClosure : public HeapRegionClosure {


   1 /*
   2  * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


  27 #include "gc/g1/g1CollectionSet.hpp"
  28 #include "gc/g1/g1CollectorState.hpp"
  29 #include "gc/g1/g1ParScanThreadState.hpp"
  30 #include "gc/g1/g1Policy.hpp"
  31 #include "gc/g1/heapRegion.inline.hpp"
  32 #include "gc/g1/heapRegionRemSet.hpp"
  33 #include "gc/g1/heapRegionSet.hpp"
  34 #include "logging/logStream.hpp"
  35 #include "utilities/debug.hpp"
  36 #include "utilities/globalDefinitions.hpp"
  37 #include "utilities/quickSort.hpp"
  38 
  39 G1CollectorState* G1CollectionSet::collector_state() {
  40   return _g1h->collector_state();
  41 }
  42 
  43 G1GCPhaseTimes* G1CollectionSet::phase_times() {
  44   return _policy->phase_times();
  45 }
  46 




  47 double G1CollectionSet::predict_region_elapsed_time_ms(HeapRegion* hr) {
  48   return _policy->predict_region_elapsed_time_ms(hr, collector_state()->in_young_only_phase());
  49 }
  50 
  51 G1CollectionSet::G1CollectionSet(G1CollectedHeap* g1h, G1Policy* policy) :
  52   _g1h(g1h),
  53   _policy(policy),
  54   _candidates(NULL),
  55   _eden_region_length(0),
  56   _survivor_region_length(0),
  57   _old_region_length(0),
  58   _collection_set_regions(NULL),
  59   _collection_set_cur_length(0),
  60   _collection_set_max_length(0),
  61   _optional_regions(NULL),
  62   _optional_region_length(0),
  63   _optional_region_max_length(0),
  64   _bytes_used_before(0),
  65   _recorded_rs_lengths(0),
  66   _inc_build_state(Inactive),
  67   _inc_bytes_used_before(0),
  68   _inc_recorded_rs_lengths(0),
  69   _inc_recorded_rs_lengths_diffs(0),
  70   _inc_predicted_elapsed_time_ms(0.0),
  71   _inc_predicted_elapsed_time_ms_diffs(0.0) {
  72 }
  73 
  74 G1CollectionSet::~G1CollectionSet() {
  75   if (_collection_set_regions != NULL) {
  76     FREE_C_HEAP_ARRAY(uint, _collection_set_regions);
  77   }
  78   free_optional_regions();
  79   clear_candidates();
  80 }
  81 
  82 void G1CollectionSet::init_region_lengths(uint eden_cset_region_length,
  83                                           uint survivor_cset_region_length) {
  84   assert_at_safepoint_on_vm_thread();
  85 
  86   _eden_region_length     = eden_cset_region_length;
  87   _survivor_region_length = survivor_cset_region_length;
  88 
  89   assert((size_t) young_region_length() == _collection_set_cur_length,
  90          "Young region length %u should match collection set length " SIZE_FORMAT, young_region_length(), _collection_set_cur_length);
  91 
  92   _old_region_length      = 0;
  93   _optional_region_length = 0;
  94 }
  95 
  96 void G1CollectionSet::initialize(uint max_region_length) {
  97   guarantee(_collection_set_regions == NULL, "Must only initialize once.");
  98   _collection_set_max_length = max_region_length;
  99   _collection_set_regions = NEW_C_HEAP_ARRAY(uint, max_region_length, mtGC);


 418   // Clear the fields that point to the survivor list - they are all young now.
 419   survivors->convert_to_eden();
 420 
 421   _bytes_used_before = _inc_bytes_used_before;
 422   time_remaining_ms = MAX2(time_remaining_ms - _inc_predicted_elapsed_time_ms, 0.0);
 423 
 424   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",
 425                             eden_region_length, survivor_region_length, _inc_predicted_elapsed_time_ms, target_pause_time_ms);
 426 
 427   // The number of recorded young regions is the incremental
 428   // collection set's current size
 429   set_recorded_rs_lengths(_inc_recorded_rs_lengths);
 430 
 431   double young_end_time_sec = os::elapsedTime();
 432   phase_times()->record_young_cset_choice_time_ms((young_end_time_sec - young_start_time_sec) * 1000.0);
 433 
 434   return time_remaining_ms;
 435 }
 436 
 437 void G1CollectionSet::add_as_old(HeapRegion* hr) {
 438   candidates()->pop_front(); // already have region via peek()
 439   _g1h->old_set_remove(hr);
 440   add_old_region(hr);
 441 }
 442 
 443 void G1CollectionSet::add_as_optional(HeapRegion* hr) {
 444   assert(_optional_regions != NULL, "Must not be called before array is allocated");
 445   candidates()->pop_front(); // already have region via peek()
 446   _g1h->old_set_remove(hr);
 447   add_optional_region(hr);
 448 }
 449 
 450 bool G1CollectionSet::optional_is_full() {
 451   assert(_optional_region_length <= _optional_region_max_length, "Invariant");
 452   return _optional_region_length == _optional_region_max_length;
 453 }
 454 
 455 void G1CollectionSet::clear_optional_region(const HeapRegion* hr) {
 456   assert(_optional_regions != NULL, "Must not be called before array is allocated");
 457   uint index = hr->index_in_opt_cset();
 458   _optional_regions[index] = NULL;
 459 }
 460 
 461 static int compare_region_idx(const uint a, const uint b) {
 462   if (a > b) {
 463     return 1;
 464   } else if (a == b) {
 465     return 0;
 466   } else {
 467     return -1;
 468   }
 469 }
 470 
 471 void G1CollectionSet::finalize_old_part(double time_remaining_ms) {
 472   double non_young_start_time_sec = os::elapsedTime();
 473   double predicted_old_time_ms = 0.0;
 474   double predicted_optional_time_ms = 0.0;
 475   double optional_threshold_ms = time_remaining_ms * _policy->optional_prediction_fraction();
 476   uint expensive_region_num = 0;
 477 
 478   if (collector_state()->in_mixed_phase()) {
 479     candidates()->verify();
 480     const uint min_old_cset_length = _policy->calc_min_old_cset_length();
 481     const uint max_old_cset_length = MAX2(min_old_cset_length, _policy->calc_max_old_cset_length());
 482     bool check_time_remaining = _policy->adaptive_young_list_length();
 483 
 484     initialize_optional(max_old_cset_length - min_old_cset_length);
 485     log_debug(gc, ergo, cset)("Start adding old regions for mixed gc. min %u regions, max %u regions, "
 486                               "time remaining %1.2fms, optional threshold %1.2fms",
 487                               min_old_cset_length, max_old_cset_length, time_remaining_ms, optional_threshold_ms);
 488 
 489     HeapRegion* hr = candidates()->peek_front();
 490     while (hr != NULL) {
 491       if (old_region_length() + optional_region_length() >= max_old_cset_length) {
 492         // Added maximum number of old regions to the CSet.
 493         log_debug(gc, ergo, cset)("Finish adding old regions to CSet (old CSet region num reached max). "
 494                                   "old %u regions, optional %u regions",
 495                                   old_region_length(), optional_region_length());
 496         break;
 497       }
 498 
 499       // Stop adding regions if the remaining reclaimable space is
 500       // not above G1HeapWastePercent.
 501       size_t reclaimable_bytes = candidates()->remaining_reclaimable_bytes();
 502       double reclaimable_percent = _policy->reclaimable_bytes_percent(reclaimable_bytes);
 503       double threshold = (double) G1HeapWastePercent;
 504       if (reclaimable_percent <= threshold) {
 505         // We've added enough old regions that the amount of uncollected
 506         // reclaimable space is at or below the waste threshold. Stop
 507         // adding old regions to the CSet.
 508         log_debug(gc, ergo, cset)("Finish adding old regions to CSet (reclaimable percentage not over threshold). "
 509                                   "reclaimable: " SIZE_FORMAT "%s (%1.2f%%) threshold: " UINTX_FORMAT "%%",
 510                                   byte_size_in_proper_unit(reclaimable_bytes), proper_unit_for_byte_size(reclaimable_bytes),
 511                                   reclaimable_percent, G1HeapWastePercent);
 512         break;
 513       }
 514 
 515       double predicted_time_ms = predict_region_elapsed_time_ms(hr);
 516       time_remaining_ms = MAX2(time_remaining_ms - predicted_time_ms, 0.0);
 517       // Add regions to old set until we reach minimum amount
 518       if (old_region_length() < min_old_cset_length) {
 519         predicted_old_time_ms += predicted_time_ms;
 520         add_as_old(hr);
 521         // Record the number of regions added when no time remaining


 530           break;
 531         }
 532         // Keep adding regions to old set until we reach optional threshold
 533         if (time_remaining_ms > optional_threshold_ms) {
 534           predicted_old_time_ms += predicted_time_ms;
 535           add_as_old(hr);
 536         } else if (time_remaining_ms > 0) {
 537           // Keep adding optional regions until time is up
 538           if (!optional_is_full()) {
 539             predicted_optional_time_ms += predicted_time_ms;
 540             add_as_optional(hr);
 541           } else {
 542             log_debug(gc, ergo, cset)("Finish adding old regions to CSet (optional set full).");
 543             break;
 544           }
 545         } else {
 546           log_debug(gc, ergo, cset)("Finish adding old regions to CSet (predicted time is too high).");
 547           break;
 548         }
 549       }
 550       hr = candidates()->peek_front();
 551     }
 552     if (hr == NULL) {
 553       log_debug(gc, ergo, cset)("Finish adding old regions to CSet (candidate old regions not available)");
 554     }
 555 
 556     candidates()->verify();
 557   }
 558 
 559   stop_incremental_building();
 560 
 561   log_debug(gc, ergo, cset)("Finish choosing CSet regions old: %u, optional: %u, "
 562                             "predicted old time: %1.2fms, predicted optional time: %1.2fms, time remaining: %1.2f",
 563                             old_region_length(), optional_region_length(),
 564                             predicted_old_time_ms, predicted_optional_time_ms, time_remaining_ms);
 565   if (expensive_region_num > 0) {
 566     log_debug(gc, ergo, cset)("CSet contains %u old regions that were added although the predicted time was too high.",
 567                               expensive_region_num);
 568   }
 569 
 570   double non_young_end_time_sec = os::elapsedTime();
 571   phase_times()->record_non_young_cset_choice_time_ms((non_young_end_time_sec - non_young_start_time_sec) * 1000.0);
 572 
 573   QuickSort::sort(_collection_set_regions, _collection_set_cur_length, compare_region_idx, true);
 574 }
 575 
 576 HeapRegion* G1OptionalCSet::region_at(uint index) {


 609 
 610 void G1OptionalCSet::complete_evacuation() {
 611   _evacuation_failed = false;
 612   for (uint i = _current_index; i < _current_limit; i++) {
 613     HeapRegion* hr = region_at(i);
 614     _cset->clear_optional_region(hr);
 615     if (hr->evacuation_failed()){
 616       _evacuation_failed = true;
 617     }
 618   }
 619   _current_index = _current_limit;
 620 }
 621 
 622 bool G1OptionalCSet::evacuation_failed() {
 623   return _evacuation_failed;
 624 }
 625 
 626 G1OptionalCSet::~G1OptionalCSet() {
 627   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 628   while (!is_empty()) {
 629     // We want to return regions not evacuated to the collection set candidates
 630     // in reverse order to maintain the old order.
 631     HeapRegion* hr = _cset->remove_last_optional_region();
 632     assert(hr != NULL, "Should be valid region left");
 633     _pset->record_unused_optional_region(hr);
 634     g1h->old_set_add(hr);
 635     g1h->clear_in_cset(hr);
 636     hr->set_index_in_opt_cset(InvalidCSetIndex);
 637     _cset->candidates()->push_front(hr);
 638   }
 639   _cset->free_optional_regions();
 640 }
 641 
 642 uint G1OptionalCSet::size() {
 643   return _cset->optional_region_length() - _current_index;
 644 }
 645 
 646 bool G1OptionalCSet::is_empty() {
 647   return size() == 0;
 648 }
 649 
 650 void G1OptionalCSet::prepare_to_evacuate_optional_region(HeapRegion* hr) {
 651   log_trace(gc, cset)("Adding region %u for optional evacuation", hr->hrm_index());
 652   G1CollectedHeap::heap()->clear_in_cset(hr);
 653   _cset->add_old_region(hr);
 654 }
 655 
 656 #ifdef ASSERT
 657 class G1VerifyYoungCSetIndicesClosure : public HeapRegionClosure {


< prev index next >